@oracle/oraclejet-selenium-driver 19.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DriverManager/DriverManager.cjs +334 -0
- package/DriverManager/DriverManager.cjs.map +1 -0
- package/DriverManager/DriverManager.d.ts +216 -0
- package/DriverManager/DriverManager.mjs +330 -0
- package/DriverManager/DriverManager.mjs.map +1 -0
- package/DriverManager/index.cjs +10 -0
- package/DriverManager/index.cjs.map +1 -0
- package/DriverManager/index.d.ts +1 -0
- package/DriverManager/index.mjs +2 -0
- package/DriverManager/index.mjs.map +1 -0
- package/UNSAFE_SeleniumDriver/SeleniumDriver.cjs +169 -0
- package/UNSAFE_SeleniumDriver/SeleniumDriver.cjs.map +1 -0
- package/UNSAFE_SeleniumDriver/SeleniumDriver.d.ts +42 -0
- package/UNSAFE_SeleniumDriver/SeleniumDriver.mjs +165 -0
- package/UNSAFE_SeleniumDriver/SeleniumDriver.mjs.map +1 -0
- package/UNSAFE_SeleniumDriver/index.cjs +10 -0
- package/UNSAFE_SeleniumDriver/index.cjs.map +1 -0
- package/UNSAFE_SeleniumDriver/index.d.ts +1 -0
- package/UNSAFE_SeleniumDriver/index.mjs +2 -0
- package/UNSAFE_SeleniumDriver/index.mjs.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { Capabilities, Builder } from 'selenium-webdriver';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @private
|
|
5
|
+
*/
|
|
6
|
+
const defaultConfigName = '';
|
|
7
|
+
/**
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
const defaultCapabilities = new Capabilities({
|
|
11
|
+
autoWebview: true,
|
|
12
|
+
browserName: 'chrome'
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* @private
|
|
16
|
+
*/
|
|
17
|
+
const defaultTimeouts = {
|
|
18
|
+
implicit: 0,
|
|
19
|
+
pageLoad: 30000,
|
|
20
|
+
script: 30000
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
const configs = {};
|
|
26
|
+
/**
|
|
27
|
+
* @private
|
|
28
|
+
*/
|
|
29
|
+
let currentInstance = {
|
|
30
|
+
configName: undefined,
|
|
31
|
+
driver: undefined
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The delay, in milliseconds, that the manager will wait after the driver is
|
|
35
|
+
* release to see if there are pending requests for a driver instance. If no
|
|
36
|
+
* requests exist, then the driver is closed, and subsequent requests will
|
|
37
|
+
* receive a new instance.
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
const quitDelay = 500;
|
|
41
|
+
/**
|
|
42
|
+
* @private
|
|
43
|
+
*/
|
|
44
|
+
let builder;
|
|
45
|
+
/**
|
|
46
|
+
* The NodeJS.Timer used to cleanup the driver instance if no subsequent test
|
|
47
|
+
* asks for the driver. The type (NodeJS.Timer) cannot be defined here because
|
|
48
|
+
* typedoc cannot resolve the NodeJS namespace, so we infer it by calling
|
|
49
|
+
* setTimeout instead.
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
let releaseTimer = setTimeout(() => true, 0);
|
|
53
|
+
/**
|
|
54
|
+
* Manage instances of [WebDriver](index._internal_.WebDriver.html)
|
|
55
|
+
* to be used by the tests. DriverManager
|
|
56
|
+
* allows a single place where the WebDriver instance can be configured and
|
|
57
|
+
* reused. Traditionally, tests instantiate the WebDriver instance on their own,
|
|
58
|
+
* passing configurations such as the browser to use:
|
|
59
|
+
* ```javascript
|
|
60
|
+
* let driver = new Builder().withCapabilities({
|
|
61
|
+
* browserName: "chrome"
|
|
62
|
+
* }).build()
|
|
63
|
+
* ```
|
|
64
|
+
* This boilerplate code then has to be copied to every test. Additionally, if
|
|
65
|
+
* the capabilities need to change (say, running against a different browser),
|
|
66
|
+
* that change must be applied to all test files.
|
|
67
|
+
*
|
|
68
|
+
* DriverManager addresses this problem by centralizing the place whereby
|
|
69
|
+
* the configuration is done, and persists that configuration for all
|
|
70
|
+
* subsequent requests for the WebDriver instance. The configuration only needs
|
|
71
|
+
* to be set once in a "setup" file, and tests retrieve the configured instance
|
|
72
|
+
* without needing to define anything else.
|
|
73
|
+
*
|
|
74
|
+
* A sample <code>mocha-setup.ts</code> file which configures DriverManager
|
|
75
|
+
* ```javascript
|
|
76
|
+
* import { DriverManager } from "@oracle/oraclejet-selenium-driver/DriverManager";
|
|
77
|
+
*
|
|
78
|
+
* DriverManager.registerConfig({
|
|
79
|
+
* capabilities: new Capabilities({
|
|
80
|
+
* browserName: "chrome"
|
|
81
|
+
* })
|
|
82
|
+
* })
|
|
83
|
+
* ```
|
|
84
|
+
* This setup test script should be run before any other tests.
|
|
85
|
+
* ```bash
|
|
86
|
+
* $ node node_modules/mocha/bin/mocha --require=ts-node/register mocha-setup.ts other-test.spec.ts ...
|
|
87
|
+
* ```
|
|
88
|
+
* Test files are agnostic of the driver configuration, and simply get the instance
|
|
89
|
+
* by calling <code>getDriver()</code>
|
|
90
|
+
* ```javascript
|
|
91
|
+
* import { DriverManager } from "@oracle/oraclejet-selenium-driver/DriverManager";
|
|
92
|
+
*
|
|
93
|
+
* describe("My test suite", function() {
|
|
94
|
+
* let driver: WebDriver;
|
|
95
|
+
*
|
|
96
|
+
* before(async function() {
|
|
97
|
+
* driver = await DriverManager.getDriver();
|
|
98
|
+
* })
|
|
99
|
+
* it("open a page to test", async function() {
|
|
100
|
+
* await driver.get("...")
|
|
101
|
+
* })
|
|
102
|
+
* after(async function() {
|
|
103
|
+
* await DriverManager.releaseDriver(driver);
|
|
104
|
+
* })
|
|
105
|
+
* })
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* ## Set default timeouts for WebDriver from Mocha.
|
|
109
|
+
* When Mocha is used to start the WebDriver tests, there are two sets of timeout
|
|
110
|
+
* values--one from Mocha and one from WebDriver. This causes some confusion as
|
|
111
|
+
* the command-line argument <code>--timeout=nnn</code> is typically the only one
|
|
112
|
+
* set and assumed to be the only timeout value in play. However, WebDriver has
|
|
113
|
+
* its own set of timeout values whose defaults are sometimes longer than what's
|
|
114
|
+
* set for Mocha. When this happens, WebDriver may be waiting on a condition to
|
|
115
|
+
* timeout, but Mocha has errored the test because its own timeout was exceeded.
|
|
116
|
+
* To ensure that WebDriver timeout conditions are properly reported to the test
|
|
117
|
+
* runner (Mocha), its timeout values must be set to a value shorter than the
|
|
118
|
+
* runner's. This is typically done in the setup test, and set to some factor of
|
|
119
|
+
* the Mocha timeout.
|
|
120
|
+
*
|
|
121
|
+
* ### Set WebDriver timeout to 1/4 of Mocha
|
|
122
|
+
* ```javascript
|
|
123
|
+
* const mochaTimeout = this.timeouts();
|
|
124
|
+
* const wdTimeout = mochaTimeout / 4;
|
|
125
|
+
* DriverManager.registerConfig({
|
|
126
|
+
* timeouts: {
|
|
127
|
+
* pageLoad: wdTimeout,
|
|
128
|
+
* script: wdTimeout,
|
|
129
|
+
* implicit: wdTimeout
|
|
130
|
+
* }
|
|
131
|
+
* });
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
*/
|
|
135
|
+
class DriverManager {
|
|
136
|
+
/**
|
|
137
|
+
* Optionally set the {@link Builder}
|
|
138
|
+
* instance used by DriverManager to create WebDriver.
|
|
139
|
+
* The Builder allows different settings for thigns such as the remote server,
|
|
140
|
+
* proxies, and other runtime options often needed when running in distributed
|
|
141
|
+
* environments.
|
|
142
|
+
* The instance can be preconfigured with capabilities, and any additional
|
|
143
|
+
* capabilities from [[registerConfig]] will also be applied during the
|
|
144
|
+
* creation process. If no Builder is explicitly passed, a default one will
|
|
145
|
+
* be used.
|
|
146
|
+
* If setting a custom Builder, this function must be called before the first
|
|
147
|
+
* test calls [[getDriver]], and must only be called once per test run. If called
|
|
148
|
+
* multiple times or after [[getDriver]], an error will be thrown.
|
|
149
|
+
* @param b A builder instance
|
|
150
|
+
*/
|
|
151
|
+
static setBuilder(b) {
|
|
152
|
+
if (builder) {
|
|
153
|
+
throw Error('DriverManager Builder instance has already been set, and cannot be set again');
|
|
154
|
+
}
|
|
155
|
+
builder = b;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Register a configuration for WebDriver instances. Configurations consist of
|
|
159
|
+
* {@link Capabilities} and/or {@link Timeouts}.
|
|
160
|
+
* This configuration is used by [[getDriver]] to retrieve a configured WebDriver
|
|
161
|
+
* instance.
|
|
162
|
+
* @param config The driver configuration
|
|
163
|
+
* @param name An optional name to assocaite with the config. If no name is given,
|
|
164
|
+
* the config will be the default. If a name is given, its configuration is merged with the default
|
|
165
|
+
* with its values taking precedence.
|
|
166
|
+
*
|
|
167
|
+
* ### Register a default config
|
|
168
|
+
* ```javascript
|
|
169
|
+
* DriverManager.registerConfig(
|
|
170
|
+
* {
|
|
171
|
+
* capabilities: new Capabilities({
|
|
172
|
+
* browserName: "chrome"
|
|
173
|
+
* }),
|
|
174
|
+
* timeouts: {
|
|
175
|
+
* implicit: 5000
|
|
176
|
+
* }
|
|
177
|
+
* }
|
|
178
|
+
* );
|
|
179
|
+
* ```
|
|
180
|
+
* ### Register a Firefox config. These capabilities override any matching ones set in the default
|
|
181
|
+
* ```javascript
|
|
182
|
+
* DriverManager.registerConfig(
|
|
183
|
+
* {
|
|
184
|
+
* capabilities: new Capabilities({
|
|
185
|
+
* browserName: "firefox",
|
|
186
|
+
* hideAlerts: true
|
|
187
|
+
* })
|
|
188
|
+
* },
|
|
189
|
+
* "firefox-no-alerts"
|
|
190
|
+
* );
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
static registerConfig(config, name) {
|
|
194
|
+
configs[name || defaultConfigName] = config;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get a {@link WebDriver}
|
|
198
|
+
* instance for a given configuration. If no configName is given, the returned
|
|
199
|
+
* driver will use the default configuration.
|
|
200
|
+
* @see [[registerConfig]]
|
|
201
|
+
*
|
|
202
|
+
* ### Get driver with default capabilities
|
|
203
|
+
* ```javascript
|
|
204
|
+
* let driver = await DriverManager.getDriver();
|
|
205
|
+
* ```
|
|
206
|
+
* ### Configure and get Firefox driver
|
|
207
|
+
* ```javascript
|
|
208
|
+
* // mocha-setup.ts
|
|
209
|
+
* DriverManager.registerConfig(
|
|
210
|
+
* {
|
|
211
|
+
* browserName: "firefox"
|
|
212
|
+
* },
|
|
213
|
+
* "firefox-config");
|
|
214
|
+
* // test.spec.ts
|
|
215
|
+
* let driver = await DriverManager.getDriver("firefox-config");
|
|
216
|
+
* ```
|
|
217
|
+
* @param configName An optional configuration name, registered through
|
|
218
|
+
* [[registerConfig]], whose set will be applied to the driver instance. If no
|
|
219
|
+
* name is given, the default configuration with the "chrome" browser
|
|
220
|
+
* will be used. If the given configName doesn't exist, an error will be thrown.
|
|
221
|
+
* @return A Promise that resolves to a WebDriver instance, configured with
|
|
222
|
+
* custom capabilities for the given configName, or the default capabilities
|
|
223
|
+
* if none is specified.
|
|
224
|
+
*/
|
|
225
|
+
static async getDriver(configName) {
|
|
226
|
+
clearTimeout(releaseTimer);
|
|
227
|
+
configName = configName || defaultConfigName;
|
|
228
|
+
if (configName === currentInstance.configName) {
|
|
229
|
+
// Test if current driver is still valid
|
|
230
|
+
try {
|
|
231
|
+
if (currentInstance.driver) {
|
|
232
|
+
await currentInstance.driver.getCurrentUrl();
|
|
233
|
+
return currentInstance.driver;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
// no driver or already quit
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
await quitCurrentDriver();
|
|
241
|
+
return createDriver(configName);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Gets the current driver instance, if one exists, otherwise create and
|
|
245
|
+
* return the default one. This method is useful for test setups which evaluate
|
|
246
|
+
* the outcome of the previous test to capture screenshots on failures. After-
|
|
247
|
+
* scripts call <code>getCurrentDriver</code> to get the instance of the driver
|
|
248
|
+
* that experienced the test failure, then capture the screenshot from it.
|
|
249
|
+
*/
|
|
250
|
+
static async getCurrentDriver() {
|
|
251
|
+
return DriverManager.getDriver(currentInstance.configName);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Release the WebDriver instance from use. Called when each test is done
|
|
255
|
+
* with its driver usage, typically, in the <code>after/afterAll</code> function.
|
|
256
|
+
* If `immediate` is not given, this method will delay a brief time before telling
|
|
257
|
+
* the driver to quit, allowing subsequent tests to reuse the same instance.
|
|
258
|
+
* If a call to {@link getDriver} is called before the timeout is reached,
|
|
259
|
+
* then the release is aborted.
|
|
260
|
+
* If `immediate` is true, then a Promise<void> will be returned and the driver
|
|
261
|
+
* told to quit immediately.
|
|
262
|
+
* @param driver The WebDriver instance
|
|
263
|
+
* @param immediate Immediately release the driver without delay
|
|
264
|
+
* @returns Promise<void> A Promise that will resolve when the driver is released if
|
|
265
|
+
* `immediate` is true, otherwise, void
|
|
266
|
+
*/
|
|
267
|
+
static releaseDriver(driver, immediate = false) {
|
|
268
|
+
clearTimeout(releaseTimer);
|
|
269
|
+
return new Promise((resolve) => {
|
|
270
|
+
if (immediate) {
|
|
271
|
+
resolve(quitDriver(driver));
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
releaseTimer = setTimeout(() => quitDriver(driver), quitDelay);
|
|
275
|
+
resolve();
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
DriverManager.registerConfig({ capabilities: defaultCapabilities, timeouts: defaultTimeouts });
|
|
281
|
+
/**
|
|
282
|
+
* Create a WebDriver instance from the given configuration name. The config should
|
|
283
|
+
* already be registered via [registerConfig].
|
|
284
|
+
* @param configName The configuration name used to retrieve the configuration
|
|
285
|
+
* object for the driver instance
|
|
286
|
+
* @return A Promise which resolves to the configured WebDriver instance
|
|
287
|
+
* @private
|
|
288
|
+
*/
|
|
289
|
+
async function createDriver(configName) {
|
|
290
|
+
const config = configs[configName];
|
|
291
|
+
if (!config) {
|
|
292
|
+
throw Error(`No driver configuration exists for "${configName}"`);
|
|
293
|
+
}
|
|
294
|
+
// Merge default capabilities with custom ones
|
|
295
|
+
const caps = new Capabilities(configs[defaultConfigName].capabilities);
|
|
296
|
+
if (config.capabilities) {
|
|
297
|
+
caps.merge(config.capabilities);
|
|
298
|
+
}
|
|
299
|
+
// Merge default timeouts with custom ones
|
|
300
|
+
const timeouts = Object.assign({}, configs[defaultConfigName].timeouts, config.timeouts);
|
|
301
|
+
if (!builder) {
|
|
302
|
+
builder = new Builder();
|
|
303
|
+
}
|
|
304
|
+
const driver = builder.withCapabilities(caps).build();
|
|
305
|
+
currentInstance = { configName, driver };
|
|
306
|
+
await driver.manage().setTimeouts(timeouts);
|
|
307
|
+
return driver;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* @private
|
|
311
|
+
*/
|
|
312
|
+
function quitCurrentDriver() {
|
|
313
|
+
return quitDriver(currentInstance.driver);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* @private
|
|
317
|
+
*/
|
|
318
|
+
function quitDriver(driver) {
|
|
319
|
+
if (driver) {
|
|
320
|
+
currentInstance = {
|
|
321
|
+
configName: undefined,
|
|
322
|
+
driver: undefined
|
|
323
|
+
};
|
|
324
|
+
return driver.quit().catch(console.warn);
|
|
325
|
+
}
|
|
326
|
+
return Promise.resolve();
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export { DriverManager };
|
|
330
|
+
//# sourceMappingURL=DriverManager.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DriverManager.mjs","sources":["../../src/DriverManager/DriverManager.ts"],"sourcesContent":["import { Builder, Capabilities, WebDriver } from 'selenium-webdriver';\n\ninterface Timeouts {\n /**\n * The timeout value for script execution. Default 30000\n */\n script?: number;\n /**\n * The timeout value for page loading (and to be ready). Default 30000\n */\n pageLoad?: number;\n /**\n * The timeout value for finding an element on the page. Default 0\n */\n implicit?: number;\n}\nexport interface DriverConfiguration {\n /**\n * The WebDriver Capabilties for the configuration\n */\n capabilities?: Capabilities | Record<string, any>;\n /**\n * The WebDriver timeout values for the configuration\n */\n timeouts?: Timeouts;\n}\n\n/**\n * @private\n */\nconst defaultConfigName = '';\n/**\n * @private\n */\nconst defaultCapabilities = new Capabilities({\n autoWebview: true,\n browserName: 'chrome'\n});\n/**\n * @private\n */\nconst defaultTimeouts: Timeouts = {\n implicit: 0,\n pageLoad: 30000,\n script: 30000\n};\n/**\n * @private\n */\nconst configs: Record<string, DriverConfiguration> = {};\n/**\n * @private\n */\nlet currentInstance: { configName: string | undefined; driver: WebDriver | undefined } = {\n configName: undefined,\n driver: undefined\n};\n\n/**\n * The delay, in milliseconds, that the manager will wait after the driver is\n * release to see if there are pending requests for a driver instance. If no\n * requests exist, then the driver is closed, and subsequent requests will\n * receive a new instance.\n * @private\n */\nconst quitDelay = 500;\n/**\n * @private\n */\nlet builder: Builder;\n/**\n * The NodeJS.Timer used to cleanup the driver instance if no subsequent test\n * asks for the driver. The type (NodeJS.Timer) cannot be defined here because\n * typedoc cannot resolve the NodeJS namespace, so we infer it by calling\n * setTimeout instead.\n * @private\n */\nlet releaseTimer = setTimeout(() => true, 0);\n\n/**\n * Manage instances of [WebDriver](index._internal_.WebDriver.html)\n * to be used by the tests. DriverManager\n * allows a single place where the WebDriver instance can be configured and\n * reused. Traditionally, tests instantiate the WebDriver instance on their own,\n * passing configurations such as the browser to use:\n * ```javascript\n * let driver = new Builder().withCapabilities({\n * browserName: \"chrome\"\n * }).build()\n * ```\n * This boilerplate code then has to be copied to every test. Additionally, if\n * the capabilities need to change (say, running against a different browser),\n * that change must be applied to all test files.\n *\n * DriverManager addresses this problem by centralizing the place whereby\n * the configuration is done, and persists that configuration for all\n * subsequent requests for the WebDriver instance. The configuration only needs\n * to be set once in a \"setup\" file, and tests retrieve the configured instance\n * without needing to define anything else.\n *\n * A sample <code>mocha-setup.ts</code> file which configures DriverManager\n * ```javascript\n * import { DriverManager } from \"@oracle/oraclejet-selenium-driver/DriverManager\";\n *\n * DriverManager.registerConfig({\n * capabilities: new Capabilities({\n * browserName: \"chrome\"\n * })\n * })\n * ```\n * This setup test script should be run before any other tests.\n * ```bash\n * $ node node_modules/mocha/bin/mocha --require=ts-node/register mocha-setup.ts other-test.spec.ts ...\n * ```\n * Test files are agnostic of the driver configuration, and simply get the instance\n * by calling <code>getDriver()</code>\n * ```javascript\n * import { DriverManager } from \"@oracle/oraclejet-selenium-driver/DriverManager\";\n *\n * describe(\"My test suite\", function() {\n * let driver: WebDriver;\n *\n * before(async function() {\n * driver = await DriverManager.getDriver();\n * })\n * it(\"open a page to test\", async function() {\n * await driver.get(\"...\")\n * })\n * after(async function() {\n * await DriverManager.releaseDriver(driver);\n * })\n * })\n * ```\n *\n * ## Set default timeouts for WebDriver from Mocha.\n * When Mocha is used to start the WebDriver tests, there are two sets of timeout\n * values--one from Mocha and one from WebDriver. This causes some confusion as\n * the command-line argument <code>--timeout=nnn</code> is typically the only one\n * set and assumed to be the only timeout value in play. However, WebDriver has\n * its own set of timeout values whose defaults are sometimes longer than what's\n * set for Mocha. When this happens, WebDriver may be waiting on a condition to\n * timeout, but Mocha has errored the test because its own timeout was exceeded.\n * To ensure that WebDriver timeout conditions are properly reported to the test\n * runner (Mocha), its timeout values must be set to a value shorter than the\n * runner's. This is typically done in the setup test, and set to some factor of\n * the Mocha timeout.\n *\n * ### Set WebDriver timeout to 1/4 of Mocha\n * ```javascript\n * const mochaTimeout = this.timeouts();\n * const wdTimeout = mochaTimeout / 4;\n * DriverManager.registerConfig({\n * timeouts: {\n * pageLoad: wdTimeout,\n * script: wdTimeout,\n * implicit: wdTimeout\n * }\n * });\n * ```\n *\n */\nexport class DriverManager {\n /**\n * Optionally set the {@link Builder}\n * instance used by DriverManager to create WebDriver.\n * The Builder allows different settings for thigns such as the remote server,\n * proxies, and other runtime options often needed when running in distributed\n * environments.\n * The instance can be preconfigured with capabilities, and any additional\n * capabilities from [[registerConfig]] will also be applied during the\n * creation process. If no Builder is explicitly passed, a default one will\n * be used.\n * If setting a custom Builder, this function must be called before the first\n * test calls [[getDriver]], and must only be called once per test run. If called\n * multiple times or after [[getDriver]], an error will be thrown.\n * @param b A builder instance\n */\n public static setBuilder(b: Builder) {\n if (builder) {\n throw Error('DriverManager Builder instance has already been set, and cannot be set again');\n }\n builder = b;\n }\n /**\n * Register a configuration for WebDriver instances. Configurations consist of\n * {@link Capabilities} and/or {@link Timeouts}.\n * This configuration is used by [[getDriver]] to retrieve a configured WebDriver\n * instance.\n * @param config The driver configuration\n * @param name An optional name to assocaite with the config. If no name is given,\n * the config will be the default. If a name is given, its configuration is merged with the default\n * with its values taking precedence.\n *\n * ### Register a default config\n * ```javascript\n * DriverManager.registerConfig(\n * {\n * capabilities: new Capabilities({\n * browserName: \"chrome\"\n * }),\n * timeouts: {\n * implicit: 5000\n * }\n * }\n * );\n * ```\n * ### Register a Firefox config. These capabilities override any matching ones set in the default\n * ```javascript\n * DriverManager.registerConfig(\n * {\n * capabilities: new Capabilities({\n * browserName: \"firefox\",\n * hideAlerts: true\n * })\n * },\n * \"firefox-no-alerts\"\n * );\n * ```\n */\n public static registerConfig(config: DriverConfiguration, name?: string): void {\n configs[name || defaultConfigName] = config;\n }\n\n /**\n * Get a {@link WebDriver}\n * instance for a given configuration. If no configName is given, the returned\n * driver will use the default configuration.\n * @see [[registerConfig]]\n *\n * ### Get driver with default capabilities\n * ```javascript\n * let driver = await DriverManager.getDriver();\n * ```\n * ### Configure and get Firefox driver\n * ```javascript\n * // mocha-setup.ts\n * DriverManager.registerConfig(\n * {\n * browserName: \"firefox\"\n * },\n * \"firefox-config\");\n * // test.spec.ts\n * let driver = await DriverManager.getDriver(\"firefox-config\");\n * ```\n * @param configName An optional configuration name, registered through\n * [[registerConfig]], whose set will be applied to the driver instance. If no\n * name is given, the default configuration with the \"chrome\" browser\n * will be used. If the given configName doesn't exist, an error will be thrown.\n * @return A Promise that resolves to a WebDriver instance, configured with\n * custom capabilities for the given configName, or the default capabilities\n * if none is specified.\n */\n public static async getDriver(configName?: string): Promise<WebDriver> {\n clearTimeout(releaseTimer);\n configName = configName || defaultConfigName;\n\n if (configName === currentInstance.configName) {\n // Test if current driver is still valid\n try {\n if (currentInstance.driver) {\n await currentInstance.driver.getCurrentUrl();\n return currentInstance.driver;\n }\n } catch {\n // no driver or already quit\n }\n }\n\n await quitCurrentDriver();\n return createDriver(configName);\n }\n\n /**\n * Gets the current driver instance, if one exists, otherwise create and\n * return the default one. This method is useful for test setups which evaluate\n * the outcome of the previous test to capture screenshots on failures. After-\n * scripts call <code>getCurrentDriver</code> to get the instance of the driver\n * that experienced the test failure, then capture the screenshot from it.\n */\n public static async getCurrentDriver(): Promise<WebDriver> {\n return DriverManager.getDriver(currentInstance.configName);\n }\n\n /**\n * Release the WebDriver instance from use. Called when each test is done\n * with its driver usage, typically, in the <code>after/afterAll</code> function.\n * If `immediate` is not given, this method will delay a brief time before telling\n * the driver to quit, allowing subsequent tests to reuse the same instance.\n * If a call to {@link getDriver} is called before the timeout is reached,\n * then the release is aborted.\n * If `immediate` is true, then a Promise<void> will be returned and the driver\n * told to quit immediately.\n * @param driver The WebDriver instance\n * @param immediate Immediately release the driver without delay\n * @returns Promise<void> A Promise that will resolve when the driver is released if\n * `immediate` is true, otherwise, void\n */\n public static releaseDriver(driver: WebDriver, immediate = false): Promise<void> {\n clearTimeout(releaseTimer);\n return new Promise((resolve) => {\n if (immediate) {\n resolve(quitDriver(driver));\n } else {\n releaseTimer = setTimeout(() => quitDriver(driver), quitDelay);\n resolve();\n }\n });\n }\n}\nDriverManager.registerConfig({ capabilities: defaultCapabilities, timeouts: defaultTimeouts });\n\n/**\n * Create a WebDriver instance from the given configuration name. The config should\n * already be registered via [registerConfig].\n * @param configName The configuration name used to retrieve the configuration\n * object for the driver instance\n * @return A Promise which resolves to the configured WebDriver instance\n * @private\n */\nasync function createDriver(configName: string) {\n const config = configs[configName];\n if (!config) {\n throw Error(`No driver configuration exists for \"${configName}\"`);\n }\n // Merge default capabilities with custom ones\n const caps = new Capabilities(configs[defaultConfigName].capabilities);\n if (config.capabilities) {\n caps.merge(config.capabilities);\n }\n // Merge default timeouts with custom ones\n const timeouts = Object.assign({}, configs[defaultConfigName].timeouts, config.timeouts);\n if (!builder) {\n builder = new Builder();\n }\n\n const driver = builder.withCapabilities(caps).build();\n currentInstance = { configName, driver };\n await driver.manage().setTimeouts(timeouts);\n return driver;\n}\n\n/**\n * @private\n */\nfunction quitCurrentDriver() {\n return quitDriver(currentInstance.driver);\n}\n\n/**\n * @private\n */\nfunction quitDriver(driver?: WebDriver) {\n if (driver) {\n currentInstance = {\n configName: undefined,\n driver: undefined\n };\n return driver.quit().catch(console.warn);\n }\n return Promise.resolve();\n}\n"],"names":[],"mappings":";;AA2BA;;AAEG;AACH,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B;;AAEG;AACH,MAAM,mBAAmB,GAAG,IAAI,YAAY,CAAC;AAC3C,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,WAAW,EAAE,QAAQ;AACtB,CAAA,CAAC,CAAC;AACH;;AAEG;AACH,MAAM,eAAe,GAAa;AAChC,IAAA,QAAQ,EAAE,CAAC;AACX,IAAA,QAAQ,EAAE,KAAK;AACf,IAAA,MAAM,EAAE,KAAK;CACd,CAAC;AACF;;AAEG;AACH,MAAM,OAAO,GAAwC,EAAE,CAAC;AACxD;;AAEG;AACH,IAAI,eAAe,GAAsE;AACvF,IAAA,UAAU,EAAE,SAAS;AACrB,IAAA,MAAM,EAAE,SAAS;CAClB,CAAC;AAEF;;;;;;AAMG;AACH,MAAM,SAAS,GAAG,GAAG,CAAC;AACtB;;AAEG;AACH,IAAI,OAAgB,CAAC;AACrB;;;;;;AAMG;AACH,IAAI,YAAY,GAAG,UAAU,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFG;MACU,aAAa,CAAA;AACxB;;;;;;;;;;;;;;AAcG;IACI,OAAO,UAAU,CAAC,CAAU,EAAA;QACjC,IAAI,OAAO,EAAE;AACX,YAAA,MAAM,KAAK,CAAC,8EAA8E,CAAC,CAAC;SAC7F;QACD,OAAO,GAAG,CAAC,CAAC;KACb;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCG;AACI,IAAA,OAAO,cAAc,CAAC,MAA2B,EAAE,IAAa,EAAA;AACrE,QAAA,OAAO,CAAC,IAAI,IAAI,iBAAiB,CAAC,GAAG,MAAM,CAAC;KAC7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;AACI,IAAA,aAAa,SAAS,CAAC,UAAmB,EAAA;QAC/C,YAAY,CAAC,YAAY,CAAC,CAAC;AAC3B,QAAA,UAAU,GAAG,UAAU,IAAI,iBAAiB,CAAC;AAE7C,QAAA,IAAI,UAAU,KAAK,eAAe,CAAC,UAAU,EAAE;;AAE7C,YAAA,IAAI;AACF,gBAAA,IAAI,eAAe,CAAC,MAAM,EAAE;AAC1B,oBAAA,MAAM,eAAe,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;oBAC7C,OAAO,eAAe,CAAC,MAAM,CAAC;iBAC/B;aACF;AAAC,YAAA,MAAM;;aAEP;SACF;QAED,MAAM,iBAAiB,EAAE,CAAC;AAC1B,QAAA,OAAO,YAAY,CAAC,UAAU,CAAC,CAAC;KACjC;AAED;;;;;;AAMG;IACI,aAAa,gBAAgB,GAAA;QAClC,OAAO,aAAa,CAAC,SAAS,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;KAC5D;AAED;;;;;;;;;;;;;AAaG;AACI,IAAA,OAAO,aAAa,CAAC,MAAiB,EAAE,SAAS,GAAG,KAAK,EAAA;QAC9D,YAAY,CAAC,YAAY,CAAC,CAAC;AAC3B,QAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAI;YAC7B,IAAI,SAAS,EAAE;AACb,gBAAA,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;aAC7B;iBAAM;AACL,gBAAA,YAAY,GAAG,UAAU,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;AAC/D,gBAAA,OAAO,EAAE,CAAC;aACX;AACH,SAAC,CAAC,CAAC;KACJ;AACF,CAAA;AACD,aAAa,CAAC,cAAc,CAAC,EAAE,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;AAE/F;;;;;;;AAOG;AACH,eAAe,YAAY,CAAC,UAAkB,EAAA;AAC5C,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,MAAM,KAAK,CAAC,CAAA,oCAAA,EAAuC,UAAU,CAAA,CAAA,CAAG,CAAC,CAAC;KACnE;;AAED,IAAA,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,YAAY,CAAC,CAAC;AACvE,IAAA,IAAI,MAAM,CAAC,YAAY,EAAE;AACvB,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;KACjC;;AAED,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzF,IAAI,CAAC,OAAO,EAAE;AACZ,QAAA,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;KACzB;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;AACtD,IAAA,eAAe,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IACzC,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC5C,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;AAEG;AACH,SAAS,iBAAiB,GAAA;AACxB,IAAA,OAAO,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED;;AAEG;AACH,SAAS,UAAU,CAAC,MAAkB,EAAA;IACpC,IAAI,MAAM,EAAE;AACV,QAAA,eAAe,GAAG;AAChB,YAAA,UAAU,EAAE,SAAS;AACrB,YAAA,MAAM,EAAE,SAAS;SAClB,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1C;AACD,IAAA,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { type DriverConfiguration, DriverManager } from './DriverManager';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var UNSAFE_Driver = require('@oracle/oraclejet-testing/UNSAFE_Driver');
|
|
6
|
+
var seleniumWebdriver = require('selenium-webdriver');
|
|
7
|
+
|
|
8
|
+
const modifierKeys = {
|
|
9
|
+
SHIFT: seleniumWebdriver.Key.SHIFT,
|
|
10
|
+
CONTROL: seleniumWebdriver.Key.CONTROL,
|
|
11
|
+
CONTROL_COMMAND: seleniumWebdriver.Key.CONTROL,
|
|
12
|
+
ALT: seleniumWebdriver.Key.ALT
|
|
13
|
+
};
|
|
14
|
+
const keyMap = {
|
|
15
|
+
...modifierKeys,
|
|
16
|
+
BACKSPACE: seleniumWebdriver.Key.BACK_SPACE,
|
|
17
|
+
TAB: seleniumWebdriver.Key.TAB,
|
|
18
|
+
ENTER: seleniumWebdriver.Key.ENTER,
|
|
19
|
+
ESCAPE: seleniumWebdriver.Key.ESCAPE,
|
|
20
|
+
PAGE_UP: seleniumWebdriver.Key.PAGE_UP,
|
|
21
|
+
PAGE_DOWN: seleniumWebdriver.Key.PAGE_DOWN,
|
|
22
|
+
END: seleniumWebdriver.Key.END,
|
|
23
|
+
HOME: seleniumWebdriver.Key.HOME,
|
|
24
|
+
ARROW_LEFT: seleniumWebdriver.Key.ARROW_LEFT,
|
|
25
|
+
ARROW_UP: seleniumWebdriver.Key.ARROW_UP,
|
|
26
|
+
ARROW_RIGHT: seleniumWebdriver.Key.ARROW_RIGHT,
|
|
27
|
+
ARROW_DOWN: seleniumWebdriver.Key.ARROW_DOWN,
|
|
28
|
+
DELETE: seleniumWebdriver.Key.DELETE,
|
|
29
|
+
F1: seleniumWebdriver.Key.F1,
|
|
30
|
+
F2: seleniumWebdriver.Key.F2,
|
|
31
|
+
F3: seleniumWebdriver.Key.F3,
|
|
32
|
+
F4: seleniumWebdriver.Key.F4,
|
|
33
|
+
F5: seleniumWebdriver.Key.F5,
|
|
34
|
+
F6: seleniumWebdriver.Key.F6,
|
|
35
|
+
F7: seleniumWebdriver.Key.F7,
|
|
36
|
+
F8: seleniumWebdriver.Key.F8,
|
|
37
|
+
F9: seleniumWebdriver.Key.F9,
|
|
38
|
+
F10: seleniumWebdriver.Key.F10,
|
|
39
|
+
F11: seleniumWebdriver.Key.F11,
|
|
40
|
+
F12: seleniumWebdriver.Key.F12
|
|
41
|
+
};
|
|
42
|
+
let currentScriptTimeout;
|
|
43
|
+
class SeleniumDriver extends UNSAFE_Driver.TestDriverBase {
|
|
44
|
+
constructor(driver) {
|
|
45
|
+
super();
|
|
46
|
+
this._platform = '';
|
|
47
|
+
this._waitForElement = async (locator, parent) => {
|
|
48
|
+
try {
|
|
49
|
+
const el = await this.waitFor(() => parent.findElement(seleniumWebdriver.By.css(locator.css)), {
|
|
50
|
+
timeout: UNSAFE_Driver.getTimeouts().elementExistsTimeout
|
|
51
|
+
});
|
|
52
|
+
return Promise.resolve(wrapElement(el, this._waitForElement, this._waitForElements));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
throw Error(`No element matching query "${JSON.stringify(locator)}"`);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
this._waitForElements = async (locator, parent) => {
|
|
59
|
+
let matches;
|
|
60
|
+
try {
|
|
61
|
+
// loop to find at least 1 match
|
|
62
|
+
matches = await this.waitFor(async () => {
|
|
63
|
+
const all = await parent.findElements(seleniumWebdriver.By.css(locator.css));
|
|
64
|
+
if (all.length) {
|
|
65
|
+
return all;
|
|
66
|
+
}
|
|
67
|
+
return;
|
|
68
|
+
}, {
|
|
69
|
+
timeout: UNSAFE_Driver.getTimeouts().elementExistsTimeout
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
return Promise.resolve(Array.from(matches || []).map((m) => wrapElement(m, this._waitForElement, this._waitForElements)));
|
|
76
|
+
};
|
|
77
|
+
this._driver = driver;
|
|
78
|
+
}
|
|
79
|
+
async executeScript(script, ...args) {
|
|
80
|
+
await this._setDriverTimeouts();
|
|
81
|
+
return this._driver.executeScript(script, ...args);
|
|
82
|
+
}
|
|
83
|
+
async waitForElement(locator) {
|
|
84
|
+
return this._waitForElement(locator, this._driver);
|
|
85
|
+
}
|
|
86
|
+
async waitForElements(locator) {
|
|
87
|
+
return this._waitForElements(locator, this._driver);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get a TestElement for the given WebElement
|
|
91
|
+
* @param from The WebElement
|
|
92
|
+
* @returns A TestElement
|
|
93
|
+
*/
|
|
94
|
+
getTestElement(from) {
|
|
95
|
+
return wrapElement(from, this._waitForElement, this._waitForElements);
|
|
96
|
+
}
|
|
97
|
+
async sendKeys(element, ...text) {
|
|
98
|
+
await this._ensurePlatform();
|
|
99
|
+
return this.unwrapElement(element).sendKeys(...text.map(this._getPlatformKey.bind(this)));
|
|
100
|
+
}
|
|
101
|
+
async click(element, options = {}) {
|
|
102
|
+
await this._ensurePlatform();
|
|
103
|
+
const modifiers = options.modifiers || [];
|
|
104
|
+
const actions = this._driver.actions();
|
|
105
|
+
if (modifiers) {
|
|
106
|
+
modifiers.map(this._getPlatformKey.bind(this)).forEach((m) => actions.keyDown(m));
|
|
107
|
+
await actions.perform();
|
|
108
|
+
}
|
|
109
|
+
await this.unwrapElement(element).click();
|
|
110
|
+
return actions.clear();
|
|
111
|
+
}
|
|
112
|
+
unwrapElement(element) {
|
|
113
|
+
return element._el;
|
|
114
|
+
}
|
|
115
|
+
async _ensurePlatform() {
|
|
116
|
+
if (!this._platform) {
|
|
117
|
+
this._platform = (await this._driver.getCapabilities()).getPlatform() || 'unknown';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get the platform-specific key value for the key, if available.
|
|
122
|
+
* @param key The key value
|
|
123
|
+
* @returns A platform-specific value for the key, or the original key if none exists
|
|
124
|
+
*/
|
|
125
|
+
_getPlatformKey(key) {
|
|
126
|
+
if (typeof key === 'object') {
|
|
127
|
+
return UNSAFE_Driver.Keys.CONTROL_COMMAND === key
|
|
128
|
+
? this._platform === 'mac'
|
|
129
|
+
? seleniumWebdriver.Key.COMMAND
|
|
130
|
+
: seleniumWebdriver.Key.CONTROL
|
|
131
|
+
: keyMap[key.key];
|
|
132
|
+
}
|
|
133
|
+
return key;
|
|
134
|
+
}
|
|
135
|
+
_setDriverTimeouts() {
|
|
136
|
+
const { scriptTimeout } = UNSAFE_Driver.getTimeouts();
|
|
137
|
+
if (scriptTimeout !== currentScriptTimeout) {
|
|
138
|
+
currentScriptTimeout = scriptTimeout;
|
|
139
|
+
// set script timeout
|
|
140
|
+
// we don't set implicit (waitForElement) because we want to enforce our own behavior
|
|
141
|
+
return this._driver.manage().setTimeouts({
|
|
142
|
+
script: scriptTimeout
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function wrapElement(element, waitForElement, waitForElements) {
|
|
149
|
+
return new TestElementImpl(element, waitForElement, waitForElements);
|
|
150
|
+
}
|
|
151
|
+
class TestElementImpl {
|
|
152
|
+
constructor(element, waitForElement, waitForElements) {
|
|
153
|
+
this._el = element;
|
|
154
|
+
this._waitForElement = waitForElement;
|
|
155
|
+
this._waitForElements = waitForElements;
|
|
156
|
+
}
|
|
157
|
+
waitForElement(locator) {
|
|
158
|
+
return this._waitForElement(locator, this._el);
|
|
159
|
+
}
|
|
160
|
+
waitForElements(locator) {
|
|
161
|
+
return this._waitForElements(locator, this._el);
|
|
162
|
+
}
|
|
163
|
+
getAttribute(attrName) {
|
|
164
|
+
return this._el.getAttribute(attrName);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
exports.SeleniumDriver = SeleniumDriver;
|
|
169
|
+
//# sourceMappingURL=SeleniumDriver.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeleniumDriver.cjs","sources":["../../src/UNSAFE_SeleniumDriver/SeleniumDriver.ts"],"sourcesContent":["import {\n type ClickOptions,\n type KeyType,\n TestDriverBase,\n type TestElement,\n getTimeouts\n} from '@oracle/oraclejet-testing/UNSAFE_Driver';\nimport { Keys as TestingKeys } from '@oracle/oraclejet-testing/UNSAFE_Driver';\nimport { ElementLocator } from '@oracle/oraclejet-testing/UNSAFE_Locators';\nimport { By, Key as WebDriverKeys, WebDriver, WebElement } from 'selenium-webdriver';\n\ntype WaitForElementType = (\n locator: ElementLocator,\n parent: WebDriver | WebElement\n) => Promise<TestElement>;\n\ntype WaitForElementsType = (\n locator: ElementLocator,\n parent: WebDriver | WebElement\n) => Promise<TestElement[]>;\n\nconst modifierKeys = {\n SHIFT: WebDriverKeys.SHIFT,\n CONTROL: WebDriverKeys.CONTROL,\n CONTROL_COMMAND: WebDriverKeys.CONTROL,\n ALT: WebDriverKeys.ALT\n};\n\nconst keyMap: { [key: string]: string } = {\n ...modifierKeys,\n BACKSPACE: WebDriverKeys.BACK_SPACE,\n TAB: WebDriverKeys.TAB,\n ENTER: WebDriverKeys.ENTER,\n ESCAPE: WebDriverKeys.ESCAPE,\n PAGE_UP: WebDriverKeys.PAGE_UP,\n PAGE_DOWN: WebDriverKeys.PAGE_DOWN,\n END: WebDriverKeys.END,\n HOME: WebDriverKeys.HOME,\n ARROW_LEFT: WebDriverKeys.ARROW_LEFT,\n ARROW_UP: WebDriverKeys.ARROW_UP,\n ARROW_RIGHT: WebDriverKeys.ARROW_RIGHT,\n ARROW_DOWN: WebDriverKeys.ARROW_DOWN,\n DELETE: WebDriverKeys.DELETE,\n\n F1: WebDriverKeys.F1,\n F2: WebDriverKeys.F2,\n F3: WebDriverKeys.F3,\n F4: WebDriverKeys.F4,\n F5: WebDriverKeys.F5,\n F6: WebDriverKeys.F6,\n F7: WebDriverKeys.F7,\n F8: WebDriverKeys.F8,\n F9: WebDriverKeys.F9,\n F10: WebDriverKeys.F10,\n F11: WebDriverKeys.F11,\n F12: WebDriverKeys.F12\n};\n\nlet currentScriptTimeout: number | undefined;\n\nexport class SeleniumDriver extends TestDriverBase {\n private _driver: WebDriver;\n private _platform = '';\n\n constructor(driver: WebDriver) {\n super();\n this._driver = driver;\n }\n\n async executeScript<T>(script: string | ((...args: any) => T), ...args: any): Promise<T> {\n await this._setDriverTimeouts();\n return this._driver.executeScript<T>(script, ...args);\n }\n\n async waitForElement(locator: ElementLocator): Promise<TestElement> {\n return this._waitForElement(locator, this._driver);\n }\n\n async waitForElements(locator: ElementLocator): Promise<TestElement[]> {\n return this._waitForElements(locator, this._driver);\n }\n\n private _waitForElement = async (locator: ElementLocator, parent: WebDriver | WebElement) => {\n try {\n const el = await this.waitFor<Promise<WebElement>>(\n () => parent.findElement(By.css(locator.css)),\n {\n timeout: getTimeouts().elementExistsTimeout\n }\n );\n return Promise.resolve(wrapElement(el, this._waitForElement, this._waitForElements));\n } catch {\n throw Error(`No element matching query \"${JSON.stringify(locator)}\"`);\n }\n };\n\n private _waitForElements = async (locator: ElementLocator, parent: WebDriver | WebElement) => {\n let matches: WebElement[] | undefined;\n try {\n // loop to find at least 1 match\n matches = await this.waitFor<WebElement[] | undefined>(\n async () => {\n const all = await parent.findElements(By.css(locator.css));\n if (all.length) {\n return all;\n }\n return;\n },\n {\n timeout: getTimeouts().elementExistsTimeout\n }\n );\n } catch {\n return [];\n }\n return Promise.resolve(\n Array.from(matches || []).map((m) =>\n wrapElement(m, this._waitForElement, this._waitForElements)\n )\n );\n };\n\n /**\n * Get a TestElement for the given WebElement\n * @param from The WebElement\n * @returns A TestElement\n */\n getTestElement(from: WebElement) {\n return wrapElement(from, this._waitForElement, this._waitForElements);\n }\n\n async sendKeys(element: TestElement, ...text: (string | KeyType)[]): Promise<void> {\n await this._ensurePlatform();\n return this.unwrapElement(element).sendKeys(\n ...text.map<string>(this._getPlatformKey.bind(this))\n );\n }\n\n async click(element: TestElement, options: ClickOptions = {}) {\n await this._ensurePlatform();\n const modifiers = options.modifiers || [];\n const actions = this._driver.actions();\n if (modifiers) {\n modifiers.map(this._getPlatformKey.bind(this)).forEach((m) => actions.keyDown(m));\n await actions.perform();\n }\n await this.unwrapElement(element).click();\n return actions.clear();\n }\n\n unwrapElement<T = WebElement>(element: TestElement): T {\n return (element as TestElementImpl)._el as T;\n }\n\n private async _ensurePlatform() {\n if (!this._platform) {\n this._platform = (await this._driver.getCapabilities()).getPlatform() || 'unknown';\n }\n }\n\n /**\n * Get the platform-specific key value for the key, if available.\n * @param key The key value\n * @returns A platform-specific value for the key, or the original key if none exists\n */\n private _getPlatformKey(key: string | KeyType) {\n if (typeof key === 'object') {\n return TestingKeys.CONTROL_COMMAND === key\n ? this._platform === 'mac'\n ? WebDriverKeys.COMMAND\n : WebDriverKeys.CONTROL\n : keyMap[key.key];\n }\n return key;\n }\n\n private _setDriverTimeouts() {\n const { scriptTimeout } = getTimeouts();\n if (scriptTimeout !== currentScriptTimeout) {\n currentScriptTimeout = scriptTimeout;\n // set script timeout\n // we don't set implicit (waitForElement) because we want to enforce our own behavior\n return this._driver.manage().setTimeouts({\n script: scriptTimeout\n });\n }\n return;\n }\n}\n\nfunction wrapElement(\n element: WebElement,\n waitForElement: WaitForElementType,\n waitForElements: WaitForElementsType\n) {\n return new TestElementImpl(element, waitForElement, waitForElements);\n}\n\nclass TestElementImpl implements TestElement {\n _el: WebElement;\n _waitForElement: WaitForElementType;\n _waitForElements: WaitForElementsType;\n\n constructor(\n element: WebElement,\n waitForElement: WaitForElementType,\n waitForElements: WaitForElementsType\n ) {\n this._el = element;\n this._waitForElement = waitForElement;\n this._waitForElements = waitForElements;\n }\n waitForElement(locator: ElementLocator): Promise<TestElement> {\n return this._waitForElement(locator, this._el);\n }\n waitForElements(locator: ElementLocator): Promise<TestElement[]> {\n return this._waitForElements(locator, this._el);\n }\n getAttribute(attrName: string): Promise<string | null> {\n return this._el.getAttribute(attrName);\n }\n}\n"],"names":["WebDriverKeys","TestDriverBase","By","getTimeouts","TestingKeys"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ClickOptions, type KeyType, TestDriverBase, type TestElement } from '@oracle/oraclejet-testing/UNSAFE_Driver';
|
|
2
|
+
import { ElementLocator } from '@oracle/oraclejet-testing/UNSAFE_Locators';
|
|
3
|
+
import { WebDriver, WebElement } from 'selenium-webdriver';
|
|
4
|
+
type WaitForElementType = (locator: ElementLocator, parent: WebDriver | WebElement) => Promise<TestElement>;
|
|
5
|
+
type WaitForElementsType = (locator: ElementLocator, parent: WebDriver | WebElement) => Promise<TestElement[]>;
|
|
6
|
+
export declare class SeleniumDriver extends TestDriverBase {
|
|
7
|
+
private _driver;
|
|
8
|
+
private _platform;
|
|
9
|
+
constructor(driver: WebDriver);
|
|
10
|
+
executeScript<T>(script: string | ((...args: any) => T), ...args: any): Promise<T>;
|
|
11
|
+
waitForElement(locator: ElementLocator): Promise<TestElement>;
|
|
12
|
+
waitForElements(locator: ElementLocator): Promise<TestElement[]>;
|
|
13
|
+
private _waitForElement;
|
|
14
|
+
private _waitForElements;
|
|
15
|
+
/**
|
|
16
|
+
* Get a TestElement for the given WebElement
|
|
17
|
+
* @param from The WebElement
|
|
18
|
+
* @returns A TestElement
|
|
19
|
+
*/
|
|
20
|
+
getTestElement(from: WebElement): TestElementImpl;
|
|
21
|
+
sendKeys(element: TestElement, ...text: (string | KeyType)[]): Promise<void>;
|
|
22
|
+
click(element: TestElement, options?: ClickOptions): Promise<void>;
|
|
23
|
+
unwrapElement<T = WebElement>(element: TestElement): T;
|
|
24
|
+
private _ensurePlatform;
|
|
25
|
+
/**
|
|
26
|
+
* Get the platform-specific key value for the key, if available.
|
|
27
|
+
* @param key The key value
|
|
28
|
+
* @returns A platform-specific value for the key, or the original key if none exists
|
|
29
|
+
*/
|
|
30
|
+
private _getPlatformKey;
|
|
31
|
+
private _setDriverTimeouts;
|
|
32
|
+
}
|
|
33
|
+
declare class TestElementImpl implements TestElement {
|
|
34
|
+
_el: WebElement;
|
|
35
|
+
_waitForElement: WaitForElementType;
|
|
36
|
+
_waitForElements: WaitForElementsType;
|
|
37
|
+
constructor(element: WebElement, waitForElement: WaitForElementType, waitForElements: WaitForElementsType);
|
|
38
|
+
waitForElement(locator: ElementLocator): Promise<TestElement>;
|
|
39
|
+
waitForElements(locator: ElementLocator): Promise<TestElement[]>;
|
|
40
|
+
getAttribute(attrName: string): Promise<string | null>;
|
|
41
|
+
}
|
|
42
|
+
export {};
|