1- import { test , _electron as electron , expect } from '@playwright/test' ;
1+ import { test , _electron as electron , expect , ElectronApplication , Page } from '@playwright/test' ;
22import path from 'path' ;
33import fs from 'fs-extra' ;
44import os from 'os' ;
@@ -10,51 +10,114 @@ const EXT_PATH = path.resolve(__dirname, '..');
1010// Where the sushi project lives which we copy from
1111const SUSHI_SOURCE_PATH = path . join ( __dirname , '..' , '..' , '..' , 'examples' , 'sushi' ) ;
1212
13- test ( 'Lineage panel renders correctly' , async ( ) => {
14- // Create a temporary directory and copy sushi example into it
15- const tempDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'vscode-test-sushi-' ) ) ;
16- await fs . copy ( SUSHI_SOURCE_PATH , tempDir ) ;
17-
13+ /**
14+ * Helper function to launch VS Code and test lineage with given project path config
15+ */
16+ async function testLineageWithProjectPath (
17+ workspaceDir : string ,
18+ projectDir : string ,
19+ projectPathConfig ?: string
20+ ) : Promise < void > {
21+ const ciArgs = process . env . CI ? [
22+ '--disable-gpu' ,
23+ '--headless' ,
24+ '--no-sandbox' ,
25+ '--disable-dev-shm-usage' ,
26+ '--window-position=-10000,0' ,
27+ ] : [ ] ;
28+
29+ const userDataDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'vscode-user-data-' ) ) ;
30+
1831 try {
19- const ciArgs = process . env . CI ? [
20- '--disable-gpu' ,
21- '--headless' ,
22- '--no-sandbox' ,
23- '--disable-dev-shm-usage' , // Prevents memory issues in Docker/CI
24- '--window-position=-10000,0' , // Ensures window is off-screen
25- ] : [ ] ;
32+ // If projectPathConfig is provided, create .vscode/settings.json in the workspace
33+ if ( projectPathConfig !== undefined ) {
34+ const vscodeDir = path . join ( workspaceDir , '.vscode' ) ;
35+ await fs . ensureDir ( vscodeDir ) ;
36+ const settings = {
37+ "sqlmesh.projectPath" : projectPathConfig
38+ } ;
39+ await fs . writeJson ( path . join ( vscodeDir , 'settings.json' ) , settings , { spaces : 2 } ) ;
40+ }
41+
2642 const args = [
2743 ...ciArgs ,
2844 `--extensionDevelopmentPath=${ EXT_PATH } ` ,
29- '--disable-workspace-trust' , // no modal prompt
45+ '--disable-workspace-trust' ,
3046 '--disable-telemetry' ,
31- ' --user-data-dir=/tmp/vscode-test' , // throwaway profile
32- ` ${ tempDir } ` , // Use the temporary directory instead of PROJECT_PATH
47+ ` --user-data-dir=${ userDataDir } ` ,
48+ workspaceDir ,
3349 ] ;
50+
3451 const electronApp = await electron . launch ( {
3552 executablePath : VS_CODE_EXE ,
3653 args,
3754 } ) ;
3855
39- // ➋ Grab the first window that appears (the Workbench)
4056 const window = await electronApp . firstWindow ( ) ;
41-
42- // Wait for VS Code to be ready
4357 await window . waitForLoadState ( 'domcontentloaded' ) ;
4458 await window . waitForLoadState ( 'networkidle' ) ;
59+
60+ // Wait a bit for the extension to fully initialize with the settings
61+ await window . waitForTimeout ( 2000 ) ;
4562
46- // ➌ Trigger our command exactly like a user would
63+ // Trigger lineage command
4764 await window . keyboard . press ( process . platform === 'darwin' ? 'Meta+Shift+P' : 'Control+Shift+P' ) ;
4865 await window . keyboard . type ( 'Lineage: Focus On View' ) ;
4966 await window . keyboard . press ( 'Enter' ) ;
5067
5168 // Wait for "Loaded SQLmesh Context" text to appear
5269 const loadedContextText = window . locator ( 'text=Loaded SQLMesh Context' ) ;
53- await expect ( loadedContextText . first ( ) ) . toBeVisible ( { timeout : 10000 } ) ;
70+ await expect ( loadedContextText . first ( ) ) . toBeVisible ( { timeout : 15000 } ) ;
5471
5572 await electronApp . close ( ) ;
5673 } finally {
57- // Clean up the temporary directory
74+ await fs . remove ( userDataDir ) ;
75+ }
76+ }
77+
78+ export const startVSCode = async ( workspaceDir : string ) => {
79+
80+ }
81+
82+ test ( 'Lineage panel renders correctly - no project path config (default)' , async ( ) => {
83+ const tempDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'vscode-test-sushi-' ) ) ;
84+ await fs . copy ( SUSHI_SOURCE_PATH , tempDir ) ;
85+
86+ try {
87+ await testLineageWithProjectPath ( tempDir , tempDir ) ;
88+ } finally {
5889 await fs . remove ( tempDir ) ;
5990 }
6091} ) ;
92+
93+ test ( 'Lineage panel renders correctly - relative project path' , async ( ) => {
94+ // Create workspace directory with subdirectory containing the project
95+ const workspaceDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'vscode-test-workspace-' ) ) ;
96+ const projectSubdir = path . join ( workspaceDir , 'projects' , 'sushi' ) ;
97+ await fs . ensureDir ( path . dirname ( projectSubdir ) ) ;
98+ await fs . copy ( SUSHI_SOURCE_PATH , projectSubdir ) ;
99+
100+ try {
101+ // Test with relative path
102+ await testLineageWithProjectPath ( workspaceDir , projectSubdir , 'projects/sushi' ) ;
103+ } finally {
104+ await fs . remove ( workspaceDir ) ;
105+ }
106+ } ) ;
107+
108+ test ( 'Lineage panel renders correctly - absolute project path' , async ( ) => {
109+ // Create workspace directory
110+ const workspaceDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'vscode-test-workspace-' ) ) ;
111+
112+ // Create project directory outside workspace
113+ const projectDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'vscode-test-sushi-project-' ) ) ;
114+ await fs . copy ( SUSHI_SOURCE_PATH , projectDir ) ;
115+
116+ try {
117+ // Test with absolute path
118+ await testLineageWithProjectPath ( workspaceDir , projectDir , projectDir ) ;
119+ } finally {
120+ await fs . remove ( workspaceDir ) ;
121+ await fs . remove ( projectDir ) ;
122+ }
123+ } ) ;
0 commit comments