@eclipse-che/che-e2e 7.73.0-dev-1397a5e → 7.73.0-dev-ed57855

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 (177) hide show
  1. package/configs/inversify.config.ts +6 -6
  2. package/configs/inversify.types.ts +27 -27
  3. package/configs/mocharc.ts +21 -21
  4. package/constants/APITestConstants.ts +39 -38
  5. package/constants/BaseTestConstants.ts +46 -43
  6. package/constants/ChromeDriverConstants.ts +29 -29
  7. package/constants/FactoryTestConstants.ts +30 -30
  8. package/constants/MonacoConstants.ts +10 -10
  9. package/constants/OAuthConstants.ts +46 -46
  10. package/constants/ReporterConstants.ts +28 -28
  11. package/constants/TimeoutConstants.ts +101 -101
  12. package/dist/configs/inversify.config.js.map +1 -1
  13. package/dist/configs/inversify.types.js.map +1 -1
  14. package/dist/configs/mocharc.js +1 -1
  15. package/dist/configs/mocharc.js.map +1 -1
  16. package/dist/constants/APITestConstants.js +2 -2
  17. package/dist/constants/APITestConstants.js.map +1 -1
  18. package/dist/constants/BaseTestConstants.js +2 -1
  19. package/dist/constants/BaseTestConstants.js.map +1 -1
  20. package/dist/constants/ChromeDriverConstants.js +1 -1
  21. package/dist/constants/ChromeDriverConstants.js.map +1 -1
  22. package/dist/constants/FactoryTestConstants.js +1 -1
  23. package/dist/constants/FactoryTestConstants.js.map +1 -1
  24. package/dist/constants/MonacoConstants.js +1 -1
  25. package/dist/constants/MonacoConstants.js.map +1 -1
  26. package/dist/constants/OAuthConstants.js +1 -1
  27. package/dist/constants/OAuthConstants.js.map +1 -1
  28. package/dist/constants/ReporterConstants.js +1 -1
  29. package/dist/constants/ReporterConstants.js.map +1 -1
  30. package/dist/constants/TimeoutConstants.js.map +1 -1
  31. package/dist/driver/ChromeDriver.js.map +1 -1
  32. package/dist/pageobjects/dashboard/CreateWorkspace.js +8 -8
  33. package/dist/pageobjects/dashboard/CreateWorkspace.js.map +1 -1
  34. package/dist/pageobjects/dashboard/Dashboard.js +11 -11
  35. package/dist/pageobjects/dashboard/Dashboard.js.map +1 -1
  36. package/dist/pageobjects/dashboard/Workspaces.js +14 -14
  37. package/dist/pageobjects/dashboard/Workspaces.js.map +1 -1
  38. package/dist/pageobjects/dashboard/workspace-details/WorkspaceDetails.js +8 -8
  39. package/dist/pageobjects/dashboard/workspace-details/WorkspaceDetails.js.map +1 -1
  40. package/dist/pageobjects/git-providers/OauthPage.js +17 -17
  41. package/dist/pageobjects/git-providers/OauthPage.js.map +1 -1
  42. package/dist/pageobjects/ide/CheCodeLocatorLoader.js +1 -1
  43. package/dist/pageobjects/ide/CheCodeLocatorLoader.js.map +1 -1
  44. package/dist/pageobjects/login/kubernetes/DexLoginPage.js +5 -5
  45. package/dist/pageobjects/login/kubernetes/DexLoginPage.js.map +1 -1
  46. package/dist/pageobjects/login/kubernetes/KubernetesLoginPage.js +1 -1
  47. package/dist/pageobjects/login/kubernetes/KubernetesLoginPage.js.map +1 -1
  48. package/dist/pageobjects/login/openshift/OcpLoginPage.js +10 -10
  49. package/dist/pageobjects/login/openshift/OcpLoginPage.js.map +1 -1
  50. package/dist/pageobjects/login/openshift/OcpRedHatLoginPage.js +2 -2
  51. package/dist/pageobjects/login/openshift/OcpRedHatLoginPage.js.map +1 -1
  52. package/dist/pageobjects/login/openshift/OcpUserLoginPage.js +1 -1
  53. package/dist/pageobjects/login/openshift/OcpUserLoginPage.js.map +1 -1
  54. package/dist/pageobjects/login/openshift/RedHatLoginPage.js +6 -6
  55. package/dist/pageobjects/login/openshift/RedHatLoginPage.js.map +1 -1
  56. package/dist/pageobjects/login/openshift/RegularUserOcpCheLoginPage.js +2 -2
  57. package/dist/pageobjects/login/openshift/RegularUserOcpCheLoginPage.js.map +1 -1
  58. package/dist/pageobjects/openshift/OcpApplicationPage.js +2 -2
  59. package/dist/pageobjects/openshift/OcpApplicationPage.js.map +1 -1
  60. package/dist/pageobjects/openshift/OcpImportFromGitPage.js +5 -5
  61. package/dist/pageobjects/openshift/OcpImportFromGitPage.js.map +1 -1
  62. package/dist/pageobjects/openshift/OcpMainPage.js +11 -11
  63. package/dist/pageobjects/openshift/OcpMainPage.js.map +1 -1
  64. package/dist/specs/MochaHooks.js +1 -1
  65. package/dist/specs/MochaHooks.js.map +1 -1
  66. package/dist/specs/SmokeTest.spec.js +7 -3
  67. package/dist/specs/SmokeTest.spec.js.map +1 -1
  68. package/dist/specs/api/ContainerOverridesAPI.spec.js.map +1 -1
  69. package/dist/specs/api/DevfileAcceptanceTestAPI.spec.js +7 -5
  70. package/dist/specs/api/DevfileAcceptanceTestAPI.spec.js.map +1 -1
  71. package/dist/specs/api/EmptyWorkspaceAPI.spec.js +1 -1
  72. package/dist/specs/api/EmptyWorkspaceAPI.spec.js.map +1 -1
  73. package/dist/specs/api/PodOverridesAPI.spec.js +2 -1
  74. package/dist/specs/api/PodOverridesAPI.spec.js.map +1 -1
  75. package/dist/specs/dashboard-samples/EmptyWorkspace.spec.js +9 -5
  76. package/dist/specs/dashboard-samples/EmptyWorkspace.spec.js.map +1 -1
  77. package/dist/specs/dashboard-samples/Quarkus.spec.js +7 -3
  78. package/dist/specs/dashboard-samples/Quarkus.spec.js.map +1 -1
  79. package/dist/specs/dashboard-samples/RecommendedExtensions.spec.js +6 -2
  80. package/dist/specs/dashboard-samples/RecommendedExtensions.spec.js.map +1 -1
  81. package/dist/specs/devconsole-intergration/DevConsoleIntegration.spec.js +3 -1
  82. package/dist/specs/devconsole-intergration/DevConsoleIntegration.spec.js.map +1 -1
  83. package/dist/specs/factory/Factory.spec.js +3 -1
  84. package/dist/specs/factory/Factory.spec.js.map +1 -1
  85. package/dist/specs/factory/NoSetupRepoFactory.spec.js +4 -2
  86. package/dist/specs/factory/NoSetupRepoFactory.spec.js.map +1 -1
  87. package/dist/specs/factory/RefusedOAuthFactory.spec.js +4 -2
  88. package/dist/specs/factory/RefusedOAuthFactory.spec.js.map +1 -1
  89. package/dist/specs/miscellaneous/PredefinedNamespace.spec.js +6 -2
  90. package/dist/specs/miscellaneous/PredefinedNamespace.spec.js.map +1 -1
  91. package/dist/tests-library/LoginTests.js.map +1 -1
  92. package/dist/tests-library/ProjectAndFileTests.js +3 -3
  93. package/dist/tests-library/ProjectAndFileTests.js.map +1 -1
  94. package/dist/tests-library/WorkspaceHandlingTests.js +54 -74
  95. package/dist/tests-library/WorkspaceHandlingTests.js.map +1 -1
  96. package/dist/utils/BrowserTabsUtil.js +10 -10
  97. package/dist/utils/BrowserTabsUtil.js.map +1 -1
  98. package/dist/utils/CheReporter.js.map +1 -1
  99. package/dist/utils/DevWorkspaceConfigurationHelper.js +2 -2
  100. package/dist/utils/DevWorkspaceConfigurationHelper.js.map +1 -1
  101. package/dist/utils/DevfilesRegistryHelper.js +7 -7
  102. package/dist/utils/DevfilesRegistryHelper.js.map +1 -1
  103. package/dist/utils/DriverHelper.js +81 -81
  104. package/dist/utils/DriverHelper.js.map +1 -1
  105. package/dist/utils/KubernetesCommandLineToolsExecutor.js +38 -35
  106. package/dist/utils/KubernetesCommandLineToolsExecutor.js.map +1 -1
  107. package/dist/utils/Logger.js +19 -10
  108. package/dist/utils/Logger.js.map +1 -1
  109. package/dist/utils/ScreenCatcher.js.map +1 -1
  110. package/dist/utils/ShellExecutor.js.map +1 -1
  111. package/dist/utils/StringUtil.js +2 -2
  112. package/dist/utils/StringUtil.js.map +1 -1
  113. package/dist/utils/request-handlers/CheApiRequestHandler.js +13 -11
  114. package/dist/utils/request-handlers/CheApiRequestHandler.js.map +1 -1
  115. package/dist/utils/request-handlers/headers/CheMultiuserAuthorizationHeaderHandler.js +1 -1
  116. package/dist/utils/request-handlers/headers/CheMultiuserAuthorizationHeaderHandler.js.map +1 -1
  117. package/dist/utils/workspace/ApiUrlResolver.js +3 -3
  118. package/dist/utils/workspace/ApiUrlResolver.js.map +1 -1
  119. package/dist/utils/workspace/TestWorkspaceUtil.js +20 -16
  120. package/dist/utils/workspace/TestWorkspaceUtil.js.map +1 -1
  121. package/dist/utils/workspace/WorkspaceStatus.js.map +1 -1
  122. package/driver/ChromeDriver.ts +44 -44
  123. package/driver/IDriver.ts +1 -1
  124. package/package.json +1 -1
  125. package/pageobjects/dashboard/CreateWorkspace.ts +52 -52
  126. package/pageobjects/dashboard/Dashboard.ts +72 -72
  127. package/pageobjects/dashboard/Workspaces.ts +138 -139
  128. package/pageobjects/dashboard/workspace-details/WorkspaceDetails.ts +92 -93
  129. package/pageobjects/git-providers/OauthPage.ts +136 -136
  130. package/pageobjects/ide/CheCodeLocatorLoader.ts +40 -40
  131. package/pageobjects/login/interfaces/ICheLoginPage.ts +1 -1
  132. package/pageobjects/login/interfaces/IOcpLoginPage.ts +1 -1
  133. package/pageobjects/login/kubernetes/DexLoginPage.ts +27 -27
  134. package/pageobjects/login/kubernetes/KubernetesLoginPage.ts +11 -11
  135. package/pageobjects/login/openshift/OcpLoginPage.ts +50 -50
  136. package/pageobjects/login/openshift/OcpRedHatLoginPage.ts +21 -21
  137. package/pageobjects/login/openshift/OcpUserLoginPage.ts +14 -14
  138. package/pageobjects/login/openshift/RedHatLoginPage.ts +44 -41
  139. package/pageobjects/login/openshift/RegularUserOcpCheLoginPage.ts +23 -23
  140. package/pageobjects/openshift/OcpApplicationPage.ts +16 -16
  141. package/pageobjects/openshift/OcpImportFromGitPage.ts +54 -54
  142. package/pageobjects/openshift/OcpMainPage.ts +64 -64
  143. package/resources/pod-overrides-airgap.yaml +37 -0
  144. package/specs/MochaHooks.ts +44 -44
  145. package/specs/SmokeTest.spec.ts +35 -31
  146. package/specs/api/ContainerOverridesAPI.spec.ts +23 -23
  147. package/specs/api/DevfileAcceptanceTestAPI.spec.ts +93 -91
  148. package/specs/api/EmptyWorkspaceAPI.spec.ts +50 -50
  149. package/specs/api/PodOverridesAPI.spec.ts +30 -29
  150. package/specs/dashboard-samples/EmptyWorkspace.spec.ts +29 -25
  151. package/specs/dashboard-samples/Quarkus.spec.ts +31 -27
  152. package/specs/dashboard-samples/RecommendedExtensions.spec.ts +156 -152
  153. package/specs/devconsole-intergration/DevConsoleIntegration.spec.ts +62 -64
  154. package/specs/factory/Factory.spec.ts +149 -147
  155. package/specs/factory/NoSetupRepoFactory.spec.ts +188 -186
  156. package/specs/factory/RefusedOAuthFactory.spec.ts +182 -180
  157. package/specs/miscellaneous/PredefinedNamespace.spec.ts +52 -48
  158. package/tests-library/LoginTests.ts +29 -29
  159. package/tests-library/ProjectAndFileTests.ts +13 -13
  160. package/tests-library/WorkspaceHandlingTests.ts +84 -103
  161. package/utils/BrowserTabsUtil.ts +69 -69
  162. package/utils/CheReporter.ts +4 -6
  163. package/utils/DevWorkspaceConfigurationHelper.ts +58 -58
  164. package/utils/DevfilesRegistryHelper.ts +51 -51
  165. package/utils/DriverHelper.ts +599 -600
  166. package/utils/KubernetesCommandLineToolsExecutor.ts +166 -158
  167. package/utils/Logger.ts +98 -67
  168. package/utils/ScreenCatcher.ts +42 -42
  169. package/utils/ShellExecutor.ts +10 -10
  170. package/utils/StringUtil.ts +29 -29
  171. package/utils/request-handlers/CheApiRequestHandler.ts +84 -82
  172. package/utils/request-handlers/headers/CheMultiuserAuthorizationHeaderHandler.ts +18 -18
  173. package/utils/request-handlers/headers/IAuthorizationHeaderHandler.ts +1 -1
  174. package/utils/workspace/ApiUrlResolver.ts +23 -23
  175. package/utils/workspace/ITestWorkspaceUtil.ts +29 -29
  176. package/utils/workspace/TestWorkspaceUtil.ts +120 -116
  177. package/utils/workspace/WorkspaceStatus.ts +3 -3
