Skip to main content

Core Principles

Writing good tests with Drama Finder requires following Playwright best practices while leveraging the Vaadin-specific element wrappers. This guide distills lessons from the Drama Finder codebase and community experience.

Element Selection

Prefer ARIA Roles Over Tag Names

Always use accessible names (labels) to locate elements rather than CSS selectors or tag names.
Using accessible names makes tests resilient to implementation changes and ensures your app is accessible.

Always Use .first() for Single Elements

When using generic locators that might match multiple elements, always call .first() to avoid ambiguity:

Use Scoped Lookups for Nested Elements

When working with elements inside containers, use scoped lookups:

Assertions

Use Playwright Assertions with Auto-Retry

Playwright assertions automatically retry until they pass or timeout, making tests resilient to timing issues.

Use Element-Specific Assertion Methods

Drama Finder provides assertion methods that handle common patterns correctly:

Assertion Symmetry Pattern

For every state, provide both positive and negative assertions:

Locator Usage

Understand Component vs. Input Locators

Vaadin components often have a wrapper element and an internal input element. Know which to use:

Shadow DOM Considerations

Playwright CSS selectors pierce shadow DOM by default, but XPath does not:
Avoid complex XPath selectors. Prefer CSS with part and slot attributes for Vaadin components.

Use Part Selectors for Internal Components

Vaadin components expose internal parts via the part attribute:

Waiting and Timing

Avoid Hard Waits

Never use Thread.sleep() or page.waitForTimeout() in test logic:
The small 10ms waits in AbstractBasePlaywrightIT helper methods are for event propagation, not for waiting on async operations.

Let Playwright Wait for Elements

Playwright automatically waits for elements to be actionable:

Use Custom Wait Conditions Sparingly

Only use custom waits when built-in waits aren’t sufficient:

Test Organization

One Assertion Focus Per Test

While tests can have multiple assertions, each test should verify one specific behavior:

Use Descriptive Test Names

Test names should describe the behavior being tested:
Use nested test classes to organize related tests:

Performance and Efficiency

Reuse Page Instances

The AbstractBasePlaywrightIT creates a new page for each test but reuses the browser. Don’t create additional page instances unless needed:

Minimize Navigation

Avoid navigating multiple times in a single test:
If you need to test multiple pages, create separate test methods or classes.

Use Constants for Element Identifiers

Define constants for frequently used labels and text:

Null Handling

Check for Null in Assertions

When asserting absence of attributes or text, properly handle null:

Event Handling

Dispatch Events When Needed

Some programmatic changes require dispatching events:

Prefer Real User Actions

When possible, use real user interactions over programmatic changes:

Documentation

Document Public APIs

All public methods should have Javadoc:

Document Behavioral Quirks

Note any non-obvious behavior:

Summary Checklist

  • Use accessible names (labels) for element lookup
  • Always call .first() on potentially ambiguous locators
  • Use scoped lookups for nested elements
  • Prefer ARIA roles over CSS selectors or tag names
  • Use Playwright assertions with auto-retry
  • Use element-specific assertion methods
  • Provide both positive and negative assertions
  • Handle null values properly
  • Know when to use component vs. input locators
  • Use CSS selectors (pierce shadow DOM) not XPath
  • Use part selectors for internal elements
  • Understand shadow DOM piercing rules
  • Never use hard waits (Thread.sleep())
  • Let Playwright wait for elements automatically
  • Use Playwright assertions for waiting
  • Only use custom waits when necessary
  • One behavior focus per test
  • Use descriptive test names
  • Group related tests with nested classes
  • Arrange-Act-Assert structure
  • Reuse the provided page instance
  • Minimize navigation in tests
  • Use constants for element identifiers
  • Consider parallel test execution

Next Steps

Common Patterns

Explore real-world testing scenarios

Troubleshooting

Solutions to common testing issues