Class Locator<C extends Component,SELF extends Locator<C,SELF>>

java.lang.Object
com.vaadin.browserless.locator.Locator<C,SELF>
Type Parameters:
C - the component type
SELF - the concrete locator subtype, used for fluent chaining
Direct Known Subclasses:
AccordionLocator, AnchorLocator, BigDecimalFieldLocator, ButtonLocator, ChartLocator, CheckboxGroupLocator, CheckboxLocator, ComboBoxLocator, ConfirmDialogLocator, ContextMenuLocator, DatePickerLocator, DateTimePickerLocator, DecimalRangeSliderLocator, DecimalSliderLocator, DescriptionListLocator, DetailsLocator, DialogLocator, DivLocator, EmailFieldLocator, EmphasisLocator, GridLocator, H1Locator, H2Locator, H3Locator, H4Locator, H5Locator, H6Locator, HrLocator, ImageLocator, InputLocator, IntegerFieldLocator, IntegerRangeSliderLocator, IntegerSliderLocator, ListBoxLocator, ListItemLocator, LoginFormLocator, LoginOverlayLocator, MenuBarLocator, MessageInputLocator, MessageListLocator, MultiSelectComboBoxLocator, MultiSelectListBoxLocator, NativeButtonLocator, NativeDetailsLocator, NativeLabelLocator, NotificationLocator, NumberFieldLocator, OrderedListLocator, ParagraphLocator, PasswordFieldLocator, PopoverLocator, PreLocator, RadioButtonGroupLocator, RadioButtonLocator, RangeInputLocator, RouterLinkLocator, SelectLocator, SideNavLocator, SpanLocator, TabSheetLocator, TabsLocator, TextAreaLocator, TextFieldLocator, TimePickerLocator, UnorderedListLocator, UploadLocator, VirtualListLocator

public abstract class Locator<C extends Component,SELF extends Locator<C,SELF>> extends Object
Prototype base class for the get* tester API. A locator is a fluent combination of a ComponentQuery filter chain and a tester: the subclass exposes both the filter methods inherited from this class and the action methods specific to the component type.

Resolution is deferred to the first action call (component()) and cached. Every filter method on this class clears the resolution cache before mutating the underlying query, so the next action re-resolves and callers never have to call invalidate() between fluent steps. Filter steps keep the locator's atIndex(int) pick sticky — it is part of the filter chain — so a single locator instance can be reused across an asynchronous boundary (e.g. roundTrip()) without holding on to a stale component reference. invalidate() is the explicit rewind hatch and additionally clears the pick.

Filters that this class does not expose directly (for example ComponentQuery.withPropertyValue(java.util.function.Function<T, V>, V) or ComponentQuery.withResultsSize(int)) are reachable through the with(UnaryOperator) escape hatch, which lets callers compose any filter the underlying ComponentQuery supports without subclassing.

