Skip to content

[WIP] Add Playwright E2E tests for Chrome extension content script injection#288

Open
Copilot wants to merge 6 commits intomainfrom
copilot/add-playwright-e2e-tests
Open

[WIP] Add Playwright E2E tests for Chrome extension content script injection#288
Copilot wants to merge 6 commits intomainfrom
copilot/add-playwright-e2e-tests

Conversation

Copy link
Contributor

Copilot AI commented Feb 24, 2026

Introduces Playwright-based E2E testing to packages/extension, starting with a baseline test that verifies the extension's content script is injected into the DOM on the target test page (https://ujiro99.github.io/selection-command/en/test).

Changes

  • playwright.config.ts — minimal Playwright config pointing at ./e2e, 30s timeout, 1 retry
  • e2e/fixtures.ts — custom fixture using chromium.launchPersistentContext with --load-extension=./dist; uses headless: false + --headless=new to support extensions in CI headless mode
  • e2e/extension.spec.ts — single test asserting #selection-command element is attached after page load
  • eslint.config.mjs — disables react-hooks/rules-of-hooks for e2e/** (Playwright's use callback is a false positive)
  • package.json — adds @playwright/test ^1.58.2 devDependency and test:e2e script
  • .gitignore — excludes playwright-report/, test-results/
// e2e/extension.spec.ts
test("E2E-01: extension is injected into the test page", async ({ page }) => {
  await page.goto("https://ujiro99.github.io/selection-command/en/test")
  await expect(page.locator("#selection-command")).toBeAttached()
})

Note: dist/ must exist before running yarn test:e2e. Run yarn build first.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • accounts.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5027 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-XphNKQ --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2002046292911829697,11220293608952573819,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome /home/REDACTED/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl k/_temp/ghcca-node/node/bin/git (dns block)
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5162 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-5ozF2D --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,11695596498033125580,768825631102381217,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
  • clients2.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5027 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-XphNKQ --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2002046292911829697,11220293608952573819,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome /home/REDACTED/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl k/_temp/ghcca-node/node/bin/git (dns block)
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5162 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-5ozF2D --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,11695596498033125580,768825631102381217,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
  • google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5027 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-XphNKQ --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2002046292911829697,11220293608952573819,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5162 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-5ozF2D --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,11695596498033125580,768825631102381217,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
  • ujiro99.github.io
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5027 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-XphNKQ --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2002046292911829697,11220293608952573819,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome /home/REDACTED/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl k/_temp/ghcca-node/node/bin/git (dns block)
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5162 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-5ozF2D --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,11695596498033125580,768825631102381217,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
  • www.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5027 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-XphNKQ --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,2002046292911829697,11220293608952573819,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome /home/REDACTED/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl k/_temp/ghcca-node/node/bin/git (dns block)
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --crashpad-handler-pid=5162 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/playwright_chromiumdev_profile-5ozF2D --change-stack-guard-on-fork=enable --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,11695596498033125580,768825631102381217,262144 --enable-features=CDPScreenshotNewSurface --disable-features=AutoDeElevate,AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,OptimizationHints,PaintHolding,Rend (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>拡張機能をplaywrightでe2eテスト可能にする</issue_title>
<issue_description>- packages/extension配下にplaywright e2eを導入する

</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: ujiro99 <677231+ujiro99@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Playwright for e2e testing of extension Add Playwright E2E tests for Chrome extension content script injection Feb 24, 2026
Copilot AI requested a review from ujiro99 February 24, 2026 23:02
@ujiro99 ujiro99 marked this pull request as ready for review February 25, 2026 21:02
@claude
Copy link

claude bot commented Feb 25, 2026

PR レビュー: Playwright E2E テスト導入

PR全体の構成は良く、Page Object Model (POM)パターンの採用やCI/CDへの統合など、良い設計が見受けられます。いくつかの改善点をお伝えします。


重要な問題

1. TypeScript設定にe2eディレクトリが含まれていない

packages/extension/tsconfig.app.json(L17-24)の include には src/ 配下のファイルのみが指定されており、e2e/ ディレクトリが含まれていません。また tsconfig.node.json(L30-32)は vite.config.ts のみを対象としており、playwright.config.ts も型チェックの対象外です。

これにより yarn tsctsc -b を実行しても、e2eテストコードの型エラーは検出されません。tsconfig.node.json または専用の tsconfig.e2e.jsone2e/**/*.tsplaywright.config.ts を追加することを検討してください。

2. @playwright/test の依存関係の重複

packages/extension/package.json(L82)とルートの package.json(L27)の両方に @playwright/test: ^1.58.2 が追加されています。Yarn workspacesのモノレポ構成では、依存関係はどちらか一方(通常はルートレベル)にのみ定義するのが適切です。重複した定義は混乱を招く可能性があります。

3. CIでの外部URLへのネットワーク依存

.github/workflows/test.yml(L67)の e2e ジョブは https://ujiro99.github.io/selection-command/en/test への接続に依存しています。PR説明のWarningにあるとおり、CIのファイアウォールでこのURLへのアクセスがブロックされており、現状ではE2EテストがCI上で実行できない可能性があります。

GitHub ActionsのCopilot coding agentの allowlist設定で ujiro99.github.io を許可するか、対応を検討してください。


中程度の問題

4. playwright.config.ts に workers の設定がない

packages/extension/playwright.config.ts(L3-7)にワーカー数の設定がありません。デフォルトではPlaywrightは並列でテストを実行します。chromium.launchPersistentContext を使った拡張機能テストでは、並列実行時にブラウザコンテキストの競合が起きる可能性があります。workers: 1 の設定を追加することを検討してください。

5. E2E-02のチェックが冗長

packages/extension/e2e/extension.spec.ts(L28-30)で expect(page.locator('[data-state="open"]')).toBeVisible({ timeout: 1000 }) を呼び出していますが、直前の testPage.selectText()waitForFunction 内で [data-state="open"] が現れるまでポーリングして待機しています(TestPage.ts L42-93)。selectText() が成功した時点でポップアップは既に表示されているため、この二重チェックは実質的に冗長です。

6. [data-state="open"] セレクターの脆弱性

packages/extension/e2e/extension.spec.ts(L28)と packages/extension/e2e/pages/TestPage.ts(L89)で使用している [data-state="open"] セレクターは、Radix UIの内部実装に依存する汎用的なセレクターです。テストページに他のRadixコンポーネントが存在する場合、意図しない要素にマッチする可能性があります。より具体的なセレクター(例: #selection-command [data-state="open"] など)の使用を検討してください。


軽微な指摘

7. window.getSelection()! の非nullアサーション

packages/extension/e2e/pages/TestPage.ts(L66)で window.getSelection()! を使用しています。ブラウザ環境では getSelection() がnullを返す可能性は低いですが、技術的には可能です。非nullアサーションよりも適切なnullチェック(if (!selection) return false)の使用を検討してください。

8. spaceIndex の計算で trimStart() 後のインデックスを使用している

packages/extension/e2e/pages/TestPage.ts(L59-60)で text.trimStart().indexOf(" ") の結果を range.setEnd(textNode, wordEnd) に渡しています。見出し要素のテキストノードが先頭にスペースを含む場合、インデックスが元のテキストノードとずれる可能性があります。text.indexOf(" ") を使うか、先頭のスペース数を考慮した計算が必要です。


良い点

  • Page Object Model (POM)の採用により、テストコードの保守性が高まっています(packages/extension/e2e/pages/TestPage.ts)。
  • race conditionへの対応が丁寧に実装・コメントされており、waitForFunction のポーリングアプローチは適切です(TestPage.ts L21-40)。
  • ESLintの設定で react-hooks/rules-of-hooks をe2eディレクトリのみで無効化している点は正しいアプローチです(packages/extension/eslint.config.mjs L20-26)。
  • vitestの除外設定でe2eディレクトリをVitestから除外している点も適切です(packages/extension/vitest.config.ts L11)。
  • テストケースの命名が E2E-XX プレフィックスで統一されており、CLAUDE.mdのガイドラインに沿っています。

最も優先度が高い修正はCI環境でのネットワーク接続問題(#3)とTypeScript設定の漏れ(#1)です。E2Eテストは拡張機能の品質向上に大きく貢献する基盤となるため、ぜひ継続して拡充していただければと思います!

@codecov
Copy link

codecov bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 0% with 85 lines in your changes missing coverage. Please review.
✅ Project coverage is 19.04%. Comparing base (64a1084) to head (2ab8ff4).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
packages/extension/e2e/pages/TestPage.ts 0.00% 48 Missing ⚠️
packages/extension/e2e/fixtures.ts 0.00% 23 Missing ⚠️
packages/extension/eslint.config.mjs 0.00% 7 Missing ⚠️
packages/extension/playwright.config.ts 0.00% 6 Missing ⚠️
packages/extension/vitest.config.ts 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #288      +/-   ##
==========================================
- Coverage   19.10%   19.04%   -0.06%     
==========================================
  Files         308      311       +3     
  Lines       28730    28815      +85     
  Branches     1317     1320       +3     
==========================================
  Hits         5488     5488              
- Misses      23242    23327      +85     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ujiro99 ujiro99 changed the title Add Playwright E2E tests for Chrome extension content script injection [WIP] Add Playwright E2E tests for Chrome extension content script injection Feb 25, 2026
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.

拡張機能をplaywrightでe2eテスト可能にする

2 participants