@redhat-developer/page-objects 1.0.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.
Files changed (127) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +5 -0
  3. package/out/components/AbstractElement.d.ts +35 -0
  4. package/out/components/AbstractElement.js +69 -0
  5. package/out/components/ElementWithContextMenu.d.ts +11 -0
  6. package/out/components/ElementWithContextMenu.js +38 -0
  7. package/out/components/WebviewMixin.d.ts +29 -0
  8. package/out/components/WebviewMixin.js +70 -0
  9. package/out/components/activityBar/ActionsControl.d.ts +18 -0
  10. package/out/components/activityBar/ActionsControl.js +27 -0
  11. package/out/components/activityBar/ActivityBar.d.ts +30 -0
  12. package/out/components/activityBar/ActivityBar.js +71 -0
  13. package/out/components/activityBar/ViewControl.d.ts +23 -0
  14. package/out/components/activityBar/ViewControl.js +56 -0
  15. package/out/components/bottomBar/AbstractViews.d.ts +38 -0
  16. package/out/components/bottomBar/AbstractViews.js +88 -0
  17. package/out/components/bottomBar/BottomBarPanel.d.ts +47 -0
  18. package/out/components/bottomBar/BottomBarPanel.js +123 -0
  19. package/out/components/bottomBar/ProblemsView.d.ts +88 -0
  20. package/out/components/bottomBar/ProblemsView.js +149 -0
  21. package/out/components/bottomBar/Views.d.ts +75 -0
  22. package/out/components/bottomBar/Views.js +195 -0
  23. package/out/components/bottomBar/WebviewView.d.ts +12 -0
  24. package/out/components/bottomBar/WebviewView.js +21 -0
  25. package/out/components/dialog/ModalDialog.d.ts +32 -0
  26. package/out/components/dialog/ModalDialog.js +56 -0
  27. package/out/components/editor/Breakpoint.d.ts +18 -0
  28. package/out/components/editor/Breakpoint.js +38 -0
  29. package/out/components/editor/ContentAssist.d.ts +34 -0
  30. package/out/components/editor/ContentAssist.js +94 -0
  31. package/out/components/editor/CustomEditor.d.ts +26 -0
  32. package/out/components/editor/CustomEditor.js +45 -0
  33. package/out/components/editor/DiffEditor.d.ts +19 -0
  34. package/out/components/editor/DiffEditor.js +31 -0
  35. package/out/components/editor/Editor.d.ts +17 -0
  36. package/out/components/editor/Editor.js +29 -0
  37. package/out/components/editor/EditorAction.d.ts +10 -0
  38. package/out/components/editor/EditorAction.js +17 -0
  39. package/out/components/editor/EditorView.d.ts +153 -0
  40. package/out/components/editor/EditorView.js +350 -0
  41. package/out/components/editor/SettingsEditor.d.ts +121 -0
  42. package/out/components/editor/SettingsEditor.js +278 -0
  43. package/out/components/editor/TextEditor.d.ts +265 -0
  44. package/out/components/editor/TextEditor.js +707 -0
  45. package/out/components/editor/WebView.d.ts +11 -0
  46. package/out/components/editor/WebView.js +38 -0
  47. package/out/components/menu/ContextMenu.d.ts +37 -0
  48. package/out/components/menu/ContextMenu.js +123 -0
  49. package/out/components/menu/MacTitleBar.d.ts +16 -0
  50. package/out/components/menu/MacTitleBar.js +41 -0
  51. package/out/components/menu/Menu.d.ts +38 -0
  52. package/out/components/menu/Menu.js +53 -0
  53. package/out/components/menu/MenuItem.d.ts +24 -0
  54. package/out/components/menu/MenuItem.js +36 -0
  55. package/out/components/menu/TitleBar.d.ts +36 -0
  56. package/out/components/menu/TitleBar.js +78 -0
  57. package/out/components/menu/WindowControls.d.ts +28 -0
  58. package/out/components/menu/WindowControls.js +59 -0
  59. package/out/components/sidebar/SideBarView.d.ts +18 -0
  60. package/out/components/sidebar/SideBarView.js +29 -0
  61. package/out/components/sidebar/ViewContent.d.ts +57 -0
  62. package/out/components/sidebar/ViewContent.js +76 -0
  63. package/out/components/sidebar/ViewItem.d.ts +97 -0
  64. package/out/components/sidebar/ViewItem.js +192 -0
  65. package/out/components/sidebar/ViewSection.d.ts +98 -0
  66. package/out/components/sidebar/ViewSection.js +164 -0
  67. package/out/components/sidebar/ViewTitlePart.d.ts +35 -0
  68. package/out/components/sidebar/ViewTitlePart.js +59 -0
  69. package/out/components/sidebar/WelcomeContent.d.ts +47 -0
  70. package/out/components/sidebar/WelcomeContent.js +72 -0
  71. package/out/components/sidebar/debug/DebugView.d.ts +33 -0
  72. package/out/components/sidebar/debug/DebugView.js +70 -0
  73. package/out/components/sidebar/extensions/ExtensionsViewItem.d.ts +48 -0
  74. package/out/components/sidebar/extensions/ExtensionsViewItem.js +93 -0
  75. package/out/components/sidebar/extensions/ExtensionsViewSection.d.ts +33 -0
  76. package/out/components/sidebar/extensions/ExtensionsViewSection.js +117 -0
  77. package/out/components/sidebar/scm/NewScmView.d.ts +34 -0
  78. package/out/components/sidebar/scm/NewScmView.js +155 -0
  79. package/out/components/sidebar/scm/ScmView.d.ts +110 -0
  80. package/out/components/sidebar/scm/ScmView.js +275 -0
  81. package/out/components/sidebar/tree/TreeSection.d.ts +14 -0
  82. package/out/components/sidebar/tree/TreeSection.js +55 -0
  83. package/out/components/sidebar/tree/custom/CustomTreeItem.d.ts +15 -0
  84. package/out/components/sidebar/tree/custom/CustomTreeItem.js +36 -0
  85. package/out/components/sidebar/tree/custom/CustomTreeSection.d.ts +26 -0
  86. package/out/components/sidebar/tree/custom/CustomTreeSection.js +66 -0
  87. package/out/components/sidebar/tree/debug/BreakpointSectionItem.d.ts +33 -0
  88. package/out/components/sidebar/tree/debug/BreakpointSectionItem.js +63 -0
  89. package/out/components/sidebar/tree/debug/DebugBreakpointSection.d.ts +7 -0
  90. package/out/components/sidebar/tree/debug/DebugBreakpointSection.js +12 -0
  91. package/out/components/sidebar/tree/debug/DebugVariablesSection.d.ts +7 -0
  92. package/out/components/sidebar/tree/debug/DebugVariablesSection.js +12 -0
  93. package/out/components/sidebar/tree/debug/SectionBreakpoint.d.ts +3 -0
  94. package/out/components/sidebar/tree/debug/SectionBreakpoint.js +8 -0
  95. package/out/components/sidebar/tree/debug/VariableSectionItem.d.ts +33 -0
  96. package/out/components/sidebar/tree/debug/VariableSectionItem.js +60 -0
  97. package/out/components/sidebar/tree/default/DefaultTreeItem.d.ts +14 -0
  98. package/out/components/sidebar/tree/default/DefaultTreeItem.js +39 -0
  99. package/out/components/sidebar/tree/default/DefaultTreeSection.d.ts +9 -0
  100. package/out/components/sidebar/tree/default/DefaultTreeSection.js +44 -0
  101. package/out/components/statusBar/StatusBar.d.ts +96 -0
  102. package/out/components/statusBar/StatusBar.js +159 -0
  103. package/out/components/workbench/DebugToolbar.d.ts +52 -0
  104. package/out/components/workbench/DebugToolbar.js +93 -0
  105. package/out/components/workbench/Notification.d.ts +78 -0
  106. package/out/components/workbench/Notification.js +134 -0
  107. package/out/components/workbench/NotificationsCenter.d.ts +27 -0
  108. package/out/components/workbench/NotificationsCenter.js +57 -0
  109. package/out/components/workbench/Workbench.d.ts +69 -0
  110. package/out/components/workbench/Workbench.js +135 -0
  111. package/out/components/workbench/input/Input.d.ts +107 -0
  112. package/out/components/workbench/input/Input.js +249 -0
  113. package/out/components/workbench/input/InputBox.d.ts +30 -0
  114. package/out/components/workbench/input/InputBox.js +75 -0
  115. package/out/components/workbench/input/QuickOpenBox.d.ts +15 -0
  116. package/out/components/workbench/input/QuickOpenBox.js +41 -0
  117. package/out/conditions/WaitForAttribute.d.ts +8 -0
  118. package/out/conditions/WaitForAttribute.js +17 -0
  119. package/out/errors/NullAttributeError.d.ts +3 -0
  120. package/out/errors/NullAttributeError.js +11 -0
  121. package/out/index.d.ts +67 -0
  122. package/out/index.js +95 -0
  123. package/out/locators/loader.d.ts +20 -0
  124. package/out/locators/loader.js +108 -0
  125. package/out/locators/locators.d.ts +463 -0
  126. package/out/locators/locators.js +52 -0
  127. package/package.json +48 -0
