@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.
- package/LICENSE +202 -0
- package/README.md +5 -0
- package/out/components/AbstractElement.d.ts +35 -0
- package/out/components/AbstractElement.js +69 -0
- package/out/components/ElementWithContextMenu.d.ts +11 -0
- package/out/components/ElementWithContextMenu.js +38 -0
- package/out/components/WebviewMixin.d.ts +29 -0
- package/out/components/WebviewMixin.js +70 -0
- package/out/components/activityBar/ActionsControl.d.ts +18 -0
- package/out/components/activityBar/ActionsControl.js +27 -0
- package/out/components/activityBar/ActivityBar.d.ts +30 -0
- package/out/components/activityBar/ActivityBar.js +71 -0
- package/out/components/activityBar/ViewControl.d.ts +23 -0
- package/out/components/activityBar/ViewControl.js +56 -0
- package/out/components/bottomBar/AbstractViews.d.ts +38 -0
- package/out/components/bottomBar/AbstractViews.js +88 -0
- package/out/components/bottomBar/BottomBarPanel.d.ts +47 -0
- package/out/components/bottomBar/BottomBarPanel.js +123 -0
- package/out/components/bottomBar/ProblemsView.d.ts +88 -0
- package/out/components/bottomBar/ProblemsView.js +149 -0
- package/out/components/bottomBar/Views.d.ts +75 -0
- package/out/components/bottomBar/Views.js +195 -0
- package/out/components/bottomBar/WebviewView.d.ts +12 -0
- package/out/components/bottomBar/WebviewView.js +21 -0
- package/out/components/dialog/ModalDialog.d.ts +32 -0
- package/out/components/dialog/ModalDialog.js +56 -0
- package/out/components/editor/Breakpoint.d.ts +18 -0
- package/out/components/editor/Breakpoint.js +38 -0
- package/out/components/editor/ContentAssist.d.ts +34 -0
- package/out/components/editor/ContentAssist.js +94 -0
- package/out/components/editor/CustomEditor.d.ts +26 -0
- package/out/components/editor/CustomEditor.js +45 -0
- package/out/components/editor/DiffEditor.d.ts +19 -0
- package/out/components/editor/DiffEditor.js +31 -0
- package/out/components/editor/Editor.d.ts +17 -0
- package/out/components/editor/Editor.js +29 -0
- package/out/components/editor/EditorAction.d.ts +10 -0
- package/out/components/editor/EditorAction.js +17 -0
- package/out/components/editor/EditorView.d.ts +153 -0
- package/out/components/editor/EditorView.js +350 -0
- package/out/components/editor/SettingsEditor.d.ts +121 -0
- package/out/components/editor/SettingsEditor.js +278 -0
- package/out/components/editor/TextEditor.d.ts +265 -0
- package/out/components/editor/TextEditor.js +707 -0
- package/out/components/editor/WebView.d.ts +11 -0
- package/out/components/editor/WebView.js +38 -0
- package/out/components/menu/ContextMenu.d.ts +37 -0
- package/out/components/menu/ContextMenu.js +123 -0
- package/out/components/menu/MacTitleBar.d.ts +16 -0
- package/out/components/menu/MacTitleBar.js +41 -0
- package/out/components/menu/Menu.d.ts +38 -0
- package/out/components/menu/Menu.js +53 -0
- package/out/components/menu/MenuItem.d.ts +24 -0
- package/out/components/menu/MenuItem.js +36 -0
- package/out/components/menu/TitleBar.d.ts +36 -0
- package/out/components/menu/TitleBar.js +78 -0
- package/out/components/menu/WindowControls.d.ts +28 -0
- package/out/components/menu/WindowControls.js +59 -0
- package/out/components/sidebar/SideBarView.d.ts +18 -0
- package/out/components/sidebar/SideBarView.js +29 -0
- package/out/components/sidebar/ViewContent.d.ts +57 -0
- package/out/components/sidebar/ViewContent.js +76 -0
- package/out/components/sidebar/ViewItem.d.ts +97 -0
- package/out/components/sidebar/ViewItem.js +192 -0
- package/out/components/sidebar/ViewSection.d.ts +98 -0
- package/out/components/sidebar/ViewSection.js +164 -0
- package/out/components/sidebar/ViewTitlePart.d.ts +35 -0
- package/out/components/sidebar/ViewTitlePart.js +59 -0
- package/out/components/sidebar/WelcomeContent.d.ts +47 -0
- package/out/components/sidebar/WelcomeContent.js +72 -0
- package/out/components/sidebar/debug/DebugView.d.ts +33 -0
- package/out/components/sidebar/debug/DebugView.js +70 -0
- package/out/components/sidebar/extensions/ExtensionsViewItem.d.ts +48 -0
- package/out/components/sidebar/extensions/ExtensionsViewItem.js +93 -0
- package/out/components/sidebar/extensions/ExtensionsViewSection.d.ts +33 -0
- package/out/components/sidebar/extensions/ExtensionsViewSection.js +117 -0
- package/out/components/sidebar/scm/NewScmView.d.ts +34 -0
- package/out/components/sidebar/scm/NewScmView.js +155 -0
- package/out/components/sidebar/scm/ScmView.d.ts +110 -0
- package/out/components/sidebar/scm/ScmView.js +275 -0
- package/out/components/sidebar/tree/TreeSection.d.ts +14 -0
- package/out/components/sidebar/tree/TreeSection.js +55 -0
- package/out/components/sidebar/tree/custom/CustomTreeItem.d.ts +15 -0
- package/out/components/sidebar/tree/custom/CustomTreeItem.js +36 -0
- package/out/components/sidebar/tree/custom/CustomTreeSection.d.ts +26 -0
- package/out/components/sidebar/tree/custom/CustomTreeSection.js +66 -0
- package/out/components/sidebar/tree/debug/BreakpointSectionItem.d.ts +33 -0
- package/out/components/sidebar/tree/debug/BreakpointSectionItem.js +63 -0
- package/out/components/sidebar/tree/debug/DebugBreakpointSection.d.ts +7 -0
- package/out/components/sidebar/tree/debug/DebugBreakpointSection.js +12 -0
- package/out/components/sidebar/tree/debug/DebugVariablesSection.d.ts +7 -0
- package/out/components/sidebar/tree/debug/DebugVariablesSection.js +12 -0
- package/out/components/sidebar/tree/debug/SectionBreakpoint.d.ts +3 -0
- package/out/components/sidebar/tree/debug/SectionBreakpoint.js +8 -0
- package/out/components/sidebar/tree/debug/VariableSectionItem.d.ts +33 -0
- package/out/components/sidebar/tree/debug/VariableSectionItem.js +60 -0
- package/out/components/sidebar/tree/default/DefaultTreeItem.d.ts +14 -0
- package/out/components/sidebar/tree/default/DefaultTreeItem.js +39 -0
- package/out/components/sidebar/tree/default/DefaultTreeSection.d.ts +9 -0
- package/out/components/sidebar/tree/default/DefaultTreeSection.js +44 -0
- package/out/components/statusBar/StatusBar.d.ts +96 -0
- package/out/components/statusBar/StatusBar.js +159 -0
- package/out/components/workbench/DebugToolbar.d.ts +52 -0
- package/out/components/workbench/DebugToolbar.js +93 -0
- package/out/components/workbench/Notification.d.ts +78 -0
- package/out/components/workbench/Notification.js +134 -0
- package/out/components/workbench/NotificationsCenter.d.ts +27 -0
- package/out/components/workbench/NotificationsCenter.js +57 -0
- package/out/components/workbench/Workbench.d.ts +69 -0
- package/out/components/workbench/Workbench.js +135 -0
- package/out/components/workbench/input/Input.d.ts +107 -0
- package/out/components/workbench/input/Input.js +249 -0
- package/out/components/workbench/input/InputBox.d.ts +30 -0
- package/out/components/workbench/input/InputBox.js +75 -0
- package/out/components/workbench/input/QuickOpenBox.d.ts +15 -0
- package/out/components/workbench/input/QuickOpenBox.js +41 -0
- package/out/conditions/WaitForAttribute.d.ts +8 -0
- package/out/conditions/WaitForAttribute.js +17 -0
- package/out/errors/NullAttributeError.d.ts +3 -0
- package/out/errors/NullAttributeError.js +11 -0
- package/out/index.d.ts +67 -0
- package/out/index.js +95 -0
- package/out/locators/loader.d.ts +20 -0
- package/out/locators/loader.js +108 -0
- package/out/locators/locators.d.ts +463 -0
- package/out/locators/locators.js +52 -0
- 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
|