@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,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MultiScmProvider = exports.SingleScmProvider = exports.NewScmView = void 0;
4
+ const ScmView_1 = require("./ScmView");
5
+ const selenium_webdriver_1 = require("selenium-webdriver");
6
+ const ElementWithContextMenu_1 = require("../../ElementWithContextMenu");
7
+ const ViewTitlePart_1 = require("../ViewTitlePart");
8
+ /**
9
+ * New SCM view for code 1.47 onwards
10
+ */
11
+ class NewScmView extends ScmView_1.ScmView {
12
+ async getProviders() {
13
+ const inputs = await this.findElements(NewScmView.locators.ScmView.inputField);
14
+ if (inputs.length < 1) {
15
+ return [];
16
+ }
17
+ const providers = await this.findElements(NewScmView.locators.ScmView.multiScmProvider);
18
+ if (inputs.length === 1 && providers.length < 1) {
19
+ const element = await this.findElement(NewScmView.locators.ScmView.singleScmProvider);
20
+ return [await new SingleScmProvider(element, this).wait()];
21
+ }
22
+ const elements = await this.findElements(NewScmView.locators.ScmView.multiProviderItem);
23
+ return await Promise.all(elements.map(async (element) => new MultiScmProvider(element, this).wait()));
24
+ }
25
+ }
26
+ exports.NewScmView = NewScmView;
27
+ /**
28
+ * Implementation for a single SCM provider
29
+ */
30
+ class SingleScmProvider extends ScmView_1.ScmProvider {
31
+ /**
32
+ * There is no title available for a single provider
33
+ */
34
+ async getTitle() {
35
+ return '';
36
+ }
37
+ /**
38
+ * No title available for single provider
39
+ */
40
+ async getType() {
41
+ return '';
42
+ }
43
+ async takeAction(title) {
44
+ const view = this.enclosingItem;
45
+ const titlePart = view.getTitlePart();
46
+ const elements = await titlePart.findElements(ScmView_1.ScmView.locators.ScmView.action);
47
+ const buttons = [];
48
+ for (const element of elements) {
49
+ const title = await element.getAttribute(ScmView_1.ScmView.locators.ScmView.actionLabel);
50
+ buttons.push(await new ViewTitlePart_1.TitleActionButton(ScmView_1.ScmView.locators.ScmView.actionConstructor(title), titlePart).wait());
51
+ }
52
+ const names = await Promise.all(buttons.map(async (button) => button.getTitle()));
53
+ const index = names.findIndex(name => name === title);
54
+ if (index > -1) {
55
+ await buttons[index].click();
56
+ return true;
57
+ }
58
+ return false;
59
+ }
60
+ async openMoreActions() {
61
+ const view = this.enclosingItem;
62
+ return await new ScmView_1.MoreAction(view).openContextMenu();
63
+ }
64
+ async getChanges(staged = false) {
65
+ const count = await this.getChangeCount(staged);
66
+ const elements = [];
67
+ if (count > 0) {
68
+ const locator = staged ? ScmView_1.ScmProvider.locators.ScmView.stagedChanges : ScmView_1.ScmProvider.locators.ScmView.changes;
69
+ const header = await this.findElement(locator);
70
+ const startIndex = +await header.getAttribute('data-index');
71
+ const depth = +await header.getAttribute('aria-level') + 1;
72
+ const items = await this.findElements(NewScmView.locators.ScmView.itemLevel(depth));
73
+ for (const item of items) {
74
+ const index = +await item.getAttribute('data-index');
75
+ if (index > startIndex && index <= startIndex + count) {
76
+ elements.push(item);
77
+ }
78
+ }
79
+ }
80
+ return Promise.all(elements.map(async (element) => new ScmView_1.ScmChange(element, this).wait()));
81
+ }
82
+ }
83
+ exports.SingleScmProvider = SingleScmProvider;
84
+ /**
85
+ * Implementation of an SCM provider when multiple providers are available
86
+ */
87
+ class MultiScmProvider extends ScmView_1.ScmProvider {
88
+ async takeAction(title) {
89
+ const actions = await this.findElements(ScmView_1.ScmProvider.locators.ScmView.action);
90
+ const names = await Promise.all(actions.map(async (action) => await action.getAttribute('title')));
91
+ const index = names.findIndex(item => item === title);
92
+ if (index > -1) {
93
+ await actions[index].click();
94
+ return true;
95
+ }
96
+ return false;
97
+ }
98
+ async openMoreActions() {
99
+ return await new MultiMoreAction(this).openContextMenu();
100
+ }
101
+ async commitChanges(message) {
102
+ const index = +await this.getAttribute('data-index') + 1;
103
+ const input = await this.enclosingItem.findElement(NewScmView.locators.ScmView.itemIndex(index));
104
+ await input.clear();
105
+ await input.sendKeys(message);
106
+ await input.sendKeys(selenium_webdriver_1.Key.chord(ScmView_1.ScmProvider.ctlKey, selenium_webdriver_1.Key.ENTER));
107
+ }
108
+ async getChanges(staged = false) {
109
+ const count = await this.getChangeCount(staged);
110
+ const elements = [];
111
+ if (count > 0) {
112
+ const index = +await this.getAttribute('data-index');
113
+ const locator = staged ? ScmView_1.ScmProvider.locators.ScmView.stagedChanges : ScmView_1.ScmProvider.locators.ScmView.changes;
114
+ const headers = await this.enclosingItem.findElements(locator);
115
+ let header;
116
+ for (const item of headers) {
117
+ if (+await item.getAttribute('data-index') > index) {
118
+ header = item;
119
+ }
120
+ }
121
+ if (!header) {
122
+ return [];
123
+ }
124
+ const startIndex = +await header.getAttribute('data-index');
125
+ const depth = +await header.getAttribute('aria-level') + 1;
126
+ const items = await this.enclosingItem.findElements(NewScmView.locators.ScmView.itemLevel(depth));
127
+ for (const item of items) {
128
+ const index = +await item.getAttribute('data-index');
129
+ if (index > startIndex && index <= startIndex + count) {
130
+ elements.push(item);
131
+ }
132
+ }
133
+ }
134
+ return await Promise.all(elements.map(async (element) => new ScmView_1.ScmChange(element, this).wait()));
135
+ }
136
+ async getChangeCount(staged = false) {
137
+ const locator = staged ? ScmView_1.ScmProvider.locators.ScmView.stagedChanges : ScmView_1.ScmProvider.locators.ScmView.changes;
138
+ const rows = await this.enclosingItem.findElements(locator);
139
+ const index = +await this.getAttribute('data-index');
140
+ for (const row of rows) {
141
+ if (+await row.getAttribute('data-index') > index) {
142
+ const count = await rows[0].findElement(ScmView_1.ScmChange.locators.ScmView.changeCount);
143
+ return +await count.getText();
144
+ }
145
+ }
146
+ return 0;
147
+ }
148
+ }
149
+ exports.MultiScmProvider = MultiScmProvider;
150
+ class MultiMoreAction extends ElementWithContextMenu_1.ElementWithContexMenu {
151
+ constructor(scm) {
152
+ super(ScmView_1.MoreAction.locators.ScmView.multiMore, scm);
153
+ }
154
+ }
155
+ //# sourceMappingURL=NewScmView.js.map
@@ -0,0 +1,110 @@
1
+ import { SideBarView } from "../SideBarView";
2
+ import { WebElement } from "selenium-webdriver";
3
+ import { AbstractElement } from "../../AbstractElement";
4
+ import { ContextMenu } from "../../..";
5
+ import { ElementWithContexMenu } from "../../ElementWithContextMenu";
6
+ /**
7
+ * Page object representing the Source Control view
8
+ */
9
+ export declare class ScmView extends SideBarView {
10
+ /**
11
+ * Get SCM provider (repository) by title
12
+ * @param title name of the repository
13
+ * @returns promise resolving to ScmProvider object
14
+ */
15
+ getProvider(title?: string): Promise<ScmProvider | undefined>;
16
+ /**
17
+ * Get all SCM providers
18
+ * @returns promise resolving to ScmProvider array
19
+ */
20
+ getProviders(): Promise<ScmProvider[]>;
21
+ /**
22
+ * Initialize repository in the current folder if no SCM provider is found
23
+ * @returns true if the action was completed succesfully, false if a provider already exists
24
+ */
25
+ initializeRepository(): Promise<boolean>;
26
+ }
27
+ /**
28
+ * Page object representing a repository in the source control view
29
+ * Maps roughly to a view section of the source control view
30
+ */
31
+ export declare class ScmProvider extends AbstractElement {
32
+ constructor(element: WebElement, view: ScmView);
33
+ /**
34
+ * Get title of the scm provider
35
+ */
36
+ getTitle(): Promise<string>;
37
+ /**
38
+ * Get type of the scm provider (e.g. Git)
39
+ */
40
+ getType(): Promise<string>;
41
+ /**
42
+ * Find an action button for the SCM provider by title and click it. (e.g 'Commit')
43
+ * @param title Title of the action button to click
44
+ * @returns true if the given action could be performed, false if the button doesn't exist
45
+ */
46
+ takeAction(title: string): Promise<boolean>;
47
+ /**
48
+ * Open a context menu using the 'More Actions...' button
49
+ * @returns Promise resolving to a ContextMenu object
50
+ */
51
+ openMoreActions(): Promise<ContextMenu>;
52
+ /**
53
+ * Fill in the message field and send ctrl/cmd + enter to commit the changes
54
+ * @param message the commit message to use
55
+ * @returns promise resolving once the keypresses are sent
56
+ */
57
+ commitChanges(message: string): Promise<void>;
58
+ /**
59
+ * Get page objects for all tree items representing individual changes
60
+ * @param staged when true, finds staged changes; otherwise finds unstaged changes
61
+ * @returns promise resolving to ScmChange object array
62
+ */
63
+ getChanges(staged?: boolean): Promise<ScmChange[]>;
64
+ /**
65
+ * Get the number of changes for a given section
66
+ * @param staged when true, counts the staged changes, unstaged otherwise
67
+ * @returns promise resolving to number of changes in the given subsection
68
+ */
69
+ getChangeCount(staged?: boolean): Promise<number>;
70
+ }
71
+ /**
72
+ * Page object representing a SCM change tree item
73
+ */
74
+ export declare class ScmChange extends ElementWithContexMenu {
75
+ constructor(row: WebElement, provider: ScmProvider);
76
+ /**
77
+ * Get label as a string
78
+ */
79
+ getLabel(): Promise<string>;
80
+ /**
81
+ * Get description as a string
82
+ */
83
+ getDescription(): Promise<string>;
84
+ /**
85
+ * Get the status string (e.g. 'Modified')
86
+ */
87
+ getStatus(): Promise<string>;
88
+ /**
89
+ * Find if the item is expanded
90
+ * @returns promise resolving to true if change is expanded, to false otherwise
91
+ */
92
+ isExpanded(): Promise<boolean>;
93
+ /**
94
+ * Expand or collapse a change item if possible, only works for folders in hierarchical view mode
95
+ * @param expand true to expand the item, false to collapse
96
+ * @returns promise resolving to true if the item changed state, to false otherwise
97
+ */
98
+ toggleExpand(expand: boolean): Promise<boolean>;
99
+ /**
100
+ * Find and click an action button available to a given change tree item
101
+ * @param title title of the action button (e.g 'Stage Changes')
102
+ * @returns promise resolving to true if the action was performed successfully,
103
+ * false if the given button does not exist
104
+ */
105
+ takeAction(title: string): Promise<boolean>;
106
+ }
107
+ export declare class MoreAction extends ElementWithContexMenu {
108
+ constructor(scm: ScmProvider | ScmView);
109
+ openContextMenu(): Promise<ContextMenu>;
110
+ }
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MoreAction = exports.ScmChange = exports.ScmProvider = exports.ScmView = void 0;
4
+ const SideBarView_1 = require("../SideBarView");
5
+ const selenium_webdriver_1 = require("selenium-webdriver");
6
+ const AbstractElement_1 = require("../../AbstractElement");
7
+ const __1 = require("../../..");
8
+ const ElementWithContextMenu_1 = require("../../ElementWithContextMenu");
9
+ /**
10
+ * Page object representing the Source Control view
11
+ */
12
+ class ScmView extends SideBarView_1.SideBarView {
13
+ /**
14
+ * Get SCM provider (repository) by title
15
+ * @param title name of the repository
16
+ * @returns promise resolving to ScmProvider object
17
+ */
18
+ async getProvider(title) {
19
+ const providers = await this.getProviders();
20
+ if (!title || providers.length === 1) {
21
+ return providers[0];
22
+ }
23
+ const names = await Promise.all(providers.map(async (item) => await item.getTitle()));
24
+ const index = names.findIndex(name => name === title);
25
+ return index > -1 ? providers[index] : undefined;
26
+ }
27
+ /**
28
+ * Get all SCM providers
29
+ * @returns promise resolving to ScmProvider array
30
+ */
31
+ async getProviders() {
32
+ const headers = await this.findElements(ScmView.locators.ScmView.providerHeader);
33
+ const sections = await Promise.all(headers.map(async (header) => await header.findElement(ScmView.locators.ScmView.providerRelative)));
34
+ return await Promise.all(sections.map(async (section) => new ScmProvider(section, this)));
35
+ }
36
+ /**
37
+ * Initialize repository in the current folder if no SCM provider is found
38
+ * @returns true if the action was completed succesfully, false if a provider already exists
39
+ */
40
+ async initializeRepository() {
41
+ const buttons = await this.findElements(ScmView.locators.ScmView.initButton);
42
+ if (buttons.length > 0) {
43
+ await buttons[0].click();
44
+ return true;
45
+ }
46
+ return false;
47
+ }
48
+ }
49
+ exports.ScmView = ScmView;
50
+ /**
51
+ * Page object representing a repository in the source control view
52
+ * Maps roughly to a view section of the source control view
53
+ */
54
+ class ScmProvider extends AbstractElement_1.AbstractElement {
55
+ constructor(element, view) {
56
+ super(element, view);
57
+ }
58
+ /**
59
+ * Get title of the scm provider
60
+ */
61
+ async getTitle() {
62
+ return await this.findElement(ScmProvider.locators.ScmView.providerTitle).getAttribute('innerHTML');
63
+ }
64
+ /**
65
+ * Get type of the scm provider (e.g. Git)
66
+ */
67
+ async getType() {
68
+ return await this.findElement(ScmProvider.locators.ScmView.providerType).getAttribute('innerHTML');
69
+ }
70
+ /**
71
+ * Find an action button for the SCM provider by title and click it. (e.g 'Commit')
72
+ * @param title Title of the action button to click
73
+ * @returns true if the given action could be performed, false if the button doesn't exist
74
+ */
75
+ async takeAction(title) {
76
+ const header = await this.findElement(ScmProvider.locators.ScmView.providerHeader);
77
+ let actions = [];
78
+ if ((await header.getAttribute('class')).indexOf('hidden') > -1) {
79
+ const view = this.enclosingItem;
80
+ actions = await view.getTitlePart().getActions();
81
+ }
82
+ else {
83
+ await this.getDriver().actions().move({ origin: this }).perform();
84
+ actions = await header.findElements(ScmProvider.locators.ScmView.action);
85
+ }
86
+ const names = await Promise.all(actions.map(async (action) => await action.getAttribute('title')));
87
+ const index = names.findIndex(item => item === title);
88
+ if (index > -1) {
89
+ await actions[index].click();
90
+ return true;
91
+ }
92
+ return false;
93
+ }
94
+ /**
95
+ * Open a context menu using the 'More Actions...' button
96
+ * @returns Promise resolving to a ContextMenu object
97
+ */
98
+ async openMoreActions() {
99
+ const header = await this.findElement(ScmProvider.locators.ScmView.providerHeader);
100
+ if ((await header.getAttribute('class')).indexOf('hidden') > -1) {
101
+ return await new MoreAction(this.enclosingItem).openContextMenu();
102
+ }
103
+ else {
104
+ await this.getDriver().actions().move({ origin: this }).perform();
105
+ return await new MoreAction(this).openContextMenu();
106
+ }
107
+ }
108
+ /**
109
+ * Fill in the message field and send ctrl/cmd + enter to commit the changes
110
+ * @param message the commit message to use
111
+ * @returns promise resolving once the keypresses are sent
112
+ */
113
+ async commitChanges(message) {
114
+ const input = await this.findElement(ScmProvider.locators.ScmView.inputField);
115
+ await input.clear();
116
+ await input.sendKeys(message);
117
+ await input.sendKeys(selenium_webdriver_1.Key.chord(ScmProvider.ctlKey, selenium_webdriver_1.Key.ENTER));
118
+ }
119
+ /**
120
+ * Get page objects for all tree items representing individual changes
121
+ * @param staged when true, finds staged changes; otherwise finds unstaged changes
122
+ * @returns promise resolving to ScmChange object array
123
+ */
124
+ async getChanges(staged = false) {
125
+ const changes = await this.getChangeCount(staged);
126
+ const label = staged ? 'STAGED CHANGES' : 'CHANGES';
127
+ let elements = [];
128
+ if (changes > 0) {
129
+ let i = -1;
130
+ elements = await this.findElements(ScmProvider.locators.ScmView.changeItem);
131
+ for (const [index, item] of elements.entries()) {
132
+ const name = await item.findElement(ScmProvider.locators.ScmView.changeName);
133
+ if (await name.getText() === label) {
134
+ i = index + 1;
135
+ break;
136
+ }
137
+ }
138
+ if (i < 0) {
139
+ return [];
140
+ }
141
+ elements = elements.slice(i, i + changes);
142
+ }
143
+ return await Promise.all(elements.map(async (element) => new ScmChange(element, this).wait()));
144
+ }
145
+ /**
146
+ * Get the number of changes for a given section
147
+ * @param staged when true, counts the staged changes, unstaged otherwise
148
+ * @returns promise resolving to number of changes in the given subsection
149
+ */
150
+ async getChangeCount(staged = false) {
151
+ const locator = staged ? ScmProvider.locators.ScmView.stagedChanges : ScmProvider.locators.ScmView.changes;
152
+ const rows = await this.findElements(locator);
153
+ if (rows.length < 1) {
154
+ return 0;
155
+ }
156
+ const count = await rows[0].findElement(ScmChange.locators.ScmView.changeCount);
157
+ return +await count.getText();
158
+ }
159
+ }
160
+ exports.ScmProvider = ScmProvider;
161
+ /**
162
+ * Page object representing a SCM change tree item
163
+ */
164
+ class ScmChange extends ElementWithContextMenu_1.ElementWithContexMenu {
165
+ constructor(row, provider) {
166
+ super(row, provider);
167
+ }
168
+ /**
169
+ * Get label as a string
170
+ */
171
+ async getLabel() {
172
+ const label = await this.findElement(ScmChange.locators.ScmView.changeLabel);
173
+ return await label.getText();
174
+ }
175
+ /**
176
+ * Get description as a string
177
+ */
178
+ async getDescription() {
179
+ const desc = await this.findElements(ScmChange.locators.ScmView.changeDesc);
180
+ if (desc.length < 1) {
181
+ return '';
182
+ }
183
+ return await desc[0].getText();
184
+ }
185
+ /**
186
+ * Get the status string (e.g. 'Modified')
187
+ */
188
+ async getStatus() {
189
+ const res = await this.findElement(ScmChange.locators.ScmView.resource);
190
+ const status = await res.getAttribute('data-tooltip');
191
+ if (status && status.length > 0) {
192
+ return status;
193
+ }
194
+ return 'folder';
195
+ }
196
+ /**
197
+ * Find if the item is expanded
198
+ * @returns promise resolving to true if change is expanded, to false otherwise
199
+ */
200
+ async isExpanded() {
201
+ const twisties = await this.findElements(ScmChange.locators.ScmView.expand);
202
+ if (twisties.length < 1) {
203
+ return true;
204
+ }
205
+ return (await twisties[0].getAttribute('class')).indexOf('collapsed') < 0;
206
+ }
207
+ /**
208
+ * Expand or collapse a change item if possible, only works for folders in hierarchical view mode
209
+ * @param expand true to expand the item, false to collapse
210
+ * @returns promise resolving to true if the item changed state, to false otherwise
211
+ */
212
+ async toggleExpand(expand) {
213
+ if (await this.isExpanded() !== expand) {
214
+ await this.click();
215
+ return true;
216
+ }
217
+ return false;
218
+ }
219
+ /**
220
+ * Find and click an action button available to a given change tree item
221
+ * @param title title of the action button (e.g 'Stage Changes')
222
+ * @returns promise resolving to true if the action was performed successfully,
223
+ * false if the given button does not exist
224
+ */
225
+ async takeAction(title) {
226
+ await this.getDriver().actions().move({ origin: this }).perform();
227
+ const actions = await this.findElements(ScmChange.locators.ScmView.action);
228
+ const names = await Promise.all(actions.map(async (action) => await action.getAttribute(ScmChange.locators.ScmView.actionLabel)));
229
+ const index = names.findIndex(item => item === title);
230
+ if (index > -1) {
231
+ await actions[index].click();
232
+ return true;
233
+ }
234
+ return false;
235
+ }
236
+ }
237
+ exports.ScmChange = ScmChange;
238
+ class MoreAction extends ElementWithContextMenu_1.ElementWithContexMenu {
239
+ constructor(scm) {
240
+ super(MoreAction.locators.ScmView.more, scm);
241
+ }
242
+ async openContextMenu() {
243
+ await this.click();
244
+ const shadowRootHost = await this.enclosingItem.findElements(selenium_webdriver_1.By.className('shadow-root-host'));
245
+ let actions = this.getDriver().actions();
246
+ await actions.clear();
247
+ await actions.sendKeys(selenium_webdriver_1.Key.ESCAPE).perform();
248
+ const webdriverCapabilities = await this.getDriver().getCapabilities();
249
+ const chromiumVersion = webdriverCapabilities.getBrowserVersion();
250
+ if (shadowRootHost.length > 0) {
251
+ if (await this.getAttribute('aria-expanded') !== 'true') {
252
+ await this.click();
253
+ }
254
+ let shadowRoot;
255
+ const webdriverCapabilities = await this.getDriver().getCapabilities();
256
+ const chromiumVersion = webdriverCapabilities.getBrowserVersion();
257
+ if (chromiumVersion && parseInt(chromiumVersion.split('.')[0]) >= 96) {
258
+ shadowRoot = await shadowRootHost[0].getShadowRoot();
259
+ return new __1.ContextMenu(await shadowRoot.findElement(selenium_webdriver_1.By.className('monaco-menu-container'))).wait();
260
+ }
261
+ else {
262
+ shadowRoot = await this.getDriver().executeScript('return arguments[0].shadowRoot', shadowRootHost[0]);
263
+ return new __1.ContextMenu(shadowRoot).wait();
264
+ }
265
+ }
266
+ else if (chromiumVersion && parseInt(chromiumVersion.split('.')[0]) >= 100) {
267
+ await this.click();
268
+ const workbench = await this.getDriver().findElement(ElementWithContextMenu_1.ElementWithContexMenu.locators.Workbench.constructor);
269
+ return new __1.ContextMenu(workbench).wait();
270
+ }
271
+ return await super.openContextMenu();
272
+ }
273
+ }
274
+ exports.MoreAction = MoreAction;
275
+ //# sourceMappingURL=ScmView.js.map
@@ -0,0 +1,14 @@
1
+ import { ViewSection } from "../ViewSection";
2
+ import { TreeItem } from "../ViewItem";
3
+ import { error } from "selenium-webdriver";
4
+ export declare class TreeItemNotFoundError extends error.NoSuchElementError {
5
+ constructor(msg?: string);
6
+ }
7
+ /**
8
+ * Abstract representation of a view section containing a tree
9
+ */
10
+ export declare abstract class TreeSection extends ViewSection {
11
+ openItem(...path: string[]): Promise<TreeItem[]>;
12
+ abstract findItem(label: string, maxLevel?: number): Promise<TreeItem | undefined>;
13
+ abstract getVisibleItems(): Promise<TreeItem[]>;
14
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TreeSection = exports.TreeItemNotFoundError = void 0;
4
+ const ViewSection_1 = require("../ViewSection");
5
+ const selenium_webdriver_1 = require("selenium-webdriver");
6
+ class TreeItemNotFoundError extends selenium_webdriver_1.error.NoSuchElementError {
7
+ constructor(msg) {
8
+ super(msg);
9
+ this.name = 'TreeItemNotFoundError';
10
+ }
11
+ }
12
+ exports.TreeItemNotFoundError = TreeItemNotFoundError;
13
+ /**
14
+ * Abstract representation of a view section containing a tree
15
+ */
16
+ class TreeSection extends ViewSection_1.ViewSection {
17
+ async openItem(...path) {
18
+ let items = [];
19
+ for (let i = 0; i < path.length; i++) {
20
+ const item = await this.findItem(path[i], i + 1);
21
+ if (await item?.hasChildren() && !await item?.isExpanded()) {
22
+ await item?.expand();
23
+ }
24
+ }
25
+ let currentItem = await this.findItem(path[0], 1);
26
+ for (let i = 0; i < path.length; i++) {
27
+ if (!currentItem) {
28
+ if (i === 0) {
29
+ items = await this.getVisibleItems();
30
+ }
31
+ let names = await Promise.all(items.map(item => item.getLabel()));
32
+ names = names.sort((a, b) => a > b ? 1 : (a < b ? -1 : 0));
33
+ const message = names.length < 1 ? `Current directory is empty.` : `Available items in current directory: [${names.toString()}]`;
34
+ throw new TreeItemNotFoundError(`Item '${path[i]}' not found. ${message}`);
35
+ }
36
+ items = await currentItem.getChildren();
37
+ if (items.length < 1) {
38
+ await currentItem.select();
39
+ return items;
40
+ }
41
+ if (i + 1 < path.length) {
42
+ currentItem = undefined;
43
+ for (const item of items) {
44
+ if (await item.getLabel() === path[i + 1]) {
45
+ currentItem = item;
46
+ break;
47
+ }
48
+ }
49
+ }
50
+ }
51
+ return items;
52
+ }
53
+ }
54
+ exports.TreeSection = TreeSection;
55
+ //# sourceMappingURL=TreeSection.js.map
@@ -0,0 +1,15 @@
1
+ import { TreeItem } from "../../ViewItem";
2
+ import { TreeSection } from "../TreeSection";
3
+ import { WebElement } from "selenium-webdriver";
4
+ /**
5
+ * View item in a custom-made content section (e.g. an extension tree view)
6
+ */
7
+ export declare class CustomTreeItem extends TreeItem {
8
+ constructor(element: WebElement, viewPart: TreeSection);
9
+ getLabel(): Promise<string>;
10
+ getTooltip(): Promise<string>;
11
+ getDescription(): Promise<string>;
12
+ isExpanded(): Promise<boolean>;
13
+ getChildren(): Promise<TreeItem[]>;
14
+ isExpandable(): Promise<boolean>;
15
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CustomTreeItem = void 0;
4
+ const ViewItem_1 = require("../../ViewItem");
5
+ /**
6
+ * View item in a custom-made content section (e.g. an extension tree view)
7
+ */
8
+ class CustomTreeItem extends ViewItem_1.TreeItem {
9
+ constructor(element, viewPart) {
10
+ super(element, viewPart);
11
+ }
12
+ async getLabel() {
13
+ return await this.findElement(CustomTreeItem.locators.CustomTreeSection.itemLabel).getText();
14
+ }
15
+ async getTooltip() {
16
+ return await this.getAttribute(CustomTreeItem.locators.CustomTreeItem.tooltipAttribute);
17
+ }
18
+ async getDescription() {
19
+ return await this.findElement(CustomTreeItem.locators.CustomTreeItem.description).getText();
20
+ }
21
+ async isExpanded() {
22
+ const attr = await this.getAttribute(CustomTreeItem.locators.CustomTreeItem.expandedAttr);
23
+ return attr === CustomTreeItem.locators.CustomTreeItem.expandedValue;
24
+ }
25
+ async getChildren() {
26
+ const rows = await this.getChildItems(CustomTreeItem.locators.DefaultTreeSection.itemRow);
27
+ const items = await Promise.all(rows.map(async (row) => new CustomTreeItem(row, this.enclosingItem).wait()));
28
+ return items;
29
+ }
30
+ async isExpandable() {
31
+ const attr = await this.getAttribute(CustomTreeItem.locators.CustomTreeItem.expandedAttr);
32
+ return attr !== null;
33
+ }
34
+ }
35
+ exports.CustomTreeItem = CustomTreeItem;
36
+ //# sourceMappingURL=CustomTreeItem.js.map