@theia/playwright 1.48.1 → 1.48.2

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.
Files changed (159) hide show
  1. package/README.md +54 -54
  2. package/lib/index.d.ts +30 -30
  3. package/lib/index.js +48 -48
  4. package/lib/tests/theia-app.test.d.ts +1 -1
  5. package/lib/tests/theia-app.test.js +29 -29
  6. package/lib/tests/theia-application-shell.test.d.ts +1 -1
  7. package/lib/tests/theia-application-shell.test.js +57 -57
  8. package/lib/tests/theia-explorer-view.test.d.ts +1 -1
  9. package/lib/tests/theia-explorer-view.test.js +183 -183
  10. package/lib/tests/theia-getting-started.test.d.ts +1 -1
  11. package/lib/tests/theia-getting-started.test.js +45 -45
  12. package/lib/tests/theia-main-menu.test.d.ts +1 -1
  13. package/lib/tests/theia-main-menu.test.js +111 -111
  14. package/lib/tests/theia-output-view.test.d.ts +1 -1
  15. package/lib/tests/theia-output-view.test.js +78 -78
  16. package/lib/tests/theia-preference-view.test.d.ts +1 -1
  17. package/lib/tests/theia-preference-view.test.js +101 -101
  18. package/lib/tests/theia-problems-view.test.d.ts +1 -1
  19. package/lib/tests/theia-problems-view.test.js +54 -54
  20. package/lib/tests/theia-quick-command.test.d.ts +1 -1
  21. package/lib/tests/theia-quick-command.test.js +69 -69
  22. package/lib/tests/theia-sample-app.test.d.ts +1 -1
  23. package/lib/tests/theia-sample-app.test.js +57 -57
  24. package/lib/tests/theia-status-bar.test.d.ts +1 -1
  25. package/lib/tests/theia-status-bar.test.js +44 -44
  26. package/lib/tests/theia-terminal-view.test.d.ts +1 -1
  27. package/lib/tests/theia-terminal-view.test.js +78 -78
  28. package/lib/tests/theia-text-editor.test.d.ts +1 -1
  29. package/lib/tests/theia-text-editor.test.js +155 -155
  30. package/lib/tests/theia-toolbar.test.d.ts +1 -1
  31. package/lib/tests/theia-toolbar.test.js +61 -61
  32. package/lib/tests/theia-workspace.test.d.ts +1 -1
  33. package/lib/tests/theia-workspace.test.js +72 -72
  34. package/lib/theia-about-dialog.d.ts +4 -4
  35. package/lib/theia-about-dialog.js +26 -26
  36. package/lib/theia-app-loader.d.ts +19 -19
  37. package/lib/theia-app-loader.js +129 -129
  38. package/lib/theia-app.d.ts +50 -50
  39. package/lib/theia-app.js +153 -153
  40. package/lib/theia-context-menu.d.ts +8 -8
  41. package/lib/theia-context-menu.js +37 -37
  42. package/lib/theia-dialog.d.ts +28 -28
  43. package/lib/theia-dialog.js +99 -99
  44. package/lib/theia-editor.d.ts +9 -9
  45. package/lib/theia-editor.js +68 -68
  46. package/lib/theia-explorer-view.d.ts +47 -47
  47. package/lib/theia-explorer-view.js +273 -273
  48. package/lib/theia-main-menu.d.ts +12 -12
  49. package/lib/theia-main-menu.js +53 -53
  50. package/lib/theia-menu-item.d.ts +14 -14
  51. package/lib/theia-menu-item.js +66 -66
  52. package/lib/theia-menu.d.ts +16 -16
  53. package/lib/theia-menu.js +86 -86
  54. package/lib/theia-monaco-editor.d.ts +15 -15
  55. package/lib/theia-monaco-editor.js +75 -75
  56. package/lib/theia-notification-indicator.d.ts +7 -7
  57. package/lib/theia-notification-indicator.js +44 -44
  58. package/lib/theia-notification-overlay.d.ts +22 -22
  59. package/lib/theia-notification-overlay.js +79 -79
  60. package/lib/theia-output-channel.d.ts +24 -24
  61. package/lib/theia-output-channel.js +71 -71
  62. package/lib/theia-output-view.d.ts +9 -9
  63. package/lib/theia-output-view.js +81 -81
  64. package/lib/theia-page-object.d.ts +7 -7
  65. package/lib/theia-page-object.js +27 -27
  66. package/lib/theia-preference-view.d.ts +84 -84
  67. package/lib/theia-preference-view.js +209 -209
  68. package/lib/theia-problem-indicator.d.ts +8 -8
  69. package/lib/theia-problem-indicator.js +38 -38
  70. package/lib/theia-problem-view.d.ts +5 -5
  71. package/lib/theia-problem-view.js +30 -30
  72. package/lib/theia-quick-command-palette.d.ts +12 -12
  73. package/lib/theia-quick-command-palette.js +78 -78
  74. package/lib/theia-rename-dialog.d.ts +5 -5
  75. package/lib/theia-rename-dialog.js +34 -34
  76. package/lib/theia-status-bar.d.ts +13 -13
  77. package/lib/theia-status-bar.js +39 -39
  78. package/lib/theia-status-indicator.d.ts +10 -10
  79. package/lib/theia-status-indicator.js +48 -48
  80. package/lib/theia-terminal.d.ts +13 -13
  81. package/lib/theia-terminal.js +59 -59
  82. package/lib/theia-text-editor.d.ts +26 -26
  83. package/lib/theia-text-editor.js +120 -120
  84. package/lib/theia-toggle-bottom-indicator.d.ts +4 -4
  85. package/lib/theia-toggle-bottom-indicator.js +26 -26
  86. package/lib/theia-toolbar-item.d.ts +10 -10
  87. package/lib/theia-toolbar-item.js +39 -39
  88. package/lib/theia-toolbar.d.ts +19 -19
  89. package/lib/theia-toolbar.js +90 -90
  90. package/lib/theia-tree-node.d.ts +19 -19
  91. package/lib/theia-tree-node.js +72 -72
  92. package/lib/theia-view.d.ts +32 -32
  93. package/lib/theia-view.js +149 -149
  94. package/lib/theia-welcome-view.d.ts +5 -5
  95. package/lib/theia-welcome-view.js +30 -30
  96. package/lib/theia-workspace.d.ts +18 -18
  97. package/lib/theia-workspace.js +69 -69
  98. package/lib/util.d.ts +19 -19
  99. package/lib/util.js +93 -93
  100. package/package.json +2 -2
  101. package/src/index.ts +46 -46
  102. package/src/tests/resources/sample-files1/sample.txt +4 -4
  103. package/src/tests/resources/sample-files1/sampleFolder/sampleFolder1/sampleFolder1-1/sampleFile1-1-1.txt +1 -1
  104. package/src/tests/resources/sample-files1/sampleFolder/sampleFolder1/sampleFolder1-1/sampleFile1-1-2.txt +1 -1
  105. package/src/tests/resources/sample-files1/sampleFolder/sampleFolder1/sampleFolder1-2/sampleFile1-2-1.txt +1 -1
  106. package/src/tests/resources/sample-files1/sampleFolder/sampleFolder1/sampleFolder1-2/sampleFile1-2-2.txt +1 -1
  107. package/src/tests/resources/sample-files1/sampleFolder/sampleFolder2/sampleFolder2-1/sampleFile2-1-1.txt +1 -1
  108. package/src/tests/resources/sample-files1/sampleFolder/sampleFolder2/sampleFolder2-1/sampleFile2-1-2.txt +1 -1
  109. package/src/tests/resources/sample-files1/sampleFolder/sampleFolder2/sampleFolder2-2/sampleFile2-2-1.txt +1 -1
  110. package/src/tests/resources/sample-files1/sampleFolder/sampleFolder2/sampleFolder2-2/sampleFile2-2-2.txt +1 -1
  111. package/src/tests/resources/sample-files2/another-sample.txt +1 -1
  112. package/src/tests/theia-app.test.ts +33 -33
  113. package/src/tests/theia-application-shell.test.ts +67 -67
  114. package/src/tests/theia-explorer-view.test.ts +211 -211
  115. package/src/tests/theia-getting-started.test.ts +50 -50
  116. package/src/tests/theia-main-menu.test.ts +133 -133
  117. package/src/tests/theia-output-view.test.ts +85 -85
  118. package/src/tests/theia-preference-view.test.ts +122 -122
  119. package/src/tests/theia-problems-view.test.ts +64 -64
  120. package/src/tests/theia-quick-command.test.ts +80 -80
  121. package/src/tests/theia-sample-app.test.ts +66 -66
  122. package/src/tests/theia-status-bar.test.ts +52 -52
  123. package/src/tests/theia-terminal-view.test.ts +90 -90
  124. package/src/tests/theia-text-editor.test.ts +187 -187
  125. package/src/tests/theia-toolbar.test.ts +69 -69
  126. package/src/tests/theia-workspace.test.ts +80 -80
  127. package/src/theia-about-dialog.ts +26 -26
  128. package/src/theia-app-loader.ts +167 -167
  129. package/src/theia-app.ts +188 -188
  130. package/src/theia-context-menu.ts +42 -42
  131. package/src/theia-dialog.ts +114 -114
  132. package/src/theia-editor.ts +73 -73
  133. package/src/theia-explorer-view.ts +311 -311
  134. package/src/theia-main-menu.ts +54 -54
  135. package/src/theia-menu-item.ts +75 -75
  136. package/src/theia-menu.ts +96 -96
  137. package/src/theia-monaco-editor.ts +83 -83
  138. package/src/theia-notification-indicator.ts +44 -44
  139. package/src/theia-notification-overlay.ts +94 -94
  140. package/src/theia-output-channel.ts +88 -88
  141. package/src/theia-output-view.ts +87 -87
  142. package/src/theia-page-object.ts +29 -29
  143. package/src/theia-preference-view.ts +240 -240
  144. package/src/theia-problem-indicator.ts +37 -37
  145. package/src/theia-problem-view.ts +30 -30
  146. package/src/theia-quick-command-palette.ts +81 -81
  147. package/src/theia-rename-dialog.ts +35 -35
  148. package/src/theia-status-bar.ts +44 -44
  149. package/src/theia-status-indicator.ts +50 -50
  150. package/src/theia-terminal.ts +69 -69
  151. package/src/theia-text-editor.ts +141 -141
  152. package/src/theia-toggle-bottom-indicator.ts +21 -21
  153. package/src/theia-toolbar-item.ts +41 -41
  154. package/src/theia-toolbar.ts +99 -99
  155. package/src/theia-tree-node.ts +81 -81
  156. package/src/theia-view.ts +177 -177
  157. package/src/theia-welcome-view.ts +31 -31
  158. package/src/theia-workspace.ts +76 -76
  159. package/src/util.ts +91 -91
