@redhat-developer/page-objects 1.19.1 → 1.21.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/out/components/AbstractElement.d.ts +1 -1
- package/out/components/AbstractElement.js +1 -1
- package/out/components/activityBar/ActionsControl.js +1 -1
- package/out/components/activityBar/ViewControl.js +4 -4
- package/out/components/bottomBar/AbstractViews.js +2 -2
- package/out/components/bottomBar/ProblemsView.js +2 -2
- package/out/components/bottomBar/Views.js +1 -1
- package/out/components/editor/ContentAssist.js +10 -7
- package/out/components/editor/CustomEditor.js +1 -1
- package/out/components/editor/EditorAction.js +1 -1
- package/out/components/editor/SettingsEditor.js +3 -3
- package/out/components/editor/TextEditor.d.ts +1 -0
- package/out/components/editor/TextEditor.js +20 -10
- package/out/components/menu/ContextMenu.js +2 -2
- package/out/components/menu/TitleBar.js +1 -1
- package/out/components/sidebar/ViewSection.js +2 -2
- package/out/components/sidebar/ViewTitlePart.js +2 -2
- package/out/components/sidebar/debug/DebugView.d.ts +10 -0
- package/out/components/sidebar/debug/DebugView.js +45 -13
- package/out/components/sidebar/extensions/ExtensionsViewItem.js +1 -1
- package/out/components/sidebar/scm/NewScmView.js +1 -1
- package/out/components/sidebar/scm/ScmView.js +2 -2
- package/out/components/sidebar/tree/custom/CustomTreeItem.js +2 -1
- package/out/components/sidebar/tree/debug/CallStackItem.js +1 -1
- package/out/components/sidebar/tree/debug/WatchSectionItem.js +1 -1
- package/out/components/sidebar/tree/default/DefaultTreeItem.js +3 -3
- package/out/components/statusBar/StatusBar.js +2 -2
- package/out/components/workbench/Notification.js +3 -3
- package/out/components/workbench/input/Input.js +2 -2
- package/out/components/workbench/input/InputBox.js +2 -2
- package/out/components/workbench/input/QuickOpenBox.js +1 -1
- package/out/index.d.ts +2 -1
- package/out/index.js +32 -3
- package/out/locators/loader.d.ts +2 -1
- package/out/locators/loader.js +2 -2
- package/out/locators/locators.d.ts +5 -2
- package/out/locators/locators.js +2 -2
- package/package.json +4 -5
|
@@ -33,7 +33,7 @@ export interface LocatorInfo {
|
|
|
33
33
|
export declare abstract class AbstractElement extends WebElement {
|
|
34
34
|
static readonly ctlKey: string;
|
|
35
35
|
protected static driver: WebDriver;
|
|
36
|
-
protected static locators: Locators
|
|
36
|
+
protected static locators: Locators & Record<string, Record<string, unknown>>;
|
|
37
37
|
protected static versionInfo: {
|
|
38
38
|
version: string;
|
|
39
39
|
browser: string;
|
|
@@ -252,7 +252,7 @@ class AbstractElement extends selenium_webdriver_1.WebElement {
|
|
|
252
252
|
*/
|
|
253
253
|
async safeGetAttribute(name) {
|
|
254
254
|
return await this.withRecovery(async (self) => {
|
|
255
|
-
return await self.getAttribute(name);
|
|
255
|
+
return (await self.getAttribute(name));
|
|
256
256
|
});
|
|
257
257
|
}
|
|
258
258
|
}
|
|
@@ -36,7 +36,7 @@ class ActionsControl extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
36
36
|
* Returns the title of the associated action
|
|
37
37
|
*/
|
|
38
38
|
async getTitle() {
|
|
39
|
-
return await this.getAttribute('aria-label');
|
|
39
|
+
return (await this.getAttribute('aria-label'));
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
exports.ActionsControl = ActionsControl;
|
|
@@ -34,12 +34,12 @@ class ViewControl extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
34
34
|
*/
|
|
35
35
|
async openView() {
|
|
36
36
|
// Check whether view is already open
|
|
37
|
-
const klass = await this.getAttribute(ViewControl.locators.ViewControl.attribute);
|
|
37
|
+
const klass = (await this.getAttribute(ViewControl.locators.ViewControl.attribute));
|
|
38
38
|
if (klass.indexOf(ViewControl.locators.ViewControl.klass) < 0) {
|
|
39
39
|
await this.click();
|
|
40
40
|
// Wait for view to be marked as active
|
|
41
41
|
await this.getWaitHelper().forCondition(async () => {
|
|
42
|
-
const newKlass = await this.getAttribute(ViewControl.locators.ViewControl.attribute);
|
|
42
|
+
const newKlass = (await this.getAttribute(ViewControl.locators.ViewControl.attribute));
|
|
43
43
|
return newKlass.includes(ViewControl.locators.ViewControl.klass);
|
|
44
44
|
}, { timeout: 2000, pollInterval: 100 });
|
|
45
45
|
}
|
|
@@ -60,7 +60,7 @@ class ViewControl extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
60
60
|
* @returns Promise resolving when the view closes
|
|
61
61
|
*/
|
|
62
62
|
async closeView() {
|
|
63
|
-
const klass = await this.getAttribute(ViewControl.locators.ViewControl.attribute);
|
|
63
|
+
const klass = (await this.getAttribute(ViewControl.locators.ViewControl.attribute));
|
|
64
64
|
if (klass.indexOf(ViewControl.locators.ViewControl.klass) > -1) {
|
|
65
65
|
await this.click();
|
|
66
66
|
}
|
|
@@ -70,7 +70,7 @@ class ViewControl extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
70
70
|
*/
|
|
71
71
|
async getTitle() {
|
|
72
72
|
const badge = await this.findElement(ViewControl.locators.ViewControl.badge);
|
|
73
|
-
return await badge.getAttribute('aria-label');
|
|
73
|
+
return (await badge.getAttribute('aria-label'));
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
exports.ViewControl = ViewControl;
|
|
@@ -35,7 +35,7 @@ class ChannelView extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
35
35
|
await Promise.all(elements.map(async (element) => {
|
|
36
36
|
const disabled = await element.getAttribute('disabled');
|
|
37
37
|
if (!disabled) {
|
|
38
|
-
names.push(await element.getAttribute('value'));
|
|
38
|
+
names.push((await element.getAttribute('value')));
|
|
39
39
|
}
|
|
40
40
|
}));
|
|
41
41
|
return names;
|
|
@@ -50,7 +50,7 @@ class ChannelView extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
50
50
|
throw Error(`DEPRECATED METHOD! The 'ChannelView.getCurrentChannel' method is broken! Read more information in 'Known Issues > Limitations in testing with VS Code 1.87+' - https://github.com/microsoft/vscode/issues/206897.`);
|
|
51
51
|
}
|
|
52
52
|
const combo = await this.enclosingItem.findElement(ChannelView.locators.BottomBarViews.channelCombo);
|
|
53
|
-
return await combo.getAttribute(ChannelView.locators.OutputView.currentChannelAttribute);
|
|
53
|
+
return (await combo.getAttribute(ChannelView.locators.OutputView.currentChannelAttribute));
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* Select a channel using the selector combo
|
|
@@ -125,7 +125,7 @@ class Marker extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
125
125
|
* @returns Promise resolving to a Marker row text
|
|
126
126
|
*/
|
|
127
127
|
async getText() {
|
|
128
|
-
return await this.getAttribute(ProblemsView.locators.ProblemsView.rowLabel);
|
|
128
|
+
return (await this.getAttribute(ProblemsView.locators.ProblemsView.rowLabel));
|
|
129
129
|
}
|
|
130
130
|
/**
|
|
131
131
|
* Get the Marker label text
|
|
@@ -141,7 +141,7 @@ class Marker extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
141
141
|
*/
|
|
142
142
|
async toggleExpand(expand) {
|
|
143
143
|
if ((await this.getType()) === MarkerType.File) {
|
|
144
|
-
const klass = await this.findElement(ProblemsView.locators.ProblemsView.markerTwistie).getAttribute('class');
|
|
144
|
+
const klass = (await this.findElement(ProblemsView.locators.ProblemsView.markerTwistie).getAttribute('class'));
|
|
145
145
|
if (klass.indexOf('collapsed') > -1 === expand) {
|
|
146
146
|
await this.click();
|
|
147
147
|
}
|
|
@@ -226,7 +226,7 @@ class TerminalView extends AbstractViews_1.ChannelView {
|
|
|
226
226
|
const rows = await list.findElements(TerminalView.locators.TerminalView.row);
|
|
227
227
|
for (const row of rows) {
|
|
228
228
|
const label = await row.getAttribute('aria-label');
|
|
229
|
-
if (label
|
|
229
|
+
if (label?.includes(channelNumber)) {
|
|
230
230
|
await row.click();
|
|
231
231
|
return;
|
|
232
232
|
}
|
|
@@ -63,7 +63,7 @@ class ContentAssist extends __1.Menu {
|
|
|
63
63
|
async getItems() {
|
|
64
64
|
await this.getDriver().wait(async () => {
|
|
65
65
|
return await this.isLoaded();
|
|
66
|
-
});
|
|
66
|
+
}, 10000);
|
|
67
67
|
const elements = await this.findElement(ContentAssist.locators.ContentAssist.itemRows).findElements(ContentAssist.locators.ContentAssist.itemRow);
|
|
68
68
|
const items = [];
|
|
69
69
|
for (const item of elements) {
|
|
@@ -84,12 +84,15 @@ class ContentAssist extends __1.Menu {
|
|
|
84
84
|
* to false otherwise
|
|
85
85
|
*/
|
|
86
86
|
async isLoaded() {
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
const messages = await this.findElements(ContentAssist.locators.ContentAssist.message);
|
|
88
|
+
if (messages.length === 0) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
if (await messages[0].isDisplayed()) {
|
|
92
|
+
const text = await messages[0].getText();
|
|
93
|
+
// Empty message means loaded; "No suggestions" is also a terminal state.
|
|
94
|
+
// Any other non-empty text (e.g. "Loading...") means still loading.
|
|
95
|
+
return text === '' || text.startsWith('No suggestions');
|
|
93
96
|
}
|
|
94
97
|
return true;
|
|
95
98
|
}
|
|
@@ -26,7 +26,7 @@ class BaseEditorAction extends ActionButtonElementDropdown_1.ActionButtonElement
|
|
|
26
26
|
* Get text description of the action.
|
|
27
27
|
*/
|
|
28
28
|
async getTitle() {
|
|
29
|
-
return await this.getAttribute(BaseEditorAction.locators.EditorView.attribute);
|
|
29
|
+
return (await this.getAttribute(BaseEditorAction.locators.EditorView.attribute));
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
class EditorAction extends BaseEditorAction {
|
|
@@ -203,7 +203,7 @@ exports.Setting = Setting;
|
|
|
203
203
|
class ComboSetting extends Setting {
|
|
204
204
|
async getValue() {
|
|
205
205
|
const combo = await this.findElement(SettingsEditor.locators.SettingsEditor.comboSetting);
|
|
206
|
-
return await combo.getAttribute(SettingsEditor.locators.SettingsEditor.comboValue);
|
|
206
|
+
return (await combo.getAttribute(SettingsEditor.locators.SettingsEditor.comboValue));
|
|
207
207
|
}
|
|
208
208
|
async setValue(value) {
|
|
209
209
|
const rows = await this.getOptions();
|
|
@@ -233,7 +233,7 @@ class ComboSetting extends Setting {
|
|
|
233
233
|
const rows = await this.getOptions();
|
|
234
234
|
for (const row of rows) {
|
|
235
235
|
try {
|
|
236
|
-
values.push(await row.getAttribute(SettingsEditor.locators.SettingsEditor.comboValue));
|
|
236
|
+
values.push((await row.getAttribute(SettingsEditor.locators.SettingsEditor.comboValue)));
|
|
237
237
|
}
|
|
238
238
|
catch (e) {
|
|
239
239
|
if (e.name === 'StaleElementReferenceError') {
|
|
@@ -256,7 +256,7 @@ exports.ComboSetting = ComboSetting;
|
|
|
256
256
|
class TextSetting extends Setting {
|
|
257
257
|
async getValue() {
|
|
258
258
|
const input = await this.findElement(SettingsEditor.locators.SettingsEditor.textSetting);
|
|
259
|
-
return await input.getAttribute('value');
|
|
259
|
+
return (await input.getAttribute('value'));
|
|
260
260
|
}
|
|
261
261
|
async setValue(value) {
|
|
262
262
|
const input = await this.findElement(SettingsEditor.locators.SettingsEditor.textSetting);
|
|
@@ -223,6 +223,7 @@ export declare class TextEditor extends Editor {
|
|
|
223
223
|
* **Caution** line & column coordinates do not start at `0` but at `1`!
|
|
224
224
|
*/
|
|
225
225
|
getCoordinates(): Promise<[number, number]>;
|
|
226
|
+
private getTabSize;
|
|
226
227
|
/**
|
|
227
228
|
* Toggle breakpoint on a given line
|
|
228
229
|
*
|
|
@@ -40,7 +40,7 @@ class TextEditor extends Editor_1.Editor {
|
|
|
40
40
|
*/
|
|
41
41
|
async isDirty() {
|
|
42
42
|
const tab = await this.enclosingItem.findElement(TextEditor.locators.TextEditor.activeTab);
|
|
43
|
-
const klass = await tab.getAttribute('class');
|
|
43
|
+
const klass = (await tab.getAttribute('class'));
|
|
44
44
|
return klass.indexOf('dirty') >= 0;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
@@ -67,7 +67,7 @@ class TextEditor extends Editor_1.Editor {
|
|
|
67
67
|
*/
|
|
68
68
|
async getFileUri() {
|
|
69
69
|
const ed = await this.findElement(TextEditor.locators.TextEditor.editorContainer);
|
|
70
|
-
return await ed.getAttribute(TextEditor.locators.TextEditor.dataUri);
|
|
70
|
+
return (await ed.getAttribute(TextEditor.locators.TextEditor.dataUri));
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
73
73
|
* Retrieve the path to the file opened in the active editor
|
|
@@ -87,7 +87,7 @@ class TextEditor extends Editor_1.Editor {
|
|
|
87
87
|
let isHidden = true;
|
|
88
88
|
try {
|
|
89
89
|
const assist = await self.findElement(TextEditor.locators.ContentAssist.constructor);
|
|
90
|
-
const klass = await assist.getAttribute('class');
|
|
90
|
+
const klass = (await assist.getAttribute('class'));
|
|
91
91
|
const visibility = await assist.getCssValue('visibility');
|
|
92
92
|
isHidden = klass.indexOf('visible') < 0 || visibility === 'hidden';
|
|
93
93
|
}
|
|
@@ -236,7 +236,7 @@ class TextEditor extends Editor_1.Editor {
|
|
|
236
236
|
if (lineNum < 1) {
|
|
237
237
|
throw new Error(`Text '${text}' not found`);
|
|
238
238
|
}
|
|
239
|
-
await this.
|
|
239
|
+
await this.setCursor(lineNum, column);
|
|
240
240
|
let actions = this.getDriver().actions();
|
|
241
241
|
await actions.clear();
|
|
242
242
|
actions.keyDown(selenium_webdriver_1.Key.SHIFT);
|
|
@@ -320,7 +320,7 @@ class TextEditor extends Editor_1.Editor {
|
|
|
320
320
|
* @returns Promise resolving when the text is typed in
|
|
321
321
|
*/
|
|
322
322
|
async typeTextAt(line, column, text) {
|
|
323
|
-
await this.
|
|
323
|
+
await this.setCursor(line, column);
|
|
324
324
|
await this.typeText(text);
|
|
325
325
|
}
|
|
326
326
|
/**
|
|
@@ -489,11 +489,15 @@ class TextEditor extends Editor_1.Editor {
|
|
|
489
489
|
let column = -1;
|
|
490
490
|
let found = 0;
|
|
491
491
|
const lines = (await this.getText()).split('\n');
|
|
492
|
+
const tabSize = await this.getTabSize();
|
|
492
493
|
for (let i = 0; i < lines.length; i++) {
|
|
493
494
|
let searchIndex = -1; // start at the beginning of the line
|
|
494
495
|
while ((searchIndex = lines[i].indexOf(text, searchIndex)) > -1) {
|
|
495
496
|
found++;
|
|
496
|
-
|
|
497
|
+
// Compute offset for tabs
|
|
498
|
+
const nTabs = lines[i].substring(0, searchIndex + 1).split('\t').length - 1;
|
|
499
|
+
const tabOffset = nTabs * (tabSize - 1); // 1 character per tab has already been counted ('\t') - now offset for the tab size
|
|
500
|
+
column = searchIndex + 1 + tabOffset;
|
|
497
501
|
line = i + 1;
|
|
498
502
|
if (found >= occurrence) {
|
|
499
503
|
return [line, column];
|
|
@@ -559,6 +563,12 @@ class TextEditor extends Editor_1.Editor {
|
|
|
559
563
|
}
|
|
560
564
|
return [coords[0], coords[1]];
|
|
561
565
|
}
|
|
566
|
+
async getTabSize() {
|
|
567
|
+
const statusBar = new StatusBar_1.StatusBar();
|
|
568
|
+
const indent = await statusBar.getCurrentIndentation();
|
|
569
|
+
const matches = indent.match(/\d+/g);
|
|
570
|
+
return +matches[0];
|
|
571
|
+
}
|
|
562
572
|
/**
|
|
563
573
|
* Toggle breakpoint on a given line
|
|
564
574
|
*
|
|
@@ -795,7 +805,7 @@ class CodeLens extends AbstractElement_1.AbstractElement {
|
|
|
795
805
|
* @returns tooltip as string
|
|
796
806
|
*/
|
|
797
807
|
async getTooltip() {
|
|
798
|
-
return await this.getAttribute('title');
|
|
808
|
+
return (await this.getAttribute('title'));
|
|
799
809
|
}
|
|
800
810
|
}
|
|
801
811
|
exports.CodeLens = CodeLens;
|
|
@@ -817,7 +827,7 @@ class FindWidget extends AbstractElement_1.AbstractElement {
|
|
|
817
827
|
*/
|
|
818
828
|
async toggleReplace(replace) {
|
|
819
829
|
const btn = await this.findElement(FindWidget.locators.FindWidget.toggleReplace);
|
|
820
|
-
const klass = await btn.getAttribute('class');
|
|
830
|
+
const klass = (await btn.getAttribute('class'));
|
|
821
831
|
if ((replace && klass.includes('collapsed')) || (!replace && !klass.includes('collapsed'))) {
|
|
822
832
|
await btn.sendKeys(selenium_webdriver_1.Key.SPACE);
|
|
823
833
|
const repl = await this.getDriver().wait(selenium_webdriver_1.until.elementLocated(FindWidget.locators.FindWidget.replacePart), 2000);
|
|
@@ -843,7 +853,7 @@ class FindWidget extends AbstractElement_1.AbstractElement {
|
|
|
843
853
|
*/
|
|
844
854
|
async getSearchText() {
|
|
845
855
|
const findPart = await this.findElement(FindWidget.locators.FindWidget.findPart);
|
|
846
|
-
return await this.getInputText(findPart);
|
|
856
|
+
return (await this.getInputText(findPart));
|
|
847
857
|
}
|
|
848
858
|
/**
|
|
849
859
|
* Set text in the replace box. Will toggle replace mode on if called in find mode.
|
|
@@ -860,7 +870,7 @@ class FindWidget extends AbstractElement_1.AbstractElement {
|
|
|
860
870
|
*/
|
|
861
871
|
async getReplaceText() {
|
|
862
872
|
const replacePart = await this.findElement(FindWidget.locators.FindWidget.replacePart);
|
|
863
|
-
return await this.getInputText(replacePart);
|
|
873
|
+
return (await this.getInputText(replacePart));
|
|
864
874
|
}
|
|
865
875
|
/**
|
|
866
876
|
* Click 'Next match'
|
|
@@ -61,7 +61,7 @@ class ContextMenu extends __1.Menu {
|
|
|
61
61
|
const elements = await this.findElements(ContextMenu.locators.ContextMenu.itemElement);
|
|
62
62
|
for (const element of elements) {
|
|
63
63
|
try {
|
|
64
|
-
const klass = await element.getAttribute('class');
|
|
64
|
+
const klass = (await element.getAttribute('class'));
|
|
65
65
|
if (klass.indexOf('disabled') < 0) {
|
|
66
66
|
items.push(await new ContextMenuItem(element, this).wait());
|
|
67
67
|
}
|
|
@@ -158,7 +158,7 @@ class ContextMenuItem extends __1.MenuItem {
|
|
|
158
158
|
}
|
|
159
159
|
async getLabel() {
|
|
160
160
|
const labelItem = await this.findElement(ContextMenu.locators.ContextMenu.itemLabel);
|
|
161
|
-
return await labelItem.getAttribute(ContextMenu.locators.ContextMenu.itemText);
|
|
161
|
+
return (await labelItem.getAttribute(ContextMenu.locators.ContextMenu.itemText));
|
|
162
162
|
}
|
|
163
163
|
async isNesting() {
|
|
164
164
|
try {
|
|
@@ -52,7 +52,7 @@ class TitleBar extends Menu_1.Menu {
|
|
|
52
52
|
for (const element of elements) {
|
|
53
53
|
try {
|
|
54
54
|
if (await element.isDisplayed()) {
|
|
55
|
-
items.push(await new TitleBarItem(await element.getAttribute(TitleBar.locators.TitleBar.itemLabel), this).wait());
|
|
55
|
+
items.push(await new TitleBarItem((await element.getAttribute(TitleBar.locators.TitleBar.itemLabel)), this).wait());
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
catch (e) {
|
|
@@ -35,7 +35,7 @@ class ViewSection extends AbstractElement_1.AbstractElement {
|
|
|
35
35
|
*/
|
|
36
36
|
async getTitle() {
|
|
37
37
|
const title = await this.findElement(ViewSection.locators.ViewSection.title);
|
|
38
|
-
return await title.getAttribute(ViewSection.locators.ViewSection.titleText);
|
|
38
|
+
return (await title.getAttribute(ViewSection.locators.ViewSection.titleText));
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* Expand the section if collapsed
|
|
@@ -186,7 +186,7 @@ class BaseViewPanelAction extends ActionButtonElementDropdown_1.ActionButtonElem
|
|
|
186
186
|
* Get label of the action button
|
|
187
187
|
*/
|
|
188
188
|
async getLabel() {
|
|
189
|
-
return await this.getAttribute(BaseViewPanelAction.locators.ViewSection.buttonLabel);
|
|
189
|
+
return (await this.getAttribute(BaseViewPanelAction.locators.ViewSection.buttonLabel));
|
|
190
190
|
}
|
|
191
191
|
/**
|
|
192
192
|
* Wait for the action button to be located within a given timeout.
|
|
@@ -42,7 +42,7 @@ class ViewTitlePart extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
42
42
|
const actions = [];
|
|
43
43
|
const elements = await this.findElements(ViewTitlePart.locators.ViewTitlePart.action);
|
|
44
44
|
for (const element of elements) {
|
|
45
|
-
const title = await element.getAttribute(ViewTitlePart.locators.ViewTitlePart.actionLabel);
|
|
45
|
+
const title = (await element.getAttribute(ViewTitlePart.locators.ViewTitlePart.actionLabel));
|
|
46
46
|
actions.push(await new TitleActionButton(TitleActionButton.locators.ViewTitlePart.actionConstructor(title), this).wait());
|
|
47
47
|
}
|
|
48
48
|
return actions;
|
|
@@ -68,7 +68,7 @@ class TitleActionButton extends AbstractElement_1.AbstractElement {
|
|
|
68
68
|
* Get title of the button
|
|
69
69
|
*/
|
|
70
70
|
async getTitle() {
|
|
71
|
-
return await this.getAttribute(TitleActionButton.locators.ViewTitlePart.actionLabel);
|
|
71
|
+
return (await this.getAttribute(TitleActionButton.locators.ViewTitlePart.actionLabel));
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
exports.TitleActionButton = TitleActionButton;
|
|
@@ -45,6 +45,16 @@ export declare class DebugView extends SideBarView {
|
|
|
45
45
|
* @param title title of the configuration to select
|
|
46
46
|
*/
|
|
47
47
|
selectLaunchConfiguration(title: string): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Opens the launch config dropdown overlay, waiting until it is visible.
|
|
50
|
+
* If it is already open (context-view-pointerBlock present) the click is skipped.
|
|
51
|
+
* @returns the context-view element to scope subsequent searches against
|
|
52
|
+
*/
|
|
53
|
+
private openLaunchDropdown;
|
|
54
|
+
/**
|
|
55
|
+
* Closes the launch config dropdown by sending Escape to the filter input that holds focus.
|
|
56
|
+
*/
|
|
57
|
+
private closeLaunchDropdown;
|
|
48
58
|
/**
|
|
49
59
|
* Start Debugging using the current launch configuration
|
|
50
60
|
*/
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.DebugView = void 0;
|
|
20
20
|
const compare_versions_1 = require("compare-versions");
|
|
21
|
+
const selenium_webdriver_1 = require("selenium-webdriver");
|
|
21
22
|
const SideBarView_1 = require("../SideBarView");
|
|
22
23
|
const DebugBreakpointSection_1 = require("../tree/debug/DebugBreakpointSection");
|
|
23
24
|
const DebugCallStackSection_1 = require("../tree/debug/DebugCallStackSection");
|
|
@@ -34,26 +35,22 @@ class DebugView extends SideBarView_1.SideBarView {
|
|
|
34
35
|
*/
|
|
35
36
|
async getLaunchConfiguration() {
|
|
36
37
|
if ((0, compare_versions_1.satisfies)(DebugView.versionInfo.version, '>=1.87.0') && process.platform !== 'darwin') {
|
|
37
|
-
throw Error(`DEPRECATED METHOD! The 'DebugView.getLaunchConfiguration' method is broken! Read more information in 'Known Issues > Limitations in testing with VS Code 1.87+' - https://github.com/microsoft/vscode/issues/206897.`);
|
|
38
|
+
throw new Error(`DEPRECATED METHOD! The 'DebugView.getLaunchConfiguration' method is broken! Read more information in 'Known Issues > Limitations in testing with VS Code 1.87+' - https://github.com/microsoft/vscode/issues/206897.`);
|
|
38
39
|
}
|
|
39
40
|
const action = await this.getTitlePart().findElement(DebugView.locators.DebugView.launchCombo);
|
|
40
|
-
|
|
41
|
-
return await combo.getAttribute(DebugView.locators.DebugView.launchSelectAttribute);
|
|
41
|
+
return await action.getText();
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
44
|
* Get titles of all available launch configurations
|
|
45
45
|
* @returns Promise resolving to list of titles
|
|
46
46
|
*/
|
|
47
47
|
async getLaunchConfigurations() {
|
|
48
|
-
const
|
|
49
|
-
const combo = await action.findElement(DebugView.locators.DebugView.launchSelect);
|
|
48
|
+
const contextView = await this.openLaunchDropdown();
|
|
50
49
|
const configs = [];
|
|
51
|
-
const options = await
|
|
50
|
+
const options = await contextView.findElements(DebugView.locators.DebugView.launchOption);
|
|
52
51
|
for (const option of options) {
|
|
53
52
|
try {
|
|
54
|
-
|
|
55
|
-
configs.push(await option.getAttribute('value'));
|
|
56
|
-
}
|
|
53
|
+
configs.push((await option.getAttribute(DebugView.locators.DebugView.launchSelectAttribute)));
|
|
57
54
|
}
|
|
58
55
|
catch (e) {
|
|
59
56
|
if (e.name === 'StaleElementReferenceError') {
|
|
@@ -62,6 +59,7 @@ class DebugView extends SideBarView_1.SideBarView {
|
|
|
62
59
|
throw e;
|
|
63
60
|
}
|
|
64
61
|
}
|
|
62
|
+
await this.closeLaunchDropdown();
|
|
65
63
|
return configs;
|
|
66
64
|
}
|
|
67
65
|
async getVariablesSection() {
|
|
@@ -81,10 +79,44 @@ class DebugView extends SideBarView_1.SideBarView {
|
|
|
81
79
|
* @param title title of the configuration to select
|
|
82
80
|
*/
|
|
83
81
|
async selectLaunchConfiguration(title) {
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
const contextView = await this.openLaunchDropdown();
|
|
83
|
+
const option = await contextView.findElement(DebugView.locators.DebugView.optionByName(title));
|
|
84
|
+
// context-view-pointerBlock overlays the list and intercepts regular clicks —
|
|
85
|
+
// use JavaScript click to bypass it.
|
|
86
|
+
await this.getDriver().executeScript('arguments[0].click()', option);
|
|
87
|
+
// Wait for the overlay to be dismissed so subsequent operations are not blocked.
|
|
88
|
+
await this.getDriver()
|
|
89
|
+
.wait(selenium_webdriver_1.until.elementIsNotVisible(contextView), 2000)
|
|
90
|
+
.catch(() => {
|
|
91
|
+
// If already gone, that's fine.
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Opens the launch config dropdown overlay, waiting until it is visible.
|
|
96
|
+
* If it is already open (context-view-pointerBlock present) the click is skipped.
|
|
97
|
+
* @returns the context-view element to scope subsequent searches against
|
|
98
|
+
*/
|
|
99
|
+
async openLaunchDropdown() {
|
|
100
|
+
// context-view persists in the DOM between uses (display:none when closed).
|
|
101
|
+
// Only click to open if it is not currently visible.
|
|
102
|
+
const existingViews = await this.getDriver().findElements(DebugView.locators.ContextMenu.contextView);
|
|
103
|
+
const isOpen = existingViews.length > 0 && (await existingViews[0].isDisplayed());
|
|
104
|
+
if (!isOpen) {
|
|
105
|
+
const action = await this.getTitlePart().findElement(DebugView.locators.DebugView.launchCombo);
|
|
106
|
+
await action.click();
|
|
107
|
+
}
|
|
108
|
+
const contextView = await this.getDriver().wait(selenium_webdriver_1.until.elementLocated(DebugView.locators.ContextMenu.contextView), 2000);
|
|
109
|
+
await this.getDriver().wait(selenium_webdriver_1.until.elementIsVisible(contextView), 2000);
|
|
110
|
+
// Wait until at least one option row is present inside the overlay
|
|
111
|
+
await this.getDriver().wait(async () => (await contextView.findElements(DebugView.locators.DebugView.launchOption)).length > 0, 2000);
|
|
112
|
+
return contextView;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Closes the launch config dropdown by sending Escape to the filter input that holds focus.
|
|
116
|
+
*/
|
|
117
|
+
async closeLaunchDropdown() {
|
|
118
|
+
const input = await this.getDriver().findElement(selenium_webdriver_1.By.className('action-list-filter-input'));
|
|
119
|
+
await input.sendKeys('\uE00C'); // Escape
|
|
88
120
|
}
|
|
89
121
|
/**
|
|
90
122
|
* Start Debugging using the current launch configuration
|
|
@@ -42,7 +42,7 @@ class ExtensionsViewItem extends ViewItem_1.ViewItem {
|
|
|
42
42
|
if (version.length > 0) {
|
|
43
43
|
return await version[0].getText();
|
|
44
44
|
}
|
|
45
|
-
const label = await this.getAttribute('aria-label');
|
|
45
|
+
const label = (await this.getAttribute('aria-label'));
|
|
46
46
|
const ver = label.split(',')[1].trim();
|
|
47
47
|
return ver;
|
|
48
48
|
}
|
|
@@ -64,7 +64,7 @@ class SingleScmProvider extends ScmView_1.ScmProvider {
|
|
|
64
64
|
const buttons = [];
|
|
65
65
|
if ((0, compare_versions_1.satisfies)(ScmView_1.ScmProvider.versionInfo.version, '>=1.93.0')) {
|
|
66
66
|
actions = await this.getProviderHeaderActions(view);
|
|
67
|
-
names = await Promise.all(actions.map(async (action) => await action.getAttribute(ScmView_1.ScmProvider.locators.ScmView.actionLabel)));
|
|
67
|
+
names = await Promise.all(actions.map(async (action) => (await action.getAttribute(ScmView_1.ScmProvider.locators.ScmView.actionLabel))));
|
|
68
68
|
}
|
|
69
69
|
else {
|
|
70
70
|
const titlePart = view.getTitlePart();
|
|
@@ -75,13 +75,13 @@ class ScmProvider extends AbstractElement_1.AbstractElement {
|
|
|
75
75
|
* Get title of the scm provider
|
|
76
76
|
*/
|
|
77
77
|
async getTitle() {
|
|
78
|
-
return await this.findElement(ScmProvider.locators.ScmView.providerTitle).getAttribute('innerHTML');
|
|
78
|
+
return (await this.findElement(ScmProvider.locators.ScmView.providerTitle).getAttribute('innerHTML'));
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
81
81
|
* Get type of the scm provider (e.g. Git)
|
|
82
82
|
*/
|
|
83
83
|
async getType() {
|
|
84
|
-
return await this.findElement(ScmProvider.locators.ScmView.providerType).getAttribute('innerHTML');
|
|
84
|
+
return (await this.findElement(ScmProvider.locators.ScmView.providerType).getAttribute('innerHTML'));
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* Find an action button for the SCM provider by title and click it. (e.g 'Commit')
|
|
@@ -29,7 +29,8 @@ class CustomTreeItem extends ViewItem_1.TreeItem {
|
|
|
29
29
|
return await this.findElement(CustomTreeItem.locators.CustomTreeSection.itemLabel).getText();
|
|
30
30
|
}
|
|
31
31
|
async getTooltip() {
|
|
32
|
-
|
|
32
|
+
const resourceItem = await this.findElement(CustomTreeItem.locators.CustomTreeItem.tooltipElement);
|
|
33
|
+
return (await resourceItem.getAttribute(CustomTreeItem.locators.CustomTreeItem.tooltipAttribute));
|
|
33
34
|
}
|
|
34
35
|
async getDescription() {
|
|
35
36
|
return await this.findElement(CustomTreeItem.locators.CustomTreeItem.description).getText();
|
|
@@ -28,7 +28,7 @@ class CallStackItem extends CustomTreeItem_1.CustomTreeItem {
|
|
|
28
28
|
*/
|
|
29
29
|
async getLabel() {
|
|
30
30
|
const name = await this.findElement(CallStackItem.locators.CallStackItem.label);
|
|
31
|
-
return await name?.getAttribute('textContent');
|
|
31
|
+
return (await name?.getAttribute('textContent'));
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Get text of the Call Stack item.
|
|
@@ -28,7 +28,7 @@ class WatchSectionItem extends CustomTreeItem_1.CustomTreeItem {
|
|
|
28
28
|
*/
|
|
29
29
|
async getLabel() {
|
|
30
30
|
const name = await this.findElement(WatchSectionItem.locators.WatchSectionItem.label);
|
|
31
|
-
return await name?.getAttribute('textContent');
|
|
31
|
+
return (await name?.getAttribute('textContent'));
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Get value of the Watch section item.
|
|
@@ -35,10 +35,10 @@ class DefaultTreeItem extends ViewItem_1.TreeItem {
|
|
|
35
35
|
}
|
|
36
36
|
async getTooltip() {
|
|
37
37
|
const tooltip = await this.findElement(DefaultTreeItem.locators.DefaultTreeItem.tooltip);
|
|
38
|
-
return await tooltip.getAttribute(DefaultTreeItem.locators.DefaultTreeItem.labelAttribute);
|
|
38
|
+
return (await tooltip.getAttribute(DefaultTreeItem.locators.DefaultTreeItem.labelAttribute));
|
|
39
39
|
}
|
|
40
40
|
async isExpanded() {
|
|
41
|
-
const twistieClass = await this.findElement(DefaultTreeItem.locators.DefaultTreeItem.twistie).getAttribute('class');
|
|
41
|
+
const twistieClass = (await this.findElement(DefaultTreeItem.locators.DefaultTreeItem.twistie).getAttribute('class'));
|
|
42
42
|
return twistieClass.indexOf('collapsed') < 0;
|
|
43
43
|
}
|
|
44
44
|
async getChildren() {
|
|
@@ -47,7 +47,7 @@ class DefaultTreeItem extends ViewItem_1.TreeItem {
|
|
|
47
47
|
return items;
|
|
48
48
|
}
|
|
49
49
|
async isExpandable() {
|
|
50
|
-
const twistieClass = await this.findElement(DefaultTreeItem.locators.DefaultTreeItem.twistie).getAttribute('class');
|
|
50
|
+
const twistieClass = (await this.findElement(DefaultTreeItem.locators.DefaultTreeItem.twistie).getAttribute('class'));
|
|
51
51
|
return twistieClass.indexOf('collapsible') > -1;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -157,7 +157,7 @@ class StatusBar extends AbstractElement_1.AbstractElement {
|
|
|
157
157
|
async toggleNotificationsCentre(open) {
|
|
158
158
|
let visible = false;
|
|
159
159
|
try {
|
|
160
|
-
const klass = await this.enclosingItem.findElement(StatusBar.locators.StatusBar.notifications).getAttribute('class');
|
|
160
|
+
const klass = (await this.enclosingItem.findElement(StatusBar.locators.StatusBar.notifications).getAttribute('class'));
|
|
161
161
|
visible = klass.indexOf('visible') > -1;
|
|
162
162
|
}
|
|
163
163
|
catch (err) {
|
|
@@ -168,7 +168,7 @@ class StatusBar extends AbstractElement_1.AbstractElement {
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
async getPartText(locator) {
|
|
171
|
-
return await this.findElement(locator).findElement(StatusBar.locators.StatusBar.aTag).getAttribute('innerHTML');
|
|
171
|
+
return (await this.findElement(locator).findElement(StatusBar.locators.StatusBar.aTag).getAttribute('innerHTML'));
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
exports.StatusBar = StatusBar;
|
|
@@ -47,7 +47,7 @@ class Notification extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
47
47
|
* @returns Promise resolving to NotificationType
|
|
48
48
|
*/
|
|
49
49
|
async getType() {
|
|
50
|
-
const iconType = await (await this.findElement(Notification.locators.Notification.icon)).getAttribute('class');
|
|
50
|
+
const iconType = (await (await this.findElement(Notification.locators.Notification.icon)).getAttribute('class'));
|
|
51
51
|
if (iconType.indexOf('icon-info') > -1) {
|
|
52
52
|
return NotificationType.Info;
|
|
53
53
|
}
|
|
@@ -68,14 +68,14 @@ class Notification extends ElementWithContextMenu_1.ElementWithContextMenu {
|
|
|
68
68
|
throw Error(`DEPRECATED METHOD! For VS Code 1.88+ this method won't be working any more.`);
|
|
69
69
|
}
|
|
70
70
|
await this.expand();
|
|
71
|
-
return await (await this.findElement(Notification.locators.Notification.source)).getAttribute('title');
|
|
71
|
+
return (await (await this.findElement(Notification.locators.Notification.source)).getAttribute('title'));
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
74
|
* Find whether the notification has an active progress bar
|
|
75
75
|
* @returns Promise resolving to true/false
|
|
76
76
|
*/
|
|
77
77
|
async hasProgress() {
|
|
78
|
-
const klass = await (await this.findElement(Notification.locators.Notification.progress)).getAttribute('class');
|
|
78
|
+
const klass = (await (await this.findElement(Notification.locators.Notification.progress)).getAttribute('class'));
|
|
79
79
|
return klass.indexOf('done') < 0;
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
@@ -31,7 +31,7 @@ class Input extends AbstractElement_1.AbstractElement {
|
|
|
31
31
|
*/
|
|
32
32
|
async getText() {
|
|
33
33
|
const input = await this.findElement(Input.locators.Input.inputBox).findElement(Input.locators.Input.input);
|
|
34
|
-
return await input.getAttribute('value');
|
|
34
|
+
return (await input.getAttribute('value'));
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Set (by selecting all and typing) text in the input field
|
|
@@ -75,7 +75,7 @@ class Input extends AbstractElement_1.AbstractElement {
|
|
|
75
75
|
* @returns Promise resolving to input placeholder
|
|
76
76
|
*/
|
|
77
77
|
async getPlaceHolder() {
|
|
78
|
-
return await this.findElement(Input.locators.Input.inputBox).findElement(Input.locators.Input.input).getAttribute('placeholder');
|
|
78
|
+
return (await this.findElement(Input.locators.Input.inputBox).findElement(Input.locators.Input.input).getAttribute('placeholder'));
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
81
81
|
* Confirm the input field by pressing Enter
|
|
@@ -42,7 +42,7 @@ class InputBox extends __1.Input {
|
|
|
42
42
|
return await this.findElement(InputBox.locators.InputBox.message).getText();
|
|
43
43
|
}
|
|
44
44
|
async hasProgress() {
|
|
45
|
-
const klass = await this.findElement(InputBox.locators.InputBox.progress).getAttribute('class');
|
|
45
|
+
const klass = (await this.findElement(InputBox.locators.InputBox.progress).getAttribute('class'));
|
|
46
46
|
return klass.indexOf('done') < 0;
|
|
47
47
|
}
|
|
48
48
|
async getQuickPicks() {
|
|
@@ -90,7 +90,7 @@ class InputBox extends __1.Input {
|
|
|
90
90
|
* @returns Promise resolving to notification message
|
|
91
91
|
*/
|
|
92
92
|
async hasError() {
|
|
93
|
-
const klass = await this.findElement(InputBox.locators.Input.inputBox).getAttribute('class');
|
|
93
|
+
const klass = (await this.findElement(InputBox.locators.Input.inputBox).getAttribute('class'));
|
|
94
94
|
return klass.indexOf('error') > -1;
|
|
95
95
|
}
|
|
96
96
|
/**
|
|
@@ -36,7 +36,7 @@ class QuickOpenBox extends __1.Input {
|
|
|
36
36
|
return new QuickOpenBox().wait();
|
|
37
37
|
}
|
|
38
38
|
async hasProgress() {
|
|
39
|
-
const klass = await this.findElement(QuickOpenBox.locators.QuickOpenBox.progress).getAttribute('class');
|
|
39
|
+
const klass = (await this.findElement(QuickOpenBox.locators.QuickOpenBox.progress).getAttribute('class'));
|
|
40
40
|
return klass.indexOf('done') < 0;
|
|
41
41
|
}
|
|
42
42
|
async getQuickPicks() {
|
package/out/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
import { WebDriver } from 'selenium-webdriver';
|
|
18
|
+
export { AbstractElement } from './components/AbstractElement';
|
|
18
19
|
export * from 'selenium-webdriver';
|
|
19
20
|
export * from './locators/locators';
|
|
20
21
|
export * from './errors/NullAttributeError';
|
|
@@ -88,4 +89,4 @@ export * from './conditions/WaitForAttribute';
|
|
|
88
89
|
* @param driver WebDriver instance
|
|
89
90
|
* @param browserID identifier/name of the browser (i.e. vscode)
|
|
90
91
|
*/
|
|
91
|
-
export declare function initPageObjects(currentVersion: string, baseVersion: string, locatorFolder: string, driver: WebDriver, browserID: string): void;
|
|
92
|
+
export declare function initPageObjects(currentVersion: string, baseVersion: string, locatorFolder: string, driver: WebDriver, browserID: string, customLocatorsPath?: string): void;
|
package/out/index.js
CHANGED
|
@@ -26,14 +26,39 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
26
26
|
if (k2 === undefined) k2 = k;
|
|
27
27
|
o[k2] = m[k];
|
|
28
28
|
}));
|
|
29
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
30
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
31
|
+
}) : function(o, v) {
|
|
32
|
+
o["default"] = v;
|
|
33
|
+
});
|
|
34
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
35
|
+
var ownKeys = function(o) {
|
|
36
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
37
|
+
var ar = [];
|
|
38
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
39
|
+
return ar;
|
|
40
|
+
};
|
|
41
|
+
return ownKeys(o);
|
|
42
|
+
};
|
|
43
|
+
return function (mod) {
|
|
44
|
+
if (mod && mod.__esModule) return mod;
|
|
45
|
+
var result = {};
|
|
46
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
47
|
+
__setModuleDefault(result, mod);
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
})();
|
|
29
51
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
30
52
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
31
53
|
};
|
|
32
54
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.NotificationType = exports.Notification = exports.ScmChange = exports.ScmProvider = exports.ScmView = void 0;
|
|
55
|
+
exports.NotificationType = exports.Notification = exports.ScmChange = exports.ScmProvider = exports.ScmView = exports.AbstractElement = void 0;
|
|
34
56
|
exports.initPageObjects = initPageObjects;
|
|
57
|
+
const path = __importStar(require("node:path"));
|
|
35
58
|
const AbstractElement_1 = require("./components/AbstractElement");
|
|
36
59
|
const loader_1 = require("./locators/loader");
|
|
60
|
+
var AbstractElement_2 = require("./components/AbstractElement");
|
|
61
|
+
Object.defineProperty(exports, "AbstractElement", { enumerable: true, get: function () { return AbstractElement_2.AbstractElement; } });
|
|
37
62
|
__exportStar(require("selenium-webdriver"), exports);
|
|
38
63
|
__exportStar(require("./locators/locators"), exports);
|
|
39
64
|
__exportStar(require("./errors/NullAttributeError"), exports);
|
|
@@ -112,8 +137,12 @@ __exportStar(require("./conditions/WaitForAttribute"), exports);
|
|
|
112
137
|
* @param driver WebDriver instance
|
|
113
138
|
* @param browserID identifier/name of the browser (i.e. vscode)
|
|
114
139
|
*/
|
|
115
|
-
function initPageObjects(currentVersion, baseVersion, locatorFolder, driver, browserID) {
|
|
116
|
-
|
|
140
|
+
function initPageObjects(currentVersion, baseVersion, locatorFolder, driver, browserID, customLocatorsPath) {
|
|
141
|
+
let locators = new loader_1.LocatorLoader(currentVersion, baseVersion, locatorFolder).loadLocators();
|
|
142
|
+
if (customLocatorsPath) {
|
|
143
|
+
const custom = require(path.resolve(customLocatorsPath));
|
|
144
|
+
locators = (0, loader_1.mergeLocators)(locators, custom);
|
|
145
|
+
}
|
|
117
146
|
AbstractElement_1.AbstractElement.init(locators, driver, browserID, currentVersion);
|
|
118
147
|
}
|
|
119
148
|
//# sourceMappingURL=index.js.map
|
package/out/locators/loader.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
|
-
import { Locators } from './locators';
|
|
17
|
+
import { Locators, LocatorDiff } from './locators';
|
|
18
18
|
/**
|
|
19
19
|
* Utility for loading locators for a given vscode version
|
|
20
20
|
*/
|
|
@@ -34,3 +34,4 @@ export declare class LocatorLoader {
|
|
|
34
34
|
*/
|
|
35
35
|
loadLocators(): Locators;
|
|
36
36
|
}
|
|
37
|
+
export declare function mergeLocators(original: Locators, diff: LocatorDiff): Locators;
|
package/out/locators/loader.js
CHANGED
|
@@ -53,6 +53,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
53
53
|
};
|
|
54
54
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
55
|
exports.LocatorLoader = void 0;
|
|
56
|
+
exports.mergeLocators = mergeLocators;
|
|
56
57
|
const fs = __importStar(require("fs-extra"));
|
|
57
58
|
const path = __importStar(require("path"));
|
|
58
59
|
const compare_versions_1 = require("compare-versions");
|
|
@@ -102,8 +103,7 @@ class LocatorLoader {
|
|
|
102
103
|
}
|
|
103
104
|
for (const version of versions) {
|
|
104
105
|
const diff = require(path.join(this.baseFolder, version)).diff;
|
|
105
|
-
|
|
106
|
-
this.locators = newLocators;
|
|
106
|
+
this.locators = mergeLocators(this.locators, diff);
|
|
107
107
|
}
|
|
108
108
|
return this.locators;
|
|
109
109
|
}
|
|
@@ -15,8 +15,10 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
import { By, IRectangle, WebElement } from 'selenium-webdriver';
|
|
18
|
-
import { PartialDeep } from 'type-fest';
|
|
19
18
|
import { ViewSection } from '../components/sidebar/ViewSection';
|
|
19
|
+
type PartialDeep<T> = T extends object ? {
|
|
20
|
+
[K in keyof T]?: PartialDeep<T[K]>;
|
|
21
|
+
} : T;
|
|
20
22
|
type WebElementFunction<E extends WebElement, T> = (element: E) => T | PromiseLike<T>;
|
|
21
23
|
type LocatorAwareWebElementFunction<T> = (element: WebElement, locator: Locators) => T | PromiseLike<T>;
|
|
22
24
|
/**
|
|
@@ -336,6 +338,7 @@ export interface Locators {
|
|
|
336
338
|
expandedAttr: string;
|
|
337
339
|
expandedValue: string;
|
|
338
340
|
tooltipAttribute: string;
|
|
341
|
+
tooltipElement: By;
|
|
339
342
|
description: By;
|
|
340
343
|
};
|
|
341
344
|
DebugBreakpointSection: {
|
|
@@ -547,7 +550,7 @@ export interface Locators {
|
|
|
547
550
|
* Definition for locator diff object
|
|
548
551
|
*/
|
|
549
552
|
export interface LocatorDiff {
|
|
550
|
-
locators: PartialDeep<Locators
|
|
553
|
+
locators: PartialDeep<Locators> & Record<string, Record<string, unknown>>;
|
|
551
554
|
extras?: object;
|
|
552
555
|
}
|
|
553
556
|
export declare function hasAttribute(attr: string, value?: string, locator?: By): (el: WebElement) => Promise<boolean>;
|
package/out/locators/locators.js
CHANGED
|
@@ -39,7 +39,7 @@ function hasClass(classOrPredicate, locator) {
|
|
|
39
39
|
const klasses = await el.getAttribute('class');
|
|
40
40
|
const segments = klasses?.split(/\s+/g);
|
|
41
41
|
const predicate = typeof classOrPredicate === 'string' ? (klass) => klass === classOrPredicate : classOrPredicate;
|
|
42
|
-
return segments
|
|
42
|
+
return segments?.find(predicate) !== undefined;
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
function hasNotClass(klass, locator) {
|
|
@@ -56,7 +56,7 @@ function hasElement(locatorSelector) {
|
|
|
56
56
|
function fromAttribute(attribute, locator) {
|
|
57
57
|
return async (el) => {
|
|
58
58
|
el = locator ? await el.findElement(locator) : el;
|
|
59
|
-
return await el.getAttribute(attribute);
|
|
59
|
+
return (await el.getAttribute(attribute));
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
function fromText(locator) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redhat-developer/page-objects",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"description": "Page Object API implementation for a VS Code editor used by ExTester framework.",
|
|
5
5
|
"main": "out/index.js",
|
|
6
6
|
"types": "out/index.d.ts",
|
|
@@ -37,15 +37,14 @@
|
|
|
37
37
|
"ui-test"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"clipboardy": "^5.3.
|
|
40
|
+
"clipboardy": "^5.3.2",
|
|
41
41
|
"clone-deep": "^4.0.1",
|
|
42
42
|
"compare-versions": "^6.1.1",
|
|
43
|
-
"fs-extra": "^11.
|
|
44
|
-
"type-fest": "^4.41.0"
|
|
43
|
+
"fs-extra": "^11.4.0"
|
|
45
44
|
},
|
|
46
45
|
"peerDependencies": {
|
|
47
46
|
"selenium-webdriver": ">=4.6.1",
|
|
48
47
|
"typescript": ">=4.6.2"
|
|
49
48
|
},
|
|
50
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "d3ed855411fdff9575ce7d7e8a65faa70a08349f"
|
|
51
50
|
}
|