Class ComponentTester<T extends Component>

java.lang.Object
com.vaadin.browserless.ComponentTester<T>
Type Parameters:
T - component type
All Implemented Interfaces:
Clickable<T>
Direct Known Subclasses:
AbstractLoginTester, AccordionTester, AvatarGroupTester, BreadcrumbsTester, ButtonTester, CardTester, ChartTester, CheckboxGroupTester, CheckboxTester, ComboBoxTester, ConfirmDialogTester, ContextMenuTester, DashboardTester, DatePickerTester, DateTimePickerTester, DecimalRangeSliderTester, DecimalSliderTester, DetailsTester, DialogTester, GridContextMenuTester, GridTester, HtmlComponentTester, InputTester, IntegerRangeSliderTester, IntegerSliderTester, ListBoxTester, MarkdownTester, MasterDetailLayoutTester, MenuBarTester, MessageInputTester, MessageListTester, MultiSelectComboBoxTester, MultiSelectListBoxTester, NotificationTester, NumberFieldTester, PopoverTester, RadioButtonGroupTester, RadioButtonTester, RangeInputTester, RouterLinkTester, SelectTester, SideNavTester, SplitLayoutTester, SwitchTester, TabSheetTester, TabsTester, TextAreaTester, TextFieldTester, TextTester, TimePickerTester, UploadTester, VirtualListTester

public class ComponentTester<T extends Component> extends Object implements Clickable<T>
Test wrapper for components with helpful methods for testing a component.

More targeted methods for specific components exist in named component wrappers.

