Skip to content

Comments

fix(e2e): stabilize monorepo playwright runs across apps#1660

Merged
yacosta738 merged 2 commits intomainfrom
fix/e2e-preflight
Feb 23, 2026
Merged

fix(e2e): stabilize monorepo playwright runs across apps#1660
yacosta738 merged 2 commits intomainfrom
fix/e2e-preflight

Conversation

@yacosta738
Copy link
Owner

@yacosta738 yacosta738 commented Feb 23, 2026

Summary

  • align apps/portfolio Playwright base URL and web server ports to 4321 so it targets the correct app during E2E execution
  • scope E2E suites per app using testIgnore (portfolio ignores blog-only specs, blog ignores portfolio contact-form spec)
  • run root test:e2e sequentially (portfolio then blog) to avoid cross-app test server contention in monorepo runs

Validation

  • pnpm test:e2e
  • make preflight

Summary by CodeRabbit

  • Chores

    • Exclude specific end-to-end tests from automated runs.
    • Change development/preview server port and base URL to use port 4321.
    • Update e2e script to run portfolio and blog tests sequentially.
  • Refactor

    • Adjust test tooling alias resolution to reference the shared package source.
  • Style

    • Reformat imports, config objects, and JSON whitespace for consistency.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 23, 2026

Deploying yap-portfolio with  Cloudflare Pages  Cloudflare Pages

Latest commit: a04dc71
Status: ✅  Deploy successful!
Preview URL: https://a2dfd464.yacosta738-github-io.pages.dev
Branch Preview URL: https://fix-e2e-preflight.yacosta738-github-io.pages.dev

View logs

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 23, 2026

📝 Walkthrough

Walkthrough

Playwright configs updated to ignore specific E2E tests and portfolio's baseURL/ports standardized to 4321; package.json test:e2e script changed to run portfolio then blog sequentially. Several non-functional formatting tweaks in content and config files; one alias update in vitest config.

Changes

Cohort / File(s) Summary
Playwright configs
apps/blog/playwright.config.ts, apps/portfolio/playwright.config.ts
Added testIgnore arrays to skip specified E2E specs; apps/portfolio also changed baseURL and webServer ports/commands from 43224321 (preview and dev paths).
Top-level scripts
package.json
Replaced combined filter-based E2E invocation with two sequential scripts: pnpm test:e2e:portfolio && pnpm test:e2e:blog.
Content & formatting tweaks
apps/blog/src/content.config.ts, apps/portfolio/src/content.config.ts, apps/blog/astro.config.mjs, apps/blog/src/pages/[lang]/index.astro, apps/blog/src/data/resume/en/resume.json, apps/blog/src/data/resume/es/resume.json
Reformatted imports and object literals; whitespace/indentation adjustments in JSON and imports. No functional changes.
Vitest alias update
apps/portfolio/vitest.config.ts
Updated path aliases to resolve @/ and @ to ../../packages/shared/src (shared package source) instead of local ./src.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • #1637: Modifies apps/portfolio/playwright.config.ts for Playwright flags and artifact/failure handling — overlaps with test config changes here.
  • #1633: Adjusts Playwright webServer and CI-aware handling in portfolio config — related to the port/baseURL changes.
  • #1577: Edits portfolio Playwright config and E2E specs touching tag-external-articles.spec.ts, which is now ignored in this PR.

Poem

🐰 Hopping through configs with a twitch of my ear,
Ports set to 4321 — the path is now clear,
Tests skipped where needed, scripts run in a line,
Formatting spruced up, the repo does shine,
A rabbit's small cheer for changes so near! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: fixing and stabilizing Playwright E2E test runs in the monorepo across multiple apps by aligning ports, scoping test suites, and ensuring sequential execution.
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 docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/e2e-preflight

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 and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 23, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
yap-api a04dc71 Commit Preview URL

Branch Preview URL
Feb 23 2026, 06:11 PM

@github-actions
Copy link
Contributor

🤖 CI Pipeline Results

Check Status
🔍 Lint & Type Check ❌ failure
🧪 Unit Tests ❌ failure
🏗️ Build ⏭️ skipped
🎭 E2E Tests ⏭️ skipped
📊 Code Quality ✅ success

Commit: 77390b8
Workflow: View Details

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
package.json (1)

48-48: Sequential execution with && silently skips blog tests on portfolio failure.

The deliberate sequential ordering correctly prevents port/server contention — that design is sound. The minor side-effect is that a portfolio failure leaves blog test status unknown in CI. If independent suite reporting matters, consider:

