@itmetsam/samurai-framework 0.10.0 → 0.12.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 +3 -4
- package/dist/assert/assertion-error.d.ts +1 -1
- package/dist/assert/expect.d.ts +5 -50
- package/dist/assert/expect.js +5 -182
- package/dist/assert/locator-assertions.d.ts +22 -0
- package/dist/assert/locator-assertions.js +61 -0
- package/dist/assert/pending-assertions.d.ts +7 -0
- package/dist/assert/pending-assertions.js +40 -0
- package/dist/assert/text-match.d.ts +4 -0
- package/dist/assert/text-match.js +11 -0
- package/dist/assert/value-assertions.d.ts +23 -0
- package/dist/assert/value-assertions.js +82 -0
- package/dist/browser/browser-context.d.ts +0 -1
- package/dist/browser/browser-context.js +13 -5
- package/dist/browser/browser-finder.js +5 -9
- package/dist/browser/browser.d.ts +3 -31
- package/dist/browser/browser.js +36 -219
- package/dist/browser/chrome-launch.d.ts +2 -1
- package/dist/browser/dialog-handling.d.ts +32 -0
- package/dist/browser/dialog-handling.js +85 -0
- package/dist/browser/document-watcher.d.ts +44 -0
- package/dist/browser/document-watcher.js +160 -0
- package/dist/browser/download-folders.d.ts +0 -1
- package/dist/browser/download-folders.js +7 -15
- package/dist/browser/download.js +5 -10
- package/dist/browser/downloads-dir.js +2 -2
- package/dist/browser/emit.d.ts +7 -0
- package/dist/browser/emit.js +16 -0
- package/dist/browser/emulation.d.ts +1 -1
- package/dist/browser/emulation.js +54 -18
- package/dist/browser/file-chooser.js +4 -11
- package/dist/browser/history.d.ts +6 -0
- package/dist/browser/history.js +89 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.js +2 -0
- package/dist/browser/init-script.d.ts +2 -0
- package/dist/browser/init-script.js +16 -0
- package/dist/browser/launch-firefox.d.ts +20 -0
- package/dist/browser/launch-firefox.js +66 -0
- package/dist/browser/launch-flags.d.ts +18 -0
- package/dist/browser/launch-flags.js +100 -0
- package/dist/browser/lazy.d.ts +21 -0
- package/dist/browser/lazy.js +44 -0
- package/dist/browser/page-events.d.ts +44 -0
- package/dist/browser/page-events.js +58 -0
- package/dist/browser/page-logs.js +2 -9
- package/dist/browser/page-navigation.d.ts +58 -0
- package/dist/browser/page-navigation.js +108 -0
- package/dist/browser/page-network.d.ts +69 -0
- package/dist/browser/page-network.js +163 -0
- package/dist/browser/page-settings.d.ts +35 -0
- package/dist/browser/page-settings.js +51 -0
- package/dist/browser/page-transfers.d.ts +36 -0
- package/dist/browser/page-transfers.js +50 -0
- package/dist/browser/page.d.ts +39 -154
- package/dist/browser/page.js +134 -758
- package/dist/browser/pdf.d.ts +1 -1
- package/dist/browser/session.d.ts +16 -0
- package/dist/browser/session.js +32 -0
- package/dist/browser/viewport.d.ts +19 -0
- package/dist/browser/viewport.js +72 -0
- package/dist/browser/warm-up.d.ts +1 -1
- package/dist/browser/warm-up.js +2 -1
- package/dist/browsers/index.d.ts +1 -1
- package/dist/browsers/index.js +1 -1
- package/dist/browsers/pins.d.ts +0 -2
- package/dist/browsers/pins.js +0 -2
- package/dist/browsers/store.d.ts +0 -2
- package/dist/browsers/store.js +1 -2
- package/dist/cli/args.d.ts +13 -6
- package/dist/cli/args.js +13 -10
- package/dist/cli/browsers.d.ts +1 -2
- package/dist/cli/browsers.js +2 -2
- package/dist/cli/console-reporter.js +3 -2
- package/dist/cli/flow-reporter.js +2 -1
- package/dist/cli/flow.d.ts +1 -2
- package/dist/cli/flow.js +25 -22
- package/dist/cli/init.js +2 -7
- package/dist/cli/io.d.ts +10 -0
- package/dist/cli/io.js +1 -0
- package/dist/cli/main.d.ts +3 -10
- package/dist/cli/main.js +10 -143
- package/dist/cli/paint.d.ts +2 -0
- package/dist/cli/paint.js +4 -0
- package/dist/cli/record.d.ts +4 -0
- package/dist/cli/record.js +93 -0
- package/dist/cli/usage.d.ts +1 -0
- package/dist/cli/usage.js +58 -0
- package/dist/cli/version.d.ts +2 -0
- package/dist/cli/version.js +7 -0
- package/dist/config/browsers.d.ts +11 -0
- package/dist/config/browsers.js +32 -0
- package/dist/config/config.js +4 -1
- package/dist/config/mask.d.ts +1 -1
- package/dist/config/mask.js +7 -2
- package/dist/config/run-settings.d.ts +1 -2
- package/dist/config/run-settings.js +1 -6
- package/dist/config/timeouts.d.ts +2 -0
- package/dist/config/timeouts.js +13 -0
- package/dist/config/workers.d.ts +14 -0
- package/dist/config/workers.js +29 -0
- package/dist/flows/run/branch-context.d.ts +14 -0
- package/dist/flows/run/branch-context.js +35 -0
- package/dist/flows/run/handlers/condition.d.ts +1 -1
- package/dist/flows/run/handlers/end.d.ts +1 -1
- package/dist/flows/run/handlers/group.d.ts +1 -1
- package/dist/flows/run/handlers/index.d.ts +2 -2
- package/dist/flows/run/handlers/parallel.d.ts +1 -1
- package/dist/flows/run/handlers/start.d.ts +1 -1
- package/dist/flows/run/handlers/support.d.ts +3 -27
- package/dist/flows/run/handlers/test.d.ts +1 -1
- package/dist/flows/run/handlers/types.d.ts +27 -0
- package/dist/flows/run/handlers/types.js +1 -0
- package/dist/flows/run/index.d.ts +1 -1
- package/dist/flows/run/prepare-flow.d.ts +14 -0
- package/dist/flows/run/prepare-flow.js +44 -0
- package/dist/flows/run/project.d.ts +33 -2
- package/dist/flows/run/project.js +139 -57
- package/dist/flows/run/run.d.ts +3 -4
- package/dist/flows/run/run.js +23 -193
- package/dist/flows/run/walker.d.ts +56 -0
- package/dist/flows/run/walker.js +225 -0
- package/dist/flows/steps/catalog.d.ts +1 -1
- package/dist/flows/steps/handler.d.ts +1 -1
- package/dist/flows/steps/set.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/locator/actionability.d.ts +33 -0
- package/dist/locator/actionability.js +104 -0
- package/dist/locator/chain-resolver.d.ts +20 -0
- package/dist/locator/chain-resolver.js +102 -0
- package/dist/locator/document-swap.d.ts +1 -0
- package/dist/locator/document-swap.js +11 -0
- package/dist/locator/element-state.d.ts +3 -1
- package/dist/locator/element-state.js +11 -3
- package/dist/locator/file-actions.d.ts +35 -0
- package/dist/locator/file-actions.js +55 -0
- package/dist/{script/helpers.js → locator/helper-realm.js} +2 -2
- package/dist/locator/input-actions.d.ts +18 -0
- package/dist/locator/input-actions.js +80 -0
- package/dist/locator/label-locator.d.ts +1 -1
- package/dist/locator/label-locator.js +5 -12
- package/dist/locator/locator.d.ts +14 -37
- package/dist/locator/locator.js +68 -424
- package/dist/locator/page-scripts.d.ts +16 -0
- package/dist/locator/page-scripts.js +54 -0
- package/dist/locator/page-search.d.ts +10 -0
- package/dist/locator/page-search.js +19 -0
- package/dist/locator/selector-errors.d.ts +0 -4
- package/dist/locator/selector-errors.js +0 -7
- package/dist/locator/selector.d.ts +14 -13
- package/dist/locator/selector.js +10 -16
- package/dist/locator/text-locator.d.ts +1 -1
- package/dist/locator/text-locator.js +5 -9
- package/dist/logger/index.d.ts +6 -0
- package/dist/logger/index.js +14 -7
- package/dist/network/bidi-wire.d.ts +10 -0
- package/dist/network/bidi-wire.js +38 -0
- package/dist/network/intercept.d.ts +30 -0
- package/dist/network/intercept.js +130 -0
- package/dist/network/network-tracker.d.ts +10 -47
- package/dist/network/network-tracker.js +34 -68
- package/dist/network/network-types.d.ts +33 -0
- package/dist/network/network-types.js +1 -0
- package/dist/network/network-wait.d.ts +7 -2
- package/dist/network/network-wait.js +14 -4
- package/dist/network/response.d.ts +1 -1
- package/dist/network/response.js +1 -1
- package/dist/network/route.d.ts +92 -0
- package/dist/network/route.js +142 -0
- package/dist/network/router.d.ts +6 -91
- package/dist/network/router.js +25 -258
- package/dist/recorder/expectation.d.ts +5 -0
- package/dist/recorder/expectation.js +20 -0
- package/dist/recorder/files-recorder.d.ts +30 -0
- package/dist/recorder/files-recorder.js +88 -0
- package/dist/recorder/normalise.d.ts +17 -6
- package/dist/recorder/normalise.js +96 -91
- package/dist/recorder/options.d.ts +56 -0
- package/dist/recorder/options.js +1 -0
- package/dist/recorder/page-messages.d.ts +35 -0
- package/dist/recorder/page-messages.js +26 -0
- package/dist/recorder/ranking.js +1 -0
- package/dist/recorder/realms.d.ts +6 -0
- package/dist/recorder/realms.js +13 -0
- package/dist/recorder/recorder.d.ts +10 -74
- package/dist/recorder/recorder.js +39 -199
- package/dist/recorder/session-browser.d.ts +22 -0
- package/dist/recorder/session-browser.js +21 -0
- package/dist/recorder/session-secrets.d.ts +8 -0
- package/dist/recorder/session-secrets.js +45 -0
- package/dist/recorder/session.d.ts +5 -14
- package/dist/recorder/session.js +22 -120
- package/dist/recorder/spec-source.d.ts +39 -0
- package/dist/recorder/spec-source.js +84 -0
- package/dist/recorder/toolbar/action-guard.d.ts +21 -0
- package/dist/recorder/toolbar/action-guard.js +43 -0
- package/dist/recorder/toolbar/actions/assert.d.ts +4 -0
- package/dist/recorder/toolbar/actions/assert.js +52 -0
- package/dist/recorder/toolbar/actions/insert.d.ts +6 -0
- package/dist/recorder/toolbar/actions/insert.js +93 -0
- package/dist/recorder/toolbar/actions/pick.d.ts +8 -0
- package/dist/recorder/toolbar/actions/pick.js +26 -0
- package/dist/recorder/toolbar/actions/reply.d.ts +7 -0
- package/dist/recorder/toolbar/actions/reply.js +10 -0
- package/dist/recorder/toolbar/controller-fixture.d.ts +47 -0
- package/dist/recorder/toolbar/controller-fixture.js +129 -0
- package/dist/recorder/toolbar/controller.d.ts +12 -78
- package/dist/recorder/toolbar/controller.js +35 -247
- package/dist/recorder/toolbar/inspect.d.ts +1 -3
- package/dist/recorder/toolbar/inspect.js +2 -2
- package/dist/recorder/toolbar/page-scope.d.ts +19 -0
- package/dist/recorder/toolbar/page-scope.js +43 -0
- package/dist/recorder/toolbar/protocol.d.ts +2 -1
- package/dist/recorder/toolbar/source/attach.d.ts +2 -0
- package/dist/recorder/toolbar/source/attach.js +41 -0
- package/dist/recorder/toolbar/source/dom.d.ts +2 -0
- package/dist/recorder/toolbar/source/dom.js +47 -0
- package/dist/recorder/toolbar/source/drag.d.ts +2 -0
- package/dist/recorder/toolbar/source/drag.js +32 -0
- package/dist/recorder/toolbar/source/events-page.d.ts +2 -0
- package/dist/recorder/toolbar/source/events-page.js +67 -0
- package/dist/recorder/toolbar/source/events-toolbar.d.ts +2 -0
- package/dist/recorder/toolbar/source/events-toolbar.js +35 -0
- package/dist/recorder/toolbar/source/fields.d.ts +2 -0
- package/dist/recorder/toolbar/source/fields.js +44 -0
- package/dist/recorder/toolbar/source/handlers.d.ts +2 -0
- package/dist/recorder/toolbar/source/handlers.js +134 -0
- package/dist/recorder/toolbar/source/names.d.ts +2 -0
- package/dist/recorder/toolbar/source/names.js +12 -0
- package/dist/recorder/toolbar/source/picking.d.ts +2 -0
- package/dist/recorder/toolbar/source/picking.js +72 -0
- package/dist/recorder/toolbar/source/placement.d.ts +2 -0
- package/dist/recorder/toolbar/source/placement.js +45 -0
- package/dist/recorder/toolbar/source/recorder-side.d.ts +2 -0
- package/dist/recorder/toolbar/source/recorder-side.js +54 -0
- package/dist/recorder/toolbar/source/setup.d.ts +2 -0
- package/dist/recorder/toolbar/source/setup.js +50 -0
- package/dist/recorder/toolbar/source/views-panels.d.ts +2 -0
- package/dist/recorder/toolbar/source/views-panels.js +150 -0
- package/dist/recorder/toolbar/source/views-rail.d.ts +2 -0
- package/dist/recorder/toolbar/source/views-rail.js +40 -0
- package/dist/recorder/toolbar/source/views-render.d.ts +2 -0
- package/dist/recorder/toolbar/source/views-render.js +48 -0
- package/dist/recorder/toolbar/source.js +30 -856
- package/dist/recorder/toolbar/types.d.ts +70 -0
- package/dist/recorder/toolbar/types.js +1 -0
- package/dist/recorder/toolbar-bridge.d.ts +43 -0
- package/dist/recorder/toolbar-bridge.js +106 -0
- package/dist/runner/browsers.d.ts +0 -12
- package/dist/runner/browsers.js +1 -33
- package/dist/runner/options.d.ts +31 -0
- package/dist/runner/options.js +1 -0
- package/dist/runner/pooled-run.d.ts +43 -0
- package/dist/runner/pooled-run.js +75 -0
- package/dist/runner/ports.d.ts +2 -0
- package/dist/runner/ports.js +2 -0
- package/dist/runner/registry.d.ts +1 -1
- package/dist/runner/registry.js +1 -1
- package/dist/runner/reporter.d.ts +31 -10
- package/dist/runner/reporter.js +39 -6
- package/dist/runner/run-test.d.ts +16 -0
- package/dist/runner/run-test.js +178 -0
- package/dist/runner/run.d.ts +5 -3
- package/dist/runner/run.js +28 -29
- package/dist/runner/select.d.ts +24 -0
- package/dist/runner/select.js +77 -0
- package/dist/runner/test-dir.d.ts +13 -0
- package/dist/runner/test-dir.js +27 -0
- package/dist/runner/test-runner.d.ts +25 -56
- package/dist/runner/test-runner.js +81 -270
- package/dist/runner/worker-pool.d.ts +67 -0
- package/dist/runner/worker-pool.js +275 -0
- package/dist/runner/worker-process.d.ts +6 -0
- package/dist/runner/worker-process.js +54 -0
- package/dist/runner/worker-protocol.d.ts +67 -0
- package/dist/runner/worker-protocol.js +1 -0
- package/dist/runner/worker-session.d.ts +7 -0
- package/dist/runner/worker-session.js +60 -0
- package/dist/runner/worker.d.ts +26 -0
- package/dist/runner/worker.js +121 -0
- package/dist/runner/workers-option.d.ts +15 -0
- package/dist/runner/workers-option.js +22 -0
- package/dist/script/call-function.d.ts +1 -9
- package/dist/script/call-function.js +2 -19
- package/dist/script/element-handle.d.ts +1 -2
- package/dist/script/element-handle.js +1 -2
- package/dist/script/serialize.d.ts +3 -12
- package/dist/script/serialize.js +53 -62
- package/dist/steps/parse/call.d.ts +3 -0
- package/dist/steps/parse/call.js +81 -0
- package/dist/steps/parse/expectation.d.ts +5 -0
- package/dist/steps/parse/expectation.js +71 -0
- package/dist/steps/parse/file-entry.d.ts +4 -0
- package/dist/steps/parse/file-entry.js +74 -0
- package/dist/steps/parse/literals.d.ts +4 -0
- package/dist/steps/parse/literals.js +28 -0
- package/dist/steps/parse/step.d.ts +4 -0
- package/dist/steps/parse/step.js +81 -0
- package/dist/steps/parse.js +2 -323
- package/dist/transport/bidi-connection.d.ts +4 -15
- package/dist/transport/bidi-connection.js +9 -63
- package/dist/transport/log-redaction.d.ts +13 -0
- package/dist/transport/log-redaction.js +51 -0
- package/dist/transport/subscriptions.js +18 -13
- package/dist/transport/unsupported.d.ts +7 -0
- package/dist/transport/unsupported.js +13 -0
- package/dist/types/bidi-modules/browser.d.ts +1 -12
- package/dist/types/bidi-modules/browsing-context.d.ts +8 -18
- package/dist/types/bidi-modules/emulation.d.ts +29 -21
- package/dist/types/bidi-modules/input.d.ts +1 -9
- package/dist/types/bidi-modules/network.d.ts +29 -24
- package/dist/types/bidi-modules/script.d.ts +0 -9
- package/dist/types/bidi-modules/session.d.ts +0 -8
- package/dist/types/bidi-modules/storage.d.ts +0 -5
- package/dist/types/bidi.d.ts +7 -37
- package/dist/types/config.d.ts +12 -0
- package/dist/types/test.d.ts +8 -3
- package/dist/wait/wait-until.d.ts +1 -5
- package/dist/wait/wait-until.js +7 -16
- package/package.json +3 -2
- package/dist/config/default.d.ts +0 -2
- package/dist/config/default.js +0 -3
- package/dist/types/bidi-modules/web-extensions.d.ts +0 -9
- package/dist/types/bidi-protocols/command.d.ts +0 -7
- package/dist/types/bidi-protocols/event.d.ts +0 -17
- /package/dist/{script/helpers.d.ts → locator/helper-realm.d.ts} +0 -0
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import EventEmitter from "node:events";
|
|
2
2
|
import logger from "../logger/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import { headersFromBidi, toRequest } from "./bidi-wire.js";
|
|
4
|
+
import { NetworkIdleTimeoutError } from "./network-wait.js";
|
|
5
|
+
import {} from "./network-types.js";
|
|
6
|
+
export { NetworkIdleTimeoutError } from "./network-wait.js";
|
|
4
7
|
/** The error text of a request that the page left before it finished, when the browser says none */
|
|
5
8
|
const ABORTED_BY_NAVIGATION = "aborted by navigation";
|
|
6
9
|
/** How many URLs a timeout message names */
|
|
7
10
|
const URLS_IN_MESSAGE = 5;
|
|
8
|
-
/** waitForIdle ran out of time with requests still in flight; `last` holds (up to five of) their URLs */
|
|
9
|
-
export class NetworkIdleTimeoutError extends WaitTimeoutError {
|
|
10
|
-
constructor(timeout, inflight, urls) {
|
|
11
|
-
super(timeout, urls);
|
|
12
|
-
this.name = "NetworkIdleTimeoutError";
|
|
13
|
-
this.message = `waitForNetworkIdle(): still ${inflight} request(s) in flight after ${timeout}ms: ${urls.join(", ")}`;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
11
|
/**
|
|
17
12
|
* Follows the network activity of one page (its frames included): which requests are in flight,
|
|
18
13
|
* and `request` / `response` / `requestfailed` events. In-flight is keyed by `request id:redirect count`,
|
|
@@ -25,28 +20,26 @@ export class NetworkTracker {
|
|
|
25
20
|
this.ignore = ignore;
|
|
26
21
|
this.connector = connector;
|
|
27
22
|
this.events = new EventEmitter();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Every hop that is in flight or may still be the source of a redirect, by hop key. A redirect response ends a
|
|
25
|
+
* hop's flight (`live` false) but keeps it, for the next hop's `redirectedFrom`.
|
|
26
|
+
*/
|
|
32
27
|
this.hops = new Map();
|
|
28
|
+
/** Rejects a pending `waitForIdle`; each wait adds its own */
|
|
33
29
|
this.waiters = new Set();
|
|
34
30
|
this.disposed = false;
|
|
35
31
|
this.onBeforeRequestSent = (params) => {
|
|
36
32
|
if (!this.owns(params.context))
|
|
37
33
|
return;
|
|
38
34
|
const key = NetworkTracker.key(params.request, params.redirectCount);
|
|
39
|
-
const redirectCount =
|
|
35
|
+
const { redirectCount } = params;
|
|
40
36
|
const previousKey = `${params.request.request}:${redirectCount - 1}`;
|
|
41
|
-
const redirectedFrom = redirectCount > 0 ? (this.hops.get(previousKey) ?? null) : null;
|
|
37
|
+
const redirectedFrom = redirectCount > 0 ? (this.hops.get(previousKey)?.request ?? null) : null;
|
|
42
38
|
this.hops.delete(previousKey);
|
|
43
39
|
const request = toRequest(params.request, params.navigation, params.isBlocked, redirectedFrom);
|
|
44
40
|
if (this.ignore(request))
|
|
45
41
|
return;
|
|
46
|
-
this.hops.set(key, request);
|
|
47
|
-
this.active.set(key, request.url);
|
|
48
|
-
if (params.context)
|
|
49
|
-
this.contexts.set(key, params.context);
|
|
42
|
+
this.hops.set(key, { request, context: params.context, live: true });
|
|
50
43
|
this.emit("request", request);
|
|
51
44
|
this.events.emit("change");
|
|
52
45
|
};
|
|
@@ -54,19 +47,21 @@ export class NetworkTracker {
|
|
|
54
47
|
if (!this.owns(params.context))
|
|
55
48
|
return;
|
|
56
49
|
const key = NetworkTracker.key(params.request, params.redirectCount);
|
|
57
|
-
const
|
|
58
|
-
if (!
|
|
50
|
+
const hop = this.hops.get(key);
|
|
51
|
+
if (!hop?.live)
|
|
59
52
|
return;
|
|
60
|
-
|
|
53
|
+
const { request } = hop;
|
|
61
54
|
const { response } = params;
|
|
62
55
|
// A redirect response keeps its request around: the next hop links back to it
|
|
63
56
|
if (response.status < 300 || response.status >= 400)
|
|
64
57
|
this.hops.delete(key);
|
|
58
|
+
else
|
|
59
|
+
hop.live = false;
|
|
65
60
|
this.emit("response", {
|
|
66
61
|
url: response.url,
|
|
67
62
|
status: response.status,
|
|
68
63
|
statusText: response.statusText,
|
|
69
|
-
headers:
|
|
64
|
+
headers: headersFromBidi(response.headers),
|
|
70
65
|
fromCache: response.fromCache,
|
|
71
66
|
request,
|
|
72
67
|
});
|
|
@@ -76,12 +71,11 @@ export class NetworkTracker {
|
|
|
76
71
|
if (!this.owns(params.context))
|
|
77
72
|
return;
|
|
78
73
|
const key = NetworkTracker.key(params.request, params.redirectCount);
|
|
79
|
-
const
|
|
80
|
-
if (!
|
|
74
|
+
const hop = this.hops.get(key);
|
|
75
|
+
if (!hop?.live)
|
|
81
76
|
return;
|
|
82
|
-
this.contexts.delete(key);
|
|
83
77
|
this.hops.delete(key);
|
|
84
|
-
this.emit("requestfailed", Object.assign(request, { errorText: params.errorText }));
|
|
78
|
+
this.emit("requestfailed", Object.assign(hop.request, { errorText: params.errorText }));
|
|
85
79
|
this.events.emit("change");
|
|
86
80
|
};
|
|
87
81
|
/**
|
|
@@ -92,14 +86,11 @@ export class NetworkTracker {
|
|
|
92
86
|
if (!this.owns(params.context))
|
|
93
87
|
return;
|
|
94
88
|
let changed = false;
|
|
95
|
-
for (const [key,
|
|
96
|
-
|
|
97
|
-
if (!request || request.navigation === params.navigation)
|
|
89
|
+
for (const [key, { request, context, live }] of [...this.hops]) {
|
|
90
|
+
if (!live || request.navigation === params.navigation)
|
|
98
91
|
continue;
|
|
99
|
-
if (!this.tree.isWithin(
|
|
92
|
+
if (!this.tree.isWithin(context, params.context))
|
|
100
93
|
continue;
|
|
101
|
-
this.contexts.delete(key);
|
|
102
|
-
this.active.delete(key);
|
|
103
94
|
this.hops.delete(key);
|
|
104
95
|
this.emit("requestfailed", Object.assign(request, { errorText: ABORTED_BY_NAVIGATION }));
|
|
105
96
|
changed = true;
|
|
@@ -131,11 +122,14 @@ export class NetworkTracker {
|
|
|
131
122
|
}
|
|
132
123
|
/** Requests currently in flight */
|
|
133
124
|
get inflight() {
|
|
134
|
-
return this.
|
|
125
|
+
return this.liveHops().length;
|
|
135
126
|
}
|
|
136
127
|
/** URLs of the requests currently in flight, oldest first */
|
|
137
128
|
get inflightUrls() {
|
|
138
|
-
return
|
|
129
|
+
return this.liveHops().map(({ request }) => request.url);
|
|
130
|
+
}
|
|
131
|
+
liveHops() {
|
|
132
|
+
return [...this.hops.values()].filter(({ live }) => live);
|
|
139
133
|
}
|
|
140
134
|
/** Waits that have not finished yet */
|
|
141
135
|
get waiting() {
|
|
@@ -154,9 +148,7 @@ export class NetworkTracker {
|
|
|
154
148
|
waitForIdle({ idleTime, timeout, }) {
|
|
155
149
|
return new Promise((resolve, reject) => {
|
|
156
150
|
let idleTimer;
|
|
157
|
-
const waiter =
|
|
158
|
-
reject: (reason) => finish(() => reject(reason)),
|
|
159
|
-
};
|
|
151
|
+
const waiter = (reason) => finish(() => reject(reason));
|
|
160
152
|
const finish = (settle) => {
|
|
161
153
|
clearTimeout(idleTimer);
|
|
162
154
|
clearTimeout(deadline);
|
|
@@ -166,10 +158,10 @@ export class NetworkTracker {
|
|
|
166
158
|
};
|
|
167
159
|
const check = () => {
|
|
168
160
|
clearTimeout(idleTimer);
|
|
169
|
-
if (this.
|
|
161
|
+
if (this.inflight === 0)
|
|
170
162
|
idleTimer = setTimeout(() => finish(resolve), idleTime);
|
|
171
163
|
};
|
|
172
|
-
const deadline = setTimeout(() => finish(() => reject(new NetworkIdleTimeoutError(timeout, this.
|
|
164
|
+
const deadline = setTimeout(() => finish(() => reject(new NetworkIdleTimeoutError(timeout, this.inflight, this.inflightUrls.slice(0, URLS_IN_MESSAGE)))), timeout);
|
|
173
165
|
this.waiters.add(waiter);
|
|
174
166
|
this.events.on("change", check);
|
|
175
167
|
check();
|
|
@@ -181,10 +173,8 @@ export class NetworkTracker {
|
|
|
181
173
|
return;
|
|
182
174
|
this.disposed = true;
|
|
183
175
|
this.removeListeners();
|
|
184
|
-
this.active.clear();
|
|
185
|
-
this.contexts.clear();
|
|
186
176
|
this.hops.clear();
|
|
187
|
-
[...this.waiters].forEach((
|
|
177
|
+
[...this.waiters].forEach((reject) => reject(new Error("page closed")));
|
|
188
178
|
await this.subscription?.unsubscribe();
|
|
189
179
|
}
|
|
190
180
|
removeListeners() {
|
|
@@ -197,7 +187,7 @@ export class NetworkTracker {
|
|
|
197
187
|
return context !== null && this.tree.isWithin(context, this.contextId);
|
|
198
188
|
}
|
|
199
189
|
static key(data, redirectCount) {
|
|
200
|
-
return `${data.request}:${
|
|
190
|
+
return `${data.request}:${redirectCount}`;
|
|
201
191
|
}
|
|
202
192
|
/** A listener that throws must not stop the tracker or the other listeners */
|
|
203
193
|
emit(event, ...args) {
|
|
@@ -211,27 +201,3 @@ export class NetworkTracker {
|
|
|
211
201
|
}
|
|
212
202
|
}
|
|
213
203
|
}
|
|
214
|
-
export function toRequest(data, navigation, isBlocked, redirectedFrom) {
|
|
215
|
-
return {
|
|
216
|
-
id: data.request,
|
|
217
|
-
url: data.url,
|
|
218
|
-
method: data.method,
|
|
219
|
-
headers: toHeaders(data.headers),
|
|
220
|
-
resourceType: data.destination || data.initiatorType || "other",
|
|
221
|
-
navigation,
|
|
222
|
-
redirectedFrom,
|
|
223
|
-
isBlocked,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
/** Header list to a lower-cased record; repeated names are joined, base64 values decoded */
|
|
227
|
-
export function toHeaders(headers) {
|
|
228
|
-
const result = {};
|
|
229
|
-
for (const { name, value } of headers) {
|
|
230
|
-
const text = value.type === "base64"
|
|
231
|
-
? Buffer.from(value.value, "base64").toString("utf8")
|
|
232
|
-
: value.value;
|
|
233
|
-
const key = name.toLowerCase();
|
|
234
|
-
result[key] = key in result ? `${result[key]}, ${text}` : text;
|
|
235
|
-
}
|
|
236
|
-
return result;
|
|
237
|
-
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface NetworkRequest {
|
|
2
|
+
/** The browser's id; the same for every hop of a redirect chain */
|
|
3
|
+
id: string;
|
|
4
|
+
url: string;
|
|
5
|
+
method: string;
|
|
6
|
+
/** Header names lower-cased; repeated headers joined with ", " */
|
|
7
|
+
headers: Record<string, string>;
|
|
8
|
+
/** "document", "script", "image", …; falls back to the initiator type, then "other" */
|
|
9
|
+
resourceType: string;
|
|
10
|
+
navigation: string | null;
|
|
11
|
+
/** The request this one is the redirect of, or null */
|
|
12
|
+
redirectedFrom: NetworkRequest | null;
|
|
13
|
+
/** True while a network intercept holds it */
|
|
14
|
+
isBlocked: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface NetworkResponse {
|
|
17
|
+
url: string;
|
|
18
|
+
status: number;
|
|
19
|
+
statusText: string;
|
|
20
|
+
headers: Record<string, string>;
|
|
21
|
+
fromCache: boolean;
|
|
22
|
+
request: NetworkRequest;
|
|
23
|
+
}
|
|
24
|
+
export type FailedRequest = NetworkRequest & {
|
|
25
|
+
errorText: string;
|
|
26
|
+
};
|
|
27
|
+
/** What `page.on` and the tracker emit: the event name and the arguments its listeners get */
|
|
28
|
+
export interface EventMap {
|
|
29
|
+
request: [NetworkRequest];
|
|
30
|
+
response: [NetworkResponse];
|
|
31
|
+
requestfailed: [FailedRequest];
|
|
32
|
+
}
|
|
33
|
+
export type NetworkEventName = keyof EventMap;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,15 +2,20 @@ import { WaitTimeoutError } from "../wait/wait-until.js";
|
|
|
2
2
|
import { type UrlPattern } from "./url-match.js";
|
|
3
3
|
/** What `page.waitForRequest` / `waitForResponse` match: a URL pattern, or a function */
|
|
4
4
|
export type NetworkMatch<T> = UrlPattern | ((item: T) => boolean);
|
|
5
|
-
/** No matching request or response arrived in time */
|
|
6
|
-
|
|
5
|
+
/** No matching request or response arrived in time; each subclass names itself */
|
|
6
|
+
declare class NetworkWaitTimeoutError extends WaitTimeoutError<undefined> {
|
|
7
7
|
constructor(operation: "waitForRequest" | "waitForResponse", match: NetworkMatch<never>, timeout: number);
|
|
8
8
|
}
|
|
9
9
|
export declare class RequestTimeoutError extends NetworkWaitTimeoutError {
|
|
10
10
|
}
|
|
11
11
|
export declare class ResponseTimeoutError extends NetworkWaitTimeoutError {
|
|
12
12
|
}
|
|
13
|
+
/** waitForIdle ran out of time with requests still in flight; `last` holds (up to five of) their URLs */
|
|
14
|
+
export declare class NetworkIdleTimeoutError extends WaitTimeoutError<string[]> {
|
|
15
|
+
constructor(timeout: number, inflight: number, urls: string[]);
|
|
16
|
+
}
|
|
13
17
|
/** The predicate for a match: a function as it is, a URL pattern tested on the item's url */
|
|
14
18
|
export declare function toPredicate<T extends {
|
|
15
19
|
url: string;
|
|
16
20
|
}>(match: NetworkMatch<T>): (item: T) => boolean;
|
|
21
|
+
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { WaitTimeoutError } from "../wait/wait-until.js";
|
|
2
2
|
import { matchUrl } from "./url-match.js";
|
|
3
|
-
/** No matching request or response arrived in time */
|
|
4
|
-
|
|
3
|
+
/** No matching request or response arrived in time; each subclass names itself */
|
|
4
|
+
class NetworkWaitTimeoutError extends WaitTimeoutError {
|
|
5
5
|
constructor(operation, match, timeout) {
|
|
6
6
|
super(timeout, undefined);
|
|
7
|
-
this.name =
|
|
7
|
+
this.name = new.target.name;
|
|
8
8
|
const kind = operation === "waitForRequest" ? "request" : "response";
|
|
9
9
|
this.message = `${operation}(): no ${kind} matching ${describeMatch(match)} within ${timeout}ms`;
|
|
10
10
|
}
|
|
@@ -13,6 +13,14 @@ export class RequestTimeoutError extends NetworkWaitTimeoutError {
|
|
|
13
13
|
}
|
|
14
14
|
export class ResponseTimeoutError extends NetworkWaitTimeoutError {
|
|
15
15
|
}
|
|
16
|
+
/** waitForIdle ran out of time with requests still in flight; `last` holds (up to five of) their URLs */
|
|
17
|
+
export class NetworkIdleTimeoutError extends WaitTimeoutError {
|
|
18
|
+
constructor(timeout, inflight, urls) {
|
|
19
|
+
super(timeout, urls);
|
|
20
|
+
this.name = "NetworkIdleTimeoutError";
|
|
21
|
+
this.message = `waitForNetworkIdle(): still ${inflight} request(s) in flight after ${timeout}ms: ${urls.join(", ")}`;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
16
24
|
function describeMatch(match) {
|
|
17
25
|
if (typeof match === "function")
|
|
18
26
|
return "the given function";
|
|
@@ -20,5 +28,7 @@ function describeMatch(match) {
|
|
|
20
28
|
}
|
|
21
29
|
/** The predicate for a match: a function as it is, a URL pattern tested on the item's url */
|
|
22
30
|
export function toPredicate(match) {
|
|
23
|
-
return typeof match === "function"
|
|
31
|
+
return typeof match === "function"
|
|
32
|
+
? match
|
|
33
|
+
: (item) => matchUrl(match, item.url);
|
|
24
34
|
}
|
package/dist/network/response.js
CHANGED
|
@@ -36,7 +36,7 @@ export class Response {
|
|
|
36
36
|
return JSON.parse(text);
|
|
37
37
|
}
|
|
38
38
|
catch (err) {
|
|
39
|
-
throw new Error(`
|
|
39
|
+
throw new Error(`json(): the response body of ${this.url} is not JSON: ${err.message}`);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { BiDiConnector } from "../transport/bidi-connection.js";
|
|
2
|
+
import type { NetworkRequest } from "./network-types.js";
|
|
3
|
+
import type { UrlPattern } from "./url-match.js";
|
|
4
|
+
export type RouteHandler = (route: Route) => void | Promise<void>;
|
|
5
|
+
export interface FulfillOptions {
|
|
6
|
+
/** @default 200 */
|
|
7
|
+
status?: number;
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
/** Sets `content-type` unless `headers` has one; `json` implies "application/json" */
|
|
10
|
+
contentType?: string;
|
|
11
|
+
body?: string | Buffer;
|
|
12
|
+
/** Sent as JSON text; cannot be combined with `body` */
|
|
13
|
+
json?: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface ContinueOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Sends the request to another URL. Firefox applies this to navigations only: the page's `fetch`, XHR and
|
|
18
|
+
* image requests fail when their URL is changed, so mock those with `fulfill` instead
|
|
19
|
+
*/
|
|
20
|
+
url?: string;
|
|
21
|
+
method?: string;
|
|
22
|
+
/** Replaces all request headers */
|
|
23
|
+
headers?: Record<string, string>;
|
|
24
|
+
postData?: string | Buffer;
|
|
25
|
+
}
|
|
26
|
+
export interface RouteEntry {
|
|
27
|
+
pattern: UrlPattern;
|
|
28
|
+
handler: RouteHandler;
|
|
29
|
+
}
|
|
30
|
+
/** Answers `network.*` commands for one blocked request */
|
|
31
|
+
export interface RouteDeps {
|
|
32
|
+
send: BiDiConnector["send"];
|
|
33
|
+
/** Passes the request to the next matching route, or lets it continue */
|
|
34
|
+
next: () => Promise<void>;
|
|
35
|
+
/** Called once the route is answered, whichever way */
|
|
36
|
+
settled: () => void;
|
|
37
|
+
/**
|
|
38
|
+
* Whether a replaced body needs a `content-length` of its own. Firefox keeps the old one and cuts the new body
|
|
39
|
+
* off; Chrome sets the right one itself and hangs the request when it is given one.
|
|
40
|
+
*/
|
|
41
|
+
sendsContentLength: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A request the browser holds until it is answered. Answer it exactly once with `fulfill`, `continue`,
|
|
45
|
+
* `abort` or `fallback`; a second call throws.
|
|
46
|
+
*/
|
|
47
|
+
export declare class Route {
|
|
48
|
+
private readonly info;
|
|
49
|
+
private readonly deps;
|
|
50
|
+
private answered;
|
|
51
|
+
constructor(info: NetworkRequest, deps: RouteDeps);
|
|
52
|
+
request(): NetworkRequest;
|
|
53
|
+
/** Answers the request without sending it: status 200 and no body unless told otherwise */
|
|
54
|
+
fulfill(options?: FulfillOptions): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Lets the request go on, optionally changed. `headers` replaces all request headers. A new `postData` brings its
|
|
57
|
+
* own `content-length` (the request's old one would cut the new body off or leave the server waiting).
|
|
58
|
+
*/
|
|
59
|
+
continue(options?: ContinueOptions): Promise<void>;
|
|
60
|
+
/** Makes the request fail (the browser reports a network error to the page) */
|
|
61
|
+
abort(): Promise<void>;
|
|
62
|
+
/** Hands the request to the next route that matches it, or lets it continue when there is none */
|
|
63
|
+
fallback(): Promise<void>;
|
|
64
|
+
private claim;
|
|
65
|
+
private answer;
|
|
66
|
+
}
|
|
67
|
+
/** What a `PendingRoute` needs of the router: how to talk to the browser and where to go on */
|
|
68
|
+
export type PendingRouteControl = Omit<RouteDeps, "settled"> & {
|
|
69
|
+
/** Called once the request is answered, whichever way */
|
|
70
|
+
onSettled: (pending: PendingRoute) => void;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* A request the browser holds, with what the router needs to see to it: the `Route` handed to the handler, the
|
|
74
|
+
* route entry that holds it, and the timer that lets it continue when the handler is too slow.
|
|
75
|
+
* Not part of the public API: handlers only ever see the `Route`.
|
|
76
|
+
*/
|
|
77
|
+
export declare class PendingRoute {
|
|
78
|
+
private readonly info;
|
|
79
|
+
readonly entry?: RouteEntry | undefined;
|
|
80
|
+
readonly route: Route;
|
|
81
|
+
private answered;
|
|
82
|
+
private timer;
|
|
83
|
+
/** `entry` is the route that holds the request; none for one nobody asked for */
|
|
84
|
+
constructor(info: NetworkRequest, control: PendingRouteControl, entry?: RouteEntry | undefined);
|
|
85
|
+
get isAnswered(): boolean;
|
|
86
|
+
/** Calls `onLate` when nothing answered after `ms`; the timer never keeps the process alive */
|
|
87
|
+
startTimer(ms: number, onLate: () => void): void;
|
|
88
|
+
/** Lets the request continue unchanged; failures are logged, not thrown */
|
|
89
|
+
release(): Promise<void>;
|
|
90
|
+
/** Fails the request; failures are logged, not thrown */
|
|
91
|
+
failQuietly(): Promise<void>;
|
|
92
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { STATUS_CODES } from "node:http";
|
|
2
|
+
import logger from "../logger/index.js";
|
|
3
|
+
import { headersToBidi, toBytes } from "./bidi-wire.js";
|
|
4
|
+
const hasHeader = (headers, name) => Object.keys(headers).some((key) => key.toLowerCase() === name);
|
|
5
|
+
/**
|
|
6
|
+
* A request the browser holds until it is answered. Answer it exactly once with `fulfill`, `continue`,
|
|
7
|
+
* `abort` or `fallback`; a second call throws.
|
|
8
|
+
*/
|
|
9
|
+
export class Route {
|
|
10
|
+
constructor(info, deps) {
|
|
11
|
+
this.info = info;
|
|
12
|
+
this.deps = deps;
|
|
13
|
+
this.answered = false;
|
|
14
|
+
}
|
|
15
|
+
request() {
|
|
16
|
+
return this.info;
|
|
17
|
+
}
|
|
18
|
+
/** Answers the request without sending it: status 200 and no body unless told otherwise */
|
|
19
|
+
async fulfill(options = {}) {
|
|
20
|
+
if (options.json !== undefined && options.body !== undefined) {
|
|
21
|
+
throw new TypeError("fulfill(): use either json or body, not both");
|
|
22
|
+
}
|
|
23
|
+
const text = options.json !== undefined ? JSON.stringify(options.json) : undefined;
|
|
24
|
+
const body = options.body ?? text;
|
|
25
|
+
const headers = { ...options.headers };
|
|
26
|
+
const contentType = options.contentType ??
|
|
27
|
+
(text !== undefined ? "application/json" : undefined);
|
|
28
|
+
if (contentType && !hasHeader(headers, "content-type"))
|
|
29
|
+
headers["content-type"] = contentType;
|
|
30
|
+
if (!hasHeader(headers, "content-length")) {
|
|
31
|
+
headers["content-length"] = String(body === undefined ? 0 : Buffer.byteLength(body));
|
|
32
|
+
}
|
|
33
|
+
const status = options.status ?? 200;
|
|
34
|
+
await this.answer("network.provideResponse", {
|
|
35
|
+
request: this.info.id,
|
|
36
|
+
statusCode: status,
|
|
37
|
+
reasonPhrase: STATUS_CODES[status] ?? "",
|
|
38
|
+
headers: headersToBidi(headers),
|
|
39
|
+
...(body !== undefined && { body: toBytes(body) }),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Lets the request go on, optionally changed. `headers` replaces all request headers. A new `postData` brings its
|
|
44
|
+
* own `content-length` (the request's old one would cut the new body off or leave the server waiting).
|
|
45
|
+
*/
|
|
46
|
+
async continue(options = {}) {
|
|
47
|
+
let headers = options.headers;
|
|
48
|
+
if (options.postData !== undefined) {
|
|
49
|
+
const withoutLength = Object.fromEntries(Object.entries(headers ?? this.info.headers).filter(([name]) => name.toLowerCase() !== "content-length"));
|
|
50
|
+
headers = this.deps.sendsContentLength
|
|
51
|
+
? {
|
|
52
|
+
...withoutLength,
|
|
53
|
+
"content-length": String(Buffer.byteLength(options.postData)),
|
|
54
|
+
}
|
|
55
|
+
: withoutLength;
|
|
56
|
+
}
|
|
57
|
+
await this.answer("network.continueRequest", {
|
|
58
|
+
request: this.info.id,
|
|
59
|
+
...(options.url !== undefined && { url: options.url }),
|
|
60
|
+
...(options.method !== undefined && { method: options.method }),
|
|
61
|
+
...(headers !== undefined && { headers: headersToBidi(headers) }),
|
|
62
|
+
...(options.postData !== undefined && {
|
|
63
|
+
body: toBytes(options.postData),
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/** Makes the request fail (the browser reports a network error to the page) */
|
|
68
|
+
async abort() {
|
|
69
|
+
await this.answer("network.failRequest", { request: this.info.id });
|
|
70
|
+
}
|
|
71
|
+
/** Hands the request to the next route that matches it, or lets it continue when there is none */
|
|
72
|
+
async fallback() {
|
|
73
|
+
this.claim();
|
|
74
|
+
await this.deps.next();
|
|
75
|
+
}
|
|
76
|
+
claim() {
|
|
77
|
+
if (this.answered)
|
|
78
|
+
throw new Error("route already handled");
|
|
79
|
+
this.answered = true;
|
|
80
|
+
this.deps.settled();
|
|
81
|
+
}
|
|
82
|
+
async answer(method, params) {
|
|
83
|
+
this.claim();
|
|
84
|
+
await this.deps.send(method, params);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* A request the browser holds, with what the router needs to see to it: the `Route` handed to the handler, the
|
|
89
|
+
* route entry that holds it, and the timer that lets it continue when the handler is too slow.
|
|
90
|
+
* Not part of the public API: handlers only ever see the `Route`.
|
|
91
|
+
*/
|
|
92
|
+
export class PendingRoute {
|
|
93
|
+
/** `entry` is the route that holds the request; none for one nobody asked for */
|
|
94
|
+
constructor(info, control, entry) {
|
|
95
|
+
this.info = info;
|
|
96
|
+
this.entry = entry;
|
|
97
|
+
this.answered = false;
|
|
98
|
+
this.route = new Route(info, {
|
|
99
|
+
send: control.send,
|
|
100
|
+
next: control.next,
|
|
101
|
+
sendsContentLength: control.sendsContentLength,
|
|
102
|
+
settled: () => {
|
|
103
|
+
this.answered = true;
|
|
104
|
+
clearTimeout(this.timer);
|
|
105
|
+
control.onSettled(this);
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
get isAnswered() {
|
|
110
|
+
return this.answered;
|
|
111
|
+
}
|
|
112
|
+
/** Calls `onLate` when nothing answered after `ms`; the timer never keeps the process alive */
|
|
113
|
+
startTimer(ms, onLate) {
|
|
114
|
+
this.timer = setTimeout(() => {
|
|
115
|
+
if (!this.answered)
|
|
116
|
+
onLate();
|
|
117
|
+
}, ms);
|
|
118
|
+
this.timer.unref?.();
|
|
119
|
+
}
|
|
120
|
+
/** Lets the request continue unchanged; failures are logged, not thrown */
|
|
121
|
+
async release() {
|
|
122
|
+
if (this.answered)
|
|
123
|
+
return;
|
|
124
|
+
try {
|
|
125
|
+
await this.route.continue();
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
logger.debug("Could not let %s continue", this.info.url, { err });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** Fails the request; failures are logged, not thrown */
|
|
132
|
+
async failQuietly() {
|
|
133
|
+
if (this.answered)
|
|
134
|
+
return;
|
|
135
|
+
try {
|
|
136
|
+
await this.route.abort();
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
logger.debug("Could not fail %s", this.info.url, { err });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|