Skip to content

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

Open
brandonmarshal wants to merge 2 commits 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 2 commits 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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 66d945fe-9c07-4cbe-a821-5026af674a8b

📥 Commits

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

📒 Files selected for processing (3)
  • playwright.config.ts
  • tests/specs/work-archive.spec.ts
  • tests/specs/work-single.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/specs/work-archive.spec.ts
  • tests/specs/work-single.spec.ts

📝 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

🚥 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 main change: setting up Playwright 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 Outdated
Comment thread playwright.config.ts
Comment thread tests/specs/work-archive.spec.ts Outdated

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 Outdated
Comment thread playwright.config.ts
Comment thread tests/specs/work-archive.spec.ts Outdated
Comment thread tests/specs/work-archive.spec.ts Outdated
Comment thread tests/specs/work-single.spec.ts
- Use fileURLToPath(import.meta.url) instead of import.meta.dirname in
  playwright.config.ts so the dotenv loader works across the full
  declared engines.node range (>=20.0.0), not just Node 20.11+
- Fail fast with a clear error if BASE_URL isn't set, instead of a
  confusing "Invalid URL" failure inside a test
- Fix work-archive.spec.ts's hero CTA test: rename it to match what it
  actually checks, and resolve the expected href from WORK_ARCHIVE_URL
  via new URL() so it respects the WORK_ARCHIVE_PATH override and can't
  produce a double slash
- Fix the same relative-href bug in the skipped work-single.spec.ts
  example, so it doesn't get copied forward when that template exists

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.

Pull request overview

Copilot reviewed 6 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (5)

tests/helpers/assertions.ts:30

  • expectSectionOrder uses indexOf() without a start position, so if a marker string appears earlier on the page as well (or markers repeat), the helper can pass/fail incorrectly. Searching for each marker after the previous match makes the ordering assertion reliable.
	const bodyText = (await page.locator('body').innerText()).toLowerCase();
	const positions = markers.map((marker) => bodyText.indexOf(marker.toLowerCase()));

tests/helpers/assertions.ts:62

  • expectLinkHref can throw a strict-mode error if more than one link partially matches linkText (because exact: false). Making the helper assert a single match first keeps failures clearer and prevents Playwright strictness errors.
export async function expectLinkHref(page: Page, linkText: string, expectedHref: string) {
	const link = page.getByRole('link', { name: linkText, exact: false });
	await expect(link).toHaveAttribute('href', expectedHref);
}

tests/helpers/assertions.ts:90

  • gridTemplateColumns.split(' ') is not a reliable way to count grid tracks because computed values can include spaces inside functions (e.g. minmax(0px, 1fr)), which inflates the count and will be browser-dependent. Split the track list on top-level whitespace instead.
	if (display === 'grid') {
		const columns = await grid.evaluate(
			(el) => getComputedStyle(el).gridTemplateColumns.split(' ').length
		);

tests/helpers/assertions.ts:96

  • In the flex/columns branch, if the grid has no child elements then tops[0] is undefined and the failure message becomes misleading (it will compare against undefined). Add an explicit assertion that the grid has at least one child first.
	// Flex/columns layout: count distinct items sharing the first row's top offset.
	const tops: number[] = await grid.evaluate((el) =>
		[...el.children].map((child) => Math.round(child.getBoundingClientRect().top))
	);
	const firstRowCount = tops.filter((t) => t === tops[0]).length;

tests/specs/work-single.spec.ts:22

  • This file is entirely skipped via test.describe.skip, so it will never exercise the helpers but will still appear as a permanently skipped suite in local runs. If it’s only meant as an example, consider switching to a normal describe with a single test.skip(true, ...) inside so the report shows an explicit reason (and it’s harder to forget this is intentionally inactive).
// Skipped: work-single doesn't exist yet, and these selectors/URL are illustrative
// guesses, not real markup. Un-skip once the template is built and selectors are
// swapped for the real ones.
test.describe.skip('Work Single template', () => {
	test('renders sections in order', async ({ page }) => {

@ZaredRogers ZaredRogers left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good @brandonmarshal

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.

3 participants