Skip to main content

Overview

This guide presents common testing patterns extracted from real Drama Finder tests. Each pattern includes working examples from the test suite.

Form Testing Patterns

Basic Form Validation

Test form validation by checking required fields, format validation, and error messages:
@Test
public void testRequiredFieldValidation() {
    TextFieldElement nameField = TextFieldElement.getByLabel(page, "Full Name");
    ButtonElement submitButton = ButtonElement.getByText(page, "Submit");
    
    // Initially valid (untouched)
    nameField.assertValid();
    
    // Focus and blur without entering value
    nameField.focus();
    submitButton.focus(); // Blur name field
    
    // Should show validation error
    nameField.assertInvalid();
    nameField.assertErrorMessage("Name is required");
    
    // Enter valid value
    nameField.setValue("John Doe");
    nameField.assertValid();
}

Form with Multiple Validation Rules

Test complex validation with min/max length, patterns, and custom validators:
@Test
public void testPasswordFieldValidation() {
    TextFieldElement password = TextFieldElement.getByLabel(page, "Password");
    
    // Test min length
    password.assertMinLength(8);
    password.setValue("short");
    password.assertInvalid();
    password.assertErrorMessage("Password must be at least 8 characters");
    
    // Test pattern matching (must contain number)
    password.setValue("longpassword");
    password.assertInvalid();
    password.assertErrorMessage("Password must contain at least one number");
    
    // Valid password
    password.setValue("SecurePass123");
    password.assertValid();
}

Testing Field Components

Test helper text, prefix, suffix, and other field decorations:
@Test
public void testFieldComponents() {
    TextFieldElement priceField = TextFieldElement.getByLabel(page, "Price");
    
    // Helper text
    priceField.assertHelperHasText("Enter price in USD");
    assertEquals("Enter price in USD", priceField.getHelperText());
    
    // Prefix
    assertThat(priceField.getPrefixLocator()).hasText("$");
    priceField.assertPrefixHasText("$");
    assertEquals("$", priceField.getPrefixText());
    
    // Suffix
    assertThat(priceField.getSuffixLocator()).hasText("USD");
    priceField.assertSuffixHasText("USD");
}

Testing Helper Components

Some fields accept components as helpers:
@Test
public void testHelperComponent() {
    ComboBoxElement field = ComboBoxElement.getByLabel(page, "Country");
    
    // Helper contains another ComboBox for currency
    ComboBoxElement currencyHelper = new ComboBoxElement(field.getHelperLocator());
    currencyHelper.assertVisible();
    currencyHelper.assertHelperHasText("Select currency");
    currencyHelper.selectItem("USD");
}

Selection Component Patterns

ComboBox Testing

Basic Selection

@Test
public void testComboBoxSelection() {
    ComboBoxElement sortBy = ComboBoxElement.getByLabel(page, "Sort by");
    sortBy.assertVisible();
    
    // Initially no selection
    sortBy.assertValue("");
    
    // Select item
    sortBy.selectItem("Rating: high to low");
    sortBy.assertValue("Rating: high to low");
    assertEquals("Rating: high to low", sortBy.getValue());
}

Filter and Select

@Test
public void testComboBoxFiltering() {
    ComboBoxElement fruits = ComboBoxElement.getByLabel(page, "Fruit");
    
    // Filter to narrow results
    fruits.filterAndSelectItem("Apr", "Apricot");
    fruits.assertValue("Apricot");
}

Lazy Loading ComboBox

@Test
public void testLazyComboBox() {
    ComboBoxElement lazyBox = ComboBoxElement.getByLabel(page, "Lazy Items");
    
    // Filter for specific item beyond initial load
    lazyBox.filterAndSelectItem("Item 250", "Item 250");
    lazyBox.assertValue("Item 250");
    
    // Test filter narrowing
    lazyBox.setFilter("Item 49");
    lazyBox.assertItemCount(11); // Item 49, Item 490-499
    lazyBox.close();
}

Custom Value Entry

@Test
public void testComboBoxCustomValue() {
    ComboBoxElement customBox = ComboBoxElement.getByLabel(page, "Custom Entry");
    
    // Type custom value and press Enter
    customBox.getInputLocator().fill("Custom entry");
    customBox.getInputLocator().press("Enter");
    
    // Verify custom value was accepted
    assertThat(page.locator("#custom-value-display")).hasText("Custom entry");
}

