testaro 76.1.2 → 76.2.1
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 +2 -0
- package/package.json +1 -1
- package/procs/catalog.js +11 -2
- package/procs/launch.js +24 -4
package/README.md
CHANGED
|
@@ -201,6 +201,8 @@ Here is a sample job, showing properties that you can set:
|
|
|
201
201
|
|
|
202
202
|
The `device` property lets you choose among [about 125 devices recognized by Playwright](https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json).
|
|
203
203
|
|
|
204
|
+
The `browserID` property dictates the first browser type that Testaro uses for its requests. When requests with that browser type are repeatedly rejected, Testaro switches to a different browser type and also replaces the `browserID` property of the job with that new browser type. Targets and their edge-management platforms often block requests from one browser type but not another, so switching browser types can make a job succeed instead of failing or make it finish quickly instead of slowly.
|
|
205
|
+
|
|
204
206
|
The act types and their options are documented in the `etc` property of the [actSpecs.js](actSpecs.js) object and in the [actSpecs-doc.md](actSpecs-doc.md) file.
|
|
205
207
|
|
|
206
208
|
## Running jobs
|
package/package.json
CHANGED
package/procs/catalog.js
CHANGED
|
@@ -65,8 +65,17 @@ exports.getCatalog = async report => {
|
|
|
65
65
|
// Initialize the index of the current heading.
|
|
66
66
|
let headingIndex = '';
|
|
67
67
|
// For each element in the page:
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
// Iterate by numeric index rather than `for...in`. `for...in` over this
|
|
69
|
+
// array also enumerates any enumerable members added to Array.prototype
|
|
70
|
+
// by the TARGET page's own scripts (e.g. legacy MooTools/Prototype-style
|
|
71
|
+
// extensions); `element` then becomes that injected value and the
|
|
72
|
+
// element.closest(...) call below throws "closest is not a function",
|
|
73
|
+
// aborting the entire catalog and the job. The indexed loop sees only
|
|
74
|
+
// real elements. `index` is kept as a string so the catalog keys
|
|
75
|
+
// (cat[index], texts[...].push(index)) are unchanged.
|
|
76
|
+
for (let i = 0; i < elements.length; i++) {
|
|
77
|
+
const index = String(i);
|
|
78
|
+
const element = elements[i];
|
|
70
79
|
// Get its ID and tag name.
|
|
71
80
|
const {id, tagName} = element;
|
|
72
81
|
// Get its start tag.
|
package/procs/launch.js
CHANGED
|
@@ -172,11 +172,26 @@ const goTo = exports.goTo = async (report, page, url, timeout, waitUntil) => {
|
|
|
172
172
|
}
|
|
173
173
|
// Otherwise, if the response status was prohibition:
|
|
174
174
|
else if (httpStatus === 403) {
|
|
175
|
-
//
|
|
175
|
+
// Log this.
|
|
176
176
|
console.log(`ERROR: Visit to ${url} prohibited (status 403)`);
|
|
177
|
+
// Collect diagnostic data from the response.
|
|
178
|
+
let rejectionData = {status: 403};
|
|
179
|
+
try {
|
|
180
|
+
const headers = await response.allHeaders();
|
|
181
|
+
rejectionData.server = headers['server'] || '';
|
|
182
|
+
rejectionData.cfRay = headers['cf-ray'] || '';
|
|
183
|
+
rejectionData.via = headers['via'] || '';
|
|
184
|
+
rejectionData.xAkamai = headers['x-akamai-transformed'] || '';
|
|
185
|
+
rejectionData.xSucuri = headers['x-sucuri-id'] || '';
|
|
186
|
+
rejectionData.xWaf = headers['x-waf-event-info'] || '';
|
|
187
|
+
rejectionData.headers = headers;
|
|
188
|
+
}
|
|
189
|
+
catch {}
|
|
190
|
+
// Return the prohibition and the data.
|
|
177
191
|
return {
|
|
178
192
|
success: false,
|
|
179
|
-
error: 'status403'
|
|
193
|
+
error: 'status403',
|
|
194
|
+
rejectionData
|
|
180
195
|
};
|
|
181
196
|
}
|
|
182
197
|
// Otherwise, if the response status was rejection of excessive requests:
|
|
@@ -534,8 +549,12 @@ const launchOnce = async opts => {
|
|
|
534
549
|
}
|
|
535
550
|
// Otherwise, i.e. if the navigation failed:
|
|
536
551
|
else {
|
|
552
|
+
const {rejectionData} = navResult;
|
|
553
|
+
const addendum = rejectionData
|
|
554
|
+
? ` (rejection data: ${JSON.stringify(rejectionData, null, 2)})`
|
|
555
|
+
: '';
|
|
537
556
|
// Throw an error.
|
|
538
|
-
throw new Error(`Navigation failed
|
|
557
|
+
throw new Error(`Navigation failed: ${navResult.error}${addendum}`);
|
|
539
558
|
}
|
|
540
559
|
}
|
|
541
560
|
// If the browser and page creation and navigation threw an error:
|
|
@@ -648,7 +667,8 @@ exports.launch = async (opts = {}) => {
|
|
|
648
667
|
if (tempBrowserID && unusedBrowserIDs.length && ! retriesLeft) {
|
|
649
668
|
// Change the browser type.
|
|
650
669
|
tempBrowserID = unusedBrowserIDs.shift();
|
|
651
|
-
console.log(`NOTICE: Changing browser type to ${tempBrowserID}`);
|
|
670
|
+
console.log(`NOTICE: Changing job browser type to ${tempBrowserID}`);
|
|
671
|
+
report.browserID = tempBrowserID;
|
|
652
672
|
// Reset the retries.
|
|
653
673
|
retriesLeft = retries;
|
|
654
674
|
}
|