diff --git a/AGENTS.md b/AGENTS.md index 043c345..43ea7a6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,40 +1,69 @@ # Repository Guidelines ## Project Structure & Module Organization -- `dramafinder/` — Core Playwright helpers for Vaadin (`src/main/java/...`), resources under `src/main/resources`. -- `dramafinder-demo/` — Spring Boot Vaadin demo app; integration tests in `src/test/java` with `*IT.java`. -- `dramafinder-test-reporting/` — Utilities for test reporting/aggregation. -- Root `pom.xml` — Maven multi-module parent (Java 17). + +- Root `pom.xml` — Core Playwright helpers for Vaadin (`src/main/java/...`), + resources under `src/main/resources`. ## Build, Test, and Development Commands + - Build all modules + unit tests: `./mvnw clean install` -- Run demo locally: `./mvnw -pl dramafinder-demo spring-boot:run` (serves at http://localhost:8080) -- Run integration tests (Failsafe, includes `**/*IT.java`): `./mvnw -pl dramafinder-demo verify -Pit` +- Run demo locally: `./mvnw -pl dramafinder-demo spring-boot:run` (serves + at http://localhost:8080) +- Run integration tests (Failsafe, includes `**/*IT.java`): + `./mvnw -B verify --file pom.xml` - Run a single test: - - Unit: `./mvnw -Dtest=MyClassTest test` - - IT: `./mvnw -pl dramafinder-demo -Dit.test=MyViewIT -Pit verify` + - IT: `./mvnw -Dit.test=MyViewIT -Pit verify` ## Coding Style & Naming Conventions -- Java 17; 4-space indent; organize imports; no trailing whitespace. -- Packages: lowercase (`org.vaadin.dramafinder`); classes: `PascalCase`; methods/fields: `camelCase`; constants: `UPPER_SNAKE_CASE`. -- Public API in `dramafinder` should be small, cohesive, and documented with Javadoc. + +- Java 21; 4-space indent; organize imports; no trailing whitespace. +- Packages: lowercase (`org.vaadin.dramafinder`); classes: `PascalCase`; + methods/fields: `camelCase`; constants: `UPPER_SNAKE_CASE`. +- Public API in `dramafinder` should be small, cohesive, and documented with + Javadoc. +- Prefer aria role for internal locators + +### Javadoc Conventions + +- Add a class-level Javadoc for each element class and shared mixin: + - Identify the Vaadin tag using inline code (e.g., `vaadin-text-field`). + - One–two sentence summary of responsibilities and notable behaviors. + - For factory helpers (e.g., `getByLabel`), mention the ARIA role used. +- For public methods, document parameters, return values, and null semantics + (especially for assertion helpers where `null` implies absence). +- Use `{@inheritDoc}` on simple overrides (e.g., locator accessors) to avoid + duplication. +- Keep Javadoc concise and consistent; prefer present tense and active voice. ## Testing Guidelines + - Frameworks: JUnit 5, Playwright (Java), Axe-core checks in demo. -- Unit tests live with their module; integration tests go in `dramafinder-demo/src/test/java/**/*IT.java`. -- Tests should be deterministic; avoid timing sleeps—prefer Playwright waits and assertions. +- Unit tests live with their module; integration tests go in + `src/test/java/**/*IT.java`. +- Tests should be deterministic; avoid timing sleeps—prefer Playwright waits and + assertions. ## Commit & Pull Request Guidelines -- Commits: short, imperative subject; optional scope prefix (e.g., `core:`, `demo:`). Example: `core: add VaadinQuery helper for nested locators`. -- PRs: describe intent and approach, link issues, list test coverage and manual steps; include screenshots/gifs for UI changes. -- Keep changes module-scoped; update README/AGENTS.md when commands or workflows change. + +- Commits: short, imperative subject; optional scope prefix (e.g., `core:`, + `demo:`). Example: `core: add TestFieldElement to test a Vaadin Textfield`. +- PRs: describe intent and approach, link issues, list test coverage and manual + steps; include screenshots/gifs for UI changes. +- Keep changes module-scoped; update README/AGENTS.md when commands or workflows + change. ## Security & Configuration Tips -- Requires Java 17. Vaadin demo uses Node tooling; first runs may download frontend and Playwright browser binaries. -- Do not commit generated/build output: `target/`, `frontend/generated/`, `vite.generated.ts`. -- Prefer configuration via `application.properties` in each module’s `src/main/resources`. + +- Requires Java 21. Vaadin demo uses Node tooling; first runs may download + frontend and Playwright browser binaries. +- Do not commit generated/build output: `target/`, `frontend/generated/`, + `vite.generated.ts`. +- Prefer configuration via `application.properties` in each module’s + `src/main/resources`. ## Agent-Specific Instructions -- Follow this file’s conventions for any edits. Keep patches minimal and focused. -- Add unit tests for new public APIs in `dramafinder`; use `*IT.java` only for end-to-end flows in `dramafinder-demo`. +- Follow this file’s conventions for any edits. Keep patches minimal and + focused. +- Use `*IT.java` only for end-to-end tests executed by Failsafe. diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..631d054 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,75 @@ +# Drama Finder Project Overview + +This document provides an overview of the Drama Finder project, its purpose, and key development aspects relevant for automated agents. + +## Project Purpose + +Drama Finder is a set of helper classes designed to facilitate testing of Vaadin applications using Playwright. It offers a collection of assertions and actions for Vaadin components, simplifying the creation of robust integration tests. + +## Key Technologies + +* **Vaadin:** Frontend framework for web applications. +* **Playwright:** A Node.js library to automate Chromium, Firefox and WebKit with a single API. Used here for browser automation and testing. +* **Spring Boot:** Used for the test/demo server and integration tests. +* **Maven:** Project build automation tool. +* **JUnit:** Testing framework. +* **Axe-core:** Used for accessibility testing within integration tests. + +## Project Structure Highlights + +* `src/main/java/`: Contains the core Java helper classes for Vaadin and Playwright integration. +* `src/test/java/`: Contains unit and integration tests for the Drama Finder library itself, as well as demo application tests. +* `pom.xml`: Maven project configuration, including dependencies and build profiles. + +## Development & Testing + +### Starting the Demo Server + +To run the demo application (used for testing the Drama Finder library): + +```bash +mvn spring-boot:run +``` + +The demo will be available at `http://localhost:8080`. + +### Running Unit Tests + +```bash +mvn test +``` + +### Running Integration Tests + +Integration tests are located in `src/test/java/.../it/` and are run with the `it` Maven profile. + +```bash +mvn -Pit verify +``` + +## How to Use Drama Finder + +To incorporate Drama Finder into a Vaadin project, add it as a test dependency in your `pom.xml`: + +```xml + + org.vaadin.addons + dramafinder + 1.0.0-SNAPSHOT + test + +``` + +Example of an integration test: + +```java +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class SimpleExampleViewIT extends SpringPlaywrightIT { + @Test + public void testTooltip() { + TextFieldElement textfield = TextFieldElement.getByLabel(page, "Textfield"); + textfield.assertVisible(); + textfield.assertTooltipHasText("Tooltip for textfield"); + } +} +``` diff --git a/README.md b/README.md index 2a5d66c..297b85f 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,15 @@ mvn spring-boot:run This deploys demo at http://localhost:8080 The demo is only here to run the test +### Javadoc + +Public APIs in the `dramafinder` module are documented with concise Javadoc: +- Element classes include a short summary referencing the underlying Vaadin + tag (e.g., `vaadin-text-field`) and any noteworthy behaviors. +- Public methods document parameters, return values, and null semantics. +- Factory helpers (e.g., `getByLabel`) note the ARIA role used to locate the + element. + ## Running tests To run the unit tests, execute the following command: diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/AbstractNumberFieldElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/AbstractNumberFieldElement.java index e400887..02f1954 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/AbstractNumberFieldElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/AbstractNumberFieldElement.java @@ -16,22 +16,43 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Base abstraction for Vaadin number-like fields. + *