Clear Button

@Test
public void testComboBoxClearButton() {
    ComboBoxElement box = ComboBoxElement.getByLabel(page, "With Clear Button");
    
    // Select value
    box.selectItem("Option 1");
    box.assertValue("Option 1");
    
    // Clear selection
    box.clickClearButton();
    box.assertValue("");
}

DatePicker Testing

@Test
public void testDatePickerWithMinMax() {
    DatePickerElement vacationDate = DatePickerElement.getByLabel(page, "Vacation Date");
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    
    LocalDate today = LocalDate.now();
    LocalDate validDate = today.plusDays(15);
    LocalDate tooLate = today.plusDays(40);
    LocalDate tooEarly = today.minusDays(1);
    
    // Test valid date
    vacationDate.setValue(validDate);
    vacationDate.assertValue(validDate);
    vacationDate.assertValue(formatter.format(validDate));
    vacationDate.assertValid();
    
    // Test max date exceeded
    vacationDate.setValue(tooLate);
    vacationDate.assertInvalid();
    vacationDate.assertErrorMessage("Maximum number of days exceeded.");
    
    // Test min date not met
    vacationDate.setValue(tooEarly);
    vacationDate.assertInvalid();
    vacationDate.assertErrorMessage("Minimum number of days exceeded.");
}

Interactive Component Patterns

Button Testing

@Test
public void testButton() {
    ButtonElement button = ButtonElement.getByText(page, "Click me");
    
    // Test initial state
    button.assertEnabled();
    button.assertVisible();
    button.assertTheme("primary");
    button.assertCssClass("custom-button");
    
    // Test click action
    button.click();
    assertThat(page.getByText("Button clicked!")).isVisible();
}

@Test
pubic void testButtonWithTooltip() {
    ButtonElement button = ButtonElement.getByText(page, "Help");
    button.assertTooltipHasText("Click for help");
}

@Test
public void testDisabledButton() {
    ButtonElement button = ButtonElement.getByText(page, "Disabled");
    button.assertDisabled();
}

Checkbox Testing

@Test
public void testCheckbox() {
    CheckboxElement checkbox = CheckboxElement.getByLabel(page, "Accept Terms");
    
    // Initial state
    checkbox.assertVisible();
    checkbox.assertNotChecked();
    checkbox.assertEnabled();
    
    // Check and uncheck
    checkbox.check();
    checkbox.assertChecked();
    
    checkbox.uncheck();
    checkbox.assertNotChecked();
}

@Test
public void testIndeterminateCheckbox() {
    CheckboxElement checkbox = CheckboxElement.getByLabel(page, "Select All");
    
    checkbox.assertIndeterminate();
    
    // Clicking removes indeterminate state
    checkbox.check();
    checkbox.assertNotIndeterminate();
    checkbox.assertChecked();
}

@Test
public void testRequiredCheckbox() {
    CheckboxElement terms = CheckboxElement.getByLabel(page, "I agree");
    
    // Valid when checked
    terms.check();
    terms.assertValid();
    
    // Invalid when unchecked
    terms.uncheck();
    terms.assertInvalid();
    terms.assertErrorMessage("You must agree to the terms");
}

Accordion Testing

@Test
public void testAccordion() {
    AccordionElement accordion = new AccordionElement(page.locator(".faq-accordion"));
    accordion.assertPanelCount(4);
    
    // Test initially opened panel
    AccordionPanelElement panel1 = accordion.getPanel("Question 1");
    panel1.assertOpened();
    panel1.assertContentVisible();
    assertThat(panel1.getContentLocator()).hasText("Answer to question 1");
    
    // Open different panel (first closes)
    accordion.openPanel("Question 2");
    panel1.assertClosed();
    
    AccordionPanelElement panel2 = accordion.getPanel("Question 2");
    panel2.assertOpened();
    
    // Test disabled panel
    AccordionPanelElement disabledPanel = accordion.getPanel("Disabled");
    disabledPanel.assertDisabled();
    disabledPanel.assertClosed();
    disabledPanel.getSummaryLocator().click();
    disabledPanel.assertClosed(); // Still closed
}

State Management Patterns

Focus Management

