diff --git a/examples/playwright/package.json b/examples/playwright/package.json index 226daa0ca4cb7..c8503677cab5a 100644 --- a/examples/playwright/package.json +++ b/examples/playwright/package.json @@ -30,7 +30,7 @@ "src" ], "dependencies": { - "@playwright/test": "^1.30.0", + "@playwright/test": "^1.32.1", "fs-extra": "^9.0.8" }, "devDependencies": { diff --git a/examples/playwright/src/tests/theia-electron-app.test.ts b/examples/playwright/src/tests/theia-electron-app.test.ts index 3f25c78573934..1ebab9e18b332 100644 --- a/examples/playwright/src/tests/theia-electron-app.test.ts +++ b/examples/playwright/src/tests/theia-electron-app.test.ts @@ -21,42 +21,55 @@ import { ElectronLaunchOptions, TheiaElectronAppLoader } from '../theia-app-load import { TheiaWorkspace } from '../theia-workspace'; import { TheiaApp } from '../theia-app'; +test.describe.configure({ mode: 'serial' }); test.describe('Theia Electron Application', () => { - let ws: TheiaWorkspace; let app: TheiaApp; + let ws: TheiaWorkspace; test.beforeAll(async () => { ws = new TheiaWorkspace(['src/tests/resources/sample-files1']); app = await TheiaElectronAppLoader.load(new ElectronLaunchOptions('../electron', '../../plugins'), ws); }); + test.afterAll(async () => { + await app.page.close(); + }); + test('should load and show main content panel', async () => { expect(await app.isMainContentPanelVisible()).toBe(true); }); test('open about dialog using menu', async () => { - // open about dialog using menu await (await app.menuBar.openMenu('Help')).clickMenuItem('About'); const aboutDialog = new TheiaAboutDialog(app); expect(await aboutDialog.isVisible()).toBe(true); - await aboutDialog.close(); + await aboutDialog.page.getByRole('button', { name: 'OK' }).click(); expect(await aboutDialog.isVisible()).toBe(false); }); - test('toggle explorer view using menu', async () => { - await (await app.menuBar.openMenu('View')).clickMenuItem('Explorer'); - const explorerView = new TheiaExplorerView(app); - expect(await explorerView.isDisplayed()).toBe(true); - await (await app.menuBar.openMenu('View')).clickMenuItem('Explorer'); - expect(await explorerView.isDisplayed()).toBe(false); + test('open file via file menu and cancel', async () => { + await (await app.menuBar.openMenu('File')).clickMenuItem('Open File...'); + const fileDialog = await app.page.waitForSelector('div[class="dialogBlock"]'); + expect(await fileDialog.isVisible()).toBe(true); + await app.page.getByRole('button', { name: 'Cancel' }).click(); + expect(await fileDialog.isVisible()).toBe(false); }); - test('open quick command palette', async () => { - const quickCommand = app.quickCommandPalette; - expect(await quickCommand.isOpen()).toBe(false); - await quickCommand.open(); - expect(await quickCommand.isOpen()).toBe(true); + test.skip('open sample.txt via file menu', async () => { + const menuEntry = 'Open Folder...'; + + await (await app.menuBar.openMenu('File')).clickMenuItem(menuEntry); + + const fileDialog = await app.page.waitForSelector('div[class="dialogBlock"]'); + expect(await fileDialog.isVisible()).toBe(true); + + const fileEntry = app.page.getByText('sample.txt'); + await fileEntry.click(); + await app.page.getByRole('button', { name: 'Open' }).click(); + + const span = await app.page.waitForSelector('span:has-text("content line 2")'); + expect(await span.isVisible()).toBe(true); }); test('open about dialog using command', async () => { @@ -65,9 +78,9 @@ test.describe('Theia Electron Application', () => { await quickCommand.type('About'); await quickCommand.trigger('About'); const aboutDialog = new TheiaAboutDialog(app); - expect(await quickCommand.isOpen()).toBe(false); expect(await aboutDialog.isVisible()).toBe(true); - await aboutDialog.close(); + await aboutDialog.page.getByRole('button', { name: 'OK' }).click(); + expect(await aboutDialog.isVisible()).toBe(false); }); test('select all using command', async () => { @@ -79,12 +92,23 @@ test.describe('Theia Electron Application', () => { test('toggle explorer view using command', async () => { const quickCommand = app.quickCommandPalette; + await quickCommand.open(); + await quickCommand.type('Toggle Explorer'); + await quickCommand.trigger('Toggle Explorer View'); const explorerView = new TheiaExplorerView(app); + expect(await explorerView.isDisplayed()).toBe(true); await quickCommand.open(); await quickCommand.type('Toggle Explorer'); await quickCommand.trigger('Toggle Explorer View'); - expect(await quickCommand.isOpen()).toBe(false); + expect(await explorerView.isDisplayed()).toBe(false); + }); + + test('toggle explorer view using menu', async () => { + await (await app.menuBar.openMenu('View')).clickMenuItem('Explorer'); + const explorerView = new TheiaExplorerView(app); expect(await explorerView.isDisplayed()).toBe(true); + await (await app.menuBar.openMenu('View')).clickMenuItem('Explorer'); + expect(await explorerView.isDisplayed()).toBe(false); }); }); diff --git a/examples/playwright/src/tests/theia-workspace.test.ts b/examples/playwright/src/tests/theia-workspace.test.ts index 9c93bad74f0b0..bdcf7c5de7a7c 100644 --- a/examples/playwright/src/tests/theia-workspace.test.ts +++ b/examples/playwright/src/tests/theia-workspace.test.ts @@ -48,4 +48,21 @@ test.describe('Theia Workspace', () => { expect(await explorer.existsFileNode('another-sample.txt')).toBe(true); }); + test('open sample.txt via file menu', async ({ page }) => { + const ws = new TheiaWorkspace(['src/tests/resources/sample-files1']); + const app = await TheiaBrowserAppLoader.load(page, ws); + const menuEntry = 'Open...'; + + await (await app.menuBar.openMenu('File')).clickMenuItem(menuEntry); + const fileDialog = await app.page.waitForSelector('div[class="dialogBlock"]'); + expect(await fileDialog.isVisible()).toBe(true); + + const fileEntry = app.page.getByText('sample.txt'); + await fileEntry.click(); + await app.page.getByRole('button', { name: 'Open' }).click(); + + const span = await app.page.waitForSelector('span:has-text("content line 2")'); + expect(await span.isVisible()).toBe(true); + }); + }); diff --git a/examples/playwright/src/theia-app-loader.ts b/examples/playwright/src/theia-app-loader.ts index 3339bfa8208be..7b515de8170ee 100644 --- a/examples/playwright/src/theia-app-loader.ts +++ b/examples/playwright/src/theia-app-loader.ts @@ -107,7 +107,7 @@ export class ElectronLaunchOptions { constructor( protected readonly electronAppPath: string, protected readonly pluginsPath?: string, - protected readonly additionalArgs: string[] = ['--no-cluster', '--no-native-window-frame'] + protected readonly additionalArgs: string[] = ['--no-cluster', '--no-native-window-frame', '--bypassCSP=true'] ) { } playwrightOptions(workspace?: TheiaWorkspace): object { @@ -131,7 +131,7 @@ export class ElectronLaunchOptions { if (workspace) { args.push(workspace.path); } - console.log(`Launching Electron from ${executablePath} with args: ${args.join(' ')}`); + console.log(`Launching Electron: ${executablePath} ${args.join(' ')}`); return { executablePath, args }; } } diff --git a/examples/playwright/src/theia-workspace.ts b/examples/playwright/src/theia-workspace.ts index 1395fea88d35b..8a9cee5a8f762 100644 --- a/examples/playwright/src/theia-workspace.ts +++ b/examples/playwright/src/theia-workspace.ts @@ -15,6 +15,7 @@ // ***************************************************************************** import * as fs from 'fs-extra'; +import * as path from 'path'; import { resolve } from 'path'; import { OSUtil, urlEncodePath } from './util'; @@ -29,7 +30,7 @@ export class TheiaWorkspace { * @param {string[]} pathOfFilesToInitialize Path to files or folders that shall be copied to the workspace */ constructor(protected pathOfFilesToInitialize?: string[]) { - this.workspacePath = fs.mkdtempSync(`${OSUtil.tmpDir}${OSUtil.fileSeparator}cloud-ws-`); + this.workspacePath = fs.mkdtempSync(path.join(OSUtil.tmpDir, 'cloud-ws-')); } /** Performs the file system operations preparing the workspace location synchronously. */ @@ -46,15 +47,7 @@ export class TheiaWorkspace { } get path(): string { - let workspacePath = this.workspacePath; - if (!OSUtil.osStartsWithFileSeparator(this.workspacePath)) { - workspacePath = `${OSUtil.fileSeparator}${workspacePath}`; - } - if (OSUtil.isWindows) { - // Drive letters in windows paths have to be lower case - workspacePath = workspacePath.replace(/.:/, matchedChar => matchedChar.toLowerCase()); - } - return workspacePath; + return path.normalize(this.workspacePath); } get urlEncodedPath(): string { diff --git a/yarn.lock b/yarn.lock index e5a5f992b4fdd..192d619b3f650 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1622,13 +1622,15 @@ "@phosphor/signaling" "^1.3.1" "@phosphor/virtualdom" "^1.2.0" -"@playwright/test@^1.30.0": - version "1.30.0" - resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.30.0.tgz#8c0c4930ff2c7be7b3ec3fd434b2a3b4465ed7cb" - integrity sha512-SVxkQw1xvn/Wk/EvBnqWIq6NLo1AppwbYOjNLmyU0R1RoQ3rLEBtmjTnElcnz8VEtn11fptj1ECxK0tgURhajw== +"@playwright/test@^1.32.1": + version "1.32.1" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.32.1.tgz#749c9791adb048c266277a39ba0f7e33fe593ffe" + integrity sha512-FTwjCuhlm1qHUGf4hWjfr64UMJD/z0hXYbk+O387Ioe6WdyZQ+0TBDAc6P+pHjx2xCv1VYNgrKbYrNixFWy4Dg== dependencies: "@types/node" "*" - playwright-core "1.30.0" + playwright-core "1.32.1" + optionalDependencies: + fsevents "2.3.2" "@sindresorhus/df@^1.0.1": version "1.0.1" @@ -5605,7 +5607,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: +fsevents@2.3.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -8986,10 +8988,10 @@ pkg-up@^3.1.0: dependencies: find-up "^3.0.0" -playwright-core@1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.30.0.tgz#de987cea2e86669e3b85732d230c277771873285" - integrity sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g== +playwright-core@1.32.1: + version "1.32.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.32.1.tgz#5a10c32403323b07d75ea428ebeed866a80b76a1" + integrity sha512-KZYUQC10mXD2Am1rGlidaalNGYk3LU1vZqqNk0gT4XPty1jOqgup8KDP8l2CUlqoNKhXM5IfGjWgW37xvGllBA== pn@^1.1.0: version "1.1.0"