Skip to content

feat : configure playwright e2e testing and integrate into CI#136

Merged
DataDave-Dev merged 1 commit into
DataDave-Dev:mainfrom
YasserYG8:feature/playwright
Jun 22, 2026
Merged

feat : configure playwright e2e testing and integrate into CI#136
DataDave-Dev merged 1 commit into
DataDave-Dev:mainfrom
YasserYG8:feature/playwright

Conversation

@YasserYG8

@YasserYG8 YasserYG8 commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Pull Request Description

Title

test: add Playwright E2E smoke test for analyze-and-render flow


Description

Resolves #69

Summary of Changes

This PR adds End-to-End (E2E) smoke testing coverage to weftmap using Playwright. It ensures that the core user flow—loading the app, clicking "Analyze", invoking the server-side WASM tree-sitter parsers, and successfully drawing the React Flow call graph—works without regressions.

Key Implementations

  1. Playwright Setup: Created playwright.config.ts running tests against the dev server (pnpm dev) for fast local feedback.
  2. E2E Smoke Test: Added e2e/smoke.spec.ts which asserts the default Python call graph successfully renders 6 canvas nodes (snippet.py + 5 functions).
  3. Environment & Security: Configured AUTH_TRUST_HOST=true and AUTH_SECRET in both Playwright and the CI runner to suppress NextAuth untrusted host warnings.
  4. CI Pipeline Integration: Created a parallel e2e workflow job in .github/workflows/ci.yml that installs browser dependencies and runs the test suite on every PR and push to main.
  5. Trace Recording: Configured Playwright to always record traces (trace: 'on') to simplify debugging browser actions.

How to Test Locally

  1. Install Playwright Browsers:

    npx playwright install chromium
  2. Run E2E Tests:

    pnpm test:e2e
  3. Run in UI / Interactive Mode:

    pnpm test:e2e:ui

Summary by CodeRabbit

Tests

  • Added end-to-end smoke tests validating the code analysis workflow, graph rendering, and output nodes
  • Enhanced CI pipeline to automatically execute E2E tests alongside the build process

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Playwright end-to-end smoke test infrastructure: a playwright.config.ts with CI-aware settings and local dev server wiring, an e2e/smoke.spec.ts that navigates the app, triggers analysis, and asserts six React Flow nodes render, plus package scripts, a @playwright/test dependency, gitignore rules, and a new CI e2e job.

Changes

Playwright E2E Smoke Test Setup

Layer / File(s) Summary
Playwright config, scripts, dependency, and gitignore
playwright.config.ts, package.json, .gitignore
Adds playwright.config.ts with CI-aware retries/workers, Chromium project, local dev server startup with auth env vars, and HTML reporter. Extends package.json with test:e2e / test:e2e:ui scripts and @playwright/test devDependency. Adds /playwright-report and /test-results to .gitignore.
Smoke test spec
e2e/smoke.spec.ts
Navigates to /en/app, asserts textarea and Analyze button visibility, clicks Analyze, then asserts the React Flow workspace renders with exactly six nodes and expected labels (snippet.py, main, clean).
CI e2e job
.github/workflows/ci.yml
Adds an e2e job on ubuntu-latest that sets auth/database environment variables, installs Playwright Chromium with OS dependencies, and runs pnpm test:e2e.

Sequence Diagram(s)

sequenceDiagram
  participant Playwright as Playwright (Chromium)
  participant AppPage as /en/app
  participant AnalyzeAPI as POST /api/analyze
  participant ReactFlow as React Flow Diagram

  Playwright->>AppPage: navigate to /en/app
  AppPage-->>Playwright: textarea visible, Analyze button enabled
  Playwright->>AppPage: click Analyze
  AppPage->>AnalyzeAPI: submit default code snippet
  AnalyzeAPI-->>AppPage: graph node data
  AppPage->>ReactFlow: render nodes
  ReactFlow-->>Playwright: assert 6 nodes, labels snippet.py / main / clean
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 Hop, hop, the test suite grows,
A smoke test checks the code that flows.
Six nodes appear in React Flow's light,
snippet.py, main, clean — just right!
The CI job now guards the gate,
No regression slips past fate. 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description provides comprehensive detail on all changes including Playwright setup, E2E smoke test, environment config, CI integration, and local testing instructions. However, it does not follow the repository's required Spanish template structure (Qué hace, Tipo checklist, verification checklist). Reformat the description to match the repository template: add sections for 'Qué hace', select the 'test' type checkbox, and include the verification checklist (lint, typecheck, test, build).
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding Playwright E2E testing configuration and CI integration. It accurately reflects the primary objectives of the PR.
Linked Issues check ✅ Passed All objectives from issue #69 are met: Playwright configuration targets the dev server, E2E smoke test validates the app load → code submission → graph rendering flow, specific assertions on 6 graph nodes are present, and CI integration via separate e2e job is implemented.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing E2E testing infrastructure and CI integration as required by issue #69. No extraneous modifications were introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🧹 Nitpick comments (4)
.github/workflows/ci.yml (2)