@Test
public void testFocusManagement() {
    TextFieldElement field1 = TextFieldElement.getByLabel(page, "First Field");
    TextFieldElement field2 = TextFieldElement.getByLabel(page, "Second Field");
    
    // First field starts focused
    assertEquals("", field1.getLocator().getAttribute("focused"));
    field1.assertIsFocused();
    field2.assertIsNotFocused();
    
    // Move focus to second field
    field2.focus();
    field2.assertIsFocused();
    field1.assertIsNotFocused();
}

Enable/Disable State

@Test
public void testEnabledDisabledToggle() {
    TextFieldElement field = TextFieldElement.getByLabel(page, "Toggle Field");
    ButtonElement toggleButton = ButtonElement.getByText(page, "Toggle Enable");
    
    // Initially disabled
    field.assertDisabled();
    
    // Enable field
    toggleButton.click();
    field.assertEnabled();
    
    // Disable again
    toggleButton.click();
    field.assertDisabled();
}

Read-Only State

@Test
public void testReadOnlyField() {
    TextFieldElement field = TextFieldElement.getByLabel(page, "Read-only Field");
    field.assertReadOnly();
    field.assertValue("Cannot edit this");
    
    // Attempt to set value (should fail or be ignored)
    field.setValue("New value");
    field.assertValue("Cannot edit this"); // Value unchanged
}

Open/Close State

@Test
public void testComboBoxOpenClose() {
    ComboBoxElement combo = ComboBoxElement.getByLabel(page, "Select Item");
    
    // Initially closed
    combo.assertClosed();
    
    // Open
    combo.open();
    combo.assertOpened();
    combo.assertItemCount(5);
    
    // Close
    combo.close();
    combo.assertClosed();
}

Accessibility Testing Patterns

ARIA Labels

@Test
public void testAriaLabel() {
    // Button with aria-label (no visible text)
    ButtonElement iconButton = ButtonElement.getByText(page, "Close");
    iconButton.assertAriaLabel("Close");
    
    // Field with aria-label (no visible label)
    TextFieldElement field = TextFieldElement.getByLabel(page, "Invisible Label");
    field.assertAriaLabel("Invisible Label");
    field.assertLabel(null); // No visible label element
}

ARIA Labelled By

@Test
public void testAriaLabelledBy() {
    // Field labeled by external element
    TextFieldElement field = TextFieldElement.getByLabel(page, "Labelled By External");
    field.assertVisible();
    field.assertAriaLabel(null); // No aria-label attribute
    // Label comes from aria-labelledby reference
}

Theme and Styling

@Test
public void testThemeAttributes() {
    TextFieldElement field = TextFieldElement.getByLabel(page, "Small Field");
    field.assertTheme("small");
    
    ButtonElement primaryButton = ButtonElement.getByText(page, "Save");
    primaryButton.assertTheme("primary");
    
    ComboBoxElement largeCombo = ComboBoxElement.getByLabel(page, "Large Combo");
    largeCombo.assertTheme("large");
}

@Test
public void testCssClasses() {
    ButtonElement customButton = ButtonElement.getByText(page, "Custom");
    customButton.assertCssClass("custom-button");
    assertThat(customButton.getLocator()).hasClass("custom-button");
}

Grid and List Patterns

Basic Grid Testing

@Test
public void testGrid() {
    GridElement grid = new GridElement(page.locator("vaadin-grid"));
    
    // Check row count
    grid.assertRowCount(10);
    
    // Get cell value
    assertEquals("John Doe", grid.getCellValue(0, "Name"));
    assertEquals("[email protected]", grid.getCellValue(0, "Email"));
    
    // Test row selection
    grid.selectRow(0);
    grid.assertRowSelected(0);
}

Filtering Grids

@Test
public void testGridFiltering() {
    GridElement grid = new GridElement(page.locator("vaadin-grid"));
    TextFieldElement filterField = TextFieldElement.getByLabel(page, "Filter");
    
    // Initial row count
    grid.assertRowCount(50);
    
    // Apply filter
    filterField.setValue("John");
    page.waitForTimeout(500); // Wait for debounced filter
    
    // Verify filtered results
    grid.assertRowCount(3);
}

Dialog and Overlay Patterns

Dialog Testing

