testaro 74.0.0 → 74.1.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 +5 -0
- package/actSpecs.js +2 -1
- package/call.js +0 -4
- package/package.json +1 -1
- package/procs/job.js +12 -2
- package/procs/launch.js +29 -7
- package/procs/shoot.js +7 -4
- package/run.js +8 -5
package/README.md
CHANGED
|
@@ -169,6 +169,11 @@ Here is a sample job, showing properties that you can set:
|
|
|
169
169
|
}
|
|
170
170
|
},
|
|
171
171
|
browserID: 'chromium', // or 'webkit' or 'firefox'
|
|
172
|
+
stealth: true, // Optional. Whether to enable puppeteer-extra-plugin-stealth
|
|
173
|
+
// evasions. Only applies to Chromium (the plugin is
|
|
174
|
+
// Chromium-specific). Defaults to true. Set false to opt
|
|
175
|
+
// out — useful for sites whose anti-bot heuristics react
|
|
176
|
+
// badly to stealth's patches.
|
|
172
177
|
creationTimeStamp: '241229T0537', // When job was created
|
|
173
178
|
executionTimeStamp: '250110T1200', // When job will be ready to be performed
|
|
174
179
|
target: {
|
package/actSpecs.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2021–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
-
©
|
|
3
|
+
© 2026 Jeff Witt.
|
|
4
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
4
5
|
|
|
5
6
|
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
7
|
https://opensource.org/license/mit/ for details.
|
package/call.js
CHANGED
|
@@ -22,13 +22,9 @@
|
|
|
22
22
|
|
|
23
23
|
// IMPORTS
|
|
24
24
|
|
|
25
|
-
// Module to keep secrets.
|
|
26
25
|
require('dotenv').config();
|
|
27
|
-
// Module to process files.
|
|
28
26
|
const fs = require('fs/promises');
|
|
29
|
-
// Function to process a testing request.
|
|
30
27
|
const {doJob} = require('./run');
|
|
31
|
-
// Function to watch for jobs.
|
|
32
28
|
const {dirWatch} = require('./dirWatch');
|
|
33
29
|
const {netWatch} = require('./netWatch');
|
|
34
30
|
|
package/package.json
CHANGED
package/procs/job.js
CHANGED
|
@@ -40,6 +40,8 @@ const tools = exports.tools = {
|
|
|
40
40
|
|
|
41
41
|
// FUNCTIONS
|
|
42
42
|
|
|
43
|
+
// Validates a browser type.
|
|
44
|
+
const isBrowserID = exports.isBrowserID = type => ['chromium', 'firefox', 'webkit'].includes(type);
|
|
43
45
|
// Returns whether a variable has a specified type.
|
|
44
46
|
const hasType = (variable, type) => {
|
|
45
47
|
if (type === 'string') {
|
|
@@ -105,8 +107,6 @@ const hasSubtype = (variable, subtype) => {
|
|
|
105
107
|
};
|
|
106
108
|
// Validates a device ID.
|
|
107
109
|
const isDeviceID = exports.isDeviceID = deviceID => deviceID === 'default' || !! devices[deviceID];
|
|
108
|
-
// Validates a browser type.
|
|
109
|
-
const isBrowserID = exports.isBrowserID = type => ['chromium', 'firefox', 'webkit'].includes(type);
|
|
110
110
|
// Validates a load state.
|
|
111
111
|
const isState = string => ['loaded', 'idle'].includes(string);
|
|
112
112
|
// Validates a URL.
|
|
@@ -177,6 +177,7 @@ exports.isValidJob = job => {
|
|
|
177
177
|
standard,
|
|
178
178
|
device,
|
|
179
179
|
browserID,
|
|
180
|
+
stealth,
|
|
180
181
|
creationTimeStamp,
|
|
181
182
|
executionTimeStamp,
|
|
182
183
|
target,
|
|
@@ -215,6 +216,15 @@ exports.isValidJob = job => {
|
|
|
215
216
|
error: 'Bad job browserID'
|
|
216
217
|
};
|
|
217
218
|
}
|
|
219
|
+
// `stealth` is optional. When omitted, Testaro defaults to enabling the
|
|
220
|
+
// puppeteer-extra-plugin-stealth evasions on Chromium (historical
|
|
221
|
+
// behavior). When present, it must be a boolean.
|
|
222
|
+
if (stealth !== undefined && typeof stealth !== 'boolean') {
|
|
223
|
+
return {
|
|
224
|
+
isValid: false,
|
|
225
|
+
error: 'Bad job stealth (must be boolean if present)'
|
|
226
|
+
};
|
|
227
|
+
}
|
|
218
228
|
if (
|
|
219
229
|
! (creationTimeStamp && typeof creationTimeStamp === 'string' && dateOf(creationTimeStamp))
|
|
220
230
|
) {
|
package/procs/launch.js
CHANGED
|
@@ -19,15 +19,22 @@
|
|
|
19
19
|
// Module to handle errors.
|
|
20
20
|
const {addError} = require('./error');
|
|
21
21
|
const headedBrowser = process.env.HEADED_BROWSER === 'true';
|
|
22
|
-
|
|
22
|
+
// Two flavors of Playwright:
|
|
23
|
+
// - `playwrightCore`: the upstream Playwright SDK with no plugins attached.
|
|
24
|
+
// - `playwrightExtra`: the playwright-extra wrapper. `run.js` registers
|
|
25
|
+
// puppeteer-extra-plugin-stealth on its `chromium` only (the plugin is
|
|
26
|
+
// Chromium-specific by design — see comment in run.js).
|
|
27
|
+
// At launch time we pick the flavor per call: Chromium with stealth enabled
|
|
28
|
+
// goes through playwright-extra, every other case (Chromium with stealth
|
|
29
|
+
// disabled, WebKit, Firefox) goes through plain Playwright.
|
|
30
|
+
const playwrightCore = require('playwright');
|
|
31
|
+
const playwrightExtra = require('playwright-extra');
|
|
23
32
|
const {isBrowserID, isDeviceID, isURL, isValidJob} = require('./job');
|
|
24
33
|
|
|
25
34
|
// CONSTANTS
|
|
26
35
|
|
|
27
36
|
// Whether to log page-context log messages.
|
|
28
37
|
const debug = process.env.DEBUG === 'true';
|
|
29
|
-
// Playwright browser types.
|
|
30
|
-
const playwrightBrowsers = {chromium, webkit, firefox};
|
|
31
38
|
// Strings in log messages indicating errors.
|
|
32
39
|
const errorWords = [
|
|
33
40
|
'but not used',
|
|
@@ -238,12 +245,27 @@ const launchOnce = async opts => {
|
|
|
238
245
|
if (isBrowserID(browserID) && isDeviceID(deviceID) && isURL(url)) {
|
|
239
246
|
// Replace the report target URL with the specified URL.
|
|
240
247
|
report.target.url = url;
|
|
241
|
-
|
|
248
|
+
// Resolve whether to run with stealth evasions. Defaults to true (the
|
|
249
|
+
// historical behavior). `report.stealth === false` opts out — useful
|
|
250
|
+
// for sites whose anti-bot heuristics react badly to stealth's patches,
|
|
251
|
+
// or when reproducing a real user agent's exact JS environment matters.
|
|
252
|
+
// Stealth only ever applies to Chromium; WebKit and Firefox always use
|
|
253
|
+
// plain Playwright regardless of the `stealth` field.
|
|
254
|
+
const useStealth = browserID === 'chromium' && report.stealth !== false;
|
|
255
|
+
const playwright = useStealth ? playwrightExtra : playwrightCore;
|
|
256
|
+
// Create a browser of the specified or default type.
|
|
257
|
+
const browserType = playwright[browserID];
|
|
258
|
+
// Define the browser-option args, depending on the browser type and head-emulation level.
|
|
242
259
|
const browserOptionArgs = [];
|
|
243
260
|
if (browserID === 'chromium') {
|
|
244
|
-
browserOptionArgs.push(
|
|
245
|
-
|
|
246
|
-
|
|
261
|
+
browserOptionArgs.push('--disable-dev-shm-usage');
|
|
262
|
+
// `--disable-blink-features=AutomationControlled` is a stealth-only
|
|
263
|
+
// arg: it hides the automation flag that stealth's other evasions
|
|
264
|
+
// assume is hidden. When stealth is opted out, leave the flag off
|
|
265
|
+
// so the browser presents an honest automation profile.
|
|
266
|
+
if (useStealth) {
|
|
267
|
+
browserOptionArgs.push('--disable-blink-features=AutomationControlled');
|
|
268
|
+
}
|
|
247
269
|
if (headEmulation === 'high') {
|
|
248
270
|
browserOptionArgs.push(
|
|
249
271
|
'--disable-gpu',
|
package/procs/shoot.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
+
© 2026 Jeff Witt.
|
|
2
3
|
© 2025–2026 Jonathan Robert Pool.
|
|
3
4
|
Licensed under the MIT License. See LICENSE file for details.
|
|
4
5
|
*/
|
|
@@ -29,10 +30,12 @@ const {PNG} = require('pngjs');
|
|
|
29
30
|
|
|
30
31
|
// FUNCTIONS
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
/*
|
|
34
|
+
Coerces a label into a filesystem-safe string. Runs of any character outside
|
|
35
|
+
[A-Za-z0-9._-] collapse to one underscore; leading and trailing dots and
|
|
36
|
+
underscores are stripped (no hidden files, no traversal); capped at 100
|
|
37
|
+
characters; falls back to 'unnamed' if nothing usable remains.
|
|
38
|
+
*/
|
|
36
39
|
const sanitizeLabel = (label) => {
|
|
37
40
|
const raw = String(label);
|
|
38
41
|
const cleaned = raw
|
package/run.js
CHANGED
|
@@ -21,13 +21,16 @@ require('dotenv').config({quiet: true});
|
|
|
21
21
|
const {isValidJob} = require('./procs/job');
|
|
22
22
|
const {getCatalog} = require('./procs/catalog');
|
|
23
23
|
const {nowString} = require('./procs/dateTime');
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
24
|
+
// Module to create browsers.
|
|
25
|
+
const {chromium} = require('playwright-extra');
|
|
26
|
+
// Module to evade automation detection.
|
|
27
|
+
// Stealth is Chromium-specific: its evasions inject Chromium-only launch
|
|
28
|
+
// flags (e.g. `--disable-blink-features=AutomationControlled`) and patch
|
|
29
|
+
// Blink-only DOM globals. WebKit and Firefox reject the unknown args at
|
|
30
|
+
// startup, so registering stealth on them breaks every launch. Job-level
|
|
31
|
+
// opt-out for Chromium happens in procs/launch.js via the `stealth` field.
|
|
27
32
|
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
|
|
28
33
|
chromium.use(StealthPlugin());
|
|
29
|
-
webkit.use(StealthPlugin());
|
|
30
|
-
firefox.use(StealthPlugin());
|
|
31
34
|
|
|
32
35
|
// FUNCTIONS
|
|
33
36
|
|