Skip to content

[CRAFTING] Add Page Object Model for datagrid-web's E2E specs#2308

Open
leonardomendix wants to merge 4 commits into
mainfrom
test/datagrid-pom
Open

[CRAFTING] Add Page Object Model for datagrid-web's E2E specs#2308
leonardomendix wants to merge 4 commits into
mainfrom
test/datagrid-pom

Conversation

@leonardomendix

Copy link
Copy Markdown
Collaborator

Pull request type

Test related change (New E2E test, test automation, etc.)


Description

This PR introduced a Page Object Model for datagrid-web's E2E specs, rewrote all six specs on it, and documented POM conventions in the e2e guidelines.

@leonardomendix leonardomendix requested a review from a team as a code owner July 6, 2026 14:02
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

AI Code Review

⚠️ Approved with suggestions — low-severity items only, safe to merge


What was reviewed

File Change
docs/requirements/e2e-test-guidelines.md Added Page Object Model section with conventions and template examples
packages/pluggableWidgets/datagrid-web/e2e/DataGrid.spec.js Migrated to POM; removed waitForMendixApp calls
packages/pluggableWidgets/datagrid-web/e2e/DataGridSelection.spec.js Migrated to POM; removed waitForMendixApp calls
packages/pluggableWidgets/datagrid-web/e2e/filtering/DataGridFilteringEmptyString.spec.js Migrated to POM with beforeEach setup
packages/pluggableWidgets/datagrid-web/e2e/filtering/DataGridFilteringIntegration.spec.js Migrated to POM; removed commented-out dead code
packages/pluggableWidgets/datagrid-web/e2e/filtering/DataGridFilteringMulti.spec.js Migrated to POM with beforeEach setup
packages/pluggableWidgets/datagrid-web/e2e/filtering/DataGridFilteringSingle.spec.js Migrated to POM with beforeEach setup
packages/pluggableWidgets/datagrid-web/e2e/pages/DataGridPage.js New POM file encapsulating all grid locators and actions

Skipped (out of scope): dist/, pnpm-lock.yaml

⚠️ CI checks status unknowngh pr checks required interactive approval during review. Verify CI is green before merging.

No CHANGELOG entry required — this is a test-only refactor with no runtime behavior changes.


Findings

⚠️ Low — dropdownFilter() silently breaks the "all locators from root" convention without a comment

File: packages/pluggableWidgets/datagrid-web/e2e/pages/DataGridPage.js line 986
Problem: dropdownFilter(n) uses this.page.locator(...) and hard-codes .mx-name-drop_downFilter${n}, while the docs and the rest of the POM scope everything to this.root. This is correct (the filter widgets are siblings of the grid, not children), but there is no comment explaining why — a future maintainer may assume it's a mistake and "fix" it to this.root, breaking the locator.
Fix: Add a one-line comment, the same way the column-selector section does:

/** A named drop-down filter widget rendered as a combobox.
 * These widgets are siblings of the grid root, not children — cannot scope to `this.root`. */
dropdownFilter(n) {
    return this.page.locator(`.mx-name-drop_downFilter${n}[role="combobox"]`);
}

⚠️ Low — globalThis.getComputedStyle in page.evaluate() is unnecessary

File: packages/pluggableWidgets/datagrid-web/e2e/DataGridSelection.spec.js line 418
Problem: The callback passed to page.evaluate() runs in browser context where window and globalThis are equivalent. The change from window.getComputedStyle(el) to globalThis.getComputedStyle(el) has no effect and departs from the browser-idiomatic form without a reason.
Fix: Revert to window.getComputedStyle(el) to match browser conventions, or leave it if globalThis is a conscious style choice — but it should be consistent across the codebase.


⚠️ Low — One spec still reaches past the POM for a one-off interaction

File: packages/pluggableWidgets/datagrid-web/e2e/filtering/DataGridFilteringSingle.spec.js line 785
Problem: Inside "reset filter state when empty option is clicked", the test uses page.getByRole("row", { name: "Pets (bool)" }).getByRole("option").first().click() directly instead of going through grid. This is the only remaining raw page.* call in the filtering specs (excluding the parameter-less tests that correctly omit { page }). Not blocking — it's genuinely an unusual compound interaction — but worth a comment explaining why it stays page-level.
Note: No code change required; a brief inline comment like // Reset option is inside a columnheader row — no POM method for this one-off is enough.


Positives

  • Removing all waitForMendixApp calls and relying on the fixture auto-wait is exactly right and eliminates a category of flakiness.
  • The POM strictly scopes column-selector items to this.root with an explicit comment explaining the Floating UI rendering behaviour — that's a great precedent for future contributors.
  • Replacing :has-text("…") pseudo-selectors with getByRole("option", { name, exact: true }) throughout is a meaningful improvement: it's web-first, accessible-name-based, and more precise.
  • columnCells(n) and headerFilterContainer(n) are correctly scoped to this.root, so tests that reference them will never match cells from other grids on the page.
  • The docs addition is actionable: concrete conventions, a worked example POM class, and a worked example spec — exactly what the guidelines section needed.

Comment on lines +22 to +25
/** Navigate to a page; the fixture auto-waits for Mendix readiness. */
async open(path = "/") {
await this.page.goto(path);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I beleive this is overkill, I would rather wrap a datagrid, then we can use for example two datagrids on a page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants