testem 3.19.0 → 3.20.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/README.md +32 -9
- package/lib/api.js +1 -1
- package/lib/app.js +204 -141
- package/lib/browser_launcher.js +5 -6
- package/lib/config.js +246 -133
- package/lib/file_watcher.js +111 -37
- package/lib/file_watcher_impl.js +295 -0
- package/lib/launcher.js +14 -23
- package/lib/log.js +92 -0
- package/lib/process-ctl.js +4 -4
- package/lib/reporters/dev/index.js +2 -1
- package/lib/reporters/dev/split_log_panel.js +2 -2
- package/lib/runners/browser_test_runner.js +15 -8
- package/lib/runners/hook_runner.js +13 -12
- package/lib/runners/process_test_runner.js +4 -5
- package/lib/runners/tap_process_test_runner.js +5 -6
- package/lib/runners/to-result.js +1 -1
- package/lib/server/index.js +62 -38
- package/lib/tap_consumer.js +74 -12
- package/lib/utils/browser-args.js +1 -1
- package/lib/utils/esbuild-browser-polyfills.js +46 -0
- package/lib/utils/esbuild-buffer-inject.js +6 -0
- package/lib/utils/expand_glob_pattern.js +19 -0
- package/lib/utils/file_watch_glob_policy.js +119 -0
- package/lib/utils/fileutils.js +4 -4
- package/lib/utils/is_emfile_error.js +16 -0
- package/lib/utils/known-browsers.js +161 -123
- package/lib/utils/path_pattern_match.js +39 -0
- package/lib/utils/process.js +45 -4
- package/lib/utils/promises.js +149 -0
- package/lib/utils/report-file.js +1 -3
- package/lib/utils/reporter.js +5 -5
- package/lib/utils/run-timeout.js +4 -4
- package/lib/utils/signal-listeners.js +9 -7
- package/lib/utils/tmp-cleanup.js +26 -0
- package/package.json +42 -32
- package/testem.js +170 -79
package/lib/utils/process.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const execa = require('execa').execa;
|
|
2
|
-
const log = require('
|
|
3
|
-
const Bluebird = require('bluebird');
|
|
2
|
+
const log = require('../log');
|
|
4
3
|
const EventEmitter = require('events').EventEmitter;
|
|
5
4
|
|
|
6
5
|
const isWin = require('./is-win')();
|
|
6
|
+
const closeTimeoutAfterExit = 1000;
|
|
7
7
|
|
|
8
8
|
module.exports = class Process extends EventEmitter {
|
|
9
9
|
constructor(name, options, process) {
|
|
@@ -14,6 +14,9 @@ module.exports = class Process extends EventEmitter {
|
|
|
14
14
|
this.process = process;
|
|
15
15
|
this.stdout = '';
|
|
16
16
|
this.stderr = '';
|
|
17
|
+
this.exitAt = null;
|
|
18
|
+
this._killResolve = null;
|
|
19
|
+
this._closeFallbackTimer = null;
|
|
17
20
|
this.process.stdout.on('data', chunk => {
|
|
18
21
|
this.stdout += chunk;
|
|
19
22
|
this.emit('out');
|
|
@@ -26,6 +29,11 @@ module.exports = class Process extends EventEmitter {
|
|
|
26
29
|
});
|
|
27
30
|
|
|
28
31
|
this.process.on('close', this.onClose.bind(this));
|
|
32
|
+
this.process.on('exit', code => {
|
|
33
|
+
this.exitAt = Date.now();
|
|
34
|
+
this.exitCode = code;
|
|
35
|
+
this.scheduleCloseFallback();
|
|
36
|
+
});
|
|
29
37
|
this.process.on('error', this.onError.bind(this));
|
|
30
38
|
|
|
31
39
|
this.process.then(result => {
|
|
@@ -38,9 +46,35 @@ module.exports = class Process extends EventEmitter {
|
|
|
38
46
|
});
|
|
39
47
|
}
|
|
40
48
|
|
|
49
|
+
scheduleCloseFallback() {
|
|
50
|
+
if (!this._killResolve || !this.exitAt || this._closeFallbackTimer || !this._killTimer) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this._closeFallbackTimer = setTimeout(() => {
|
|
55
|
+
this._closeFallbackTimer = null;
|
|
56
|
+
|
|
57
|
+
if (!this._killResolve || !this.exitAt) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (this._killTimer) {
|
|
62
|
+
clearTimeout(this._killTimer);
|
|
63
|
+
this._killTimer = null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.process = null;
|
|
67
|
+
|
|
68
|
+
const resolve = this._killResolve;
|
|
69
|
+
this._killResolve = null;
|
|
70
|
+
resolve(this.exitCode);
|
|
71
|
+
}, closeTimeoutAfterExit);
|
|
72
|
+
}
|
|
73
|
+
|
|
41
74
|
onKillTimeout() {
|
|
42
75
|
log.warn('Process ' + this.name + ' not terminated in ' + this.killTimeout + 'ms.');
|
|
43
76
|
kill(this.process, 'SIGKILL');
|
|
77
|
+
this.scheduleCloseFallback();
|
|
44
78
|
}
|
|
45
79
|
|
|
46
80
|
onClose(code) {
|
|
@@ -95,15 +129,21 @@ module.exports = class Process extends EventEmitter {
|
|
|
95
129
|
if (!this.process) {
|
|
96
130
|
log.info('Process ' + this.name + ' already killed.');
|
|
97
131
|
|
|
98
|
-
return
|
|
132
|
+
return Promise.resolve(this.exitCode);
|
|
99
133
|
}
|
|
100
134
|
|
|
101
135
|
sig = sig || 'SIGTERM';
|
|
102
136
|
|
|
103
137
|
let self = this;
|
|
104
138
|
|
|
105
|
-
return new
|
|
139
|
+
return new Promise(resolve => {
|
|
140
|
+
self._killResolve = resolve;
|
|
106
141
|
self.process.once('close', (code, sig) => {
|
|
142
|
+
if (self._closeFallbackTimer) {
|
|
143
|
+
clearTimeout(self._closeFallbackTimer);
|
|
144
|
+
self._closeFallbackTimer = null;
|
|
145
|
+
}
|
|
146
|
+
self._killResolve = null;
|
|
107
147
|
self.process = null;
|
|
108
148
|
if (self._killTimer) {
|
|
109
149
|
clearTimeout(self._killTimer);
|
|
@@ -123,6 +163,7 @@ module.exports = class Process extends EventEmitter {
|
|
|
123
163
|
// See https://github.com/testem/testem/pull/1335 for more information.
|
|
124
164
|
if (self.process) {
|
|
125
165
|
kill(self.process, sig);
|
|
166
|
+
self.scheduleCloseFallback();
|
|
126
167
|
} else {
|
|
127
168
|
log.info('Process ' + this.name + ' already killed.');
|
|
128
169
|
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
function fromCallback(fn) {
|
|
2
|
+
return new Promise((resolve, reject) => {
|
|
3
|
+
fn((err, result) => {
|
|
4
|
+
if (err) {
|
|
5
|
+
reject(err);
|
|
6
|
+
} else {
|
|
7
|
+
resolve(result);
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function filter(arr, predicate) {
|
|
14
|
+
const results = await Promise.all(arr.map(item => predicate(item)));
|
|
15
|
+
return arr.filter((_, i) => results[i]);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function reduce(arr, reducer, initialValue) {
|
|
19
|
+
return arr.reduce(
|
|
20
|
+
(acc, item) => acc.then(a => reducer(a, item)),
|
|
21
|
+
Promise.resolve(initialValue)
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function each(arr, fn) {
|
|
26
|
+
return arr.reduce(
|
|
27
|
+
(p, item) => p.then(() => fn(item)),
|
|
28
|
+
Promise.resolve()
|
|
29
|
+
).then(() => arr);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
class Disposer {
|
|
33
|
+
constructor(promise, cleanup) {
|
|
34
|
+
this.promise = Promise.resolve(promise);
|
|
35
|
+
this.cleanup = cleanup;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function disposer(promise, cleanup) {
|
|
40
|
+
return new Disposer(promise, cleanup);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function using(resource, fn) {
|
|
44
|
+
const isDisposer = resource instanceof Disposer;
|
|
45
|
+
let value;
|
|
46
|
+
|
|
47
|
+
if (isDisposer) {
|
|
48
|
+
try {
|
|
49
|
+
value = await resource.promise;
|
|
50
|
+
} catch (setupErr) {
|
|
51
|
+
const inspection = {
|
|
52
|
+
isRejected: () => true,
|
|
53
|
+
reason: () => setupErr,
|
|
54
|
+
};
|
|
55
|
+
try {
|
|
56
|
+
await resource.cleanup(undefined, inspection);
|
|
57
|
+
} catch {
|
|
58
|
+
// Prefer the setup error below
|
|
59
|
+
}
|
|
60
|
+
throw setupErr;
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
value = await resource;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let result, rejected = false, error;
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
result = await fn(value);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
rejected = true;
|
|
72
|
+
error = err;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (isDisposer) {
|
|
76
|
+
const inspection = {
|
|
77
|
+
isRejected: () => rejected,
|
|
78
|
+
reason: () => error,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
await resource.cleanup(value, inspection);
|
|
83
|
+
} catch (cleanupErr) {
|
|
84
|
+
if (!rejected) {
|
|
85
|
+
// Callback succeeded but cleanup failed — surface cleanup error
|
|
86
|
+
throw cleanupErr;
|
|
87
|
+
}
|
|
88
|
+
// Both callback and cleanup failed — suppress cleanup error, re-throw original below
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (rejected) {
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function mapLimit(arr, concurrency, fn) {
|
|
99
|
+
if (!isFinite(concurrency) || concurrency >= arr.length) {
|
|
100
|
+
return Promise.all(arr.map(fn));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let index = 0;
|
|
104
|
+
let results = new Array(arr.length);
|
|
105
|
+
|
|
106
|
+
function next() {
|
|
107
|
+
let i = index++;
|
|
108
|
+
if (i >= arr.length) {
|
|
109
|
+
return Promise.resolve();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return Promise.resolve(fn(arr[i])).then(result => {
|
|
113
|
+
results[i] = result;
|
|
114
|
+
return next();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let workers = [];
|
|
119
|
+
for (let w = 0; w < Math.min(concurrency, arr.length); w++) {
|
|
120
|
+
workers.push(next());
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return Promise.all(workers).then(() => results);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function retry(fn, { max_tries = 3 } = {}) {
|
|
127
|
+
let lastErr;
|
|
128
|
+
for (let i = 0; i < max_tries; i++) {
|
|
129
|
+
try {
|
|
130
|
+
return await fn();
|
|
131
|
+
} catch (e) {
|
|
132
|
+
lastErr = e;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
throw lastErr;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function delay(ms) {
|
|
139
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function asCallback(cb) {
|
|
143
|
+
return [
|
|
144
|
+
result => { if (cb) { cb(null, result); } return result; },
|
|
145
|
+
err => { if (cb) { cb(err); } throw err; }
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
module.exports = { fromCallback, filter, reduce, each, mapLimit, retry, delay, asCallback, Disposer, disposer, using };
|
package/lib/utils/report-file.js
CHANGED
|
@@ -4,8 +4,6 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const mkdirp = require('mkdirp');
|
|
6
6
|
const PassThrough = require('stream').PassThrough;
|
|
7
|
-
const Bluebird = require('bluebird');
|
|
8
|
-
|
|
9
7
|
module.exports = class ReportFile {
|
|
10
8
|
constructor(reportFile) {
|
|
11
9
|
this.file = reportFile;
|
|
@@ -27,7 +25,7 @@ module.exports = class ReportFile {
|
|
|
27
25
|
this.outputStream.on('end', finish);
|
|
28
26
|
this.outputStream.on('error', finish);
|
|
29
27
|
|
|
30
|
-
this.closePromise = new
|
|
28
|
+
this.closePromise = new Promise((resolve, reject) => {
|
|
31
29
|
this.outputStream.on('finish', resolve);
|
|
32
30
|
this.outputStream.on('error', reject);
|
|
33
31
|
});
|
package/lib/utils/reporter.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const log = require('
|
|
3
|
+
const { disposer } = require('./promises');
|
|
4
|
+
const log = require('../log');
|
|
5
5
|
|
|
6
6
|
const reporters = require('../reporters');
|
|
7
7
|
const isa = require('./isa');
|
|
@@ -107,11 +107,11 @@ class Reporter {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
Reporter.with = (app, stdout, path) =>
|
|
110
|
+
Reporter.with = (app, stdout, path) => disposer(Promise.resolve(new Reporter(app, stdout, path)), (reporter, promise) => {
|
|
111
111
|
if (promise.isRejected()) {
|
|
112
112
|
let err = promise.reason();
|
|
113
113
|
|
|
114
|
-
if (!err.hideFromReporter) {
|
|
114
|
+
if (reporter && !err.hideFromReporter) {
|
|
115
115
|
reporter.report(null, {
|
|
116
116
|
passed: false,
|
|
117
117
|
name: err.name || 'unknown error',
|
|
@@ -122,7 +122,7 @@ Reporter.with = (app, stdout, path) => Bluebird.try(() => new Reporter(app, stdo
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
return reporter.close();
|
|
125
|
+
return reporter ? reporter.close() : Promise.resolve();
|
|
126
126
|
});
|
|
127
127
|
|
|
128
128
|
function forwardToReporters(fn) {
|
package/lib/utils/run-timeout.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { disposer } = require('./promises');
|
|
4
4
|
const EventEmitter = require('events').EventEmitter;
|
|
5
5
|
|
|
6
6
|
class RunTimeout {
|
|
@@ -11,7 +11,7 @@ class RunTimeout {
|
|
|
11
11
|
static with(timeout) {
|
|
12
12
|
let runTimeout = new RunTimeout(timeout);
|
|
13
13
|
|
|
14
|
-
return runTimeout.start()
|
|
14
|
+
return disposer(runTimeout.start(), () => runTimeout.stop());
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
start() {
|
|
@@ -23,7 +23,7 @@ class RunTimeout {
|
|
|
23
23
|
}, this.timeout * 1000);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
return
|
|
26
|
+
return Promise.resolve(this);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
setTimedOut() {
|
|
@@ -39,7 +39,7 @@ class RunTimeout {
|
|
|
39
39
|
|
|
40
40
|
try(fn) {
|
|
41
41
|
if (this.timedOut) {
|
|
42
|
-
return
|
|
42
|
+
return Promise.reject(new Error('Run timed out.'));
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
return fn();
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { disposer } = require('./promises');
|
|
4
4
|
const EventEmitter = require('events').EventEmitter;
|
|
5
5
|
|
|
6
6
|
class SignalListeners extends EventEmitter {
|
|
7
7
|
static with() {
|
|
8
8
|
let signalListeners = new this();
|
|
9
9
|
|
|
10
|
-
return signalListeners.add()
|
|
10
|
+
return disposer(signalListeners.add(), () => signalListeners.remove());
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
SignalListeners.prototype.add =
|
|
14
|
+
SignalListeners.prototype.add = function() {
|
|
15
15
|
this._boundSigInterrupt = () => {
|
|
16
16
|
this.emit('signal', new Error('Received SIGINT signal'));
|
|
17
17
|
};
|
|
@@ -23,16 +23,18 @@ SignalListeners.prototype.add = Bluebird.method(function() {
|
|
|
23
23
|
};
|
|
24
24
|
process.on('SIGTERM', this._boundSigTerminate);
|
|
25
25
|
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
26
|
+
return Promise.resolve(this);
|
|
27
|
+
};
|
|
28
28
|
|
|
29
|
-
SignalListeners.prototype.remove =
|
|
29
|
+
SignalListeners.prototype.remove = function() {
|
|
30
30
|
if (this._boundSigInterrupt) {
|
|
31
31
|
process.removeListener('SIGINT', this._boundSigInterrupt);
|
|
32
32
|
}
|
|
33
33
|
if (this._boundSigTerminate) {
|
|
34
34
|
process.removeListener('SIGTERM', this._boundSigTerminate);
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
return Promise.resolve();
|
|
38
|
+
};
|
|
37
39
|
|
|
38
40
|
module.exports = SignalListeners;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const dirsToClean = new Set();
|
|
6
|
+
|
|
7
|
+
process.on('exit', () => {
|
|
8
|
+
for (const dir of dirsToClean) {
|
|
9
|
+
try {
|
|
10
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
11
|
+
} catch {
|
|
12
|
+
// Best-effort cleanup: ignore errors during process exit
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Allow graceful cleanup when the process is terminated by a signal.
|
|
18
|
+
// Calling process.exit() ensures the 'exit' event fires and cleanup runs.
|
|
19
|
+
process.on('SIGTERM', () => process.exit(0));
|
|
20
|
+
process.on('SIGINT', () => process.exit(130));
|
|
21
|
+
|
|
22
|
+
function registerCleanup(dir) {
|
|
23
|
+
dirsToClean.add(dir);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { registerCleanup, _registeredDirs: dirsToClean };
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"unittest",
|
|
8
8
|
"browser"
|
|
9
9
|
],
|
|
10
|
-
"version": "3.
|
|
10
|
+
"version": "3.20.0",
|
|
11
11
|
"author": "Toby Ho <airportyh@gmail.com>",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
@@ -17,35 +17,34 @@
|
|
|
17
17
|
"url": "http://github.com/testem/testem/issues"
|
|
18
18
|
},
|
|
19
19
|
"engines": {
|
|
20
|
-
"node": ">=
|
|
20
|
+
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
21
21
|
},
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@xmldom/xmldom": "^0.
|
|
25
|
-
"backbone": "^1.1
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"commander": "^
|
|
29
|
-
"compression": "^1.
|
|
30
|
-
"consolidate": "^0.
|
|
24
|
+
"@xmldom/xmldom": "^0.9.9",
|
|
25
|
+
"backbone": "^1.6.1",
|
|
26
|
+
"charm": "^1.0.2",
|
|
27
|
+
"chokidar": "^5.0.0",
|
|
28
|
+
"commander": "^14.0.3",
|
|
29
|
+
"compression": "^1.8.1",
|
|
30
|
+
"consolidate": "^1.0.4",
|
|
31
31
|
"execa": "^9.6.1",
|
|
32
|
-
"express": "^
|
|
33
|
-
"fireworm": "^0.7.2",
|
|
32
|
+
"express": "^5.2.1",
|
|
34
33
|
"glob": "^13.0.6",
|
|
35
|
-
"http-proxy": "^1.
|
|
36
|
-
"js-yaml": "^
|
|
37
|
-
"lodash": "^4.
|
|
34
|
+
"http-proxy": "^1.18.1",
|
|
35
|
+
"js-yaml": "^4.1.1",
|
|
36
|
+
"lodash": "^4.18.1",
|
|
37
|
+
"minimatch": "^10.2.5",
|
|
38
38
|
"mkdirp": "^3.0.1",
|
|
39
39
|
"mustache": "^4.2.0",
|
|
40
|
-
"node-notifier": "^10.0.
|
|
41
|
-
"npmlog": "^6.0.0",
|
|
40
|
+
"node-notifier": "^10.0.1",
|
|
42
41
|
"printf": "^0.6.1",
|
|
42
|
+
"proc-log": "^6.1.0",
|
|
43
43
|
"rimraf": "^6.1.3",
|
|
44
|
-
"socket.io": "^4.
|
|
44
|
+
"socket.io": "^4.8.3",
|
|
45
45
|
"spawn-args": "^0.2.0",
|
|
46
46
|
"styled_string": "0.0.1",
|
|
47
|
-
"tap-parser": "^
|
|
48
|
-
"tmp": "^0.2.5"
|
|
47
|
+
"tap-parser": "^18.3.0"
|
|
49
48
|
},
|
|
50
49
|
"files": [
|
|
51
50
|
"lib",
|
|
@@ -59,30 +58,41 @@
|
|
|
59
58
|
"scripts": {
|
|
60
59
|
"install:all": "npm install && npm install phantomjs-prebuilt",
|
|
61
60
|
"test": "mocha tests/*_tests.js tests/**/*_tests.js",
|
|
61
|
+
"test:verbose": "TESTEM_VERBOSE=1 mocha tests/*_tests.js tests/**/*_tests.js",
|
|
62
62
|
"cover": "cover run ./node_modules/.bin/_mocha tests/*_tests.js tests/**/*_tests.js; cover report html; open cover_html/index.html",
|
|
63
63
|
"integration": "node ./bin/run-integration.js",
|
|
64
|
+
"ci:safari-smoke": "node ./scripts/safari-ci-smoke.js",
|
|
64
65
|
"browser-tests": "cd examples/saucelabs/ && ../../testem.js ci -d",
|
|
65
66
|
"lint": "eslint ."
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
68
|
-
"
|
|
69
|
-
"
|
|
69
|
+
"@cypress/request": "^3.0.10",
|
|
70
|
+
"@eslint/eslintrc": "^3.3.5",
|
|
71
|
+
"@eslint/js": "^10.0.1",
|
|
70
72
|
"chai": "^6.2.2",
|
|
71
|
-
"chai-files": "^1.
|
|
72
|
-
"chai-shallow-deep-equal": "^1.4.
|
|
73
|
-
"cheerio": "1.
|
|
73
|
+
"chai-files": "^1.4.0",
|
|
74
|
+
"chai-shallow-deep-equal": "^1.4.6",
|
|
75
|
+
"cheerio": "^1.2.0",
|
|
74
76
|
"dirty-chai": "^3.0.0",
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
+
"esbuild": "^0.27.4",
|
|
78
|
+
"esbuild-plugins-node-modules-polyfill": "^1.8.1",
|
|
79
|
+
"eslint": "^10.2.0",
|
|
80
|
+
"eslint-config-prettier": "^10.1.8",
|
|
81
|
+
"eslint-plugin-chai-expect": "^4.0.0",
|
|
77
82
|
"eslint-plugin-mocha": "^11.2.0",
|
|
83
|
+
"fresh-tape": "^5.9.1",
|
|
78
84
|
"mocha": "^11.7.5",
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"shelljs": "^0.8.2",
|
|
82
|
-
"sinon": "10.0.0",
|
|
85
|
+
"saucie": "^4.0.1",
|
|
86
|
+
"sinon": "^21.0.3",
|
|
83
87
|
"sinon-chai": "^4.0.1",
|
|
84
|
-
"socket.io-client": "^4.
|
|
85
|
-
|
|
88
|
+
"socket.io-client": "^4.8.3"
|
|
89
|
+
},
|
|
90
|
+
"overrides": {
|
|
91
|
+
"mocha": {
|
|
92
|
+
"diff": "^8.0.3",
|
|
93
|
+
"minimatch": "^9.0.7",
|
|
94
|
+
"serialize-javascript": "^7.0.5"
|
|
95
|
+
}
|
|
86
96
|
},
|
|
87
97
|
"bin": {
|
|
88
98
|
"testem": "./testem.js"
|