-		"test:e2e": "pnpm test:e2e:portfolio && pnpm test:e2e:blog",
+		"test:e2e": "pnpm test:e2e:portfolio; pnpm test:e2e:blog",

Using ; runs both suites unconditionally and still preserves the exit code of the last command. If fail-fast is intentional, the current && is fine — just worth documenting.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` at line 48, The test:e2e script currently uses "pnpm
test:e2e:portfolio && pnpm test:e2e:blog" which stops running blog tests if
portfolio fails; change the script so both suites always run (e.g., replace &&
with ; to run them sequentially unconditionally) or implement a runner that
executes both and aggregates exit codes; update the "test:e2e" entry to run
"pnpm test:e2e:portfolio" then "pnpm test:e2e:blog" unconditionally (or use a
small wrapper to run both and return a non-zero exit if either fails) so CI
reports both suites even when one fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/blog/playwright.config.ts`:
- Line 9: The Playwright config's testIgnore patterns use relative globs that
won't reliably match absolute paths; update the testIgnore arrays in the
Playwright configs (the testIgnore property in apps/blog/playwright.config.ts
and apps/portfolio/playwright.config.ts) to prefix ignored file patterns with
"**/" (e.g., change "tests/e2e/contact-form.spec.ts" to
"**/tests/e2e/contact-form.spec.ts") so the glob will match absolute file paths
as Playwright expects.

---

Nitpick comments:
In `@package.json`:
- Line 48: The test:e2e script currently uses "pnpm test:e2e:portfolio && pnpm
test:e2e:blog" which stops running blog tests if portfolio fails; change the
script so both suites always run (e.g., replace && with ; to run them
sequentially unconditionally) or implement a runner that executes both and
aggregates exit codes; update the "test:e2e" entry to run "pnpm
test:e2e:portfolio" then "pnpm test:e2e:blog" unconditionally (or use a small
wrapper to run both and return a non-zero exit if either fails) so CI reports
both suites even when one fails.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0df5fc and 08752a1.

📒 Files selected for processing (3)
  • apps/blog/playwright.config.ts
  • apps/portfolio/playwright.config.ts
  • package.json

