Skip to content

Commit ee2eb8b

Browse files
committed
ci: move all e2e vscode tests to run in ci
1 parent e07c5fe commit ee2eb8b

20 files changed

+955
-789
lines changed

.github/workflows/pr.yaml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ jobs:
4646
python -m venv .venv
4747
source .venv/bin/activate
4848
make install-dev
49-
- name: Fetch VS Code
50-
working-directory: ./vscode/extension
51-
run: pnpm run fetch-vscode
52-
5349
- name: Install code-server
5450
run: curl -fsSL https://code-server.dev/install.sh | sh
5551
- name: Install Playwright browsers
@@ -59,4 +55,10 @@ jobs:
5955
working-directory: ./vscode/extension
6056
run: |
6157
source ../../.venv/bin/activate
62-
pnpm run test:e2e tests/stop.spec.ts
58+
pnpm run test:e2e
59+
- uses: actions/upload-artifact@v4
60+
if: ${{ !cancelled() }}
61+
with:
62+
name: playwright-report
63+
path: vscode/extension/playwright-report/
64+
retention-days: 30

vscode/extension/E2E_TESTING.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,9 @@ This directory contains end-to-end tests for the SQLMesh VS Code extension using
99
pnpm install
1010
```
1111

12-
2. **Download VS Code executable (one-time setup):**
12+
2. **Install Playwright browsers:**
1313
```bash
14-
pnpm run fetch-vscode
15-
```
16-
17-
This downloads VS Code and caches it in `.vscode-test/` directory. The paths are saved to `.vscode-test/paths.json` for Playwright to use.
18-
19-
3. **Install Playwright browsers:**
20-
```bash
21-
npx playwright install
14+
pnpm run playwright:install
2215
```
2316

2417
## Running Tests

vscode/extension/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@
124124
"test:e2e": "pnpm run vscode:package && playwright test",
125125
"test:e2e:ui": "pnpm run vscode:package && playwright test --ui",
126126
"test:e2e:headed": "pnpm run vscode:package && playwright test --headed",
127-
"fetch-vscode": "tsx scripts/fetch-vscode.ts",
128127
"compile": "pnpm run check-types && node esbuild.js",
129128
"check-types": "tsc --noEmit -p ./tsconfig.build.json",
130129
"watch": "node esbuild.js --watch",

vscode/extension/playwright.config.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ export default defineConfig({
55
timeout: 60_000,
66
retries: process.env.CI ? 1 : 0,
77
workers: 1,
8+
reporter: [['html', { outputFolder: 'playwright-report' }], ['list']],
89
projects: [
910
{
1011
name: 'electron-vscode',
1112
use: {
12-
// ⭢ we'll launch Electron ourselves – no browser needed
1313
browserName: 'chromium',
14-
headless: true, // headless mode for tests
14+
headless: true,
1515
launchOptions: {
1616
slowMo: process.env.CI ? 0 : 100,
1717
},
18+
viewport: { width: 1512, height: 944 },
19+
video: 'retain-on-failure',
1820
},
1921
},
2022
],

vscode/extension/tests/bad_setup.spec.ts

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ import os from 'os'
44
import path from 'path'
55
import {
66
createVirtualEnvironment,
7+
openFile,
78
openLineageView,
89
pipInstall,
910
REPO_ROOT,
10-
startVSCode,
1111
SUSHI_SOURCE_PATH,
1212
} from './utils'
13+
import { startCodeServer, stopCodeServer } from './utils_code_server'
1314

14-
test('missing LSP dependencies shows install prompt', async ({}, testInfo) => {
15+
test('missing LSP dependencies shows install prompt', async ({
16+
page,
17+
}, testInfo) => {
1518
testInfo.setTimeout(120_000) // 2 minutes for venv creation and package installation
1619
const tempDir = await fs.mkdtemp(
1720
path.join(os.tmpdir(), 'vscode-test-tcloud-'),
@@ -26,6 +29,11 @@ test('missing LSP dependencies shows install prompt', async ({}, testInfo) => {
2629
const sqlmeshWithExtras = `${REPO_ROOT}[bigquery]`
2730
await pipInstall(pythonDetails, [sqlmeshWithExtras, custom_materializations])
2831

32+
// Start VS Code
33+
const context = await startCodeServer({
34+
tempDir,
35+
})
36+
2937
try {
3038
// Copy sushi project
3139
await fs.copy(SUSHI_SOURCE_PATH, tempDir)
@@ -42,45 +50,43 @@ test('missing LSP dependencies shows install prompt', async ({}, testInfo) => {
4250
{ spaces: 2 },
4351
)
4452

45-
// Start VS Code
46-
const { window, close } = await startVSCode(tempDir)
53+
await page.goto(`http://127.0.0.1:${context.codeServerPort}`)
4754

4855
// Open a SQL file to trigger SQLMesh activation
4956
// Wait for the models folder to be visible
50-
await window.waitForSelector('text=models')
57+
await page.waitForSelector('text=models')
5158

