Skip to content

Commit fdb86fa

Browse files
authored
@W-19444022@ E2E tests base level (#121)
* feat: e2e testing * feat: expanding to outline verification case * fix: more tests for specifically outline view * fix: removing some cruft * chore: lint fix and cleanup * fix: some structure * fix: minor * fix: pr feedback * fix: ci fix * fix: improve e2e test CI environment compatibility * fix: CI fix * fix: resolve webServer working directory issue in e2e tests - Fix Playwright webServer configuration to use correct working directory - Add dynamic cwd detection to run npm scripts from root when executed from e2e-tests directory - Update GitHub Actions workflow to properly handle directory context - Ensure test:e2e:server script can be found and executed correctly This resolves the remaining e2e test failures by ensuring the webServer can properly locate and execute the test server startup script. * fix: use headless browser in CI environment for test server - Set headless: true in CI environments to avoid X11 display issues - Add CI-specific Chrome launch arguments for better stability - Keep headed mode for local development debugging - Resolves browser launch failures in GitHub Actions runners This fixes the 'Missing X server or $DISPLAY' error that was preventing the test server from starting in CI environments. * fix: minor config change to fix up for demo * feat: testing CI changes * fix: tweak timers * fix: minor CI tweaking still * fix: pr feedback 2 * fix: regex fix
1 parent 72533a4 commit fdb86fa

File tree

21 files changed

+1888
-52
lines changed

21 files changed

+1888
-52
lines changed

.cursor/rules/ts-rules.mdc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ The application we are working on uses the following tech stack:
110110
- Include elaborate details in the body of the commit message
111111
- Always follow the conventional commit message format
112112
- Add two newlines after the commit message title
113+
- Do not ever commit and push without asking for consent from the user
113114

114115
## When to create a class
115116

.github/workflows/e2e-tests.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: E2E Tests
2+
3+
on:
4+
push:
5+
branches: [main, kyledev/e2eTests]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
jobs:
11+
e2e-tests:
12+
name: End-to-End Tests
13+
runs-on: ubuntu-latest
14+
timeout-minutes: 15
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: '20'
24+
cache: 'npm'
25+
26+
- name: Install dependencies
27+
run: npm ci
28+
29+
- name: Build all packages and extension
30+
run: |
31+
npm run compile
32+
npm run bundle
33+
npm run build -w packages/apex-lsp-vscode-extension
34+
35+
- name: Verify extension build
36+
run: |
37+
if [ ! -f "packages/apex-lsp-vscode-extension/dist/package.json" ]; then
38+
echo "❌ package.json not found in dist"
39+
exit 1
40+
fi
41+
if [ ! -f "packages/apex-lsp-vscode-extension/dist/extension.js" ]; then
42+
echo "❌ extension.js not found in dist"
43+
exit 1
44+
fi
45+
if [ ! -f "packages/apex-lsp-vscode-extension/dist/extension.web.js" ]; then
46+
echo "❌ extension.web.js not found in dist"
47+
exit 1
48+
fi
49+
50+
- name: Install Playwright browsers
51+
run: npx playwright install --with-deps chromium
52+
53+
- name: Run E2E tests
54+
run: npm run test -w e2e-tests
55+
env:
56+
CI: true
57+
58+
- name: Upload test results and artifacts
59+
if: always()
60+
uses: actions/upload-artifact@v4
61+
with:
62+
name: playwright-results-${{ github.run_number }}
63+
path: |
64+
e2e-tests/playwright-report/
65+
e2e-tests/test-results/
66+
retention-days: 30
67+
if-no-files-found: warn

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,10 @@ grammars/
7575

7676
# Language server bundle copied into the VS Code extension package
7777
packages/apex-lsp-vscode-extension/server-bundle/
78+
79+
# E2E Testing artifacts
80+
e2e-tests/test-results/
81+
e2e-tests/playwright-report/
82+
e2e-tests/.playwright/
83+
test-results/
84+
playwright-report/

build-config/tsup.shared.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const COMMON_EXTERNAL = [
1515
'vscode',
1616
'vscode-languageserver',
1717
'vscode-languageserver/node',
18-
'vscode-languageserver/browser',
18+
'vscode-languageserver/browser',
1919
'vscode-languageserver-protocol',
2020
'vscode-jsonrpc',
2121
'vscode-jsonrpc/node',
@@ -45,17 +45,14 @@ export const nodeBaseConfig: Partial<Options> = {
4545
minify: false,
4646
dts: false,
4747
splitting: false,
48-
external: [
49-
...COMMON_EXTERNAL,
50-
'crypto', 'fs', 'path', 'url', 'os', 'stream',
51-
],
48+
external: [...COMMON_EXTERNAL, 'crypto', 'fs', 'path', 'url', 'os', 'stream'],
5249
};
5350

5451
/**
5552
* Base configuration for browser/web builds
5653
*/
5754
export const browserBaseConfig: Partial<Options> = {
58-
platform: 'browser',
55+
platform: 'browser',
5956
target: 'es2022',
6057
format: ['cjs'],
6158
sourcemap: true,
@@ -70,11 +67,11 @@ export const browserBaseConfig: Partial<Options> = {
7067
* Browser polyfill aliases - simplified from complex esbuild setup
7168
*/
7269
export const BROWSER_ALIASES = {
73-
'path': 'path-browserify',
74-
'crypto': 'crypto-browserify',
75-
'stream': 'stream-browserify',
76-
'fs': 'memfs',
77-
'url': 'url-browserify',
78-
'os': 'os-browserify/browser',
70+
path: 'path-browserify',
71+
crypto: 'crypto-browserify',
72+
stream: 'stream-browserify',
73+
fs: 'memfs',
74+
url: 'url-browserify',
75+
os: 'os-browserify/browser',
7976
'vscode-languageclient/node': 'vscode-languageclient/browser',
80-
};
77+
};

e2e-tests/README.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# E2E Tests for Apex Language Server Extension
2+
3+
This package provides comprehensive end-to-end testing for the Apex Language Server Extension in VS Code Web environments. The test suite validates that the extension correctly integrates with VS Code's language server protocol and provides essential Apex language features.
4+
5+
## Purpose
6+
7+
The e2e test suite ensures the Apex Language Server Extension works correctly in real-world browser environments by testing:
8+
9+
- **Extension Activation**: Verifies the extension properly activates when Apex files are opened
10+
- **Language Server Integration**: Confirms the LSP worker starts and initializes without errors
11+
- **Symbol Parsing**: Validates that Apex code is correctly parsed and symbols are identified
12+
- **Outline View**: Tests that the VS Code outline view displays Apex class structure
13+
- **Workspace Integration**: Ensures Apex files are recognized and handled in the workspace
14+
- **Stability**: Confirms the extension doesn't cause VS Code crashes or performance issues
15+
16+
## Test Philosophy
17+
18+
These tests focus on critical user-facing functionality rather than internal implementation details. They simulate real user interactions with the extension in a browser environment, providing confidence that the extension will work correctly when published.
19+
20+
The test suite prioritizes:
21+
22+
- **Reliability**: Tests are designed to be stable across different environments
23+
- **Performance**: Fast execution with parallel test runs where possible
24+
- **Maintainability**: Clean abstractions and reusable utilities
25+
- **Comprehensive Coverage**: Core functionality is thoroughly validated
26+
27+
## Prerequisites
28+
29+
- Node.js >= 20.0.0
30+
- Extension must be built before running tests
31+
- VS Code Web test server capability
32+
33+
## Running Tests
34+
35+
```bash
36+
# Run all tests (recommended)
37+
npm run test:e2e
38+
39+
# Debug mode with browser UI
40+
npm run test:e2e:debug
41+
42+
# Visual mode for test development
43+
npm run test:e2e:visual
44+
```
45+
46+
## Test Environment
47+
48+
The tests run against a real VS Code Web instance with the extension pre-loaded. This provides high confidence that the extension will work correctly in production browser environments.
49+
50+
**Supported Browsers**: Chromium (primary testing target)
51+
52+
**Environment Support**:
53+
54+
- Local development with detailed debugging
55+
- CI/CD with stability optimizations
56+
- Debug modes for test development
57+
58+
## Architecture
59+
60+
The test suite uses Playwright for browser automation and is structured with:
61+
62+
- **Utilities**: Reusable functions for common test operations
63+
- **Test Helpers**: Specialized functions for extension-specific testing
64+
- **Configuration**: Centralized settings and selectors
65+
- **Type Safety**: Full TypeScript support throughout
66+
67+
## Debugging and Development
68+
69+
The test suite includes comprehensive debugging capabilities:
70+
71+
- Console error monitoring with intelligent filtering
72+
- Network failure tracking
73+
- Screenshot and video capture on failures
74+
- Detailed logging for test analysis
75+
76+
For manual debugging, tests can be run against a standalone VS Code Web server with full developer tools access.
77+
78+
## CI/CD Integration
79+
80+
Tests are configured for continuous integration with:
81+
82+
- Retry logic for flaky test handling
83+
- Environment-specific timeouts and worker configuration
84+
- Comprehensive reporting and artifact collection
85+
- Headless execution with debugging artifact generation
86+
87+
## Contributing
88+
89+
When adding new tests:
90+
91+
1. Use existing test utilities and patterns
92+
2. Focus on user-facing functionality
93+
3. Ensure tests are reliable across environments
94+
4. Include proper error handling and logging
95+
5. Follow TypeScript best practices
96+
97+
The test suite is designed to grow with the extension while maintaining reliability and performance.

e2e-tests/package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "e2e-tests",
3+
"version": "1.0.0",
4+
"private": true,
5+
"description": "End-to-end tests for Apex Language Server Extension",
6+
"scripts": {
7+
"test": "playwright test",
8+
"test:debug": "playwright test --debug --headed",
9+
"test:visual": "DEBUG_MODE=1 playwright test --headed",
10+
"server": "node test-server.js"
11+
},
12+
"devDependencies": {
13+
"@playwright/test": "^1.55.0",
14+
"@types/node": "^20.11.30",
15+
"typescript": "^5.8.2"
16+
}
17+
}

e2e-tests/playwright.config.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2025, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the
6+
* repo root or https://opensource.org/licenses/BSD-3-Clause
7+
*/
8+
import { defineConfig, devices } from '@playwright/test';
9+
10+
/**
11+
* Playwright configuration for Apex Language Server Extension e2e tests.
12+
*
13+
* Configures test execution for VS Code Web environment with proper
14+
* browser settings, timeouts, and CI/CD integration.
15+
*/
16+
export default defineConfig({
17+
testDir: './tests',
18+
19+
fullyParallel: !process.env.DEBUG_MODE,
20+
forbidOnly: !!process.env.CI,
21+
retries: process.env.CI ? 2 : 0,
22+
workers: process.env.CI || process.env.DEBUG_MODE ? 1 : undefined,
23+
reporter: process.env.CI
24+
? [['html'], ['line'], ['junit', { outputFile: 'test-results/junit.xml' }]]
25+
: 'html',
26+
27+
use: {
28+
baseURL: 'http://localhost:3000',
29+
trace: process.env.CI ? 'retain-on-failure' : 'on-first-retry',
30+
screenshot: process.env.CI ? 'on' : 'only-on-failure',
31+
video: process.env.CI ? 'on' : 'retain-on-failure',
32+
actionTimeout: 15000,
33+
},
34+
35+
projects: [
36+
{
37+
name: 'chromium',
38+
use: {
39+
...devices['Desktop Chrome'],
40+
launchOptions: {
41+
args: [
42+
'--disable-web-security',
43+
'--disable-features=VizDisplayCompositor',
44+
'--enable-logging=stderr',
45+
'--log-level=0',
46+
'--v=1',
47+
...(process.env.CI || process.env.DEBUG_MODE
48+
? [
49+
'--no-sandbox',
50+
'--disable-dev-shm-usage',
51+
'--disable-background-timer-throttling',
52+
'--disable-backgrounding-occluded-windows',
53+
'--disable-renderer-backgrounding',
54+
]
55+
: []),
56+
],
57+
headless: process.env.CI || !process.env.DEBUG_MODE ? true : false,
58+
slowMo: process.env.DEBUG_MODE ? 300 : 0,
59+
},
60+
},
61+
},
62+
],
63+
64+
webServer: {
65+
command: 'npm run test:e2e:server',
66+
port: 3000,
67+
reuseExistingServer: !process.env.CI,
68+
timeout: 120_000,
69+
cwd: process.cwd().endsWith('e2e-tests') ? '..' : '.',
70+
},
71+
72+
timeout: process.env.CI ? 120_000 : 60_000,
73+
});

0 commit comments

Comments
 (0)