@@ -15,704 +15,703 @@ import 'reflect-metadata';
15
15
  import { Logger } from './Logger';
16
16
  import { TimeoutConstants } from '../constants/TimeoutConstants';
17
17
 
18
-
19
18
  @injectable()
20
19
  export class DriverHelper {
21
- private readonly driver: ThenableWebDriver;
20
+ private readonly driver: ThenableWebDriver;
22
21
 
23
- constructor(@inject(TYPES.Driver) driver: IDriver) {
24
- this.driver = driver.get() as ThenableWebDriver;
25
- }
22
+ constructor(@inject(TYPES.Driver) driver: IDriver) {
23
+ this.driver = driver.get() as ThenableWebDriver;
24
+ }
25
+
26
+ getAction(): Actions {
27
+ Logger.trace();
28
+
29
+ return this.driver.actions();
30
+ }
26
31
 
27
- getAction(): Actions {
28
- Logger.trace('DriverHelper.getAction');
32
+ async isVisible(locator: By): Promise<boolean> {
33
+ Logger.trace(`${locator}`);
29
34
 
30
- return this.driver.actions();
35
+ try {
36
+ const element: WebElement = await this.driver.findElement(locator);
37
+ return await element.isDisplayed();
38
+ } catch {
39
+ return false;
31
40
  }
41
+ }
32
42
 
33
- async isVisible(locator: By): Promise<boolean> {
34
- Logger.trace(`DriverHelper.isVisible ${locator}`);
43
+ async wait(milliseconds: number): Promise<void> {
44
+ Logger.trace(`(${milliseconds} milliseconds)`);
35
45
 
36
- try {
37
- const element: WebElement = await this.driver.findElement(locator);
38
- return await element.isDisplayed();
39
- } catch {
40
- return false;
41
- }
46
+ await this.driver.sleep(milliseconds);
47
+ }
48
+
49
+ async refreshPage(): Promise<void> {
50
+ Logger.trace();
51
+
52
+ await this.driver.navigate().refresh();
53
+ }
54
+
55
+ async waitVisibilityBoolean(locator: By,
56
+ attempts: number = TimeoutConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
57
+ polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<boolean> {
58
+
59
+ Logger.trace(`${locator}`);
60
+
61
+ for (let i: number = 0; i < attempts; i++) {
62
+ const isVisible: boolean = await this.isVisible(locator);
63
+
64
+ if (isVisible) {
65
+ return true;
66
+ }
67
+
68
+ await this.wait(polling);
42
69
  }
43
70
 
44
- async wait(milliseconds: number): Promise<void> {
45
- Logger.trace(`DriverHelper.wait (${milliseconds} milliseconds)`);
71
+ return false;
72
+ }
73
+
74
+ async waitDisappearanceBoolean(locator: By,
75
+ attempts: number = TimeoutConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
76
+ polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<boolean> {
77
+
78
+ Logger.trace(`${locator}`);
79
+
80
+ for (let i: number = 0; i < attempts; i++) {
81
+ const isVisible: boolean = await this.isVisible(locator);
46
82
 
47
- await this.driver.sleep(milliseconds);
83
+ if (!isVisible) {
84
+ return true;
85
+ }
86
+
87
+ await this.wait(polling);
48
88
  }
49
89
 
50
- async refreshPage(): Promise<void> {
51
- Logger.trace(`DriverHelper.refreshPage`);
90
+ return false;
91
+ }
92
+
93
+ async waitVisibility(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<WebElement> {
94
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
95
+ const attempts: number = Math.ceil(timeout / polling);
96
+
97
+ Logger.trace(`${elementLocator}`);
98
+
99
+ for (let i: number = 0; i < attempts; i++) {
100
+ let element: WebElement;
101
+ try {
102
+ element = await this.driver.wait(until.elementLocated(elementLocator), polling);
103
+ } catch (err) {
104
+ if (i >= attempts - 1) {
105
+ Logger.error(`failed with exception, out of attempts - ${err}`);
106
+ throw err;
107
+ }
108
+
109
+ if (err instanceof error.TimeoutError) {
110
+ if (attempts !== 1) { // waitVisibility was spamming other methods when the number of attempts was 1 - only show message if attempts > 1
111
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
112
+ }
113
+ continue;
114
+ }
115
+
116
+ if (err instanceof error.NoSuchWindowError) { // sometimes waitVisibility fails with NoSuchWindowError when the check is run too soon before the page loads
117
+ Logger.trace(`failed with NoSuchWindow exception. Attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
118
+ continue;
119
+ }
120
+
121
+ Logger.error(`failed with an unexpected exception - ${err}`);
122
+ throw err;
123
+ }
124
+
125
+ try {
126
+ const visibleWebElement: WebElement = await this.driver.wait(until.elementIsVisible(element), polling);
127
+ Logger.trace('element is located and is visible.');
128
+ return visibleWebElement;
129
+ } catch (err) {
130
+ if (err instanceof error.TimeoutError) {
131
+ if (attempts !== 1) { // waitVisibility was spamming other methods when the number of attempts was 1 - only show message if attempts > 1
132
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
133
+ }
134
+ continue;
135
+ }
52
136
 
53
- await this.driver.navigate().refresh();
137
+ if (err instanceof error.StaleElementReferenceError) {
138
+ Logger.debug(`stale element error - ${err}`);
139
+ await this.wait(polling);
140
+ continue;
141
+ }
142
+
143
+ Logger.error(`failed with an unexpected exception - ${err}`);
144
+ throw err;
145
+ }
54
146
  }
55
147
 
56
- async waitVisibilityBoolean(locator: By,
57
- attempts: number = TimeoutConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
58
- polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<boolean> {
148
+ throw new error.TimeoutError(`Exceeded maximum visibility checking attempts for '${elementLocator}' element, timeouted after ${timeout}`);
149
+ }
59
150
 
60
- Logger.trace(`DriverHelper.waitVisibilityBoolean ${locator}`);
151
+ async waitPresence(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<WebElement> {
152
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
153
+ const attempts: number = Math.ceil(timeout / polling);
61
154
 
62
- for (let i: number = 0; i < attempts; i++) {
63
- const isVisible: boolean = await this.isVisible(locator);
155
+ Logger.trace(`${elementLocator}`);
64
156
 
65
- if (isVisible) {
66
- return true;
67
- }
157
+ for (let i: number = 0; i < attempts; i++) {
158
+ try {
159
+ return await this.driver.wait(until.elementLocated(elementLocator), polling);
160
+ } catch (err) {
161
+ if (err instanceof error.TimeoutError) {
162
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
163
+ continue;
164
+ }
68
165
 
69
- await this.wait(polling);
166
+ if (err instanceof error.StaleElementReferenceError) {
167
+ await this.wait(polling);
168
+ continue;
70
169
  }
71
170
 
72
- return false;
171
+ Logger.error(`failed with an unexpected exception - ${err}`);
172
+ throw err;
173
+ }
73
174
  }
74
175
 
75
- async waitDisappearanceBoolean(locator: By,
76
- attempts: number = TimeoutConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
77
- polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<boolean> {
176
+ throw new error.TimeoutError(`Exceeded maximum presence checking attempts, problems with 'StaleElementReferenceError' of '${elementLocator}' element`);
177
+ }
78
178
 
79
- Logger.trace(`DriverHelper.waitDisappearanceBoolean ${locator}`);
179
+ async waitAllPresence(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<Array<WebElement>> {
180
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
181
+ const attempts: number = Math.ceil(timeout / polling);
80
182
 
81
- for (let i: number = 0; i < attempts; i++) {
82
- const isVisible: boolean = await this.isVisible(locator);
183
+ Logger.trace(`${elementLocator}`);
83
184
 
84
- if (!isVisible) {
85
- return true;
86
- }
185
+ for (let i: number = 0; i < attempts; i++) {
186
+ try {
187
+ return await this.driver.wait(until.elementsLocated(elementLocator), polling);
188
+ } catch (err) {
189
+ if (err instanceof error.TimeoutError) {
190
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
191
+ continue;
192
+ }
87
193
 
88
- await this.wait(polling);
194
+ if (err instanceof error.StaleElementReferenceError) {
195
+ await this.wait(polling);
196
+ continue;
89
197
  }
90
198
 
91
- return false;
199
+ Logger.error(`failed with an unexpected exception - ${err}`);
200
+ throw err;
201
+ }
92
202
  }
93
203
 
94
- async waitVisibility(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<WebElement> {
95
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
96
- const attempts: number = Math.ceil(timeout / polling);
97
-
98
- Logger.trace(`DriverHelper.waitVisibility ${elementLocator}`);
99
-
100
- for (let i: number = 0; i < attempts; i++) {
101
- let element: WebElement;
102
- try {
103
- element = await this.driver.wait(until.elementLocated(elementLocator), polling);
104
- } catch (err) {
105
- if (i >= attempts - 1) {
106
- Logger.error(`DriverHelper.waitVisibility - failed with exception, out of attempts - ${err}`);
107
- throw err;
108
- }
109
-
110
- if (err instanceof error.TimeoutError) {
111
- if (attempts !== 1) { // waitVisibility was spamming other methods when the number of attempts was 1 - only show message if attempts > 1
112
- Logger.trace(`DriverHelper.waitVisibility - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
113
- }
114
- continue;
115
- }
116
-
117
- if (err instanceof error.NoSuchWindowError) { // sometimes waitVisibility fails with NoSuchWindowError when the check is run too soon before the page loads
118
- Logger.trace(`DriverHelper.waitVisibility - failed with NoSuchWindow exception. Attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
119
- continue;
120
- }
121
-
122
- Logger.error(`DriverHelper.waitVisibility - failed with an unexpected exception - ${err}`);
123
- throw err;
124
- }
125
-
126
- try {
127
- const visibleWebElement: WebElement = await this.driver.wait(until.elementIsVisible(element), polling);
128
- Logger.trace('DriverHelper.waitVisibility - Element is located and is visible.');
129
- return visibleWebElement;
130
- } catch (err) {
131
- if (err instanceof error.TimeoutError) {
132
- if (attempts !== 1) { // waitVisibility was spamming other methods when the number of attempts was 1 - only show message if attempts > 1
133
- Logger.trace(`DriverHelper.waitVisibility - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
134
- }
135
- continue;
136
- }
137
-
138
- if (err instanceof error.StaleElementReferenceError) {
139
- Logger.debug(`DriverHelper.waitVisibility - Stale element error - ${err}`);
140
- await this.wait(polling);
141
- continue;
142
- }
143
-
144
- Logger.error(`DriverHelper.waitVisibility - failed with an unexpected exception - ${err}`);
145
- throw err;
146
- }
147
- }
148
-
149
- throw new error.TimeoutError(`Exceeded maximum visibility checkings attempts for '${elementLocator}' element, timeouted after ${timeout}`);
204
+ throw new error.TimeoutError(`Exceeded maximum presence checkings attempts, problems with 'StaleElementReferenceError' of '${elementLocator}' element`);
205
+ }
206
+
207
+ async waitAllVisibility(locators: Array<By>, timeout: number): Promise<void> {
208
+ Logger.trace(`${locators}`);
209
+
210
+ for (const elementLocator of locators) {
211
+ await this.waitVisibility(elementLocator, timeout);
150
212
  }
213
+ }
214
+
215
+ async waitDisappearance(elementLocator: By,
216
+ attempts: number = TimeoutConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
217
+ polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<void> {
151
218
 
152
- async waitPresence(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<WebElement> {
153
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
154
- const attempts: number = Math.ceil(timeout / polling);
219
+ Logger.trace(`${elementLocator}`);
155
220
 
156
- Logger.trace(`DriverHelper.waitPresence ${elementLocator}`);
221
+ const isDisappeared: boolean = await this.waitDisappearanceBoolean(elementLocator, attempts, polling);
157
222
 
158
- for (let i: number = 0; i < attempts; i++) {
159
- try {
160
- return await this.driver.wait(until.elementLocated(elementLocator), polling);
161
- } catch (err) {
162
- if (err instanceof error.TimeoutError) {
163
- Logger.trace(`DriverHelper.waitPresence - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
164
- continue;
165
- }
223
+ if (!isDisappeared) {
224
+ throw new error.TimeoutError(`Waiting attempts exceeded, element '${elementLocator}' is still visible`);
225
+ }
226
+ }
166
227
 
167
- if (err instanceof error.StaleElementReferenceError) {
168
- await this.wait(polling);
169
- continue;
170
- }
228
+ async waitDisappearanceWithTimeout(elementLocator: By, timeout: number): Promise<void> {
229
+ Logger.trace(`${elementLocator}`);
171
230
 
172
- Logger.error(`DriverHelper.waitPresence - failed with an unexpected exception - ${err}`);
173
- throw err;
174
- }
175
- }
231
+ await this.getDriver().wait(async () => {
232
+ const isVisible: boolean = await this.isVisible(elementLocator);
233
+
234
+ if (!isVisible) {
235
+ return true;
236
+ }
237
+ }, timeout);
238
+ }
239
+
240
+ async waitAllDisappearance(locators: Array<By>,
241
+ attemptsPerLocator: number = TimeoutConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
242
+ pollingPerLocator: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<void> {
176
243
 
177
- throw new error.TimeoutError(`Exceeded maximum presence checking attempts, problems with 'StaleElementReferenceError' of '${elementLocator}' element`);
244
+ Logger.trace(`${locators}`);
245
+
246
+ for (const elementLocator of locators) {
247
+ await this.waitDisappearance(elementLocator, attemptsPerLocator, pollingPerLocator);
178
248
  }
249
+ }
250
+
251
+ async waitAndClick(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
252
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
253
+ const attempts: number = Math.ceil(timeout / polling);
179
254
 
180
- async waitAllPresence(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<Array<WebElement>> {
181
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
182
- const attempts: number = Math.ceil(timeout / polling);
255
+ Logger.trace(`${elementLocator}`);
183
256
 
184
- Logger.trace(`DriverHelper.waitAllPresence ${elementLocator}`);
257
+ for (let i: number = 0; i < attempts; i++) {
258
+ let element: WebElement;
259
+ try {
260
+ element = await this.waitVisibility(elementLocator, polling);
261
+ } catch (err) {
262
+ if (i >= attempts - 1) {
263
+ Logger.error(`failed with exception, out of attempts - ${err}`);
264
+ throw err;
265
+ }
185
266
 
186
- for (let i: number = 0; i < attempts; i++) {
187
- try {
188
- return await this.driver.wait(until.elementsLocated(elementLocator), polling);
189
- } catch (err) {
190
- if (err instanceof error.TimeoutError) {
191
- Logger.trace(`DriverHelper.waitAllPresence - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
192
- continue;
193
- }
267
+ if (err instanceof error.TimeoutError) {
268
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
269
+ continue;
270
+ }
194
271
 
195
- if (err instanceof error.StaleElementReferenceError) {
196
- await this.wait(polling);
197
- continue;
198
- }
272
+ Logger.error(`failed with an unexpected exception - ${err}`);
273
+ throw err;
274
+ }
199
275
 
200
- Logger.error(`DriverHelper.waitAllPresence - failed with an unexpected exception - ${err}`);
201
- throw err;
202
- }
276
+ try {
277
+ await element.click();
278
+ return;
279
+ } catch (err) {
280
+ function isElementClickInterceptedOnLastAttempt(err: Error, i: number): boolean {
281
+ return err instanceof error.ElementClickInterceptedError && i === attempts - 1;
203
282
  }
204
283
 
205
- throw new error.TimeoutError(`Exceeded maximum presence checkings attempts, problems with 'StaleElementReferenceError' of '${elementLocator}' element`);
284
+ if (err instanceof error.StaleElementReferenceError || err instanceof error.ElementClickInterceptedError) {
285
+ Logger.debug(`${elementLocator} - ${err}`);
286
+ await this.wait(polling);
287
+ continue;
288
+ }
289
+
290
+ if (isElementClickInterceptedOnLastAttempt(err, i)) {
291
+ Logger.debug(`element is not clickable, try to perform pointer click`);
292
+ await this.getAction()
293
+ .move({
294
+ origin: await this.waitPresence(elementLocator)
295
+ })
296
+ .click()
297
+ .perform();
298
+ return;
299
+ }
300
+
301
+ Logger.error(`failed with an unexpected exception - ${err}`);
302
+ throw err;
303
+ }
206
304
  }
207
305
 
208
- async waitAllVisibility(locators: Array<By>, timeout: number): Promise<void> {
209
- Logger.trace(`DriverHelper.waitAllVisibility ${locators}`);
306
+ throw new error.TimeoutError(`Exceeded maximum clicking attempts, the '${elementLocator}' element is not clickable`);
307
+ }
308
+
309
+ async waitAndGetElementAttribute(elementLocator: By, attribute: string,
310
+ timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<string> {
311
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
312
+ const attempts: number = Math.ceil(timeout / polling);
313
+
314
+ Logger.trace(`${elementLocator} attribute: '${attribute}'`);
315
+
316
+ for (let i: number = 0; i < attempts; i++) {
317
+ let element: WebElement;
318
+ try {
319
+ element = await this.waitVisibility(elementLocator, polling);
320
+ } catch (err) {
321
+ if (i >= attempts - 1) {
322
+ Logger.error(`failed with exception, out of attempts - ${err}`);
323
+ throw err;
324
+ }
325
+
326
+ if (err instanceof error.TimeoutError) {
327
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
328
+ continue;
329
+ }
330
+
331
+ Logger.error(`failed with an unexpected exception - ${err}`);
332
+ throw err;
333
+ }
210
334
 
211
- for (const elementLocator of locators) {
212
- await this.waitVisibility(elementLocator, timeout);
335
+ try {
336
+ return await element.getAttribute(attribute);
337
+ } catch (err) {
338
+ if (err instanceof error.StaleElementReferenceError) {
339
+ await this.wait(polling);
340
+ continue;
213
341
  }
342
+
343
+ Logger.error(`failed with an unexpected exception - ${err}`);
344
+ throw err;
345
+ }
214
346
  }
215
347
 
216
- async waitDisappearance(elementLocator: By,
217
- attempts: number = TimeoutConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
218
- polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<void> {
348
+ throw new error.TimeoutError(`Exceeded maximum gettin of the '${attribute}' attribute attempts, from the '${elementLocator}' element`);
349
+ }
350
+
351
+ async waitAndGetCssValue(elementLocator: By, cssAttribute: string,
352
+ timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<string> {
353
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
354
+ const attempts: number = Math.ceil(timeout / polling);
355
+
356
+ Logger.trace(`${elementLocator} cssAttribute: ${cssAttribute}`);
219
357
 
220
- Logger.trace(`DriverHelper.waitDisappearance ${elementLocator}`);
358
+ for (let i: number = 0; i < attempts; i++) {
359
+ let element: WebElement;
360
+ try {
361
+ element = await this.waitVisibility(elementLocator, polling);
362
+ } catch (err) {
363
+ if (i >= attempts - 1) {
364
+ Logger.error(`failed with exception, out of attempts - ${err}`);
365
+ throw err;
366
+ }
367
+
368
+ if (err instanceof error.TimeoutError) {
369
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
370
+ continue;
371
+ }
221
372
 
222
- const isDisappeared: boolean = await this.waitDisappearanceBoolean(elementLocator, attempts, polling);
373
+ Logger.error(`failed with an unexpected exception - ${err}`);
374
+ throw err;
375
+ }
223
376
 
224
- if (!isDisappeared) {
225
- throw new error.TimeoutError(`Waiting attempts exceeded, element '${elementLocator}' is still visible`);
377
+ try {
378
+ return await element.getCssValue(cssAttribute);
379
+ } catch (err) {
380
+ if (err instanceof error.StaleElementReferenceError) {
381
+ await this.wait(polling);
382
+ continue;
226
383
  }
384
+
385
+ Logger.error(`failed with an unexpected exception - ${err}`);
386
+ throw err;
387
+ }
227
388
  }
228
389
 
229
- async waitDisappearanceWithTimeout(elementLocator: By, timeout: number): Promise<void> {
230
- Logger.trace(`DriverHelper.waitDisappearanceWithTimeout ${elementLocator}`);
390
+ throw new error.TimeoutError(`Exceeded maximum gettin of the '${cssAttribute}' css attribute attempts, from the '${elementLocator}' element`);
391
+ }
392
+
393
+ async waitAttributeValue(elementLocator: By,
394
+ attribute: string,
395
+ expectedValue: string,
396
+ timeout: number): Promise<void> {
397
+
398
+ Logger.trace(`${elementLocator}`);
399
+
400
+ await this.driver.wait(async () => {
401
+ const attributeValue: string = await this.waitAndGetElementAttribute(elementLocator, attribute, timeout);
231
402
 
232
- await this.getDriver().wait(async () => {
233
- const isVisible: boolean = await this.isVisible(elementLocator);
403
+ return expectedValue === attributeValue;
404
+ },
405
+ timeout,
406
+ `The '${attribute}' attribute value doesn't match with expected value '${expectedValue}'`);
407
+ }
234
408
 
235
- if (!isVisible) {
236
- return true;
237
- }
238
- }, timeout);
409
+ async type(elementLocator: By, text: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
410
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
411
+ const attempts: number = Math.ceil(timeout / polling);
412
+
413
+ if (elementLocator.toString().toLocaleLowerCase().includes('password')) {
414
+ Logger.trace(`${elementLocator} text: ***`);
415
+ } else {
416
+ Logger.trace(`${elementLocator} text: ${text}`);
239
417
  }
240
418
 
241
- async waitAllDisappearance(locators: Array<By>,
242
- attemptsPerLocator: number = TimeoutConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
243
- pollingPerLocator: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<void> {
419
+ for (let i: number = 0; i < attempts; i++) {
420
+ let element: WebElement;
421
+ try {
422
+ element = await this.waitVisibility(elementLocator, polling);
423
+ } catch (err) {
424
+ if (i >= attempts - 1) {
425
+ Logger.error(`failed with exception, out of attempts - ${err}`);
426
+ throw err;
427
+ }
244
428
 
245
- Logger.trace(`DriverHelper.waitAllDisappearance ${locators}`);
429
+ if (err instanceof error.TimeoutError) {
430
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
431
+ continue;
432
+ }
246
433
 
247
- for (const elementLocator of locators) {
248
- await this.waitDisappearance(elementLocator, attemptsPerLocator, pollingPerLocator);
434
+ Logger.error(`failed with an unexpected exception - ${err}`);
435
+ throw err;
436
+ }
437
+
438
+ try {
439
+ await element.sendKeys(text);
440
+ return;
441
+ } catch (err) {
442
+ if (err instanceof error.StaleElementReferenceError) {
443
+ await this.wait(polling);
444
+ continue;
249
445
  }
250
- }
251
446
 
252
- async waitAndClick(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
253
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
254
- const attempts: number = Math.ceil(timeout / polling);
255
-
256
- Logger.trace(`DriverHelper.waitAndClick ${elementLocator}`);
257
-
258
- for (let i: number = 0; i < attempts; i++) {
259
- let element: WebElement;
260
- try {
261
- element = await this.waitVisibility(elementLocator, polling);
262
- } catch (err) {
263
- if (i >= attempts - 1) {
264
- Logger.error(`DriverHelper.waitAndClick - failed with exception, out of attempts - ${err}`);
265
- throw err;
266
- }
267
-
268
- if (err instanceof error.TimeoutError) {
269
- Logger.trace(`DriverHelper.waitAndClick - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
270
- continue;
271
- }
272
-
273
- Logger.error(`DriverHelper.waitAndClick - failed with an unexpected exception - ${err}`);
274
- throw err;
275
- }
276
-
277
- try {
278
- await element.click();
279
- return;
280
- } catch (err) {
281
- function isElementClickInterceptedOnLastAttempt(err: Error, i: number): boolean {
282
- return err instanceof error.ElementClickInterceptedError && i === attempts - 1;
283
- }
284
-
285
- if (err instanceof error.StaleElementReferenceError || err instanceof error.ElementClickInterceptedError) {
286
- Logger.debug(`DriverHelper.waitAndClick - ${elementLocator} - ${err}`);
287
- await this.wait(polling);
288
- continue;
289
- }
290
-
291
- if (isElementClickInterceptedOnLastAttempt(err, i)) {
292
- Logger.debug(`DriverHelper.waitAndClick - Element is not clickable, try to perform pointer click`);
293
- await this.getAction()
294
- .move({
295
- origin: await this.waitPresence(elementLocator)
296
- })
297
- .click()
298
- .perform();
299
- return;
300
- }
301
-
302
- Logger.error(`DriverHelper.waitAndClick - failed with an unexpected exception - ${err}`);
303
- throw err;
304
- }
305
- }
306
-
307
- throw new error.TimeoutError(`Exceeded maximum clicking attempts, the '${elementLocator}' element is not clickable`);
447
+ Logger.error(`failed with an unexpected exception - ${err}`);
448
+ throw err;
449
+ }
308
450
  }
309
451
 
310
- async waitAndGetElementAttribute(elementLocator: By, attribute: string,
311
- timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<string> {
312
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
313
- const attempts: number = Math.ceil(timeout / polling);
314
-
315
- Logger.trace(`DriverHelper.waitAndGetElementAttribute ${elementLocator} attribute: '${attribute}'`);
316
-
317
- for (let i: number = 0; i < attempts; i++) {
318
- let element: WebElement;
319
- try {
320
- element = await this.waitVisibility(elementLocator, polling);
321
- } catch (err) {
322
- if (i >= attempts - 1) {
323
- Logger.error(`DriverHelper.waitAndGetElementAttribute - failed with exception, out of attempts - ${err}`);
324
- throw err;
325
- }
326
-
327
- if (err instanceof error.TimeoutError) {
328
- Logger.trace(`DriverHelper.waitAndGetElementAttribute - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
329
- continue;
330
- }
331
-
332
- Logger.error(`DriverHelper.waitAndGetElementAttribute - failed with an unexpected exception - ${err}`);
333
- throw err;
334
- }
335
-
336
- try {
337
- return await element.getAttribute(attribute);
338
- } catch (err) {
339
- if (err instanceof error.StaleElementReferenceError) {
340
- await this.wait(polling);
341
- continue;
342
- }
343
-
344
- Logger.error(`DriverHelper.waitAndGetElementAttribute - failed with an unexpected exception - ${err}`);
345
- throw err;
346
- }
347
- }
348
-
349
- throw new error.TimeoutError(`Exceeded maximum gettin of the '${attribute}' attribute attempts, from the '${elementLocator}' element`);
350
- }
452
+ throw new error.TimeoutError(`Exceeded maximum typing attempts, to the '${elementLocator}' element`);
453
+ }
351
454
 
352
- async waitAndGetCssValue(elementLocator: By, cssAttribute: string,
353
- timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<string> {
354
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
355
- const attempts: number = Math.ceil(timeout / polling);
356
-
357
- Logger.trace(`DriverHelper.waitAndGetCssValue ${elementLocator} cssAttribute: ${cssAttribute}`);
358
-
359
- for (let i: number = 0; i < attempts; i++) {
360
- let element: WebElement;
361
- try {
362
- element = await this.waitVisibility(elementLocator, polling);
363
- } catch (err) {
364
- if (i >= attempts - 1) {
365
- Logger.error(`DriverHelper.waitAndGetCssValue - failed with exception, out of attempts - ${err}`);
366
- throw err;
367
- }
368
-
369
- if (err instanceof error.TimeoutError) {
370
- Logger.trace(`DriverHelper.waitAndGetCssValue - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
371
- continue;
372
- }
373
-
374
- Logger.error(`DriverHelper.waitAndGetCssValue - failed with an unexpected exception - ${err}`);
375
- throw err;
376
- }
377
-
378
- try {
379
- return await element.getCssValue(cssAttribute);
380
- } catch (err) {
381
- if (err instanceof error.StaleElementReferenceError) {
382
- await this.wait(polling);
383
- continue;
384
- }
385
-
386
- Logger.error(`DriverHelper.waitAndGetCssValue - failed with an unexpected exception - ${err}`);
387
- throw err;
388
- }
389
- }
390
-
391
- throw new error.TimeoutError(`Exceeded maximum gettin of the '${cssAttribute}' css attribute attempts, from the '${elementLocator}' element`);
392
- }
455
+ async typeToInvisible(elementLocator: By, text: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
456
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
457
+ const attempts: number = Math.ceil(timeout / polling);
393
458
 
394
- async waitAttributeValue(elementLocator: By,
395
- attribute: string,
396
- expectedValue: string,
397
- timeout: number): Promise<void> {
459
+ Logger.trace(`${elementLocator} text: ${text}`);
398
460
 
399
- Logger.trace(`DriverHelper.waitAttributeValue ${elementLocator}`);
461
+ for (let i: number = 0; i < attempts; i++) {
462
+ let element: WebElement;
463
+ try {
464
+ element = await this.waitPresence(elementLocator, polling);
465
+ } catch (err) {
466
+ if (i >= attempts - 1) {
467
+ Logger.error(`failed with exception, out of attempts - ${err}`);
468
+ throw err;
469
+ }
400
470
 
401
- await this.driver.wait(async () => {
402
- const attributeValue: string = await this.waitAndGetElementAttribute(elementLocator, attribute, timeout);
471
+ if (err instanceof error.TimeoutError) {
472
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
473
+ continue;
474
+ }
403
475
 
404
- return expectedValue === attributeValue;
405
- },
406
- timeout,
407
- `The '${attribute}' attribute value doesn't match with expected value '${expectedValue}'`);
408
- }
476
+ Logger.error(`failed with an unexpected exception - ${err}`);
477
+ throw err;
478
+ }
479
+
480
+ try {
481
+ await element.sendKeys(text);
482
+ return;
483
+ } catch (err) {
484
+ if (err instanceof error.StaleElementReferenceError) {
485
+ await this.wait(polling);
486
+ continue;
487
+ }
409
488
 
410
- async type(elementLocator: By, text: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
411
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
412
- const attempts: number = Math.ceil(timeout / polling);
413
-
414
- if (elementLocator.toString().toLocaleLowerCase().includes('password')) {
415
- Logger.trace(`DriverHelper.type ${elementLocator} text: ***`);
416
- } else {
417
- Logger.trace(`DriverHelper.type ${elementLocator} text: ${text}`);
418
- }
419
-
420
- for (let i: number = 0; i < attempts; i++) {
421
- let element: WebElement;
422
- try {
423
- element = await this.waitVisibility(elementLocator, polling);
424
- } catch (err) {
425
- if (i >= attempts - 1) {
426
- Logger.error(`DriverHelper.type - failed with exception, out of attempts - ${err}`);
427
- throw err;
428
- }
429
-
430
- if (err instanceof error.TimeoutError) {
431
- Logger.trace(`DriverHelper.type - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
432
- continue;
433
- }
434
-
435
- Logger.error(`DriverHelper.type - failed with an unexpected exception - ${err}`);
436
- throw err;
437
- }
438
-
439
- try {
440
- await element.sendKeys(text);
441
- return;
442
- } catch (err) {
443
- if (err instanceof error.StaleElementReferenceError) {
444
- await this.wait(polling);
445
- continue;
446
- }
447
-
448
- Logger.error(`DriverHelper.type - failed with an unexpected exception - ${err}`);
449
- throw err;
450
- }
451
- }
452
-
453
- throw new error.TimeoutError(`Exceeded maximum typing attempts, to the '${elementLocator}' element`);
489
+ Logger.error(`failed with an unexpected exception - ${err}`);
490
+ throw err;
491
+ }
454
492
  }
455
493
 
456
- async typeToInvisible(elementLocator: By, text: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
457
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
458
- const attempts: number = Math.ceil(timeout / polling);
459
-
460
- Logger.trace(`DriverHelper.typeToInvisible ${elementLocator} text: ${text}`);
461
-
462
- for (let i: number = 0; i < attempts; i++) {
463
- let element: WebElement;
464
- try {
465
- element = await this.waitPresence(elementLocator, polling);
466
- } catch (err) {
467
- if (i >= attempts - 1) {
468
- Logger.error(`DriverHelper.typeToInvisible - failed with exception, out of attempts - ${err}`);
469
- throw err;
470
- }
471
-
472
- if (err instanceof error.TimeoutError) {
473
- Logger.trace(`DriverHelper.typeToInvisible - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
474
- continue;
475
- }
476
-
477
- Logger.error(`DriverHelper.typeToInvisible - failed with an unexpected exception - ${err}`);
478
- throw err;
479
- }
480
-
481
- try {
482
- await element.sendKeys(text);
483
- return;
484
- } catch (err) {
485
- if (err instanceof error.StaleElementReferenceError) {
486
- await this.wait(polling);
487
- continue;
488
- }
489
-
490
- Logger.error(`DriverHelper.typeToInvisible - failed with an unexpected exception - ${err}`);
491
- throw err;
492
- }
493
- }
494
-
495
- throw new error.TimeoutError(`Exceeded maximum typing attempts, to the '${elementLocator}' element`);
496
- }
494
+ throw new error.TimeoutError(`Exceeded maximum typing attempts, to the '${elementLocator}' element`);
495
+ }
497
496
 
498
- async clear(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
499
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
500
- const attempts: number = Math.ceil(timeout / polling);
501
-
502
- Logger.trace(`DriverHelper.clear ${elementLocator}`);
503
-
504
- for (let i: number = 0; i < attempts; i++) {
505
- let element: WebElement;
506
- try {
507
- element = await this.waitVisibility(elementLocator, polling);
508
- } catch (err) {
509
- if (i >= attempts - 1) {
510
- Logger.error(`DriverHelper.clear - failed with exception, out of attempts - ${err}`);
511
- throw err;
512
- }
513
-
514
- if (err instanceof error.TimeoutError) {
515
- Logger.trace(`DriverHelper.clear - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
516
- continue;
517
- }
518
-
519
- Logger.error(`DriverHelper.clear - failed with an unexpected exception - ${err}`);
520
- throw err;
521
- }
522
-
523
- try {
524
- await element.clear();
525
- return;
526
- } catch (err) {
527
- if (err instanceof error.StaleElementReferenceError) {
528
- await this.wait(polling);
529
- continue;
530
- }
531
-
532
- Logger.error(`DriverHelper.clear - failed with an unexpected exception - ${err}`);
533
- throw err;
534
- }
535
- }
536
-
537
- throw new error.TimeoutError(`Exceeded maximum clearing attempts, to the '${elementLocator}' element`);
538
- }
497
+ async clear(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
498
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
499
+ const attempts: number = Math.ceil(timeout / polling);
539
500
 
540
- async clearInvisible(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
541
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
542
- const attempts: number = Math.ceil(timeout / polling);
543
-
544
- Logger.trace(`DriverHelper.clearInvisible ${elementLocator}`);
545
-
546
- for (let i: number = 0; i < attempts; i++) {
547
- let element: WebElement;
548
- try {
549
- element = await this.waitPresence(elementLocator, polling);
550
- } catch (err) {
551
- if (i >= attempts - 1) {
552
- Logger.error(`DriverHelper.clearInvisible - failed with exception, out of attempts - ${err}`);
553
- throw err;
554
- }
555
-
556
- if (err instanceof error.TimeoutError) {
557
- Logger.trace(`DriverHelper.clearInvisible - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
558
- continue;
559
- }
560
-
561
- Logger.error(`DriverHelper.clearInvisible - failed with an unexpected exception - ${err}`);
562
- throw err;
563
- }
564
-
565
- try {
566
- await element.clear();
567
- return;
568
- } catch (err) {
569
- if (err instanceof error.StaleElementReferenceError) {
570
- await this.wait(polling);
571
- continue;
572
- }
573
-
574
- Logger.error(`DriverHelper.clearInvisible - failed with an unexpected exception - ${err}`);
575
- throw err;
576
- }
577
- }
578
-
579
- throw new error.TimeoutError(`Exceeded maximum clearing attempts, to the '${elementLocator}' element`);
580
- }
501
+ Logger.trace(`${elementLocator}`);
581
502
 
582
- async enterValue(elementLocator: By, text: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
583
- if (elementLocator.toString().toLocaleLowerCase().includes('password')) {
584
- Logger.trace(`DriverHelper.enterValue ${elementLocator} text: ***`);
585
- } else {
586
- Logger.trace(`DriverHelper.enterValue ${elementLocator} text: ${text}`);
503
+ for (let i: number = 0; i < attempts; i++) {
504
+ let element: WebElement;
505
+ try {
506
+ element = await this.waitVisibility(elementLocator, polling);
507
+ } catch (err) {
508
+ if (i >= attempts - 1) {
509
+ Logger.error(`failed with exception, out of attempts - ${err}`);
510
+ throw err;
587
511
  }
588
512
 
589
- await this.waitVisibility(elementLocator, timeout);
590
- await this.clear(elementLocator);
591
- await this.waitAttributeValue(elementLocator, 'value', '', timeout);
592
- await this.type(elementLocator, text, timeout);
593
- await this.waitAttributeValue(elementLocator, 'value', text, timeout);
594
- }
513
+ if (err instanceof error.TimeoutError) {
514
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
515
+ continue;
516
+ }
595
517
 
596
- async waitAndSwitchToFrame(iframeLocator: By, timeout: number): Promise<void> {
597
- Logger.trace(`DriverHelper.waitAndSwitchToFrame ${iframeLocator}`);
518
+ Logger.error(`failed with an unexpected exception - ${err}`);
519
+ throw err;
520
+ }
521
+
522
+ try {
523
+ await element.clear();
524
+ return;
525
+ } catch (err) {
526
+ if (err instanceof error.StaleElementReferenceError) {
527
+ await this.wait(polling);
528
+ continue;
529
+ }
598
530
 
599
- await this.driver.wait(until.ableToSwitchToFrame(iframeLocator), timeout);
531
+ Logger.error(`failed with an unexpected exception - ${err}`);
532
+ throw err;
533
+ }
600
534
  }
601
535
 
602
- async waitAndGetText(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<string> {
603
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
604
- const attempts: number = Math.ceil(timeout / polling);
605
-
606
- Logger.trace(`DriverHelper.waitAndGetText ${elementLocator}`);
607
-
608
- for (let i: number = 0; i < attempts; i++) {
609
- let element: WebElement;
610
- try {
611
- element = await this.waitVisibility(elementLocator, polling);
612
- } catch (err) {
613
- if (i >= attempts - 1) {
614
- Logger.error(`DriverHelper.waitAndGetText - failed with exception, out of attempts - ${err}`);
615
- throw err;
616
- }
617
-
618
- if (err instanceof error.TimeoutError) {
619
- Logger.trace(`DriverHelper.waitAndGetText - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
620
- continue;
621
- }
622
-
623
- Logger.error(`DriverHelper.waitAndGetText - failed with an unexpected exception - ${err}`);
624
- throw err;
625
- }
626
-
627
- try {
628
- return await element.getText();
629
- } catch (err) {
630
- if (err instanceof error.StaleElementReferenceError) {
631
- await this.wait(polling);
632
- continue;
633
- }
634
-
635
- Logger.error(`DriverHelper.waitAndGetText - failed with an unexpected exception - ${err}`);
636
- throw err;
637
- }
638
- }
639
-
640
- throw new error.TimeoutError(`Exceeded maximum text obtaining attempts, from the '${elementLocator}' element`);
641
- }
536
+ throw new error.TimeoutError(`Exceeded maximum clearing attempts, to the '${elementLocator}' element`);
537
+ }
642
538
 
643
- async waitAndGetValue(elementLocator: By, timeout: number): Promise<string> {
644
- Logger.trace(`DriverHelper.waitAndGetValue ${elementLocator}`);
539
+ async clearInvisible(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
540
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
541
+ const attempts: number = Math.ceil(timeout / polling);
645
542
 
646
- return await this.waitAndGetElementAttribute(elementLocator, 'value', timeout);
647
- }
543
+ Logger.trace(`${elementLocator}`);
648
544
 
649
- async waitUntilTrue(callback: any, timeout: number): Promise<void> {
650
- Logger.trace('DriverHelper.waitUntilTrue');
545
+ for (let i: number = 0; i < attempts; i++) {
546
+ let element: WebElement;
547
+ try {
548
+ element = await this.waitPresence(elementLocator, polling);
549
+ } catch (err) {
550
+ if (i >= attempts - 1) {
551
+ Logger.error(`failed with exception, out of attempts - ${err}`);
552
+ throw err;
553
+ }
651
554
 
652
- await this.driver.wait(callback, timeout);
653
- }
555
+ if (err instanceof error.TimeoutError) {
556
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
557
+ continue;
558
+ }
654
559
 
655
- async scrollTo(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
656
- const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
657
- const attempts: number = Math.ceil(timeout / polling);
658
-
659
- Logger.trace(`DriverHelper.scrollTo ${elementLocator}`);
660
-
661
- for (let i: number = 0; i < attempts; i++) {
662
- let element: WebElement;
663
- try {
664
- element = await this.waitPresence(elementLocator, polling);
665
- } catch (err) {
666
- if (i >= attempts - 1) {
667
- Logger.error(`DriverHelper.scrollTo - failed with exception, out of attempts - ${err}`);
668
- throw err;
669
- }
670
-
671
- if (err instanceof error.TimeoutError) {
672
- Logger.trace(`DriverHelper.scrollTo - Polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
673
- continue;
674
- }
675
-
676
- Logger.error(`DriverHelper.scrollTo - failed with an unexpected exception - ${err}`);
677
- throw err;
678
- }
679
-
680
- try {
681
- await this.getDriver()
682
- .executeScript('arguments[0].scrollIntoView(true);', element);
683
- return;
684
- } catch (err) {
685
- if (err instanceof error.StaleElementReferenceError) {
686
- await this.wait(polling);
687
- continue;
688
- }
689
-
690
- Logger.error(`DriverHelper.scrollTo - failed with an unexpected exception - ${err}`);
691
- throw err;
692
- }
693
- }
694
-
695
- throw new error.TimeoutError(`Exceeded maximum mouse move attempts, for the '${elementLocator}' element`);
696
- }
560
+ Logger.error(`failed with an unexpected exception - ${err}`);
561
+ throw err;
562
+ }
563
+
564
+ try {
565
+ await element.clear();
566
+ return;
567
+ } catch (err) {
568
+ if (err instanceof error.StaleElementReferenceError) {
569
+ await this.wait(polling);
570
+ continue;
571
+ }
697
572
 
698
- async scrollToAndClick(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
699
- await this.scrollTo(elementLocator, timeout);
700
- await this.waitAndClick(elementLocator, timeout);
573
+ Logger.error(`failed with an unexpected exception - ${err}`);
574
+ throw err;
575
+ }
701
576
  }
702
577
 
703
- async scrollToAndEnterValue(elementLocator: By, value: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
704
- await this.scrollTo(elementLocator, timeout);
705
- await this.enterValue(elementLocator, value, timeout);
578
+ throw new error.TimeoutError(`Exceeded maximum clearing attempts, to the '${elementLocator}' element`);
579
+ }
580
+
581
+ async enterValue(elementLocator: By, text: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
582
+ if (elementLocator.toString().toLocaleLowerCase().includes('password')) {
583
+ Logger.trace(`${elementLocator} text: ***`);
584
+ } else {
585
+ Logger.trace(`${elementLocator} text: ${text}`);
706
586
  }
707
587
 
708
- // method is useful to debug page object elements
709
- async highLightElement(element: WebElement): Promise<void> {
710
- await this.getDriver().executeScript('arguments[0].style.border=\'2px solid red\'', element);
588
+ await this.waitVisibility(elementLocator, timeout);
589
+ await this.clear(elementLocator);
590
+ await this.waitAttributeValue(elementLocator, 'value', '', timeout);
591
+ await this.type(elementLocator, text, timeout);
592
+ await this.waitAttributeValue(elementLocator, 'value', text, timeout);
593
+ }
594
+
595
+ async waitAndSwitchToFrame(iframeLocator: By, timeout: number): Promise<void> {
596
+ Logger.trace(`${iframeLocator}`);
597
+
598
+ await this.driver.wait(until.ableToSwitchToFrame(iframeLocator), timeout);
599
+ }
600
+
601
+ async waitAndGetText(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<string> {
602
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
603
+ const attempts: number = Math.ceil(timeout / polling);
604
+
605
+ Logger.trace(`${elementLocator}`);
606
+
607
+ for (let i: number = 0; i < attempts; i++) {
608
+ let element: WebElement;
609
+ try {
610
+ element = await this.waitVisibility(elementLocator, polling);
611
+ } catch (err) {
612
+ if (i >= attempts - 1) {
613
+ Logger.error(`failed with exception, out of attempts - ${err}`);
614
+ throw err;
615
+ }
616
+
617
+ if (err instanceof error.TimeoutError) {
618
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
619
+ continue;
620
+ }
621
+
622
+ Logger.error(`failed with an unexpected exception - ${err}`);
623
+ throw err;
624
+ }
625
+
626
+ try {
627
+ return await element.getText();
628
+ } catch (err) {
629
+ if (err instanceof error.StaleElementReferenceError) {
630
+ await this.wait(polling);
631
+ continue;
632
+ }
633
+
634
+ Logger.error(`failed with an unexpected exception - ${err}`);
635
+ throw err;
636
+ }
711
637
  }
712
638
 
713
- getDriver(): ThenableWebDriver {
714
- Logger.trace('DriverHelper.getDriver');
639
+ throw new error.TimeoutError(`Exceeded maximum text obtaining attempts, from the '${elementLocator}' element`);
640
+ }
641
+
642
+ async waitAndGetValue(elementLocator: By, timeout: number): Promise<string> {
643
+ Logger.trace(`${elementLocator}`);
644
+
645
+ return await this.waitAndGetElementAttribute(elementLocator, 'value', timeout);
646
+ }
647
+
648
+ async waitUntilTrue(callback: any, timeout: number): Promise<void> {
649
+ Logger.trace();
650
+
651
+ await this.driver.wait(callback, timeout);
652
+ }
715
653
 
716
- return this.driver;
654
+ async scrollTo(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
655
+ const polling: number = TimeoutConstants.TS_SELENIUM_DEFAULT_POLLING;
656
+ const attempts: number = Math.ceil(timeout / polling);
657
+
658
+ Logger.trace(`${elementLocator}`);
659
+
660
+ for (let i: number = 0; i < attempts; i++) {
661
+ let element: WebElement;
662
+ try {
663
+ element = await this.waitPresence(elementLocator, polling);
664
+ } catch (err) {
665
+ if (i >= attempts - 1) {
666
+ Logger.error(`failed with exception, out of attempts - ${err}`);
667
+ throw err;
668
+ }
669
+
670
+ if (err instanceof error.TimeoutError) {
671
+ Logger.trace(`polling timed out attempt #${(i + 1)}, retrying with ${polling}ms timeout`);
672
+ continue;
673
+ }
674
+
675
+ Logger.error(`failed with an unexpected exception - ${err}`);
676
+ throw err;
677
+ }
678
+
679
+ try {
680
+ await this.getDriver()
681
+ .executeScript('arguments[0].scrollIntoView(true);', element);
682
+ return;
683
+ } catch (err) {
684
+ if (err instanceof error.StaleElementReferenceError) {
685
+ await this.wait(polling);
686
+ continue;
687
+ }
688
+
689
+ Logger.error(`failed with an unexpected exception - ${err}`);
690
+ throw err;
691
+ }
717
692
  }
693
+
694
+ throw new error.TimeoutError(`Exceeded maximum mouse move attempts, for the '${elementLocator}' element`);
695
+ }
696
+
697
+ async scrollToAndClick(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
698
+ await this.scrollTo(elementLocator, timeout);
699
+ await this.waitAndClick(elementLocator, timeout);
700
+ }
701
+
702
+ async scrollToAndEnterValue(elementLocator: By, value: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
703
+ await this.scrollTo(elementLocator, timeout);
704
+ await this.enterValue(elementLocator, value, timeout);
705
+ }
706
+
707
+ // method is useful to debug page object elements
708
+ async highLightElement(element: WebElement): Promise<void> {
709
+ await this.getDriver().executeScript('arguments[0].style.border=\'2px solid red\'', element);
710
+ }
711
+
712
+ getDriver(): ThenableWebDriver {
713
+ Logger.trace();
714
+
715
+ return this.driver;
716
+ }
718
717
  }