31-37: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consider making the e2e job dependent on successful build.

The e2e job runs in parallel with the build job, which means E2E tests could start even if linting, type-checking, or unit tests fail. This wastes CI resources and creates confusing failure scenarios.

⚡ Proposed fix
   e2e:
     runs-on: ubuntu-latest
+    needs: build
     env:
🤖 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 @.github/workflows/ci.yml around lines 31 - 37, The e2e job runs in parallel
with the build job instead of waiting for it to complete, which wastes CI
resources if the build fails. Add a job dependency directive to the e2e job
definition to make it wait for the build job to finish successfully before
starting. This should be added as a property at the same level as runs-on and
env in the e2e job configuration.

38-45: 🧹 Nitpick | 🔵 Trivial

Security: Consider pinning GitHub Actions to commit SHAs.

Static analysis flagged that actions are referenced by tag (e.g., @v7) rather than pinned to specific commit hashes. Pinning to SHAs provides stronger supply chain security against tag manipulation.

Additionally, consider setting persist-credentials: false on the checkout action to prevent credential leakage.

🔒 Example hardening
       steps:
-        - uses: actions/checkout@v7
+        - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v7
+          with:
+            persist-credentials: false
 
-        - uses: pnpm/action-setup@v6
+        - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v6
 
-        - uses: actions/setup-node@v6
+        - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v6

Note: These concerns may also apply to the existing build job. Consider addressing them repository-wide if they're not already handled.

🤖 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 @.github/workflows/ci.yml around lines 38 - 45, Replace the version tag
references (v7, v6, v6) with specific commit SHAs for the three GitHub Actions
in this workflow: actions/checkout, pnpm/action-setup, and actions/setup-node.
Additionally, add a configuration parameter `persist-credentials: false` to the
actions/checkout action to prevent credential leakage. This strengthens supply
chain security by pinning to immutable commit hashes instead of mutable tags,
making the workflow resistant to tag manipulation attacks.

Source: Linters/SAST tools

playwright.config.ts (1)

10-23: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider extracting the base URL to a constant.

The URL http://localhost:3000 is repeated in both webServer.url (line 12) and use.baseURL (line 22). Extracting it to a constant would reduce duplication and ensure consistency if the port ever needs to change.