Since:
1.0
  • Constructor Details

    • ComponentTester

      public ComponentTester(T component)
      Wrap given component for testing.
      Parameters:
      component - target component
  • Method Details

    • getComponent

      public T getComponent()
      Get the wrapped component.
      Specified by:
      getComponent in interface Clickable<T extends Component>
      Returns:
      wrapped component
    • isUsable

      public boolean isUsable()
      Validate that component can be interacted with and should be visible in the UI. Subclasses overriding this method should also override notUsableReasons(Consumer) to provide additional details to the potential exception thrown by ensureComponentIsUsable().
      Returns:
      true if component can be interacted with by the user
      See Also:
    • isComponentReadOnly

      protected boolean isComponentReadOnly()
      Checks whether the wrapped component is a value component that is currently in read-only state.

      A read-only HasValue component cannot be interacted with to change its value, so it is considered not usable.

      Returns:
      true if the component is read-only
    • isUsable

      protected static boolean isUsable(Component component)
      Validate that the given component can be interacted with and should be visible in the UI. Subclasses overriding this method should also override notUsableReasons(Consumer) to provide additional details to the potential exception thrown by ensureComponentIsUsable().
      Returns:
      true if component can be interacted with by the user
      See Also:
    • setModal

      public void setModal(boolean modal)
      Set component modality.

      Automatically generates a client side change to propagate modality.

      Parameters:
      modal - true to make component modal, false to remove modality
    • find

      public <R extends Component> ComponentQuery<R> find(Class<R> componentType)
      Gets a ComponentQuery to search for component of the given type nested inside the wrapped component.

      The query walks the server-side component tree. A component that another component renders per item, such as the component a ComponentRenderer column renders for a grid row, is rendered into the column and not into the tree, and the content of an overlay, such as a context menu, is attached only while the overlay is open. Neither is reachable this way, and the lookup returns an empty result rather than failing, so reach those components through the owning component tester instead: GridTester.getCellComponent(row, column) for grid cells, ContextMenuTester.open() and then clickItem(...) for a context menu, and GridTester.contextMenu(row).open() for a grid context menu.

      Type Parameters:
      R - type of the component to search.
      Parameters:
      componentType - type of the component to search.
      Returns:
      a ComponentQuery instance, searching for wrapped component children.
    • ensureComponentIsUsable

      public final void ensureComponentIsUsable()
      Checks that wrapped component is usable, otherwise throws an IllegalStateException with details on the current state of the component.
      Specified by:
      ensureComponentIsUsable in interface Clickable<T extends Component>
    • ensureComponentIsUsableOrDetach

      protected void ensureComponentIsUsableOrDetach()
      Checks that the wrapped component is usable and, if it is not, detaches it from the UI before rethrowing.

      For an overlay the tester has to attach to the UI before it can tell whether it is usable, such as a context menu opened by a before-open event. Detaching it again keeps a refused interaction from leaving a closed overlay behind in the UI tree, where a top level find(...) would still reach its content.

      Throws:
      IllegalStateException - if the component is not usable, with details on its current state.
    • ensureComponentIsUsable

      protected static void ensureComponentIsUsable(Component component, Predicate<Component> usableTest)
      Throws an IllegalStateException with details on the current state of the component if it is not usable according to the provided test.
      Parameters:
      component - the component to check
      usableTest - function that tests if the component is usable or not.
    • notUsableReasons

      protected void notUsableReasons(Consumer<String> collector)
      Provides messages explaining why the component is actually not usable. Subclasses overriding isUsable() should also override this method to provide additional details to the potential exception throw by ensureComponentIsUsable().
      See Also:
    • notUsableReasons

      protected static void notUsableReasons(Component component, Consumer<String> collector)
      Provides messages explaining why the given component is actually not usable. Subclasses overriding isUsable() should also override this method to provide additional details to the potential exception throw by ensureComponentIsUsable().
      See Also:
    • ensureVisible

      protected void ensureVisible()
      Check that the component is visible for the user. Else throw an IllegalStateException
    • ensureVisible

      protected static void ensureVisible(Component component)
      Check that the given component is visible for the user. Else throw an IllegalStateException
    • roundTrip

      protected void roundTrip()
      Simulates a server round-trip, flushing pending component changes.
    • getField

      protected Field getField(String fieldName)
      Get field with given name in the wrapped component.

      The wrapped component is often an application's own subclass of the component the tester targets, so the field is looked up on the whole class hierarchy, not only on the component's concrete class.

      Parameters:
      fieldName - field name
      Returns:
      accessible field
      Throws:
      IllegalArgumentException - if field doesn't exist
    • getField

      protected Field getField(Class target, String fieldName)
      Get field with given name in the given class or in one of its superclasses.
      Parameters:
      target - class to get field from
      fieldName - field name
      Returns:
      accessible field
      Throws:
      IllegalArgumentException - if field doesn't exist
    • getMethod

      protected Method getMethod(String methodName, Class<?>... parameterTypes)
      Get method with given name and parameters in the wrapped component.

      The wrapped component is often an application's own subclass of the component the tester targets, so the method is looked up on the whole class hierarchy, not only on the component's concrete class.

      Parameters:
      methodName - method name
      parameterTypes - parameter types the method has
      Returns:
      accessible method
    • getMethod

      protected Method getMethod(Class target, String methodName, Class<?>... parameterTypes)
      Get method with given name and parameters in the given class or in one of its superclasses.
      Parameters:
      target - class to get method from
      methodName - method name
      parameterTypes - parameter types the method has
      Returns:
      accessible method
    • fireDomEvent

      protected void fireDomEvent(String eventType)
      Fires a DOM event of the given type on the wrapped component.
      Parameters:
      eventType - the type of the event, not null.
    • fireDomEvent

      protected void fireDomEvent(String eventType, tools.jackson.databind.node.ObjectNode eventData)
      Fires a DOM event with the given type and payload on the wrapped component.
      Parameters:
      eventType - the type of the event, not null.
      eventData - additional data related to the event, not null
    • fireDomEvent

      protected void fireDomEvent(DomEvent event)
      Fires a DOM event on the wrapped component.
      Parameters:
      event - the event that should be fired.
    • findByQuery

      protected <R extends Component> Optional<R> findByQuery(Class<R> componentType, Consumer<ComponentQuery<R>> queryBuilder)
      Searches for a nested component of the given type that matches the conditions set on the component query. Query is expected to return zero or one component. An exception is thrown if more than one component matches the specifications. Usually the ComponentQuery consumer should only define conditions, not invoke any terminal operator.
      Type Parameters:
      R - the type of the component to search for
      Parameters:
      componentType - the type of the component to search for
      queryBuilder - the function that sets query condition
      Returns:
      the component found by query execution, wrapped into an Optional, or empty if the query does not produce results.
    • findAllByQuery

      protected <R extends Component> List<R> findAllByQuery(Class<R> componentType, Consumer<ComponentQuery<R>> queryBuilder)
      Searches for nested components of the given type that matches the conditions set on the component query. Usually the ComponentQuery consumer should only define conditions, not invoke any terminal operator.
      Type Parameters:
      R - the type of the component to search for
      Parameters:
      componentType - the type of the component to search for
      queryBuilder - the function that sets query condition
      Returns:
      the components found by query execution, or an empty list.
    • clearAsUser

      protected void clearAsUser()
      Empties the field as the user would, by setting the component's empty value.

      Emptying a field is always available to the user ? select the contents, press Delete ? and stays legal even when it leaves the field invalid, so the empty value is set unconditionally. This is the shared implementation behind the clear() methods of the value testers; each of them declares clear() itself so that the generated locators pick it up.

      Throws:
      IllegalStateException - if the component is not usable
      IllegalArgumentException - if the component does not hold a value
    • clickClearButtonAsUser

      protected void clickClearButtonAsUser()
      Empties the field by clicking its clear button, as the user would.

      Unlike clearAsUser(), which models the keyboard route and is therefore always available, this requires the clear button to actually be on screen: a hidden clear button is not something the user can click. Past that check the value is emptied exactly as clearAsUser() does.

      Testers for components implementing HasClearButton expose this as a public clickClearButton(); LocatorProcessor fails the build when one of them does not.

      Throws:
      IllegalStateException - if the component is not usable, or its clear button is not visible
      IllegalArgumentException - if the component does not hold a value
    • setValueAsUser

      protected <V> void setValueAsUser(V value)
      Sets the value to given component. Supports pretending that the value came from the browser. Will throw an exception if the component is not instance of AbstractField. This method is purposed for internal use and when creating custom testers extending ComponentTesters.
      Parameters:
      value - the new value, may be null.
    • setValueAsUser

      protected <V> void setValueAsUser(HasValue<?,V> field, V value)
      Sets the value to the given field, pretending that the value came from the browser, so that the fired value change event reports isFromClient() == true. Will throw an exception if the field is not backed by an AbstractField or an AbstractCompositeField; use canSetValueAsUser(HasValue) to check up front.

      This method is purposed for internal use and when creating custom testers extending ComponentTesters, for fields other than the wrapped component, such as an editor field owned by the wrapped component.

      Parameters:
      field - the field to set the value to, not null.
      value - the new value, may be null.
    • canSetValueAsUser

      protected boolean canSetValueAsUser(HasValue<?,?> field)
      Checks whether setValueAsUser(HasValue, Object) can simulate a client side value change on the given field. Only fields backed by AbstractField or AbstractCompositeField have such a path; a tester driving a foreign HasValue implementation has to fall back to HasValue.setValue(Object).
      Parameters:
      field - the field to check, not null.
      Returns:
      true if the value can be set as a user
    • setPropertyAsUser

      protected void setPropertyAsUser(String property, Serializable value)
      Updates an element property of the wrapped component as if the update was sent by the browser, so that events derived from the property change report isFromClient() == true. Ends with a roundTrip().

      Use this for components that expose state as a synchronized element property rather than as a field value, such as the opened property of Details and Accordion.

      Parameters:
      property - name of the property to update, not null.
      value - the value as the client would send it, may be null.
      Throws:
      IllegalStateException - if the property does not accept updates from the client