@camperaid/watest 2.5.4 → 2.5.6
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/core/series.js +16 -9
- package/core/settings.js +23 -2
- package/package.json +1 -1
- package/tests/series/perform/t-timeout.js +107 -0
- package/tests/series/run/t-debunk-failure.js +1 -0
- package/tests/series/run/t-debunk-success.js +1 -0
- package/tests/series/run/t-nested.js +1 -0
- package/tests/series/run/t-verify-webdriver.js +1 -0
- package/tests/series/run/t-verify.js +1 -0
- package/tests/series/servicer/t-nested-servicer-lifecycle.js +1 -0
- package/tests/series/servicer/t-servicer-no-services.js +1 -0
- package/tests/series/servicer/t-servicer-type-switching.js +1 -0
- package/tests/series/servicer/t-servicer.js +1 -0
- package/webdriver/driver-base.js +4 -1
package/.watestrc.js
CHANGED
|
@@ -43,6 +43,12 @@ const cfg = {
|
|
|
43
43
|
*/
|
|
44
44
|
webdriver_loglevel: process.env.WATEST_WEBDRIVER_LOGLEVEL,
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Additional Chrome arguments.
|
|
48
|
+
* JSON array, e.g.: ["enable-unsafe-swiftshader", "use-gl=swiftshader"]
|
|
49
|
+
*/
|
|
50
|
+
webdriver_chrome_args: process.env.WATEST_WEBDRIVER_CHROME_ARGS,
|
|
51
|
+
|
|
46
52
|
/**
|
|
47
53
|
* Web drivers to run tests for.
|
|
48
54
|
*/
|
package/core/series.js
CHANGED
|
@@ -481,6 +481,7 @@ class Series {
|
|
|
481
481
|
failures_info: [],
|
|
482
482
|
skip_on_fail: 'skip-on-fail',
|
|
483
483
|
init_or_uninit: true,
|
|
484
|
+
...(test_module.timeout && { timeout: test_module.timeout }),
|
|
484
485
|
});
|
|
485
486
|
}
|
|
486
487
|
|
|
@@ -500,13 +501,17 @@ class Series {
|
|
|
500
501
|
testname: path,
|
|
501
502
|
});
|
|
502
503
|
|
|
503
|
-
|
|
504
|
+
const testObj = {
|
|
504
505
|
name,
|
|
505
506
|
path,
|
|
506
507
|
func: test_wrap,
|
|
507
508
|
webdriver,
|
|
508
509
|
failures_info,
|
|
509
|
-
}
|
|
510
|
+
};
|
|
511
|
+
if (test_module.timeout) {
|
|
512
|
+
testObj.timeout = test_module.timeout;
|
|
513
|
+
}
|
|
514
|
+
tests.push(testObj);
|
|
510
515
|
}
|
|
511
516
|
|
|
512
517
|
// Add tests from subfolders.
|
|
@@ -531,6 +536,7 @@ class Series {
|
|
|
531
536
|
failures_info: [],
|
|
532
537
|
skip_on_fail: 'skip-on-fail',
|
|
533
538
|
init_or_uninit: true,
|
|
539
|
+
...(test_module.timeout && { timeout: test_module.timeout }),
|
|
534
540
|
});
|
|
535
541
|
}
|
|
536
542
|
|
|
@@ -653,6 +659,7 @@ class Series {
|
|
|
653
659
|
skip_on_fail,
|
|
654
660
|
run_in_child_process,
|
|
655
661
|
init_or_uninit,
|
|
662
|
+
timeout,
|
|
656
663
|
} = test;
|
|
657
664
|
|
|
658
665
|
if (stop && !name.endsWith('uninit')) {
|
|
@@ -678,6 +685,7 @@ class Series {
|
|
|
678
685
|
|
|
679
686
|
// Invoke a test.
|
|
680
687
|
log(`\n!Running: ${name}, path: ${path}\n`);
|
|
688
|
+
|
|
681
689
|
let start_time = new Date();
|
|
682
690
|
let kungFuDeathGrip = null;
|
|
683
691
|
let kungFuDeathGripResolve = null;
|
|
@@ -695,22 +703,21 @@ class Series {
|
|
|
695
703
|
try {
|
|
696
704
|
this.core.setExpectedFailures(failures_info);
|
|
697
705
|
|
|
698
|
-
// If timeout is given then race it against the test.
|
|
699
|
-
|
|
706
|
+
// If timeout is given (from meta.js or settings) then race it against the test.
|
|
707
|
+
const effectiveTimeout = timeout ?? settings.timeout;
|
|
708
|
+
if (effectiveTimeout) {
|
|
709
|
+
const timeoutMs = effectiveTimeout * 1000;
|
|
700
710
|
kungFuDeathGrip = new Promise(
|
|
701
711
|
resolve => (kungFuDeathGripResolve = resolve),
|
|
702
712
|
).then(value => {
|
|
703
713
|
if (value != kKungFuDeathGripCancelled) {
|
|
704
714
|
fail(
|
|
705
|
-
`Test ${name} takes longer than ${
|
|
715
|
+
`Test ${name} takes longer than ${effectiveTimeout}s. It's either slow or never ends.`,
|
|
706
716
|
);
|
|
707
717
|
return kKungFuDeathGripTimeout;
|
|
708
718
|
}
|
|
709
719
|
});
|
|
710
|
-
kungFuDeathGripTimer = setTimeout(
|
|
711
|
-
kungFuDeathGripResolve,
|
|
712
|
-
settings.timeout,
|
|
713
|
-
);
|
|
720
|
+
kungFuDeathGripTimer = setTimeout(kungFuDeathGripResolve, timeoutMs);
|
|
714
721
|
let retval = await Promise.race([func(), kungFuDeathGrip]);
|
|
715
722
|
if (retval != kKungFuDeathGripTimeout) {
|
|
716
723
|
clearTimeout(kungFuDeathGripTimer);
|
package/core/settings.js
CHANGED
|
@@ -54,11 +54,11 @@ class Settings {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
get testFilePattern() {
|
|
57
|
-
return this.rc
|
|
57
|
+
return this.rc?.test_file_pattern || /^t[-_]/;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
get timeout() {
|
|
61
|
-
return parseInt(this.rc
|
|
61
|
+
return parseInt(this.rc?.timeout) || 0;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
setupTmpStorageDir() {
|
|
@@ -112,12 +112,33 @@ class Settings {
|
|
|
112
112
|
this.rc.webdriver_headless == true ||
|
|
113
113
|
this.rc.webdriver_headless == 'true';
|
|
114
114
|
this.webdriver_loglevel = this.rc.webdriver_loglevel;
|
|
115
|
+
this.webdriver_chrome_args = [];
|
|
116
|
+
|
|
117
|
+
if (typeof this.rc.webdriver_chrome_args == 'string') {
|
|
118
|
+
try {
|
|
119
|
+
const parsed = JSON.parse(this.rc.webdriver_chrome_args);
|
|
120
|
+
if (Array.isArray(parsed)) {
|
|
121
|
+
this.webdriver_chrome_args = parsed;
|
|
122
|
+
}
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.error(
|
|
125
|
+
`Settings: failed to parse webdriver_chrome_args '${this.rc.webdriver_chrome_args}'`,
|
|
126
|
+
e,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
115
130
|
|
|
116
131
|
this.webdriver_window_width =
|
|
117
132
|
parseInt(this.rc.webdriver_window_width) || 1366;
|
|
118
133
|
this.webdriver_window_height =
|
|
119
134
|
parseInt(this.rc.webdriver_window_height) || 768;
|
|
120
135
|
|
|
136
|
+
if (!this.silent) {
|
|
137
|
+
console.log(
|
|
138
|
+
`Settings: webdriver_chrome_args=${JSON.stringify(this.webdriver_chrome_args)}`,
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
121
142
|
if (this.webdrivers && !this.silent) {
|
|
122
143
|
console.log(`Settings: ${this.webdrivers.join(', ')} webdrivers`);
|
|
123
144
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { is_test_output } from '../test.js';
|
|
2
|
+
import { success } from '../../../core/core.js';
|
|
3
|
+
import { Core } from '../../../core/core.js';
|
|
4
|
+
import { Series } from '../../../core/series.js';
|
|
5
|
+
|
|
6
|
+
class MockLogPipe {
|
|
7
|
+
attach() {
|
|
8
|
+
return Promise.resolve();
|
|
9
|
+
}
|
|
10
|
+
release() {
|
|
11
|
+
return Promise.resolve();
|
|
12
|
+
}
|
|
13
|
+
logToFile() {}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function make_perform_with_timeout(tests) {
|
|
17
|
+
return async () => {
|
|
18
|
+
const series = new Series('tests/', {
|
|
19
|
+
core: new Core(),
|
|
20
|
+
LogPipe: new MockLogPipe(),
|
|
21
|
+
});
|
|
22
|
+
try {
|
|
23
|
+
await series.perform({ folder: 'tests/', tests });
|
|
24
|
+
} finally {
|
|
25
|
+
series.shutdown();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export async function test() {
|
|
31
|
+
// Test that timeout from meta.js causes test to fail after specified time
|
|
32
|
+
await is_test_output(
|
|
33
|
+
make_perform_with_timeout([
|
|
34
|
+
{
|
|
35
|
+
name: 't-slow.js',
|
|
36
|
+
path: 'tests/t-slow.js',
|
|
37
|
+
func: () => new Promise(resolve => setTimeout(resolve, 500)),
|
|
38
|
+
failures_info: [],
|
|
39
|
+
timeout: 0.05, // 50ms timeout in seconds
|
|
40
|
+
},
|
|
41
|
+
]),
|
|
42
|
+
[
|
|
43
|
+
'\x1B[38;5;99mStarted\x1B[0m tests/',
|
|
44
|
+
'!Running: t-slow.js, path: tests/t-slow.js',
|
|
45
|
+
'>t-slow.js completed in',
|
|
46
|
+
'\x1B[38;5;243mCompleted\x1B[0m tests/',
|
|
47
|
+
'Testsuite: shutdown',
|
|
48
|
+
],
|
|
49
|
+
[
|
|
50
|
+
"\x1B[31mFailed:\x1B[0m Test t-slow.js takes longer than 0.05s. It's either slow or never ends.",
|
|
51
|
+
'\x1B[31m>t-slow.js\x1B[0m has 1 failure(s)',
|
|
52
|
+
],
|
|
53
|
+
'meta timeout causes test to fail',
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Test that test completes normally when timeout is not exceeded
|
|
57
|
+
await is_test_output(
|
|
58
|
+
make_perform_with_timeout([
|
|
59
|
+
{
|
|
60
|
+
name: 't-fast.js',
|
|
61
|
+
path: 'tests/t-fast.js',
|
|
62
|
+
func: () => {
|
|
63
|
+
success('fast test passes');
|
|
64
|
+
return Promise.resolve();
|
|
65
|
+
},
|
|
66
|
+
failures_info: [],
|
|
67
|
+
timeout: 1, // 1 second timeout
|
|
68
|
+
},
|
|
69
|
+
]),
|
|
70
|
+
[
|
|
71
|
+
'\x1B[38;5;99mStarted\x1B[0m tests/',
|
|
72
|
+
'!Running: t-fast.js, path: tests/t-fast.js',
|
|
73
|
+
'\x1B[32mOk:\x1B[0m fast test passes',
|
|
74
|
+
'>t-fast.js completed in',
|
|
75
|
+
'\x1B[38;5;243mCompleted\x1B[0m tests/',
|
|
76
|
+
'Testsuite: shutdown',
|
|
77
|
+
],
|
|
78
|
+
[],
|
|
79
|
+
'test completes within timeout',
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// Test that no timeout applies when timeout is undefined
|
|
83
|
+
await is_test_output(
|
|
84
|
+
make_perform_with_timeout([
|
|
85
|
+
{
|
|
86
|
+
name: 't-no-timeout.js',
|
|
87
|
+
path: 'tests/t-no-timeout.js',
|
|
88
|
+
func: () => {
|
|
89
|
+
success('no timeout test passes');
|
|
90
|
+
return new Promise(resolve => setTimeout(resolve, 10));
|
|
91
|
+
},
|
|
92
|
+
failures_info: [],
|
|
93
|
+
// timeout: undefined - no timeout set
|
|
94
|
+
},
|
|
95
|
+
]),
|
|
96
|
+
[
|
|
97
|
+
'\x1B[38;5;99mStarted\x1B[0m tests/',
|
|
98
|
+
'!Running: t-no-timeout.js, path: tests/t-no-timeout.js',
|
|
99
|
+
'\x1B[32mOk:\x1B[0m no timeout test passes',
|
|
100
|
+
'>t-no-timeout.js completed in',
|
|
101
|
+
'\x1B[38;5;243mCompleted\x1B[0m tests/',
|
|
102
|
+
'Testsuite: shutdown',
|
|
103
|
+
],
|
|
104
|
+
[],
|
|
105
|
+
'test runs without timeout when not specified',
|
|
106
|
+
);
|
|
107
|
+
}
|
|
@@ -20,6 +20,7 @@ export async function test() {
|
|
|
20
20
|
const expected_stdout = [
|
|
21
21
|
'Settings: no temporary storage dir',
|
|
22
22
|
'Settings: logging into /tmp',
|
|
23
|
+
'Settings: webdriver_chrome_args=[]',
|
|
23
24
|
'Settings: chrome webdrivers',
|
|
24
25
|
'\x1B[38;5;99mStarted\x1B[0m mac/',
|
|
25
26
|
'\x1B[38;5;99mStarted\x1B[0m mac/unit',
|
|
@@ -33,6 +33,7 @@ export async function test() {
|
|
|
33
33
|
const expected_stdout = [
|
|
34
34
|
'Settings: no temporary storage dir',
|
|
35
35
|
'Settings: logging into /tmp',
|
|
36
|
+
'Settings: webdriver_chrome_args=[]',
|
|
36
37
|
'Settings: chrome webdrivers',
|
|
37
38
|
...expected_out_for_success,
|
|
38
39
|
...expected_out_for_success,
|
|
@@ -35,6 +35,7 @@ export async function test() {
|
|
|
35
35
|
[
|
|
36
36
|
'Settings: no temporary storage dir',
|
|
37
37
|
'Settings: logging into /tmp',
|
|
38
|
+
'Settings: webdriver_chrome_args=[]',
|
|
38
39
|
'Settings: chrome webdrivers',
|
|
39
40
|
'\x1B[38;5;99mStarted\x1B[0m mac/',
|
|
40
41
|
'\x1B[38;5;99mStarted\x1B[0m mac/unit',
|
|
@@ -33,6 +33,7 @@ export async function test() {
|
|
|
33
33
|
const expected_stdout = [
|
|
34
34
|
'Settings: no temporary storage dir',
|
|
35
35
|
'Settings: logging into /tmp',
|
|
36
|
+
'Settings: webdriver_chrome_args=[]',
|
|
36
37
|
'Settings: chrome webdrivers',
|
|
37
38
|
'\x1B[38;5;99mStarted\x1B[0m mac/',
|
|
38
39
|
'\x1B[38;5;99mStarted\x1B[0m mac/webdriver',
|
|
@@ -33,6 +33,7 @@ export async function test() {
|
|
|
33
33
|
const expected_stdout = [
|
|
34
34
|
'Settings: no temporary storage dir',
|
|
35
35
|
'Settings: logging into /tmp',
|
|
36
|
+
'Settings: webdriver_chrome_args=[]',
|
|
36
37
|
'Settings: chrome webdrivers',
|
|
37
38
|
'\x1B[38;5;99mStarted\x1B[0m mac/',
|
|
38
39
|
'\x1B[38;5;99mStarted\x1B[0m mac/unit',
|
|
@@ -26,6 +26,7 @@ export async function test() {
|
|
|
26
26
|
[
|
|
27
27
|
'Settings: no temporary storage dir',
|
|
28
28
|
'Settings: logging into /tmp',
|
|
29
|
+
'Settings: webdriver_chrome_args=[]',
|
|
29
30
|
'Settings: chrome webdrivers',
|
|
30
31
|
'\x1B[38;5;99mStarted\x1B[0m mac/',
|
|
31
32
|
'!Running: mac/init, path: tests/meta.js',
|
|
@@ -66,6 +66,7 @@ export async function test() {
|
|
|
66
66
|
[
|
|
67
67
|
'Settings: no temporary storage dir',
|
|
68
68
|
'Settings: logging into /tmp',
|
|
69
|
+
'Settings: webdriver_chrome_args=[]',
|
|
69
70
|
'Settings: chrome webdrivers',
|
|
70
71
|
'\x1B[38;5;99mStarted\x1B[0m mac/',
|
|
71
72
|
'\x1B[38;5;99mStarted\x1B[0m mac/folder1',
|
|
@@ -22,6 +22,7 @@ export async function test() {
|
|
|
22
22
|
[
|
|
23
23
|
'Settings: no temporary storage dir',
|
|
24
24
|
'Settings: logging into /tmp',
|
|
25
|
+
'Settings: webdriver_chrome_args=[]',
|
|
25
26
|
'Settings: chrome webdrivers',
|
|
26
27
|
'\x1B[38;5;99mStarted\x1B[0m mac/',
|
|
27
28
|
'!Running: mac/init, path: tests/meta.js',
|
package/webdriver/driver-base.js
CHANGED
|
@@ -30,7 +30,7 @@ function getChromeOptions() {
|
|
|
30
30
|
height: settings.webdriver_window_height,
|
|
31
31
|
});
|
|
32
32
|
if (settings.webdriver_headless) {
|
|
33
|
-
chromeOptions.addArguments('headless');
|
|
33
|
+
chromeOptions.addArguments('headless=new');
|
|
34
34
|
}
|
|
35
35
|
if (settings.webdriver == 'chrome-mobile') {
|
|
36
36
|
chromeOptions.setMobileEmulation({
|
|
@@ -44,6 +44,9 @@ function getChromeOptions() {
|
|
|
44
44
|
chromeOptions.addArguments('no-sandbox');
|
|
45
45
|
chromeOptions.addArguments('disable-dev-shm-usage');
|
|
46
46
|
|
|
47
|
+
for (const arg of settings.webdriver_chrome_args || []) {
|
|
48
|
+
chromeOptions.addArguments(arg);
|
|
49
|
+
}
|
|
47
50
|
return chromeOptions;
|
|
48
51
|
}
|
|
49
52
|
|