Skip to content

Set up Playwright for local, manual e2e testing (LS-2335) - #20

Open
brandonmarshal wants to merge 1 commit into
developfrom
feature/ls-2335-set-up-playwright-testing-and-write-generic-assertion
Open

Set up Playwright for local, manual e2e testing (LS-2335)#20
brandonmarshal wants to merge 1 commit into
developfrom
feature/ls-2335-set-up-playwright-testing-and-write-generic-assertion

Conversation

@brandonmarshal

@brandonmarshal brandonmarshal commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Installed Playwright matching the official create-playwright scaffold defaults (verified directly against the real installer output): @playwright/test, dotenv, @types/node, all 3 browser projects (Chromium, Firefox, WebKit), reporter: 'html', forbidOnly, CI-aware retries/workers
  • baseURL is read from a local, gitignored .env (not hardcoded) so each developer points tests at their own environment
  • No CI wiring for now — there's no environment that reflects a PR's own branch code before merge, so tests are run manually via npx playwright test
  • Added a real spec, tests/specs/work-archive.spec.ts, using the 6 generic assertion helpers from tests/helpers/assertions.ts (LS-2244) against the live Work Archive template

Test plan

  • npx playwright test passes locally against the Work Archive template
  • Config verified against the real, unmodified create-playwright output
  • .env confirmed gitignored, never committed

LS-2335

Summary by CodeRabbit

  • Tests

    • Added end-to-end coverage for the Work Archive page, including section order, cards, links, responsive layouts, and divider styling.
    • Added a prepared test suite for individual Work pages.
    • Added support for testing across Chromium, Firefox, and WebKit.
  • Chores

    • Added Playwright tooling and configuration for environment-based test URLs.
    • Added ignore rules for generated test reports and authentication artifacts.
    • Documented how to run the new tests.

Install Playwright via the official create-playwright scaffold shape
(@playwright/test, dotenv, @types/node) and configure all 3 browser
projects (Chromium, Firefox, WebKit). baseURL is read from a local,
gitignored .env so each developer points tests at their own
environment — no CI wiring, since there's no shared environment that
reflects a PR's own code before merge; tests run manually via
`npx playwright test`.

Add a real spec (tests/specs/work-archive.spec.ts) exercising all 6
generic assertion helpers from tests/helpers/assertions.ts (LS-2244)
against the live Work Archive template: section order, category-card
count/parts, hero link href, related-routes grid reflow at mobile,
and stats-grid divider styling.
@brandonmarshal brandonmarshal added area:dependencies Composer/npm dependency work lang:js JavaScript/TypeScript status:needs-review Awaiting code review labels Aug 6, 2026
@linear-code

linear-code Bot commented Aug 6, 2026

Copy link
Copy Markdown

LS-2335

@brandonmarshal brandonmarshal self-assigned this Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Note

.coderabbit.yml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key: "version"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
📝 Walkthrough

Walkthrough

Added a Playwright end-to-end testing setup with environment-based configuration, three browser projects, shared assertion helpers, and Work Archive coverage. Added a skipped Work Single specification and ignored Playwright artifacts.

Changes

Playwright end-to-end testing

Layer / File(s) Summary
Configure Playwright execution
package.json, playwright.config.ts, .gitignore, CHANGELOG.md
Added Playwright tooling, .env loading, BASE_URL support, Chromium/Firefox/WebKit projects, CI execution settings, report and trace handling, ignored artifacts, and changelog coverage.
Add reusable page assertions
tests/helpers/assertions.ts
Added assertions for section order, element counts, card parts, link URLs, responsive columns, and computed CSS properties.
Cover Work templates
tests/specs/work-archive.spec.ts, tests/specs/work-single.spec.ts
Added Work Archive checks for structure, cards, links, responsive layout, and divider styling. Added a skipped Work Single specification with equivalent coverage targets.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PlaywrightTest
  participant PlaywrightConfig
  participant Browser
  participant WorkTemplate
  PlaywrightTest->>PlaywrightConfig: Load BASE_URL and browser project
  PlaywrightConfig->>Browser: Start Chromium, Firefox, or WebKit
  PlaywrightTest->>WorkTemplate: Navigate to Work Archive path
  WorkTemplate-->>PlaywrightTest: Render sections, cards, links, and layout
  PlaywrightTest->>WorkTemplate: Inspect text, counts, URLs, columns, and styles
Loading

Suggested reviewers: ashleyshaw, josearmandoabreu, krugazul, tibiii, zaredrogers

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the Playwright setup for local, manual end-to-end testing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/ls-2335-set-up-playwright-testing-and-write-generic-assertion

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mergify

