Skip to content

[UIUnit] find() from a non-root search context contains the search context as first found component #1921

@stefanuebe

Description

@stefanuebe

The UIUnit test api provide a method to find components based on a given search context component, to search exclusively in that dom branch.

Unfortunately the resulting list of components also contain the search context itself, when the type of the search context matches the searched sub component type. This leads to the problem, that calling first() on the component query always returns the search context itself in that case.

Not sure if that is intentional, but from the Javadocs and also logical structure of the api, it feels like it is not or should not be.

Simple sample view

@Route("")
public class SampleView extends VerticalLayout {

    public SampleView() {
        addClassName("root");

        VerticalLayout inner = new VerticalLayout(new Span("span1"), new Span("span2"), new Span("span3"));
        inner.addClassName("inner1");
        add(inner);
       
        inner = new VerticalLayout(new Span("span1"), new Span("span2"), new Span("span3"));
        inner.addClassName("inner2");
        add(inner);
       
        inner = new VerticalLayout(new Span("span1"), new Span("span2"), new Span("span3"));
        inner.addClassName("inner3");
        add(inner);
    }
}

UIUnit test to get the first inner vertical layout. The assertion will fail.

public class SampleTest extends SpringUIUnitTest {

    @Test
    public void test() {
        navigate(SampleView.class);
        VerticalLayout root = $(VerticalLayout.class).withClassName("root").first();

        // fetching the inner layout using the tester of the outer one
        VerticalLayout firstInner = test(root).find(VerticalLayout.class).first();
        
        // alternative way of fetching the inner layout
        // VerticalLayout firstInner = $(VerticalLayout.class, root).first();

        // both variants do basically this internally
        // VerticalLayout firstInner = new ComponentQuery<>(VerticalLayout.class).from(root).first();

        // all of them will fail
        Assertions.assertNotEquals(firstInner, root);
    }
}

A workaround is to not use the first() method, but the all() one and filter for the search context before returning the first result:

        ComponentQuery<VerticalLayout> query = test(root).find(VerticalLayout.class);
//        ComponentQuery<VerticalLayout> query = $(VerticalLayout.class, root);
//        ComponentQuery<VerticalLayout> query = new ComponentQuery<>(VerticalLayout.class).from(root);

        VerticalLayout firstInner = query.all()
                .stream()
                .filter(Predicate.not(root::equals))
                .findFirst()
                .orElseThrow();

        // passes the test
        Assertions.assertNotEquals(firstInner, root);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    🔎 Investigation

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions