@theia/playwright 1.24.0-next.40 → 1.24.0-next.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/playwright",
|
|
3
|
-
"version": "1.24.0-next.
|
|
3
|
+
"version": "1.24.0-next.43+2ba15749ca9",
|
|
4
4
|
"description": "System tests for Theia",
|
|
5
5
|
"license": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "2ba15749ca9c334f486eacd3e441663a3fa02927"
|
|
43
43
|
}
|
|
@@ -21,7 +21,7 @@ import { TheiaMenuItem } from './theia-menu-item';
|
|
|
21
21
|
import { TheiaRenameDialog } from './theia-rename-dialog';
|
|
22
22
|
import { TheiaTreeNode } from './theia-tree-node';
|
|
23
23
|
import { TheiaView } from './theia-view';
|
|
24
|
-
import { elementContainsClass, normalizeId } from './util';
|
|
24
|
+
import { elementContainsClass, normalizeId, OSUtil, urlEncodePath } from './util';
|
|
25
25
|
|
|
26
26
|
const TheiaExplorerViewData = {
|
|
27
27
|
tabSelector: '#shell-tab-explorer-view-container',
|
|
@@ -75,16 +75,17 @@ export class TheiaExplorerView extends TheiaView {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
async refresh(): Promise<void> {
|
|
78
|
-
await this.clickButton('
|
|
78
|
+
await this.clickButton('navigator.refresh');
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
async collapseAll(): Promise<void> {
|
|
82
|
-
await this.clickButton('
|
|
82
|
+
await this.clickButton('navigator.collapse.all');
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
protected async clickButton(id: string): Promise<void> {
|
|
86
86
|
await this.activate();
|
|
87
87
|
const viewElement = await this.viewElement();
|
|
88
|
+
await viewElement?.hover();
|
|
88
89
|
const button = await viewElement?.waitForSelector(`#${normalizeId(id)}`);
|
|
89
90
|
await button?.click();
|
|
90
91
|
}
|
|
@@ -161,7 +162,11 @@ export class TheiaExplorerView extends TheiaView {
|
|
|
161
162
|
|
|
162
163
|
protected treeNodeId(filePath: string): string {
|
|
163
164
|
const workspacePath = this.app.workspace.path;
|
|
164
|
-
|
|
165
|
+
const nodeId = `${workspacePath}:${workspacePath}${OSUtil.fileSeparator}${filePath}`;
|
|
166
|
+
if (OSUtil.isWindows) {
|
|
167
|
+
return urlEncodePath(nodeId);
|
|
168
|
+
}
|
|
169
|
+
return nodeId;
|
|
165
170
|
}
|
|
166
171
|
|
|
167
172
|
async clickContextMenuItem(file: string, path: string[]): Promise<void> {
|
|
@@ -199,8 +204,7 @@ export class TheiaExplorerView extends TheiaView {
|
|
|
199
204
|
|
|
200
205
|
async getNumberOfVisibleNodes(): Promise<number> {
|
|
201
206
|
await this.activate();
|
|
202
|
-
await this.
|
|
203
|
-
await this.app.quickCommandPalette.trigger('File: Refresh in Explorer');
|
|
207
|
+
await this.refresh();
|
|
204
208
|
const fileStatElements = await this.visibleFileStatNodes(DOT_FILES_FILTER);
|
|
205
209
|
return fileStatElements.length;
|
|
206
210
|
}
|
|
@@ -224,6 +228,7 @@ export class TheiaExplorerView extends TheiaView {
|
|
|
224
228
|
await renameDialog.enterNewName(newName);
|
|
225
229
|
confirm ? await renameDialog.confirm() : await renameDialog.close();
|
|
226
230
|
await renameDialog.waitForClosed();
|
|
231
|
+
await this.refresh();
|
|
227
232
|
}
|
|
228
233
|
|
|
229
234
|
}
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
|
|
17
17
|
import { ElementHandle } from '@playwright/test';
|
|
18
18
|
import { TheiaPageObject } from './theia-page-object';
|
|
19
|
-
import { USER_KEY_TYPING_DELAY } from './util';
|
|
19
|
+
import { OSUtil, USER_KEY_TYPING_DELAY } from './util';
|
|
20
20
|
|
|
21
21
|
export class TheiaQuickCommandPalette extends TheiaPageObject {
|
|
22
22
|
|
|
23
23
|
selector = '.quick-input-widget';
|
|
24
24
|
|
|
25
25
|
async open(): Promise<void> {
|
|
26
|
-
await this.page.keyboard.press('Control+Shift+p');
|
|
26
|
+
await this.page.keyboard.press(OSUtil.isMacOS ? 'Meta+Shift+p' : 'Control+Shift+p');
|
|
27
27
|
await this.page.waitForSelector(this.selector);
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { TheiaDialog } from './theia-dialog';
|
|
18
|
-
import { USER_KEY_TYPING_DELAY } from './util';
|
|
18
|
+
import { OSUtil, USER_KEY_TYPING_DELAY } from './util';
|
|
19
19
|
|
|
20
20
|
export class TheiaRenameDialog extends TheiaDialog {
|
|
21
21
|
|
|
22
22
|
async enterNewName(newName: string): Promise<void> {
|
|
23
23
|
const inputField = await this.page.waitForSelector(`${this.blockSelector} .theia-input`);
|
|
24
|
-
await inputField.press('Control+a');
|
|
24
|
+
await inputField.press(OSUtil.isMacOS ? 'Meta+a' : 'Control+a');
|
|
25
25
|
await inputField.type(newName, { delay: USER_KEY_TYPING_DELAY });
|
|
26
26
|
await this.page.waitForTimeout(USER_KEY_TYPING_DELAY);
|
|
27
27
|
}
|
package/src/theia-text-editor.ts
CHANGED
|
@@ -15,17 +15,20 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { ElementHandle } from '@playwright/test';
|
|
18
|
+
import { join } from 'path';
|
|
18
19
|
|
|
19
20
|
import { TheiaApp } from './theia-app';
|
|
20
21
|
import { TheiaEditor } from './theia-editor';
|
|
21
|
-
import { normalizeId } from './util';
|
|
22
|
+
import { normalizeId, OSUtil, urlEncodePath } from './util';
|
|
22
23
|
|
|
23
24
|
export class TheiaTextEditor extends TheiaEditor {
|
|
24
25
|
|
|
25
26
|
constructor(filePath: string, app: TheiaApp) {
|
|
27
|
+
// shell-tab-code-editor-opener:file:///c%3A/Users/user/AppData/Local/Temp/cloud-ws-JBUhb6/sample.txt:1
|
|
28
|
+
// code-editor-opener:file:///c%3A/Users/user/AppData/Local/Temp/cloud-ws-JBUhb6/sample.txt:1
|
|
26
29
|
super({
|
|
27
|
-
tabSelector: normalizeId(`#shell-tab-code-editor-opener:file://${app.workspace.escapedPath
|
|
28
|
-
viewSelector: normalizeId(`#code-editor-opener:file://${app.workspace.escapedPath
|
|
30
|
+
tabSelector: normalizeId(`#shell-tab-code-editor-opener:file://${urlEncodePath(join(app.workspace.escapedPath, OSUtil.fileSeparator, filePath))}:1`),
|
|
31
|
+
viewSelector: normalizeId(`#code-editor-opener:file://${urlEncodePath(join(app.workspace.escapedPath, OSUtil.fileSeparator, filePath))}:1`) + '.theia-editor'
|
|
29
32
|
}, app);
|
|
30
33
|
}
|
|
31
34
|
|
package/src/theia-view.ts
CHANGED
|
@@ -50,6 +50,7 @@ export class TheiaView extends TheiaPageObject {
|
|
|
50
50
|
if (!this.data.viewName) {
|
|
51
51
|
throw new Error('View name must be specified to open via command palette');
|
|
52
52
|
}
|
|
53
|
+
await this.app.quickCommandPalette.type('View: Open View');
|
|
53
54
|
await this.app.quickCommandPalette.trigger('View: Open View...', this.data.viewName);
|
|
54
55
|
await this.waitForVisible();
|
|
55
56
|
return this;
|
package/src/theia-workspace.ts
CHANGED
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import * as fs from 'fs-extra';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import * as path from 'path';
|
|
18
|
+
import { resolve } from 'path';
|
|
19
|
+
import { OSUtil, urlEncodePath } from './util';
|
|
21
20
|
|
|
22
21
|
export class TheiaWorkspace {
|
|
23
22
|
|
|
@@ -30,14 +29,14 @@ export class TheiaWorkspace {
|
|
|
30
29
|
* @param {string[]} pathOfFilesToInitialize Path to files or folders that shall be copied to the workspace
|
|
31
30
|
*/
|
|
32
31
|
constructor(protected pathOfFilesToInitialize?: string[]) {
|
|
33
|
-
this.workspacePath = fs.mkdtempSync(`${
|
|
32
|
+
this.workspacePath = fs.mkdtempSync(`${OSUtil.tmpDir}${OSUtil.fileSeparator}cloud-ws-`);
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
/** Performs the file system operations preparing the workspace location synchronously. */
|
|
37
36
|
initialize(): void {
|
|
38
37
|
if (this.pathOfFilesToInitialize) {
|
|
39
38
|
for (const initPath of this.pathOfFilesToInitialize) {
|
|
40
|
-
const absoluteInitPath =
|
|
39
|
+
const absoluteInitPath = resolve(process.cwd(), initPath);
|
|
41
40
|
if (!fs.pathExistsSync(absoluteInitPath)) {
|
|
42
41
|
throw Error('Workspace does not exist at ' + absoluteInitPath);
|
|
43
42
|
}
|
|
@@ -47,15 +46,23 @@ export class TheiaWorkspace {
|
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
get path(): string {
|
|
50
|
-
|
|
49
|
+
let workspacePath = this.workspacePath;
|
|
50
|
+
if (!OSUtil.osStartsWithFileSeparator(this.workspacePath)) {
|
|
51
|
+
workspacePath = `${OSUtil.fileSeparator}${workspacePath}`;
|
|
52
|
+
}
|
|
53
|
+
if (OSUtil.isWindows) {
|
|
54
|
+
// Drive letters in windows paths have to be lower case
|
|
55
|
+
workspacePath = workspacePath.replace(/.:/, matchedChar => matchedChar.toLowerCase());
|
|
56
|
+
}
|
|
57
|
+
return workspacePath;
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
get urlEncodedPath(): string {
|
|
54
|
-
return this.path
|
|
61
|
+
return urlEncodePath(this.path);
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
get escapedPath(): string {
|
|
58
|
-
return this.path.replace(/:/g, '%3A')
|
|
65
|
+
return this.path.replace(/:/g, '%3A');
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
clear(): void {
|
package/src/util.ts
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { ElementHandle } from '@playwright/test';
|
|
18
|
+
import { tmpdir, platform } from 'os';
|
|
19
|
+
import { sep } from 'path';
|
|
18
20
|
|
|
19
21
|
export const USER_KEY_TYPING_DELAY = 80;
|
|
20
22
|
|
|
@@ -23,6 +25,10 @@ export function normalizeId(nodeId: string): string {
|
|
|
23
25
|
return nodeId.replace(/[.:,%/\\]/g, matchedChar => '\\' + matchedChar);
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
export function urlEncodePath(path: string): string {
|
|
29
|
+
return path.replace(/\\/g, '/');
|
|
30
|
+
}
|
|
31
|
+
|
|
26
32
|
export async function toTextContentArray(items: ElementHandle<SVGElement | HTMLElement>[]): Promise<string[]> {
|
|
27
33
|
const contents = items.map(item => item.textContent());
|
|
28
34
|
const resolvedContents = await Promise.all(contents);
|
|
@@ -70,3 +76,16 @@ export async function elementId(element: ElementHandle<SVGElement | HTMLElement>
|
|
|
70
76
|
if (id === null) { throw new Error('Could not get ID of ' + element); }
|
|
71
77
|
return id;
|
|
72
78
|
}
|
|
79
|
+
|
|
80
|
+
export namespace OSUtil {
|
|
81
|
+
export const isWindows = platform() === 'win32';
|
|
82
|
+
export const isMacOS = platform() === 'darwin';
|
|
83
|
+
// The platform-specific file separator '\' or '/'.
|
|
84
|
+
export const fileSeparator = sep;
|
|
85
|
+
// The platform-specific location of the temporary directory.
|
|
86
|
+
export const tmpDir = tmpdir();
|
|
87
|
+
|
|
88
|
+
export function osStartsWithFileSeparator(path: string): boolean {
|
|
89
|
+
return path.startsWith(fileSeparator);
|
|
90
|
+
}
|
|
91
|
+
}
|