5259
// Click on the models folder
53-
await window
60+
await page
5461
.getByRole('treeitem', { name: 'models', exact: true })
5562
.locator('a')
5663
.click()
5764

5865
// Open the top_waiters model
59-
await window
66+
await page
6067
.getByRole('treeitem', { name: 'customers.sql', exact: true })
6168
.locator('a')
6269
.click()
6370

6471
// Wait for the message to show that LSP extras need to be installed
65-
await window.waitForSelector('text=LSP dependencies missing')
66-
expect(await window.locator('text=Install').count()).toBeGreaterThanOrEqual(
67-
1,
68-
)
69-
70-
await close()
72+
await page.waitForSelector('text=LSP dependencies missing')
73+
expect(await page.locator('text=Install').count()).toBeGreaterThanOrEqual(1)
7174
} finally {
72-
// Clean up
73-
await fs.remove(tempDir)
75+
await stopCodeServer(context)
7476
}
7577
})
7678

77-
test('lineage, no sqlmesh found', async ({}) => {
79+
test('lineage, no sqlmesh found', async ({ page }) => {
7880
const tempDir = await fs.mkdtemp(
7981
path.join(os.tmpdir(), 'vscode-test-tcloud-'),
8082
)
8183
const pythonEnvDir = path.join(tempDir, '.venv')
8284
const pythonDetails = await createVirtualEnvironment(pythonEnvDir)
8385

86+
const context = await startCodeServer({
87+
tempDir,
88+
})
89+
8490
try {
8591
// Copy sushi project
8692
await fs.copy(SUSHI_SOURCE_PATH, tempDir)
@@ -97,25 +103,30 @@ test('lineage, no sqlmesh found', async ({}) => {
97103
{ spaces: 2 },
98104
)
99105

100-
const { window, close } = await startVSCode(tempDir)
106+
// navigate to code-server instance
107+
await page.goto(`http://127.0.0.1:${context.codeServerPort}`)
108+
109+
await page.waitForSelector('text=models')
110+
await page.waitForTimeout(5000)
101111

102112
// Open lineage view
103-
await openLineageView(window)
113+
await openLineageView(page)
104114

105115
// Assert shows that sqlmesh is not installed
106-
await window.waitForSelector('text=SQLMesh LSP not found')
107-
108-
await close()
116+
await page.waitForSelector('text=SQLMesh LSP not found')
109117
} finally {
110118
// Clean up
111-
await fs.remove(tempDir)
119+
await stopCodeServer(context)
112120
}
113121
})
114122

115123
// Checks that if you have another file open like somewhere else, it still checks the workspace first for a successful context
116124
// it's very flaky but runs when debugging
117125
// - the typing in of the file name is very flaky
118-
test('check that the LSP runs correctly by opening lineage when looking at another file before not in workspace', async ({}) => {
126+
test('check that the LSP runs correctly by opening lineage when looking at another file before not in workspace', async ({
127+
page,
128+
}, testInfo) => {
129+
testInfo.setTimeout(120_000) // 2 minutes for venv creation and package installation
119130
const tempDir = await fs.mkdtemp(
120131
path.join(os.tmpdir(), 'vscode-test-tcloud-'),
121132
)
@@ -133,7 +144,7 @@ test('check that the LSP runs correctly by opening lineage when looking at anoth
133144
// Configure VS Code settings to use our Python environment
134145
const settings = {
135146
'python.defaultInterpreterPath': pythonDetails.pythonPath,
136-
'sqlmesh.environmentPath': pythonEnvDir,
147+
'sqlmesh.environmentPath': tempDir,
137148
}
138149
await fs.ensureDir(path.join(tempDir, '.vscode'))
139150
await fs.writeJson(path.join(tempDir, '.vscode', 'settings.json'), settings, {
@@ -148,19 +159,20 @@ test('check that the LSP runs correctly by opening lineage when looking at anoth
148159
await fs.ensureDir(path.dirname(sqlFile))
149160
await fs.writeFile(sqlFile, 'SELECT 1')
150161

151-
const { window, close } = await startVSCode(tempDir)
162+
const context = await startCodeServer({
163+
tempDir,
164+
})
152165
try {
166+
await page.goto(`http://127.0.0.1:${context.codeServerPort}`)
167+
168+
await page.waitForSelector('text=models')
169+
await page.waitForTimeout(5_000)
170+
153171
// Open the SQL file from the other directory
154-
await window.keyboard.press('Meta+P')
155-
await window.waitForTimeout(100)
156-
await window.keyboard.type(sqlFile.toString(), { delay: 10 })
157-
await window.waitForTimeout(100)
158-
await window.keyboard.press('Enter')
159-
await window.waitForTimeout(100)
160-
161-
await window.waitForSelector('text=Loaded SQLMesh context')
172+
await openFile(page, sqlFile)
173+
174+
await page.waitForSelector('text=Loaded SQLMesh context')
162175
} finally {
163-
await close()
164-
await fs.remove(tempDir)
176+
await stopCodeServer(context)
165177
}
166178
})

0 commit comments

Comments
 (0)