*/
export default defineConfig({
testDir: "tests/e2e",
testIgnore: ["tests/e2e/contact-form.spec.ts"],
Copy link
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
# 1. Check if contact-form.spec.ts physically exists in apps/blog's test tree
echo "=== Checking for contact-form.spec.ts in apps/blog ==="
fd "contact-form.spec.ts" apps/blog 2>/dev/null || echo "Not found"

# 2. List all .spec.ts files in apps/blog/tests/e2e to see what exists
echo "=== All .spec.ts files in apps/blog/tests/e2e ==="
fd -e "spec.ts" apps/blog/tests/e2e 2>/dev/null || echo "Directory does not exist or no specs found"

# 3. Check if apps/blog/tests/e2e directory exists at all
echo "=== Directory listing for apps/blog/tests ==="
ls -la apps/blog/tests 2>/dev/null || echo "No tests directory in apps/blog"

# 4. Look for the playwright.config.ts file and read its content
echo "=== Current playwright.config.ts content in apps/blog ==="
cat apps/blog/playwright.config.ts 2>/dev/null || echo "File not found"

# 5. Check apps/portfolio's playwright config for comparison
echo "=== Current playwright.config.ts content in apps/portfolio ==="
cat apps/portfolio/playwright.config.ts 2>/dev/null || echo "File not found"

# 6. List all test files in apps/portfolio to see blog-only specs
echo "=== All .spec.ts files in apps/portfolio/tests/e2e ==="
fd -e "spec.ts" apps/portfolio/tests 2>/dev/null || echo "No test files found"

Repository: yacosta738/yacosta738.github.io

Length of output: 7353


🌐 Web query:

Playwright testIgnore relative path pattern matching documentation

💡 Result:

testIgnore patterns are matched against the absolute file path of each test file; string values are treated as glob patterns (you can also use RegExp or an array of globs/regexes). So “relative-looking” patterns generally need to be written to match anywhere in the absolute path (e.g., prefix with **/). (playwright.dev)

Examples (from the docs and typical usage):

  • Ignore a directory anywhere: testIgnore: '**/test-assets/**' (playwright.dev)
  • You can also do: testIgnore: ['**/e2e/experimental/**', /.*\.flaky\.spec\.(ts|js)$/] (glob + regex) (playwright.dev)

Sources

  • [1] Playwright API docs — testConfig.testIgnore (playwright.dev)
  • [2] Playwright “Test configuration” — filtering tests (testIgnore/testMatch) (playwright.dev)

Citations:


Fix testIgnore glob patterns to use **/ prefix for reliable absolute-path matching.

Per Playwright's official documentation, testIgnore patterns are matched against the absolute file path using glob semantics. The pattern "tests/e2e/contact-form.spec.ts" (relative form) will not reliably match an absolute path like /runner/work/.../apps/blog/tests/e2e/contact-form.spec.ts without the **/ prefix.

Update both apps/blog/playwright.config.ts and apps/portfolio/playwright.config.ts to use the documented glob format:

Example for apps/blog
-	testIgnore: ["tests/e2e/contact-form.spec.ts"],
+	testIgnore: ["**/contact-form.spec.ts"],
Example for apps/portfolio
 	testIgnore: [
-		"tests/e2e/comments*.spec.ts",
-		"tests/e2e/search.spec.ts",
-		"tests/e2e/newsletter.spec.ts",
-		"tests/e2e/tag-external-articles.spec.ts",
+		"**/comments*.spec.ts",
+		"**/search.spec.ts",
+		"**/newsletter.spec.ts",
+		"**/tag-external-articles.spec.ts",
 	],
📝 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
testIgnore: ["tests/e2e/contact-form.spec.ts"],
testIgnore: ["**/contact-form.spec.ts"],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/blog/playwright.config.ts` at line 9, The Playwright config's testIgnore
patterns use relative globs that won't reliably match absolute paths; update the
testIgnore arrays in the Playwright configs (the testIgnore property in
apps/blog/playwright.config.ts and apps/portfolio/playwright.config.ts) to
prefix ignored file patterns with "**/" (e.g., change
"tests/e2e/contact-form.spec.ts" to "**/tests/e2e/contact-form.spec.ts") so the
glob will match absolute file paths as Playwright expects.

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
79.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/portfolio/vitest.config.ts (1)

22-26: ⚠️ Potential issue | 🟡 Minor

Coverage include may no longer align with what the unit tests actually exercise.

With the alias now pointing to packages/shared/src/, code imported via @/ in unit tests lives outside apps/portfolio/src/. The current coverage.include of src/**/*.ts and src/**/*.astro will not capture shared-package execution paths, so coverage numbers will undercount what is being exercised (and may overcount uncovered files in apps/portfolio/src/ that are no longer reachable via @/).

If the portfolio's unit tests are primarily testing shared-package code through the @/ alias, consider also including the shared package source in coverage (or adjusting the include to match the actual tested surface).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/portfolio/vitest.config.ts` around lines 22 - 26, The coverage.include
in vitest.config.ts currently only targets "src/**/*.ts" and "src/**/*.astro"
but tests import shared code through the "@/” alias (pointing at
packages/shared/src), so coverage undercounts executed code; update the
coverage.include to also include the shared package sources (e.g.,
packages/shared/src/**/*.ts and any relevant extensions) or otherwise adjust the
include globs to match the actual tested surface so files imported via "@/..."
are measured; locate the coverage.include setting in
apps/portfolio/vitest.config.ts and add the shared package glob(s) (or replace
the includes with a combined pattern) to ensure coverage captures shared-package
execution paths.
🧹 Nitpick comments (2)
apps/portfolio/vitest.config.ts (2)

11-13: Consider anchoring the resolved path to the config file rather than process.cwd().

path.resolve("../../packages/shared/src") is resolved relative to process.cwd(), which is apps/portfolio/ only when the script is invoked through the package's own pnpm script. Invoking vitest from the monorepo root (e.g., vitest run apps/portfolio/...) would produce a wrong path. A file-relative anchor is safer:

♻️ Proposed fix using `import.meta.url`
+import { fileURLToPath } from "node:url";
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
 alias: [
   {
     find: "@/",
-    replacement: `${path.resolve("../../packages/shared/src")}/`,
+    replacement: `${path.resolve(__dirname, "../../packages/shared/src")}/`,
   },
-  { find: "@", replacement: path.resolve("../../packages/shared/src") },
+  { find: "@", replacement: path.resolve(__dirname, "../../packages/shared/src") },
 ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/portfolio/vitest.config.ts` around lines 11 - 13, The current
replacement entry uses path.resolve("../../packages/shared/src") which is
resolved from process.cwd() and can be incorrect when Vitest is run from the
monorepo root; change the resolution to be file-relative by computing the config
directory from import.meta.url (e.g. const __dirname =
path.dirname(fileURLToPath(import.meta.url))) and then use
path.resolve(__dirname, "../../packages/shared/src") for both replacement
entries (the one ending with a trailing slash and the one for "@" in the config)
so the aliases are always resolved relative to the vitest config file.

9-13: Consider using import.meta.url for more robust path resolution instead of path.resolve() with relative paths.

The module imports in unit tests (@/utils/resolveSiteUrl, @/lib/collection.entity, @/core/resume/*, @/i18n) all resolve correctly—these modules exist only in the shared package, not locally in portfolio/src (which contains only 13 files: pages, layouts, and config). The alias redirect is working as intended. However, path.resolve("../../packages/shared/src") is CWD-dependent; if vitest is invoked from the monorepo root or a different directory, the relative path resolution may break. Using import.meta.url with fileURLToPath() would provide file-relative resolution that works regardless of where the command is run.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/portfolio/vitest.config.ts` around lines 9 - 13, The alias entries using
path.resolve("../../packages/shared/src") in vitest.config.ts are CWD-dependent;
replace them with file-relative resolution using import.meta.url and
fileURLToPath so the alias always points to the shared/src directory regardless
of where vitest is run. Update the two alias objects (find: "@/"; replacement:
... and find: "@"; replacement: ...) to compute the replacement via const
__dirname = path.dirname(fileURLToPath(import.meta.url)) and then resolve the
shared/src path from __dirname (or directly use fileURLToPath(new URL(...,
import.meta.url))); ensure both alias replacements use this file-relative value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@apps/portfolio/vitest.config.ts`:
- Around line 22-26: The coverage.include in vitest.config.ts currently only
targets "src/**/*.ts" and "src/**/*.astro" but tests import shared code through
the "@/” alias (pointing at packages/shared/src), so coverage undercounts
executed code; update the coverage.include to also include the shared package
sources (e.g., packages/shared/src/**/*.ts and any relevant extensions) or
otherwise adjust the include globs to match the actual tested surface so files
imported via "@/..." are measured; locate the coverage.include setting in
apps/portfolio/vitest.config.ts and add the shared package glob(s) (or replace
the includes with a combined pattern) to ensure coverage captures shared-package
execution paths.

---

Nitpick comments:
In `@apps/portfolio/vitest.config.ts`:
- Around line 11-13: The current replacement entry uses
path.resolve("../../packages/shared/src") which is resolved from process.cwd()
and can be incorrect when Vitest is run from the monorepo root; change the
resolution to be file-relative by computing the config directory from
import.meta.url (e.g. const __dirname =
path.dirname(fileURLToPath(import.meta.url))) and then use
path.resolve(__dirname, "../../packages/shared/src") for both replacement
entries (the one ending with a trailing slash and the one for "@" in the config)
so the aliases are always resolved relative to the vitest config file.
- Around line 9-13: The alias entries using
path.resolve("../../packages/shared/src") in vitest.config.ts are CWD-dependent;
replace them with file-relative resolution using import.meta.url and
fileURLToPath so the alias always points to the shared/src directory regardless
of where vitest is run. Update the two alias objects (find: "@/"; replacement:
... and find: "@"; replacement: ...) to compute the replacement via const
__dirname = path.dirname(fileURLToPath(import.meta.url)) and then resolve the
shared/src path from __dirname (or directly use fileURLToPath(new URL(...,
import.meta.url))); ensure both alias replacements use this file-relative value.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08752a1 and a04dc71.

📒 Files selected for processing (7)
  • apps/blog/astro.config.mjs
  • apps/blog/src/content.config.ts
  • apps/blog/src/data/resume/en/resume.json
  • apps/blog/src/data/resume/es/resume.json
  • apps/blog/src/pages/[lang]/index.astro
  • apps/portfolio/src/content.config.ts
  • apps/portfolio/vitest.config.ts
✅ Files skipped from review due to trivial changes (4)
  • apps/portfolio/src/content.config.ts
  • apps/blog/src/content.config.ts
  • apps/blog/src/data/resume/en/resume.json
  • apps/blog/src/data/resume/es/resume.json

@github-actions
Copy link
Contributor

🤖 CI Pipeline Results

Check Status
🔍 Lint & Type Check ✅ success
🧪 Unit Tests ✅ success
🏗️ Build ✅ success
🎭 E2E Tests ✅ success
📊 Code Quality ✅ success

Commit: f76d8b5
Workflow: View Details

@yacosta738 yacosta738 merged commit ad89f78 into main Feb 23, 2026
38 of 39 checks passed
@yacosta738 yacosta738 deleted the fix/e2e-preflight branch February 23, 2026 18:24
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.

1 participant