@@ -0,0 +1,707 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FindWidget = exports.CodeLens = exports.TextEditor = exports.BreakpointError = void 0;
4
+ const __1 = require("../..");
5
+ const selenium_webdriver_1 = require("selenium-webdriver");
6
+ const url_1 = require("url");
7
+ const StatusBar_1 = require("../statusBar/StatusBar");
8
+ const Editor_1 = require("./Editor");
9
+ const ElementWithContextMenu_1 = require("../ElementWithContextMenu");
10
+ const AbstractElement_1 = require("../AbstractElement");
11
+ const Breakpoint_1 = require("./Breakpoint");
12
+ class BreakpointError extends Error {
13
+ }
14
+ exports.BreakpointError = BreakpointError;
15
+ /**
16
+ * Page object representing the active text editor
17
+ */
18
+ class TextEditor extends Editor_1.Editor {
19
+ breakPoints = [];
20
+ /**
21
+ * Find whether the active editor has unsaved changes
22
+ * @returns Promise resolving to true/false
23
+ */
24
+ async isDirty() {
25
+ const tab = await this.enclosingItem.findElement(TextEditor.locators.TextEditor.activeTab);
26
+ const klass = await tab.getAttribute('class');
27
+ return klass.indexOf('dirty') >= 0;
28
+ }
29
+ /**
30
+ * Saves the active editor
31
+ * @returns Promise resolving when ctrl+s is invoked
32
+ */
33
+ async save() {
34
+ const inputarea = await this.findElement(TextEditor.locators.Editor.inputArea);
35
+ await inputarea.sendKeys(selenium_webdriver_1.Key.chord(TextEditor.ctlKey, 's'));
36
+ }
37
+ /**
38
+ * Open the Save as prompt
39
+ *
40
+ * @returns InputBox serving as a simple file dialog
41
+ */
42
+ async saveAs() {
43
+ const tab = await this.getTab();
44
+ await tab.sendKeys(selenium_webdriver_1.Key.chord(TextEditor.ctlKey, selenium_webdriver_1.Key.SHIFT, 's'));
45
+ return await __1.InputBox.create();
46
+ }
47
+ /**
48
+ * Retrieve the Uri of the file opened in the active editor
49
+ * @returns Promise resolving to editor's underlying Uri
50
+ */
51
+ async getFileUri() {
52
+ const ed = await this.findElement(TextEditor.locators.TextEditor.editorContainer);
53
+ return await ed.getAttribute(TextEditor.locators.TextEditor.dataUri);
54
+ }
55
+ /**
56
+ * Retrieve the path to the file opened in the active editor
57
+ * @returns Promise resolving to editor's underlying file path
58
+ */
59
+ async getFilePath() {
60
+ return (0, url_1.fileURLToPath)(await this.getFileUri());
61
+ }
62
+ /**
63
+ * Open/Close the content assistant at the current position in the editor by sending the default
64
+ * keyboard shortcut signal
65
+ * @param open true to open, false to close
66
+ * @returns Promise resolving to ContentAssist object when opening, void otherwise
67
+ */
68
+ async toggleContentAssist(open) {
69
+ let isHidden = true;
70
+ try {
71
+ const assist = await this.findElement(TextEditor.locators.ContentAssist.constructor);
72
+ const klass = await assist.getAttribute('class');
73
+ const visibility = await assist.getCssValue('visibility');
74
+ isHidden = klass.indexOf('visible') < 0 || visibility === 'hidden';
75
+ }
76
+ catch (err) {
77
+ isHidden = true;
78
+ }
79
+ const inputarea = await this.findElement(TextEditor.locators.Editor.inputArea);
80
+ if (open) {
81
+ if (isHidden) {
82
+ await inputarea.sendKeys(selenium_webdriver_1.Key.chord(selenium_webdriver_1.Key.CONTROL, selenium_webdriver_1.Key.SPACE));
83
+ await this.getDriver().wait(selenium_webdriver_1.until.elementLocated(TextEditor.locators.ContentAssist.constructor), 2000);
84
+ }
85
+ const assist = await new __1.ContentAssist(this).wait();
86
+ await this.getDriver().wait(() => { return assist.isLoaded(); }, 10000);
87
+ return assist;
88
+ }
89
+ else {
90
+ if (!isHidden) {
91
+ await inputarea.sendKeys(selenium_webdriver_1.Key.ESCAPE);
92
+ }
93
+ }
94
+ }
95
+ /**
96
+ * Get all text from the editor
97
+ * @returns Promise resolving to editor text
98
+ */
99
+ async getText() {
100
+ const clipboard = (await import('clipboardy')).default;
101
+ let originalClipboard = '';
102
+ try {
103
+ originalClipboard = clipboard.readSync();
104
+ }
105
+ catch (error) {
106
+ // workaround issue https://github.com/redhat-developer/vscode-extension-tester/issues/835
107
+ // do not fail if clipboard is empty
108
+ }
109
+ const inputarea = await this.findElement(TextEditor.locators.Editor.inputArea);
110
+ await inputarea.sendKeys(selenium_webdriver_1.Key.chord(TextEditor.ctlKey, 'a'), selenium_webdriver_1.Key.chord(TextEditor.ctlKey, 'c'));
111
+ await new Promise(res => setTimeout(res, 500));
112
+ const text = clipboard.readSync();
113
+ await inputarea.sendKeys(selenium_webdriver_1.Key.UP);
114
+ if (originalClipboard.length > 0) {
115
+ clipboard.writeSync(originalClipboard);
116
+ }
117
+ return text;
118
+ }
119
+ /**
120
+ * Replace the contents of the editor with a given text
121
+ * @param text text to type into the editor
122
+ * @param formatText format the new text, default false
123
+ * @returns Promise resolving once the new text is copied over
124
+ */
125
+ async setText(text, formatText = false) {
126
+ const clipboard = (await import('clipboardy')).default;
127
+ let originalClipboard = '';
128
+ try {
129
+ originalClipboard = clipboard.readSync();
130
+ }
131
+ catch (error) {
132
+ // workaround issue https://github.com/redhat-developer/vscode-extension-tester/issues/835
133
+ // do not fail if clipboard is empty
134
+ }
135
+ const inputarea = await this.findElement(TextEditor.locators.Editor.inputArea);
136
+ clipboard.writeSync(text);
137
+ await inputarea.sendKeys(selenium_webdriver_1.Key.chord(TextEditor.ctlKey, 'a'), selenium_webdriver_1.Key.chord(TextEditor.ctlKey, 'v'));
138
+ if (originalClipboard.length > 0) {
139
+ clipboard.writeSync(originalClipboard);
140
+ }
141
+ if (formatText) {
142
+ await this.formatDocument();
143
+ }
144
+ }
145
+ /**
146
+ * Deletes all text within the editor
147
+ * @returns Promise resolving once the text is deleted
148
+ */
149
+ async clearText() {
150
+ const inputarea = await this.findElement(TextEditor.locators.Editor.inputArea);
151
+ await inputarea.sendKeys(selenium_webdriver_1.Key.chord(TextEditor.ctlKey, 'a'));
152
+ await inputarea.sendKeys(selenium_webdriver_1.Key.BACK_SPACE);
153
+ }
154
+ /**
155
+ * Get text from a given line
156
+ * @param line number of the line to retrieve
157
+ * @returns Promise resolving to text at the given line number
158
+ */
159
+ async getTextAtLine(line) {
160
+ const text = await this.getText();
161
+ const lines = text.split('\n');
162
+ if (line < 1 || line > lines.length) {
163
+ throw new Error(`Line number ${line} does not exist`);
164
+ }
165
+ return lines[line - 1];
166
+ }
167
+ /**
168
+ * Replace the contents of a line with a given text
169
+ * @param line number of the line to edit
170
+ * @param text text to set at the line
171
+ * @returns Promise resolving when the text is typed in
172
+ */
173
+ async setTextAtLine(line, text) {
174
+ if (line < 1 || line > await this.getNumberOfLines()) {
175
+ throw new Error(`Line number ${line} does not exist`);
176
+ }
177
+ const lines = (await this.getText()).split('\n');
178
+ lines[line - 1] = text;
179
+ await this.setText(lines.join('\n'));
180
+ }
181
+ /**
182
+ * Get line number that contains the given text. Not suitable for multi line inputs.
183
+ *
184
+ * @param text text to search for
185
+ * @param occurrence select which occurrence of the search text to look for in case there are multiple in the document, defaults to 1 (the first instance)
186
+ *
187
+ * @returns Number of the line that contains the start of the given text. -1 if no such text is found.
188
+ * If occurrence number is specified, searches until it finds as many instances of the given text.
189
+ * Returns the line number that holds the last occurrence found this way.
190
+ */
191
+ async getLineOfText(text, occurrence = 1) {
192
+ let lineNum = -1;
193
+ let found = 0;
194
+ const lines = (await this.getText()).split('\n');
195
+ for (let i = 0; i < lines.length; i++) {
196
+ if (lines[i].includes(text)) {
197
+ found++;
198
+ lineNum = i + 1;
199
+ if (found >= occurrence) {
200
+ break;
201
+ }
202
+ }
203
+ }
204
+ return lineNum;
205
+ }
206
+ /**
207
+ * Find and select a given text. Not usable for multi line selection.
208
+ *
209
+ * @param text text to select
210
+ * @param occurrence specify which onccurrence of text to select if multiple are present in the document
211
+ */
212
+ async selectText(text, occurrence = 1) {
213
+ const lineNum = await this.getLineOfText(text, occurrence);
214
+ if (lineNum < 1) {
215
+ throw new Error(`Text '${text}' not found`);
216
+ }
217
+ const line = await this.getTextAtLine(lineNum);
218
+ const column = line.indexOf(text) + 1;
219
+ await this.moveCursor(lineNum, column);
220
+ let actions = this.getDriver().actions();
221
+ await actions.clear();
222
+ actions.keyDown(selenium_webdriver_1.Key.SHIFT);
223
+ for (const _i of text) {
224
+ actions = actions.sendKeys(selenium_webdriver_1.Key.RIGHT);
225
+ }
226
+ actions = actions.keyUp(selenium_webdriver_1.Key.SHIFT);
227
+ await actions.perform();
228
+ await new Promise(res => setTimeout(res, 500));
229
+ }
230
+ /**
231
+ * Get the text that is currently selected as string
232
+ */
233
+ async getSelectedText() {
234
+ const clipboard = (await import('clipboardy')).default;
235
+ let originalClipboard = '';
236
+ try {
237
+ originalClipboard = clipboard.readSync();
238
+ }
239
+ catch (error) {
240
+ // workaround issue https://github.com/redhat-developer/vscode-extension-tester/issues/835
241
+ // do not fail if clipboard is empty
242
+ }
243
+ if (process.platform !== 'darwin') {
244
+ const selection = await this.getSelection();
245
+ if (!selection) {
246
+ return '';
247
+ }
248
+ const menu = await selection.openContextMenu();
249
+ await menu.select('Copy');
250
+ }
251
+ else {
252
+ const inputarea = await this.findElement(TextEditor.locators.Editor.inputArea);
253
+ await inputarea.sendKeys(selenium_webdriver_1.Key.chord(TextEditor.ctlKey, 'c'));
254
+ await new Promise(res => setTimeout(res, 500));
255
+ await inputarea.sendKeys(selenium_webdriver_1.Key.UP);
256
+ }
257
+ await new Promise(res => setTimeout(res, 500));
258
+ const text = clipboard.readSync();
259
+ if (originalClipboard.length > 0) {
260
+ clipboard.writeSync(originalClipboard);
261
+ }
262
+ return text;
263
+ }
264
+ /**
265
+ * Get the selection block as a page object
266
+ * @returns Selection page object
267
+ */
268
+ async getSelection() {
269
+ const selection = await this.findElements(TextEditor.locators.TextEditor.selection);
270
+ if (selection.length < 1) {
271
+ return undefined;
272
+ }
273
+ return new Selection(selection[0], this);
274
+ }
275
+ async openFindWidget() {
276
+ let actions = this.getDriver().actions();
277
+ await actions.clear();
278
+ await actions.keyDown(TextEditor.ctlKey).sendKeys('f').keyUp(TextEditor.ctlKey).perform();
279
+ const widget = await this.getDriver().wait(selenium_webdriver_1.until.elementLocated(TextEditor.locators.TextEditor.findWidget), 2000);
280
+ await this.getDriver().wait(selenium_webdriver_1.until.elementIsVisible(widget), 2000);
281
+ return new FindWidget(widget, this);
282
+ }
283
+ /**
284
+ * Add the given text to the given coordinates
285
+ * @param line number of the line to type into
286
+ * @param column number of the column to start typing at
287
+ * @param text text to add
288
+ * @returns Promise resolving when the text is typed in
289
+ */
290
+ async typeTextAt(line, column, text) {
291
+ await this.moveCursor(line, column);
292
+ await this.typeText(text);
293
+ }
294
+ /**
295
+ * Type given text at the current coordinates
296
+ * @param text text to type
297
+ * @returns promise resolving when the text is typed in
298
+ */
299
+ async typeText(text) {
300
+ const inputarea = await this.findElement(TextEditor.locators.Editor.inputArea);
301
+ await inputarea.sendKeys(text);
302
+ }
303
+ /**
304
+ * Move the cursor to the given coordinates
305
+ * @param line line number to move to
306
+ * @param column column number to move to
307
+ * @returns Promise resolving when the cursor has reached the given coordinates
308
+ */
309
+ async moveCursor(line, column) {
310
+ if (line < 1 || line > await this.getNumberOfLines()) {
311
+ throw new Error(`Line number ${line} does not exist`);
312
+ }
313
+ if (column < 1) {
314
+ throw new Error(`Column number ${column} does not exist`);
315
+ }
316
+ if (process.platform === 'darwin') {
317
+ const input = await new __1.Workbench().openCommandPrompt();
318
+ await input.setText(`:${line},${column}`);
319
+ await input.confirm();
320
+ }
321
+ else {
322
+ const inputarea = await this.findElement(TextEditor.locators.Editor.inputArea);
323
+ let coordinates = await this.getCoordinates();
324
+ const lineGap = coordinates[0] - line;
325
+ const lineKey = lineGap >= 0 ? selenium_webdriver_1.Key.UP : selenium_webdriver_1.Key.DOWN;
326
+ for (let i = 0; i < Math.abs(lineGap); i++) {
327
+ await inputarea.sendKeys(lineKey);
328
+ }
329
+ coordinates = await this.getCoordinates();
330
+ const columnGap = coordinates[1] - column;
331
+ const columnKey = columnGap >= 0 ? selenium_webdriver_1.Key.LEFT : selenium_webdriver_1.Key.RIGHT;
332
+ for (let i = 0; i < Math.abs(columnGap); i++) {
333
+ await inputarea.sendKeys(columnKey);
334
+ let actualCoordinates = (await this.getCoordinates())[0];
335
+ if (actualCoordinates != coordinates[0]) {
336
+ throw new Error(`Column number ${column} is not accessible on line ${line}`);
337
+ }
338
+ }
339
+ }
340
+ await this.getDriver().wait(async () => {
341
+ const coor = await this.getCoordinates();
342
+ return coor[0] === line && coor[1] === column;
343
+ }, 10000, `Unable to set cursor at position ${column}:${line}`);
344
+ }
345
+ /**
346
+ * Get number of lines in the editor
347
+ * @returns Promise resolving to number of lines
348
+ */
349
+ async getNumberOfLines() {
350
+ const lines = (await this.getText()).split('\n');
351
+ return lines.length;
352
+ }
353
+ /**
354
+ * Use the built-in 'Format Document' option to format the text
355
+ * @returns Promise resolving when the Format Document command is invoked
356
+ */
357
+ async formatDocument() {
358
+ const menu = await this.openContextMenu();
359
+ try {
360
+ await menu.select('Format Document');
361
+ }
362
+ catch (err) {
363
+ console.log('Warn: Format Document not available for selected language');
364
+ if (await menu.isDisplayed()) {
365
+ await menu.close();
366
+ }
367
+ }
368
+ }
369
+ async openContextMenu() {
370
+ await this.getDriver().actions().contextClick(this).perform();
371
+ const shadowRootHost = await this.enclosingItem.findElements(selenium_webdriver_1.By.className('shadow-root-host'));
372
+ if (shadowRootHost.length > 0) {
373
+ let shadowRoot;
374
+ const webdriverCapabilities = await this.getDriver().getCapabilities();
375
+ const chromiumVersion = webdriverCapabilities.getBrowserVersion();
376
+ if (chromiumVersion && parseInt(chromiumVersion.split('.')[0]) >= 96) {
377
+ shadowRoot = await shadowRootHost[0].getShadowRoot();
378
+ return new __1.ContextMenu(await shadowRoot.findElement(selenium_webdriver_1.By.className('monaco-menu-container'))).wait();
379
+ }
380
+ else {
381
+ shadowRoot = await this.getDriver().executeScript('return arguments[0].shadowRoot', shadowRootHost[0]);
382
+ return new __1.ContextMenu(shadowRoot).wait();
383
+ }
384
+ }
385
+ return await super.openContextMenu();
386
+ }
387
+ /**
388
+ * Get the cursor's coordinates as an array of two numbers: `[line, column]`
389
+ *
390
+ * **Caution** line & column coordinates do not start at `0` but at `1`!
391
+ */
392
+ async getCoordinates() {
393
+ const coords = [];
394
+ const statusBar = new StatusBar_1.StatusBar();
395
+ const coordinates = (await statusBar.getCurrentPosition()).match(/\d+/g);
396
+ for (const c of coordinates) {
397
+ coords.push(+c);
398
+ }
399
+ return [coords[0], coords[1]];
400
+ }
401
+ /**
402
+ * Toggle breakpoint on a given line
403
+ *
404
+ * @param line target line number
405
+ * @returns promise resolving to True when a breakpoint was added, False when removed
406
+ */
407
+ async toggleBreakpoint(line) {
408
+ const margin = await this.findElement(TextEditor.locators.TextEditor.marginArea);
409
+ const lineNum = await margin.findElement(TextEditor.locators.TextEditor.lineNumber(line));
410
+ await this.getDriver().actions().move({ origin: lineNum }).perform();
411
+ const lineOverlay = await margin.findElement(TextEditor.locators.TextEditor.lineOverlay(line));
412
+ const breakpointContainer = TextEditor.versionInfo.version >= '1.80.0' ? await this.findElement(selenium_webdriver_1.By.className('glyph-margin-widgets')) : lineOverlay;
413
+ const breakPoint = await breakpointContainer.findElements(TextEditor.locators.TextEditor.breakpoint.generalSelector);
414
+ if (breakPoint.length > 0) {
415
+ if (this.breakPoints.indexOf(line) != -1) {
416
+ await breakPoint[this.breakPoints.indexOf(line)].click();
417
+ await new Promise(res => setTimeout(res, 200));
418
+ this.breakPoints.splice(this.breakPoints.indexOf(line), 1);
419
+ return false;
420
+ }
421
+ }
422
+ const noBreak = await breakpointContainer.findElements(TextEditor.locators.TextEditor.debugHint);
423
+ if (noBreak.length > 0) {
424
+ await noBreak[0].click();
425
+ await new Promise(res => setTimeout(res, 200));
426
+ this.breakPoints.push(line);
427
+ return true;
428
+ }
429
+ return false;
430
+ }
431
+ /**
432
+ * Get paused breakpoint if available. Otherwise, return undefined.
433
+ * @returns promise which resolves to either Breakpoint page object or undefined
434
+ */
435
+ async getPausedBreakpoint() {
436
+ const breakpointLocators = Breakpoint_1.Breakpoint.locators.TextEditor.breakpoint;
437
+ const breakpointContainer = TextEditor.versionInfo.version >= '1.80.0' ? await this.findElement(selenium_webdriver_1.By.className('glyph-margin-widgets')) : this;
438
+ const breakpoints = await breakpointContainer.findElements(breakpointLocators.pauseSelector);
439
+ if (breakpoints.length === 0) {
440
+ return undefined;
441
+ }
442
+ if (breakpoints.length > 1) {
443
+ throw new BreakpointError(`unexpected number of paused breakpoints: ${breakpoints.length}; expected 1 at most`);
444
+ }
445
+ // get parent
446
+ let lineElement;
447
+ if (TextEditor.versionInfo.version >= '1.80.0') {
448
+ const styleTopAttr = await breakpoints[0].getCssValue('top');
449
+ lineElement = await this.findElement(TextEditor.locators.TextEditor.marginArea).findElement(selenium_webdriver_1.By.xpath(`.//div[contains(@style, "${styleTopAttr}")]`));
450
+ }
451
+ else {
452
+ lineElement = await breakpoints[0].findElement(selenium_webdriver_1.By.xpath('./..'));
453
+ }
454
+ return new Breakpoint_1.Breakpoint(breakpoints[0], lineElement);
455
+ }
456
+ /**
457
+ * Get all code lenses within the editor
458
+ * @returns list of CodeLens page objects
459
+ */
460
+ async getCodeLenses() {
461
+ const lenses = [];
462
+ const widgets = await this.findElement(selenium_webdriver_1.By.className('contentWidgets'));
463
+ const items = await widgets.findElements(selenium_webdriver_1.By.xpath(`.//span[contains(@widgetid, 'codelens.widget')]/a[@id]`));
464
+ for (const item of items) {
465
+ lenses.push(await new CodeLens(item, this).wait());
466
+ }
467
+ return lenses;
468
+ }
469
+ /**
470
+ * Get a code lens based on title, or zero based index
471
+ *
472
+ * @param indexOrTitle zero based index (counting from the top of the editor), or partial title of the code lens
473
+ * @returns CodeLens object if such a code lens exists, undefined otherwise
474
+ */
475
+ async getCodeLens(indexOrTitle) {
476
+ const lenses = await this.getCodeLenses();
477
+ if (typeof (indexOrTitle) === 'string') {
478
+ for (const lens of lenses) {
479
+ const title = await lens.getText();
480
+ const match = title.match(indexOrTitle);
481
+ if (match && match.length > 0) {
482
+ return lens;
483
+ }
484
+ }
485
+ }
486
+ else if (lenses[indexOrTitle]) {
487
+ return lenses[indexOrTitle];
488
+ }
489
+ return undefined;
490
+ }
491
+ }
492
+ exports.TextEditor = TextEditor;
493
+ /**
494
+ * Text selection block
495
+ */
496
+ class Selection extends ElementWithContextMenu_1.ElementWithContexMenu {
497
+ constructor(el, editor) {
498
+ super(el, editor);
499
+ }
500
+ async openContextMenu() {
501
+ const ed = this.getEnclosingElement();
502
+ await this.getDriver().actions().contextClick(this).perform();
503
+ const shadowRootHost = await ed.getEnclosingElement().findElements(selenium_webdriver_1.By.className('shadow-root-host'));
504
+ if (shadowRootHost.length > 0) {
505
+ let shadowRoot;
506
+ const webdriverCapabilities = await this.getDriver().getCapabilities();
507
+ const chromiumVersion = webdriverCapabilities.getBrowserVersion();
508
+ if (chromiumVersion && parseInt(chromiumVersion.split('.')[0]) >= 96) {
509
+ shadowRoot = await shadowRootHost[0].getShadowRoot();
510
+ return new __1.ContextMenu(await shadowRoot.findElement(selenium_webdriver_1.By.className('monaco-menu-container'))).wait();
511
+ }
512
+ else {
513
+ shadowRoot = await this.getDriver().executeScript('return arguments[0].shadowRoot', shadowRootHost[0]);
514
+ return new __1.ContextMenu(shadowRoot).wait();
515
+ }
516
+ }
517
+ return await super.openContextMenu();
518
+ }
519
+ }
520
+ /**
521
+ * Page object for Code Lens inside a text editor
522
+ */
523
+ class CodeLens extends AbstractElement_1.AbstractElement {
524
+ /**
525
+ * Get tooltip of the code lens
526
+ * @returns tooltip as string
527
+ */
528
+ async getTooltip() {
529
+ return await this.getAttribute('title');
530
+ }
531
+ }
532
+ exports.CodeLens = CodeLens;
533
+ /**
534
+ * Text Editor's Find Widget
535
+ */
536
+ class FindWidget extends AbstractElement_1.AbstractElement {
537
+ constructor(element, editor) {
538
+ super(element, editor);
539
+ }
540
+ /**
541
+ * Toggle between find and replace mode
542
+ * @param replace true for replace, false for find
543
+ */
544
+ async toggleReplace(replace) {
545
+ const btn = await this.findElement(FindWidget.locators.FindWidget.toggleReplace);
546
+ const klass = await btn.getAttribute('class');
547
+ if (replace && klass.includes('collapsed') || !replace && !klass.includes('collapsed')) {
548
+ await btn.sendKeys(selenium_webdriver_1.Key.SPACE);
549
+ const repl = await this.getDriver().wait(selenium_webdriver_1.until.elementLocated(FindWidget.locators.FindWidget.replacePart), 2000);
550
+ if (replace) {
551
+ await this.getDriver().wait(selenium_webdriver_1.until.elementIsVisible(repl), 2000);
552
+ }
553
+ else {
554
+ await this.getDriver().wait(selenium_webdriver_1.until.elementIsNotVisible(repl), 2000);
555
+ }
556
+ }
557
+ }
558
+ /**
559
+ * Set text in the search box
560
+ * @param text text to fill in
561
+ */
562
+ async setSearchText(text) {
563
+ const findPart = await this.findElement(FindWidget.locators.FindWidget.findPart);
564
+ await this.setText(text, findPart);
565
+ }
566
+ /**
567
+ * Get text from Find input box
568
+ * @returns value of find input as string
569
+ */
570
+ async getSearchText() {
571
+ const findPart = await this.findElement(FindWidget.locators.FindWidget.findPart);
572
+ return await this.getInputText(findPart);
573
+ }
574
+ /**
575
+ * Set text in the replace box. Will toggle replace mode on if called in find mode.
576
+ * @param text text to fill in
577
+ */
578
+ async setReplaceText(text) {
579
+ await this.toggleReplace(true);
580
+ const replacePart = await this.findElement(FindWidget.locators.FindWidget.replacePart);
581
+ await this.setText(text, replacePart);
582
+ }
583
+ /**
584
+ * Get text from Replace input box
585
+ * @returns value of replace input as string
586
+ */
587
+ async getReplaceText() {
588
+ const replacePart = await this.findElement(FindWidget.locators.FindWidget.replacePart);
589
+ return await this.getInputText(replacePart);
590
+ }
591
+ /**
592
+ * Click 'Next match'
593
+ */
594
+ async nextMatch() {
595
+ const name = TextEditor.versionInfo.version < '1.59.0' ? 'Next match' : 'Next Match';
596
+ await this.clickButton(name, 'find');
597
+ }
598
+ /**
599
+ * Click 'Previous match'
600
+ */
601
+ async previousMatch() {
602
+ const name = TextEditor.versionInfo.version < '1.59.0' ? 'Previous match' : 'Previous Match';
603
+ await this.clickButton(name, 'find');
604
+ }
605
+ /**
606
+ * Click 'Replace'. Only works in replace mode.
607
+ */
608
+ async replace() {
609
+ await this.clickButton('Replace', 'replace');
610
+ }
611
+ /**
612
+ * Click 'Replace All'. Only works in replace mode.
613
+ */
614
+ async replaceAll() {
615
+ await this.clickButton('Replace All', 'replace');
616
+ }
617
+ /**
618
+ * Close the widget.
619
+ */
620
+ async close() {
621
+ const part = TextEditor.versionInfo.version >= '1,80.0' ? 'close' : 'find';
622
+ await this.clickButton('Close', part);
623
+ }
624
+ /**
625
+ * Get the number of results as an ordered pair of numbers
626
+ * @returns pair in form of [current result index, total number of results]
627
+ */
628
+ async getResultCount() {
629
+ const count = await this.findElement(FindWidget.locators.FindWidget.matchCount);
630
+ const text = await count.getText();
631
+ if (text.includes('No results')) {
632
+ return [0, 0];
633
+ }
634
+ const numbers = text.split(' of ');
635
+ return [+numbers[0], +numbers[1]];
636
+ }
637
+ /**
638
+ * Toggle the search to match case
639
+ * @param toggle true to turn on, false to turn off
640
+ */
641
+ async toggleMatchCase(toggle) {
642
+ await this.toggleControl('Match Case', 'find', toggle);
643
+ }
644
+ /**
645
+ * Toggle the search to match whole words
646
+ * @param toggle true to turn on, false to turn off
647
+ */
648
+ async toggleMatchWholeWord(toggle) {
649
+ await this.toggleControl('Match Whole Word', 'find', toggle);
650
+ }
651
+ /**
652
+ * Toggle the search to use regular expressions
653
+ * @param toggle true to turn on, false to turn off
654
+ */
655
+ async toggleUseRegularExpression(toggle) {
656
+ await this.toggleControl('Use Regular Expression', 'find', toggle);
657
+ }
658
+ /**
659
+ * Toggle the replace to preserve case
660
+ * @param toggle true to turn on, false to turn off
661
+ */
662
+ async togglePreserveCase(toggle) {
663
+ await this.toggleControl('Preserve Case', 'replace', toggle);
664
+ }
665
+ async toggleControl(title, part, toggle) {
666
+ let element;
667
+ if (part === 'find') {
668
+ element = await this.findElement(FindWidget.locators.FindWidget.findPart);
669
+ }
670
+ if (part === 'replace') {
671
+ element = await this.findElement(FindWidget.locators.FindWidget.replacePart);
672
+ await this.toggleReplace(true);
673
+ }
674
+ const control = await element.findElement(FindWidget.locators.FindWidget.checkbox(title));
675
+ const checked = await control.getAttribute('aria-checked');
676
+ if ((toggle && checked !== 'true') || (!toggle && checked === 'true')) {
677
+ await control.click();
678
+ }
679
+ }
680
+ async clickButton(title, part) {
681
+ let element;
682
+ if (part === 'find') {
683
+ element = await this.findElement(FindWidget.locators.FindWidget.findPart);
684
+ }
685
+ if (part === 'replace') {
686
+ element = await this.findElement(FindWidget.locators.FindWidget.replacePart);
687
+ await this.toggleReplace(true);
688
+ }
689
+ if (part === 'close') {
690
+ element = this;
691
+ }
692
+ const btn = await element.findElement(FindWidget.locators.FindWidget.button(title));
693
+ await btn.click();
694
+ await this.getDriver().sleep(100);
695
+ }
696
+ async setText(text, composite) {
697
+ const input = await composite.findElement(FindWidget.locators.FindWidget.input);
698
+ await input.clear();
699
+ await input.sendKeys(text);
700
+ }
701
+ async getInputText(composite) {
702
+ const input = await composite.findElement(FindWidget.locators.FindWidget.content);
703
+ return await input.getAttribute('innerHTML');
704
+ }
705
+ }
706
+ exports.FindWidget = FindWidget;
707
+ //# sourceMappingURL=TextEditor.js.map