+ * Provides shared behavior for numeric inputs, including access to step + * controls (increase/decrease buttons) and common mixins for validation, + * input handling, theming, accessibility, and focus. + */ public abstract class AbstractNumberFieldElement extends VaadinElement implements HasValidationPropertiesElement, HasInputFieldElement, HasPrefixElement, HasSuffixElement, HasClearButtonElement, HasPlaceholderElement, HasAllowedCharPatternElement, HasThemeElement, FocusableElement, HasAriaLabelElement, HasEnabledElement, HasTooltipElement { + /** + * Creates a new {@code AbstractNumberFieldElement}. + * + * @param locator the locator pointing at the component root element + */ public AbstractNumberFieldElement(Locator locator) { super(locator); } - + /** + * Whether the step controls (increase/decrease buttons) are visible. + * + * @return {@code true} if the attribute is present, otherwise {@code false} + */ public boolean getHasControls() { String v = getLocator().getAttribute("step-buttons-visible"); return Boolean.parseBoolean(v); } + /** + * Assert the visibility of step controls. + * + * @param hasControls expected presence of the controls + */ public void assertHasControls(boolean hasControls) { if (hasControls) { assertThat(getLocator()).hasAttribute("step-buttons-visible", ""); @@ -40,10 +61,16 @@ public void assertHasControls(boolean hasControls) { } } + /** + * Click the increase button. + */ public void clickIncreaseButton() { getLocator().locator("[part='increase-button']").click(); } + /** + * Click the decrease button. + */ public void clickDecreaseButton() { getLocator().locator("[part='decrease-button']").click(); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/AccordionElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/AccordionElement.java index 758b135..e22f6af 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/AccordionElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/AccordionElement.java @@ -5,44 +5,79 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Provides helpers to access panels by their summary text and to assert + * open/closed state and panel count. + */ @PlaywrightElement(AccordionElement.FIELD_TAG_NAME) public class AccordionElement extends VaadinElement implements HasStyleElement { public static final String FIELD_TAG_NAME = "vaadin-accordion"; + /** + * Create a new {@code AccordionElement}. + * + * @param locator the locator for the {@code } element + */ public AccordionElement(Locator locator) { super(locator); } + /** + * Assert the number of panels present in the accordion. + */ public void assertPanelCount(int count) { Locator panels = getLocator().locator(AccordionPanelElement.FIELD_TAG_NAME); assertThat(panels).hasCount(count); } + /** + * Get a panel by its summary text. + */ public AccordionPanelElement getPanel(String summary) { return AccordionPanelElement.getAccordionPanelBySummary(getLocator(), summary); } + /** + * Open a panel by its summary text. + */ public void openPanel(String summary) { getPanel(summary).setOpen(true); } + /** + * Close a panel by its summary text. + */ public void closePanel(String summary) { getPanel(summary).setOpen(false); } + /** + * Whether the panel with the given summary is open. + */ public boolean isPanelOpened(String summary) { return getPanel(summary).isOpen(); } + /** + * Assert that the panel with the given summary is open. + */ public void assertPanelOpened(String summary) { getPanel(summary).assertOpened(); } + /** + * Assert that the panel with the given summary is closed. + */ public void assertPanelClosed(String summary) { getPanel(summary).assertClosed(); } + /** + * Get the currently opened panel. + */ public AccordionPanelElement getOpenedPanel() { return AccordionPanelElement.getOpenedAccordionPanel(getLocator()); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/AccordionPanelElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/AccordionPanelElement.java index 8360ad9..7632a0c 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/AccordionPanelElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/AccordionPanelElement.java @@ -5,54 +5,72 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Offers utilities to toggle open state, read summary and access content. + */ @PlaywrightElement(AccordionPanelElement.FIELD_TAG_NAME) public class AccordionPanelElement extends VaadinElement { public static final String FIELD_TAG_NAME = "vaadin-accordion-panel"; public static final String FIELD_HEADING_TAG_NAME = "vaadin-accordion-heading"; + /** + * Create a new {@code AccordionPanelElement}. + */ public AccordionPanelElement(Locator locator) { super(locator); } + /** Assert that the panel is opened. */ public void assertOpened() { assertThat(getLocator()).hasAttribute("opened", ""); } + /** Assert that the panel is closed. */ public void assertClosed() { assertThat(getLocator()).not().hasAttribute("opened", ""); } + /** Whether the panel is open. */ public boolean isOpen() { return getLocator().getAttribute("opened") != null; } + /** Set the open state by clicking the summary when needed. */ public void setOpen(boolean open) { if (isOpen() != open) { getSummaryLocator().click(); } } + /** Locator pointing to the summary heading. */ public Locator getSummaryLocator() { return getLocator().locator(FIELD_HEADING_TAG_NAME); } + /** Text content of the summary heading. */ public String getSummaryText() { return getSummaryLocator().textContent(); } + /** Locator pointing to the first non-slotted content element. */ public Locator getContentLocator() { return getLocator().locator("xpath=./*[not(@slot)][1]"); } + /** Assert that the content area is visible. */ public void assertContentVisible() { assertThat(getContentLocator()).isVisible(); } + /** Assert that the content area is not visible. */ public void assertContentNotVisible() { assertThat(getContentLocator()).not().isVisible(); } + /** Get an accordion panel by its summary text within a scope. */ public static AccordionPanelElement getAccordionPanelBySummary(Locator locator, String summary) { return new AccordionPanelElement(locator.locator(FIELD_TAG_NAME).filter( new Locator.FilterOptions().setHas( @@ -61,6 +79,7 @@ public static AccordionPanelElement getAccordionPanelBySummary(Locator locator, ))); } + /** Get the currently opened accordion panel within a scope. */ public static AccordionPanelElement getOpenedAccordionPanel(Locator locator) { return new AccordionPanelElement(locator.locator(FIELD_TAG_NAME).filter( new Locator.FilterOptions().setHas( @@ -68,10 +87,12 @@ public static AccordionPanelElement getOpenedAccordionPanel(Locator locator) { ))); } + /** Assert that the panel is enabled. */ public void assertEnabled() { assertThat(getLocator()).not().hasAttribute("disabled", ""); } + /** Assert that the panel is disabled. */ public void assertDisabled() { assertThat(getLocator()).hasAttribute("disabled", ""); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/BigDecimalFieldElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/BigDecimalFieldElement.java index 571d58c..4862ce4 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/BigDecimalFieldElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/BigDecimalFieldElement.java @@ -16,6 +16,9 @@ import org.vaadin.addons.dramafinder.element.shared.HasTooltipElement; import org.vaadin.addons.dramafinder.element.shared.HasValidationPropertiesElement; +/** + * PlaywrightElement for {@code }. + */ @PlaywrightElement(BigDecimalFieldElement.FIELD_TAG_NAME) public class BigDecimalFieldElement extends VaadinElement implements HasValidationPropertiesElement, HasInputFieldElement, @@ -24,10 +27,22 @@ public class BigDecimalFieldElement extends VaadinElement public static final String FIELD_TAG_NAME = "vaadin-big-decimal-field"; + /** + * Create a new {@code BigDecimalFieldElement}. + * + * @param locator the locator for the {@code } element + */ public BigDecimalFieldElement(Locator locator) { super(locator); } + /** + * Get the {@code BigDecimalFieldElement} by its label. + * + * @param page the Playwright page + * @param label the accessible label of the field + * @return the matching {@code BigDecimalFieldElement} + */ public static BigDecimalFieldElement getByLabel(Page page, String label) { return new BigDecimalFieldElement( page.locator(FIELD_TAG_NAME) @@ -37,6 +52,13 @@ public static BigDecimalFieldElement getByLabel(Page page, String label) { ).first()); } + /** + * Get the {@code BigDecimalFieldElement} by its label within a given scope. + * + * @param locator the locator to search within + * @param label the accessible label of the field + * @return the matching {@code BigDecimalFieldElement} + */ public static BigDecimalFieldElement getByLabel(Locator locator, String label) { return new BigDecimalFieldElement( locator.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/ButtonElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/ButtonElement.java index 7415feb..7136438 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/ButtonElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/ButtonElement.java @@ -12,6 +12,12 @@ import org.vaadin.addons.dramafinder.element.shared.HasThemeElement; import org.vaadin.addons.dramafinder.element.shared.HasTooltipElement; +/** + * PlaywrightElement for {@code }. + *

+ * Provides lookup helpers based on accessible name or visible text and + * exposes common focus, aria-label, enablement, prefix/suffix and theming mixins. + */ @PlaywrightElement(ButtonElement.FIELD_TAG_NAME) public class ButtonElement extends VaadinElement implements FocusableElement, HasAriaLabelElement, HasEnabledElement, @@ -19,21 +25,33 @@ public class ButtonElement extends VaadinElement public static final String FIELD_TAG_NAME = "vaadin-button"; + /** + * Create a new {@code ButtonElement}. + * + * @param locator the locator for the {@code } element + */ public ButtonElement(Locator locator) { super(locator); } /** - * Get by label or text + * Get a {@code ButtonElement} by its accessible name or visible text. * - * @param page - * @param text - * @return + * @param page the Playwright page + * @param text the button's accessible name or text content + * @return the matching {@code ButtonElement} */ public static ButtonElement getByText(Page page, String text) { return getByText(page, new Page.GetByRoleOptions().setName(text)); } + /** + * Get a {@code ButtonElement} by its accessible name with custom role options. + * + * @param page the Playwright page + * @param options options for {@code getByRole} + * @return the matching {@code ButtonElement} + */ public static ButtonElement getByText(Page page, Page.GetByRoleOptions options) { return new ButtonElement( page.getByRole( @@ -43,10 +61,24 @@ public static ButtonElement getByText(Page page, Page.GetByRoleOptions options) ); } + /** + * Get a {@code ButtonElement} by its accessible name or visible text within a scope. + * + * @param locator the scope to search within + * @param text the button's accessible name or text content + * @return the matching {@code ButtonElement} + */ public static ButtonElement getByText(Locator locator, String text) { return getByText(locator, new Locator.GetByRoleOptions().setName(text)); } + /** + * Get a {@code ButtonElement} by its accessible name with custom role options within a scope. + * + * @param locator the scope to search within + * @param options options for {@code getByRole} + * @return the matching {@code ButtonElement} + */ public static ButtonElement getByText(Locator locator, Locator.GetByRoleOptions options) { return new ButtonElement( locator.getByRole( @@ -56,6 +88,9 @@ public static ButtonElement getByText(Locator locator, Locator.GetByRoleOptions ); } + /** + * Alias for {@link #getByText(Page, String)}. + */ public static ButtonElement getByLabel(Page page, String text) { return getByText(page, text); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/CheckboxElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/CheckboxElement.java index 9d198ff..086896c 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/CheckboxElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/CheckboxElement.java @@ -14,6 +14,12 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Provides helpers to read and modify checked/indeterminate state and + * access common mixins for label, helper, validation and enablement. + */ @PlaywrightElement(CheckboxElement.FIELD_TAG_NAME) public class CheckboxElement extends VaadinElement implements FocusableElement, HasAriaLabelElement, HasEnabledElement, @@ -21,6 +27,11 @@ public class CheckboxElement extends VaadinElement public static final String FIELD_TAG_NAME = "vaadin-checkbox"; + /** + * Create a new {@code CheckboxElement}. + * + * @param locator the locator for the {@code } element + */ public CheckboxElement(Locator locator) { super(locator); } @@ -40,42 +51,82 @@ public Locator getFocusLocator() { return getInputLocator(); } + /** + * Whether the checkbox is currently checked. + * + * @return {@code true} if checked + */ public boolean isChecked() { return getInputLocator().isChecked(); } + /** + * Assert that the checkbox is checked. + */ public void assertChecked() { assertThat(getInputLocator()).isChecked(); } + /** + * Assert that the checkbox is not checked. + */ public void assertNotChecked() { assertThat(getInputLocator()).not().isChecked(); } + /** + * Check the checkbox. + */ public void check() { getInputLocator().check(); } + /** + * Uncheck the checkbox. + */ public void uncheck() { getInputLocator().uncheck(); } + /** + * Whether the checkbox is in indeterminate state. + * + * @return {@code true} when indeterminate + */ public boolean isIndeterminate() { return getLocator().getAttribute("indeterminate") != null; } + /** + * Assert that the checkbox is indeterminate. + */ public void assertIndeterminate() { assertThat(getLocator()).hasAttribute("indeterminate", ""); } + /** + * Assert that the checkbox is not indeterminate. + */ public void assertNotIndeterminate() { assertThat(getLocator()).not().hasAttribute("indeterminate", ""); } + /** + * Set the indeterminate state. + * + * @param indeterminate {@code true} to set indeterminate + */ public void setIndeterminate(boolean indeterminate) { getLocator().evaluate("(el, val) => el.indeterminate = val", indeterminate); } + /** + * Get a {@code CheckboxElement} by its accessible label. + * + * @param page the Playwright page + * @param label the accessible label of the checkbox + * @return the matching {@code CheckboxElement} + */ public static CheckboxElement getByLabel(Page page, String label) { return new CheckboxElement( page.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/DatePickerElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/DatePickerElement.java index f6ac098..78077cc 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/DatePickerElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/DatePickerElement.java @@ -20,6 +20,11 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Adds convenience methods for {@link LocalDate} values and lookup by label. + */ @PlaywrightElement(DatePickerElement.FIELD_TAG_NAME) public class DatePickerElement extends VaadinElement implements HasInputFieldElement, HasValidationPropertiesElement, HasClearButtonElement, HasPlaceholderElement, HasThemeElement, FocusableElement, HasAriaLabelElement, @@ -27,15 +32,30 @@ public class DatePickerElement extends VaadinElement implements HasInputFieldEle public static final String FIELD_TAG_NAME = "vaadin-date-picker"; + /** + * Create a new {@code DatePickerElement}. + * + * @param locator the locator for the {@code } element + */ public DatePickerElement(Locator locator) { super(locator); } + /** + * Set the value using a {@link LocalDate} formatted as ISO-8601. + * + * @param date the date to set + */ public void setValue(LocalDate date) { String formattedDate = date.format(DateTimeFormatter.ISO_LOCAL_DATE); setProperty("value", formattedDate); } + /** + * Get the current value as a {@link LocalDate}. + * + * @return the parsed date or {@code null} when empty + */ public LocalDate getValueAsLocalDate() { String value = getValue(); if (value == null || value.isEmpty()) { @@ -72,7 +92,7 @@ public void setValue(String value) { /** - * Check if the input value equals to the parameter + * Assert that the input value equals the provided string. * * @param value formatted as in the view dd/mm/yyyy. */ @@ -82,9 +102,9 @@ public void assertValue(String value) { } /** - * Check if the value equals to the parameter + * Assert that the value equals the provided date. * - * @param value + * @param value expected {@link LocalDate} or {@code null} for empty */ public void assertValue(LocalDate value) { if (value != null) { @@ -95,6 +115,13 @@ public void assertValue(LocalDate value) { } + /** + * Get the {@code DatePickerElement} by its label. + * + * @param page the Playwright page + * @param label the accessible label of the field + * @return the matching {@code DatePickerElement} + */ public static DatePickerElement getByLabel(Page page, String label) { return new DatePickerElement( page.locator(FIELD_TAG_NAME) @@ -104,6 +131,13 @@ public static DatePickerElement getByLabel(Page page, String label) { ).first()); } + /** + * Get the {@code DatePickerElement} by its label within a given scope. + * + * @param locator the locator to search within + * @param label the accessible label of the field + * @return the matching {@code DatePickerElement} + */ public static DatePickerElement getByLabel(Locator locator, String label) { return new DatePickerElement( locator.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/DateTimePickerElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/DateTimePickerElement.java index f3c7869..bb7b429 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/DateTimePickerElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/DateTimePickerElement.java @@ -22,6 +22,12 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE; +/** + * PlaywrightElement for {@code }. + *

+ * Composes a {@link DatePickerElement} and {@link TimePickerElement} and exposes + * helpers to interact using {@link LocalDateTime}. + */ @PlaywrightElement(DateTimePickerElement.FIELD_TAG_NAME) public class DateTimePickerElement extends VaadinElement implements HasInputFieldElement, HasValidationPropertiesElement, HasClearButtonElement, HasPlaceholderElement, HasThemeElement, FocusableElement, HasAriaLabelElement, @@ -37,18 +43,33 @@ public class DateTimePickerElement extends VaadinElement implements HasInputFiel .append(TimePickerElement.LOCAL_TIME) .toFormatter(); + /** + * Create a new {@code DateTimePickerElement}. + * + * @param locator the locator for the {@code } element + */ public DateTimePickerElement(Locator locator) { super(locator); datePickerElement = new DatePickerElement(locator.locator(DatePickerElement.FIELD_TAG_NAME)); timePickerElement = new TimePickerElement(locator.locator(TimePickerElement.FIELD_TAG_NAME)); } + /** + * Set the value using a {@link LocalDateTime}. + * + * @param date the date-time to set + */ public void setValue(LocalDateTime date) { datePickerElement.setValue(date.toLocalDate()); timePickerElement.setValue(date.toLocalTime()); getLocator().dispatchEvent("change"); } + /** + * Get the current value as a {@link LocalDateTime}. + * + * @return the parsed value or {@code null} when empty + */ public LocalDateTime getValueAsLocalDateTime() { String value = getValue(); if (value == null || value.isEmpty()) { @@ -102,7 +123,7 @@ public void setValue(String value) { /** - * Check if the input value equals to the parameter + * Assert that the input value equals the provided string. * * @param value formatted as in the view dd/mm/yyyy hh:mm. */ @@ -112,9 +133,9 @@ public void assertValue(String value) { } /** - * Check if the value equals to the parameter + * Assert that the value equals the provided date-time. * - * @param value + * @param value expected {@link LocalDateTime} or {@code null} for empty */ public void assertValue(LocalDateTime value) { if (value != null) { @@ -125,6 +146,13 @@ public void assertValue(LocalDateTime value) { } + /** + * Get the {@code DateTimePickerElement} by its label. + * + * @param page the Playwright page + * @param label the accessible label of the field + * @return the matching {@code DateTimePickerElement} + */ public static DateTimePickerElement getByLabel(Page page, String label) { return new DateTimePickerElement( page.locator(FIELD_TAG_NAME) @@ -134,6 +162,13 @@ public static DateTimePickerElement getByLabel(Page page, String label) { ).first()); } + /** + * Get the {@code DateTimePickerElement} by its label within a given scope. + * + * @param locator the locator to search within + * @param label the accessible label of the field + * @return the matching {@code DateTimePickerElement} + */ public static DateTimePickerElement getByLabel(Locator locator, String label) { return new DateTimePickerElement( locator.locator(FIELD_TAG_NAME) @@ -141,22 +176,34 @@ public static DateTimePickerElement getByLabel(Locator locator, String label) { .first()); } + /** + * Set only the date part (string input) and dispatch change events. + */ public void setDate(String date) { datePickerElement.setValue(date); getLocator().page().keyboard().press("Enter"); getLocator().dispatchEvent("change"); } + /** + * Set only the time part (string input) and dispatch change events. + */ public void setTime(String date) { timePickerElement.setValue(date); getLocator().page().keyboard().press("Enter"); getLocator().dispatchEvent("change"); } + /** + * Assert the date sub-field value equals the expected string. + */ public void assertDateValue(String date) { datePickerElement.assertValue(date); } + /** + * Assert the time sub-field value equals the expected string. + */ public void assertTimeValue(String time) { timePickerElement.assertValue(time); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/DetailsElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/DetailsElement.java index 87d9280..a76af7c 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/DetailsElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/DetailsElement.java @@ -8,55 +8,71 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Provides helpers to open/close and access the summary/content. + */ @PlaywrightElement(DetailsElement.FIELD_TAG_NAME) public class DetailsElement extends VaadinElement implements HasStyleElement, HasThemeElement, HasTooltipElement { public static final String FIELD_TAG_NAME = "vaadin-details"; + /** Create a new {@code DetailsElement}. */ public DetailsElement(Locator locator) { super(locator); } + /** Assert that the component is enabled. */ public void assertEnabled() { assertThat(getLocator()).not().hasAttribute("disabled", ""); } + /** Assert that the component is disabled. */ public void assertDisabled() { assertThat(getLocator()).hasAttribute("disabled", ""); } + /** Assert that the details is opened. */ public void assertOpened() { assertThat(getLocator()).hasAttribute("opened", ""); } + /** Assert that the details is closed. */ public void assertClosed() { assertThat(getLocator()).not().hasAttribute("opened", ""); } + /** Whether the details is opened. */ public boolean isOpen() { return getLocator().getAttribute("opened") != null; } + /** Set the opened state by clicking the summary when necessary. */ public void setOpen(boolean open) { if (isOpen() != open) { getSummaryLocator().click(); } } + /** Locator for the summary element. */ public Locator getSummaryLocator() { return getLocator().locator("vaadin-details-summary"); } + /** Text of the summary element. */ public String getSummaryText() { return getSummaryLocator().textContent(); } + /** Locator for the currently visible content container. */ public Locator getContentLocator() { return getLocator().locator("> div[aria-hidden='false']"); } + /** Get a details component by its summary text. */ public static DetailsElement getBySummaryText(Page page, String summary) { return new DetailsElement( page.locator(FIELD_TAG_NAME).filter( @@ -67,10 +83,12 @@ public static DetailsElement getBySummaryText(Page page, String summary) { ); } + /** Assert that the content is visible. */ public void assertContentVisible() { assertThat(getContentLocator()).isVisible(); } + /** Assert that the content is not visible. */ public void assertContentNotVisible() { assertThat(getContentLocator()).not().isVisible(); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/DialogElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/DialogElement.java index f4d82b9..f8f7860 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/DialogElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/DialogElement.java @@ -8,67 +8,89 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Provides access to header/content/footer slots, modal flags and open state. + */ public class DialogElement extends VaadinElement implements HasThemeElement, HasStyleElement { public static final String FIELD_TAG_NAME = "vaadin-dialog-overlay"; + /** + * Create a {@code DialogElement} by resolving the dialog with ARIA role. + */ public DialogElement(Page page) { super(page.locator(FIELD_TAG_NAME)); } + /** Create a {@code DialogElement} from an existing locator. */ public DialogElement(Locator locator) { super(locator); } + /** Close the dialog using the Escape key. */ public void closeWithEscape() { getLocator().press("Escape"); } + /** Whether the dialog is open (visible). */ public boolean isOpen() { return getLocator().isVisible(); } + /** Assert that the dialog is open. */ public void assertOpen() { assertThat(getLocator()).hasAttribute("opened", ""); } + /** Whether the dialog is modal (i.e. not modeless). */ public boolean isModal() { return getLocator().getAttribute("modeless") == null; } + /** Assert that the dialog is modal. */ public void assertModal() { assertThat(getLocator()).not().hasAttribute("modeless", ""); } + /** Assert that the dialog is modeless. */ public void assertModeless() { assertThat(getLocator()).hasAttribute("modeless", ""); } + /** Assert that the dialog is closed (hidden). */ public void assertClosed() { assertThat(getLocator()).isHidden(); } + /** Get the header text from the title slot. */ public String getHeaderText() { return getLocator().locator("> [slot='title']").textContent(); } + /** Assert the header text matches. */ public void assertHeaderText(String headerText) { assertThat(getLocator().locator("> [slot='title']")).hasText(headerText); } + /** Locator for the header content slot. */ public Locator getHeaderLocator() { return getLocator().locator("> [slot='header-content']"); } + /** Locator for the dialog content (first non-slotted child). */ public Locator getContentLocator() { // using xpath to not pierce the shadow dom return getLocator().locator("xpath=./*[not(@slot)][1]"); } + /** Locator for the footer slot. */ public Locator getFooterLocator() { return getLocator().locator("> [slot='footer']"); } + /** Get a dialog by its header text (accessible name). */ public static DialogElement getByHeaderText(Page page, String summary) { return new DialogElement( page.getByRole(AriaRole.DIALOG, new Page.GetByRoleOptions().setName(summary)) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/EmailFieldElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/EmailFieldElement.java index f36613d..ba4bfea 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/EmailFieldElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/EmailFieldElement.java @@ -4,15 +4,30 @@ import com.microsoft.playwright.Page; import com.microsoft.playwright.options.AriaRole; +/** + * PlaywrightElement for {@code }. + */ @PlaywrightElement(EmailFieldElement.FIELD_TAG_NAME) public class EmailFieldElement extends TextFieldElement { public static final String FIELD_TAG_NAME = "vaadin-email-field"; + /** + * Create a new {@code EmailFieldElement}. + * + * @param locator the locator for the {@code } element + */ public EmailFieldElement(Locator locator) { super(locator); } + /** + * Get the {@code EmailFieldElement} by its label. + * + * @param page the Playwright page + * @param label the accessible label of the field + * @return the matching {@code EmailFieldElement} + */ public static EmailFieldElement getByLabel(Page page, String label) { return new EmailFieldElement( page.locator(FIELD_TAG_NAME) @@ -22,6 +37,13 @@ public static EmailFieldElement getByLabel(Page page, String label) { ).first()); } + /** + * Get the {@code EmailFieldElement} by its label within a given scope. + * + * @param locator the locator to search within + * @param label the accessible label of the field + * @return the matching {@code EmailFieldElement} + */ public static EmailFieldElement getByLabel(Locator locator, String label) { return new EmailFieldElement( locator.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/IntegerFieldElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/IntegerFieldElement.java index 6977cd0..aeee74d 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/IntegerFieldElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/IntegerFieldElement.java @@ -6,24 +6,51 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Provides typed helpers to read and modify integer-specific attributes + * such as {@code min}, {@code max}, and {@code step}, and convenient + * factory methods to locate the element by its accessible label. + */ @PlaywrightElement(IntegerFieldElement.FIELD_TAG_NAME) public class IntegerFieldElement extends AbstractNumberFieldElement { public static final String FIELD_TAG_NAME = "vaadin-integer-field"; + /** + * Creates a new {@code IntegerFieldElement}. + * + * @param locator the locator for the {@code } element + */ public IntegerFieldElement(Locator locator) { super(locator); } + /** + * Get the current {@code step} value. + * + * @return the step as an {@link Integer}, or {@code null} if not set + */ public Integer getStep() { String v = getInputLocator().getAttribute("step"); return v == null ? null : Integer.valueOf(v); } + /** + * Set the {@code step} value. + * + * @param step the step to apply + */ public void setStep(int step) { getInputLocator().evaluate("(el, v) => el.step = v", step); } + /** + * Assert that the {@code step} attribute matches the expected value. + * + * @param step the expected step, or {@code null} to assert that no explicit step is set + */ public void assertStep(Integer step) { if (step != null) { assertThat(getInputLocator()).hasAttribute("step", step + ""); @@ -32,15 +59,30 @@ public void assertStep(Integer step) { } } + /** + * Get the current {@code min} value. + * + * @return the minimum as an {@link Integer}, or {@code null} if not set + */ public Integer getMin() { String v = getInputLocator().getAttribute("min"); return v == null ? null : Integer.valueOf(v); } + /** + * Set the {@code min} value. + * + * @param min the minimum to apply + */ public void setMin(int min) { getInputLocator().evaluate("(el, v) => el.min = v", min); } + /** + * Assert that the {@code min} attribute matches the expected value. + * + * @param min the expected minimum, or {@code null} to assert that no explicit minimum is set + */ public void assertMin(Integer min) { if (min != null) { assertThat(getInputLocator()).hasAttribute("min", min + ""); @@ -49,15 +91,30 @@ public void assertMin(Integer min) { } } + /** + * Get the current {@code max} value. + * + * @return the maximum as an {@link Integer}, or {@code null} if not set + */ public Integer getMax() { String v = getInputLocator().getAttribute("max"); return v == null ? null : Integer.valueOf(v); } + /** + * Set the {@code max} value. + * + * @param max the maximum to apply + */ public void setMax(int max) { getInputLocator().evaluate("(el, v) => el.max = v", max); } + /** + * Assert that the {@code max} attribute matches the expected value. + * + * @param max the expected maximum, or {@code null} to assert that no explicit maximum is set + */ public void assertMax(Integer max) { if (max != null) { assertThat(getInputLocator()).hasAttribute("max", max + ""); @@ -66,6 +123,15 @@ public void assertMax(Integer max) { } } + /** + * Get the {@code IntegerFieldElement} by its label. + * + *

Matches the internal input by ARIA role {@code spinbutton} and accessible name.

+ * + * @param page the Playwright page + * @param label the accessible label of the field + * @return the matching {@code IntegerFieldElement} + */ public static IntegerFieldElement getByLabel(Page page, String label) { return new IntegerFieldElement( page.locator(FIELD_TAG_NAME) @@ -75,6 +141,15 @@ public static IntegerFieldElement getByLabel(Page page, String label) { ).first()); } + /** + * Get the {@code IntegerFieldElement} by its label within a given scope. + * + *

Searches under the provided locator and matches by accessible label.

+ * + * @param locator the locator to search within + * @param label the accessible label of the field + * @return the matching {@code IntegerFieldElement} + */ public static IntegerFieldElement getByLabel(Locator locator, String label) { return new IntegerFieldElement( locator.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/ListBoxElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/ListBoxElement.java index 952273a..cc3af9b 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/ListBoxElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/ListBoxElement.java @@ -13,6 +13,12 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Supports single and multiple selection, item-level enablement assertions, + * and label-based lookup. + */ @PlaywrightElement(ListBoxElement.FIELD_TAG_NAME) public class ListBoxElement extends VaadinElement implements HasAriaLabelElement, HasStyleElement, HasTooltipElement, @@ -22,24 +28,35 @@ public class ListBoxElement extends VaadinElement public static final String FIELD_ITEM_TAG_NAME = "vaadin-item"; public static final String MULTIPLE_ATTRIBUTE = "multiple"; + /** + * Create a new {@code ListBoxElement}. + * + * @param locator the locator for the {@code } element + */ public ListBoxElement(Locator locator) { super(locator); } /** - * select the item based on the text. - * In multiple mode, if the item is already selected unselect it + * Select the item based on its text. + * In multiple mode, toggles selection state when already selected. * - * @param item + * @param item visible label of the item */ public void selectItem(String item) { getItem(item).click(); } + /** + * Get the selected value for single-select list boxes. + */ public String getSingleSelectedValue() { return getLocatorValue().innerText(); } + /** + * Get all selected values for multi-select list boxes. + */ public List getSelectedValue() { return getLocatorValue().allTextContents(); } @@ -48,6 +65,9 @@ private Locator getLocatorValue() { return getLocator().locator("vaadin-item[selected]"); } + /** + * Assert that the selected values match the expected labels. + */ public void assertSelectedValue(String... expected) { int length = expected.length; assertThat(getLocatorValue()).hasCount(length); @@ -72,10 +92,16 @@ public void assertDisabled() { assertThat(getLocator()).hasAttribute("disabled", ""); } + /** + * Assert that a specific item is enabled. + */ public void assertItemEnabled(String item) { assertThat(getItem(item)).isEnabled(); } + /** + * Assert that a specific item is disabled. + */ public void assertItemDisabled(String item) { assertThat(getItem(item)).isDisabled(); } @@ -84,10 +110,16 @@ public boolean isMultiple() { return getLocator().getAttribute(MULTIPLE_ATTRIBUTE) != null; } + /** + * Assert that multiple selection is enabled. + */ public void assertMultiple() { assertThat(getLocator()).hasAttribute(MULTIPLE_ATTRIBUTE, ""); } + /** + * Assert that single selection mode is enabled. + */ public void assertSingle() { assertThat(getLocator()).not().hasAttribute(MULTIPLE_ATTRIBUTE, ""); } @@ -99,6 +131,9 @@ private Locator getItem(String label) { } + /** + * Get the {@code ListBoxElement} by its label. + */ public static ListBoxElement getByLabel(Page page, String label) { return new ListBoxElement( page.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/MenuBarElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/MenuBarElement.java index 6737622..0542893 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/MenuBarElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/MenuBarElement.java @@ -7,22 +7,33 @@ import org.vaadin.addons.dramafinder.element.shared.HasStyleElement; import org.vaadin.addons.dramafinder.element.shared.HasThemeElement; +/** + * PlaywrightElement for {@code }. + *

+ * Provides utilities to access menu items and open submenus. + */ public class MenuBarElement extends VaadinElement implements HasThemeElement, HasStyleElement, HasAriaLabelElement { public static final String FIELD_TAG_NAME = "vaadin-menu-bar"; + /** Create a {@code MenuBarElement} from the page. */ public MenuBarElement(Page page) { this(page.locator(FIELD_TAG_NAME)); } + /** Create a {@code MenuBarElement} from an existing locator. */ public MenuBarElement(Locator locator) { super(locator); } + /** Get a menu item by visible label. */ public MenuItemElement getMenuItemElement(String name) { return MenuItemElement.getByLabel(getLocator(), name); } + /** + * Click a menu item to open its submenu and return the submenu overlay. + */ public MenuElement openSubMenu(String name) { MenuItemElement menuItemElement = getMenuItemElement(name); menuItemElement.click(); @@ -30,6 +41,7 @@ public MenuElement openSubMenu(String name) { return new MenuElement(getLocator().page()); } + /** Get a menu bar by its accessible label. */ public static MenuBarElement getByLabel(Page page, String label) { return new MenuBarElement( page.getByRole(AriaRole.MENUBAR, new Page.GetByRoleOptions().setName(label)) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/MenuElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/MenuElement.java index 6858e2e..ec30255 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/MenuElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/MenuElement.java @@ -7,22 +7,29 @@ import org.vaadin.addons.dramafinder.element.shared.HasStyleElement; import org.vaadin.addons.dramafinder.element.shared.HasThemeElement; +/** + * PlaywrightElement for the menu overlay list {@code }. + */ public class MenuElement extends VaadinElement implements HasThemeElement, HasStyleElement, HasAriaLabelElement { public static final String FIELD_TAG_NAME = "vaadin-menu-bar-list-box"; + /** Create a {@code MenuElement} from the page. */ public MenuElement(Page page) { super(page.locator(FIELD_TAG_NAME)); } + /** Create a {@code MenuElement} from an existing locator. */ public MenuElement(Locator locator) { super(locator); } + /** Get a menu item by its visible label within this menu. */ public MenuItemElement getMenuItemElement(String name) { return MenuItemElement.getByLabel(getLocator(), name); } + /** Click a menu item to open its submenu and return the next overlay. */ public MenuElement openSubMenu(String name) { MenuItemElement menuItemElement = getMenuItemElement(name); menuItemElement.click(); @@ -31,6 +38,7 @@ public MenuElement openSubMenu(String name) { } + /** Get a menu overlay by its accessible label. */ public static MenuElement getByLabel(Page page, String label) { return new MenuElement( page.getByRole(AriaRole.MENU, new Page.GetByRoleOptions().setName(label)) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/MenuItemElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/MenuItemElement.java index 8d66823..7b145f0 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/MenuItemElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/MenuItemElement.java @@ -8,24 +8,31 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for individual menu items {@code }. + */ public class MenuItemElement extends VaadinElement implements HasThemeElement, HasStyleElement, HasAriaLabelElement { public static final String FIELD_TAG_NAME = "vaadin-menu-bar-button"; + /** Create a {@code MenuItemElement} from an existing locator. */ public MenuItemElement(Locator locator) { super(locator); } + /** Get a menu item by its accessible label within a scope. */ public static MenuItemElement getByLabel(Locator locator, String label) { return new MenuItemElement( locator.getByRole(AriaRole.MENUITEM, new Locator.GetByRoleOptions().setName(label)) ); } + /** Assert that the menu item is expanded (shows submenu). */ public void assertExpanded() { assertThat(getLocator()).hasAttribute("expanded", ""); } + /** Assert that the menu item is collapsed. */ public void assertCollapsed() { assertThat(getLocator()).not().hasAttribute("expanded", ""); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/NotificationElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/NotificationElement.java index b97ddc4..1997626 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/NotificationElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/NotificationElement.java @@ -7,30 +7,39 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for notification cards {@code }. + */ public class NotificationElement extends VaadinElement implements HasThemeElement, HasStyleElement { public static final String FIELD_TAG_NAME = "vaadin-notification-card"; + /** Create a {@code NotificationElement} from the page. */ public NotificationElement(Page page) { super(page.locator(FIELD_TAG_NAME)); } + /** Create a {@code NotificationElement} from an existing locator. */ public NotificationElement(Locator locator) { super(locator); } + /** Whether the notification is open (visible). */ public boolean isOpen() { return getLocator().isVisible(); } + /** Assert that the notification is open. */ public void assertOpen() { assertThat(getLocator()).isVisible(); } + /** Assert that the notification is closed. */ public void assertClosed() { assertThat(getLocator()).isHidden(); } + /** Locator for the notification content. */ public Locator getContentLocator() { return getLocator(); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/NumberFieldElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/NumberFieldElement.java index 270fd2c..fc07762 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/NumberFieldElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/NumberFieldElement.java @@ -7,24 +7,51 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Provides helpers for numeric attributes ({@code min}, {@code max}, {@code step}) + * using {@link Double} types and locator utilities to find the component by + * its accessible label. + */ @PlaywrightElement(NumberFieldElement.FIELD_TAG_NAME) public class NumberFieldElement extends AbstractNumberFieldElement { public static final String FIELD_TAG_NAME = "vaadin-number-field"; + /** + * Creates a new {@code NumberFieldElement}. + * + * @param locator the locator for the {@code } element + */ public NumberFieldElement(Locator locator) { super(locator); } + /** + * Get the current {@code step} value. + * + * @return the step as a {@link Double}, or {@code null} if not set + */ public Double getStep() { String v = getInputLocator().getAttribute("step"); return v == null ? null : Double.valueOf(v); } + /** + * Set the {@code step} value. + * + * @param step the step to apply + */ public void setStep(double step) { getInputLocator().evaluate("(el, v) => el.step = v", step); } + /** + * Assert that the {@code step} attribute matches the expected value. + * + * @param step the expected step, or {@code null} to assert that no explicit step is set + */ public void assertStep(Double step) { if (step != null) { assertThat(getInputLocator()).hasAttribute("step", NumberUtils.formatDouble(step)); @@ -33,15 +60,30 @@ public void assertStep(Double step) { } } + /** + * Get the current {@code min} value. + * + * @return the minimum as a {@link Double}, or {@code null} if not set + */ public Double getMin() { String v = getInputLocator().getAttribute("min"); return v == null ? null : Double.valueOf(v); } + /** + * Set the {@code min} value. + * + * @param min the minimum to apply + */ public void setMin(double min) { getInputLocator().evaluate("(el, v) => el.min = v", min); } + /** + * Assert that the {@code min} attribute matches the expected value. + * + * @param min the expected minimum, or {@code null} to assert that no explicit minimum is set + */ public void assertMin(Double min) { if (min != null) { assertThat(getInputLocator()).hasAttribute("min", NumberUtils.formatDouble(min)); @@ -50,15 +92,30 @@ public void assertMin(Double min) { } } + /** + * Get the current {@code max} value. + * + * @return the maximum as a {@link Double}, or {@code null} if not set + */ public Double getMax() { String v = getInputLocator().getAttribute("max"); return v == null ? null : Double.valueOf(v); } + /** + * Set the {@code max} value. + * + * @param max the maximum to apply + */ public void setMax(double max) { getInputLocator().evaluate("(el, v) => el.max = v", max); } + /** + * Assert that the {@code max} attribute matches the expected value. + * + * @param max the expected maximum, or {@code null} to assert that no explicit maximum is set + */ public void assertMax(Double max) { if (max != null) { assertThat(getInputLocator()).hasAttribute("max", NumberUtils.formatDouble(max)); @@ -67,6 +124,15 @@ public void assertMax(Double max) { } } + /** + * Get the {@code NumberFieldElement} by its label. + * + *

Matches the internal input by ARIA role {@code spinbutton} and accessible name.

+ * + * @param page the Playwright page + * @param label the accessible label of the field + * @return the matching {@code NumberFieldElement} + */ public static NumberFieldElement getByLabel(Page page, String label) { return new NumberFieldElement( page.locator(FIELD_TAG_NAME) @@ -76,6 +142,15 @@ public static NumberFieldElement getByLabel(Page page, String label) { ).first()); } + /** + * Get the {@code NumberFieldElement} by its label within a given scope. + * + *

Searches under the provided locator and matches by accessible label.

+ * + * @param locator the locator to search within + * @param label the accessible label of the field + * @return the matching {@code NumberFieldElement} + */ public static NumberFieldElement getByLabel(Locator locator, String label) { return new NumberFieldElement( locator.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/PasswordFieldElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/PasswordFieldElement.java index b2c10ec..2889c79 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/PasswordFieldElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/PasswordFieldElement.java @@ -4,15 +4,30 @@ import com.microsoft.playwright.Page; import com.microsoft.playwright.options.AriaRole; +/** + * PlaywrightElement for {@code }. + */ @PlaywrightElement(PasswordFieldElement.FIELD_TAG_NAME) public class PasswordFieldElement extends TextFieldElement { public static final String FIELD_TAG_NAME = "vaadin-password-field"; + /** + * Create a new {@code PasswordFieldElement}. + * + * @param locator the locator for the {@code } element + */ public PasswordFieldElement(Locator locator) { super(locator); } + /** + * Get the {@code PasswordFieldElement} by its label. + * + * @param page the Playwright page + * @param label the accessible label of the field + * @return the matching {@code PasswordFieldElement} + */ public static PasswordFieldElement getByLabel(Page page, String label) { return new PasswordFieldElement( page.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/PopoverElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/PopoverElement.java index b88e448..6c4ffce 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/PopoverElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/PopoverElement.java @@ -9,36 +9,46 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + */ public class PopoverElement extends VaadinElement implements HasThemeElement, HasStyleElement, HasAriaLabelElement { public static final String FIELD_TAG_NAME = "vaadin-popover-overlay"; + /** Create a {@code PopoverElement} by resolving the dialog with ARIA role. */ public PopoverElement(Page page) { // use xpath to exclude the shadow dom super(page.locator("//" + FIELD_TAG_NAME)); } + /** Create a {@code PopoverElement} from an existing locator. */ public PopoverElement(Locator locator) { super(locator); } + /** Whether the popover is open (visible). */ public boolean isOpen() { return getLocator().isVisible(); } + /** Assert that the popover is open. */ public void assertOpen() { assertThat(getLocator()).hasAttribute("opened", ""); } + /** Assert that the popover is closed (hidden). */ public void assertClosed() { assertThat(getLocator()).isHidden(); } + /** Locator for the popover content. */ public Locator getContentLocator() { return getLocator(); } + /** Get a popover by its accessible label. */ public static PopoverElement getByLabel(Page page, String label) { return new PopoverElement( page.getByRole(AriaRole.DIALOG, new Page.GetByRoleOptions().setName(label)) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/ProgressBarElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/ProgressBarElement.java index 02430e0..6b7553e 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/ProgressBarElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/ProgressBarElement.java @@ -7,24 +7,33 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Supports value/min/max setters and assertions and indeterminate state. + */ @PlaywrightElement(ProgressBarElement.FIELD_TAG_NAME) public class ProgressBarElement extends VaadinElement implements HasThemeElement, HasStyleElement { public static final String FIELD_TAG_NAME = "vaadin-progress-bar"; public static final String INDETERMINATE_ATTRIBUTE = "indeterminate"; + /** Create a {@code ProgressBarElement} from an existing locator. */ public ProgressBarElement(Locator locator) { super(locator); } + /** Current numeric value parsed from {@code aria-valuenow}. */ public double getValue() { return Double.parseDouble(getLocator().getAttribute("aria-valuenow")); } + /** Set the progress bar {@code value}. */ public void setValue(double min) { getLocator().evaluate("(el, v) => el.value = v", min); } + /** Assert that the numeric value matches. */ public void assertValue(Double expected) { if (expected != null) { assertThat(getLocator()).hasAttribute("aria-valuenow", NumberUtils.formatDouble(expected)); @@ -33,44 +42,54 @@ public void assertValue(Double expected) { } } + /** Get the {@code min} value. */ public Double getMin() { String v = getLocator().getAttribute("aria-valuemin"); return v == null ? null : Double.valueOf(v); } + /** Set the {@code min} value. */ public void setMin(double min) { getLocator().evaluate("(el, v) => el.min = v", min); } + /** Assert that {@code min} matches the expected value. */ public void assertMin(double min) { assertThat(getLocator()).hasAttribute("aria-valuemin", NumberUtils.formatDouble(min)); } + /** Get the {@code max} value. */ public Double getMax() { String v = getLocator().getAttribute("aria-valuemax"); return v == null ? null : Double.valueOf(v); } + /** Set the {@code max} value. */ public void setMax(double max) { getLocator().evaluate("(el, v) => el.max = v", max); } + /** Assert that {@code max} matches the expected value. */ public void assertMax(double max) { assertThat(getLocator()).hasAttribute("aria-valuemax", NumberUtils.formatDouble(max)); } + /** Whether the bar is indeterminate. */ public boolean isIndeterminate() { return getLocator().getAttribute(INDETERMINATE_ATTRIBUTE) != null; } + /** Assert indeterminate state. */ public void assertIndeterminate() { assertThat(getLocator()).hasAttribute(INDETERMINATE_ATTRIBUTE, ""); } + /** Assert not indeterminate. */ public void assertNotIndeterminate() { assertThat(getLocator()).not().hasAttribute(INDETERMINATE_ATTRIBUTE, ""); } + /** Set the indeterminate state. */ public void setIndeterminate(boolean indeterminate) { getLocator().evaluate("(el, val) => el.indeterminate = val", indeterminate); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/RadioButtonElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/RadioButtonElement.java index 3e83f29..d5bd844 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/RadioButtonElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/RadioButtonElement.java @@ -14,6 +14,9 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code } (package-private). + */ @PlaywrightElement(RadioButtonElement.FIELD_TAG_NAME) class RadioButtonElement extends VaadinElement implements FocusableElement, HasAriaLabelElement, HasEnabledElement, @@ -21,6 +24,9 @@ class RadioButtonElement extends VaadinElement public static final String FIELD_TAG_NAME = "vaadin-radio-button"; + /** + * Create a new {@code RadioButtonElement}. + */ public RadioButtonElement(Locator locator) { super(locator); } @@ -40,22 +46,27 @@ public Locator getFocusLocator() { return getInputLocator(); } + /** Whether the radio is checked. */ boolean isChecked() { return getInputLocator().isChecked(); } + /** Assert that the radio is checked. */ void assertChecked() { assertThat(getInputLocator()).isChecked(); } + /** Assert that the radio is not checked. */ void assertNotChecked() { assertThat(getInputLocator()).not().isChecked(); } + /** Check the radio. */ void check() { getInputLocator().check(); } + /** Get a radio by its label within a given scope. */ static RadioButtonElement getByLabel(Locator locator, String label) { return new RadioButtonElement( locator.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/RadioButtonGroupElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/RadioButtonGroupElement.java index fcc9e39..0e8543d 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/RadioButtonGroupElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/RadioButtonGroupElement.java @@ -10,28 +10,50 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Provides helpers to select by label/value and assert selected state. + */ @PlaywrightElement(RadioButtonGroupElement.FIELD_TAG_NAME) public class RadioButtonGroupElement extends VaadinElement implements HasLabelElement, HasEnabledElement, HasHelperElement, HasValidationPropertiesElement { public static final String FIELD_TAG_NAME = "vaadin-radio-group"; + /** + * Create a new {@code RadioButtonGroupElement}. + * + * @param locator the locator for the {@code } element + */ public RadioButtonGroupElement(Locator locator) { super(locator); } + /** + * Select a radio by its label text. + */ public void selectByLabel(String label) { getRadioButtonByLabel(label).check(); } + /** + * Select a radio by its value. + */ public void selectByValue(String value) { getLocator().evaluate("(el, value) => el.value = value", value); } + /** + * Get a specific radio by its label within the group. + */ public RadioButtonElement getRadioButtonByLabel(String label) { return RadioButtonElement.getByLabel(getLocator(), label); } + /** + * Get the group by its accessible label. + */ public static RadioButtonGroupElement getByLabel(Page page, String label) { return new RadioButtonGroupElement( page.locator(FIELD_TAG_NAME).and( @@ -40,10 +62,16 @@ public static RadioButtonGroupElement getByLabel(Page page, String label) { )).first()); } + /** + * Set the selected value by label. + */ public void setValue(String value) { RadioButtonElement.getByLabel(getLocator(), value).check(); } + /** + * Assert the selected value by label. + */ public void assertValue(String value) { if (value != null && !value.isEmpty()) { assertThat(getLocator().locator("vaadin-radio-button input:checked")) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/SelectElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/SelectElement.java index 399eb54..f0046b2 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/SelectElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/SelectElement.java @@ -17,6 +17,12 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Provides helpers to open the overlay and pick items by visible text, + * along with aria/placeholder/validation mixins. + */ @PlaywrightElement(SelectElement.FIELD_TAG_NAME) public class SelectElement extends VaadinElement implements FocusableElement, HasAriaLabelElement, HasInputFieldElement, @@ -32,12 +38,17 @@ public Locator getInputLocator() { return getLocator().locator("*[slot=\"value\"]").first(); } + /** + * Create a new {@code SelectElement}. + * + * @param locator the locator for the {@code } element + */ public SelectElement(Locator locator) { super(locator); } /** - * Select the item by label + * Select an item by its visible label. * * @param item label of the item */ @@ -47,6 +58,7 @@ public void selectItem(String item) { } /** + * Get the selected value label for single-select. * * @return the label of the value */ @@ -96,8 +108,9 @@ public void assertPlaceholder(String placeholder) { } /** + * Assert the selected value label equals the expected string. * - * @param expected + * @param expected expected label or empty for no selection */ @Override public void assertValue(String expected) { @@ -110,6 +123,13 @@ private static Locator getSelectItem(Locator locator, String label) { .setHasText(label)).first(); } + /** + * Get the {@code SelectElement} by its label. + * + * @param page the Playwright page + * @param label the accessible label of the field + * @return the matching {@code SelectElement} + */ public static SelectElement getByLabel(Page page, String label) { return new SelectElement( page.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/TabElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/TabElement.java index 75994f4..91f53a2 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/TabElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/TabElement.java @@ -4,40 +4,51 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for tabs {@code }. + */ @PlaywrightElement(TabElement.FIELD_TAG_NAME) public class TabElement extends VaadinElement { public static final String FIELD_PARENT_TAG_NAME = "vaadin-tabs"; public static final String FIELD_TAG_NAME = "vaadin-tab"; + /** Create a {@code TabElement} from an existing locator. */ public TabElement(Locator locator) { super(locator); } + /** Whether the tab is currently selected. */ public boolean isSelected() { return getLocator().getAttribute("selected") != null; } + /** Select the tab by clicking it. */ public void select() { getLocator().click(); } + /** Get the tab label text. */ public String getLabel() { return getLocator().textContent(); } + /** Assert that the tab is selected. */ public void assertSelected() { assertThat(getLocator()).hasAttribute("selected", ""); } + /** Assert that the tab is not selected. */ public void assertNotSelected() { assertThat(getLocator()).not().hasAttribute("selected", ""); } + /** Get a tab by visible text within a scope. */ public static TabElement getTabByText(Locator locator, String summary) { return new TabElement(locator.locator(FIELD_PARENT_TAG_NAME).locator(FIELD_TAG_NAME).getByText(summary)); } + /** Get the currently selected tab within a scope. */ public static TabElement getSelectedTab(Locator locator) { return new TabElement(locator.locator(FIELD_PARENT_TAG_NAME).locator(FIELD_TAG_NAME + "[selected]")); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/TabSheetElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/TabSheetElement.java index 15b1791..75b3b98 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/TabSheetElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/TabSheetElement.java @@ -5,32 +5,43 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Provides helpers to access/select tabs and current content panel. + */ @PlaywrightElement(TabSheetElement.FIELD_TAG_NAME) public class TabSheetElement extends VaadinElement { public static final String FIELD_TAG_NAME = "vaadin-tabsheet"; + /** Create a {@code TabSheetElement} from an existing locator. */ public TabSheetElement(Locator locator) { super(locator); } + /** Get the first tabsheet instance on the page. */ public static TabSheetElement get(Page page) { return new TabSheetElement(page.locator(FIELD_TAG_NAME).first()); } + /** Assert the count of tabs. */ public void assertTabsCount(int count) { Locator tabs = getLocator().locator(TabElement.FIELD_TAG_NAME); assertThat(tabs).hasCount(count); } + /** Get a tab by its label. */ public TabElement getTab(String label) { return TabElement.getTabByText(getLocator(), label); } + /** Get the currently selected tab. */ public TabElement getSelectedTab() { return TabElement.getSelectedTab(getLocator()); } + /** Select a tab by label text. */ public void selectTab(String label) { TabElement tab = getTab(label); if (tab != null) { @@ -38,6 +49,7 @@ public void selectTab(String label) { } } + /** Locator for the currently visible content panel. */ public Locator getContentLocator() { return getLocator().locator("[tab]:not([hidden])"); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/TextAreaElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/TextAreaElement.java index ff02bad..6b35cad 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/TextAreaElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/TextAreaElement.java @@ -4,19 +4,39 @@ import com.microsoft.playwright.Page; import com.microsoft.playwright.options.AriaRole; +/** + * PlaywrightElement for {@code }. + *

+ * Extends {@link TextFieldElement} with a textarea input slot and label-based lookup. + */ @PlaywrightElement(TextAreaElement.FIELD_TAG_NAME) public class TextAreaElement extends TextFieldElement { public static final String FIELD_TAG_NAME = "vaadin-text-area"; + /** + * Create a new {@code TextAreaElement}. + * + * @param locator the locator for the {@code } element + */ public TextAreaElement(Locator locator) { super(locator); } + /** + * {@inheritDoc} + */ public Locator getInputLocator() { return getLocator().locator("*[slot=\"textarea\"]").first(); // slot="helper" } + /** + * Get the {@code TextAreaElement} by its label. + * + * @param page the Playwright page + * @param label the accessible label of the text area + * @return the matching {@code TextAreaElement} + */ public static TextAreaElement getByLabel(Page page, String label) { return new TextAreaElement( page.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/TextFieldElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/TextFieldElement.java index a14f02a..af366a4 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/TextFieldElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/TextFieldElement.java @@ -20,6 +20,9 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code } + */ @PlaywrightElement(TextFieldElement.FIELD_TAG_NAME) public class TextFieldElement extends VaadinElement implements HasValidationPropertiesElement, HasInputFieldElement, @@ -31,19 +34,39 @@ public class TextFieldElement extends VaadinElement public static final String PATTERN_ATTRIBUTE = "pattern"; public static final String MIN_LENGTH_ATTRIBUTE = "minLength"; + /** + * Creates a new {@code TextFieldElement} + * + * @param locator the locator for the {@code } element + */ public TextFieldElement(Locator locator) { super(locator); } + /** + * Get the current minimum length of the text field. + * + * @return the minimum length or {@code null} if not set + */ public Integer getMinLength() { String v = getInputLocator().getAttribute(MIN_LENGTH_ATTRIBUTE); return v == null ? null : Integer.valueOf(v); } + /** + * Set the minimum length for the text field. + * + * @param min the minimum length + */ public void setMinLength(int min) { getLocator().evaluate("(el, v) => el.minLength = v", min); } + /** + * Assert that the minimum length of the text field is as expected. + * + * @param min the expected minimum length or {@code null} if no minimum length is expected + */ public void assertMinLength(Integer min) { if (min != null) { assertThat(getInputLocator()).hasAttribute(MIN_LENGTH_ATTRIBUTE, min + ""); @@ -52,15 +75,30 @@ public void assertMinLength(Integer min) { } } + /** + * Get the current maximum length of the text field. + * + * @return the maximum length or {@code null} if not set + */ public Integer getMaxLength() { String v = getInputLocator().getAttribute(MAXLENGTH_ATTRIBUTE); return v == null ? null : Integer.valueOf(v); } + /** + * Set the maximum length for the text field. + * + * @param max the maximum length + */ public void setMaxLength(int max) { getLocator().evaluate("(el, v) => el.maxLength = v", max); } + /** + * Assert that the maximum length of the text field is as expected. + * + * @param max the expected maximum length or {@code null} if no maximum length is expected + */ public void assertMaxLength(Integer max) { if (max != null) { assertThat(getInputLocator()).hasAttribute(MAXLENGTH_ATTRIBUTE, max + ""); @@ -69,14 +107,29 @@ public void assertMaxLength(Integer max) { } } + /** + * Get the current pattern of the text field. + * + * @return the pattern or {@code null} if not set + */ public String getPattern() { return getInputLocator().getAttribute(PATTERN_ATTRIBUTE); } + /** + * Set the pattern for the text field. + * + * @param pattern the pattern + */ public void setPattern(String pattern) { getInputLocator().evaluate("(el, p) => el.pattern = p", pattern); } + /** + * Assert that the pattern of the text field is as expected. + * + * @param pattern the expected pattern or {@code null} if no pattern is expected + */ public void assertPattern(String pattern) { if (pattern != null) { assertThat(getInputLocator()).hasAttribute(PATTERN_ATTRIBUTE, pattern); @@ -85,6 +138,13 @@ public void assertPattern(String pattern) { } } + /** + * Get the {@code TextFieldElement} by its label. + * + * @param page the Playwright page + * @param label the label of the text field + * @return the {@code TextFieldElement} + */ public static TextFieldElement getByLabel(Page page, String label) { return new TextFieldElement( page.locator(FIELD_TAG_NAME) @@ -94,6 +154,13 @@ public static TextFieldElement getByLabel(Page page, String label) { ).first()); } + /** + * Get the {@code TextFieldElement} by its label. + * + * @param locator the locator to search within + * @param label the label of the text field + * @return the {@code TextFieldElement} + */ public static TextFieldElement getByLabel(Locator locator, String label) { return new TextFieldElement( locator.locator(FIELD_TAG_NAME) @@ -101,16 +168,25 @@ public static TextFieldElement getByLabel(Locator locator, String label) { ).first()); } + /** + * {@inheritDoc} + */ @Override public Locator getFocusLocator() { return getInputLocator(); } + /** + * {@inheritDoc} + */ @Override public Locator getAriaLabelLocator() { return getInputLocator(); } + /** + * {@inheritDoc} + */ @Override public Locator getEnabledLocator() { return getInputLocator(); diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/TimePickerElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/TimePickerElement.java index d7f83d6..39a1bea 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/TimePickerElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/TimePickerElement.java @@ -20,6 +20,11 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * PlaywrightElement for {@code }. + *

+ * Adds convenience methods for {@link LocalTime} values and lookup by label. + */ @PlaywrightElement(TimePickerElement.FIELD_TAG_NAME) public class TimePickerElement extends VaadinElement implements HasInputFieldElement, HasValidationPropertiesElement, HasClearButtonElement, HasPlaceholderElement, HasThemeElement, FocusableElement, HasAriaLabelElement, @@ -28,15 +33,30 @@ public class TimePickerElement extends VaadinElement implements HasInputFieldEle public static final String FIELD_TAG_NAME = "vaadin-time-picker"; public static final DateTimeFormatter LOCAL_TIME = DateTimeFormatter.ofPattern("HH:mm"); + /** + * Create a new {@code TimePickerElement}. + * + * @param locator the locator for the {@code } element + */ public TimePickerElement(Locator locator) { super(locator); } + /** + * Set the value using a {@link LocalTime} formatted as HH:mm. + * + * @param time the time to set + */ public void setValue(LocalTime time) { String formattedTime = time.format(LOCAL_TIME); setProperty("value", formattedTime); } + /** + * Get the current value as a {@link LocalTime}. + * + * @return the parsed time or {@code null} when empty + */ public LocalTime getValueAsLocalTime() { String value = getValue(); if (value == null || value.isEmpty()) { @@ -61,9 +81,9 @@ public Locator getEnabledLocator() { } /** - * Check if the value equals to the parameter + * Assert that the value equals the provided time. * - * @param value + * @param value expected {@link LocalTime} or {@code null} for empty */ public void assertValue(LocalTime value) { if (value != null) { @@ -73,6 +93,13 @@ public void assertValue(LocalTime value) { } } + /** + * Get the {@code TimePickerElement} by its label. + * + * @param page the Playwright page + * @param label the accessible label of the field + * @return the matching {@code TimePickerElement} + */ public static TimePickerElement getByLabel(Page page, String label) { return new TimePickerElement( page.locator(FIELD_TAG_NAME) @@ -82,6 +109,13 @@ public static TimePickerElement getByLabel(Page page, String label) { ).first()); } + /** + * Get the {@code TimePickerElement} by its label within a given scope. + * + * @param locator the locator to search within + * @param label the accessible label of the field + * @return the matching {@code TimePickerElement} + */ public static TimePickerElement getByLabel(Locator locator, String label) { return new TimePickerElement( locator.locator(FIELD_TAG_NAME) diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/VaadinElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/VaadinElement.java index b902b2a..f94f770 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/VaadinElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/VaadinElement.java @@ -7,52 +7,95 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Base class for typed Playwright wrappers around Vaadin components. + *

+ * Exposes common helpers such as clicking, visibility assertions, text + * retrieval and generic DOM property access. Concrete components add + * component-specific APIs on top of this. + */ public abstract class VaadinElement implements HasLocatorElement { protected final Locator locator; + /** + * Create a new VaadinElement wrapper. + * + * @param locator the locator pointing to the component root element + */ public VaadinElement(Locator locator) { this.locator = locator; } + /** + * Click the component root. + */ public void click() { locator.click(); } + /** + * Get the textual content of the component root. + * + * @return the text content, or {@code null} if none + */ public String getText() { return locator.textContent(); } @Override + /** {@inheritDoc} */ public Locator getLocator() { return locator; } /** - * Set a DOM property (e.g. `value`, `disabled`, etc.) + * Set a DOM property on the underlying element (e.g. {@code value}, {@code disabled}). + * + * @param name property name + * @param value property value */ public void setProperty(String name, Object value) { locator.evaluate("(el, args) => el[args.name] = args.value", Map.of("name", name, "value", value)); } /** - * Optional: get a DOM property + * Get a DOM property from the underlying element. + * + * @param name property name + * @return the property value or {@code null} if absent */ public Object getProperty(String name) { return locator.evaluate("(el, args) => el[args.name]", Map.of("name", name)); } + /** + * Whether the component is visible. + * + * @return {@code true} when visible + */ public boolean isVisible() { return locator.isVisible(); } + /** + * Assert that the component is visible. + */ public void assertVisible() { assertThat(getLocator()).isVisible(); } + /** + * Assert that the component is hidden. + */ public void assertHidden() { assertThat(getLocator()).isHidden(); } + /** + * Whether the component is hidden. + * + * @return {@code true} when hidden + */ public boolean isHidden() { return !isVisible(); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/FocusableElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/FocusableElement.java index 0f62fde..36ab633 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/FocusableElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/FocusableElement.java @@ -4,34 +4,45 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components that can receive keyboard focus. + */ public interface FocusableElement extends HasLocatorElement { + /** + * The locator to focus/blur. Defaults to the component root. + */ default Locator getFocusLocator() { return getLocator(); } /** - * Focus the field + * Focus the component. */ default void focus() { getFocusLocator().focus(); } /** - * Blur the field + * Blur the component. */ default void blur() { getFocusLocator().blur(); } + /** + * Current tab index as string (from {@code tabIndex} attribute). + */ default String getTabIndex() { return getFocusLocator().getAttribute("tabIndex"); } + /** Assert that the component has focus. */ default void assertIsFocused() { assertThat(getFocusLocator()).isFocused(); } + /** Assert that the component does not have focus. */ default void assertIsNotFocused() { assertThat(getFocusLocator()).not().isFocused(); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasAllowedCharPatternElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasAllowedCharPatternElement.java index f9c5413..507521e 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasAllowedCharPatternElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasAllowedCharPatternElement.java @@ -4,16 +4,34 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components supporting {@code allowedCharPattern} to constrain input. + */ public interface HasAllowedCharPatternElement extends HasLocatorElement { + /** + * Get the current {@code allowedCharPattern}. + * + * @return the pattern string or {@code null} + */ default String getAllowedCharPattern() { return getLocator().evaluate("el => el.allowedCharPattern").toString(); } + /** + * Set the {@code allowedCharPattern}. + * + * @param pattern the pattern to apply + */ default void setAllowedCharPattern(String pattern) { getLocator().evaluate("(el, p) => el.allowedCharPattern = p", pattern); } + /** + * Assert that the {@code allowedCharPattern} matches the expected value. + * + * @param pattern expected pattern, or {@code null} to assert absence + */ default void assertAllowedCharPattern(String pattern) { if (pattern != null) { assertThat(getLocator()).hasJSProperty("allowedCharPattern", pattern); diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasAriaLabelElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasAriaLabelElement.java index fbcd7b1..33291d6 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasAriaLabelElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasAriaLabelElement.java @@ -6,16 +6,24 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components exposing an ARIA label. + */ public interface HasAriaLabelElement extends HasLocatorElement { + /** Locator where the {@code aria-label} is applied. Defaults to root. */ default Locator getAriaLabelLocator() { return getLocator(); } + /** Get the current {@code aria-label} value. */ default String getAriaLabel() { return getAriaLabelLocator().getAttribute("aria-label"); } + /** + * Assert that the {@code aria-label} matches the expected text, or is absent when null. + */ default void assertAriaLabel(String ariaLabel) { if (ariaLabel != null) { assertThat(getAriaLabelLocator()).hasAttribute("aria-label", ariaLabel); @@ -24,4 +32,4 @@ default void assertAriaLabel(String ariaLabel) { } } -} \ No newline at end of file +} diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasClearButtonElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasClearButtonElement.java index e959a82..cd96503 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasClearButtonElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasClearButtonElement.java @@ -4,24 +4,32 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components with a clear button part. + */ public interface HasClearButtonElement extends HasLocatorElement { + /** Locator for the clear button ({@code part~=clear-button}). */ default Locator getClearButtonLocator() { return getLocator().locator("[part=\"clear-button\"]"); } + /** Click the clear button. */ default void clickClearButton() { getClearButtonLocator().click(); } + /** Whether the clear button is visible. */ default boolean isClearButtonVisible() { return getClearButtonLocator().isVisible(); } + /** Assert that the clear button is visible. */ default void assertClearButtonVisible() { assertThat(getClearButtonLocator()).isVisible(); } + /** Assert that the clear button is not visible. */ default void assertClearButtonNotVisible() { assertThat(getClearButtonLocator()).not().isVisible(); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasEnabledElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasEnabledElement.java index eb933c9..5f34ae3 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasEnabledElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasEnabledElement.java @@ -4,20 +4,27 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components that expose enabled/disabled state. + */ public interface HasEnabledElement extends HasLocatorElement { + /** Locator used to check enablement. Defaults to root. */ default Locator getEnabledLocator() { return getLocator(); } + /** Whether the component is enabled. */ default boolean isEnabled() { return getEnabledLocator().isEnabled(); } + /** Assert that the component is enabled. */ default void assertEnabled() { assertThat(getEnabledLocator()).isEnabled(); } + /** Assert that the component is disabled. */ default void assertDisabled() { assertThat(getEnabledLocator()).isDisabled(); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasHelperElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasHelperElement.java index a2b89b8..e13bd2f 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasHelperElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasHelperElement.java @@ -4,16 +4,22 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components that provide helper text via the {@code helper} slot. + */ public interface HasHelperElement extends HasLocatorElement { + /** Locator for the helper slot content. */ default Locator getHelperLocator() { return getLocator().locator("*[slot=\"helper\"]").first(); // slot="helper" } + /** Text content of the helper slot. */ default String getHelperText() { return getHelperLocator().textContent(); // slot="helper" } + /** Assert that the helper slot has the expected text. */ default void assertHelperHasText(String helperText) { assertThat(getHelperLocator()).hasText(helperText); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasInputFieldElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasInputFieldElement.java index 272a9a3..17d2c22 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasInputFieldElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasInputFieldElement.java @@ -1,4 +1,8 @@ package org.vaadin.addons.dramafinder.element.shared; +/** + * Convenience mixin grouping common capabilities of Vaadin input fields + * (label, value handling, helper and styling). + */ public interface HasInputFieldElement extends HasHelperElement, HasValueElement, HasStyleElement, HasLabelElement { } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasLabelElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasLabelElement.java index 15ddd24..8077fc9 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasLabelElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasLabelElement.java @@ -4,16 +4,22 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components that render a visible label. + */ public interface HasLabelElement extends HasLocatorElement { + /** Locator for the visible label element. */ default Locator getLabelLocator() { return getLocator().locator("label").first(); } + /** Get the label text. */ default String getLabel() { return getLabelLocator().textContent(); } + /** Assert that the label text matches, or is hidden when null. */ default void assertLabel(String label) { if (label != null) { assertThat(getLabelLocator()).hasText(label); @@ -22,4 +28,4 @@ default void assertLabel(String label) { } } -} \ No newline at end of file +} diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasLocatorElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasLocatorElement.java index 2b88401..7b9b792 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasLocatorElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasLocatorElement.java @@ -2,6 +2,10 @@ import com.microsoft.playwright.Locator; +/** + * Base contract for objects that expose a Playwright {@link Locator}. + */ public interface HasLocatorElement { + /** The root locator for the component. */ Locator getLocator(); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasPlaceholderElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasPlaceholderElement.java index 2863185..38109f8 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasPlaceholderElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasPlaceholderElement.java @@ -2,16 +2,22 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components that support the {@code placeholder} attribute. + */ public interface HasPlaceholderElement extends HasLocatorElement { + /** Set the {@code placeholder} attribute. */ default void setPlaceholder(String placeholder) { getLocator().evaluate("(el, placeholder) => el.placeholder = placeholder", placeholder); } + /** Get the current {@code placeholder} text. */ default String getPlaceholder() { return getLocator().evaluate("el => el.placeholder").toString(); } + /** Assert that the {@code placeholder} matches the expected text. */ default void assertPlaceholder(String placeholder) { assertThat(getLocator()).hasAttribute("placeholder", placeholder); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasPrefixElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasPrefixElement.java index 5a69b1a..18b73a2 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasPrefixElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasPrefixElement.java @@ -10,14 +10,17 @@ */ public interface HasPrefixElement extends HasLocatorElement { + /** Locator for the prefix slot content. */ default Locator getPrefixLocator() { return getLocator().locator("*[slot=\"prefix\"]").first(); } + /** Text content of the prefix slot. */ default String getPrefixText() { return getPrefixLocator().textContent(); } + /** Assert that the prefix slot has the expected text, or is hidden when null. */ default void assertPrefixHasText(String text) { if (text != null) { assertThat(getPrefixLocator()).hasText(text); @@ -26,4 +29,3 @@ default void assertPrefixHasText(String text) { } } } - diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasStyleElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasStyleElement.java index c582219..2954855 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasStyleElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasStyleElement.java @@ -4,12 +4,19 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components exposing styling via CSS classes. + */ public interface HasStyleElement extends HasLocatorElement { + /** Get the raw {@code class} attribute value. */ default String getCssClass() { return getLocator().getAttribute("class"); } + /** + * Assert the component has exactly the provided class names, or no classes when null. + */ default void assertCssClass(String... classnames) { if (classnames != null) { assertThat(getLocator()).hasClass(classnames); @@ -18,4 +25,4 @@ default void assertCssClass(String... classnames) { } } -} \ No newline at end of file +} diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasSuffixElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasSuffixElement.java index 5e3b49f..ba377a6 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasSuffixElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasSuffixElement.java @@ -10,14 +10,17 @@ */ public interface HasSuffixElement extends HasLocatorElement { + /** Locator for the suffix slot content. */ default Locator getSuffixLocator() { return getLocator().locator("*[slot=\"suffix\"]").first(); } + /** Text content of the suffix slot. */ default String getSuffixText() { return getSuffixLocator().textContent(); } + /** Assert that the suffix slot has the expected text, or is hidden when null. */ default void assertSuffixHasText(String text) { if (text != null) { assertThat(getSuffixLocator()).hasText(text); @@ -26,4 +29,3 @@ default void assertSuffixHasText(String text) { } } } - diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasThemeElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasThemeElement.java index c4ebf3c..fe41d99 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasThemeElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasThemeElement.java @@ -4,12 +4,17 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components that support the {@code theme} attribute. + */ public interface HasThemeElement extends HasLocatorElement { + /** Get the current {@code theme} attribute value. */ default String getTheme() { return getLocator().getAttribute("theme"); } + /** Assert that the {@code theme} attribute matches, or is absent when null. */ default void assertTheme(String theme) { if (theme != null) { assertThat(getLocator()).hasAttribute("theme", theme); @@ -18,4 +23,4 @@ default void assertTheme(String theme) { } } -} \ No newline at end of file +} diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasTooltipElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasTooltipElement.java index dc48c01..ad34b80 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasTooltipElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasTooltipElement.java @@ -11,10 +11,12 @@ */ public interface HasTooltipElement extends HasLocatorElement { + /** Locator for the tooltip content (role=tooltip). */ default Locator getTooltipLocator() { return getLocator().locator("*[slot=\"tooltip\"]").first(); } + /** Tooltip text content. */ default String getTooltipText() { return getTooltipLocator().textContent(); } @@ -27,4 +29,3 @@ default void assertTooltipHasText(String text) { } } } - diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasValidationPropertiesElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasValidationPropertiesElement.java index d45ed2c..27ec5f6 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasValidationPropertiesElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasValidationPropertiesElement.java @@ -4,20 +4,27 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components exposing validation state and error messages. + */ public interface HasValidationPropertiesElement extends HasLocatorElement { + /** Locator for the error message slot. */ default Locator getErrorMessageLocator() { return getLocator().locator("> [slot=\"error-message\"]").first(); // slot="helper" } + /** Assert that the component is valid (not {@code invalid}). */ default void assertValid() { assertThat(getLocator()).not().hasAttribute("invalid", ""); } + /** Assert that the component is invalid. */ default void assertInvalid() { assertThat(getLocator()).hasAttribute("invalid", ""); } + /** Assert that the error message equals the expected text. */ default void assertErrorMessage(String errorMessage) { assertThat(getErrorMessageLocator()).hasText(errorMessage); } diff --git a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasValueElement.java b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasValueElement.java index 457bfc3..f036393 100644 --- a/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasValueElement.java +++ b/src/main/java/org/vaadin/addons/dramafinder/element/shared/HasValueElement.java @@ -4,31 +4,35 @@ import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +/** + * Mixin for components that expose a textual {@code value} through an input slot. + */ public interface HasValueElement extends HasLocatorElement { + /** Locator for the native input element inside the component. */ default Locator getInputLocator() { return getLocator().locator("*[slot=\"input\"]").first(); // slot="helper" } + /** Get the current string value. */ default String getValue() { return getLocator().evaluate("el => el.value").toString(); } /** - * Set value via JavaScript (ensures the `value-changed` event is triggered) + * Set the field value by filling the input and dispatching a change event. */ default void setValue(String value) { getInputLocator().fill(value); getLocator().dispatchEvent("change"); } - /** - * Clear the input field - */ + /** Clear the input value. */ default void clear() { setValue(""); } + /** Assert that the input value matches the expected string. */ default void assertValue(String value) { assertThat(getInputLocator()).hasValue(value); } diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 0000000..e69de29