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