Construction modes. The default constructor (Locator(Class)) seeds an empty query that searches the active UI. Tests that already hold a direct reference to the component they want to act on can instead use the seeded-query constructor (Locator(Class, Component)), which pre-filters the query with an identity predicate. Both modes share the same filter/resolution machinery — additional filters compose on top of the identity predicate, and a filter that excludes the seeded component just makes exists() return false and component() throw. Custom locator subclasses can opt in by declaring a second constructor that forwards to super(Class, component).

  • Constructor Details

    • Locator

      protected Locator(Class<C> componentType)
      Creates a locator that searches for components of the given type from the current UI root.
      Parameters:
      componentType - the component type to match
    • Locator

      protected Locator(Class<C> componentType, C component)
      Creates a locator seeded with a direct reference to the component to match. The query is pre-filtered with an identity predicate so the only resolution is the given instance; additional filter steps compose on top of it.
      Parameters:
      componentType - the component type to match
      component - the component instance to seed the query with; must not be null
  • Method Details

    • withId

      public SELF withId(String id)
      Requires the matched component to have the given id.
    • withCaption

      public SELF withCaption(String caption)
      Requires the matched component to have a caption equal to the given text.
    • withCaptionContaining

      public SELF withCaptionContaining(String text)
      Requires the matched component to have a caption containing the given text.
    • withLabel

      public SELF withLabel(String label)
      Requires the matched component's label property to be exactly the given value. Use this for form fields where the end user identifies a field by its label.
    • withLabelContaining

      public SELF withLabelContaining(String text)
      Requires the matched component's label property to contain the given text.
    • withAriaLabel

      public SELF withAriaLabel(String ariaLabel)
      Requires the matched component's aria-label attribute to be exactly the given value.
    • withAriaLabelContaining

      public SELF withAriaLabelContaining(String text)
      Requires the matched component's aria-label attribute to contain the given text.
    • withText

      public SELF withText(String text)
      Requires the text content of the component to equal the given text.
    • withTextContaining

      public SELF withTextContaining(String text)
      Requires the text content of the component to contain the given text.
    • withClassName

      public SELF withClassName(String... className)
      Requires the matched component to have all the given CSS class names.
    • withoutClassName

      public SELF withoutClassName(String... className)
      Requires the matched component to have none of the given CSS class names.
    • withTheme

      public SELF withTheme(String theme)
      Requires the matched component to have the given theme set.
    • withoutTheme

      public SELF withoutTheme(String theme)
      Requires the matched component to not have the given theme set.
    • withAttribute

      public SELF withAttribute(String attribute)
      Requires the matched component to have the given attribute set.
    • withAttribute

      public SELF withAttribute(String attribute, String value)
      Requires the matched component to have the given attribute with the expected value.
    • withoutAttribute

      public SELF withoutAttribute(String attribute)
      Requires the matched component not to have the given attribute.
    • withoutAttribute

      public SELF withoutAttribute(String attribute, String value)
      Requires the matched component not to have the given attribute value (or not to have the attribute at all).
    • withValue

      public <V> SELF withValue(V expectedValue)
      Requires the matched component to implement HasValue and to have the given value. Has no effect when expectedValue is null.
    • withCondition

      public SELF withCondition(Predicate<C> condition)
      Requires the matched component to satisfy the given predicate.
    • with

      public SELF with(UnaryOperator<ComponentQuery<C>> op)
      Escape hatch for filters not directly exposed on Locator. Applies the given operator to the underlying ComponentQuery, letting users compose any filter the query supports without subclassing.
       findButton().with(q -> q.withPropertyValue(Button::getText, "Save"))
               .click();
       
      Honors the UnaryOperator contract: whatever the operator returns becomes the locator's new underlying query. ComponentQuery's built-in filter methods all return this, so a fluent chain just re-installs the same instance; an operator that builds and returns a fresh query replaces the prior one wholesale.
      Throws:
      IllegalStateException - if the operator returns null instead of a ComponentQuery — the operator is expected either to mutate and return the same instance, or to build and return a fresh one.
    • inside

      public SELF inside(Component parent)
      Scopes the search to descendants of the given component. Replaces any lazy parent previously installed by inside(Locator) with a fixed reference.
    • inside

      public SELF inside(Locator<?,?> parent)
      Scopes the search to descendants of the component matched by the given locator.

      The parent is resolved lazily, at child-resolution time: each call to component(), components(), or exists() first invokes parent.component() and installs the result as this locator's search context. A later invalidate() on parent therefore propagates — the next child action re-resolves both. Calling inside(Component) afterwards replaces this lazy parent with a fixed reference; calling inside(Locator) again replaces the lazy parent.

      Throws:
      NullPointerException - if parent is null
      IllegalArgumentException - if parent is this locator itself — a self-reference would recurse indefinitely under lazy resolution
    • atIndex

      public SELF atIndex(int index)
      Picks the n-th match (1-based) when the filter chain yields multiple matches. Without this, the default expectation is exactly one match.
      Throws:
      IllegalArgumentException - if index is zero or negative — mirrors ComponentQuery.atIndex(int)'s own contract, so the violation is reported at the locator's filter step rather than masked into a "single match" resolution at action time.
    • component

      public C component()
      Resolves the locator to a single matching component, caching the result. Subclasses call this from action methods (e.g. click).
      Returns:
      the matched component
      Throws:
      NoSuchElementException - if no component matches or more than one matches (and no atIndex(int) was provided)
    • components

      public List<C> components()
      Returns all matching components, bypassing the cache. Useful for assertions on counts without committing to a single match.
    • exists

      public boolean exists()
      Returns true if the filter chain matches at least one component.
    • invalidate

      public SELF invalidate()
      Rewinds picker state: discards any cached resolution and clears the atIndex(int) pick. Filter methods on this class call a private cache-only reset internally, so they keep the locator's atIndex(n) sticky as part of the filter chain. invalidate() is the explicit "rewind" hatch: after a UI change that replaces or detaches the resolved component, calling it forces the next action to re-resolve, and also drops the pick so the next resolution defaults back to "single match expected" until the caller re-applies atIndex(int).
    • self

      protected SELF self()