mergify Bot commented Aug 6, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playwright.config.ts`:
- Line 34: Update the Playwright configuration’s baseURL assignment to validate
that process.env.BASE_URL is present and non-empty before the suite starts, and
fail clearly during configuration when it is missing. Preserve the existing
baseURL behavior for valid values.
- Line 12: Update the Playwright configuration’s dotenv path resolution to
support Node.js 20.0.0 by deriving the directory from import.meta.url with
fileURLToPath and path.dirname instead of using import.meta.dirname; add or
reuse the required imports while preserving the existing .env path.

In `@tests/specs/work-archive.spec.ts`:
- Around line 43-50: Update the hero CTA assertion in the test using
WORK_ARCHIVE_URL as the source of truth: resolve the expected href with new
URL() so WORK_ARCHIVE_PATH is respected and trailing slashes in baseURL cannot
produce a double slash. Keep the existing “Explore case studies” link
verification unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: ffe2f40e-284b-4139-b1ec-67cf8cfcdc4c

📥 Commits

Reviewing files that changed from the base of the PR and between be67839 and 8726988.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • .gitignore
  • CHANGELOG.md
  • package.json
  • playwright.config.ts
  • tests/helpers/assertions.ts
  • tests/specs/work-archive.spec.ts
  • tests/specs/work-single.spec.ts

Comment thread playwright.config.ts
// This repo's package.json has "type": "module", so __dirname (assumed by
// Playwright's own generated template) isn't available here — using
// Node's documented ESM equivalent instead: https://nodejs.org/api/esm.html#importmetadirname
dotenv.config({ path: path.resolve(import.meta.dirname, '.env') });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n '"node"|import\.meta\.dirname' package.json playwright.config.ts
curl -fsSL https://nodejs.org/download/release/v20.11.0/docs/api/esm.html |
  rg -n 'import\.meta\.dirname|Added in: v20\.11\.0'

Repository: lightspeedwp/ls-theme

Length of output: 930


🌐 Web query:

Node.js v20.10.0 import.meta.dirname documentation

💡 Result:

In Node.js v20.10.0, the import.meta.dirname property is not available [1][2]. The import.meta.dirname and import.meta.filename properties were introduced in Node.js version 20.11.0 [3][2][4]. Because these properties are not available in v20.10.0, developers using this version must replicate the functionality of the CommonJS dirname variable by deriving the path from import.meta.url using the node:url and node:path modules [1][5]: import { fileURLToPath } from 'node:url'; import { dirname } from 'node:path'; const filename = fileURLToPath(import.meta.url); const dirname = dirname(filename);

Citations:


Support the declared Node.js version range.

package.json allows Node.js 20.0.0, but import.meta.dirname is only available from Node.js 20.11.0. On earlier supported Node.js 20 releases, Playwright cannot load this config. Use path.dirname(fileURLToPath(import.meta.url)), or raise the engine floor. (nodejs.org)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright.config.ts` at line 12, Update the Playwright configuration’s
dotenv path resolution to support Node.js 20.0.0 by deriving the directory from
import.meta.url with fileURLToPath and path.dirname instead of using
import.meta.dirname; add or reuse the required imports while preserving the
existing .env path.

Comment thread playwright.config.ts
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('')`. */
baseURL: process.env.BASE_URL,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 3 'BASE_URL|baseURL|page\.goto\(' playwright.config.ts tests/specs

Repository: lightspeedwp/ls-theme

Length of output: 6439


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== candidate test files =="
git ls-files 'tests/specs/*.ts' | sort

echo
echo "== URL constants and goto usages =="
rg -n '^[A-Z_]+URL|page\.goto\(' tests/specs -S

echo
echo "== all page.goto usages in repository =="
rg -n 'page\.goto\(' . -S

echo
echo "== full playwright config outline/content =="
wc -l playwright.config.ts
sed -n '1,120p' playwright.config.ts

Repository: lightspeedwp/ls-theme

Length of output: 4742


Require BASE_URL before starting the suite.

baseURL is used by the existing specs for relative page.goto() calls. If BASE_URL is empty in .env, assigning it directly creates an invalid base URL instead of a clear setup failure. Reject a missing or empty BASE_URL in playwright.config.ts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playwright.config.ts` at line 34, Update the Playwright configuration’s
baseURL assignment to validate that process.env.BASE_URL is present and
non-empty before the suite starts, and fail clearly during configuration when it
is missing. Preserve the existing baseURL behavior for valid values.

