feat(vscode): add Playwright-based e2e test infrastructure#3109
feat(vscode): add Playwright-based e2e test infrastructure#3109
Conversation
Adds a new `vscode-e2e` project with Playwright + Electron support for end-to-end testing the VS Code extension against a real VS Code instance with a real Nx workspace. Architecture (ported from GitLens): - Runner HTTP server injected into VS Code extension host via --extensionTestsPath, exposes POST /invoke for vscode API access - File-based evaluator discovers the runner's URL via temp marker files - Worker-scoped Playwright fixture creates an isolated Nx workspace, launches VS Code, connects the evaluator, and provides page objects - Page objects for activity bar, sidebar, quick pick, and Nx Console specific tree view interactions Smoke test covers: extension activation, command registration, activity bar visibility, project tree loading, and project target expansion. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
View your CI Pipeline Execution ↗ for commit 42d7c7e
☁️ Nx Cloud last updated this comment at |
| } | ||
|
|
||
| async execute(command: string): Promise<void> { | ||
| await this.page.keyboard.press('Meta+Shift+P'); |
There was a problem hiding this comment.
Platform-specific keyboard shortcut breaks on Windows/Linux
Meta+Shift+P only works on macOS. On Windows and Linux, the command palette shortcut is Control+Shift+P. This will fail on non-macOS platforms.
Fix: Use cross-platform modifier or detect platform:
const modifier = process.platform === 'darwin' ? 'Meta' : 'Control';
await this.page.keyboard.press(`${modifier}+Shift+P`);| await this.page.keyboard.press('Meta+Shift+P'); | |
| const modifier = process.platform === 'darwin' ? 'Meta' : 'Control'; | |
| await this.page.keyboard.press(`${modifier}+Shift+P`); |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
apps/vscode-e2e/specs/smoke.test.ts
Outdated
| await expect(projectsSection.locator('.monaco-list-row')).not.toHaveCount(2, { | ||
| timeout: 10_000, | ||
| }); |
There was a problem hiding this comment.
Test logic error: This assertion waits for the row count to NOT be 2, but this doesn't guarantee expansion has occurred. If the initial count is 1 (just the collapsed project), the assertion passes immediately since 1 ≠ 2, even though expansion hasn't happened yet. This can cause race conditions where line 40's assertion expect(rowCount).toBeGreaterThan(2) fails.
// Wait for expansion to complete by checking for minimum expected rows
await expect(projectsSection.locator('.monaco-list-row')).toHaveCount(
3,
{ timeout: 10_000 }
).catch(() => {}); // or use a more specific count if known
// Or wait for a specific target to appear
await expect(
projectsSection.locator('.monaco-list-row').nth(1)
).toBeVisible({ timeout: 10_000 });| await expect(projectsSection.locator('.monaco-list-row')).not.toHaveCount(2, { | |
| timeout: 10_000, | |
| }); | |
| await expect(projectsSection.locator('.monaco-list-row')).toHaveCount( | |
| 3, | |
| { timeout: 10_000 } | |
| ).catch(() => {}); |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
apps/vscode-e2e/runner/src/index.ts
Outdated
| } | ||
|
|
||
| let body = ''; | ||
| req.on('data', (chunk: string) => { |
There was a problem hiding this comment.
Type annotation is incorrect. The data event emits Buffer objects, not strings. This will cause incorrect concatenation behavior.
req.on('data', (chunk: Buffer) => {
body += chunk.toString();
});Or remove the type annotation and let TypeScript infer it.
| req.on('data', (chunk: string) => { | |
| req.on('data', (chunk: Buffer) => { |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
There was a problem hiding this comment.
Important
At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.
Nx Cloud is proposing a fix for your failed CI:
We replaced --experimental-strip-types with --loader ts-node/esm in the vscode-e2e:test command to fix the failure on Node.js v20, where that flag does not exist (it was introduced in v22.6.0). We also updated the spec's import specifier from ./vscode-e2e-runtime.ts to ./vscode-e2e-runtime.js, which is the standard TypeScript ESM convention that ts-node/esm uses to resolve the corresponding .ts source file at runtime.
Warning
❌ We could not verify this fix.
diff --git a/apps/vscode-e2e/fixtures/vscode-e2e-runtime.spec.ts b/apps/vscode-e2e/fixtures/vscode-e2e-runtime.spec.ts
index 96c31b86..a5f24668 100644
--- a/apps/vscode-e2e/fixtures/vscode-e2e-runtime.spec.ts
+++ b/apps/vscode-e2e/fixtures/vscode-e2e-runtime.spec.ts
@@ -5,7 +5,7 @@ import {
getMarkerFilePath,
getMarkerId,
getWorkerDisplay,
-} from './vscode-e2e-runtime.ts';
+} from './vscode-e2e-runtime.js';
test('marker ids and file paths are worker-specific', () => {
const firstWorkerId = getMarkerId(0);
diff --git a/apps/vscode-e2e/project.json b/apps/vscode-e2e/project.json
index f348d25b..5c72c26b 100644
--- a/apps/vscode-e2e/project.json
+++ b/apps/vscode-e2e/project.json
@@ -29,7 +29,7 @@
]
},
"test": {
- "command": "node --test --experimental-strip-types apps/vscode-e2e/fixtures/vscode-e2e-runtime.spec.ts"
+ "command": "node --loader ts-node/esm --test apps/vscode-e2e/fixtures/vscode-e2e-runtime.spec.ts"
},
"build-runner": {
"command": "esbuild apps/vscode-e2e/runner/src/index.ts --bundle --outfile=dist/apps/vscode-e2e/runner/index.js --platform=node --external:vscode --format=cjs",
Or Apply changes locally with:
npx nx-cloud apply-locally qZ4m-X5LE
Apply fix locally with your editor ↗ View interactive diff ↗
🎓 Learn more about Self-Healing CI on nx.dev
…ntain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
.github/workflows/vscode-e2e.yml
Outdated
|
|
||
| - name: Upload VS Code E2E videos | ||
| if: always() | ||
| uses: actions/upload-artifact@v4.6.2 |
There was a problem hiding this comment.
Should we pin the commit hash here as well?
Summary
apps/vscode-e2eproject with Playwright + Electron for e2e testing the VS Code extension against a real VS Code instance and real Nx workspaceKey design decisions
_electron.launch()drives VS Code directly (no Selenium/WebDriver)create-nx-workspace(reuseslibs/shared/e2e-utils)New dependencies
@playwright/test1.52.0playwright1.52.0Test plan
npx playwright test -c apps/vscode-e2e/playwright.config.tspasses locally.github/workflows/vscode-e2e.ymlwithworkflow_dispatchfor on-demand CI runs🤖 Generated with Claude Code