@@ -1,81 +1,81 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2021 logi.cals GmbH, EclipseSource and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- import { ElementHandle } from '@playwright/test';
18
-
19
- import { TheiaApp } from './theia-app';
20
- import { TheiaContextMenu } from './theia-context-menu';
21
- import { TheiaMenu } from './theia-menu';
22
-
23
- export class TheiaTreeNode {
24
-
25
- labelElementCssClass = '.theia-TreeNodeSegmentGrow';
26
- nodeSegmentLabelCssClass = '.theia-tree-compressed-label-part';
27
- expansionToggleCssClass = '.theia-ExpansionToggle';
28
- collapsedCssClass = '.theia-mod-collapsed';
29
-
30
- constructor(protected elementHandle: ElementHandle<SVGElement | HTMLElement>, protected app: TheiaApp) { }
31
-
32
- async label(): Promise<string | null> {
33
- const labelNode = await this.elementHandle.$(this.labelElementCssClass);
34
- if (!labelNode) {
35
- throw new Error('Cannot read label of ' + this.elementHandle);
36
- }
37
- return labelNode.textContent();
38
- }
39
-
40
- async isCollapsed(): Promise<boolean> {
41
- return !! await this.elementHandle.$(this.collapsedCssClass);
42
- }
43
-
44
- async isExpandable(): Promise<boolean> {
45
- return !! await this.elementHandle.$(this.expansionToggleCssClass);
46
- }
47
-
48
- async expand(): Promise<void> {
49
- if (!await this.isCollapsed()) {
50
- return;
51
- }
52
- const expansionToggle = await this.elementHandle.waitForSelector(this.expansionToggleCssClass);
53
- await expansionToggle.click();
54
- await this.elementHandle.waitForSelector(`${this.expansionToggleCssClass}:not(${this.collapsedCssClass})`);
55
- }
56
-
57
- async collapse(): Promise<void> {
58
- if (await this.isCollapsed()) {
59
- return;
60
- }
61
- const expansionToggle = await this.elementHandle.waitForSelector(this.expansionToggleCssClass);
62
- await expansionToggle.click();
63
- await this.elementHandle.waitForSelector(`${this.expansionToggleCssClass}${this.collapsedCssClass}`);
64
- }
65
-
66
- async openContextMenu(): Promise<TheiaMenu> {
67
- return TheiaContextMenu.open(this.app, () => this.elementHandle.waitForSelector(this.labelElementCssClass));
68
- }
69
-
70
- async openContextMenuOnSegment(nodeSegmentLabel: string): Promise<TheiaMenu> {
71
- const treeNodeLabel = await this.elementHandle.waitForSelector(this.labelElementCssClass);
72
- const treeNodeLabelSegments = await treeNodeLabel.$$(`span${this.nodeSegmentLabelCssClass}`);
73
- for (const segmentLabel of treeNodeLabelSegments) {
74
- if (await segmentLabel.textContent() === nodeSegmentLabel) {
75
- return TheiaContextMenu.open(this.app, () => Promise.resolve(segmentLabel));
76
- }
77
- }
78
- throw new Error('Could not find tree node segment label "' + nodeSegmentLabel + '"');
79
- }
80
-
81
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2021 logi.cals GmbH, EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { ElementHandle } from '@playwright/test';
18
+
19
+ import { TheiaApp } from './theia-app';
20
+ import { TheiaContextMenu } from './theia-context-menu';
21
+ import { TheiaMenu } from './theia-menu';
22
+
23
+ export class TheiaTreeNode {
24
+
25
+ labelElementCssClass = '.theia-TreeNodeSegmentGrow';
26
+ nodeSegmentLabelCssClass = '.theia-tree-compressed-label-part';
27
+ expansionToggleCssClass = '.theia-ExpansionToggle';
28
+ collapsedCssClass = '.theia-mod-collapsed';
29
+
30
+ constructor(protected elementHandle: ElementHandle<SVGElement | HTMLElement>, protected app: TheiaApp) { }
31
+
32
+ async label(): Promise<string | null> {
33
+ const labelNode = await this.elementHandle.$(this.labelElementCssClass);
34
+ if (!labelNode) {
35
+ throw new Error('Cannot read label of ' + this.elementHandle);
36
+ }
37
+ return labelNode.textContent();
38
+ }
39
+
40
+ async isCollapsed(): Promise<boolean> {
41
+ return !! await this.elementHandle.$(this.collapsedCssClass);
42
+ }
43
+
44
+ async isExpandable(): Promise<boolean> {
45
+ return !! await this.elementHandle.$(this.expansionToggleCssClass);
46
+ }
47
+
48
+ async expand(): Promise<void> {
49
+ if (!await this.isCollapsed()) {
50
+ return;
51
+ }
52
+ const expansionToggle = await this.elementHandle.waitForSelector(this.expansionToggleCssClass);
53
+ await expansionToggle.click();
54
+ await this.elementHandle.waitForSelector(`${this.expansionToggleCssClass}:not(${this.collapsedCssClass})`);
55
+ }
56
+
57
+ async collapse(): Promise<void> {
58
+ if (await this.isCollapsed()) {
59
+ return;
60
+ }
61
+ const expansionToggle = await this.elementHandle.waitForSelector(this.expansionToggleCssClass);
62
+ await expansionToggle.click();
63
+ await this.elementHandle.waitForSelector(`${this.expansionToggleCssClass}${this.collapsedCssClass}`);
64
+ }
65
+
66
+ async openContextMenu(): Promise<TheiaMenu> {
67
+ return TheiaContextMenu.open(this.app, () => this.elementHandle.waitForSelector(this.labelElementCssClass));
68
+ }
69
+
70
+ async openContextMenuOnSegment(nodeSegmentLabel: string): Promise<TheiaMenu> {
71
+ const treeNodeLabel = await this.elementHandle.waitForSelector(this.labelElementCssClass);
72
+ const treeNodeLabelSegments = await treeNodeLabel.$$(`span${this.nodeSegmentLabelCssClass}`);
73
+ for (const segmentLabel of treeNodeLabelSegments) {
74
+ if (await segmentLabel.textContent() === nodeSegmentLabel) {
75
+ return TheiaContextMenu.open(this.app, () => Promise.resolve(segmentLabel));
76
+ }
77
+ }
78
+ throw new Error('Could not find tree node segment label "' + nodeSegmentLabel + '"');
79
+ }
80
+
81
+ }
package/src/theia-view.ts CHANGED
@@ -1,177 +1,177 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2021 logi.cals GmbH, EclipseSource and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- import { ElementHandle } from '@playwright/test';
18
-
19
- import { TheiaApp } from './theia-app';
20
- import { TheiaContextMenu } from './theia-context-menu';
21
- import { TheiaMenu } from './theia-menu';
22
- import { TheiaPageObject } from './theia-page-object';
23
- import { containsClass, isElementVisible, textContent } from './util';
24
-
25
- export interface TheiaViewData {
26
- tabSelector: string;
27
- viewSelector: string;
28
- viewName?: string;
29
- }
30
-
31
- export class TheiaView extends TheiaPageObject {
32
-
33
- constructor(protected readonly data: TheiaViewData, app: TheiaApp) {
34
- super(app);
35
- }
36
-
37
- get tabSelector(): string {
38
- return this.data.tabSelector;
39
- }
40
-
41
- get viewSelector(): string {
42
- return this.data.viewSelector;
43
- }
44
-
45
- get name(): string | undefined {
46
- return this.data.viewName;
47
- }
48
-
49
- async open(): Promise<TheiaView> {
50
- if (!this.data.viewName) {
51
- throw new Error('View name must be specified to open via command palette');
52
- }
53
- await this.app.quickCommandPalette.type('View: Open View');
54
- await this.app.quickCommandPalette.trigger('View: Open View...', this.data.viewName);
55
- await this.waitForVisible();
56
- return this;
57
- }
58
-
59
- async focus(): Promise<void> {
60
- await this.activate();
61
- const view = await this.viewElement();
62
- await view?.click();
63
- }
64
-
65
- async activate(): Promise<void> {
66
- await this.page.waitForSelector(this.tabSelector, { state: 'visible' });
67
- if (!await this.isActive()) {
68
- const tab = await this.tabElement();
69
- await tab?.click();
70
- }
71
- return this.waitForVisible();
72
- }
73
-
74
- async waitForVisible(): Promise<void> {
75
- await this.page.waitForSelector(this.viewSelector, { state: 'visible' });
76
- }
77
-
78
- async isTabVisible(): Promise<boolean> {
79
- return isElementVisible(this.tabElement());
80
- }
81
-
82
- async isDisplayed(): Promise<boolean> {
83
- return isElementVisible(this.viewElement());
84
- }
85
-
86
- async isActive(): Promise<boolean> {
87
- return await this.isTabVisible() && containsClass(this.tabElement(), 'p-mod-current');
88
- }
89
-
90
- async isClosable(): Promise<boolean> {
91
- return await this.isTabVisible() && containsClass(this.tabElement(), 'p-mod-closable');
92
- }
93
-
94
- async close(waitForClosed = true): Promise<void> {
95
- if (!(await this.isTabVisible())) {
96
- return;
97
- }
98
- if (!(await this.isClosable())) {
99
- throw Error(`View ${this.tabSelector} is not closable`);
100
- }
101
- const tab = await this.tabElement();
102
- const side = await this.side();
103
- if (side === 'main' || side === 'bottom') {
104
- const closeIcon = await tab?.waitForSelector('div.p-TabBar-tabCloseIcon');
105
- await closeIcon?.click();
106
- } else {
107
- const menu = await this.openContextMenuOnTab();
108
- const closeItem = await menu.menuItemByName('Close');
109
- await closeItem?.click();
110
- }
111
- if (waitForClosed) {
112
- await this.waitUntilClosed();
113
- }
114
- }
115
-
116
- protected async waitUntilClosed(): Promise<void> {
117
- await this.page.waitForSelector(this.tabSelector, { state: 'detached' });
118
- }
119
-
120
- async title(): Promise<string | undefined> {
121
- if ((await this.isInSidePanel()) && !(await this.isActive())) {
122
- // we can only determine the label of a side-panel view, if it is active
123
- await this.activate();
124
- }
125
- switch (await this.side()) {
126
- case 'left':
127
- return textContent(this.page.waitForSelector('div.theia-left-side-panel > div.theia-sidepanel-title'));
128
- case 'right':
129
- return textContent(this.page.waitForSelector('div.theia-right-side-panel > div.theia-sidepanel-title'));
130
- }
131
- const tab = await this.tabElement();
132
- if (tab) {
133
- return textContent(tab.waitForSelector('div.theia-tab-icon-label > div.p-TabBar-tabLabel'));
134
- }
135
- return undefined;
136
- }
137
-
138
- async isInSidePanel(): Promise<boolean> {
139
- return (await this.side() === 'left') || (await this.side() === 'right');
140
- }
141
-
142
- async side(): Promise<'left' | 'right' | 'bottom' | 'main'> {
143
- if (!await this.isTabVisible()) {
144
- throw Error(`Unable to determine side of invisible view tab '${this.tabSelector}'`);
145
- }
146
- const tab = await this.tabElement();
147
- const appAreaElement = tab?.$('xpath=../../../..');
148
- if (await containsClass(appAreaElement, 'theia-app-left')) {
149
- return 'left';
150
- }
151
- if (await containsClass(appAreaElement, 'theia-app-right')) {
152
- return 'right';
153
- }
154
-
155
- if (await containsClass(appAreaElement, 'theia-app-bottom')) {
156
- return 'bottom';
157
- }
158
- if (await containsClass(appAreaElement, 'theia-app-main')) {
159
- return 'main';
160
- }
161
- throw Error(`Unable to determine side of view tab '${this.tabSelector}'`);
162
- }
163
-
164
- async openContextMenuOnTab(): Promise<TheiaMenu> {
165
- await this.activate();
166
- return TheiaContextMenu.open(this.app, () => this.page.waitForSelector(this.tabSelector));
167
- }
168
-
169
- protected viewElement(): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
170
- return this.page.$(this.viewSelector);
171
- }
172
-
173
- protected tabElement(): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
174
- return this.page.$(this.tabSelector);
175
- }
176
-
177
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2021 logi.cals GmbH, EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { ElementHandle } from '@playwright/test';
18
+
19
+ import { TheiaApp } from './theia-app';
20
+ import { TheiaContextMenu } from './theia-context-menu';
21
+ import { TheiaMenu } from './theia-menu';
22
+ import { TheiaPageObject } from './theia-page-object';
23
+ import { containsClass, isElementVisible, textContent } from './util';
24
+
25
+ export interface TheiaViewData {
26
+ tabSelector: string;
27
+ viewSelector: string;
28
+ viewName?: string;
29
+ }
30
+
31
+ export class TheiaView extends TheiaPageObject {
32
+
33
+ constructor(protected readonly data: TheiaViewData, app: TheiaApp) {
34
+ super(app);
35
+ }
36
+
37
+ get tabSelector(): string {
38
+ return this.data.tabSelector;
39
+ }
40
+
41
+ get viewSelector(): string {
42
+ return this.data.viewSelector;
43
+ }
44
+
45
+ get name(): string | undefined {
46
+ return this.data.viewName;
47
+ }
48
+
49
+ async open(): Promise<TheiaView> {
50
+ if (!this.data.viewName) {
51
+ throw new Error('View name must be specified to open via command palette');
52
+ }
53
+ await this.app.quickCommandPalette.type('View: Open View');
54
+ await this.app.quickCommandPalette.trigger('View: Open View...', this.data.viewName);
55
+ await this.waitForVisible();
56
+ return this;
57
+ }
58
+
59
+ async focus(): Promise<void> {
60
+ await this.activate();
61
+ const view = await this.viewElement();
62
+ await view?.click();
63
+ }
64
+
65
+ async activate(): Promise<void> {
66
+ await this.page.waitForSelector(this.tabSelector, { state: 'visible' });
67
+ if (!await this.isActive()) {
68
+ const tab = await this.tabElement();
69
+ await tab?.click();
70
+ }
71
+ return this.waitForVisible();
72
+ }
73
+
74
+ async waitForVisible(): Promise<void> {
75
+ await this.page.waitForSelector(this.viewSelector, { state: 'visible' });
76
+ }
77
+
78
+ async isTabVisible(): Promise<boolean> {
79
+ return isElementVisible(this.tabElement());
80
+ }
81
+
82
+ async isDisplayed(): Promise<boolean> {
83
+ return isElementVisible(this.viewElement());
84
+ }
85
+
86
+ async isActive(): Promise<boolean> {
87
+ return await this.isTabVisible() && containsClass(this.tabElement(), 'p-mod-current');
88
+ }
89
+
90
+ async isClosable(): Promise<boolean> {
91
+ return await this.isTabVisible() && containsClass(this.tabElement(), 'p-mod-closable');
92
+ }
93
+
94
+ async close(waitForClosed = true): Promise<void> {
95
+ if (!(await this.isTabVisible())) {
96
+ return;
97
+ }
98
+ if (!(await this.isClosable())) {
99
+ throw Error(`View ${this.tabSelector} is not closable`);
100
+ }
101
+ const tab = await this.tabElement();
102
+ const side = await this.side();
103
+ if (side === 'main' || side === 'bottom') {
104
+ const closeIcon = await tab?.waitForSelector('div.p-TabBar-tabCloseIcon');
105
+ await closeIcon?.click();
106
+ } else {
107
+ const menu = await this.openContextMenuOnTab();
108
+ const closeItem = await menu.menuItemByName('Close');
109
+ await closeItem?.click();
110
+ }
111
+ if (waitForClosed) {
112
+ await this.waitUntilClosed();
113
+ }
114
+ }
115
+
116
+ protected async waitUntilClosed(): Promise<void> {
117
+ await this.page.waitForSelector(this.tabSelector, { state: 'detached' });
118
+ }
119
+
120
+ async title(): Promise<string | undefined> {
121
+ if ((await this.isInSidePanel()) && !(await this.isActive())) {
122
+ // we can only determine the label of a side-panel view, if it is active
123
+ await this.activate();
124
+ }
125
+ switch (await this.side()) {
126
+ case 'left':
127
+ return textContent(this.page.waitForSelector('div.theia-left-side-panel > div.theia-sidepanel-title'));
128
+ case 'right':
129
+ return textContent(this.page.waitForSelector('div.theia-right-side-panel > div.theia-sidepanel-title'));
130
+ }
131
+ const tab = await this.tabElement();
132
+ if (tab) {
133
+ return textContent(tab.waitForSelector('div.theia-tab-icon-label > div.p-TabBar-tabLabel'));
134
+ }
135
+ return undefined;
136
+ }
137
+
138
+ async isInSidePanel(): Promise<boolean> {
139
+ return (await this.side() === 'left') || (await this.side() === 'right');
140
+ }
141
+
142
+ async side(): Promise<'left' | 'right' | 'bottom' | 'main'> {
143
+ if (!await this.isTabVisible()) {
144
+ throw Error(`Unable to determine side of invisible view tab '${this.tabSelector}'`);
145
+ }
146
+ const tab = await this.tabElement();
147
+ const appAreaElement = tab?.$('xpath=../../../..');
148
+ if (await containsClass(appAreaElement, 'theia-app-left')) {
149
+ return 'left';
150
+ }
151
+ if (await containsClass(appAreaElement, 'theia-app-right')) {
152
+ return 'right';
153
+ }
154
+
155
+ if (await containsClass(appAreaElement, 'theia-app-bottom')) {
156
+ return 'bottom';
157
+ }
158
+ if (await containsClass(appAreaElement, 'theia-app-main')) {
159
+ return 'main';
160
+ }
161
+ throw Error(`Unable to determine side of view tab '${this.tabSelector}'`);
162
+ }
163
+
164
+ async openContextMenuOnTab(): Promise<TheiaMenu> {
165
+ await this.activate();
166
+ return TheiaContextMenu.open(this.app, () => this.page.waitForSelector(this.tabSelector));
167
+ }
168
+
169
+ protected viewElement(): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
170
+ return this.page.$(this.viewSelector);
171
+ }
172
+
173
+ protected tabElement(): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
174
+ return this.page.$(this.tabSelector);
175
+ }
176
+
177
+ }
@@ -1,31 +1,31 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2023 Toro Cloud Pty Ltd and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
-
16
- import { TheiaApp } from './theia-app';
17
- import { TheiaView } from './theia-view';
18
- import { normalizeId } from './util';
19
-
20
- const TheiaWelcomeViewData = {
21
- tabSelector: normalizeId('#shell-tab-getting.started.widget'),
22
- viewSelector: normalizeId('#getting.started.widget'),
23
- viewName: 'Welcome'
24
- };
25
-
26
- export class TheiaWelcomeView extends TheiaView {
27
-
28
- constructor(app: TheiaApp) {
29
- super(TheiaWelcomeViewData, app);
30
- }
31
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 Toro Cloud Pty Ltd and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+
16
+ import { TheiaApp } from './theia-app';
17
+ import { TheiaView } from './theia-view';
18
+ import { normalizeId } from './util';
19
+
20
+ const TheiaWelcomeViewData = {
21
+ tabSelector: normalizeId('#shell-tab-getting.started.widget'),
22
+ viewSelector: normalizeId('#getting.started.widget'),
23
+ viewName: 'Welcome'
24
+ };
25
+
26
+ export class TheiaWelcomeView extends TheiaView {
27
+
28
+ constructor(app: TheiaApp) {
29
+ super(TheiaWelcomeViewData, app);
30
+ }
31
+ }