@Test
public void testDialog() {
    ButtonElement openButton = ButtonElement.getByText(page, "Open Dialog");
    openButton.click();
    
    DialogElement dialog = DialogElement.get(page);
    dialog.assertOpened();
    
    // Interact with dialog contents
    ButtonElement confirmButton = ButtonElement.getByText(dialog.getLocator(), "Confirm");
    confirmButton.click();
    
    dialog.assertClosed();
}

Notification Testing

@Test
public void testNotification() {
    ButtonElement saveButton = ButtonElement.getByText(page, "Save");
    saveButton.click();
    
    NotificationElement notification = NotificationElement.get(page);
    notification.assertOpened();
    notification.assertText("Saved successfully");
    notification.assertTheme("success");
    
    // Wait for auto-close or manually close
    notification.close();
    notification.assertClosed();
}

Context Menu Testing

@Test
public void testContextMenu() {
    ButtonElement menuButton = ButtonElement.getByText(page, "Menu");
    menuButton.click();
    
    ContextMenuElement menu = ContextMenuElement.get(page);
    menu.assertOpened();
    
    // Click menu item
    menu.clickItem("Edit");
    
    assertThat(page.getByText("Editing...")).isVisible();
}

Complex Interaction Patterns

Multi-Step Form Wizard

@Test
public void testMultiStepWizard() {
    // Step 1: Personal Info
    TextFieldElement name = TextFieldElement.getByLabel(page, "Name");
    name.setValue("John Doe");
    
    ButtonElement nextButton = ButtonElement.getByText(page, "Next");
    nextButton.click();
    
    // Step 2: Address
    TextFieldElement address = TextFieldElement.getByLabel(page, "Address");
    address.assertVisible();
    address.setValue("123 Main St");
    nextButton.click();
    
    // Step 3: Review and Submit
    assertThat(page.getByText("Name: John Doe")).isVisible();
    assertThat(page.getByText("Address: 123 Main St")).isVisible();
    
    ButtonElement submitButton = ButtonElement.getByText(page, "Submit");
    submitButton.click();
    
    assertThat(page.getByText("Form submitted successfully")).isVisible();
}

Master-Detail Pattern

@Test
public void testMasterDetail() {
    GridElement masterGrid = new GridElement(page.locator("#master-grid"));
    
    // Select item in master
    masterGrid.selectRow(0);
    
    // Verify detail panel appears
    TextFieldElement detailName = TextFieldElement.getByLabel(page, "Detail Name");
    detailName.assertVisible();
    detailName.assertValue("John Doe");
    
    // Edit in detail
    detailName.setValue("Jane Doe");
    ButtonElement saveButton = ButtonElement.getByText(page, "Save");
    saveButton.click();
    
    // Verify master updated
    assertEquals("Jane Doe", masterGrid.getCellValue(0, "Name"));
}

Drag and Drop (if supported)

@Test
public void testDragAndDrop() {
    Locator sourceItem = page.locator("#item-1");
    Locator targetZone = page.locator("#drop-zone");
    
    sourceItem.dragTo(targetZone);
    
    assertThat(targetZone.locator("#item-1")).isVisible();
    assertThat(page.getByText("Item moved")).isVisible();
}

Testing Utilities

Custom Wait Conditions

// Wait for data to load
public void waitForDataLoaded() {
    page.waitForFunction("() => window.dataLoaded === true");
}

// Wait for specific element count
public void waitForItemCount(int expectedCount) {
    page.waitForFunction(
        "(count) => document.querySelectorAll('.item').length === count",
        expectedCount
    );
}

Reusable Test Helpers

// Login helper
private void login(String username, String password) {
    TextFieldElement userField = TextFieldElement.getByLabel(page, "Username");
    TextFieldElement passField = TextFieldElement.getByLabel(page, "Password");
    ButtonElement loginButton = ButtonElement.getByText(page, "Login");
    
    userField.setValue(username);
    passField.setValue(password);
    loginButton.click();
    
    assertThat(page).hasURL("/dashboard");
}

// Fill form helper
private void fillUserForm(String name, String email, String phone) {
    TextFieldElement.getByLabel(page, "Name").setValue(name);
    TextFieldElement.getByLabel(page, "Email").setValue(email);
    TextFieldElement.getByLabel(page, "Phone").setValue(phone);
}

Next Steps

Troubleshooting

Solutions to common testing issues

Best Practices

Best practices for maintainable tests

Build docs developers (and LLMs) love