Comment on lines +43 to +50
test('the hero CTA links to the consultation page', async ({ page, baseURL }) => {
await page.goto(WORK_ARCHIVE_URL);
// "Book a consultation" text also appears (with a trailing "→") in the
// Discuss Project section further down, so use the hero-only
// "Explore case studies" link to keep the match unambiguous. WP renders
// home_url() links as absolute URLs, so the expected href must match
// the full origin too.
await expectLinkHref(page, 'Explore case studies', `${baseURL}/work/`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Build the expected href from WORK_ARCHIVE_URL.

Line 14 permits WORK_ARCHIVE_PATH=/portfolio/, but Line 50 still asserts /work/. The template string also produces //work/ when BASE_URL ends with /. This creates a false failure for valid local environments. Resolve the configured path with new URL().

Proposed fix
-	test('the hero CTA links to the consultation page', async ({ page, baseURL }) => {
+	test('the hero CTA links to the Work Archive page', async ({ page }) => {
 		await page.goto(WORK_ARCHIVE_URL);
-		await expectLinkHref(page, 'Explore case studies', `${baseURL}/work/`);
+		await expectLinkHref(page, 'Explore case studies', new URL(WORK_ARCHIVE_URL, page.url()).href);
 	});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('the hero CTA links to the consultation page', async ({ page, baseURL }) => {
await page.goto(WORK_ARCHIVE_URL);
// "Book a consultation" text also appears (with a trailing "→") in the
// Discuss Project section further down, so use the hero-only
// "Explore case studies" link to keep the match unambiguous. WP renders
// home_url() links as absolute URLs, so the expected href must match
// the full origin too.
await expectLinkHref(page, 'Explore case studies', `${baseURL}/work/`);
test('the hero CTA links to the Work Archive page', async ({ page }) => {
await page.goto(WORK_ARCHIVE_URL);
// "Book a consultation" text also appears (with a trailing "→") in the
// Discuss Project section further down, so use the hero-only
// "Explore case studies" link to keep the match unambiguous. WP renders
// home_url() links as absolute URLs, so the expected href must match
// the full origin too.
await expectLinkHref(page, 'Explore case studies', new URL(WORK_ARCHIVE_URL, page.url()).href);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/specs/work-archive.spec.ts` around lines 43 - 50, Update the hero CTA
assertion in the test using WORK_ARCHIVE_URL as the source of truth: resolve the
expected href with new URL() so WORK_ARCHIVE_PATH is respected and trailing
slashes in baseURL cannot produce a double slash. Keep the existing “Explore
case studies” link verification unchanged.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The Playwright config is not compatible with the repo’s stated Node support range, and the Work Archive spec hardcodes /work/ despite supporting an override path.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Adds a local Playwright test harness to the theme repo to support manual, developer-run end-to-end checks against live environments, plus initial assertion helpers and template specs.

Changes:

  • Adds Playwright configuration (multi-browser projects, html reporter) and loads BASE_URL from a local .env.
  • Introduces reusable Playwright assertion helpers and a real “Work Archive” spec using them.
  • Updates Node devDependencies and ignores Playwright output directories; documents the addition in the changelog.
File summaries
File Description
playwright.config.ts Adds Playwright test configuration and dotenv loading for local base URL.
tests/helpers/assertions.ts Adds generic assertion helpers used by e2e specs.
tests/specs/work-archive.spec.ts Adds a real, running spec for the Work Archive template using the helpers.
tests/specs/work-single.spec.ts Adds an illustrative (skipped) spec demonstrating intended helper usage.
package.json Adds Playwright + dotenv + Node types to devDependencies.
package-lock.json Locks Playwright/dotenv dependency tree.
CHANGELOG.md Notes the addition of Playwright e2e testing setup.
.gitignore Ignores Playwright reports/output directories.
Review details
  • Files reviewed: 6/8 changed files
  • Comments generated: 5
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment thread playwright.config.ts
Comment on lines +7 to +12
import dotenv from 'dotenv';
import path from 'path';
// This repo's package.json has "type": "module", so __dirname (assumed by
// Playwright's own generated template) isn't available here — using
// Node's documented ESM equivalent instead: https://nodejs.org/api/esm.html#importmetadirname
dotenv.config({ path: path.resolve(import.meta.dirname, '.env') });
Comment thread playwright.config.ts
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('')`. */
baseURL: process.env.BASE_URL,
]);
});

test('the hero CTA links to the consultation page', async ({ page, baseURL }) => {
// "Explore case studies" link to keep the match unambiguous. WP renders
// home_url() links as absolute URLs, so the expected href must match
// the full origin too.
await expectLinkHref(page, 'Explore case studies', `${baseURL}/work/`);
Comment on lines +42 to +45
test('the CTA button links to the consultation page', async ({ page }) => {
await page.goto(SINGLE_PROJECT_URL);
await expectLinkHref(page, 'Book a consultation', '/free-consultation/');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:dependencies Composer/npm dependency work lang:js JavaScript/TypeScript status:needs-review Awaiting code review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants