@theia/playwright 1.26.0-next.7 → 1.26.0
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/lib/tests/theia-preference-view.test.js +34 -13
- package/lib/tests/theia-preference-view.test.js.map +1 -1
- package/lib/tests/theia-text-editor.test.js +6 -1
- package/lib/tests/theia-text-editor.test.js.map +1 -1
- package/lib/theia-notification-indicator.d.ts +1 -2
- package/lib/theia-notification-indicator.d.ts.map +1 -1
- package/lib/theia-notification-indicator.js +11 -11
- package/lib/theia-notification-indicator.js.map +1 -1
- package/lib/theia-preference-view.d.ts +36 -10
- package/lib/theia-preference-view.d.ts.map +1 -1
- package/lib/theia-preference-view.js +72 -67
- package/lib/theia-preference-view.js.map +1 -1
- package/lib/theia-problem-indicator.d.ts +1 -1
- package/lib/theia-problem-indicator.d.ts.map +1 -1
- package/lib/theia-problem-indicator.js +4 -5
- package/lib/theia-problem-indicator.js.map +1 -1
- package/lib/theia-status-indicator.d.ts +7 -11
- package/lib/theia-status-indicator.d.ts.map +1 -1
- package/lib/theia-status-indicator.js +13 -41
- package/lib/theia-status-indicator.js.map +1 -1
- package/lib/theia-toggle-bottom-indicator.d.ts +1 -1
- package/lib/theia-toggle-bottom-indicator.d.ts.map +1 -1
- package/lib/theia-toggle-bottom-indicator.js +3 -3
- package/lib/theia-toggle-bottom-indicator.js.map +1 -1
- package/package.json +2 -2
- package/src/tests/theia-preference-view.test.ts +38 -13
- package/src/tests/theia-text-editor.test.ts +7 -1
- package/src/theia-notification-indicator.ts +9 -14
- package/src/theia-preference-view.ts +78 -72
- package/src/theia-problem-indicator.ts +2 -9
- package/src/theia-status-indicator.ts +15 -44
- package/src/theia-toggle-bottom-indicator.ts +1 -5
|
@@ -17,11 +17,10 @@
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.TheiaProblemIndicator = void 0;
|
|
19
19
|
const theia_status_indicator_1 = require("./theia-status-indicator");
|
|
20
|
-
const PROBLEM_ICON = 'codicon-error';
|
|
21
20
|
class TheiaProblemIndicator extends theia_status_indicator_1.TheiaStatusIndicator {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.id = 'problem-marker-status';
|
|
25
24
|
}
|
|
26
25
|
async numberOfProblems() {
|
|
27
26
|
const spans = await this.getSpans();
|
|
@@ -32,7 +31,7 @@ class TheiaProblemIndicator extends theia_status_indicator_1.TheiaStatusIndicato
|
|
|
32
31
|
return spans ? +await spans[3].innerText() : -1;
|
|
33
32
|
}
|
|
34
33
|
async getSpans() {
|
|
35
|
-
const handle = await
|
|
34
|
+
const handle = await this.getElementHandle();
|
|
36
35
|
return handle === null || handle === void 0 ? void 0 : handle.$$('span');
|
|
37
36
|
}
|
|
38
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theia-problem-indicator.js","sourceRoot":"","sources":["../src/theia-problem-indicator.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;;AAGhF,qEAAgE;AAEhE,
|
|
1
|
+
{"version":3,"file":"theia-problem-indicator.js","sourceRoot":"","sources":["../src/theia-problem-indicator.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;;AAGhF,qEAAgE;AAEhE,MAAa,qBAAsB,SAAQ,6CAAoB;IAA/D;;QACI,OAAE,GAAG,uBAAuB,CAAC;IAgBjC,CAAC;IAdG,KAAK,CAAC,gBAAgB;QAClB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IAES,KAAK,CAAC,QAAQ;QACpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC7C,OAAO,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;CACJ;AAjBD,sDAiBC"}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { ElementHandle } from '@playwright/test';
|
|
2
2
|
import { TheiaPageObject } from './theia-page-object';
|
|
3
|
-
export declare class TheiaStatusIndicator extends TheiaPageObject {
|
|
4
|
-
protected
|
|
5
|
-
protected
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
getElementHandleByIcon(iconClass: string | string[], titleContain?: string): Promise<ElementHandle<SVGElement | HTMLElement> | null>;
|
|
11
|
-
waitForVisibleByTitle(title: string, waitForDetached?: boolean): Promise<void>;
|
|
12
|
-
waitForVisibleByIcon(icon: string, waitForDetached?: boolean): Promise<void>;
|
|
13
|
-
isVisible(icon: string | string[], titleContain?: string): Promise<boolean>;
|
|
3
|
+
export declare abstract class TheiaStatusIndicator extends TheiaPageObject {
|
|
4
|
+
protected abstract id: string;
|
|
5
|
+
protected statusBarElementSelector: string;
|
|
6
|
+
protected getSelectorForId(id: string): string;
|
|
7
|
+
waitForVisible(waitForDetached?: boolean): Promise<void>;
|
|
8
|
+
getElementHandle(): Promise<ElementHandle<SVGElement | HTMLElement>>;
|
|
9
|
+
isVisible(): Promise<boolean>;
|
|
14
10
|
}
|
|
15
11
|
//# sourceMappingURL=theia-status-indicator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theia-status-indicator.d.ts","sourceRoot":"","sources":["../src/theia-status-indicator.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,
|
|
1
|
+
{"version":3,"file":"theia-status-indicator.d.ts","sourceRoot":"","sources":["../src/theia-status-indicator.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,8BAAsB,oBAAqB,SAAQ,eAAe;IAC9D,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAE9B,SAAS,CAAC,wBAAwB,SAAkC;IAEpE,SAAS,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAIxC,cAAc,CAAC,eAAe,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC;IAQpE,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAStC"}
|
|
@@ -20,53 +20,25 @@ const theia_page_object_1 = require("./theia-page-object");
|
|
|
20
20
|
class TheiaStatusIndicator extends theia_page_object_1.TheiaPageObject {
|
|
21
21
|
constructor() {
|
|
22
22
|
super(...arguments);
|
|
23
|
-
this.
|
|
23
|
+
this.statusBarElementSelector = '#theia-statusBar div.element';
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
return this.
|
|
27
|
-
}
|
|
28
|
-
async waitForVisible() {
|
|
29
|
-
await this.page.waitForSelector(this.elementSpanSelector);
|
|
30
|
-
}
|
|
31
|
-
getSelectorByTitle(title) {
|
|
32
|
-
return `.element[title="${title}"]`;
|
|
33
|
-
}
|
|
34
|
-
async getElementHandleByTitle(title) {
|
|
35
|
-
// Fetch element via title in case status elements exist without a dedicated Codicon icon
|
|
36
|
-
return this.page.$(this.getSelectorByTitle(title));
|
|
25
|
+
getSelectorForId(id) {
|
|
26
|
+
return `${this.statusBarElementSelector}#status-bar-${id}`;
|
|
37
27
|
}
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
async waitForVisible(waitForDetached = false) {
|
|
29
|
+
await this.page.waitForSelector(this.getSelectorForId(this.id), waitForDetached ? { state: 'detached' } : {});
|
|
40
30
|
}
|
|
41
|
-
async
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (span) {
|
|
46
|
-
const parent = await span.$('..');
|
|
47
|
-
if (titleContain === '') {
|
|
48
|
-
return parent;
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
const parentTitle = await (parent === null || parent === void 0 ? void 0 : parent.getAttribute('title'));
|
|
52
|
-
if (parentTitle === null || parentTitle === void 0 ? void 0 : parentTitle.includes(titleContain)) {
|
|
53
|
-
return parent;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
31
|
+
async getElementHandle() {
|
|
32
|
+
const element = await this.page.$(this.getSelectorForId(this.id));
|
|
33
|
+
if (element) {
|
|
34
|
+
return element;
|
|
57
35
|
}
|
|
58
|
-
throw new Error('
|
|
59
|
-
}
|
|
60
|
-
async waitForVisibleByTitle(title, waitForDetached = false) {
|
|
61
|
-
await this.page.waitForSelector(this.getSelectorByTitle(title), waitForDetached ? { state: 'detached' } : {});
|
|
62
|
-
}
|
|
63
|
-
async waitForVisibleByIcon(icon, waitForDetached = false) {
|
|
64
|
-
await this.page.waitForSelector(this.getSelectorByIcon(icon), waitForDetached ? { state: 'detached' } : {});
|
|
36
|
+
throw new Error('Could not find status bar element with ID ' + this.id);
|
|
65
37
|
}
|
|
66
|
-
async isVisible(
|
|
38
|
+
async isVisible() {
|
|
67
39
|
try {
|
|
68
|
-
const element = await this.
|
|
69
|
-
return
|
|
40
|
+
const element = await this.getElementHandle();
|
|
41
|
+
return element.isVisible();
|
|
70
42
|
}
|
|
71
43
|
catch (err) {
|
|
72
44
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theia-status-indicator.js","sourceRoot":"","sources":["../src/theia-status-indicator.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;;AAGhF,2DAAsD;AAEtD,
|
|
1
|
+
{"version":3,"file":"theia-status-indicator.js","sourceRoot":"","sources":["../src/theia-status-indicator.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;;AAGhF,2DAAsD;AAEtD,MAAsB,oBAAqB,SAAQ,mCAAe;IAAlE;;QAGc,6BAAwB,GAAG,8BAA8B,CAAC;IA2BxE,CAAC;IAzBa,gBAAgB,CAAC,EAAU;QACjC,OAAO,GAAG,IAAI,CAAC,wBAAwB,eAAe,EAAE,EAAE,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,KAAK;QACxC,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClH,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAClE,IAAI,OAAO,EAAE;YACT,OAAO,OAAO,CAAC;SAClB;QACD,MAAM,IAAI,KAAK,CAAC,4CAA4C,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,SAAS;QACX,IAAI;YACA,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC9C,OAAO,OAAO,CAAC,SAAS,EAAE,CAAC;SAC9B;QAAC,OAAO,GAAG,EAAE;YACV,OAAO,KAAK,CAAC;SAChB;IACL,CAAC;CAEJ;AA9BD,oDA8BC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theia-toggle-bottom-indicator.d.ts","sourceRoot":"","sources":["../src/theia-toggle-bottom-indicator.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"theia-toggle-bottom-indicator.d.ts","sourceRoot":"","sources":["../src/theia-toggle-bottom-indicator.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,qBAAa,0BAA2B,SAAQ,oBAAoB;IAChE,EAAE,SAAyB;CAC9B"}
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.TheiaToggleBottomIndicator = void 0;
|
|
19
19
|
const theia_status_indicator_1 = require("./theia-status-indicator");
|
|
20
|
-
const TOGGLE_BOTTOM_ICON = 'codicon-window';
|
|
21
20
|
class TheiaToggleBottomIndicator extends theia_status_indicator_1.TheiaStatusIndicator {
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.id = 'bottom-panel-toggle';
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
exports.TheiaToggleBottomIndicator = TheiaToggleBottomIndicator;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theia-toggle-bottom-indicator.js","sourceRoot":"","sources":["../src/theia-toggle-bottom-indicator.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;;AAEhF,qEAAgE;AAEhE,
|
|
1
|
+
{"version":3,"file":"theia-toggle-bottom-indicator.js","sourceRoot":"","sources":["../src/theia-toggle-bottom-indicator.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;;AAEhF,qEAAgE;AAEhE,MAAa,0BAA2B,SAAQ,6CAAoB;IAApE;;QACI,OAAE,GAAG,qBAAqB,CAAC;IAC/B,CAAC;CAAA;AAFD,gEAEC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/playwright",
|
|
3
|
-
"version": "1.26.0
|
|
3
|
+
"version": "1.26.0",
|
|
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": {
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"main": "lib/index",
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "38e2466568e69d55a9c64c96878deff5a005b814"
|
|
45
45
|
}
|
|
@@ -38,14 +38,14 @@ test.describe('Preference View', () => {
|
|
|
38
38
|
const preferences = await app.openPreferences(TheiaPreferenceView);
|
|
39
39
|
const preferenceId = PreferenceIds.DiffEditor.MaxComputationTime;
|
|
40
40
|
|
|
41
|
-
await preferences.
|
|
41
|
+
await preferences.resetPreferenceById(preferenceId);
|
|
42
42
|
expect(await preferences.getStringPreferenceById(preferenceId)).toBe(DefaultPreferences.DiffEditor.MaxComputationTime);
|
|
43
43
|
|
|
44
44
|
await preferences.setStringPreferenceById(preferenceId, '8000');
|
|
45
45
|
await preferences.waitForModified(preferenceId);
|
|
46
46
|
expect(await preferences.getStringPreferenceById(preferenceId)).toBe('8000');
|
|
47
47
|
|
|
48
|
-
await preferences.
|
|
48
|
+
await preferences.resetPreferenceById(preferenceId);
|
|
49
49
|
expect(await preferences.getStringPreferenceById(preferenceId)).toBe(DefaultPreferences.DiffEditor.MaxComputationTime);
|
|
50
50
|
});
|
|
51
51
|
|
|
@@ -53,29 +53,48 @@ test.describe('Preference View', () => {
|
|
|
53
53
|
const preferences = await app.openPreferences(TheiaPreferenceView);
|
|
54
54
|
const preferenceId = PreferenceIds.Explorer.AutoReveal;
|
|
55
55
|
|
|
56
|
-
await preferences.
|
|
56
|
+
await preferences.resetPreferenceById(preferenceId);
|
|
57
57
|
expect(await preferences.getBooleanPreferenceById(preferenceId)).toBe(DefaultPreferences.Explorer.AutoReveal.Enabled);
|
|
58
58
|
|
|
59
59
|
await preferences.setBooleanPreferenceById(preferenceId, false);
|
|
60
60
|
await preferences.waitForModified(preferenceId);
|
|
61
61
|
expect(await preferences.getBooleanPreferenceById(preferenceId)).toBe(false);
|
|
62
62
|
|
|
63
|
-
await preferences.
|
|
63
|
+
await preferences.resetPreferenceById(preferenceId);
|
|
64
64
|
expect(await preferences.getBooleanPreferenceById(preferenceId)).toBe(DefaultPreferences.Explorer.AutoReveal.Enabled);
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
+
test('should be able to read, set, and reset Options preferences', async () => {
|
|
68
|
+
const preferences = await app.openPreferences(TheiaPreferenceView);
|
|
69
|
+
const preferenceId = PreferenceIds.Editor.RenderWhitespace;
|
|
70
|
+
|
|
71
|
+
await preferences.resetPreferenceById(preferenceId);
|
|
72
|
+
expect(await preferences.getOptionsPreferenceById(preferenceId)).toBe(DefaultPreferences.Editor.RenderWhitespace.Selection);
|
|
73
|
+
|
|
74
|
+
await preferences.setOptionsPreferenceById(preferenceId, DefaultPreferences.Editor.RenderWhitespace.Boundary);
|
|
75
|
+
await preferences.waitForModified(preferenceId);
|
|
76
|
+
expect(await preferences.getOptionsPreferenceById(preferenceId)).toBe(DefaultPreferences.Editor.RenderWhitespace.Boundary);
|
|
77
|
+
|
|
78
|
+
await preferences.resetPreferenceById(preferenceId);
|
|
79
|
+
expect(await preferences.getOptionsPreferenceById(preferenceId)).toBe(DefaultPreferences.Editor.RenderWhitespace.Selection);
|
|
80
|
+
});
|
|
81
|
+
|
|
67
82
|
test('should throw an error if we try to read, set, or reset a non-existing preference', async () => {
|
|
68
83
|
const preferences = await app.openPreferences(TheiaPreferenceView);
|
|
69
84
|
|
|
70
85
|
preferences.customTimeout = 500;
|
|
71
86
|
try {
|
|
72
|
-
await expect(preferences.getBooleanPreferenceById('
|
|
73
|
-
await expect(preferences.setBooleanPreferenceById('
|
|
74
|
-
await expect(preferences.
|
|
87
|
+
await expect(preferences.getBooleanPreferenceById('not.a.real.preference')).rejects.toThrowError();
|
|
88
|
+
await expect(preferences.setBooleanPreferenceById('not.a.real.preference', true)).rejects.toThrowError();
|
|
89
|
+
await expect(preferences.resetPreferenceById('not.a.real.preference')).rejects.toThrowError();
|
|
75
90
|
|
|
76
|
-
await expect(preferences.getStringPreferenceById('
|
|
77
|
-
await expect(preferences.setStringPreferenceById('
|
|
78
|
-
await expect(preferences.
|
|
91
|
+
await expect(preferences.getStringPreferenceById('not.a.real.preference')).rejects.toThrowError();
|
|
92
|
+
await expect(preferences.setStringPreferenceById('not.a.real.preference', 'a')).rejects.toThrowError();
|
|
93
|
+
await expect(preferences.resetPreferenceById('not.a.real.preference')).rejects.toThrowError();
|
|
94
|
+
|
|
95
|
+
await expect(preferences.getOptionsPreferenceById('not.a.real.preference')).rejects.toThrowError();
|
|
96
|
+
await expect(preferences.setOptionsPreferenceById('not.a.real.preference', 'a')).rejects.toThrowError();
|
|
97
|
+
await expect(preferences.resetPreferenceById('not.a.real.preference')).rejects.toThrowError();
|
|
79
98
|
} finally {
|
|
80
99
|
preferences.customTimeout = undefined;
|
|
81
100
|
}
|
|
@@ -86,8 +105,14 @@ test.describe('Preference View', () => {
|
|
|
86
105
|
const stringPreference = PreferenceIds.DiffEditor.MaxComputationTime;
|
|
87
106
|
const booleanPreference = PreferenceIds.Explorer.AutoReveal;
|
|
88
107
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
108
|
+
preferences.customTimeout = 500;
|
|
109
|
+
try {
|
|
110
|
+
await expect(preferences.getBooleanPreferenceById(stringPreference)).rejects.toThrowError();
|
|
111
|
+
await expect(preferences.setBooleanPreferenceById(stringPreference, true)).rejects.toThrowError();
|
|
112
|
+
await expect(preferences.setStringPreferenceById(booleanPreference, 'true')).rejects.toThrowError();
|
|
113
|
+
await expect(preferences.setOptionsPreferenceById(booleanPreference, 'true')).rejects.toThrowError();
|
|
114
|
+
} finally {
|
|
115
|
+
preferences.customTimeout = undefined;
|
|
116
|
+
}
|
|
92
117
|
});
|
|
93
118
|
});
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { expect } from '@playwright/test';
|
|
18
|
+
import { DefaultPreferences, PreferenceIds, TheiaPreferenceView } from '../theia-preference-view';
|
|
18
19
|
import { TheiaApp } from '../theia-app';
|
|
19
20
|
import { TheiaTextEditor } from '../theia-text-editor';
|
|
20
21
|
import { TheiaWorkspace } from '../theia-workspace';
|
|
@@ -27,6 +28,11 @@ test.describe('Theia Text Editor', () => {
|
|
|
27
28
|
test.beforeAll(async () => {
|
|
28
29
|
const ws = new TheiaWorkspace(['src/tests/resources/sample-files1']);
|
|
29
30
|
app = await TheiaApp.load(page, ws);
|
|
31
|
+
|
|
32
|
+
// set auto-save preference to off
|
|
33
|
+
const preferenceView = await app.openPreferences(TheiaPreferenceView);
|
|
34
|
+
await preferenceView.setOptionsPreferenceById(PreferenceIds.Editor.AutoSave, DefaultPreferences.Editor.AutoSave.Off);
|
|
35
|
+
await preferenceView.close();
|
|
30
36
|
});
|
|
31
37
|
|
|
32
38
|
test('should be visible and active after opening "sample.txt"', async () => {
|
|
@@ -164,7 +170,7 @@ test.describe('Theia Text Editor', () => {
|
|
|
164
170
|
await sampleTextEditor.saveAndClose();
|
|
165
171
|
});
|
|
166
172
|
|
|
167
|
-
test
|
|
173
|
+
test('should close without saving', async () => {
|
|
168
174
|
const sampleTextEditor = await app.openEditor('sample.txt', TheiaTextEditor);
|
|
169
175
|
await sampleTextEditor.replaceLineWithLineNumber('change again', 1);
|
|
170
176
|
expect(await sampleTextEditor.isDirty()).toBe(true);
|
|
@@ -16,31 +16,26 @@
|
|
|
16
16
|
|
|
17
17
|
import { TheiaStatusIndicator } from './theia-status-indicator';
|
|
18
18
|
|
|
19
|
-
const NOTIFICATION_ICON = 'codicon-bell';
|
|
20
19
|
const NOTIFICATION_DOT_ICON = 'codicon-bell-dot';
|
|
21
|
-
const NOTIFICATION_ICONS = [NOTIFICATION_ICON, NOTIFICATION_DOT_ICON];
|
|
22
20
|
|
|
23
21
|
export class TheiaNotificationIndicator extends TheiaStatusIndicator {
|
|
24
|
-
|
|
25
|
-
protected get title(): string {
|
|
26
|
-
return 'Notification';
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
override async isVisible(): Promise<boolean> {
|
|
30
|
-
return super.isVisible(NOTIFICATION_ICONS, this.title);
|
|
31
|
-
}
|
|
22
|
+
id = 'theia-notification-center';
|
|
32
23
|
|
|
33
24
|
async hasNotifications(): Promise<boolean> {
|
|
34
|
-
|
|
25
|
+
const container = await this.getElementHandle();
|
|
26
|
+
const bellWithDot = await container.$(`.${NOTIFICATION_DOT_ICON}`);
|
|
27
|
+
return Boolean(bellWithDot?.isVisible());
|
|
35
28
|
}
|
|
36
29
|
|
|
37
30
|
override async waitForVisible(expectNotifications = false): Promise<void> {
|
|
38
|
-
await super.
|
|
31
|
+
await super.waitForVisible();
|
|
32
|
+
if (expectNotifications && !(await this.hasNotifications())) {
|
|
33
|
+
throw new Error('No notifications when notifications expected.');
|
|
34
|
+
}
|
|
39
35
|
}
|
|
40
36
|
|
|
41
37
|
async toggleOverlay(): Promise<void> {
|
|
42
|
-
const
|
|
43
|
-
const element = await this.getElementHandleByIcon(hasNotifications ? NOTIFICATION_DOT_ICON : NOTIFICATION_ICON, this.title);
|
|
38
|
+
const element = await this.getElementHandle();
|
|
44
39
|
if (element) {
|
|
45
40
|
await element.click();
|
|
46
41
|
}
|
|
@@ -24,6 +24,10 @@ const TheiaSettingsViewData = {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export const PreferenceIds = {
|
|
27
|
+
Editor: {
|
|
28
|
+
AutoSave: 'files.autoSave',
|
|
29
|
+
RenderWhitespace: 'editor.renderWhitespace'
|
|
30
|
+
},
|
|
27
31
|
Explorer: {
|
|
28
32
|
AutoReveal: 'explorer.autoReveal'
|
|
29
33
|
},
|
|
@@ -33,6 +37,21 @@ export const PreferenceIds = {
|
|
|
33
37
|
};
|
|
34
38
|
|
|
35
39
|
export const DefaultPreferences = {
|
|
40
|
+
Editor: {
|
|
41
|
+
AutoSave: {
|
|
42
|
+
Off: 'off',
|
|
43
|
+
AfterDelay: 'afterDelay',
|
|
44
|
+
OnFocusChange: 'onFocusChange',
|
|
45
|
+
OnWindowChange: 'onWindowChange'
|
|
46
|
+
},
|
|
47
|
+
RenderWhitespace: {
|
|
48
|
+
None: 'none',
|
|
49
|
+
Boundary: 'boundary',
|
|
50
|
+
Selection: 'selection',
|
|
51
|
+
Trailing: 'trailing',
|
|
52
|
+
All: 'all'
|
|
53
|
+
}
|
|
54
|
+
},
|
|
36
55
|
Explorer: {
|
|
37
56
|
AutoReveal: {
|
|
38
57
|
Enabled: true
|
|
@@ -50,6 +69,10 @@ export enum TheiaPreferenceScope {
|
|
|
50
69
|
|
|
51
70
|
export class TheiaPreferenceView extends TheiaView {
|
|
52
71
|
public customTimeout?: number;
|
|
72
|
+
protected modificationIndicator = '.theia-mod-item-modified';
|
|
73
|
+
protected optionSelectLabel = '.theia-select-component-label';
|
|
74
|
+
protected optionSelectDropdown = '.theia-select-component-dropdown';
|
|
75
|
+
protected optionSelectDropdownValue = '.theia-select-component-option-value';
|
|
53
76
|
|
|
54
77
|
constructor(app: TheiaApp) {
|
|
55
78
|
super(TheiaSettingsViewData, app);
|
|
@@ -72,14 +95,19 @@ export class TheiaPreferenceView extends TheiaView {
|
|
|
72
95
|
await scopeTab.click();
|
|
73
96
|
}
|
|
74
97
|
|
|
98
|
+
async getBooleanPreferenceByPath(sectionTitle: string, name: string): Promise<boolean> {
|
|
99
|
+
const preferenceId = await this.findPreferenceId(sectionTitle, name);
|
|
100
|
+
return this.getBooleanPreferenceById(preferenceId);
|
|
101
|
+
}
|
|
102
|
+
|
|
75
103
|
async getBooleanPreferenceById(preferenceId: string): Promise<boolean> {
|
|
76
104
|
const element = await this.findPreferenceEditorById(preferenceId);
|
|
77
105
|
return element.isChecked();
|
|
78
106
|
}
|
|
79
107
|
|
|
80
|
-
async
|
|
108
|
+
async setBooleanPreferenceByPath(sectionTitle: string, name: string, value: boolean): Promise<void> {
|
|
81
109
|
const preferenceId = await this.findPreferenceId(sectionTitle, name);
|
|
82
|
-
return this.
|
|
110
|
+
return this.setBooleanPreferenceById(preferenceId, value);
|
|
83
111
|
}
|
|
84
112
|
|
|
85
113
|
async setBooleanPreferenceById(preferenceId: string, value: boolean): Promise<void> {
|
|
@@ -87,9 +115,9 @@ export class TheiaPreferenceView extends TheiaView {
|
|
|
87
115
|
return value ? element.check() : element.uncheck();
|
|
88
116
|
}
|
|
89
117
|
|
|
90
|
-
async
|
|
118
|
+
async getStringPreferenceByPath(sectionTitle: string, name: string): Promise<string> {
|
|
91
119
|
const preferenceId = await this.findPreferenceId(sectionTitle, name);
|
|
92
|
-
return this.
|
|
120
|
+
return this.getStringPreferenceById(preferenceId);
|
|
93
121
|
}
|
|
94
122
|
|
|
95
123
|
async getStringPreferenceById(preferenceId: string): Promise<string> {
|
|
@@ -97,9 +125,9 @@ export class TheiaPreferenceView extends TheiaView {
|
|
|
97
125
|
return element.evaluate(e => (e as HTMLInputElement).value);
|
|
98
126
|
}
|
|
99
127
|
|
|
100
|
-
async
|
|
128
|
+
async setStringPreferenceByPath(sectionTitle: string, name: string, value: string): Promise<void> {
|
|
101
129
|
const preferenceId = await this.findPreferenceId(sectionTitle, name);
|
|
102
|
-
return this.
|
|
130
|
+
return this.setStringPreferenceById(preferenceId, value);
|
|
103
131
|
}
|
|
104
132
|
|
|
105
133
|
async setStringPreferenceById(preferenceId: string, value: string): Promise<void> {
|
|
@@ -107,63 +135,39 @@ export class TheiaPreferenceView extends TheiaView {
|
|
|
107
135
|
return element.fill(value);
|
|
108
136
|
}
|
|
109
137
|
|
|
110
|
-
async
|
|
138
|
+
async getOptionsPreferenceByPath(sectionTitle: string, name: string): Promise<string> {
|
|
111
139
|
const preferenceId = await this.findPreferenceId(sectionTitle, name);
|
|
112
|
-
return this.
|
|
140
|
+
return this.getOptionsPreferenceById(preferenceId);
|
|
113
141
|
}
|
|
114
142
|
|
|
115
|
-
async
|
|
116
|
-
await this.
|
|
117
|
-
|
|
118
|
-
await viewElement?.waitForSelector(`${this.getPreferenceGutterSelector(preferenceId)}.theia-mod-item-modified`, { timeout: this.customTimeout });
|
|
143
|
+
async getOptionsPreferenceById(preferenceId: string): Promise<string> {
|
|
144
|
+
const element = await this.findPreferenceEditorById(preferenceId, this.optionSelectLabel);
|
|
145
|
+
return element.evaluate(e => e.textContent ?? '');
|
|
119
146
|
}
|
|
120
147
|
|
|
121
|
-
async
|
|
122
|
-
const resetPreferenceButton = await this.findPreferenceResetButton(preferenceId);
|
|
123
|
-
if (!resetPreferenceButton) {
|
|
124
|
-
// preference not modified
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
const previousValue = await this.getStringPreferenceById(preferenceId);
|
|
128
|
-
const selector = this.getPreferenceEditorSelector(preferenceId);
|
|
129
|
-
const done = await resetPreferenceButton.click();
|
|
130
|
-
await this.page.waitForFunction(data => {
|
|
131
|
-
const element = document.querySelector(data.selector);
|
|
132
|
-
if (!element) {
|
|
133
|
-
throw new Error(`Could not find preference element with id "${data.preferenceId}"`);
|
|
134
|
-
}
|
|
135
|
-
const value = (element as HTMLInputElement).value;
|
|
136
|
-
return value !== data.previousValue;
|
|
137
|
-
}, { preferenceId, selector, previousValue, done }, { timeout: this.customTimeout });
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async resetStringPreferenceByPath(sectionTitle: string, name: string): Promise<void> {
|
|
148
|
+
async setOptionsPreferenceByPath(sectionTitle: string, name: string, value: string): Promise<void> {
|
|
141
149
|
const preferenceId = await this.findPreferenceId(sectionTitle, name);
|
|
142
|
-
return this.
|
|
150
|
+
return this.setOptionsPreferenceById(preferenceId, value);
|
|
143
151
|
}
|
|
144
152
|
|
|
145
|
-
async
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const done = await resetPreferenceButton.click();
|
|
154
|
-
await this.page.waitForFunction(data => {
|
|
155
|
-
const element = document.querySelector(data.selector);
|
|
156
|
-
if (!element) {
|
|
157
|
-
throw new Error(`Could not find preference element with id "${data.preferenceId}"`);
|
|
158
|
-
}
|
|
159
|
-
const value = (element as HTMLInputElement).checked;
|
|
160
|
-
return value !== data.previousValue;
|
|
161
|
-
}, { preferenceId, selector, previousValue, done }, { timeout: this.customTimeout });
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
async resetBooleanPreferenceByPath(sectionTitle: string, name: string): Promise<void> {
|
|
153
|
+
async setOptionsPreferenceById(preferenceId: string, value: string): Promise<void> {
|
|
154
|
+
const element = await this.findPreferenceEditorById(preferenceId, this.optionSelectLabel);
|
|
155
|
+
await element.click();
|
|
156
|
+
const option = await this.page.waitForSelector(`${this.optionSelectDropdown} ${this.optionSelectDropdownValue}:has-text("${value}")`);
|
|
157
|
+
await option.click();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async resetPreferenceByPath(sectionTitle: string, name: string): Promise<void> {
|
|
165
161
|
const preferenceId = await this.findPreferenceId(sectionTitle, name);
|
|
166
|
-
return this.
|
|
162
|
+
return this.resetPreferenceById(preferenceId);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async resetPreferenceById(preferenceId: string): Promise<void> {
|
|
166
|
+
// this is just to fail if the preference doesn't exist at all
|
|
167
|
+
await this.findPreferenceEditorById(preferenceId, '');
|
|
168
|
+
const resetPreferenceButton = await this.findPreferenceResetButton(preferenceId);
|
|
169
|
+
await resetPreferenceButton.click();
|
|
170
|
+
await this.waitForUnmodified(preferenceId);
|
|
167
171
|
}
|
|
168
172
|
|
|
169
173
|
private async findPreferenceId(sectionTitle: string, name: string): Promise<string> {
|
|
@@ -178,9 +182,9 @@ export class TheiaPreferenceView extends TheiaView {
|
|
|
178
182
|
return preferenceId;
|
|
179
183
|
}
|
|
180
184
|
|
|
181
|
-
private async findPreferenceEditorById(preferenceId: string): Promise<ElementHandle<SVGElement | HTMLElement>> {
|
|
185
|
+
private async findPreferenceEditorById(preferenceId: string, elementType: string = 'input'): Promise<ElementHandle<SVGElement | HTMLElement>> {
|
|
182
186
|
const viewElement = await this.viewElement();
|
|
183
|
-
const element = await viewElement?.waitForSelector(this.getPreferenceEditorSelector(preferenceId), { timeout: this.customTimeout });
|
|
187
|
+
const element = await viewElement?.waitForSelector(this.getPreferenceEditorSelector(preferenceId, elementType), { timeout: this.customTimeout });
|
|
184
188
|
if (!element) {
|
|
185
189
|
throw new Error(`Could not find element with preference id "${preferenceId}"`);
|
|
186
190
|
}
|
|
@@ -191,26 +195,13 @@ export class TheiaPreferenceView extends TheiaView {
|
|
|
191
195
|
return `li[data-pref-id="${preferenceId}"]`;
|
|
192
196
|
}
|
|
193
197
|
|
|
194
|
-
private getPreferenceEditorSelector(preferenceId: string): string {
|
|
195
|
-
return `${this.getPreferenceSelector(preferenceId)}
|
|
198
|
+
private getPreferenceEditorSelector(preferenceId: string, elementType: string): string {
|
|
199
|
+
return `${this.getPreferenceSelector(preferenceId)} ${elementType}`;
|
|
196
200
|
}
|
|
197
201
|
|
|
198
|
-
private
|
|
199
|
-
return `${this.getPreferenceSelector(preferenceId)} .pref-context-gutter`;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
private async findPreferenceResetButton(preferenceId: string): Promise<ElementHandle<SVGElement | HTMLElement> | undefined> {
|
|
202
|
+
private async findPreferenceResetButton(preferenceId: string): Promise<ElementHandle<SVGElement | HTMLElement>> {
|
|
203
203
|
await this.activate();
|
|
204
204
|
const viewElement = await this.viewElement();
|
|
205
|
-
const gutter = await viewElement?.waitForSelector(`${this.getPreferenceGutterSelector(preferenceId)}`, { timeout: this.customTimeout });
|
|
206
|
-
if (!gutter) {
|
|
207
|
-
throw new Error(`Could not determine modified state for element with preference id "${preferenceId}"`);
|
|
208
|
-
}
|
|
209
|
-
const isModified = await gutter.evaluate(e => e.classList.contains('theia-mod-item-modified'));
|
|
210
|
-
if (!isModified) {
|
|
211
|
-
return undefined;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
205
|
const settingsContextMenuBtn = await viewElement?.waitForSelector(`${this.getPreferenceSelector(preferenceId)} .settings-context-menu-btn`);
|
|
215
206
|
if (!settingsContextMenuBtn) {
|
|
216
207
|
throw new Error(`Could not find context menu button for element with preference id "${preferenceId}"`);
|
|
@@ -223,4 +214,19 @@ export class TheiaPreferenceView extends TheiaView {
|
|
|
223
214
|
return resetPreferenceButton;
|
|
224
215
|
}
|
|
225
216
|
|
|
217
|
+
async waitForModified(preferenceId: string): Promise<void> {
|
|
218
|
+
await this.activate();
|
|
219
|
+
const viewElement = await this.viewElement();
|
|
220
|
+
await viewElement?.waitForSelector(`${this.getPreferenceGutterSelector(preferenceId)}${this.modificationIndicator}`, { timeout: this.customTimeout });
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async waitForUnmodified(preferenceId: string): Promise<void> {
|
|
224
|
+
await this.activate();
|
|
225
|
+
const viewElement = await this.viewElement();
|
|
226
|
+
await viewElement?.waitForSelector(`${this.getPreferenceGutterSelector(preferenceId)}${this.modificationIndicator}`, { state: 'detached', timeout: this.customTimeout });
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private getPreferenceGutterSelector(preferenceId: string): string {
|
|
230
|
+
return `${this.getPreferenceSelector(preferenceId)} .pref-context-gutter`;
|
|
231
|
+
}
|
|
226
232
|
}
|
|
@@ -17,14 +17,8 @@
|
|
|
17
17
|
import { ElementHandle } from '@playwright/test';
|
|
18
18
|
import { TheiaStatusIndicator } from './theia-status-indicator';
|
|
19
19
|
|
|
20
|
-
const PROBLEM_ICON = 'codicon-error';
|
|
21
|
-
|
|
22
20
|
export class TheiaProblemIndicator extends TheiaStatusIndicator {
|
|
23
|
-
|
|
24
|
-
override async isVisible(): Promise<boolean> {
|
|
25
|
-
const handle = await super.getElementHandleByIcon(PROBLEM_ICON);
|
|
26
|
-
return !!handle && handle.isVisible();
|
|
27
|
-
}
|
|
21
|
+
id = 'problem-marker-status';
|
|
28
22
|
|
|
29
23
|
async numberOfProblems(): Promise<number> {
|
|
30
24
|
const spans = await this.getSpans();
|
|
@@ -37,8 +31,7 @@ export class TheiaProblemIndicator extends TheiaStatusIndicator {
|
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
protected async getSpans(): Promise<ElementHandle[] | undefined> {
|
|
40
|
-
const handle = await
|
|
34
|
+
const handle = await this.getElementHandle();
|
|
41
35
|
return handle?.$$('span');
|
|
42
36
|
}
|
|
43
|
-
|
|
44
37
|
}
|