@camperaid/watest 2.6.1 → 2.6.3
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/.watestrc.js +6 -0
- package/README.md +29 -2
- package/core/base.js +16 -2
- package/core/series.js +3 -0
- package/core/settings.js +144 -0
- package/package.json +1 -1
- package/tests/core/t-webdriver-aliases.js +179 -0
- package/tests/e2e/samples/folder/package-lock.json +1 -1
- package/tests/e2e/samples/loader/package-lock.json +1 -1
- package/tests/e2e/samples/loader-mixed/package-lock.json +1 -1
- package/tests/e2e/samples/loader-multiple/package-lock.json +1 -1
- package/tests/e2e/samples/single/package-lock.json +1 -1
- package/tests/e2e/samples/wd-mixed/package-lock.json +1 -1
- package/tests/e2e/samples/wd-single/package-lock.json +1 -1
- package/tests/meta.js +1 -1
- package/webdriver/driver-base.js +35 -38
package/.watestrc.js
CHANGED
|
@@ -54,6 +54,12 @@ const cfg = {
|
|
|
54
54
|
*/
|
|
55
55
|
webdrivers: process.env.WATEST_WEBDRIVERS,
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Project-defined webdriver aliases. JSON object mapping alias names to
|
|
59
|
+
* { browser, isMobile?, chrome?, windowWidth?, windowHeight? }.
|
|
60
|
+
*/
|
|
61
|
+
webdriver_aliases: process.env.WATEST_WEBDRIVER_ALIASES,
|
|
62
|
+
|
|
57
63
|
/**
|
|
58
64
|
* Logger module.
|
|
59
65
|
*/
|
package/README.md
CHANGED
|
@@ -121,6 +121,7 @@ WATEST_TMP_DIR=/tmp # Temporary files directory
|
|
|
121
121
|
|
|
122
122
|
# WebDriver
|
|
123
123
|
WATEST_WEBDRIVERS='["chrome","firefox"]' # Browser list (JSON array)
|
|
124
|
+
WATEST_WEBDRIVER_ALIASES='{"chrome-mobile":{"browser":"chrome","isMobile":true,"chrome":{"mobileEmulation":{"deviceName":"iPhone 7"}}}}'
|
|
124
125
|
WATEST_WEBDRIVER_HEADLESS=true # Run browsers headless
|
|
125
126
|
WATEST_WEBDRIVER_LOGLEVEL=info # WebDriver log level
|
|
126
127
|
WATEST_WEBDRIVER_WINDOW_WIDTH=1280 # Browser window width
|
|
@@ -134,12 +135,38 @@ WATEST_IGNORE_PATTERN=_browser\.js$ # Regex for files to skip
|
|
|
134
135
|
|
|
135
136
|
### Webdrivers
|
|
136
137
|
|
|
137
|
-
Built-in
|
|
138
|
+
Built-in browsers:
|
|
138
139
|
|
|
139
140
|
- `chrome` - Chrome browser
|
|
140
|
-
- `chrome-mobile` - Chrome with iPhone emulation
|
|
141
141
|
- `firefox` - Firefox browser
|
|
142
142
|
- `safari` - Safari browser
|
|
143
|
+
- `edge` - Edge browser
|
|
144
|
+
|
|
145
|
+
Project-defined aliases go in `.watestrc.js` as `webdriver_aliases` (or
|
|
146
|
+
`WATEST_WEBDRIVER_ALIASES` JSON env var). Each alias maps a name to a base
|
|
147
|
+
browser plus overrides:
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
webdriver_aliases: {
|
|
151
|
+
'chrome-mobile': {
|
|
152
|
+
browser: 'chrome',
|
|
153
|
+
isMobile: true,
|
|
154
|
+
chrome: {
|
|
155
|
+
mobileEmulation: { deviceName: 'iPhone 7' },
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
'chrome-iphone10': {
|
|
159
|
+
browser: 'chrome',
|
|
160
|
+
isMobile: true,
|
|
161
|
+
chrome: {
|
|
162
|
+
mobileEmulation: { deviceName: 'iPhone X' },
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Supported alias fields: `browser` (required), `isMobile`, `browserLoggingOn`,
|
|
169
|
+
`chrome.mobileEmulation`, `windowWidth`, `windowHeight`.
|
|
143
170
|
|
|
144
171
|
## CLI Options
|
|
145
172
|
|
package/core/base.js
CHANGED
|
@@ -213,7 +213,7 @@ function is_primitive(
|
|
|
213
213
|
|
|
214
214
|
// Overlimit got: keep it small to not pollute output.
|
|
215
215
|
let printable_got =
|
|
216
|
-
String(got).length > limit ? `${String(got).substring(0, limit)}
|
|
216
|
+
String(got).length > limit ? `${String(got).substring(0, limit)}...` : got;
|
|
217
217
|
if (typeof got == 'string') {
|
|
218
218
|
printable_got = `'${printable_got}'`;
|
|
219
219
|
}
|
|
@@ -310,8 +310,22 @@ function is_object_impl(
|
|
|
310
310
|
) {
|
|
311
311
|
const contextmsg = `${msg}${(fieldpath && ` '${fieldpath}' field`) || ''}`;
|
|
312
312
|
|
|
313
|
-
//
|
|
313
|
+
// When got is null / a primitive but expected is a plain object or array,
|
|
314
|
+
// report a clear type mismatch rather than falling into is_primitive where
|
|
315
|
+
// the value would stringify as [object Object].
|
|
316
|
+
// Functions and RegExps are excluded: is_primitive handles them as
|
|
317
|
+
// predicates / pattern matchers against the primitive got value.
|
|
314
318
|
if (!(got instanceof Object)) {
|
|
319
|
+
if (
|
|
320
|
+
expected instanceof Object &&
|
|
321
|
+
typeof expected !== 'function' &&
|
|
322
|
+
!(expected instanceof RegExp)
|
|
323
|
+
) {
|
|
324
|
+
fail_(
|
|
325
|
+
`${contextmsg} value mismatch, got: ${stringify(got)}, expected: ${stringify(expected)}`,
|
|
326
|
+
);
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
315
329
|
return is_primitive(got, expected, contextmsg, {
|
|
316
330
|
enrich_failure_msg: true,
|
|
317
331
|
fail_,
|
package/core/series.js
CHANGED
package/core/settings.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
|
|
3
|
+
const baseBrowsers = ['chrome', 'firefox', 'safari', 'edge'];
|
|
4
|
+
|
|
5
|
+
const baseBrowserDefaults = {
|
|
6
|
+
chrome: { chrome: true, browserLoggingOn: true },
|
|
7
|
+
firefox: { firefox: true },
|
|
8
|
+
safari: { safari: true },
|
|
9
|
+
edge: { edge: true },
|
|
10
|
+
};
|
|
11
|
+
|
|
3
12
|
class Settings {
|
|
4
13
|
constructor() {
|
|
5
14
|
this.log_dir = '';
|
|
@@ -8,6 +17,11 @@ class Settings {
|
|
|
8
17
|
this.logger = null;
|
|
9
18
|
this.servicer = null;
|
|
10
19
|
this.silent = false;
|
|
20
|
+
this.webdriver_aliases = {};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get baseBrowsers() {
|
|
24
|
+
return baseBrowsers;
|
|
11
25
|
}
|
|
12
26
|
|
|
13
27
|
async initialize(options = {}) {
|
|
@@ -94,7 +108,128 @@ class Settings {
|
|
|
94
108
|
}
|
|
95
109
|
}
|
|
96
110
|
|
|
111
|
+
parseJsonObject(value, label) {
|
|
112
|
+
if (value == null || value === '') {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
if (typeof value == 'object') {
|
|
116
|
+
return value;
|
|
117
|
+
}
|
|
118
|
+
if (typeof value == 'string') {
|
|
119
|
+
try {
|
|
120
|
+
return JSON.parse(value);
|
|
121
|
+
} catch (e) {
|
|
122
|
+
console.error(`Settings: failed to parse ${label} '${value}'`, e);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
setupWebdriverAliases() {
|
|
129
|
+
this.webdriver_aliases = {};
|
|
130
|
+
|
|
131
|
+
const aliases = this.parseJsonObject(
|
|
132
|
+
this.rc.webdriver_aliases,
|
|
133
|
+
'webdriver_aliases',
|
|
134
|
+
);
|
|
135
|
+
if (!aliases) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
for (const [name, alias] of Object.entries(aliases)) {
|
|
140
|
+
if (baseBrowsers.includes(name)) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`Settings: webdriver alias '${name}' conflicts with built-in browser`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
if (!alias || typeof alias != 'object') {
|
|
146
|
+
throw new Error(
|
|
147
|
+
`Settings: webdriver alias '${name}' must be an object`,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
if (!alias.browser) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`Settings: webdriver alias '${name}' is missing required 'browser' field`,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
if (!baseBrowsers.includes(alias.browser)) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`Settings: webdriver alias '${name}' has unexpected browser '${alias.browser}'`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
this.webdriver_aliases[name] = alias;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
isKnownWebdriver(name) {
|
|
165
|
+
return baseBrowsers.includes(name) || name in this.webdriver_aliases;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
resolveWebdriver(name) {
|
|
169
|
+
if (!name) {
|
|
170
|
+
throw new Error(`Settings: no webdriver name provided`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const alias = this.webdriver_aliases[name];
|
|
174
|
+
if (alias) {
|
|
175
|
+
const flags = {
|
|
176
|
+
...baseBrowserDefaults[alias.browser],
|
|
177
|
+
};
|
|
178
|
+
if (alias.isMobile) {
|
|
179
|
+
flags.isMobile = true;
|
|
180
|
+
}
|
|
181
|
+
if (alias.browserLoggingOn != null) {
|
|
182
|
+
flags.browserLoggingOn = alias.browserLoggingOn;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
name,
|
|
187
|
+
browser: alias.browser,
|
|
188
|
+
flags,
|
|
189
|
+
chrome: alias.chrome || null,
|
|
190
|
+
windowWidth: alias.windowWidth,
|
|
191
|
+
windowHeight: alias.windowHeight,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (baseBrowsers.includes(name)) {
|
|
196
|
+
return {
|
|
197
|
+
name,
|
|
198
|
+
browser: name,
|
|
199
|
+
flags: { ...baseBrowserDefaults[name] },
|
|
200
|
+
chrome: null,
|
|
201
|
+
windowWidth: undefined,
|
|
202
|
+
windowHeight: undefined,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
throw new Error(
|
|
207
|
+
`Settings: unexpected webdriver '${name}', define it in webdriver_aliases`,
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
validateWebdrivers() {
|
|
212
|
+
if (!this.webdrivers) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (!(this.webdrivers instanceof Array)) {
|
|
216
|
+
throw new Error(
|
|
217
|
+
`Settings: webdrivers must be an array, got: ${JSON.stringify(this.webdrivers)}`,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
for (const webdriver of this.webdrivers) {
|
|
222
|
+
if (!this.isKnownWebdriver(webdriver)) {
|
|
223
|
+
throw new Error(
|
|
224
|
+
`Settings: unexpected webdriver '${webdriver}', define it in webdriver_aliases`,
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
97
230
|
setupWebdrivers() {
|
|
231
|
+
this.setupWebdriverAliases();
|
|
232
|
+
|
|
98
233
|
this.webdrivers = this.rc.webdrivers;
|
|
99
234
|
if (typeof this.rc.webdrivers == 'string') {
|
|
100
235
|
try {
|
|
@@ -107,6 +242,8 @@ class Settings {
|
|
|
107
242
|
}
|
|
108
243
|
}
|
|
109
244
|
|
|
245
|
+
this.validateWebdrivers();
|
|
246
|
+
|
|
110
247
|
this.webdriver = null;
|
|
111
248
|
this.webdriver_headless =
|
|
112
249
|
this.rc.webdriver_headless == true ||
|
|
@@ -142,6 +279,13 @@ class Settings {
|
|
|
142
279
|
if (this.webdrivers && !this.silent) {
|
|
143
280
|
console.log(`Settings: ${this.webdrivers.join(', ')} webdrivers`);
|
|
144
281
|
}
|
|
282
|
+
|
|
283
|
+
const aliasCount = Object.keys(this.webdriver_aliases).length;
|
|
284
|
+
if (aliasCount > 0 && !this.silent) {
|
|
285
|
+
console.log(
|
|
286
|
+
`Settings: ${aliasCount} webdriver alias(es): ${Object.keys(this.webdriver_aliases).join(', ')}`,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
145
289
|
}
|
|
146
290
|
}
|
|
147
291
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { is, throws } from '../base/test.js';
|
|
2
|
+
import { settings } from '../../core/settings.js';
|
|
3
|
+
import { DriverBase } from '../../webdriver/driver-base.js';
|
|
4
|
+
|
|
5
|
+
function withSettings(rcPatch, fn) {
|
|
6
|
+
const saved = {
|
|
7
|
+
rc: { ...settings.rc },
|
|
8
|
+
webdriver_aliases: { ...settings.webdriver_aliases },
|
|
9
|
+
webdrivers: settings.webdrivers,
|
|
10
|
+
};
|
|
11
|
+
settings.rc = { ...settings.rc, ...rcPatch };
|
|
12
|
+
settings.silent = true;
|
|
13
|
+
try {
|
|
14
|
+
settings.setupWebdrivers();
|
|
15
|
+
return fn();
|
|
16
|
+
} finally {
|
|
17
|
+
settings.rc = saved.rc;
|
|
18
|
+
settings.webdriver_aliases = saved.webdriver_aliases;
|
|
19
|
+
settings.webdrivers = saved.webdrivers;
|
|
20
|
+
settings.silent = false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function test() {
|
|
25
|
+
const chromeMobileAlias = {
|
|
26
|
+
browser: 'chrome',
|
|
27
|
+
isMobile: true,
|
|
28
|
+
chrome: {
|
|
29
|
+
mobileEmulation: { deviceName: 'iPhone 7' },
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
withSettings(
|
|
34
|
+
{
|
|
35
|
+
webdriver_aliases: {
|
|
36
|
+
'chrome-mobile': chromeMobileAlias,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
() => {
|
|
40
|
+
is(
|
|
41
|
+
settings.resolveWebdriver('chrome-mobile'),
|
|
42
|
+
{
|
|
43
|
+
name: 'chrome-mobile',
|
|
44
|
+
browser: 'chrome',
|
|
45
|
+
flags: {
|
|
46
|
+
chrome: true,
|
|
47
|
+
browserLoggingOn: true,
|
|
48
|
+
isMobile: true,
|
|
49
|
+
},
|
|
50
|
+
chrome: {
|
|
51
|
+
mobileEmulation: { deviceName: 'iPhone 7' },
|
|
52
|
+
},
|
|
53
|
+
windowWidth: undefined,
|
|
54
|
+
windowHeight: undefined,
|
|
55
|
+
},
|
|
56
|
+
'resolve chrome-mobile alias',
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
is(
|
|
60
|
+
settings.resolveWebdriver('chrome'),
|
|
61
|
+
{
|
|
62
|
+
name: 'chrome',
|
|
63
|
+
browser: 'chrome',
|
|
64
|
+
flags: {
|
|
65
|
+
chrome: true,
|
|
66
|
+
browserLoggingOn: true,
|
|
67
|
+
},
|
|
68
|
+
chrome: null,
|
|
69
|
+
windowWidth: undefined,
|
|
70
|
+
windowHeight: undefined,
|
|
71
|
+
},
|
|
72
|
+
'resolve chrome base browser',
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
is(settings.isKnownWebdriver('chrome-mobile'), true, 'known alias');
|
|
76
|
+
is(settings.isKnownWebdriver('firefox'), true, 'known base browser');
|
|
77
|
+
is(settings.isKnownWebdriver('unknown'), false, 'unknown webdriver');
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
withSettings(
|
|
82
|
+
{
|
|
83
|
+
webdriver_aliases: JSON.stringify({
|
|
84
|
+
'firefox-mobile': {
|
|
85
|
+
browser: 'firefox',
|
|
86
|
+
isMobile: true,
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
},
|
|
90
|
+
() => {
|
|
91
|
+
is(
|
|
92
|
+
settings.resolveWebdriver('firefox-mobile').browser,
|
|
93
|
+
'firefox',
|
|
94
|
+
'parse alias JSON string',
|
|
95
|
+
);
|
|
96
|
+
is(
|
|
97
|
+
DriverBase.isStdOutLogging('firefox-mobile'),
|
|
98
|
+
true,
|
|
99
|
+
'firefox alias uses stdout logging',
|
|
100
|
+
);
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
withSettings(
|
|
105
|
+
{
|
|
106
|
+
webdriver_aliases: {
|
|
107
|
+
'safari-mobile': {
|
|
108
|
+
browser: 'safari',
|
|
109
|
+
isMobile: true,
|
|
110
|
+
windowWidth: 375,
|
|
111
|
+
windowHeight: 667,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
() => {
|
|
116
|
+
is(
|
|
117
|
+
settings.resolveWebdriver('safari-mobile'),
|
|
118
|
+
{
|
|
119
|
+
name: 'safari-mobile',
|
|
120
|
+
browser: 'safari',
|
|
121
|
+
flags: {
|
|
122
|
+
safari: true,
|
|
123
|
+
isMobile: true,
|
|
124
|
+
},
|
|
125
|
+
chrome: null,
|
|
126
|
+
windowWidth: 375,
|
|
127
|
+
windowHeight: 667,
|
|
128
|
+
},
|
|
129
|
+
'resolve safari-mobile alias',
|
|
130
|
+
);
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
withSettings(
|
|
135
|
+
{
|
|
136
|
+
webdrivers: ['chrome-mobile'],
|
|
137
|
+
webdriver_aliases: {
|
|
138
|
+
'chrome-mobile': chromeMobileAlias,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
() => {
|
|
142
|
+
is(settings.webdrivers, ['chrome-mobile'], 'validate known alias');
|
|
143
|
+
},
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
throws(
|
|
147
|
+
() =>
|
|
148
|
+
withSettings(
|
|
149
|
+
{
|
|
150
|
+
webdrivers: ['chrome-mobile'],
|
|
151
|
+
},
|
|
152
|
+
() => {},
|
|
153
|
+
),
|
|
154
|
+
/unexpected webdriver 'chrome-mobile'/,
|
|
155
|
+
'reject undefined alias in webdrivers',
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
throws(
|
|
159
|
+
() =>
|
|
160
|
+
withSettings(
|
|
161
|
+
{
|
|
162
|
+
webdriver_aliases: {
|
|
163
|
+
chrome: {
|
|
164
|
+
browser: 'chrome',
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
() => {},
|
|
169
|
+
),
|
|
170
|
+
/conflicts with built-in browser/,
|
|
171
|
+
'reject alias colliding with base browser',
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
throws(
|
|
175
|
+
() => settings.resolveWebdriver('unknown-alias'),
|
|
176
|
+
/unexpected webdriver 'unknown-alias'/,
|
|
177
|
+
'reject unknown webdriver resolution',
|
|
178
|
+
);
|
|
179
|
+
}
|
package/tests/meta.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export var folders = ['base', 'series', 'webdriver', 'e2e', 'deps'];
|
|
1
|
+
export var folders = ['base', 'core', 'series', 'webdriver', 'e2e', 'deps'];
|
package/webdriver/driver-base.js
CHANGED
|
@@ -24,18 +24,21 @@ import {
|
|
|
24
24
|
import firefox from 'selenium-webdriver/firefox.js';
|
|
25
25
|
import chrome from 'selenium-webdriver/chrome.js';
|
|
26
26
|
|
|
27
|
-
function getChromeOptions() {
|
|
27
|
+
function getChromeOptions(resolved) {
|
|
28
|
+
const windowWidth =
|
|
29
|
+
resolved.windowWidth ?? settings.webdriver_window_width;
|
|
30
|
+
const windowHeight =
|
|
31
|
+
resolved.windowHeight ?? settings.webdriver_window_height;
|
|
32
|
+
|
|
28
33
|
const chromeOptions = new chrome.Options().windowSize({
|
|
29
|
-
width:
|
|
30
|
-
height:
|
|
34
|
+
width: windowWidth,
|
|
35
|
+
height: windowHeight,
|
|
31
36
|
});
|
|
32
37
|
if (settings.webdriver_headless) {
|
|
33
38
|
chromeOptions.addArguments('headless=new');
|
|
34
39
|
}
|
|
35
|
-
if (
|
|
36
|
-
chromeOptions.setMobileEmulation(
|
|
37
|
-
deviceName: 'iPhone 7',
|
|
38
|
-
});
|
|
40
|
+
if (resolved.chrome?.mobileEmulation) {
|
|
41
|
+
chromeOptions.setMobileEmulation(resolved.chrome.mobileEmulation);
|
|
39
42
|
}
|
|
40
43
|
// Accept self-signed certificates (for k3s testing)
|
|
41
44
|
chromeOptions.addArguments('ignore-certificate-errors');
|
|
@@ -44,6 +47,11 @@ function getChromeOptions() {
|
|
|
44
47
|
chromeOptions.addArguments('no-sandbox');
|
|
45
48
|
chromeOptions.addArguments('disable-dev-shm-usage');
|
|
46
49
|
|
|
50
|
+
// Use pipe-based DevTools instead of a port file. Prevents
|
|
51
|
+
// "DevToolsActivePort file doesn't exist" when Chrome exits early or on some
|
|
52
|
+
// macOS setups (Chrome 111+).
|
|
53
|
+
chromeOptions.addArguments('remote-debugging-pipe');
|
|
54
|
+
|
|
47
55
|
// Disable disk cache so stale resources from previous deploys are never
|
|
48
56
|
// served from cache. Each test session fetches everything from the network.
|
|
49
57
|
chromeOptions.addArguments('disk-cache-size=0');
|
|
@@ -58,6 +66,15 @@ function getFirefoxArgs() {
|
|
|
58
66
|
return settings.webdriver_headless ? ['-headless'] : [];
|
|
59
67
|
}
|
|
60
68
|
|
|
69
|
+
async function applyResolvedWindowSize(driver, resolved) {
|
|
70
|
+
if (resolved.windowWidth == null && resolved.windowHeight == null) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const width = resolved.windowWidth ?? settings.webdriver_window_width;
|
|
74
|
+
const height = resolved.windowHeight ?? settings.webdriver_window_height;
|
|
75
|
+
await driver.manage().window().setRect({ width, height, x: 0, y: 0 });
|
|
76
|
+
}
|
|
77
|
+
|
|
61
78
|
const defaultTimeout = 10;
|
|
62
79
|
const getTimeout = () => (testflow.core.getTimeout() || defaultTimeout) * 1000;
|
|
63
80
|
const getTimeoutOnFailure = () => (testflow.core.getTimeout() || 0) * 1000; // use non zero values for failure debugging
|
|
@@ -102,9 +119,10 @@ class DriverBase {
|
|
|
102
119
|
* Creates an instance of web driver.
|
|
103
120
|
*/
|
|
104
121
|
static async build() {
|
|
105
|
-
|
|
122
|
+
const resolved = settings.resolveWebdriver(settings.webdriver);
|
|
123
|
+
log(`Build WebDriver for '${resolved.name}'`);
|
|
106
124
|
|
|
107
|
-
switch (
|
|
125
|
+
switch (resolved.browser) {
|
|
108
126
|
case 'chrome': {
|
|
109
127
|
const driver = await new Builder()
|
|
110
128
|
.withCapabilities({
|
|
@@ -113,14 +131,13 @@ class DriverBase {
|
|
|
113
131
|
browser: browserLogLevel,
|
|
114
132
|
},
|
|
115
133
|
})
|
|
116
|
-
.setChromeOptions(getChromeOptions())
|
|
134
|
+
.setChromeOptions(getChromeOptions(resolved))
|
|
117
135
|
.build();
|
|
118
136
|
|
|
119
137
|
return [
|
|
120
138
|
driver,
|
|
121
139
|
{
|
|
122
|
-
|
|
123
|
-
chrome: true,
|
|
140
|
+
...resolved.flags,
|
|
124
141
|
},
|
|
125
142
|
];
|
|
126
143
|
}
|
|
@@ -149,38 +166,18 @@ class DriverBase {
|
|
|
149
166
|
return [
|
|
150
167
|
driver,
|
|
151
168
|
{
|
|
152
|
-
|
|
153
|
-
},
|
|
154
|
-
];
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
case 'chrome-mobile': {
|
|
158
|
-
const driver = await new Builder()
|
|
159
|
-
.withCapabilities({
|
|
160
|
-
'browserName': Browser.CHROME,
|
|
161
|
-
'goog:loggingPrefs': {
|
|
162
|
-
browser: browserLogLevel,
|
|
163
|
-
},
|
|
164
|
-
})
|
|
165
|
-
.setChromeOptions(getChromeOptions())
|
|
166
|
-
.build();
|
|
167
|
-
|
|
168
|
-
return [
|
|
169
|
-
driver,
|
|
170
|
-
{
|
|
171
|
-
isMobile: true,
|
|
172
|
-
chrome: true,
|
|
173
|
-
browserLoggingOn: true,
|
|
169
|
+
...resolved.flags,
|
|
174
170
|
},
|
|
175
171
|
];
|
|
176
172
|
}
|
|
177
173
|
|
|
178
174
|
case 'safari': {
|
|
179
175
|
const driver = await new Builder().forBrowser(Browser.SAFARI).build();
|
|
176
|
+
await applyResolvedWindowSize(driver, resolved);
|
|
180
177
|
return [
|
|
181
178
|
driver,
|
|
182
179
|
{
|
|
183
|
-
|
|
180
|
+
...resolved.flags,
|
|
184
181
|
},
|
|
185
182
|
];
|
|
186
183
|
}
|
|
@@ -190,18 +187,18 @@ class DriverBase {
|
|
|
190
187
|
return [
|
|
191
188
|
driver,
|
|
192
189
|
{
|
|
193
|
-
|
|
190
|
+
...resolved.flags,
|
|
194
191
|
},
|
|
195
192
|
];
|
|
196
193
|
}
|
|
197
194
|
|
|
198
195
|
default:
|
|
199
|
-
throw new Error(`Unexpected '${
|
|
196
|
+
throw new Error(`Unexpected '${resolved.browser}' webdriver browser`);
|
|
200
197
|
}
|
|
201
198
|
}
|
|
202
199
|
|
|
203
200
|
static isStdOutLogging(webdriver) {
|
|
204
|
-
return webdriver == 'firefox';
|
|
201
|
+
return settings.resolveWebdriver(webdriver).browser == 'firefox';
|
|
205
202
|
}
|
|
206
203
|
|
|
207
204
|
static get Errors() {
|