@wdio/utils 9.0.0-alpha.9 → 9.0.4
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/build/envDetector.d.ts +3 -3
- package/build/envDetector.d.ts.map +1 -1
- package/build/index.d.ts +2 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1902 -24
- package/build/initializeServices.d.ts +3 -3
- package/build/initializeServices.d.ts.map +1 -1
- package/build/monad.d.ts.map +1 -1
- package/build/node/manager.d.ts +2 -2
- package/build/node/manager.d.ts.map +1 -1
- package/build/node/startWebDriver.d.ts +2 -3
- package/build/node/startWebDriver.d.ts.map +1 -1
- package/build/node/utils.d.ts.map +1 -1
- package/build/node.js +473 -0
- package/build/pIteration.d.ts.map +1 -1
- package/build/shim.d.ts.map +1 -1
- package/build/startWebDriver.d.ts +2 -3
- package/build/startWebDriver.d.ts.map +1 -1
- package/build/test-framework/errorHandler.d.ts.map +1 -1
- package/build/test-framework/testFnWrapper.d.ts.map +1 -1
- package/build/test-framework/testInterfaceWrapper.d.ts.map +1 -1
- package/build/utils.d.ts +11 -2
- package/build/utils.d.ts.map +1 -1
- package/package.json +10 -11
- package/build/constants.js +0 -114
- package/build/envDetector.js +0 -251
- package/build/initializePlugin.js +0 -38
- package/build/initializeServices.js +0 -159
- package/build/monad.js +0 -196
- package/build/node/index.js +0 -3
- package/build/node/manager.js +0 -106
- package/build/node/startWebDriver.js +0 -140
- package/build/node/utils.js +0 -285
- package/build/pIteration.js +0 -347
- package/build/shim.js +0 -293
- package/build/startWebDriver.js +0 -20
- package/build/test-framework/errorHandler.js +0 -33
- package/build/test-framework/index.js +0 -4
- package/build/test-framework/testFnWrapper.js +0 -97
- package/build/test-framework/testInterfaceWrapper.js +0 -162
- package/build/test-framework/types.js +0 -1
- package/build/utils.js +0 -320
- /package/{LICENSE-MIT → LICENSE} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/utils",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.4",
|
|
4
4
|
"description": "A WDIO helper utility to provide several utility functions used across the project.",
|
|
5
5
|
"author": "Christian Bromann <mail@bromann.dev>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-utils",
|
|
@@ -12,10 +12,9 @@
|
|
|
12
12
|
"types": "./build/index.d.ts"
|
|
13
13
|
},
|
|
14
14
|
"./node": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
}
|
|
18
|
-
"./package.json": "./package.json"
|
|
15
|
+
"source": "./src/node/index.ts",
|
|
16
|
+
"import": "./build/node.js"
|
|
17
|
+
}
|
|
19
18
|
},
|
|
20
19
|
"types": "./build/index.d.ts",
|
|
21
20
|
"typeScriptVersion": "3.8.3",
|
|
@@ -24,7 +23,7 @@
|
|
|
24
23
|
},
|
|
25
24
|
"repository": {
|
|
26
25
|
"type": "git",
|
|
27
|
-
"url": "git://github.com/webdriverio/webdriverio.git",
|
|
26
|
+
"url": "git+https://github.com/webdriverio/webdriverio.git",
|
|
28
27
|
"directory": "packages/wdio-utils"
|
|
29
28
|
},
|
|
30
29
|
"keywords": [
|
|
@@ -38,11 +37,11 @@
|
|
|
38
37
|
},
|
|
39
38
|
"dependencies": {
|
|
40
39
|
"@puppeteer/browsers": "^2.2.0",
|
|
41
|
-
"@wdio/logger": "9.0.
|
|
42
|
-
"@wdio/types": "9.0.
|
|
40
|
+
"@wdio/logger": "9.0.4",
|
|
41
|
+
"@wdio/types": "9.0.4",
|
|
43
42
|
"decamelize": "^6.0.0",
|
|
44
|
-
"deepmerge-ts": "^
|
|
45
|
-
"edgedriver": "^5.
|
|
43
|
+
"deepmerge-ts": "^7.0.3",
|
|
44
|
+
"edgedriver": "^5.6.1",
|
|
46
45
|
"geckodriver": "^4.3.3",
|
|
47
46
|
"get-port": "^7.0.0",
|
|
48
47
|
"import-meta-resolve": "^4.0.0",
|
|
@@ -54,5 +53,5 @@
|
|
|
54
53
|
"publishConfig": {
|
|
55
54
|
"access": "public"
|
|
56
55
|
},
|
|
57
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "1f3d6f781391548e8672e768e72b3d5c499a3aa7"
|
|
58
57
|
}
|
package/build/constants.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* unicode characters
|
|
3
|
-
* https://w3c.github.io/webdriver/webdriver-spec.html#character-types
|
|
4
|
-
*/
|
|
5
|
-
export const UNICODE_CHARACTERS = {
|
|
6
|
-
'NULL': '\uE000',
|
|
7
|
-
'Unidentified': '\uE000',
|
|
8
|
-
'Cancel': '\uE001',
|
|
9
|
-
'Help': '\uE002',
|
|
10
|
-
'Backspace': '\uE003',
|
|
11
|
-
'Back space': '\uE003',
|
|
12
|
-
'Tab': '\uE004',
|
|
13
|
-
'Clear': '\uE005',
|
|
14
|
-
'Return': '\uE006',
|
|
15
|
-
'Enter': '\uE007',
|
|
16
|
-
'Shift': '\uE008',
|
|
17
|
-
'Control': '\uE009',
|
|
18
|
-
'Control Left': '\uE009',
|
|
19
|
-
'Control Right': '\uE051',
|
|
20
|
-
'Alt': '\uE00A',
|
|
21
|
-
'Pause': '\uE00B',
|
|
22
|
-
'Escape': '\uE00C',
|
|
23
|
-
'Space': '\uE00D',
|
|
24
|
-
' ': '\uE00D',
|
|
25
|
-
'PageUp': '\uE00E',
|
|
26
|
-
'Pageup': '\uE00E',
|
|
27
|
-
'Page_Up': '\uE00E',
|
|
28
|
-
'PageDown': '\uE00F',
|
|
29
|
-
'Pagedown': '\uE00F',
|
|
30
|
-
'Page_Down': '\uE00F',
|
|
31
|
-
'End': '\uE010',
|
|
32
|
-
'Home': '\uE011',
|
|
33
|
-
'ArrowLeft': '\uE012',
|
|
34
|
-
'Left arrow': '\uE012',
|
|
35
|
-
'Arrow_Left': '\uE012',
|
|
36
|
-
'ArrowUp': '\uE013',
|
|
37
|
-
'Up arrow': '\uE013',
|
|
38
|
-
'Arrow_Up': '\uE013',
|
|
39
|
-
'ArrowRight': '\uE014',
|
|
40
|
-
'Right arrow': '\uE014',
|
|
41
|
-
'Arrow_Right': '\uE014',
|
|
42
|
-
'ArrowDown': '\uE015',
|
|
43
|
-
'Down arrow': '\uE015',
|
|
44
|
-
'Arrow_Down': '\uE015',
|
|
45
|
-
'Insert': '\uE016',
|
|
46
|
-
'Delete': '\uE017',
|
|
47
|
-
'Semicolon': '\uE018',
|
|
48
|
-
'Equals': '\uE019',
|
|
49
|
-
'Numpad 0': '\uE01A',
|
|
50
|
-
'Numpad 1': '\uE01B',
|
|
51
|
-
'Numpad 2': '\uE01C',
|
|
52
|
-
'Numpad 3': '\uE01D',
|
|
53
|
-
'Numpad 4': '\uE01E',
|
|
54
|
-
'Numpad 5': '\uE01F',
|
|
55
|
-
'Numpad 6': '\uE020',
|
|
56
|
-
'Numpad 7': '\uE021',
|
|
57
|
-
'Numpad 8': '\uE022',
|
|
58
|
-
'Numpad 9': '\uE023',
|
|
59
|
-
'Multiply': '\uE024',
|
|
60
|
-
'Add': '\uE025',
|
|
61
|
-
'Separator': '\uE026',
|
|
62
|
-
'Subtract': '\uE027',
|
|
63
|
-
'Decimal': '\uE028',
|
|
64
|
-
'Divide': '\uE029',
|
|
65
|
-
'F1': '\uE031',
|
|
66
|
-
'F2': '\uE032',
|
|
67
|
-
'F3': '\uE033',
|
|
68
|
-
'F4': '\uE034',
|
|
69
|
-
'F5': '\uE035',
|
|
70
|
-
'F6': '\uE036',
|
|
71
|
-
'F7': '\uE037',
|
|
72
|
-
'F8': '\uE038',
|
|
73
|
-
'F9': '\uE039',
|
|
74
|
-
'F10': '\uE03A',
|
|
75
|
-
'F11': '\uE03B',
|
|
76
|
-
'F12': '\uE03C',
|
|
77
|
-
'Command': '\uE03D',
|
|
78
|
-
'Meta': '\uE03D',
|
|
79
|
-
'ZenkakuHankaku': '\uE040',
|
|
80
|
-
'Zenkaku_Hankaku': '\uE040'
|
|
81
|
-
};
|
|
82
|
-
export const SUPPORTED_BROWSERNAMES = {
|
|
83
|
-
chrome: ['chrome', 'googlechrome', 'chromium', 'chromium-browser'],
|
|
84
|
-
firefox: ['firefox', 'ff', 'mozilla', 'mozilla firefox'],
|
|
85
|
-
edge: ['edge', 'microsoftedge', 'msedge'],
|
|
86
|
-
safari: ['safari', 'safari technology preview']
|
|
87
|
-
};
|
|
88
|
-
export const DEFAULT_HOSTNAME = 'localhost';
|
|
89
|
-
export const DEFAULT_PROTOCOL = 'http';
|
|
90
|
-
export const DEFAULT_PATH = '/';
|
|
91
|
-
/* istanbul ignore next */
|
|
92
|
-
export const HOOK_DEFINITION = {
|
|
93
|
-
type: 'object',
|
|
94
|
-
validate: (param) => {
|
|
95
|
-
/**
|
|
96
|
-
* option must be an array
|
|
97
|
-
*/
|
|
98
|
-
if (!Array.isArray(param)) {
|
|
99
|
-
throw new Error('a hook option needs to be a list of functions');
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* array elements must be functions
|
|
103
|
-
*/
|
|
104
|
-
for (const option of param) {
|
|
105
|
-
/**
|
|
106
|
-
* either a string
|
|
107
|
-
*/
|
|
108
|
-
if (typeof option === 'function') {
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
throw new Error('expected hook to be type of function');
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
};
|
package/build/envDetector.js
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import { SUPPORTED_BROWSERNAMES } from './constants.js';
|
|
2
|
-
const MOBILE_BROWSER_NAMES = ['ipad', 'iphone', 'android'];
|
|
3
|
-
const MOBILE_CAPABILITIES = [
|
|
4
|
-
'appium-version', 'appiumVersion', 'device-type', 'deviceType', 'app', 'appArguments',
|
|
5
|
-
'device-orientation', 'deviceOrientation', 'deviceName', 'automationName'
|
|
6
|
-
];
|
|
7
|
-
/**
|
|
8
|
-
* check if session is based on W3C protocol based on the /session response
|
|
9
|
-
* @param {Object} capabilities caps of session response
|
|
10
|
-
* @return {Boolean} true if W3C (browser)
|
|
11
|
-
*/
|
|
12
|
-
export function isW3C(capabilities) {
|
|
13
|
-
/**
|
|
14
|
-
* JSONWire protocol doesn't return a property `capabilities`.
|
|
15
|
-
* Also check for Appium response as it is using JSONWire protocol for most of the part.
|
|
16
|
-
*/
|
|
17
|
-
if (!capabilities) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* assume session to be a WebDriver session when
|
|
22
|
-
* - capabilities are returned
|
|
23
|
-
* (https://w3c.github.io/webdriver/#dfn-new-sessions)
|
|
24
|
-
* - it is an Appium session (since Appium is full W3C compliant)
|
|
25
|
-
*/
|
|
26
|
-
const isAppium = Boolean(
|
|
27
|
-
// @ts-expect-error outdated jsonwp cap
|
|
28
|
-
capabilities.automationName ||
|
|
29
|
-
capabilities['appium:automationName'] ||
|
|
30
|
-
capabilities.deviceName ||
|
|
31
|
-
capabilities.appiumVersion);
|
|
32
|
-
const hasW3CCaps = Boolean(
|
|
33
|
-
/**
|
|
34
|
-
* safari docker image may not provide a platformName therefore
|
|
35
|
-
* check one of the available "platformName" or "browserVersion"
|
|
36
|
-
*/
|
|
37
|
-
(capabilities.platformName || capabilities.browserVersion) &&
|
|
38
|
-
/**
|
|
39
|
-
* local safari and BrowserStack don't provide platformVersion therefore
|
|
40
|
-
* check also if setWindowRect is provided
|
|
41
|
-
*/
|
|
42
|
-
(capabilities.platformVersion ||
|
|
43
|
-
capabilities['appium:platformVersion'] ||
|
|
44
|
-
Object.prototype.hasOwnProperty.call(capabilities, 'setWindowRect')));
|
|
45
|
-
const hasWebdriverFlag = Boolean(capabilities['ms:experimental-webdriver']);
|
|
46
|
-
return Boolean(hasW3CCaps || isAppium || hasWebdriverFlag);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* check if session is run by Chromedriver
|
|
50
|
-
* @param {Object} capabilities caps of session response
|
|
51
|
-
* @return {Boolean} true if run by Chromedriver
|
|
52
|
-
*/
|
|
53
|
-
function isChrome(capabilities) {
|
|
54
|
-
if (!capabilities) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
return Boolean(capabilities.chrome || capabilities['goog:chromeOptions']);
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* check if session is run by Edgedriver
|
|
61
|
-
* @param {Object} capabilities caps of session response
|
|
62
|
-
* @return {Boolean} true if run by Edgedriver
|
|
63
|
-
*/
|
|
64
|
-
function isEdge(capabilities) {
|
|
65
|
-
if (!capabilities) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
return (Boolean(capabilities.browserName && SUPPORTED_BROWSERNAMES.edge.includes(capabilities.browserName.toLowerCase()) ||
|
|
69
|
-
capabilities['ms:edgeOptions']));
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* check if session is run by Geckodriver
|
|
73
|
-
* @param {Object} capabilities caps of session response
|
|
74
|
-
* @return {Boolean} true if run by Geckodriver
|
|
75
|
-
*/
|
|
76
|
-
function isFirefox(capabilities) {
|
|
77
|
-
if (!capabilities) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
return (capabilities.browserName === 'firefox' ||
|
|
81
|
-
Boolean(Object.keys(capabilities).find((cap) => cap.startsWith('moz:'))));
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* check if current platform is mobile device
|
|
85
|
-
*
|
|
86
|
-
* @param {Object} caps capabilities
|
|
87
|
-
* @return {Boolean} true if platform is mobile device
|
|
88
|
-
*/
|
|
89
|
-
function isMobile(capabilities) {
|
|
90
|
-
const browserName = (capabilities.browserName || '').toLowerCase();
|
|
91
|
-
const bsOptions = capabilities['bstack:options'] || {};
|
|
92
|
-
const browserstackBrowserName = (bsOptions.browserName || '').toLowerCase();
|
|
93
|
-
/**
|
|
94
|
-
* we have mobile capabilities if
|
|
95
|
-
*/
|
|
96
|
-
return Boolean(
|
|
97
|
-
/**
|
|
98
|
-
* If the device is ios, tvos or android, the device might be mobile.
|
|
99
|
-
*/
|
|
100
|
-
capabilities.platformName && capabilities.platformName.match(/ios/i) ||
|
|
101
|
-
capabilities.platformName && capabilities.platformName.match(/tvos/i) ||
|
|
102
|
-
capabilities.platformName && capabilities.platformName.match(/android/i) ||
|
|
103
|
-
/ios/i.test(bsOptions.platformName || '') ||
|
|
104
|
-
/tvos/i.test(bsOptions.platformName || '') ||
|
|
105
|
-
/android/i.test(bsOptions.platformName || '') ||
|
|
106
|
-
/**
|
|
107
|
-
* capabilities contain mobile only specific capabilities
|
|
108
|
-
*/
|
|
109
|
-
Object.keys(capabilities).find((cap) => (MOBILE_CAPABILITIES.includes(cap) ||
|
|
110
|
-
MOBILE_CAPABILITIES.map((c) => `appium:${c}`).includes(cap))) ||
|
|
111
|
-
/**
|
|
112
|
-
* browserName is empty (and eventually app is defined)
|
|
113
|
-
*/
|
|
114
|
-
capabilities.browserName === '' ||
|
|
115
|
-
bsOptions.browserName === '' ||
|
|
116
|
-
/**
|
|
117
|
-
* browserName is a mobile browser
|
|
118
|
-
*/
|
|
119
|
-
MOBILE_BROWSER_NAMES.includes(browserName) ||
|
|
120
|
-
MOBILE_BROWSER_NAMES.includes(browserstackBrowserName));
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* check if session is run on iOS device
|
|
124
|
-
* @param {Object} capabilities of session response
|
|
125
|
-
* @return {Boolean} true if run on iOS device
|
|
126
|
-
*/
|
|
127
|
-
function isIOS(capabilities) {
|
|
128
|
-
const bsOptions = capabilities?.['bstack:options'] || {};
|
|
129
|
-
if (!capabilities) {
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
return Boolean((capabilities.platformName && capabilities.platformName.match(/iOS/i)) ||
|
|
133
|
-
(capabilities.deviceName && capabilities.deviceName.match(/(iPad|iPhone)/i)) ||
|
|
134
|
-
(/iOS/i.test(bsOptions.platformName || '')) ||
|
|
135
|
-
(/(iPad|iPhone)/i.test(bsOptions.deviceName || '')));
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* check if session is run on Android device
|
|
139
|
-
* @param {Object} capabilities caps of session response
|
|
140
|
-
* @return {Boolean} true if run on Android device
|
|
141
|
-
*/
|
|
142
|
-
function isAndroid(capabilities) {
|
|
143
|
-
const bsOptions = capabilities?.['bstack:options'] || {};
|
|
144
|
-
if (!capabilities) {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
return Boolean((capabilities.platformName && capabilities.platformName.match(/Android/i)) ||
|
|
148
|
-
(/Android/i.test(bsOptions.platformName || '')) ||
|
|
149
|
-
(/Android/i.test(bsOptions.browserName || '')) ||
|
|
150
|
-
(capabilities.browserName && capabilities.browserName.match(/Android/i)));
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* detects if session is run on Sauce with extended debugging enabled
|
|
154
|
-
* @param {object} capabilities session capabilities
|
|
155
|
-
* @return {Boolean} true if session is running on Sauce with extended debugging enabled
|
|
156
|
-
*/
|
|
157
|
-
function isSauce(capabilities) {
|
|
158
|
-
if (!capabilities) {
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
const caps = capabilities.alwaysMatch
|
|
162
|
-
? capabilities.alwaysMatch
|
|
163
|
-
: capabilities;
|
|
164
|
-
return Boolean(caps.extendedDebugging ||
|
|
165
|
-
(caps['sauce:options'] &&
|
|
166
|
-
caps['sauce:options'].extendedDebugging));
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* detects if session has support for WebDriver Bidi
|
|
170
|
-
* @param {object} capabilities session capabilities
|
|
171
|
-
* @return {Boolean} true if session has WebDriver Bidi support
|
|
172
|
-
*/
|
|
173
|
-
function isBidi(capabilities) {
|
|
174
|
-
if (!capabilities) {
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
const caps = capabilities.alwaysMatch
|
|
178
|
-
? capabilities.alwaysMatch
|
|
179
|
-
: capabilities;
|
|
180
|
-
return Boolean(caps.webSocketUrl);
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* detects if session is run using Selenium Standalone server
|
|
184
|
-
* @param {object} capabilities session capabilities
|
|
185
|
-
* @return {Boolean} true if session is run with Selenium Standalone Server
|
|
186
|
-
*/
|
|
187
|
-
function isSeleniumStandalone(capabilities) {
|
|
188
|
-
if (!capabilities) {
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
return (
|
|
192
|
-
/**
|
|
193
|
-
* Selenium v3 and below
|
|
194
|
-
*/
|
|
195
|
-
Boolean(capabilities['webdriver.remote.sessionid']) ||
|
|
196
|
-
/**
|
|
197
|
-
* Selenium v4 and up
|
|
198
|
-
*/
|
|
199
|
-
Boolean(capabilities['se:cdp']));
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* detects if session is run using Chromium protocol
|
|
203
|
-
* @param {object} capabilities session capabilities
|
|
204
|
-
* @return {Boolean} true if session is run with Chromium protocol
|
|
205
|
-
*/
|
|
206
|
-
function isChromium(capabilities) {
|
|
207
|
-
if (!capabilities) {
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
return (isChrome(capabilities) || isEdge(capabilities));
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* returns information about the environment before the session is created
|
|
214
|
-
* @param {Object} capabilities caps provided by user
|
|
215
|
-
* @return {Object} object with environment flags
|
|
216
|
-
*/
|
|
217
|
-
export function capabilitiesEnvironmentDetector(capabilities) {
|
|
218
|
-
return {
|
|
219
|
-
isChrome: isChrome(capabilities),
|
|
220
|
-
isFirefox: isFirefox(capabilities),
|
|
221
|
-
isMobile: isMobile(capabilities),
|
|
222
|
-
isIOS: isIOS(capabilities),
|
|
223
|
-
isAndroid: isAndroid(capabilities),
|
|
224
|
-
isSauce: isSauce(capabilities),
|
|
225
|
-
isBidi: isBidi(capabilities),
|
|
226
|
-
isChromium: isChromium(capabilities)
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* returns information about the environment when the session is created
|
|
231
|
-
* @param {Object} capabilities caps of session response
|
|
232
|
-
* @param {Object} requestedCapabilities
|
|
233
|
-
* @return {Object} object with environment flags
|
|
234
|
-
*/
|
|
235
|
-
export function sessionEnvironmentDetector({ capabilities, requestedCapabilities }) {
|
|
236
|
-
const cap = 'alwaysMatch' in capabilities
|
|
237
|
-
? capabilities.alwaysMatch
|
|
238
|
-
: capabilities;
|
|
239
|
-
return {
|
|
240
|
-
isW3C: isW3C(cap),
|
|
241
|
-
isChrome: isChrome(cap),
|
|
242
|
-
isFirefox: isFirefox(cap),
|
|
243
|
-
isMobile: isMobile(cap),
|
|
244
|
-
isIOS: isIOS(cap),
|
|
245
|
-
isAndroid: isAndroid(cap),
|
|
246
|
-
isSauce: isSauce(requestedCapabilities),
|
|
247
|
-
isSeleniumStandalone: isSeleniumStandalone(cap),
|
|
248
|
-
isBidi: isBidi(capabilities),
|
|
249
|
-
isChromium: isChromium(cap)
|
|
250
|
-
};
|
|
251
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { safeImport, isAbsolute } from './utils.js';
|
|
2
|
-
/**
|
|
3
|
-
* initialize WebdriverIO compliant plugins like reporter or services in the following way:
|
|
4
|
-
* 1. if package name is scoped (starts with "@"), require scoped package name
|
|
5
|
-
* 2. otherwise try to require "@wdio/<name>-<type>"
|
|
6
|
-
* 3. otherwise try to require "wdio-<name>-<type>"
|
|
7
|
-
*/
|
|
8
|
-
export default async function initializePlugin(name, type) {
|
|
9
|
-
/**
|
|
10
|
-
* directly import packages that are scoped or start with an absolute path
|
|
11
|
-
*/
|
|
12
|
-
if (name[0] === '@' || isAbsolute(name)) {
|
|
13
|
-
const service = await safeImport(name);
|
|
14
|
-
if (service) {
|
|
15
|
-
return service;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
if (typeof type !== 'string') {
|
|
19
|
-
throw new Error('No plugin type provided');
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* check for scoped version of plugin first (e.g. @wdio/sauce-service)
|
|
23
|
-
*/
|
|
24
|
-
const scopedPlugin = await safeImport(`@wdio/${name.toLowerCase()}-${type}`);
|
|
25
|
-
if (scopedPlugin) {
|
|
26
|
-
return scopedPlugin;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* check for old type of
|
|
30
|
-
*/
|
|
31
|
-
const plugin = await safeImport(`wdio-${name.toLowerCase()}-${type}`);
|
|
32
|
-
if (plugin) {
|
|
33
|
-
return plugin;
|
|
34
|
-
}
|
|
35
|
-
throw new Error(`Couldn't find plugin "${name}" ${type}, neither as wdio scoped package ` +
|
|
36
|
-
`"@wdio/${name.toLowerCase()}-${type}" nor as community package ` +
|
|
37
|
-
`"wdio-${name.toLowerCase()}-${type}". Please make sure you have it installed!`);
|
|
38
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import logger from '@wdio/logger';
|
|
2
|
-
import initializePlugin from './initializePlugin.js';
|
|
3
|
-
const log = logger('@wdio/utils:initializeServices');
|
|
4
|
-
/**
|
|
5
|
-
* Maps list of services of a config file into a list of actionable objects
|
|
6
|
-
* @param {Object} config config of running session
|
|
7
|
-
* @param {Object} caps capabilities of running session
|
|
8
|
-
* @return {[(Object|Class), Object][]} list of services with their config objects
|
|
9
|
-
*/
|
|
10
|
-
async function initializeServices(services) {
|
|
11
|
-
const initializedServices = [];
|
|
12
|
-
for (const [serviceName, serviceConfig = {}] of services) {
|
|
13
|
-
/**
|
|
14
|
-
* allow custom services that are already initialized, e.g.
|
|
15
|
-
*
|
|
16
|
-
* ```
|
|
17
|
-
* services: [
|
|
18
|
-
* [{ beforeTest: () => { ... } }]
|
|
19
|
-
* ]
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
if (typeof serviceName === 'object') {
|
|
23
|
-
log.debug('initialize custom initiated service');
|
|
24
|
-
initializedServices.push([serviceName, {}]);
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* allow custom service classes, e.g.
|
|
29
|
-
*
|
|
30
|
-
* ```
|
|
31
|
-
* class MyService { ... }
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* in wdio.conf.js:
|
|
35
|
-
*
|
|
36
|
-
* ```
|
|
37
|
-
* services: [MyService]
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
if (typeof serviceName === 'function') {
|
|
41
|
-
log.debug(`initialize custom service "${serviceName.name}"`);
|
|
42
|
-
initializedServices.push([serviceName, serviceConfig]);
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* services as NPM packages
|
|
47
|
-
*
|
|
48
|
-
* ```
|
|
49
|
-
* services: ['@wdio/devtools-service']
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
log.debug(`initialize service "${serviceName}" as NPM package`);
|
|
53
|
-
const service = await initializePlugin(serviceName, 'service');
|
|
54
|
-
initializedServices.push([service, serviceConfig, serviceName]);
|
|
55
|
-
}
|
|
56
|
-
return initializedServices;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* formats service array into proper structure which is an array with
|
|
60
|
-
* the service object as first parameter and the service option as
|
|
61
|
-
* second parameter
|
|
62
|
-
* @param {[Any]} service list of services from config file
|
|
63
|
-
* @return {[service, serviceConfig][]} formatted list of services
|
|
64
|
-
*/
|
|
65
|
-
function sanitizeServiceArray(service) {
|
|
66
|
-
return Array.isArray(service) ? service : [service, {}];
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* initialize service for launcher process
|
|
70
|
-
* @param {Object} config wdio config
|
|
71
|
-
* @param {Object[]} caps list of capabilities
|
|
72
|
-
* @return {Object} containing a list of launcher services as well
|
|
73
|
-
* as a list of services that don't need to be
|
|
74
|
-
* required in the worker
|
|
75
|
-
*/
|
|
76
|
-
export async function initializeLauncherService(config, caps) {
|
|
77
|
-
const ignoredWorkerServices = [];
|
|
78
|
-
const launcherServices = [];
|
|
79
|
-
let serviceLabelToBeInitialised = 'unknown';
|
|
80
|
-
try {
|
|
81
|
-
const services = await initializeServices(config.services.map(sanitizeServiceArray));
|
|
82
|
-
for (const [service, serviceConfig, serviceName] of services) {
|
|
83
|
-
/**
|
|
84
|
-
* add custom services as object or function
|
|
85
|
-
*/
|
|
86
|
-
if (typeof service === 'object' && !serviceName) {
|
|
87
|
-
serviceLabelToBeInitialised = 'object';
|
|
88
|
-
launcherServices.push(service);
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* add class service from imported package
|
|
93
|
-
*/
|
|
94
|
-
const Launcher = service.launcher;
|
|
95
|
-
if (typeof Launcher === 'function' && serviceName) {
|
|
96
|
-
serviceLabelToBeInitialised = `"${serviceName}"`;
|
|
97
|
-
launcherServices.push(new Launcher(serviceConfig, caps, config));
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* add class service from passed in class
|
|
101
|
-
*/
|
|
102
|
-
if (typeof service === 'function' && !serviceName) {
|
|
103
|
-
serviceLabelToBeInitialised = `"${service.constructor?.name || service.toString()}"`;
|
|
104
|
-
launcherServices.push(new service(serviceConfig, caps, config));
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* check if service has a default export, if not we can later filter it out so the
|
|
108
|
-
* service module is not even loaded in the worker process
|
|
109
|
-
*/
|
|
110
|
-
if (serviceName &&
|
|
111
|
-
typeof service.default !== 'function' &&
|
|
112
|
-
typeof service !== 'function') {
|
|
113
|
-
ignoredWorkerServices.push(serviceName);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
catch (err) {
|
|
118
|
-
throw new Error(`Failed to initilialise launcher service ${serviceLabelToBeInitialised}: ${err.stack}`);
|
|
119
|
-
}
|
|
120
|
-
return { ignoredWorkerServices, launcherServices };
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* initialize services for worker instance
|
|
124
|
-
* @param {Object} config wdio config
|
|
125
|
-
* @param {Object} caps worker capabilities
|
|
126
|
-
* @param {object} ignoredWorkerServices list of services that don't need to be required in a worker
|
|
127
|
-
* as they don't export a service for it
|
|
128
|
-
* @return {Object[]} list if worker initiated worker services
|
|
129
|
-
*/
|
|
130
|
-
export async function initializeWorkerService(config, caps, ignoredWorkerServices = []) {
|
|
131
|
-
let serviceLabelToBeInitialised = 'unknown';
|
|
132
|
-
const initializedServices = [];
|
|
133
|
-
const workerServices = config.services
|
|
134
|
-
.map(sanitizeServiceArray)
|
|
135
|
-
.filter(([serviceName]) => !ignoredWorkerServices.includes(serviceName));
|
|
136
|
-
try {
|
|
137
|
-
const services = await initializeServices(workerServices);
|
|
138
|
-
for (const [service, serviceConfig, serviceName] of services) {
|
|
139
|
-
/**
|
|
140
|
-
* add object service
|
|
141
|
-
*/
|
|
142
|
-
if (typeof service === 'object' && !serviceName) {
|
|
143
|
-
serviceLabelToBeInitialised = 'object';
|
|
144
|
-
initializedServices.push(service);
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
const Service = service.default || service;
|
|
148
|
-
if (typeof Service === 'function') {
|
|
149
|
-
serviceLabelToBeInitialised = serviceName || Service.constructor?.name || Service.toString();
|
|
150
|
-
initializedServices.push(new Service(serviceConfig, caps, config));
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return initializedServices;
|
|
155
|
-
}
|
|
156
|
-
catch (err) {
|
|
157
|
-
throw new Error(`Failed to initilialise service ${serviceLabelToBeInitialised}: ${err.stack}`);
|
|
158
|
-
}
|
|
159
|
-
}
|