♻️ Proposed refactor
+const BASE_URL = "http://localhost:3000";
+
 export default defineConfig({
   testDir: "./e2e",
   fullyParallel: true,
   forbidOnly: !!process.env.CI,
   retries: process.env.CI ? 2 : 0,
   workers: process.env.CI ? 1 : undefined,
   reporter: "html",
   webServer: {
     command: "pnpm dev",
-    url: "http://localhost:3000",
+    url: BASE_URL,
     reuseExistingServer: !process.env.CI,
     stdout: "ignore",
     stderr: "pipe",
     env: {
       AUTH_TRUST_HOST: "true",
       AUTH_SECRET: "some-dummy-secret-for-e2e",
     },
   },
   use: {
-    baseURL: "http://localhost:3000",
+    baseURL: BASE_URL,
     trace: "on",
   },
🤖 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` around lines 10 - 23, The base URL string
http://localhost:3000 is duplicated in the playwright.config.ts configuration
object, appearing in both the webServer.url and use.baseURL fields. Extract this
URL to a constant variable defined at the top of the file (before the export
statement), and then replace both hardcoded occurrences with references to this
constant to eliminate duplication and improve maintainability.
e2e/smoke.spec.ts (1)

24-27: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider verifying all function labels for completeness.

The test verifies 3 node labels (snippet.py, main, clean) but the default Python sample defines 5 functions: main, load, transform, clean, and save. Adding assertions for the remaining functions (load, transform, save) would provide more comprehensive smoke test coverage.

♻️ Proposed additional assertions
   // 6. Verify key node labels contain our function names and container file
   await expect(page.locator(".react-flow__node", { hasText: "snippet.py" })).toBeVisible();
   await expect(page.locator(".react-flow__node", { hasText: "main" })).toBeVisible();
+  await expect(page.locator(".react-flow__node", { hasText: "load" })).toBeVisible();
+  await expect(page.locator(".react-flow__node", { hasText: "transform" })).toBeVisible();
   await expect(page.locator(".react-flow__node", { hasText: "clean" })).toBeVisible();
+  await expect(page.locator(".react-flow__node", { hasText: "save" })).toBeVisible();
 });
🤖 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 `@e2e/smoke.spec.ts` around lines 24 - 27, The smoke test in the verification
section currently only checks for three node labels (snippet.py, main, and
clean) but the default Python sample defines five functions total. Add two
additional await expect statements after the existing assertions to verify the
remaining function nodes for "load", "transform", and "save" using the same
page.locator pattern with the ".react-flow__node" selector and hasText matcher.
This will ensure the test comprehensively validates all expected function nodes
are rendered in the flow diagram.
🤖 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 @.github/workflows/ci.yml:
- Around line 31-53: The e2e CI job is missing artifact uploads for Playwright
test results, which means debugging information is lost when tests fail. After
the "Run E2E Smoke Tests" step that executes pnpm test:e2e, add a new step using
the actions/upload-artifact@v4 action to upload the Playwright HTML report and
traces directory. Configure the upload to run even when tests fail by adding a
condition that checks the job status, and specify the appropriate paths where
Playwright stores its report and trace files (typically playwright-report and
test-results directories).
- Line 36: The E2E job configures TURSO_DATABASE_URL to use a local file-based
database but does not initialize the database schema before running tests. The
application does not automatically create tables on startup; instead, it only
validates the environment variable. Add a database migration step by inserting
pnpm db:push command in the CI workflow before the pnpm test:e2e command to
ensure that the schema from drizzle/schema.sql is executed and all required
tables are created before the E2E tests run against the local database.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 31-37: The e2e job runs in parallel with the build job instead of
waiting for it to complete, which wastes CI resources if the build fails. Add a
job dependency directive to the e2e job definition to make it wait for the build
job to finish successfully before starting. This should be added as a property
at the same level as runs-on and env in the e2e job configuration.
- Around line 38-45: Replace the version tag references (v7, v6, v6) with
specific commit SHAs for the three GitHub Actions in this workflow:
actions/checkout, pnpm/action-setup, and actions/setup-node. Additionally, add a
configuration parameter `persist-credentials: false` to the actions/checkout
action to prevent credential leakage. This strengthens supply chain security by
pinning to immutable commit hashes instead of mutable tags, making the workflow
resistant to tag manipulation attacks.

In `@e2e/smoke.spec.ts`:
- Around line 24-27: The smoke test in the verification section currently only
checks for three node labels (snippet.py, main, and clean) but the default
Python sample defines five functions total. Add two additional await expect
statements after the existing assertions to verify the remaining function nodes
for "load", "transform", and "save" using the same page.locator pattern with the
".react-flow__node" selector and hasText matcher. This will ensure the test
comprehensively validates all expected function nodes are rendered in the flow
diagram.

In `@playwright.config.ts`:
- Around line 10-23: The base URL string http://localhost:3000 is duplicated in
the playwright.config.ts configuration object, appearing in both the
webServer.url and use.baseURL fields. Extract this URL to a constant variable
defined at the top of the file (before the export statement), and then replace
both hardcoded occurrences with references to this constant to eliminate
duplication and improve maintainability.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cfd0c108-7e82-4f01-b40b-bb4e6302d0fc

📥 Commits

Reviewing files that changed from the base of the PR and between c237c7d and 4a63387.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • .gitignore
  • e2e/smoke.spec.ts
  • package.json
  • playwright.config.ts

Comment thread .github/workflows/ci.yml
Comment on lines +31 to +53
e2e:
runs-on: ubuntu-latest
env:
AUTH_SECRET: some-dummy-secret-for-ci
AUTH_TRUST_HOST: "true"
TURSO_DATABASE_URL: file:local.db
steps:
- uses: actions/checkout@v7

- uses: pnpm/action-setup@v6

- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm

- run: pnpm install --frozen-lockfile

- name: Install Playwright Chromium Browser
run: pnpm exec playwright install --with-deps chromium

- name: Run E2E Smoke Tests
run: pnpm test:e2e

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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add artifact upload for Playwright test results.

When E2E tests fail in CI, the HTML report and traces are essential for debugging. Without artifact upload, these files are lost when the job completes.

📦 Proposed addition
       - name: Run E2E Smoke Tests
         run: pnpm test:e2e
+
+      - name: Upload Playwright Report
+        if: always()
+        uses: actions/upload-artifact@v4
+        with:
+          name: playwright-report
+          path: playwright-report/
+          retention-days: 30
📝 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
e2e:
runs-on: ubuntu-latest
env:
AUTH_SECRET: some-dummy-secret-for-ci
AUTH_TRUST_HOST: "true"
TURSO_DATABASE_URL: file:local.db
steps:
- uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Install Playwright Chromium Browser
run: pnpm exec playwright install --with-deps chromium
- name: Run E2E Smoke Tests
run: pnpm test:e2e
e2e:
runs-on: ubuntu-latest
env:
AUTH_SECRET: some-dummy-secret-for-ci
AUTH_TRUST_HOST: "true"
TURSO_DATABASE_URL: file:local.db
steps:
- uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Install Playwright Chromium Browser
run: pnpm exec playwright install --with-deps chromium
- name: Run E2E Smoke Tests
run: pnpm test:e2e
- name: Upload Playwright Report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 38-38: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 31-54: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 38-38: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 40-40: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 42-42: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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 @.github/workflows/ci.yml around lines 31 - 53, The e2e CI job is missing
artifact uploads for Playwright test results, which means debugging information
is lost when tests fail. After the "Run E2E Smoke Tests" step that executes pnpm
test:e2e, add a new step using the actions/upload-artifact@v4 action to upload
the Playwright HTML report and traces directory. Configure the upload to run
even when tests fail by adding a condition that checks the job status, and
specify the appropriate paths where Playwright stores its report and trace files
(typically playwright-report and test-results directories).

Comment thread .github/workflows/ci.yml
env:
AUTH_SECRET: some-dummy-secret-for-ci
AUTH_TRUST_HOST: "true"
TURSO_DATABASE_URL: file:local.db

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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for database initialization or migration logic

# Check for Turso/database initialization in the app
rg -n --type=ts --type=js -C3 'TURSO_DATABASE_URL|drizzle.*migrate|prisma.*migrate' 

# Check for any db setup in package.json scripts
rg -n 'db.*setup|db.*migrate|db.*push' package.json

Repository: DataDave-Dev/weftmap

Length of output: 1256


🏁 Script executed:

# Check the full CI workflow E2E job setup
cat -n .github/workflows/ci.yml | head -60

Repository: DataDave-Dev/weftmap

Length of output: 1653


🏁 Script executed:

# Search for any startup/middleware that might trigger migrations
rg -n --type=ts --type=js "db:push|migrate|startup|middleware" src/

Repository: DataDave-Dev/weftmap

Length of output: 46


🏁 Script executed:

# Check the test:e2e script definition in package.json
rg -n "test:e2e" package.json -A 2

Repository: DataDave-Dev/weftmap

Length of output: 228


🏁 Script executed:

# Look for any startup/initialization code that might run migrations
rg -n "db:push|migrat" src/ --type=ts --type=js

Repository: DataDave-Dev/weftmap

Length of output: 46


🏁 Script executed:

# Check if there's a drizzle migration directory or any setup in the app
find . -name "drizzle" -type d -o -name "*migrat*" -type f | head -20

Repository: DataDave-Dev/weftmap

Length of output: 2565


🏁 Script executed:

# Check what's in the drizzle directory
ls -la drizzle/ 2>/dev/null | head -20

Repository: DataDave-Dev/weftmap

Length of output: 238


🏁 Script executed:

# Read full src/db/index.ts to see initialization logic
cat -n src/db/index.ts

Repository: DataDave-Dev/weftmap

Length of output: 834


Add database migration step to E2E job before running tests.

The E2E job sets TURSO_DATABASE_URL: file:local.db but does not run migrations. The application only validates the environment variable at startup and does not automatically initialize the database—the drizzle/schema.sql migration file exists but is never executed in CI. Add pnpm db:push before pnpm test:e2e to ensure tables exist when E2E tests run.

🤖 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 @.github/workflows/ci.yml at line 36, The E2E job configures
TURSO_DATABASE_URL to use a local file-based database but does not initialize
the database schema before running tests. The application does not automatically
create tables on startup; instead, it only validates the environment variable.
Add a database migration step by inserting pnpm db:push command in the CI
workflow before the pnpm test:e2e command to ensure that the schema from
drizzle/schema.sql is executed and all required tables are created before the
E2E tests run against the local database.

@DataDave-Dev DataDave-Dev merged commit 5068a6f into DataDave-Dev:main Jun 22, 2026
1 of 3 checks passed
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.

Add a Playwright E2E smoke test for the analyze-and-render flow

2 participants