Skip to content

[personal-wp] Add Playwright e2e tests#3405

Merged
ashfame merged 23 commits intotrunkfrom
mywp_tests
Mar 20, 2026
Merged

[personal-wp] Add Playwright e2e tests#3405
ashfame merged 23 commits intotrunkfrom
mywp_tests

Conversation

@ashfame
Copy link
Copy Markdown
Member

@ashfame ashfame commented Mar 17, 2026

Summary

Adds Playwright E2E tests for the personal-wp package, focused on code paths and UI that are unique to personal-wp.

personal-wp forks several core modules — resolve-blueprint-from-url.ts, boot-site-client.ts, and router.ts — rather than importing from playground-website. Blueprint step execution is shared via @wp-playground/blueprints, so we don't re-test individual step types (writeFile, wp-cli, etc.) that core already covers extensively. Instead, these tests verify personal-wp's own parsing → boot chain and its unique UI.

9 tests across 2 spec files:

  • Smoke (4): default blueprint welcome page landing, completion of welcome flow, blueprint-from-URL-hash (exercises forked parsing/boot path), toolbar display
  • UI (5): Site Tools panel, menu overlay (open/close/escape), page title, address bar navigation

Implementation details

  • playwright.config.ts — targets port 5401 (personal-wp dev server), Chromium-only (Firefox/WebKit can't boot via Vite dev server due to missing COEP/COOP headers before service worker claims the page)
  • playground-fixtures.ts — extends Playwright test with wordpress (iframe chain) and website (PersonalWPPage helper) fixtures
  • personal-wp-page.ts — page helper with goto() that waits for nested iframes, plus site tools, menu overlay, and address bar methods
  • CI runs as a dedicated test-e2e-personal-wp job on Chromium

Test plan

  • Run locally npx playwright test --config=packages/playground/personal-wp/playwright/playwright.config.ts --project=chromium
  • CI passes all 9 tests on Chromium

Made with Cursor

@ashfame ashfame requested review from a team, bgrgicak and Copilot and removed request for bgrgicak and Copilot March 17, 2026 03:40
Add end-to-end test infrastructure for the personal-wp package,
mirroring the existing playground-website Playwright setup.

- Playwright config targeting port 5401 dev server
- Test fixtures with iframe-aware WordPress locator
- PersonalWPPage helper for common interactions
- 16 tests across smoke, blueprints, and UI specs
- e2e:playwright NX target in project.json

Made-with: Cursor
Copilot AI review requested due to automatic review settings March 17, 2026 03:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Playwright E2E test infrastructure and coverage for the personal-wp package, aligned with the existing playground-website approach.

Changes:

  • Adds an Nx e2e:playwright target for running Playwright tests for playground-personal-wp
  • Introduces Playwright config, fixtures, and a PersonalWPPage helper for nested-iframe interactions
  • Adds 3 spec files covering smoke, blueprint, and UI behaviors (16 tests total)

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/playground/personal-wp/project.json Adds Nx target for running Playwright E2E tests
packages/playground/personal-wp/playwright/playwright.config.ts New Playwright config including webServer startup and browser projects
packages/playground/personal-wp/playwright/playground-fixtures.ts New fixtures extending Playwright test with wordpress and website helpers
packages/playground/personal-wp/playwright/personal-wp-page.ts New page-object helper for navigation + Personal WP UI interactions
packages/playground/personal-wp/playwright/e2e/ui.spec.ts Adds UI interaction assertions (address bar, panels, overlay, navigation)
packages/playground/personal-wp/playwright/e2e/smoke.spec.ts Adds boot + auto-login + basic shell/iframe smoke checks
packages/playground/personal-wp/playwright/e2e/blueprints.spec.ts Adds blueprint hash/query-based execution tests (base64/JSON/data URL/wp-cli)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

ashfame added 4 commits March 17, 2026 09:41
Add a dedicated CI workflow job to run the personal-wp Playwright
e2e tests on every PR, matching the pattern of existing e2e jobs.

Made-with: Cursor
The playwright install runs as the regular user, so the test must
also run without sudo to find the cached browser binaries. Port 5401
does not require root privileges.

Made-with: Cursor
- smoke: check for 'Howdy' text instead of #wpadminbar visibility
  (admin bar element exists but is CSS-hidden before JS initializes)
- ui: use getByRole('heading', { name: 'Backup' }) to avoid strict
  mode violation from 6 elements matching getByText('Backup')
- blueprints: remove blueprint-url data URL test that fails on fresh
  CI browsers (no existing OPFS site for the query param path)
- Use type-only re-export for Page in playground-fixtures
- Use proper Playwright type for goto options parameter
- Scope address bar selector to the toolbar header
- Use toBeVisible() instead of not.toBeEmpty() in waitForNestedIframes

Made-with: Cursor
…n checks

'Start over' and 'Recovery' also match multiple elements (heading +
paragraph). Use getByRole('heading') consistently for all menu sections.

Made-with: Cursor
@ashfame ashfame marked this pull request as draft March 17, 2026 05:29
@ashfame ashfame self-assigned this Mar 17, 2026
ashfame and others added 11 commits March 18, 2026 12:40
Smoke tests:
- Rename to reflect actual first-visit flow (default my-wordpress
  blueprint lands on welcome page, not dashboard)
- Check #wpwrap visibility for boot confirmation
- Check #wpadminbar attachment (not visibility) for login verification
- Add explicit welcome page URL assertion via address bar

Browser coverage:
- Add webkit (Desktop Safari) project to match core playground-website
- CI now runs a matrix of chromium/firefox/webkit instead of chromium-only

Made-with: Cursor
…er timeout

Firefox and WebKit use Asyncify (not JSPI), where the WordPress body
inside the iframe may be CSS-hidden during boot. toBeVisible() fails
in this state while not.toBeEmpty() (used by core playground-website)
succeeds. Additionally, personal-wp boots are heavier (OPFS site
creation + default blueprint fetches a plugin from GitHub), so the
timeout is increased to 180s to accommodate slower Asyncify mode.

Made-with: Cursor
Firefox and WebKit fail because the WASM PHP runtime needs
SharedArrayBuffer, which requires cross-origin isolation headers
(COEP/COOP). These are provided by the service worker after it
claims the page, but on a fresh Vite dev server load the service
worker isn't active yet and the runtime never boots.

The core playground-website E2E tests already cover Firefox/WebKit
via a built app served with proper headers. Personal-wp E2E tests
focus on the UI layer and run on Chromium (with JSPI) only.

Made-with: Cursor
… ones

Blueprint execution (base64, JSON, writeFile, login, wp-cli) is
thoroughly covered by the core playground-website E2E tests. The
welcome page test already proves blueprints work through personal-wp.

Similarly, WordPress boot, auto-login, and viewport rendering are
implicitly tested by core.

Remaining 8 tests focus on what personal-wp uniquely adds:
- Default my-wordpress blueprint flow (welcome page landing)
- Personal-wp toolbar
- Address bar, Site Tools panel, menu overlay, page title, navigation

Made-with: Cursor
personal-wp forks resolve-blueprint-from-url.ts and boot-site-client.ts
from core. Add a smoke test that exercises this forked parsing → boot
chain, while avoiding re-testing shared step execution from
@wp-playground/blueprints.

Made-with: Cursor
@ashfame ashfame marked this pull request as ready for review March 18, 2026 14:37
@ashfame ashfame requested a review from Copilot March 18, 2026 14:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Playwright E2E coverage for the personal-wp package, focusing on the fork-specific boot/parsing path and personal-wp UI behaviors.

Changes:

  • Adds Playwright config + fixtures + page object helper for personal-wp E2E.
  • Introduces 2 E2E spec files (smoke + UI) totaling 9 tests.
  • Wires execution via Nx target and a dedicated CI job.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/playground/personal-wp/project.json Adds an Nx target to run the personal-wp Playwright E2E suite.
packages/playground/personal-wp/playwright/playwright.config.ts Introduces Playwright configuration, Chromium-only project, and dev-server startup via webServer.
packages/playground/personal-wp/playwright/playground-fixtures.ts Defines Playwright fixtures for nested WP iframe access and a PersonalWP page helper.
packages/playground/personal-wp/playwright/personal-wp-page.ts Adds a Page Object helper for navigation/iframe readiness and toolbar/UI interactions.
packages/playground/personal-wp/playwright/e2e/ui.spec.ts Adds UI-focused E2E checks (Site Tools, menu overlay, title, address bar navigation).
packages/playground/personal-wp/playwright/e2e/smoke.spec.ts Adds smoke tests validating default landing, welcome flow, and URL-hash blueprint path.
.github/workflows/ci.yml Adds a dedicated CI job to install Chromium and run the personal-wp E2E suite.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +4 to +6
const baseURL =
process.env.PLAYWRIGHT_TEST_BASE_URL ||
'http://127.0.0.1:5401/website-server/';
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This mirrors the existing playground-website Playwright config (port 5400 vs 5401). In practice, PLAYWRIGHT_TEST_BASE_URL is only used when a server is already running, and reuseExistingServer: !process.env.CI (true locally) means Playwright skips starting/polling the hardcoded URL entirely. If this were worth changing, it should be addressed across both configs together.

Comment on lines +44 to +48
webServer: {
command: 'npx nx run playground-personal-wp:dev',
url: 'http://127.0.0.1:5401/website-server/',
reuseExistingServer: !process.env.CI,
},
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Duplicate of the above — same pattern inherited from the existing playground-website config.

Comment on lines +12 to +19
await expect(
page
.frameLocator(
'#playground-viewport:visible,.playground-viewport:visible'
)
.frameLocator('#wp')
.locator('body')
).not.toBeEmpty();
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is intentionally a loose minimum-viability gate — it confirms the nested iframe chain loaded and PHP rendered something. Each test then makes its own specific assertions (toHaveText, toHaveValue, toBeVisible) which serve as the actual readiness guarantees. A tighter gate like #wpadminbar would actually be more fragile (e.g. it is not present on the welcome page). Combined with generous timeouts (60s expect, 300s test) and 3 retries, flakiness from this gate is unlikely. We can revisit if flakiness is actually observed.

- name: Install Playwright Browser
run: npx playwright install chromium --with-deps
- name: Run personal-wp Playwright e2e tests
run: CI=true npx playwright test --config=packages/playground/personal-wp/playwright/playwright.config.ts --project=chromium
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This follows the same pattern used by the existing playground-website E2E CI job (direct npx playwright test commands, not Nx targets). Consistent with the rest of the repo CI setup.

Comment on lines +12 to +13
retries: 3,
workers: 3,
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The existing playground-website config uses the identical values (retries: 3, workers: 3) without CI conditioning — this is an intentional project-wide convention. If worth revisiting, it should be done across both configs consistently, not just here.

@ashfame ashfame requested a review from brandonpayton March 18, 2026 14:42
@ashfame ashfame requested review from bgrgicak and brandonpayton and removed request for brandonpayton March 18, 2026 14:42
@ashfame ashfame requested a review from zaerl March 19, 2026 08:31
@bgrgicak
Copy link
Copy Markdown
Collaborator

personal-wp forks several core modules — resolve-blueprint-from-url.ts, boot-site-client.ts, and router.ts — rather than importing from playground-website.

This isn't directly related to the PR. Why are these files copied? If they are useful, let's export them.

ashfame added 3 commits March 19, 2026 17:36
The wordpress FrameLocator was defined in three places — the fixture,
the page object's wordpress() method, and waitForNestedIframes(). Now
wordpress() is the single source of truth and both callers delegate to it.

Made-with: Cursor
…orNestedIframes()

Both methods always operate on this.page — the parameter was never
called with a non-default value.

Made-with: Cursor
@ashfame
Copy link
Copy Markdown
Member Author

ashfame commented Mar 19, 2026

@bgrgicak I guess because this package is like a forked version of playground instance. So, it copies over some stuff like that. So, not a usual requirement from consumer's side.

Resolving blueprint can definitely be exported, we needed it in wpcom stuff too. Others, perhaps not so much.

ashfame and others added 2 commits March 19, 2026 19:18
Verify clicking "you can reset this WordPress" reveals the "Delete
everything" button and clicking "you can troubleshoot" reveals the
"Install Health Check & Troubleshoot" link.

Made-with: Cursor
@bgrgicak
Copy link
Copy Markdown
Collaborator

Resolving blueprint can definitely be exported, we needed it in wpcom stuff too. Others, perhaps not so much.

I agree it's a rare use case, but if it's simple for us it will make these advanced use cases easier to implement.

@ashfame ashfame merged commit ba6aca1 into trunk Mar 20, 2026
47 checks passed
@ashfame ashfame deleted the mywp_tests branch March 20, 2026 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants