Tuesday, August 26, 2025
Home Blog Page 1939

Check-Driving HTML Templates

After a decade or extra the place Single-Web page-Purposes generated by
JavaScript frameworks have
grow to be the norm
, we see that server-side rendered HTML is turning into
widespread once more, additionally due to libraries corresponding to HTMX or Turbo. Writing a wealthy net UI in a
historically server-side language like Go or Java is not simply attainable,
however a really enticing proposition.

We then face the issue of how you can write automated exams for the HTML
elements of our net functions. Whereas the JavaScript world has advanced highly effective and subtle methods to check the UI,
ranging in dimension from unit-level to integration to end-to-end, in different
languages we would not have such a richness of instruments accessible.

When writing an internet software in Go or Java, HTML is usually generated
by way of templates, which include small fragments of logic. It’s actually
attainable to check them not directly by way of end-to-end exams, however these exams
are sluggish and costly.

We will as a substitute write unit exams that use CSS selectors to probe the
presence and proper content material of particular HTML components inside a doc.
Parameterizing these exams makes it simple so as to add new exams and to obviously
point out what particulars every take a look at is verifying. This method works with any
language that has entry to an HTML parsing library that helps CSS
selectors; examples are offered in Go and Java.

Degree 1: checking for sound HTML

The primary factor we wish to examine is that the HTML we produce is
principally sound. I do not imply to examine that HTML is legitimate in accordance with the
W3C; it will be cool to do it, but it surely’s higher to start out with a lot less complicated and quicker checks.
As an example, we wish our exams to
break if the template generates one thing like

<div>foo</p> 

Let’s examine how you can do it in levels: we begin with the next take a look at that
tries to compile the template. In Go we use the usual html/template bundle.

Go

  func Test_wellFormedHtml(t *testing.T) {     templ := template.Should(template.ParseFiles("index.tmpl"))     _ = templ   }

In Java, we use jmustache
as a result of it is quite simple to make use of; Freemarker or
Velocity are different frequent selections.

Java

  @Check   void indexIsSoundHtml() {       var template = Mustache.compiler().compile(               new InputStreamReader(                       getClass().getResourceAsStream("/index.tmpl")));   }

If we run this take a look at, it can fail, as a result of the index.tmpl file does
not exist. So we create it, with the above damaged HTML. Now the take a look at ought to move.

Then we create a mannequin for the template to make use of. The applying manages a todo-list, and
we are able to create a minimal mannequin for demonstration functions.

Go

  func Test_wellFormedHtml(t *testing.T) {     templ := template.Should(template.ParseFiles("index.tmpl"))     mannequin := todo.NewList()     _ = templ     _ = mannequin   }

Java

  @Check   void indexIsSoundHtml() {       var template = Mustache.compiler().compile(               new InputStreamReader(                       getClass().getResourceAsStream("/index.tmpl")));       var mannequin = new TodoList();   }

Now we render the template, saving the leads to a bytes buffer (Go) or as a String (Java).

Go

  func Test_wellFormedHtml(t *testing.T) {     templ := template.Should(template.ParseFiles("index.tmpl"))     mannequin := todo.NewList()     var buf bytes.Buffer     err := templ.Execute(&buf, mannequin)     if err != nil {       panic(err)     }   }

Java

  @Check   void indexIsSoundHtml() {       var template = Mustache.compiler().compile(               new InputStreamReader(                       getClass().getResourceAsStream("/index.tmpl")));       var mannequin = new TodoList();          var html = template.execute(mannequin);   }

At this level, we wish to parse the HTML and we count on to see an
error, as a result of in our damaged HTML there’s a div component that
is closed by a p component. There’s an HTML parser within the Go
customary library, however it’s too lenient: if we run it on our damaged HTML, we do not get an
error. Fortunately, the Go customary library additionally has an XML parser that may be
configured to parse HTML (due to this Stack Overflow reply)

Go

  func Test_wellFormedHtml(t *testing.T) {     templ := template.Should(template.ParseFiles("index.tmpl"))     mannequin := todo.NewList()          // render the template right into a buffer     var buf bytes.Buffer     err := templ.Execute(&buf, mannequin)     if err != nil {       panic(err)     }        // examine that the template may be parsed as (lenient) XML     decoder := xml.NewDecoder(bytes.NewReader(buf.Bytes()))     decoder.Strict = false     decoder.AutoClose = xml.HTMLAutoClose     decoder.Entity = xml.HTMLEntity     for {       _, err := decoder.Token()       change err {       case io.EOF:         return // We're carried out, it is legitimate!       case nil:         // do nothing       default:         t.Fatalf("Error parsing html: %s", err)       }     }   }

supply

This code configures the HTML parser to have the appropriate stage of leniency
for HTML, after which parses the HTML token by token. Certainly, we see the error
message we needed:

--- FAIL: Test_wellFormedHtml (0.00s)     index_template_test.go:61: Error parsing html: XML syntax error on line 4: surprising finish component </p> 

In Java, a flexible library to make use of is jsoup:

Java

  @Check   void indexIsSoundHtml() {       var template = Mustache.compiler().compile(               new InputStreamReader(                       getClass().getResourceAsStream("/index.tmpl")));       var mannequin = new TodoList();          var html = template.execute(mannequin);          var parser = Parser.htmlParser().setTrackErrors(10);       Jsoup.parse(html, "", parser);       assertThat(parser.getErrors()).isEmpty();   }

supply

And we see it fail:

java.lang.AssertionError:  Anticipating empty however was:<[<1:13>: Unexpected EndTag token [</p>] when in state [InBody], 

Success! Now if we copy over the contents of the TodoMVC
template
to our index.tmpl file, the take a look at passes.

The take a look at, nevertheless, is simply too verbose: we extract two helper features, in
order to make the intention of the take a look at clearer, and we get

Go

  func Test_wellFormedHtml(t *testing.T) {     mannequin := todo.NewList()        buf := renderTemplate("index.tmpl", mannequin)        assertWellFormedHtml(t, buf)   }

supply

Java

  @Check   void indexIsSoundHtml() {       var mannequin = new TodoList();          var html = renderTemplate("/index.tmpl", mannequin);          assertSoundHtml(html);   }

supply

Degree 2: testing HTML construction

What else ought to we take a look at?

We all know that the seems of a web page can solely be examined, in the end, by a
human how it’s rendered in a browser. Nonetheless, there may be usually
logic in templates, and we wish to have the ability to take a look at that logic.

One may be tempted to check the rendered HTML with string equality,
however this method fails in apply, as a result of templates include lots of
particulars that make string equality assertions impractical. The assertions
grow to be very verbose, and when studying the assertion, it turns into troublesome
to grasp what it’s that we’re attempting to show.

What we want
is a method to say that some elements of the rendered HTML
correspond to what we count on, and to ignore all the main points we do not
care about.
A method to do that is by operating queries with the CSS selector language:
it’s a highly effective language that enables us to pick out the
components that we care about from the entire HTML doc. As soon as now we have
chosen these components, we (1) rely that the variety of component returned
is what we count on, and (2) that they include the textual content or different content material
that we count on.

The UI that we’re speculated to generate seems like this:

Check-Driving HTML Templates

There are a number of particulars which can be rendered dynamically:

  1. The variety of gadgets and their textual content content material change, clearly
  2. The model of the todo-item modifications when it is accomplished (e.g., the
    second)
  3. The “2 gadgets left” textual content will change with the variety of non-completed
    gadgets
  4. One of many three buttons “All”, “Lively”, “Accomplished” might be
    highlighted, relying on the present url; as an illustration if we resolve that the
    url that reveals solely the “Lively” gadgets is /lively, then when the present url
    is /lively, the “Lively” button ought to be surrounded by a skinny purple
    rectangle
  5. The “Clear accomplished” button ought to solely be seen if any merchandise is
    accomplished

Every of this issues may be examined with the assistance of CSS selectors.

It is a snippet from the TodoMVC template (barely simplified). I
haven’t but added the dynamic bits, so what we see right here is static
content material, offered for example:

index.tmpl

  <part class="todoapp">     <ul class="todo-list">       <!-- These are right here simply to point out the construction of the record gadgets -->       <!-- Listing gadgets ought to get the category `accomplished` when marked as accomplished -->       <li class="accomplished">           <div class="view">           <enter class="toggle" kind="checkbox" checked>           <label>Style JavaScript</label>            <button class="destroy"></button>         </div>       </li>       <li>         <div class="view">           <enter class="toggle" kind="checkbox">           <label>Purchase a unicorn</label>            <button class="destroy"></button>         </div>       </li>     </ul>     <footer class="footer">       <!-- This ought to be `0 gadgets left` by default -->       <span class="todo-count"><sturdy>0</sturdy> merchandise left</span>        <ul class="filters">         <li>           <a class="chosen" href="#/">All</a>          </li>         <li>           <a href="#/lively">Lively</a>         </li>         <li>           <a href="#/accomplished">Accomplished</a>         </li>       </ul>       <!-- Hidden if no accomplished gadgets are left ↓ -->       <button class="clear-completed">Clear accomplished</button>      </footer>   </part>  

supply

By wanting on the static model of the template, we are able to deduce which
CSS selectors can be utilized to determine the related components for the 5 dynamic
options listed above:

function CSS selector
All of the gadgets ul.todo-list li
Accomplished gadgets ul.todo-list li.accomplished
Gadgets left span.todo-count
Highlighted navigation hyperlink ul.filters a.chosen
Clear accomplished button button.clear-completed

We will use these selectors to focus our exams on simply the issues we wish to take a look at.

Testing HTML content material

The primary take a look at will search for all of the gadgets, and show that the info
arrange by the take a look at is rendered accurately.

func Test_todoItemsAreShown(t *testing.T) {   mannequin := todo.NewList()   mannequin.Add("Foo")   mannequin.Add("Bar")   buf := renderTemplate(mannequin)   // assert there are two <li> components contained in the <ul class="todo-list">    // assert the primary <li> textual content is "Foo"   // assert the second <li> textual content is "Bar" } 

We’d like a approach to question the HTML doc with our CSS selector; an excellent
library for Go is goquery, that implements an API impressed by jQuery.
In Java, we maintain utilizing the identical library we used to check for sound HTML, specifically
jsoup. Our take a look at turns into:

Go

  func Test_todoItemsAreShown(t *testing.T) {     mannequin := todo.NewList()     mannequin.Add("Foo")     mannequin.Add("Bar")        buf := renderTemplate("index.tmpl", mannequin)        // parse the HTML with goquery     doc, err := goquery.NewDocumentFromReader(bytes.NewReader(buf.Bytes()))     if err != nil {       // if parsing fails, we cease the take a look at right here with t.FatalF       t.Fatalf("Error rendering template %s", err)     }        // assert there are two <li> components contained in the <ul class="todo-list">     choice := doc.Discover("ul.todo-list li")     assert.Equal(t, 2, choice.Size())        // assert the primary <li> textual content is "Foo"     assert.Equal(t, "Foo", textual content(choice.Nodes[0]))        // assert the second <li> textual content is "Bar"     assert.Equal(t, "Bar", textual content(choice.Nodes[1]))   }      func textual content(node *html.Node) string {     // A bit of mess on account of the truth that goquery has     // a .Textual content() methodology on Choice however not on html.Node     sel := goquery.Choice{Nodes: []*html.Node{node}}     return strings.TrimSpace(sel.Textual content())   }

supply

Java

  @Check   void todoItemsAreShown() throws IOException {       var mannequin = new TodoList();       mannequin.add("Foo");       mannequin.add("Bar");          var html = renderTemplate("/index.tmpl", mannequin);          // parse the HTML with jsoup       Doc doc = Jsoup.parse(html, "");          // assert there are two <li> components contained in the <ul class="todo-list">       var choice = doc.choose("ul.todo-list li");       assertThat(choice).hasSize(2);          // assert the primary <li> textual content is "Foo"       assertThat(choice.get(0).textual content()).isEqualTo("Foo");          // assert the second <li> textual content is "Bar"       assertThat(choice.get(1).textual content()).isEqualTo("Bar");   }

supply

If we nonetheless have not modified the template to populate the record from the
mannequin, this take a look at will fail, as a result of the static template
todo gadgets have completely different textual content:

Go

  --- FAIL: Test_todoItemsAreShown (0.00s)       index_template_test.go:44: First record merchandise: need Foo, bought Style JavaScript       index_template_test.go:49: Second record merchandise: need Bar, bought Purchase a unicorn

Java

  IndexTemplateTest > todoItemsAreShown() FAILED       org.opentest4j.AssertionFailedError:       Anticipating:        <"Style JavaScript">       to be equal to:        <"Foo">       however was not.

We repair it by making the template use the mannequin information:

Go

  <ul class="todo-list">     {{ vary .Gadgets }}       <li>         <div class="view">           <enter class="toggle" kind="checkbox">           <label>{{ .Title }}</label>           <button class="destroy"></button>         </div>       </li>     {{ finish }}   </ul>

supply

Java – jmustache

  <ul class="todo-list">     {{ #allItems }}     <li>       <div class="view">         <enter class="toggle" kind="checkbox">         <label>{{ title }}</label>         <button class="destroy"></button>       </div>     </li>     {{ /allItems }}   </ul>

supply

Check each content material and soundness on the identical time

Our take a look at works, however it’s a bit verbose, particularly the Go model. If we’ll have extra
exams, they’ll grow to be repetitive and troublesome to learn, so we make it extra concise by extracting a helper perform for parsing the html. We additionally take away the
feedback, because the code ought to be clear sufficient

Go

  func Test_todoItemsAreShown(t *testing.T) {     mannequin := todo.NewList()     mannequin.Add("Foo")     mannequin.Add("Bar")        buf := renderTemplate("index.tmpl", mannequin)        doc := parseHtml(t, buf)     choice := doc.Discover("ul.todo-list li")     assert.Equal(t, 2, choice.Size())     assert.Equal(t, "Foo", textual content(choice.Nodes[0]))     assert.Equal(t, "Bar", textual content(choice.Nodes[1]))   }      func parseHtml(t *testing.T, buf bytes.Buffer) *goquery.Doc {     doc, err := goquery.NewDocumentFromReader(bytes.NewReader(buf.Bytes()))     if err != nil {       // if parsing fails, we cease the take a look at right here with t.FatalF       t.Fatalf("Error rendering template %s", err)     }     return doc   } 

Java

  @Check   void todoItemsAreShown() throws IOException {       var mannequin = new TodoList();       mannequin.add("Foo");       mannequin.add("Bar");          var html = renderTemplate("/index.tmpl", mannequin);          var doc = parseHtml(html);       var choice = doc.choose("ul.todo-list li");       assertThat(choice).hasSize(2);       assertThat(choice.get(0).textual content()).isEqualTo("Foo");       assertThat(choice.get(1).textual content()).isEqualTo("Bar");   }      non-public static Doc parseHtml(String html) {       return Jsoup.parse(html, "");   } 

A lot better! At the least in my view. Now that we extracted the parseHtml helper, it is
a good suggestion to examine for sound HTML within the helper:

Go

  func parseHtml(t *testing.T, buf bytes.Buffer) *goquery.Doc {     assertWellFormedHtml(t, buf)     doc, err := goquery.NewDocumentFromReader(bytes.NewReader(buf.Bytes()))     if err != nil {       // if parsing fails, we cease the take a look at right here with t.FatalF       t.Fatalf("Error rendering template %s", err)     }     return doc   }

supply

Java

  non-public static Doc parseHtml(String html) {       var parser = Parser.htmlParser().setTrackErrors(10);       var doc = Jsoup.parse(html, "", parser);       assertThat(parser.getErrors()).isEmpty();       return doc;   }

supply

And with this, we are able to do away with the primary take a look at that we wrote, as we are actually testing for sound HTML on a regular basis.

The second take a look at

Now we’re in an excellent place for testing extra rendering logic. The
second dynamic function in our record is “Listing gadgets ought to get the category
accomplished when marked as accomplished”. We will write a take a look at for this:

Go

  func Test_completedItemsGetCompletedClass(t *testing.T) {     mannequin := todo.NewList()     mannequin.Add("Foo")     mannequin.AddCompleted("Bar")        buf := renderTemplate("index.tmpl", mannequin)        doc := parseHtml(t, buf)     choice := doc.Discover("ul.todo-list li.accomplished")     assert.Equal(t, 1, choice.Measurement())     assert.Equal(t, "Bar", textual content(choice.Nodes[0]))   }

supply

Java

  @Check   void completedItemsGetCompletedClass() {       var mannequin = new TodoList();       mannequin.add("Foo");       mannequin.addCompleted("Bar");          var html = renderTemplate("/index.tmpl", mannequin);          Doc doc = Jsoup.parse(html, "");       var choice = doc.choose("ul.todo-list li.accomplished");       assertThat(choice).hasSize(1);       assertThat(choice.textual content()).isEqualTo("Bar");   }

supply

And this take a look at may be made inexperienced by including this little bit of logic to the
template:

Go

  <ul class="todo-list">     {{ vary .Gadgets }}       <li class="{{ if .IsCompleted }}accomplished{{ finish }}">         <div class="view">           <enter class="toggle" kind="checkbox">           <label>{{ .Title }}</label>           <button class="destroy"></button>         </div>       </li>     {{ finish }}   </ul>

supply

Java – jmustache

  <ul class="todo-list">     {{ #allItems }}     <li class="{{ #isCompleted }}accomplished{{ /isCompleted }}">       <div class="view">         <enter class="toggle" kind="checkbox">         <label>{{ title }}</label>         <button class="destroy"></button>       </div>     </li>     {{ /allItems }}   </ul>

supply

So little by little, we are able to take a look at and add the assorted dynamic options
that our template ought to have.

Make it simple so as to add new exams

The primary of the 20 ideas from the superb discuss by Russ Cox on Go
Testing
is “Make it simple so as to add new take a look at circumstances“. Certainly, in Go there
is a bent to make most exams parameterized, for this very cause.
Alternatively, whereas Java has
good assist
for parameterized exams
with JUnit 5, they aren’t used as a lot.

Since our present two exams have the identical construction, we
may issue them right into a single parameterized take a look at.

A take a look at case for us will encompass:

  • A reputation (in order that we are able to produce clear error messages when the take a look at
    fails)
  • A mannequin (in our case a todo.Listing)
  • A CSS selector
  • A listing of textual content matches that we anticipate finding once we run the CSS
    selector on the rendered HTML.

So that is the info construction for our take a look at circumstances:

Go

  var testCases = []struct {     title     string     mannequin    *todo.Listing     selector string     matches  []string   }{     {       title: "all todo gadgets are proven",       mannequin: todo.NewList().         Add("Foo").         Add("Bar"),       selector: "ul.todo-list li",       matches:  []string{"Foo", "Bar"},     },     {       title: "accomplished gadgets get the 'accomplished' class",       mannequin: todo.NewList().         Add("Foo").         AddCompleted("Bar"),       selector: "ul.todo-list li.accomplished",       matches:  []string{"Bar"},     },   }

supply

Java

  file TestCase(String title,                   TodoList mannequin,                   String selector,                   Listing<String> matches) {       @Override       public String toString() {           return title;       }   }      public static TestCase[] indexTestCases() {       return new TestCase[]{               new TestCase(                       "all todo gadgets are proven",                       new TodoList()                               .add("Foo")                               .add("Bar"),                       "ul.todo-list li",                       Listing.of("Foo", "Bar")),               new TestCase(                       "accomplished gadgets get the 'accomplished' class",                       new TodoList()                               .add("Foo")                               .addCompleted("Bar"),                       "ul.todo-list li.accomplished",                       Listing.of("Bar")),       };   }

supply

And that is our parameterized take a look at:

Go

  func Test_indexTemplate(t *testing.T) {     for _, take a look at := vary testCases {       t.Run(take a look at.title, func(t *testing.T) {         buf := renderTemplate("index.tmpl", take a look at.mannequin)            assertWellFormedHtml(t, buf)         doc := parseHtml(t, buf)         choice := doc.Discover(take a look at.selector)         require.Equal(t, len(take a look at.matches), len(choice.Nodes), "surprising # of matches")         for i, node := vary choice.Nodes {           assert.Equal(t, take a look at.matches[i], textual content(node))         }       })     }   }

supply

Java

  @ParameterizedTest   @MethodSource("indexTestCases")   void testIndexTemplate(TestCase take a look at) {       var html = renderTemplate("/index.tmpl", take a look at.mannequin);          var doc = parseHtml(html);       var choice = doc.choose(take a look at.selector);       assertThat(choice).hasSize(take a look at.matches.dimension());       for (int i = 0; i < take a look at.matches.dimension(); i++) {           assertThat(choice.get(i).textual content()).isEqualTo(take a look at.matches.get(i));       }   }

supply

We will now run our parameterized take a look at and see it move:

Go

  $ go take a look at -v   === RUN   Test_indexTemplate   === RUN   Test_indexTemplate/all_todo_items_are_shown   === RUN   Test_indexTemplate/completed_items_get_the_'accomplished'_class   --- PASS: Test_indexTemplate (0.00s)       --- PASS: Test_indexTemplate/all_todo_items_are_shown (0.00s)       --- PASS: Test_indexTemplate/completed_items_get_the_'accomplished'_class (0.00s)   PASS   okay    tdd-html-templates  0.608s

Java

  $ ./gradlew take a look at      > Activity :take a look at      IndexTemplateTest > testIndexTemplate(TestCase) > [1] all todo gadgets are proven PASSED   IndexTemplateTest > testIndexTemplate(TestCase) > [2] accomplished gadgets get the 'accomplished' class PASSED

Be aware how, by giving a reputation to our take a look at circumstances, we get very readable take a look at output, each on the terminal and within the IDE:

Having rewritten our two outdated exams in desk type, it is now tremendous simple so as to add
one other. That is the take a look at for the “x gadgets left” textual content:

Go

  {     title: "gadgets left",     mannequin: todo.NewList().       Add("One").       Add("Two").       AddCompleted("Three"),     selector: "span.todo-count",     matches:  []string{"2 gadgets left"},   },

supply

Java

  new TestCase(       "gadgets left",       new TodoList()               .add("One")               .add("Two")               .addCompleted("Three"),       "span.todo-count",       Listing.of("2 gadgets left")),

supply

And the corresponding change within the html template is:

Go

  <span class="todo-count"><sturdy>{{len .ActiveItems}}</sturdy> gadgets left</span>

supply

Java – jmustache

  <span class="todo-count"><sturdy>{{activeItemsCount}}</sturdy> gadgets left</span>

supply

The above change within the template requires a supporting methodology within the mannequin:

Go

  kind Merchandise struct {     Title       string     IsCompleted bool   }      kind Listing struct {     Gadgets []*Merchandise   }      func (l *Listing) ActiveItems() []*Merchandise {     var end result []*Merchandise     for _, merchandise := vary l.Gadgets {       if !merchandise.IsCompleted {         end result = append(end result, merchandise)       }     }     return end result   } 

supply

Java

  public class TodoList {       non-public last Listing<TodoItem> gadgets = new ArrayList<>();       // ...       public lengthy activeItemsCount() {           return gadgets.stream().filter(TodoItem::isActive).rely();       }   }

supply

We have invested slightly effort in our testing infrastructure, in order that including new
take a look at circumstances is simpler. Within the subsequent part, we’ll see that the necessities
for the following take a look at circumstances will push us to refine our take a look at infrastructure additional.

Making the desk extra expressive, on the expense of the take a look at code

We are going to now take a look at the “All”, “Lively” and “Accomplished” navigation hyperlinks at
the underside of the UI (see the image above),
and these depend upon which url we’re visiting, which is
one thing that our template has no approach to discover out.

Presently, all we move to our template is our mannequin, which is a todo-list.
It is not appropriate so as to add the at the moment visited url to the mannequin, as a result of that’s
consumer navigation state, not software state.

So we have to move extra info to the template past the mannequin. A straightforward method
is to move a map, which we assemble in our
renderTemplate perform:

Go

  func renderTemplate(mannequin *todo.Listing, path string) bytes.Buffer {     templ := template.Should(template.ParseFiles("index.tmpl"))     var buf bytes.Buffer     information := map[string]any{       "mannequin": mannequin,       "path":  path,     }     err := templ.Execute(&buf, information)     if err != nil {       panic(err)     }     return buf   }

Java

  non-public String renderTemplate(String templateName, TodoList mannequin, String path) {       var template = Mustache.compiler().compile(               new InputStreamReader(                       getClass().getResourceAsStream(templateName)));       var information = Map.of(               "mannequin", mannequin,               "path", path       );       return template.execute(information);   }

And correspondingly our take a look at circumstances desk has yet another area:

Go

  var testCases = []struct {     title     string     mannequin    *todo.Listing     path     string     selector string     matches  []string   }{     {       title: "all todo gadgets are proven",       mannequin: todo.NewList().         Add("Foo").         Add("Bar"),       selector: "ul.todo-list li",       matches:  []string{"Foo", "Bar"},     },   // ... the opposite circumstances     {       title:     "highlighted navigation hyperlink: All",       path:     "/",       selector: "ul.filters a.chosen",       matches:  []string{"All"},     },     {       title:     "highlighted navigation hyperlink: Lively",       path:     "/lively",       selector: "ul.filters a.chosen",       matches:  []string{"Lively"},     },     {       title:     "highlighted navigation hyperlink: Accomplished",       path:     "/accomplished",       selector: "ul.filters a.chosen",       matches:  []string{"Accomplished"},     },   }

Java

  file TestCase(String title,                   TodoList mannequin,                   String path,                   String selector,                   Listing<String> matches) {       @Override       public String toString() {           return title;       }   }      public static TestCase[] indexTestCases() {       return new TestCase[]{               new TestCase(                       "all todo gadgets are proven",                       new TodoList()                               .add("Foo")                               .add("Bar"),                       "/",                       "ul.todo-list li",                       Listing.of("Foo", "Bar")),               // ... the earlier circumstances               new TestCase(                       "highlighted navigation hyperlink: All",                       new TodoList(),                       "/",                       "ul.filters a.chosen",                       Listing.of("All")),               new TestCase(                       "highlighted navigation hyperlink: Lively",                       new TodoList(),                       "/lively",                       "ul.filters a.chosen",                       Listing.of("Lively")),               new TestCase(                       "highlighted navigation hyperlink: Accomplished",                       new TodoList(),                       "/accomplished",                       "ul.filters a.chosen",                       Listing.of("Accomplished")),       };   }

We discover that for the three new circumstances, the mannequin is irrelevant;
whereas for the earlier circumstances, the trail is irrelevant. The Go syntax permits us
to initialize a struct with simply the fields we’re occupied with, however Java doesn’t have
the same function, so we’re pushed to move additional info, and this makes the take a look at circumstances
desk tougher to grasp.

A developer may take a look at the primary take a look at case and marvel if the anticipated conduct relies upon
on the trail being set to "/", and may be tempted so as to add extra circumstances with
a unique path. In the identical method, when studying the
highlighted navigation hyperlink take a look at circumstances, the developer may marvel if the
anticipated conduct relies on the mannequin being set to an empty todo record. In that case, one may
be led so as to add irrelevant take a look at circumstances for the highlighted hyperlink with non-empty todo-lists.

We wish to optimize for the time of the builders, so it is worthwhile to keep away from including irrelevant
information to our take a look at case. In Java we’d move null for the
irrelevant fields, however there’s a greater method: we are able to use
the builder sample,
popularized by Joshua Bloch.
We will rapidly write one for the Java TestCase file this manner:

Java

  file TestCase(String title,                   TodoList mannequin,                   String path,                   String selector,                   Listing<String> matches) {       @Override       public String toString() {           return title;       }          public static last class Builder {           String title;           TodoList mannequin;           String path;           String selector;           Listing<String> matches;              public Builder title(String title) {               this.title = title;               return this;           }              public Builder mannequin(TodoList mannequin) {               this.mannequin = mannequin;               return this;           }              public Builder path(String path) {               this.path = path;               return this;           }              public Builder selector(String selector) {               this.selector = selector;               return this;           }              public Builder matches(String ... matches) {               this.matches = Arrays.asList(matches);               return this;           }              public TestCase construct() {               return new TestCase(title, mannequin, path, selector, matches);           }       }   }

Hand-coding builders is slightly tedious, however doable, although there are
automated methods to jot down them.
Now we are able to rewrite our Java take a look at circumstances with the Builder, to
obtain larger readability:

Java

  public static TestCase[] indexTestCases() {       return new TestCase[]{               new TestCase.Builder()                       .title("all todo gadgets are proven")                       .mannequin(new TodoList()                               .add("Foo")                               .add("Bar"))                       .selector("ul.todo-list li")                       .matches("Foo", "Bar")                       .construct(),               // ... different circumstances               new TestCase.Builder()                       .title("highlighted navigation hyperlink: Accomplished")                       .path("/accomplished")                       .selector("ul.filters a.chosen")                       .matches("Accomplished")                       .construct(),       };   }

So, the place are we with our exams? At current, they fail for the unsuitable cause: null-pointer exceptions
as a result of lacking mannequin and path values.
So as to get our new take a look at circumstances to fail for the appropriate cause, specifically that the template does
not but have logic to focus on the right hyperlink, we should
present default values for mannequin and path. In Go, we are able to do that
within the take a look at methodology:

Go

  func Test_indexTemplate(t *testing.T) {     for _, take a look at := vary testCases {       t.Run(take a look at.title, func(t *testing.T) {         if take a look at.mannequin == nil {           take a look at.mannequin = todo.NewList()         }         buf := renderTemplate(take a look at.mannequin, take a look at.path)         // ... identical as earlier than        })     }   }

supply

In Java, we are able to present default values within the builder:

Java

  public static last class Builder {       String title;       TodoList mannequin = new TodoList();       String path = "/";       String selector;       Listing<String> matches;       // ...   }

supply

With these modifications, we see that the final two take a look at circumstances, those for the highlighted hyperlink Lively
and Accomplished fail, for the anticipated cause that the highlighted hyperlink doesn’t change:

Go

  === RUN   Test_indexTemplate/highlighted_navigation_link:_Active       index_template_test.go:82:              Error Hint:  .../tdd-templates/go/index_template_test.go:82             Error:        Not equal:                            anticipated: "Lively"                           precise  : "All"   === RUN   Test_indexTemplate/highlighted_navigation_link:_Completed       index_template_test.go:82:              Error Hint:  .../tdd-templates/go/index_template_test.go:82             Error:        Not equal:                            anticipated: "Accomplished"                           precise  : "All" 

Java

  IndexTemplateTest > testIndexTemplate(TestCase) > [5] highlighted navigation hyperlink: Lively FAILED       org.opentest4j.AssertionFailedError:       Anticipating:        <"All">       to be equal to:        <"Lively">       however was not.      IndexTemplateTest > testIndexTemplate(TestCase) > [6] highlighted navigation hyperlink: Accomplished FAILED       org.opentest4j.AssertionFailedError:       Anticipating:        <"All">       to be equal to:        <"Accomplished">       however was not.

To make the exams move, we make these modifications to the template:

Go

  <ul class="filters">     <li>       <a class="{{ if eq .path "/" }}chosen{{ finish }}" href="#/">All</a>     </li>     <li>       <a class="{{ if eq .path "/lively" }}chosen{{ finish }}" href="#/lively">Lively</a>     </li>     <li>       <a class="{{ if eq .path "/accomplished" }}chosen{{ finish }}" href="#/accomplished">Accomplished</a>     </li>   </ul>

supply

Java – jmustache

  <ul class="filters">     <li>       <a class="{{ #pathRoot }}chosen{{ /pathRoot }}" href="#/">All</a>     </li>     <li>       <a class="{{ #pathActive }}chosen{{ /pathActive }}" href="#/lively">Lively</a>     </li>     <li>       <a class="{{ #pathCompleted }}chosen{{ /pathCompleted }}" href="#/accomplished">Accomplished</a>     </li>   </ul>

supply

For the reason that Mustache template language doesn’t enable for equality testing, we should change the
information handed to the template in order that we execute the equality exams earlier than rendering the template:

Java

  non-public String renderTemplate(String templateName, TodoList mannequin, String path) {       var template = Mustache.compiler().compile(               new InputStreamReader(                       getClass().getResourceAsStream(templateName)));       var information = Map.of(               "mannequin", mannequin,               "pathRoot", path.equals("/"),               "pathActive", path.equals("/lively"),               "pathCompleted", path.equals("/accomplished")       );       return template.execute(information);   }

supply

And with these modifications, all of our exams now move.

To recap this part, we made the take a look at code slightly bit extra difficult, in order that the take a look at
circumstances are clearer: it is a excellent tradeoff!

Degree 3: testing HTML behaviour

Within the story to this point, we examined the behaviour of the HTML
templates
, by checking the construction of the generated HTML.
That is good, however what if we needed to check the behaviour of the HTML
itself, plus any CSS and JavaScript it could use?

The behaviour of HTML by itself is often fairly apparent, as a result of
there may be not a lot of it. The one components that may work together with the
consumer are the anchor (<a>), <type> and
<enter> components, however the image modifications utterly when
we add CSS, that may disguise, present, transfer round issues and much extra, and
with JavaScript, that may add any behaviour to a web page.

In an software that’s primarily rendered server-side, we count on
that the majority behaviour is applied by returning new HTML with a
round-trip to the consumer, and this may be examined adequately with the
strategies we have seen to this point, however what if we needed to hurry up the
software behaviour with a library corresponding to HTMX? This library works by way of particular
attributes which can be added to components so as to add Ajax behaviour. These
attributes are in impact a DSL that we’d wish to
take a look at.

How can we take a look at the mixture of HTML, CSS and JavaScript in
a unit take a look at?

Testing HTML, CSS and JavaScript requires one thing that is ready to
interpret and execute their behaviours; in different phrases, we want a
browser! It’s customary to make use of headless browsers in end-to-end exams;
can we use them for unitary exams as a substitute? I believe that is attainable,
utilizing the next strategies, though I have to admit I’ve but to attempt
this on an actual mission.

We are going to use the Playwright
library, that’s accessible for each Go and
Java. The exams we
are going to jot down might be slower, as a result of we must wait a couple of
seconds for the headless browser to start out, however will retain among the
vital traits of unit exams, primarily that we’re testing
simply the HTML (and any related CSS and JavaScript), in isolation from
some other server-side logic.

Persevering with with the TodoMVC
instance, the following factor we’d wish to take a look at is what occurs when the
consumer clicks on the checkbox of a todo merchandise. What we might prefer to occur is
that:

  1. A POST name to the server is made, in order that the applying is aware of
    that the state of a todo merchandise has modified
  2. The server returns new HTML for the dynamic a part of the web page,
    specifically the entire part with class “todoapp”, in order that we are able to present the
    new state of the applying together with the rely of remaining “lively”
    gadgets (see the template above)
  3. The web page replaces the outdated contents of the “todoapp” part with
    the brand new ones.

Loading the web page within the Playwright browser

We begin with a take a look at that may simply load the preliminary HTML. The take a look at
is slightly concerned, so I present the whole code right here, after which I’ll
remark it little by little.

Go

  func Test_toggleTodoItem(t *testing.T) {     // render the preliminary HTML     mannequin := todo.NewList().       Add("One").       Add("Two")     initialHtml := renderTemplate("index.tmpl", mannequin, "/")        // open the browser web page with Playwright     web page := openPage()     defer web page.Shut()     logActivity(web page)        // stub community calls     err := web page.Route("**", func(route playwright.Route) {       if route.Request().URL() == "http://localhost:4567/index.html" {         // serve the preliminary HTML         stubResponse(route, initialHtml.String(), "textual content/html")       } else {         // keep away from surprising requests         panic("surprising request: " + route.Request().URL())       }     })     if err != nil {       t.Deadly(err)     }        // load preliminary HTML within the web page     response, err := web page.Goto("http://localhost:4567/index.html")     if err != nil {       t.Deadly(err)     }     if response.Standing() != 200 {       t.Fatalf("surprising standing: %d", response.Standing())     }   }

supply

Java

  public class IndexBehaviourTest {       static Playwright playwright;       static Browser browser;          @BeforeAll       static void launchBrowser() {           playwright = Playwright.create();           browser = playwright.chromium().launch();       }          @AfterAll       static void closeBrowser() {           playwright.shut();       }          @Check       void toggleTodoItem() {           // Render the preliminary html           TodoList mannequin = new TodoList()                   .add("One")                   .add("Two");           String initialHtml = renderTemplate("/index.tmpl", mannequin, "/");                      attempt (Web page web page = browser.newPage()) {               logActivity(web page);                  // stub community calls               web page.route("**", route -> {                   if (route.request().url().equals("http://localhost:4567/index.html")) {                       // serve the preliminary HTML                       route.fulfill(new Route.FulfillOptions()                               .setContentType("textual content/html")                               .setBody(initialHtml));                   } else {                       // we do not need surprising calls                       fail(String.format("Sudden request: %s %s", route.request().methodology(), route.request().url()));                   }               });                          // load preliminary html               web page.navigate("http://localhost:4567/index.html");           }       }   }

supply

Firstly of the take a look at, we initialize the mannequin with two todo
gadgets “One” and “Two”, then we render the template as earlier than:

Go

  mannequin := todo.NewList().     Add("One").     Add("Two")   initialHtml := renderTemplate("index.tmpl", mannequin, "/") 

Java

  TodoList mannequin = new TodoList()           .add("One")           .add("Two");   String initialHtml = renderTemplate("/index.tmpl", mannequin, "/");

Then we open the Playwright “web page”, which can begin a headless
browser

Go

  web page := openPage()   defer web page.Shut()   logActivity(web page) 

Java

  attempt (Web page web page = browser.newPage()) {       logActivity(web page);

The openPage perform in Go returns a Playwright
Web page object,

Go

  func openPage() playwright.Web page {     pw, err := playwright.Run()     if err != nil {       log.Fatalf("couldn't begin playwright: %v", err)     }     browser, err := pw.Chromium.Launch()     if err != nil {       log.Fatalf("couldn't launch browser: %v", err)     }     web page, err := browser.NewPage()     if err != nil {       log.Fatalf("couldn't create web page: %v", err)     }     return web page   }

and the logActivity perform gives suggestions on what
the web page is doing

Go

  func logActivity(web page playwright.Web page) {     web page.OnRequest(func(request playwright.Request) {       log.Printf(">> %s %sn", request.Methodology(), request.URL())     })     web page.OnResponse(func(response playwright.Response) {       log.Printf("<< %d %sn", response.Standing(), response.URL())     })     web page.OnLoad(func(web page playwright.Web page) {       log.Println("Loaded: " + web page.URL())     })     web page.OnConsole(func(message playwright.ConsoleMessage) {       log.Println("!  " + message.Textual content())     })   }

Java

  non-public void logActivity(Web page web page) {       web page.onRequest(request -> System.out.printf(">> %s %spercentn", request.methodology(), request.url()));       web page.onResponse(response -> System.out.printf("<< %s %spercentn", response.standing(), response.url()));       web page.onLoad(page1 -> System.out.println("Loaded: " + page1.url()));       web page.onConsoleMessage(consoleMessage -> System.out.println("!  " + consoleMessage.textual content()));   }

Then we stub all community exercise that the web page may attempt to do

Go

  err := web page.Route("**", func(route playwright.Route) {     if route.Request().URL() == "http://localhost:4567/index.html" {       // serve the preliminary HTML       stubResponse(route, initialHtml.String(), "textual content/html")     } else {       // keep away from surprising requests       panic("surprising request: " + route.Request().URL())     }   }) 

Java

  // stub community calls   web page.route("**", route -> {       if (route.request().url().equals("http://localhost:4567/index.html")) {           // serve the preliminary HTML           route.fulfill(new Route.FulfillOptions()                   .setContentType("textual content/html")                   .setBody(initialHtml));       } else {           // we do not need surprising calls           fail(String.format("Sudden request: %s %s", route.request().methodology(), route.request().url()));       }   });

and we ask the web page to load the preliminary HTML

Go

  response, err := web page.Goto("http://localhost:4567/index.html") 

Java

  web page.navigate("http://localhost:4567/index.html");

With all this equipment in place, we run the take a look at; it succeeds and
it logs the stubbed community exercise on customary output:

Go

  === RUN   Test_toggleTodoItem   >> GET http://localhost:4567/index.html   << 200 http://localhost:4567/index.html   Loaded: http://localhost:4567/index.html   --- PASS: Test_toggleTodoItem (0.89s)

Java

  IndexBehaviourTest > toggleTodoItem() STANDARD_OUT       >> GET http://localhost:4567/index.html       << 200 http://localhost:4567/index.html       Loaded: http://localhost:4567/index.html      IndexBehaviourTest > toggleTodoItem() PASSED

So with this take a look at we are actually capable of load arbitrary HTML in a
headless browser. Within the subsequent sections we’ll see how you can simulate consumer
interplay with components of the web page, and observe the web page’s
behaviour. However first we have to resolve an issue with the shortage of
identifiers in our area mannequin.

Figuring out todo gadgets

Now we wish to click on on the “One” checkbox. The issue now we have is
that at current, now we have no approach to determine particular person todo gadgets, so
we introduce an Id area within the todo merchandise:

Go – up to date mannequin with Id

  kind Merchandise struct {     Id          int     Title       string     IsCompleted bool   }      func (l *Listing) AddWithId(id int, title string) *Listing {     merchandise := Merchandise{       Id:    id,       Title: title,     }     l.Gadgets = append(l.Gadgets, &merchandise)     return l   }      // Add creates a brand new todo.Merchandise with a random Id   func (l *Listing) Add(title string) *Listing {     merchandise := Merchandise{       Id:    generateRandomId(),       Title: title,     }     l.Gadgets = append(l.Gadgets, &merchandise)     return l   }      func generateRandomId() int {     return abs(rand.Int())   }

Java – up to date mannequin with Id

  public class TodoList {       non-public last Listing<TodoItem> gadgets = new ArrayList<>();          public TodoList add(String title) {           gadgets.add(new TodoItem(generateRandomId(), title, false));           return this;       }          public TodoList addCompleted(String title) {           gadgets.add(new TodoItem(generateRandomId(), title, true));           return this;       }          public TodoList add(int id, String title) {           gadgets.add(new TodoItem(id, title, false));           return this;       }          non-public static int generateRandomId() {           return new Random().nextInt(0, Integer.MAX_VALUE);       }   }      public file TodoItem(int id, String title, boolean isCompleted) {       public boolean isActive() {           return !isCompleted;       }   }

And we replace the mannequin in our take a look at so as to add express Ids

Go – including Id within the take a look at information

  func Test_toggleTodoItem(t *testing.T) {     // render the preliminary HTML     mannequin := todo.NewList().       AddWithId(101, "One").       AddWithId(102, "Two")     initialHtml := renderTemplate("index.tmpl", mannequin, "/")     // ...    }

Java – including Id within the take a look at information

  @Check   void toggleTodoItem() {       // Render the preliminary html       TodoList mannequin = new TodoList()               .add(101, "One")               .add(102, "Two");       String initialHtml = renderTemplate("/index.tmpl", mannequin, "/");   }

We are actually prepared to check consumer interplay with the web page.

Clicking on a todo merchandise

We wish to simulate consumer interplay with the HTML web page. It may be
tempting to proceed to make use of CSS selectors to determine the particular
checkbox that we wish to click on, however there’s a greater method: there’s a
consensus amongst front-end builders that one of the best ways to check
interplay with a web page is to make use of it
the identical method that customers do
. As an example, you do not search for a
button by way of a CSS locator corresponding to button.purchase; as a substitute,
you search for one thing clickable with the label “Purchase”. In apply,
this implies figuring out elements of the web page by way of their
ARIA
roles.

To this finish, we add code to our take a look at to search for a checkbox labelled
“One”:

Go

  func Test_toggleTodoItem(t *testing.T) {     // ...     // click on on the "One" checkbox     checkbox := web page.GetByRole(*playwright.AriaRoleCheckbox, playwright.PageGetByRoleOptions{Identify: "One"})     if err := checkbox.Click on(); err != nil {       t.Deadly(err)     }   }

Java

  @Check   void toggleTodoItem() {           // ...           // click on on the "One" checkbox           var checkbox = web page.getByRole(AriaRole.CHECKBOX, new Web page.GetByRoleOptions().setName("One"));           checkbox.click on();       }   }

We run the take a look at, and it fails:

Go

  >> GET http://localhost:4567/index.html   << 200 http://localhost:4567/index.html   Loaded: http://localhost:4567/index.html   --- FAIL: Test_toggleTodoItem (32.74s)       index_behaviour_test.go:50: playwright: timeout: Timeout 30000ms exceeded.

Java

  IndexBehaviourTest > toggleTodoItem() STANDARD_OUT       >> GET http://localhost:4567/index.html       << 200 http://localhost:4567/index.html       Loaded: http://localhost:4567/index.html      IndexBehaviourTest > toggleTodoItem() FAILED       com.microsoft.playwright.TimeoutError: Error {         message="hyperlink the label to the checkbox correctly: 

generated HTML with dangerous accessibility

  <li>     <div class="view">       <enter class="toggle" kind="checkbox">       <label>One</label>       <button class="destroy"></button>     </div>   </li>

We repair it through the use of the for attribute within the
template,

index.tmpl – Go

  <li>     <div class="view">       <enter id="checkbox-{{.Id}}" class="toggle" kind="checkbox">       <label for="checkbox-{{.Id}}">{{.Title}}</label>       <button class="destroy"></button>     </div>   </li>

index.tmpl – Java

  <li>     <div class="view">       <enter id="checkbox-{{ id }}" class="toggle" kind="checkbox">       <label for="checkbox-{{ id }}">{{ title }}</label>       <button class="destroy"></button>     </div>   </li>

In order that it generates correct, accessible HTML:

generated HTML with higher accessibility

  <li>     <div class="view">       <enter id="checkbox-101" class="toggle" kind="checkbox">       <label for="checkbox-101">One</label>       <button class="destroy"></button>     </div>   </li>

We run once more the take a look at, and it passes.

On this part we noticed how testing the HTML in the identical was as customers
work together with it led us to make use of ARIA roles, which led to enhancing
accessibility of our generated HTML. Within the subsequent part, we'll see
how you can take a look at that the clicking on a todo merchandise triggers a distant name to the
server, that ought to lead to swapping part of the present HTML with
the HTML returned by the XHR name.

Spherical-trip to the server

Now we’ll prolong our take a look at. We inform the take a look at that if name to
POST /toggle/101 is obtained, it ought to return some
stubbed HTML.

Go

  } else if route.Request().URL() == "http://localhost:4567/toggle/101" && route.Request().Methodology() == "POST" {     // we count on {that a} POST /toggle/101 request is made once we click on on the "One" checkbox     const stubbedHtml = `       <part class="todoapp">         <p>Stubbed html</p>       </part>`     stubResponse(route, stubbedHtml, "textual content/html")

Java

  } else if (route.request().url().equals("http://localhost:4567/toggle/101") && route.request().methodology().equals("POST")) {       // we count on {that a} POST /toggle/101 request is made once we click on on the "One" checkbox       String stubbedHtml = """           <part class="todoapp">               <p>Stubbed html</p>           </part>           """;       route.fulfill(new Route.FulfillOptions()               .setContentType("textual content/html")               .setBody(stubbedHtml));

And we stub the loading of the HTMX library, which we load from a
native file:

Go

  } else if route.Request().URL() == "https://unpkg.com/htmx.org@1.9.12" {     // serve the htmx library     stubResponse(route, readFile("testdata/htmx.min.js"), "software/javascript")

Go

  } else if (route.request().url().equals("https://unpkg.com/htmx.org@1.9.12")) {       // serve the htmx library       route.fulfill(new Route.FulfillOptions()               .setContentType("textual content/html")               .setBody(readFile("/htmx.min.js")));

Lastly, we add the expectation that, after we click on the checkbox,
the part of the HTML that incorporates many of the software is
reloaded.

Go

  // click on on the "One" checkbox   checkbox := web page.GetByRole(*playwright.AriaRoleCheckbox, playwright.PageGetByRoleOptions{Identify: "One"})   if err := checkbox.Click on(); err != nil {     t.Deadly(err)   }   // examine that the web page has been up to date   doc := parseHtml(t, content material(t, web page))   components := doc.Discover("physique > part.todoapp > p")   assert.Equal(t, "Stubbed html", components.Textual content(), should(web page.Content material())) 

java

  // click on on the "One" checkbox   var checkbox = web page.getByRole(AriaRole.CHECKBOX, new Web page.GetByRoleOptions().setName("One"));   checkbox.click on();   // examine that the web page has been up to date   var doc = parseHtml(web page.content material());   var components = doc.choose("physique > part.todoapp > p");   assertThat(components.textual content())           .describedAs(web page.content material())           .isEqualTo("Stubbed html");

We run the take a look at, and it fails, as anticipated. So as to perceive
why precisely it fails, we add to the error message the entire HTML
doc.

Go

  assert.Equal(t, "Stubbed html", components.Textual content(), should(web page.Content material())) 

Java

  assertThat(components.textual content())           .describedAs(web page.content material())           .isEqualTo("Stubbed html");

The error message may be very verbose, however we see that the explanation it
fails is that we do not see the stubbed HTML within the output. This implies
that the web page didn’t make the anticipated XHR name.

Go – Java is analogous

  --- FAIL: Test_toggleTodoItem (2.75s)   === RUN   Test_toggleTodoItem   >> GET http://localhost:4567/index.html   << 200 http://localhost:4567/index.html   Loaded: http://localhost:4567/index.html       index_behaviour_test.go:67:             Error Hint:  .../index_behaviour_test.go:67             Error:        Not equal:                           anticipated: "Stubbed html"                           precise  : ""                           ...             Check:         Test_toggleTodoItem             Messages:     <!DOCTYPE html><html lang="en"><head>                               <meta charset="utf-8">                               <meta title="viewport" content material="width=device-width, initial-scale=1">                               <title>Template • TodoMVC</title>                               <script src="https://unpkg.com/htmx.org@1.9.12"></script>                             <physique>                               <part class="todoapp">                           ...                                     <li class="">                                       <div class="view">                                         <enter id="checkbox-101" class="toggle" kind="checkbox">                                         <label for="checkbox-101">One</label>                                         <button class="destroy"></button>                                       </div>                                     </li>                           ...

We will make this take a look at move by altering the HTML template to make use of HTMX
to make an XHR name again to the server. First we load the HTMX
library:

index.tmpl

  <title>Template • TodoMVC</title>   <script src="https://unpkg.com/htmx.org@1.9.12"></script> 

Then we add the HTMX attributes to the checkboxes:

index.tmpl

  <enter       data-hx-post="/toggle/{{.Id}}"       data-hx-target="part.todoapp"       id="checkbox-{{.Id}}"       class="toggle"       kind="checkbox">

The data-hx-post annotation will make HTMX do a POST
name to the required url. The data-hx-target tells HTMX
to repeat the HTML returned by the decision, to the component specified by the
part.todoapp CSS locator.

We run once more the take a look at, and it nonetheless fails!

Go – Java is analogous

  --- FAIL: Test_toggleTodoItem (2.40s)   === RUN   Test_toggleTodoItem   >> GET http://localhost:4567/index.html   << 200 http://localhost:4567/index.html   >> GET https://unpkg.com/htmx.org@1.9.12   << 200 https://unpkg.com/htmx.org@1.9.12   Loaded: http://localhost:4567/index.html   >> POST http://localhost:4567/toggle/101   << 200 http://localhost:4567/toggle/101       index_behaviour_test.go:67:             Error Hint:  .../index_behaviour_test.go:67             Error:        Not equal:                           anticipated: "Stubbed html"                           precise  : ""                           ...             Check:         Test_toggleTodoItem             Messages:     <!DOCTYPE html><html lang="en"><head>                               <meta charset="utf-8">                               <meta title="viewport" content material="width=device-width, initial-scale=1">                               <title>Template • TodoMVC</title>                               <script src="https://unpkg.com/htmx.org@1.9.12"></script>                           ...                             <physique>                               <part class="todoapp"><part class="todoapp">                                     <p>Stubbed html</p>                                   </part></part>                           ...                           </physique></html>

The log strains present that the POST name occurred as anticipated, however
examination of the error message reveals that the HTML construction we
anticipated just isn’t there: now we have a part.todoapp nested
inside one other. Because of this we aren’t utilizing the HTMX annotations
accurately, and reveals why this type of take a look at may be beneficial. We add the
lacking annotation

index.tmpl

  <enter       data-hx-post="/toggle/{{.Id}}"       data-hx-target="part.todoapp"       data-hx-swap="outerHTML"       id="checkbox-{{.Id}}"       class="toggle"       kind="checkbox">

The default behaviour of HTMX is to switch the internal HTML of the
goal component. The data-hx-swap="outerHTML" annotation
tells HTMX to switch the outer HTML as a substitute.

and we take a look at once more, and this time it passes!

Go

  === RUN   Test_toggleTodoItem   >> GET http://localhost:4567/index.html   << 200 http://localhost:4567/index.html   >> GET https://unpkg.com/htmx.org@1.9.12   << 200 https://unpkg.com/htmx.org@1.9.12   Loaded: http://localhost:4567/index.html   >> POST http://localhost:4567/toggle/101   << 200 http://localhost:4567/toggle/101   --- PASS: Test_toggleTodoItem (1.39s)

Java

  IndexBehaviourTest > toggleTodoItem() STANDARD_OUT       >> GET http://localhost:4567/index.html       << 200 http://localhost:4567/index.html       >> GET https://unpkg.com/htmx.org@1.9.12       << 200 https://unpkg.com/htmx.org@1.9.12       Loaded: http://localhost:4567/index.html       >> POST http://localhost:4567/toggle/101       << 200 http://localhost:4567/toggle/101      IndexBehaviourTest > toggleTodoItem() PASSED

On this part we noticed how you can write a take a look at for the behaviour of our
HTML that, whereas utilizing the difficult equipment of a headless browser,
nonetheless feels extra like a unit take a look at than an integration take a look at. It’s in
truth testing simply an HTML web page with any related CSS and JavaScript,
in isolation from different elements of the applying corresponding to controllers,
companies or repositories.

The take a look at prices 2-3 seconds of ready time for the headless browser to return up, which is often an excessive amount of for a unit take a look at; nevertheless, like a unit take a look at, it is rather secure, as it’s not flaky, and its failures are documented with a comparatively clear error message.

See the ultimate model of the take a look at in Go and in Java.

Bonus stage: Stringly asserted

Esko Luontola, TDD skilled and writer of the net course tdd.mooc.fi, recommended an alternate to testing HTML with CSS selectors: the concept is to rework HTML right into a human-readable canonical type.

Let’s take for instance this snippet of generated HTML:

<ul class="todo-list">   <li class="">     <div class="view">       <enter id="checkbox-100" class="toggle" kind="checkbox">       <label for="checkbox-100">One</label>       <button class="destroy"></button>     </div>   </li>   <li class="">     <div class="view">       <enter id="checkbox-200" class="toggle" kind="checkbox">       <label for="checkbox-200">Two</label>       <button class="destroy"></button>     </div>   </li>   <li class="accomplished">     <div class="view">       <enter id="checkbox-300" class="toggle" kind="checkbox">       <label for="checkbox-300">Three</label>       <button class="destroy"></button>     </div>   </li> </ul> 

We may visualize the above HTML by:

  1. deleting all HTML tags
  2. decreasing each sequence of whitespace characters to a single clean

to reach at:

One Two Three

This, nevertheless, removes an excessive amount of of the HTML construction to be helpful. As an example, it doesn’t allow us to distinguish between lively and accomplished gadgets. Some HTML component symbolize seen content material: as an illustration

<enter worth="foo" />

reveals a textual content field with the phrase “foo” that is a crucial a part of the method we understand HTML. To visualise these components, Esko suggests so as to add a data-test-icon attribute that provides some textual content for use instead of the component when visualizing it for testing. With this,

<enter worth="foo" data-test-icon="[foo]" />

the enter component is visualized as [foo], with the sq. brackets hinting that the phrase “foo” sits inside an editable textual content field. Now if we add test-icons to our HTML template,

Go — Java is analogous

  <ul class="todo-list">       {{ vary .mannequin.AllItems }}       <li class="{{ if .IsCompleted }}accomplished{{ finish }}">           <div class="view">               <enter data-hx-post="/toggle/{{ .Id }}"                      data-hx-target="part.todoapp"                      data-hx-swap="outerHTML"                      id="checkbox-{{ .Id }}"                      class="toggle"                      kind="checkbox"                      data-test-icon="{{ if .IsCompleted }}✅{{ else }}⬜{{ finish }}">               <label for="checkbox-{{ .Id }}">{{ .Title }}</label>               <button class="destroy" data-test-icon="❌️"></button>           </div>       </li>       {{ finish }}   </ul>

we are able to assert in opposition to its canonical visible illustration like this:

Go

  func Test_visualize_html_example(t *testing.T) {     mannequin := todo.NewList().       Add("One").       Add("Two").       AddCompleted("Three")        buf := renderTemplate("todo-list.tmpl", mannequin, "/")        anticipated := `       ⬜ One ❌️       ⬜ Two ❌️       ✅ Three ❌️       `     assert.Equal(t, normalizeWhitespace(anticipated), visualizeHtml(buf.String()))   }

Java

  @Check   void visualize_html_example() {       var mannequin = new TodoList()               .add("One")               .add("Two")               .addCompleted("Three");          var html = renderTemplate("/todo-list.tmpl", mannequin, "/");          assertThat(visualizeHtml(html))               .isEqualTo(normalizeWhitespace("""                       ⬜ One ❌️                       ⬜ Two ❌️                       ✅ Three ❌️                       """));   }

Right here is Esko Luontola’s Java implementation of the 2 features that make this attainable, and my translation to Go of his code.

Go

  func visualizeHtml(html string) string abbr      func normalizeWhitespace(s string) string {     return strings.TrimSpace(replaceAll(s, "s+", " "))   }      func replaceAll(src, regex, repl string) string {     re := regexp.MustCompile(regex)     return re.ReplaceAllString(src, repl)   }

supply

Java

  public static String visualizeHtml(String html) tt)b.*?>", "") // inline components              .replaceAll("<[^>]*>", " ");  // block components      // substitute HTML character entities      html = html.replaceAll("&nbsp;", " ")              .replaceAll("&lt;", "<") // have to be after stripping HTML tags, to keep away from creating unintended components              .replaceAll("&gt;", ">")              .replaceAll("&quot;", """)              .replaceAll("&apos;", "'")              .replaceAll("&amp;", "&"); // have to be final, to keep away from creating unintended character entities      return normalizeWhitespace(html);         public static String normalizeWhitespace(String s) {      return s.replaceAll("s+", " ").trim();   }

supply

On this part, now we have seen a method for asserting HTML content material that’s an alternative choice to the CSS selector-based approach utilized in the remainder of the article. Esko Luontola has reported nice success with it, and I hope readers have success with it too!

This method of asserting in opposition to giant, difficult information constructions corresponding to HTML pages by decreasing them to a canonical string model has no title that I do know of. Martin Fowler recommended “stringly asserted”, and from his suggestion comes the title of this part.

Modeling Extraordinarily Giant Photos with xT – The Berkeley Synthetic Intelligence Analysis Weblog


As laptop imaginative and prescient researchers, we consider that each pixel can inform a narrative. Nonetheless, there appears to be a author’s block settling into the sector with regards to coping with giant photos. Giant photos are not uncommon—the cameras we feature in our pockets and people orbiting our planet snap photos so massive and detailed that they stretch our present greatest fashions and {hardware} to their breaking factors when dealing with them. Typically, we face a quadratic improve in reminiscence utilization as a operate of picture dimension.

In the present day, we make one among two sub-optimal decisions when dealing with giant photos: down-sampling or cropping. These two strategies incur vital losses within the quantity of data and context current in a picture. We take one other take a look at these approaches and introduce $x$T, a brand new framework to mannequin giant photos end-to-end on up to date GPUs whereas successfully aggregating international context with native particulars.



Structure for the $x$T framework.

BVLOS Pipeline Inspections: Avisight, Occasion 38 and Elsight

0

New Connectivity Options Drive Effectivity in Difficult Terrains

Occasion 38 Unmanned Programs, a number one producer of unmanned aerial automobiles, and AviSight, a important infrastructure inspection supplier, have introduced their collaboration with Elsight to combine its AI-based UAV connectivity answer, Halo, into their operations. This partnership goals to reinforce past visual-line-of-sight (BVLOS) inspections for intensive oil and fuel pipeline monitoring over troublesome terrain.

Elsight’s Halo is a light-weight and dependable communications system. Halo makes use of AI-based software program to combination a number of IP hyperlinks right into a safe bond utilizing private and non-private mobile, satellite tv for pc, and RF applied sciences. This ensures uninterrupted drone communications even in probably the most difficult environments, facilitating steady transmission of high-bandwidth video and information to the command-and-control heart (C2).

Elsight Halo

AviSight’s CEO, Suzanne Herring, emphasised the significance of connectivity of their operations: “AviSight’s repute relies on our potential to supply correct, well timed and constantly important infrastructure inspections by the usage of unmanned ariel methods in an economical method. In a know-how market that’s quickly creating, it’s important to stay progressive in our methods methodology whereas additionally embodying the challenges of an environment friendly execution of the mission. With C2 linkage being a main precedence for our BVLOS missions, it was important to discover a companion with the capabilities to take care of communications all through our risky terrains. Elsight has offered us with the flexibility to take care of C2 by huge wetlands, mountainous areas, and distant areas. Whereas Occasion 38’s E455 has given us the flexibility to fly intensive linear inspections effectively and extra affordably.”

The E455, Occasion 38’s newest VTOL drone, is a fixed-wing, vertical takeoff and touchdown plane weighing 55lbs. It presents a 2.5-hour flight endurance on battery energy alone and is able to carrying numerous payloads, together with mapping sensors, LiDAR, and EO/IR surveillance sensors. This versatility meets the strict calls for of assorted purposes, together with prolonged pipeline inspections.

BVLOS Pipeline Inspections: Avisight, Occasion 38 and Elsight

Jeff Taylor, CEO of Occasion 38 Unmanned Programs, highlighted the importance of this integration: “The excessive bandwidth and low energy utilization of the Elsight Halo paired with the E455 open infinite prospects of inspections over lengthy distances and rugged terrain that weren’t doable beforehand. Our E455 VTOL was capable of get nearer to the pipelines with the assistance of Elsight.”

Yoav Amitai, CEO of Elsight, commented on the collaboration: “Working with Occasion 38 and AviSight has been very fulfilling from each technological and enterprise views. Our Halo was designed for mission-critical objectives, significantly, in troublesome conditions. Elsight optimizes the usage of drones in lots of industries with dependable BVLOS connectivity for operational effectiveness. On the identical time, we allow trade progress by utilizing just one operator to regulate a drone fleet from distant areas anyplace. That is how we see our Halo as a market catalyst for drones in pipelines, and inspections in lots of industries, through which eradicating the human component delivers higher and safer outcomes.”

Learn extra:

 

 

Congratulations to the #ICRA2024 finest paper winners

0

The 2024 IEEE Worldwide Convention on Robotics and Automation (ICRA) finest paper winners and finalists within the numerous totally different classes have been introduced. The recipients have been revealed throughout an award luncheon on the convention, which came about from 13-17 Might in Yokohama, Japan.


IEEE ICRA Finest Paper Award in Automation

Winner

TinyMPC: Mannequin-Predictive Management on Useful resource-Constrained Microcontrollers, Anoushka Alavilli, Khai Nguyen, Samuel Schoedel, Brian Plancher, and Zachary Manchester

Finalists

  • A Movable Microfluidic Chip with Hole Impact for Manipulation of Oocytes, Shuzhang Liang, Satoshi Amaya, Hirotaka Sugiura, Hao Mo, Yuguo Dai, and Fumihito Arai
  • Beneath Stress: Studying-Primarily based Analog Gauge Studying within the Wild, Maurits Reitsma, Julian Keller, Kenneth Blomqvist, and Roland Siegwart
  • Environment friendly Composite Studying Robotic Management Beneath Partial Interval Excitation, Tian Shi, Weibing Li, Haoyong Yu, and Yongping Pan
  • MORALS: Evaluation of Excessive-Dimensional Robotic Controllers by way of Topological Instruments in a Latent Area, Ewerton Vieira, Aravind Sivaramakrishnan, Sumanth Tangirala, Edgar Granados, Konstantin Mischaikow, and Kostas E. Bekris

IEEE ICRA Finest Paper Award in Cognitive Robotics

Winner

VLFM: Imaginative and prescient-Language Frontier Maps for Semantic Navigation, Naoki Yokoyama, Sehoon Ha, Dhruv Batra, Jiuguang Wang, and Bernadette Bucher

Finalists

  • NoMaD: Objective Masked Diffusion Insurance policies for Navigation and Exploration, Ajay Sridhar, Dhruv Shah, Catherine Glossop, and Sergey Levine
  • Resilient Legged Native Navigation: Studying to Traverse with Compromised Notion Finish-to-Finish, Chong Zhang, Jin Jin, Jonas Frey, Nikita Rudin, Matias Mattamala, Cesar Cadena Lerma, and Marco Hutter
  • Studying Steady Management with Geometric Regularity from Robotic Intrinsic Symmetry, Shengchao Yan, Baohe Zhang, Yuan Zhang, Joschka Boedecker, and Wolfram Burgard
  • Studying Imaginative and prescient-Primarily based Bipedal Locomotion for Difficult Terrain, Helei Duan, Bikram Pandit, Mohitvishnu S. Gadde, Bart Jaap Van Marum, Jeremy Dao, Chanho Kim, and Alan Fern

IEEE ICRA Finest Paper Award in Robotic Manipulation

Winner

SARA-RT: Scaling up Robotics Transformers with Self-Adaptive Strong Consideration, Isabel Leal, Krzysztof Choromanski, Deepali Jain, Avinava Dubey, Jacob Varley, Michael S. Ryoo, Yao Lu, Frederick Liu, Vikas Sindhwani, Tamas Sarlos, Kenneth Oslund, Karol Hausman, Quan Vuong, and Kanishka Rao

Finalists

  • Open X-Embodiment: Robotic Studying Datasets and RT-X Fashions, Sergey Levine, Chelsea Finn, Ken Goldberg, Lawrence Yunliang Chen, Gaurav Sukhatme, Shivin Dass, Lerrel Pinto, Yuke Zhu, Yifeng Zhu, Shuran Music, Oier Mees, Deepak Pathak, Hao-Shu Fang, Henrik Iskov Christensen, Mingyu Ding, Youngwoon Lee, Dorsa Sadigh, Ilija Radosavovic, Jeannette Bohg, Xiaolong Wang, Xuanlin Li, Krishan Rana, Kento Kawaharazuka, Tatsuya Matsushima, Jihoon Oh, Takayuki Osa, Oliver Kroemer, Beomjoon Kim, Edward Johns, Freek Stulp, Jan Schneider, Jiajun Wu, Yunzhu Li, Heni Ben Amor, Lionel Ott, Roberto Martin-Marin, Karol Hausman, Quan Vuong, Pannag Sanketi, Nicolas Heess, Vincent Vanhoucke, Karl Pertsch, Stefan Schaal, Cheng Chi, Chuer Pan, and Alex Bewley
  • In the direction of Generalizable Zero-Shot Manipulation by way of Translating Human Interplay Plans, Homanga Bharadhwaj, Abhinav Gupta, Vikash Kumar, and Shubham Tulsiani
  • Listening to Contact: Audio-Visible Pretraining for Contact-Wealthy Manipulation, Jared Mejia, Victoria Dean, Tess Hellebrekers, and Abhinav Gupta
  • DenseTact-Mini: An Optical Tactile Sensor for Greedy Multi-Scale Objects From Flat Surfaces, Gained Kyung Do, Ankush Ankush Dhawan, Mathilda Kitzmann, and Monroe Kennedy
  • Constrained Bimanual Planning with Analytic Inverse Kinematics, Thomas Cohn, Seiji Shaw, Max Simchowitz, and Russ Tedrake

IEEE ICRA Finest Paper Award on Human-Robotic Interplay

Winner

CoFRIDA: Self-Supervised Effective-Tuning for Human-Robotic Co-Portray, Peter Schaldenbrand, Gaurav Parmar, Jun-Yan Zhu, James Mccann, and Jean Oh

Finalists

  • POLITE: Preferences Mixed with Highlights in Reinforcement Studying, Simon Holk, Daniel Marta, and Iolanda Leite
  • MateRobot: Materials Recognition in Wearable Robotics for Individuals with Visible Impairments, Junwei Zheng, Jiaming Zhang, Kailun Yang, Kunyu Peng, and Rainer Stiefelhagen
  • Robotic-Assisted Navigation for Visually Impaired by means of Adaptive Impedance and Path Planning, Pietro Balatti, Idil Ozdamar, Doganay Sirintuna, Luca Fortini, Mattia Leonori, Juan M. Gandarias, and Arash Ajoudani
  • Incremental Studying of Full-Pose By way of-Level Motion Primitives on Riemannian Manifolds, Tilman Daab, Noémie Jaquier, Christian R. G. Dreher, Andre Meixner, Franziska Krebs, and Tamim Asfour
  • Supernumerary Robotic Limbs to Help Submit-Fall Recoveries for Astronauts, Erik Ballesteros, Sang-Yoep Lee, Kalind Carpenter, and Harry Asada

IEEE ICRA Finest Paper Award in Medical Robotics

Winner

Exoskeleton-Mediated Bodily Human-Human Interplay for a Sit-to-Stand Rehabilitation Activity, Lorenzo Vianello, Emek Baris Kucuktabak, Matthew Quick, Clément Lhoste, Lorenzo Amato, Kevin Lynch, and Jose L. Pons

Finalists

  • Intraoperatively Iterative Hough Rework Primarily based In-plane Hybrid Management of Arterial Robotic Ultrasound for Magnetic Catheterization, Zhengyang Li, Magejiang Yeerbulati, and Qingsong Xu
  • Environment friendly Mannequin Studying and Adaptive Monitoring Management of Magnetic Micro-Robots for Non-Contact Manipulation, Yongyi Jia, Shu Miao, Junjian Zhou, Niandong Jiao, Lianqing Liu, and Xiang Li
  • Colibri5: Actual-Time Monocular 5-DoF Trocar Pose Monitoring for Robotic-Assisted Vitreoretinal Surgical procedure, Shervin Dehghani, Michael Sommersperger, Mahdi Saleh, Alireza Alikhani, Benjamin Busam, Peter Gehlbach, Ioan Iulian Iordachita, Nassir Navab, and M. Ali Nasseri
  • Hybrid Volitional Management of a Robotic Transtibial Prosthesis utilizing a Section Variable Impedance Controller, Ryan Posh, Jonathan Allen Tittle, David Kelly, James Schmiedeler, and Patrick M. Wensing
  • Design and Implementation of a Robotized Hand-held Dissector for Endoscopic Pulmonary Endarterectomy, Runfeng Zhu, Xilong Hou, Wei Huang, Lei Du, Zhong Wu, Hongbin Liu, Henry Chu, and Qing Xiang Zhao

IEEE ICRA Finest Paper Award on Mechanisms and Design

Winner

Design and Modeling of a Nested Bi-cavity-based Gentle Rising Robotic for Greedy in Constrained Environments, Haochen Yong, Fukang Xu, Chenfei Li, Han Ding, and Zhigang Wu

Finalists

  • Optimized Design and Fabrication of Skeletal Muscle Actuators for Bio-syncretic Robots, Lianchao Yang, Chuang Zhang, Ruiqian Wang, Yiwei Zhang, and Lianqing Liu
  • Lissajous Curve-Primarily based Vibrational Orbit Management of a Versatile Vibrational Actuator with a Structural Anisotropy, Yuto Miyazaki and Mitsuru Higashimori
  • Dynamic Modeling of Wing-Assisted Inclined Operating with a Morphing Multi-Modal Robotic, Eric Sihite, Alireza Ramezani, and Gharib Morteza

IEEE ICRA Finest Paper Award on Multi-Robotic Methods

Winner

Do We Run Giant-Scale Multi-Robotic Methods on the Edge? Extra Proof for Two-Section Efficiency in System Dimension Scaling, Jonas Kuckling, Robin Luckey, Viktor Avrutin, Andrew Vardy, Andreagiovanni Reina, and Heiko Hamann

Finalists

  • Observer-based Distributed MPC for Collaborative Quadrotor-Quadruped Manipulation of a Cable-Towed Load, Shaohang Xu, Yi’An Wang, Wentao Zhang, Chin Pang Ho, and Lijun Zhu
  • Studying for Dynamic Subteaming and Voluntary Ready in Heterogeneous Multi-Robotic Collaborative Scheduling, Williard Joshua Jose and Hao Zhang
  • Asynchronous Distributed Smoothing and Mapping by way of On-Manifold Consensus ADMM, Daniel Mcgann, Kyle Lassak, and Michael Kaess
  • Uncertainty-Bounded Lively Monitoring of Unknown Dynamic Targets in Street-Networks with Minimal Fleet, Shuaikang Wang, Yiannis Kantaros, and Meng Guo

IEEE ICRA Finest Paper Award in Service Robotics

Winner

Studying to Stroll in Confined Areas Utilizing 3D Illustration, Takahiro Miki, Joonho Lee, Lorenz Wellhausen, and Marco Hutter

Finalists

  • Censible: A Strong and Sensible World Localization Framework for Planetary Floor Missions, Jeremy Nash, Quintin Dwight, Lucas Saldyt, Haoda Wang, Steven Myint, Adnan Ansar, and Vandi Verma
  • Environment friendly and Correct Transformer-Primarily based 3D Form Completion and Reconstruction of Fruits for Agricultural Robots, Federico Magistri, Rodrigo Marcuzzi, Elias Ariel Marks, Matteo Sodano, Jens Behley, and Cyrill Stachniss
  • CoPAL: Corrective Planning of Robotic Actions with Giant Language Fashions, Frank Joublin, Antonello Ceravola, Pavel Smirnov, Felix Ocker, Joerg Deigmoeller, Anna Belardinelli, Chao Wang, Stephan Hasler, Daniel Tanneberg, and Michael Gienger
  • CalliRewrite: Recovering Handwriting Behaviors from Calligraphy Photographs with out Supervision, Yuxuan Luo, Zekun Wu, and Zhouhui Lian

IEEE ICRA Finest Paper Award in Robotic Imaginative and prescient

Winner

NGEL-SLAM: Neural Implicit Illustration-based World Constant Low-Latency SLAM System, Yunxuan Mao, Xuan Yu, Kai Wang, Yue Wang, Rong Xiong, and Yiyi Liao

Finalists

  • HEGN: Hierarchical Equivariant Graph Neural Community for 9DoF Level Cloud Registration, Adam Misik, Driton Salihu, Xin Su, Heike Brock, and Eckehard Steinbach
  • Deep Evidential Uncertainty Estimation for Semantic Segmentation below Out-Of-Distribution Obstacles, Siddharth Ancha, Philip Osteen, and Nicholas Roy
  • SeqTrack3D: Exploring Sequence Info for Strong 3D Level Cloud Monitoring, Yu Lin, Zhiheng Li, Yubo Cui, and Zheng Fang
  • Ultrafast Sq.-Root Filter-based VINS, Yuxiang Peng, Chuchu Chen, and Guoquan Huang
  • Common Visible Decomposer: Lengthy-Horizon Manipulation Made Straightforward, Zichen Zhang, Yunshuang Li, Osbert Bastani, Abhishek Gupta, Dinesh Jayaraman, Yecheng Jason Ma, and Luca Weihs

IEEE ICRA Finest Paper Award on Unmanned Aerial Automobiles

Winner

Time-Optimum Gate-Traversing Planner for Autonomous Drone Racing, Chao Qin, Maxime Simon Joseph Michet, Jingxiang Chen, and Hugh H.-T. Liu

Finalists

  • A Trajectory-based Flight Assistive System for Novice Pilots in Drone Racing State of affairs, Yuhang Zhong, Guangyu Zhao, Qianhao Wang, Guangtong Xu, Chao Xu, and Fei Gao
  • Co-Design Optimisation of Morphing Topology and Management of Winged Drones, Fabio Bergonti, Gabriele Nava, Valentin Wüest, Antonello Paolino, Giuseppe L’Erario, Daniele Pucci, and Dario Floreano
  • FC-Planner: A Skeleton-guided Planning Framework for Quick Aerial Protection of Complicated 3D Scenes, Chen Feng, Haojia Li, Mingjie Zhang, Xinyi Chen, Boyu Zhou, and Shaojie Shen
  • Sequential Trajectory Optimization for Externally-Actuated Modular Manipulators with Joint Locking, Jaeu Choe, Jeongseob Lee, Hyunsoo Yang, Hai-Nguyen (Hann) Nguyen, and Dongjun Lee
  • Spatial Assisted Human-Drone Collaborative Navigation and Interplay by means of Immersive Combined Actuality, Luca Morando and Giuseppe Loianno

IEEE ICRA Finest Scholar Paper Award

Winner

Optimized Design and Fabrication of Skeletal Muscle Actuators for Bio-syncretic Robots, Lianchao Yang, Chuang Zhang, Ruiqian Wang, Yiwei Zhang, and Lianqing Liu

Finalists

  • TinyMPC: Mannequin-Predictive Management on Useful resource-Constrained Microcontrollers, Anoushka Alavilli, Khai Nguyen, Samuel Schoedel, Brian Plancher, and Zachary Manchester
  • Objective Masked Diffusion Insurance policies for Unified Navigation and Exploration, Ajay Sridhar, Dhruv Shah, Catherine Glossop, and Sergey Levine
  • Open X-Embodiment: Robotic Studying Datasets and RT-X Fashions, Sergey Levine, Chelsea Finn, Ken Goldberg, Lawrence Yunliang Chen, Gaurav Sukhatme, Shivin Dass, Lerrel Pinto, Yuke Zhu, Yifeng Zhu, Shuran Music, Oier Mees, Deepak Pathak, Hao-Shu Fang, Henrik Iskov Christensen, Mingyu Ding, Youngwoon Lee, Dorsa Sadigh, Ilija Radosavovic, Jeannette Bohg, Xiaolong Wang, Xuanlin Li, Krishan Rana, Kento Kawaharazuka, Tatsuya Matsushima, Jihoon Oh, Takayuki Osa, Oliver Kroemer, Beomjoon Kim, Edward Johns, Freek Stulp, Jan Schneider, Jiajun Wu, Yunzhu Li, Heni Ben Amor, Lionel Ott, Roberto Martin-Martin, Karol Hausman, Quan Vuong, Pannag Sanketi, Nicolas Heess, Vincent Vanhoucke, Karl Pertsch, Stefan Schaal, Cheng Chi, Chuer Pan, and Alex Bewley
  • POLITE: Preferences Mixed with Highlights in Reinforcement Studying, Simon Holk, Daniel Marta, and Iolanda Leite
  • Exoskeleton-Mediated Bodily Human-Human Interplay for a Sit-to-Stand Rehabilitation Activity, Lorenzo Vianello, Emek Baris Kucuktabak, Matthew Quick, Clément Lhoste, Lorenzo Amato, Kevin Lynch, and Jose L. Pons
  • Design and Modeling of a Nested Bi-cavity- primarily based Gentle Rising Robotic for Greedy in Constrained Environments, Haochen Yong, Fukang Xu, Chenfei Li, Han Ding, and Zhigang Wu
  • Observer-based Distributed MPC for Collaborative Quadrotor-Quadruped Manipulation of a Cable-Towed Load, Shaohang Xu, Yi’An Wang, Wentao Zhang, Chin Pang Ho, and Lijun Zhu
  • Censible: A Strong and Sensible World Localization Framework for Planetary Floor Missions, Jeremy Nash, Quintin Dwight, Lucas Saldyt, Haoda Wang, Steven Myint, Adnan Ansar, and Vandi Verma
  • HEGN: Hierarchical Equivariant Graph Neural Community for 9DoF Level Cloud Registration, Adam Misik, Driton Salihu, Xin Su, Heike Brock, and Eckehard Steinbach
  • A Trajectory-based Flight Assistive System for Novice Pilots in Drone Racing State of affairs, Yuhang Zhong, Guangyu Zhao, Qianhao Wang, Guangtong Xu, Chao Xu, and Fei Gao

IEEE ICRA Finest Convention Paper Award

Winners

  • Objective Masked Diffusion Insurance policies for Unified Navigation and Exploration, Ajay Sridhar, Dhruv Shah, Catherine Glossop, and Sergey Levine
  • Open X-Embodiment: Robotic Studying Datasets and RT-X, Sergey Levine, Chelsea Finn, Ken Goldberg, Lawrence Yunliang Chen, Gaurav Sukhatme, Shivin Dass, Lerrel Pinto, Yuke Zhu, Yifeng Zhu, Shuran Music, Oier Mees, Deepak Pathak, Hao-Shu Fang, Henrik Iskov Christensen, Mingyu Ding, Youngwoon Lee, Dorsa Sadigh, Ilija Radosavovic, Jeannette Bohg, Xiaolong Wang, Xuanlin Li, Krishan Rana, Kento Kawaharazuka, Tatsuya Matsushima, Jihoon Oh, Takayuki Osa, Oliver Kroemer, Beomjoon Kim, Edward Johns, Freek Stulp, Jan Schneider, Jiajun Wu, Yunzhu Li, Heni Ben Amor, Lionel Ott, Roberto Martin-Martin, Karol Hausman, Quan Vuong, Pannag Sanketi, Nicolas Heess, Vincent Vanhoucke, Karl Pertsch, Stefan Schaal, Cheng Chi, Chuer Pan, and Alex Bewley

Finalists

  • TinyMPC: Mannequin-Predictive Management on Useful resource-Constrained Microcontrollers, Anoushka Alavilli, Khai Nguyen, Samuel Schoedel, Brian Plancher, and Zachary Manchester
  • POLITE: Preferences Mixed with Highlights in Reinforcement Studying, Simon Holk, Daniel Marta, and Iolanda Leite
  • Exoskeleton-Mediated Bodily Human-Human Interplay for a Sit-to-Stand Rehabilitation Activity, Lorenzo Vianello, Emek Baris Kucuktabak, Matthew Quick, Clément Lhoste, Lorenzo Amato, Kevin Lynch, and Jose L. Pons
  • Optimized Design and Fabrication of Skeletal Muscle Actuators for Bio-syncretic Robots, Lianchao Yang, Chuang Zhang, Ruiqian Wang, Yiwei Zhang, and Lianqing Liu
  • Design and Modeling of a Nested Bi-cavity- primarily based Gentle Rising Robotic for Greedy in Constrained Environments, Haochen Yong, Fukang Xu, Chenfei Li, Han Ding, and Zhigang Wu
  • Observer-based Distributed MPC for Collaborative Quadrotor-Quadruped Manipulation of a Cable-Towed Load, Shaohang Xu, Yi’An Wang, Wentao Zhang, Chin Pang Ho, and Lijun Zhu
  • Censible: A Strong and Sensible World Localization Framework for Planetary Floor Missions, Jeremy Nash, Quintin Dwight, Lucas Saldyt, Haoda Wang, Steven Myint, Adnan Ansar, and Vandi Verma
  • HEGN: Hierarchical Equivariant Graph Neural Community for 9DoF Level Cloud Registration, Adam Misik, Driton Salihu, Xin Su, Heike Brock, and Eckehard Steinbach
  • A Trajectory-based Flight Assistive System for Novice Pilots in Drone Racing State of affairs, Yuhang Zhong, Guangyu Zhao, Qianhao Wang, Guangtong Xu, Chao Xu, and Fei Gao




AIhub
is a non-profit devoted to connecting the AI neighborhood to the general public by offering free, high-quality info in AI.

AIhub
is a non-profit devoted to connecting the AI neighborhood to the general public by offering free, high-quality info in AI.

The Startup Journal Lead Era Magic: Attracting High quality Leads and Filtering Out the Noise

0

In in the present day’s aggressive market, attracting high quality leads is extra vital than ever. Companies of all sizes and sectors are always looking for progressive methods to seize the eye of potential clients. Amidst the noise of generic advertising messages, it may be difficult to zero in on prospects who’re genuinely all in favour of what you provide. Right here’s how one can grasp the magic of lead era, guaranteeing you each appeal to and retain top quality leads whereas filtering out the noise.

quality leads
Specializing in Your Gross sales Funnel

Understanding Your Preferrred Buyer

The muse of efficient lead era lies in a deep understanding of your ultimate buyer. This implies figuring out the precise demographics, behaviors, and ache factors of these almost definitely to profit out of your services or products. Conducting thorough market analysis, sending out buyer surveys, and analyzing current buyer information are all important steps in portray a transparent image of your audience. Harnessing instruments like reverse handle search for might be invaluable on this stage. 

This specific software permits companies to collect in depth details about potential leads, together with their geographic location and different private particulars that may help in tailoring extra customized advertising messages. By integrating such insights, firms can sharpen their focus, guaranteeing advertising efforts attain the proper individuals.

Creating Compelling Content material

Content material is king within the realm of lead era. High quality content material can seize curiosity, educate, and persuade potential clients to take motion. However the hot button is to supply worth. Whether or not you’re producing weblog posts, e-books, whitepapers, webinars, or movies, your content material ought to handle the ache factors and questions of your viewers. Create content material that not solely informs but additionally engages and evokes.

Bear in mind to combine sturdy calls-to-action (CTAs). A compelling CTA can information your viewers to the subsequent step, whether or not it’s signing up for a e-newsletter, downloading a useful resource, or requesting a demo. When executed successfully, CTAs create a seamless path from curiosity to conversion, driving certified leads additional down the gross sales funnel.

Leveraging Social Proof

Social proof is a strong weapon within the lead era arsenal. Potential clients usually tend to belief and interact with a model that’s validated by others. Spotlight buyer opinions, testimonials, case research, and user-generated content material in your web site and social media channels. Encourage happy clients to share their constructive experiences and think about making a referral program to additional incentivize them.

Moreover, participating with influencers in your area of interest can amplify your attain. Genuine endorsements from trusted voices can considerably improve your credibility and appeal to high quality leads who’re influenced by their suggestions.

Using Advertising Automation and AI

The developments in advertising automation and synthetic intelligence (AI) are reworking the panorama of lead era. By using advertising automation instruments, companies can streamline and scale their efforts, nurturing leads with customized messaging on the proper instances. Automated electronic mail sequences, for example, can maintain your model top-of-mind and information potential clients by the purchaser’s journey with out handbook intervention at each step.

AI-powered instruments improve concentrating on and personalization even additional. Predictive analytics can forecast which leads are almost definitely to transform, permitting gross sales and advertising groups to focus their efforts on the very best high quality prospects. Chatbots and digital assistants present real-time engagement, answering questions and capturing lead data across the clock, guaranteeing no alternative slips by the cracks.

Filtering Out the Noise

Attracting high quality leads is simply half the battle; the opposite half entails filtering out the noise. In a world flooded with information, it’s important to tell apart between real prospects and those that are unlikely to transform. Listed here are some methods to realize this:

Lead Scoring: Develop a lead scoring system to rank prospects primarily based on their engagement and match. Assign factors for actions like visiting key pages in your web site, downloading content material, or attending webinars. Prioritize leads with increased scores for additional follow-up.

Qualification Questions: Implement qualification questions in your types and surveys to collect important details about a lead’s wants, timeline, and funds. It will assist your gross sales workforce establish which leads are price pursuing.

Monitoring Engagement: Monitor how leads work together together with your content material and communications. Leads who open emails, click on on hyperlinks, and request extra data are extra engaged and prone to convert.

Common Evaluation: Constantly analyze your lead era efforts. Usually evaluation metrics resembling conversion charges and buyer acquisition prices to refine your methods and deal with what works finest.

Conclusion

Mastering lead era is a mix of artwork and science. By understanding your ultimate buyer, creating compelling content material, leveraging social proof, using superior expertise, and implementing efficient noise-filtering methods, you may appeal to high-quality leads that drive your enterprise ahead. Bear in mind, the objective isn’t just to generate high quality leads, however to nurture and convert them into loyal clients. With these methods in place, you may flip the magic of lead era into tangible enterprise success.

Amazon is creating a stay motion Completely Spies sequence

0

A live-action adaptation of Completely Spies is now in manufacturing at Amazon. In accordance with a report from , Will Ferrell is the chief producer of the live-action sequence primarily based on the favored 2000s animated sequence from French media firm Banijay Children, previously generally known as Marathon Media.

The live-action Completely Spies will observe Sam, Clover and Alex as they stability saving the world as worldwide spies working for the company WOOHP with tackling schoolwork and social lives as faculty freshmen. No actors have been forged as any of the enduring ladies, nor are writers connected to the mission simply but.

The unique Completely Spies was created by Vincent Chalvon-Demersay and David Michel, and it revolved across the three aforementioned teenage ladies from Beverly Hills, California as they’re recruited by WOOHP to unravel worsening crimes that come up all over the world. They’re outfitted with spy gear disguised as girls’s equipment akin to hair dryers, high-heel footwear and lipstick. It’s like an animated Charlie’s Angels, besides the women really see their boss in individual.

Since its premiere in 2002, the sequence aired over 180 episodes, in addition to spawned a prequel film and a spin-off present, The Superb Spiez. The seventh season of Completely Spies premiered in France final month after an almost ten-year break, and it’ll air on Cartoon Community and Max within the US later this 12 months.

This is Every thing New within the Messages App on iOS 18

0

iOS 18 provides many new options to the Messages app, together with the power to schedule messages to be despatched later, the power to make use of any emoji or sticker as a Tapback, textual content formatting choices like daring and italics, and way more.

iOS 18 Messages Feature 1
iOS 18 is at the moment obtainable in beta for members of the Apple Developer Program, with a public beta to observe in July. The software program replace needs to be broadly launched in September, and it’s appropriate with the iPhone XS and newer.

Beneath, we define every little thing new within the Messages app on iOS 18, together with some smaller modifications that Apple’s web site doesn’t point out.

Schedule Messages

iMessages can now be scheduled to be despatched at a later date and time in each particular person and group conversations. As of the primary iOS 18 beta, you’ll be able to schedule a message to be despatched as much as 14 days later. After scheduling a message, it turns into seen to you in a dotted-line bubble, with edit, delete, and reschedule choices.

iMessage Send Later iOS 18
To entry this characteristic, faucet the plus signal to the left of the textual content discipline, faucet Extra, and faucet Ship Later.

Tapback Modifications

Redesigned Tapbacks

The traditional set of Tapback icons are actually colourful, together with the center, thumbs up, thumbs down, HA HA, exclamation marks, and query mark.

iMessage iOS 18 2

Emoji Tapbacks

Now you can use any emoji or sticker as a Tapback.

iMessage iOS 18 4

Improved Visibility

It’s now simpler to view a number of Tapback reactions on a single message.

Textual content Formatting and Results

Daring, italics, underline, and strikeout formatting is lastly obtainable for iMessages. As well as, there are all-new textual content results that may animate phrases inside an iMessage, together with Huge, Small, Shake, Nod, Explode, Ripple, Bloom, and Jitter.

iMessage iOS 18 1iOS 18 Text Effects iMessage

Messages through Satellite tv for pc U.S. Solely

iOS 18 permits you to ship and obtain each iMessages and SMS messages through a satellite tv for pc connection, even when there isn’t a emergency.

iOS 18 Messages via Satellite
This characteristic will work with messages, emoji, and Tapbacks, and all iMessages despatched over satellite tv for pc are secured with end-to-end encryption.

Messages through satellite tv for pc is accessible on all iPhone 14 fashions and newer within the U.S. solely at launch.

Palms-on demo movies present the characteristic in motion.

RCS Help Later This 12 months

Apple’s web site says that iOS 18 will assist RCS (Wealthy Communication Companies) within the Messages app. Whereas this characteristic shouldn’t be enabled within the first iOS 18 beta, Apple stated it will likely be rolled out later this yr, seemingly by time iOS 18 is broadly launched.

iOS 18 WWDC SlideWWDC keynote slide confirming RCS assist on iOS 18

RCS assist will outcome within the following enhancements to the default messaging expertise between iPhones and Android gadgets:

  • Increased-resolution images and movies
  • Audio messages
  • Typing indicators
  • Learn receipts
  • Wi-Fi messaging
  • Improved group chats, together with the power for iPhone customers to depart a dialog that features Android customers

SMS continues to be supported as nicely.

Emoji and Hyperlink Card Modifications

Whenever you ship a message with solely a single emoji, it now seems even bigger than earlier than.

iMessage iOS 18 Link Cards
Hyperlink playing cards are actually extra colourful, with the background higher matching the linked content material.

For some hyperlinks, now you can select between full-size and compact hyperlink playing cards, and there may be an choice to ship a hyperlink as plain textual content as an alternative.

Different Modifications

Older Pixel Execs now have handbook lens choice, can seize higher HDR+ photographs

0

The June Pixel Function Drop is backporting some Pixel 8 digital camera options to the Pixel 6, 7 and the Pixel Fold (and in a single case, the Pixel Pill too). This comes with Pixel Digital camera model 9.4.

Usually, the digital camera app mechanically decides which lens to make use of primarily based on zoom stage, lighting situations and extra. However now you possibly can go into the Picture Settings and select a handbook lens choice – this allows you to choose which digital camera to make use of (broad, extremely broad or tele) as a substitute of regardless of the telephone decides. Notice that that is restricted to the Pixel 6 Professional, 7 Professional and Pixel Fold (i.e. the vanilla Pixels nonetheless solely have the auto choice).


Manual lens selection comes to older Pixel Pros

Handbook lens choice involves older Pixel Execs

This toggle lives beneath the “Professional” tab of the Picture Settings. Additionally right here you will discover the setting for the way photographs are saved – JPEG solely or JPEG+RAW. This isn’t a brand new function, however beforehand it was positioned beneath Settings > Superior.


HDR+ is better at picking the perfect moment to snap a photo

HDR+ is healthier at choosing the right second to snap a photograph

Moreover, the HDR+ mode is now higher at choosing the right second – you faucet the shutter key and the telephone will do its greatest to seize the picture when the topic’s face is in focus and they’re smiling. That is added to the Pixel 6 and newer, Pixel Fold and in addition the Pixel Pill.

Supply

The Obtain: Synthetic surf swimming pools, and unfunny AI

0

For practically so long as browsing has existed, surfers have been obsessive about the seek for the right wave. 

Whereas this hunt has taken surfers from tropical coastlines to icebergs, lately that search could happen nearer to residence. That’s, not less than, the imaginative and prescient offered by builders and boosters within the rising trade of surf swimming pools, spurred by advances in wave-­producing expertise which have lastly created synthetic waves surfers really wish to experience.

However there’s an issue: a few of these swimming pools are in drought-ridden areas, and face fierce native opposition. On the core of those fights is a query that’s additionally on the coronary heart of the game: What’s the price of discovering, or now creating, the right wave—and who must bear it? Learn the complete story.

—Eileen Guo

This story is from the forthcoming print challenge of MIT Know-how Evaluate, which explores the theme of Play. It’s set to go stay on Wednesday June 26, so in the event you don’t already, subscribe now to get a replica when it lands.

What occurred when 20 comedians obtained AI to write down their routines

AI is sweet at plenty of issues: recognizing patterns in knowledge, creating fantastical photographs, and condensing hundreds of phrases into only a few paragraphs. However can it’s a great tool for writing comedy?

Alleged Boss of ‘Scattered Spider’ Hacking Group Arrested – Krebs on Safety

0

A 22-year-old man from the UK arrested this week in Spain is allegedly the ringleader of Scattered Spider, a cybercrime group suspected of hacking into Twilio, LastPass, DoorDash, Mailchimp, and practically 130 different organizations over the previous two years.

The Spanish each day Murcia In the present day experiences the suspect was needed by the FBI and arrested in Palma de Mallorca as he tried to board a flight to Italy.

Alleged Boss of ‘Scattered Spider’ Hacking Group Arrested – Krebs on Safety

A nonetheless body from a video launched by the Spanish nationwide police reveals Tylerb in custody on the airport.

“He stands accused of hacking into company accounts and stealing crucial info, which allegedly enabled the group to entry multi-million-dollar funds,” Murcia In the present day wrote. “Based on Palma police, at one level he managed Bitcoins value $27 million.”

The cybercrime-focused Twitter/X account vx-underground stated the U.Ok. man arrested was a SIM-swapper who glided by the alias “Tyler.” In a SIM-swapping assault, crooks switch the goal’s telephone quantity to a tool they management and intercept any textual content messages or telephone calls despatched to the sufferer — together with one-time passcodes for authentication, or password reset hyperlinks despatched through SMS.

“He’s a identified SIM-swapper and is allegedly concerned with the notorious Scattered Spider group,” vx-underground wrote on June 15, referring to a prolific gang implicated in pricey knowledge ransom assaults at MGM and Caesars casinos in Las Vegas final yr.

Sources acquainted with the investigation informed KrebsOnSecurity the accused is a 22-year-old from Dundee, Scotland named Tyler Buchanan, additionally allegedly referred to as “tylerb” on Telegram chat channels centered round SIM-swapping.

In January 2024, U.S. authorities arrested one other alleged Scattered Spider member — 19-year-old Noah Michael City of Palm Coast, Fla. — and charged him with stealing a minimum of $800,000 from 5 victims between August 2022 and March 2023. City allegedly glided by the nicknames “Sosa” and “King Bob,” and is believed to be a part of the identical crew that hacked Twilio and a slew of different firms in 2022.

Investigators say Scattered Spider members are a part of a extra diffuse cybercriminal neighborhood on-line referred to as “The Com,” whereby hackers from completely different cliques boast loudly about high-profile cyber thefts that nearly invariably start with social engineering — tricking folks over the telephone, electronic mail or SMS into freely giving credentials that permit distant entry to company inside networks.

One of many extra fashionable SIM-swapping channels on Telegram maintains a regularly up to date leaderboard of essentially the most achieved SIM-swappers, listed by their supposed conquests in stealing cryptocurrency. That leaderboard presently lists Sosa as #24 (out of 100), and Tylerb at #65.

0KTAPUS

In August 2022, KrebsOnSecurity wrote about peering inside the info harvested in a months-long cybercrime marketing campaign by Scattered Spider involving numerous SMS-based phishing assaults towards workers at main firms. The safety agency Group-IB known as the gang by a distinct title — 0ktapus, a nod to how the legal group phished workers for credentials.

The missives requested customers to click on a hyperlink and log in at a phishing web page that mimicked their employer’s Okta authentication web page. Those that submitted credentials have been then prompted to offer the one-time password wanted for multi-factor authentication.

These phishing assaults used newly-registered domains that always included the title of the focused firm, and despatched textual content messages urging workers to click on on hyperlinks to those domains to view details about a pending change of their work schedule. The phishing websites additionally featured a hidden Telegram on the spot message bot to ahead any submitted credentials in real-time, permitting the attackers to make use of the phished username, password and one-time code to log in as that worker at the true employer web site.

One among Scattered Spider’s first massive victims in its 2022 SMS phishing spree was Twilio, an organization that gives providers for making and receiving textual content messages and telephone calls. The group then pivoted, utilizing their entry to Twilio to assault a minimum of 163 of its prospects.

A Scattered Spider phishing lure despatched to Twilio workers.

Amongst these was the encrypted messaging app Sign, which stated the breach might have let attackers re-register the telephone quantity on one other system for about 1,900 customers.

Additionally in August 2022, a number of workers at electronic mail supply agency Mailchimp supplied their distant entry credentials to this phishing group. Based on Mailchimp, the attackers used their entry to Mailchimp worker accounts to steal knowledge from 214 prospects concerned in cryptocurrency and finance.

On August 25, 2022, the password supervisor service LastPass disclosed a breach through which attackers stole some supply code and proprietary LastPass technical info, and weeks later LastPass stated an investigation revealed no buyer knowledge or password vaults have been accessed.

Nonetheless, on November 30, 2022 LastPass disclosed a much more critical breach that the corporate stated leveraged knowledge stolen within the August breach. LastPass stated legal hackers had stolen encrypted copies of some password vaults, in addition to different private info.

In February 2023, LastPass disclosed that the intrusion concerned a extremely advanced, focused assault towards an engineer who was one among solely 4 LastPass workers with entry to the company vault. In that incident, the attackers exploited a safety vulnerability in a Plex media server that the worker was operating on his dwelling community, and succeeded in putting in malicious software program that stole passwords and different authentication credentials. The vulnerability exploited by the intruders was patched again in 2020, however the worker by no means up to date his Plex software program.

Plex introduced its personal knowledge breach in the future earlier than LastPass disclosed its preliminary August intrusion. On August 24, 2022, Plex’s safety crew urged customers to reset their passwords, saying an intruder had accessed buyer emails, usernames and encrypted passwords.

TURF WARS

Sosa and Tylerb have been each subjected to bodily assaults from rival SIM-swapping gangs. These communities have been identified to settle scores by turning to so-called “violence-as-a-service” choices on cybercrime channels, whereby folks could be employed to carry out a range geographically-specific “in actual life” jobs, reminiscent of bricking home windows, slashing automotive tires, and even dwelling invasions.

In 2022, a video surfaced on a preferred cybercrime channel purporting to point out attackers hurling a brick by way of a window at an handle that matches the spacious and upscale dwelling of City’s dad and mom in Sanford, Fl.

January’s story on Sosa famous {that a} junior member of his crew named “Foreshadow” was kidnapped, crushed and held for ransom in September 2022. Foreshadow’s captors held weapons to his bloodied head whereas forcing him to document a video message pleading along with his crew to fork over a $200,000 ransom in change for his life (Foreshadow escaped additional hurt in that incident).

Based on a number of SIM-swapping channels on Telegram the place Tylerb was identified to frequent, rival SIM-swappers employed thugs to invade his dwelling in February 2023. These accounts state that the intruders assaulted Tylerb’s mom within the dwelling invasion, and that they threatened to burn him with a blowtorch if he didn’t hand over the keys to his cryptocurrency wallets. Tylerb was reputed to have fled the UK after that assault.

KrebsOnSecurity sought remark from Mr. Buchanan, and can replace this story within the occasion he responds.