Skip to main content

Element Lookup

Drama Finder provides static factory methods on element classes to locate Vaadin components using accessibility-first patterns. Instead of writing complex CSS selectors or XPath expressions, you can find elements by their accessible names, labels, and text content.

Factory Method Pattern

Every element class provides static factory methods that combine tag names with ARIA role queries for robust, accessible element lookup.

Basic Lookup by Label

Most input fields support getByLabel() which finds elements by their accessible label:
// Find a text field by its label
TextFieldElement nameField = TextFieldElement.getByLabel(page, "Full Name");

// Find a date picker by its label
DatePickerElement birthDate = DatePickerElement.getByLabel(page, "Birth Date");

// Find a checkbox by its label
CheckboxElement termsCheckbox = CheckboxElement.getByLabel(page, "I agree to the terms");
Factory methods use ARIA roles internally to ensure accurate matching. For example, TextFieldElement.getByLabel() searches for elements with the TEXTBOX role.

Lookup by Text Content

Buttons and other text-based elements support getByText() to find elements by their visible text:
// Find a button by its text
ButtonElement saveButton = ButtonElement.getByText(page, "Save");
ButtonElement cancelButton = ButtonElement.getByText(page, "Cancel");

// getByLabel is an alias for getByText on buttons
ButtonElement submitButton = ButtonElement.getByLabel(page, "Submit");

ARIA Role-Based Lookup

Factory methods leverage Playwright’s getByRole() with appropriate ARIA roles for each component type:
// TextFieldElement uses AriaRole.TEXTBOX
public static TextFieldElement getByLabel(Page page, String label) {
    return new TextFieldElement(
        page.locator(FIELD_TAG_NAME)
            .filter(new Locator.FilterOptions()
                .setHas(page.getByRole(AriaRole.TEXTBOX,
                    new Page.GetByRoleOptions().setName(label))))
            .first());
}

// ComboBoxElement uses AriaRole.COMBOBOX
public static ComboBoxElement getByLabel(Page page, String label) {
    return new ComboBoxElement(
        page.locator(FIELD_TAG_NAME)
            .filter(new Locator.FilterOptions()
                .setHas(page.getByRole(AriaRole.COMBOBOX,
                    new Page.GetByRoleOptions().setName(label))))
            .first());
}
Using ARIA roles ensures your tests align with how assistive technologies and real users interact with your application.

Scoped Lookups

All factory methods support both page-level and scoped lookups. Scoped lookups restrict the search to a specific container:
// Page-level lookup
ButtonElement saveButton = ButtonElement.getByText(page, "Save");

// Scoped lookup within a dialog
DialogElement dialog = DialogElement.get(page);
ButtonElement dialogSaveButton = ButtonElement.getByText(dialog.getLocator(), "Save");

// Scoped lookup within a form
Locator formLocator = page.locator("form.user-details");
TextFieldElement emailField = TextFieldElement.getByLabel(formLocator, "Email");

Scoped Lookup Example

// Multiple forms on the page - scope to avoid ambiguity
Locator loginForm = page.locator("form#login");
Locator signupForm = page.locator("form#signup");

TextFieldElement loginEmail = TextFieldElement.getByLabel(loginForm, "Email");
TextFieldElement signupEmail = TextFieldElement.getByLabel(signupForm, "Email");

loginEmail.setValue("[email protected]");
signupEmail.setValue("[email protected]");

Lookup by ID or Custom Selector

Some elements like Grid provide additional lookup methods:
// Grid lookup by ID
GridElement grid = GridElement.getById(page, "user-grid");

// First grid on the page
GridElement firstGrid = GridElement.get(page);

// Grid within a container
Locator container = page.locator(".data-panel");
GridElement scopedGrid = GridElement.get(container);
For elements without dedicated factory methods, construct them directly:
// Direct construction with custom locator
AccordionElement accordion = new AccordionElement(page.locator(".custom-css"));

Common ARIA Roles

Using the wrong ARIA role will cause your lookups to fail. Always verify the role of the internal input element.
Here’s a reference of ARIA roles used by common Vaadin components:
Component TypeARIA RoleFactory Method
Text FieldTEXTBOXgetByLabel()
Number FieldSPINBUTTONgetByLabel()
Date PickerCOMBOBOXgetByLabel()
Time PickerCOMBOBOXgetByLabel()
Combo BoxCOMBOBOXgetByLabel()
ButtonBUTTONgetByText()
CheckboxCHECKBOXgetByLabel()
Radio ButtonRADIOgetByLabel()

Advanced Options

Factory methods that accept custom role options provide flexibility for complex scenarios:
// Button with exact name matching
ButtonElement exactButton = ButtonElement.getByText(page,
    new Page.GetByRoleOptions()
        .setName("Save")
        .setExact(true)
);

// Button that is not disabled
ButtonElement enabledButton = ButtonElement.getByText(page,
    new Page.GetByRoleOptions()
        .setName("Submit")
        .setDisabled(false)
);

Best Practices

Always use factory methods that leverage accessible names (labels, text content) rather than CSS selectors or XPath. This makes tests more maintainable and accessible.
// Good: Accessible and maintainable
TextFieldElement nameField = TextFieldElement.getByLabel(page, "Full Name");

// Bad: Brittle and not accessibility-focused
TextFieldElement nameField = new TextFieldElement(page.locator("#name-field"));
When your locator might match multiple elements, always use .first() or scope your query:
// Locator automatically uses .first() in factory methods
ButtonElement button = ButtonElement.getByText(page, "Submit");

// When constructing directly, add .first()
ButtonElement firstButton = new ButtonElement(
    page.locator("vaadin-button").first()
);
When multiple elements share the same label or text, use scoped lookups:
// Scope to a specific dialog or container
Locator dialogLocator = page.locator("vaadin-dialog[opened]");
ButtonElement dialogButton = ButtonElement.getByText(dialogLocator, "OK");

Build docs developers (and LLMs) love