@orkestrel/browser 0.0.23 → 0.0.25
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/dist/bin/main.js +17 -3
- package/dist/bin/main.js.map +1 -1
- package/dist/src/core/index.cjs +99 -25
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +30 -13
- package/dist/src/core/index.d.ts +30 -13
- package/dist/src/core/index.js +99 -25
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +701 -187
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +107 -13
- package/dist/src/server/index.d.ts +107 -13
- package/dist/src/server/index.js +698 -190
- package/dist/src/server/index.js.map +1 -1
- package/package.json +6 -6
|
@@ -107,7 +107,7 @@ export declare const BROWSER_FRAME_WORLD_NAME = "__orkestrelBrowserFrame";
|
|
|
107
107
|
*/
|
|
108
108
|
export declare const BROWSER_HAR_CREATOR: Readonly<{
|
|
109
109
|
name: "@orkestrel/browser";
|
|
110
|
-
version: "0.0.
|
|
110
|
+
version: "0.0.25";
|
|
111
111
|
}>;
|
|
112
112
|
|
|
113
113
|
/** Names accessibility roles that receive actionable outline references. */
|
|
@@ -159,7 +159,7 @@ export declare const BROWSER_JOURNEY_STEP_KEYS: readonly string[];
|
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
161
|
* Names the journey tools a toolset constructed with `journeys` registers and reserves: `record`,
|
|
162
|
-
* `save`, `journeys`, `edit`, `replay`, and `
|
|
162
|
+
* `save`, `journeys`, `edit`, `replay`, `forget`, and `capture`.
|
|
163
163
|
*/
|
|
164
164
|
export declare const BROWSER_JOURNEY_TOOL_NAMES: readonly BrowserToolName[];
|
|
165
165
|
|
|
@@ -711,6 +711,7 @@ export declare class BrowserContext implements BrowserContextInterface {
|
|
|
711
711
|
constructor(client: CDPClientInterface, id?: string, viewport?: BrowserViewport, writer?: BrowserWriterInterface, emulation?: BrowserEmulationOptions, downloads?: BrowserDownloadOptions, options?: BrowserContextOptions);
|
|
712
712
|
get emitter(): EmitterInterface<BrowserContextEventMap>;
|
|
713
713
|
get id(): string | undefined;
|
|
714
|
+
get disposal(): BrowserContextDisposal | undefined;
|
|
714
715
|
get cookies(): BrowserCookieManagerInterface;
|
|
715
716
|
get permissions(): BrowserPermissionManagerInterface;
|
|
716
717
|
get storage(): BrowserStorageManagerInterface;
|
|
@@ -723,6 +724,14 @@ export declare class BrowserContext implements BrowserContextInterface {
|
|
|
723
724
|
close(): Promise<void>;
|
|
724
725
|
}
|
|
725
726
|
|
|
727
|
+
/** Records Chromium's disposal acknowledgement or the failure that left disposal unconfirmed. */
|
|
728
|
+
export declare type BrowserContextDisposal = {
|
|
729
|
+
readonly confirmed: true;
|
|
730
|
+
} | {
|
|
731
|
+
readonly confirmed: false;
|
|
732
|
+
readonly error: unknown;
|
|
733
|
+
};
|
|
734
|
+
|
|
726
735
|
/** Maps the browser-context lifecycle events. */
|
|
727
736
|
export declare type BrowserContextEventMap = {
|
|
728
737
|
readonly page: readonly [page: BrowserPageInterface];
|
|
@@ -746,6 +755,8 @@ export declare type BrowserContextEventMap = {
|
|
|
746
755
|
export declare interface BrowserContextInterface {
|
|
747
756
|
readonly emitter: EmitterInterface<BrowserContextEventMap>;
|
|
748
757
|
readonly id: string | undefined;
|
|
758
|
+
/** Holds the remote disposal receipt after `close()` attempts disposal; wrapper destruction has none. */
|
|
759
|
+
readonly disposal: BrowserContextDisposal | undefined;
|
|
749
760
|
readonly cookies: BrowserCookieManagerInterface;
|
|
750
761
|
readonly permissions: BrowserPermissionManagerInterface;
|
|
751
762
|
readonly storage: BrowserStorageManagerInterface;
|
|
@@ -1801,7 +1812,7 @@ export declare type BrowserJourneyEditRequest = BrowserJourneyEdit | {
|
|
|
1801
1812
|
*
|
|
1802
1813
|
* @remarks
|
|
1803
1814
|
* - `store` — keeps the journeys the tools record, list, edit, and replay
|
|
1804
|
-
* - `runs` — keeps each replay's run
|
|
1815
|
+
* - `runs` — keeps each replay's run and saves standalone images when it provides `snapshot`
|
|
1805
1816
|
* - `limit` — positive integer listing cap in characters; Default: the owner's `limit`, including direct construction
|
|
1806
1817
|
* - `readonly` — if `true`, refuses `record`, `save`, `edit`, and `forget` before any store access, and
|
|
1807
1818
|
* `replay` still writes runs; if `false` or omitted, every tool runs
|
|
@@ -1930,13 +1941,13 @@ export declare interface BrowserJourneyTarget {
|
|
|
1930
1941
|
}
|
|
1931
1942
|
|
|
1932
1943
|
/**
|
|
1933
|
-
* Registers the journey tools `record`, `save`, `journeys`, `edit`, `replay`, and `
|
|
1944
|
+
* Registers the journey tools `record`, `save`, `journeys`, `edit`, `replay`, `forget`, and `capture` over a toolset
|
|
1934
1945
|
* and owns the recording and the active replay.
|
|
1935
1946
|
*
|
|
1936
1947
|
* @remarks
|
|
1937
1948
|
* The journey toolset composes the toolset's public members: `perform` reads the view a receipt
|
|
1938
1949
|
* carries through `look`, `hold` and `emitter` drive the recorder and the replay, `view` converts
|
|
1939
|
-
* an edit's `ref` to a target, and `tools` receives the
|
|
1950
|
+
* an edit's `ref` to a target, and `tools` receives the journey tools at construction, which refuses
|
|
1940
1951
|
* with `BROWSER_TOOLSET_RESERVED` when the manager already holds one of the names. Every refusal
|
|
1941
1952
|
* is a sentence that names the next call, and a reason inside it is a clause without a directive
|
|
1942
1953
|
* or a final period.
|
|
@@ -1952,7 +1963,7 @@ export declare interface BrowserJourneyTarget {
|
|
|
1952
1963
|
* by the view after the run.
|
|
1953
1964
|
*
|
|
1954
1965
|
* `destroy()` aborts the active replay and waits for it to finish, stops a recording without
|
|
1955
|
-
* saving it, and removes the
|
|
1966
|
+
* saving it, and removes the journey tools the manager still holds under the instances it added.
|
|
1956
1967
|
*
|
|
1957
1968
|
* @example
|
|
1958
1969
|
* ```ts
|
|
@@ -1972,7 +1983,7 @@ export declare class BrowserJourneyToolset implements BrowserJourneyToolsetInter
|
|
|
1972
1983
|
}
|
|
1973
1984
|
|
|
1974
1985
|
/**
|
|
1975
|
-
* Registers the
|
|
1986
|
+
* Registers the journey tools over a toolset and owns the recording and the active replay.
|
|
1976
1987
|
*
|
|
1977
1988
|
* @remarks
|
|
1978
1989
|
* - `recording` — the name of the journey being recorded, or `undefined` when none is
|
|
@@ -1981,7 +1992,7 @@ export declare class BrowserJourneyToolset implements BrowserJourneyToolsetInter
|
|
|
1981
1992
|
export declare interface BrowserJourneyToolsetInterface {
|
|
1982
1993
|
readonly recording: string | undefined;
|
|
1983
1994
|
readonly replaying: string | undefined;
|
|
1984
|
-
/** Aborts the active replay and removes the
|
|
1995
|
+
/** Aborts the active replay and removes the journey tools from the manager. */
|
|
1985
1996
|
destroy(): Promise<void>;
|
|
1986
1997
|
}
|
|
1987
1998
|
|
|
@@ -3483,6 +3494,14 @@ export declare interface BrowserRunStep {
|
|
|
3483
3494
|
|
|
3484
3495
|
/** Keeps runs by the journey name and run id the run carries. */
|
|
3485
3496
|
export declare interface BrowserRunStoreInterface {
|
|
3497
|
+
/**
|
|
3498
|
+
* Saves a standalone PNG under the runs root without replacing an existing file.
|
|
3499
|
+
* @param bytes - PNG bytes to persist
|
|
3500
|
+
* @param options - Cancellation options
|
|
3501
|
+
* @returns Absolute path of the saved image
|
|
3502
|
+
* @remarks Stores without standalone file storage omit this capability.
|
|
3503
|
+
*/
|
|
3504
|
+
snapshot?(bytes: Uint8Array, options?: BrowserStoreOptions): Promise<string>;
|
|
3486
3505
|
/** Mints a run id for the journey and creates its run directory exclusively. */
|
|
3487
3506
|
open(name: string, options?: BrowserStoreOptions): Promise<BrowserRunSlot>;
|
|
3488
3507
|
/** Returns the run stored under the journey name and id, or `undefined` when none is stored. */
|
|
@@ -3967,9 +3986,9 @@ export declare interface BrowserRunStoreInterface {
|
|
|
3967
3986
|
/**
|
|
3968
3987
|
* Names a tool the browser toolset reserves: the generic tools, the staged `dialog`, the
|
|
3969
3988
|
* opt-in `tabs` and `switch`, and the journey tools `record`, `save`, `journeys`, `edit`,
|
|
3970
|
-
* `replay`, and `
|
|
3989
|
+
* `replay`, `forget`, and `capture`, which a toolset constructed with `journeys` reserves.
|
|
3971
3990
|
*/
|
|
3972
|
-
export declare type BrowserToolName = 'look' | 'read' | 'plain' | 'click' | 'type' | 'press' | 'navigate' | 'wait' | 'dialog' | 'tabs' | 'switch' | 'record' | 'save' | 'journeys' | 'edit' | 'replay' | 'forget';
|
|
3991
|
+
export declare type BrowserToolName = 'look' | 'read' | 'plain' | 'click' | 'type' | 'press' | 'navigate' | 'wait' | 'dialog' | 'tabs' | 'switch' | 'record' | 'save' | 'journeys' | 'edit' | 'replay' | 'forget' | 'capture';
|
|
3973
3992
|
|
|
3974
3993
|
/** Identifies a removed WebMCP tool by document and name. */
|
|
3975
3994
|
export declare interface BrowserToolRemoval {
|
|
@@ -4753,9 +4772,7 @@ export declare interface BrowserRunStoreInterface {
|
|
|
4753
4772
|
}
|
|
4754
4773
|
|
|
4755
4774
|
/**
|
|
4756
|
-
* Reports that a CDP request could not be sent or completed because the client was not
|
|
4757
|
-
* connectable state — not connected, closed while connecting, or the connection dropped
|
|
4758
|
-
* mid-request — under the code `BROWSER_CDP_CONNECTION_ERROR`.
|
|
4775
|
+
* Reports that a CDP request could not be sent or completed because the client was not connected, closed while connecting, lost its connection, or lost the request's target session, under the code `BROWSER_CDP_CONNECTION_ERROR`.
|
|
4759
4776
|
*/
|
|
4760
4777
|
export declare class CDPConnectionError extends BrowserError {
|
|
4761
4778
|
constructor(message: string, context?: Readonly<Record<string, unknown>>);
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -107,7 +107,7 @@ export declare const BROWSER_FRAME_WORLD_NAME = "__orkestrelBrowserFrame";
|
|
|
107
107
|
*/
|
|
108
108
|
export declare const BROWSER_HAR_CREATOR: Readonly<{
|
|
109
109
|
name: "@orkestrel/browser";
|
|
110
|
-
version: "0.0.
|
|
110
|
+
version: "0.0.25";
|
|
111
111
|
}>;
|
|
112
112
|
|
|
113
113
|
/** Names accessibility roles that receive actionable outline references. */
|
|
@@ -159,7 +159,7 @@ export declare const BROWSER_JOURNEY_STEP_KEYS: readonly string[];
|
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
161
|
* Names the journey tools a toolset constructed with `journeys` registers and reserves: `record`,
|
|
162
|
-
* `save`, `journeys`, `edit`, `replay`, and `
|
|
162
|
+
* `save`, `journeys`, `edit`, `replay`, `forget`, and `capture`.
|
|
163
163
|
*/
|
|
164
164
|
export declare const BROWSER_JOURNEY_TOOL_NAMES: readonly BrowserToolName[];
|
|
165
165
|
|
|
@@ -711,6 +711,7 @@ export declare class BrowserContext implements BrowserContextInterface {
|
|
|
711
711
|
constructor(client: CDPClientInterface, id?: string, viewport?: BrowserViewport, writer?: BrowserWriterInterface, emulation?: BrowserEmulationOptions, downloads?: BrowserDownloadOptions, options?: BrowserContextOptions);
|
|
712
712
|
get emitter(): EmitterInterface<BrowserContextEventMap>;
|
|
713
713
|
get id(): string | undefined;
|
|
714
|
+
get disposal(): BrowserContextDisposal | undefined;
|
|
714
715
|
get cookies(): BrowserCookieManagerInterface;
|
|
715
716
|
get permissions(): BrowserPermissionManagerInterface;
|
|
716
717
|
get storage(): BrowserStorageManagerInterface;
|
|
@@ -723,6 +724,14 @@ export declare class BrowserContext implements BrowserContextInterface {
|
|
|
723
724
|
close(): Promise<void>;
|
|
724
725
|
}
|
|
725
726
|
|
|
727
|
+
/** Records Chromium's disposal acknowledgement or the failure that left disposal unconfirmed. */
|
|
728
|
+
export declare type BrowserContextDisposal = {
|
|
729
|
+
readonly confirmed: true;
|
|
730
|
+
} | {
|
|
731
|
+
readonly confirmed: false;
|
|
732
|
+
readonly error: unknown;
|
|
733
|
+
};
|
|
734
|
+
|
|
726
735
|
/** Maps the browser-context lifecycle events. */
|
|
727
736
|
export declare type BrowserContextEventMap = {
|
|
728
737
|
readonly page: readonly [page: BrowserPageInterface];
|
|
@@ -746,6 +755,8 @@ export declare type BrowserContextEventMap = {
|
|
|
746
755
|
export declare interface BrowserContextInterface {
|
|
747
756
|
readonly emitter: EmitterInterface<BrowserContextEventMap>;
|
|
748
757
|
readonly id: string | undefined;
|
|
758
|
+
/** Holds the remote disposal receipt after `close()` attempts disposal; wrapper destruction has none. */
|
|
759
|
+
readonly disposal: BrowserContextDisposal | undefined;
|
|
749
760
|
readonly cookies: BrowserCookieManagerInterface;
|
|
750
761
|
readonly permissions: BrowserPermissionManagerInterface;
|
|
751
762
|
readonly storage: BrowserStorageManagerInterface;
|
|
@@ -1801,7 +1812,7 @@ export declare type BrowserJourneyEditRequest = BrowserJourneyEdit | {
|
|
|
1801
1812
|
*
|
|
1802
1813
|
* @remarks
|
|
1803
1814
|
* - `store` — keeps the journeys the tools record, list, edit, and replay
|
|
1804
|
-
* - `runs` — keeps each replay's run
|
|
1815
|
+
* - `runs` — keeps each replay's run and saves standalone images when it provides `snapshot`
|
|
1805
1816
|
* - `limit` — positive integer listing cap in characters; Default: the owner's `limit`, including direct construction
|
|
1806
1817
|
* - `readonly` — if `true`, refuses `record`, `save`, `edit`, and `forget` before any store access, and
|
|
1807
1818
|
* `replay` still writes runs; if `false` or omitted, every tool runs
|
|
@@ -1930,13 +1941,13 @@ export declare interface BrowserJourneyTarget {
|
|
|
1930
1941
|
}
|
|
1931
1942
|
|
|
1932
1943
|
/**
|
|
1933
|
-
* Registers the journey tools `record`, `save`, `journeys`, `edit`, `replay`, and `
|
|
1944
|
+
* Registers the journey tools `record`, `save`, `journeys`, `edit`, `replay`, `forget`, and `capture` over a toolset
|
|
1934
1945
|
* and owns the recording and the active replay.
|
|
1935
1946
|
*
|
|
1936
1947
|
* @remarks
|
|
1937
1948
|
* The journey toolset composes the toolset's public members: `perform` reads the view a receipt
|
|
1938
1949
|
* carries through `look`, `hold` and `emitter` drive the recorder and the replay, `view` converts
|
|
1939
|
-
* an edit's `ref` to a target, and `tools` receives the
|
|
1950
|
+
* an edit's `ref` to a target, and `tools` receives the journey tools at construction, which refuses
|
|
1940
1951
|
* with `BROWSER_TOOLSET_RESERVED` when the manager already holds one of the names. Every refusal
|
|
1941
1952
|
* is a sentence that names the next call, and a reason inside it is a clause without a directive
|
|
1942
1953
|
* or a final period.
|
|
@@ -1952,7 +1963,7 @@ export declare interface BrowserJourneyTarget {
|
|
|
1952
1963
|
* by the view after the run.
|
|
1953
1964
|
*
|
|
1954
1965
|
* `destroy()` aborts the active replay and waits for it to finish, stops a recording without
|
|
1955
|
-
* saving it, and removes the
|
|
1966
|
+
* saving it, and removes the journey tools the manager still holds under the instances it added.
|
|
1956
1967
|
*
|
|
1957
1968
|
* @example
|
|
1958
1969
|
* ```ts
|
|
@@ -1972,7 +1983,7 @@ export declare class BrowserJourneyToolset implements BrowserJourneyToolsetInter
|
|
|
1972
1983
|
}
|
|
1973
1984
|
|
|
1974
1985
|
/**
|
|
1975
|
-
* Registers the
|
|
1986
|
+
* Registers the journey tools over a toolset and owns the recording and the active replay.
|
|
1976
1987
|
*
|
|
1977
1988
|
* @remarks
|
|
1978
1989
|
* - `recording` — the name of the journey being recorded, or `undefined` when none is
|
|
@@ -1981,7 +1992,7 @@ export declare class BrowserJourneyToolset implements BrowserJourneyToolsetInter
|
|
|
1981
1992
|
export declare interface BrowserJourneyToolsetInterface {
|
|
1982
1993
|
readonly recording: string | undefined;
|
|
1983
1994
|
readonly replaying: string | undefined;
|
|
1984
|
-
/** Aborts the active replay and removes the
|
|
1995
|
+
/** Aborts the active replay and removes the journey tools from the manager. */
|
|
1985
1996
|
destroy(): Promise<void>;
|
|
1986
1997
|
}
|
|
1987
1998
|
|
|
@@ -3483,6 +3494,14 @@ export declare interface BrowserRunStep {
|
|
|
3483
3494
|
|
|
3484
3495
|
/** Keeps runs by the journey name and run id the run carries. */
|
|
3485
3496
|
export declare interface BrowserRunStoreInterface {
|
|
3497
|
+
/**
|
|
3498
|
+
* Saves a standalone PNG under the runs root without replacing an existing file.
|
|
3499
|
+
* @param bytes - PNG bytes to persist
|
|
3500
|
+
* @param options - Cancellation options
|
|
3501
|
+
* @returns Absolute path of the saved image
|
|
3502
|
+
* @remarks Stores without standalone file storage omit this capability.
|
|
3503
|
+
*/
|
|
3504
|
+
snapshot?(bytes: Uint8Array, options?: BrowserStoreOptions): Promise<string>;
|
|
3486
3505
|
/** Mints a run id for the journey and creates its run directory exclusively. */
|
|
3487
3506
|
open(name: string, options?: BrowserStoreOptions): Promise<BrowserRunSlot>;
|
|
3488
3507
|
/** Returns the run stored under the journey name and id, or `undefined` when none is stored. */
|
|
@@ -3967,9 +3986,9 @@ export declare interface BrowserRunStoreInterface {
|
|
|
3967
3986
|
/**
|
|
3968
3987
|
* Names a tool the browser toolset reserves: the generic tools, the staged `dialog`, the
|
|
3969
3988
|
* opt-in `tabs` and `switch`, and the journey tools `record`, `save`, `journeys`, `edit`,
|
|
3970
|
-
* `replay`, and `
|
|
3989
|
+
* `replay`, `forget`, and `capture`, which a toolset constructed with `journeys` reserves.
|
|
3971
3990
|
*/
|
|
3972
|
-
export declare type BrowserToolName = 'look' | 'read' | 'plain' | 'click' | 'type' | 'press' | 'navigate' | 'wait' | 'dialog' | 'tabs' | 'switch' | 'record' | 'save' | 'journeys' | 'edit' | 'replay' | 'forget';
|
|
3991
|
+
export declare type BrowserToolName = 'look' | 'read' | 'plain' | 'click' | 'type' | 'press' | 'navigate' | 'wait' | 'dialog' | 'tabs' | 'switch' | 'record' | 'save' | 'journeys' | 'edit' | 'replay' | 'forget' | 'capture';
|
|
3973
3992
|
|
|
3974
3993
|
/** Identifies a removed WebMCP tool by document and name. */
|
|
3975
3994
|
export declare interface BrowserToolRemoval {
|
|
@@ -4753,9 +4772,7 @@ export declare interface BrowserRunStoreInterface {
|
|
|
4753
4772
|
}
|
|
4754
4773
|
|
|
4755
4774
|
/**
|
|
4756
|
-
* Reports that a CDP request could not be sent or completed because the client was not
|
|
4757
|
-
* connectable state — not connected, closed while connecting, or the connection dropped
|
|
4758
|
-
* mid-request — under the code `BROWSER_CDP_CONNECTION_ERROR`.
|
|
4775
|
+
* Reports that a CDP request could not be sent or completed because the client was not connected, closed while connecting, lost its connection, or lost the request's target session, under the code `BROWSER_CDP_CONNECTION_ERROR`.
|
|
4759
4776
|
*/
|
|
4760
4777
|
export declare class CDPConnectionError extends BrowserError {
|
|
4761
4778
|
constructor(message: string, context?: Readonly<Record<string, unknown>>);
|
package/dist/src/core/index.js
CHANGED
|
@@ -162,7 +162,7 @@ var BROWSER_MOUSE_BUTTON_MASKS = Object.freeze({
|
|
|
162
162
|
*/
|
|
163
163
|
var BROWSER_HAR_CREATOR = Object.freeze({
|
|
164
164
|
name: "@orkestrel/browser",
|
|
165
|
-
version: "0.0.
|
|
165
|
+
version: "0.0.25"
|
|
166
166
|
});
|
|
167
167
|
/** Names the attribute that tags temporary screenshot styles and masks. */
|
|
168
168
|
var BROWSER_SCREENSHOT_ATTRIBUTE = "data-orkestrel-screenshot";
|
|
@@ -741,7 +741,7 @@ var BROWSER_TOOL_COPY = Object.freeze({
|
|
|
741
741
|
description: "The journey name, such as add-kettle."
|
|
742
742
|
}),
|
|
743
743
|
edits: Object.freeze({
|
|
744
|
-
description: "The changes, as an array or
|
|
744
|
+
description: "The changes, as an array or its JSON string, applied in order; one invalid change refuses them all.",
|
|
745
745
|
anyOf: Object.freeze([Object.freeze({
|
|
746
746
|
type: "array",
|
|
747
747
|
items: Object.freeze({
|
|
@@ -817,6 +817,18 @@ var BROWSER_TOOL_COPY = Object.freeze({
|
|
|
817
817
|
required: Object.freeze(["journey"])
|
|
818
818
|
})
|
|
819
819
|
}),
|
|
820
|
+
capture: Object.freeze({
|
|
821
|
+
name: "capture",
|
|
822
|
+
description: "Saves the current view as a PNG in the runs directory and returns its path.",
|
|
823
|
+
parameters: Object.freeze({
|
|
824
|
+
type: "object",
|
|
825
|
+
properties: Object.freeze({ full: Object.freeze({
|
|
826
|
+
type: "boolean",
|
|
827
|
+
description: "True captures the full page; false captures the viewport."
|
|
828
|
+
}) }),
|
|
829
|
+
required: Object.freeze(["full"])
|
|
830
|
+
})
|
|
831
|
+
}),
|
|
820
832
|
forget: Object.freeze({
|
|
821
833
|
name: "forget",
|
|
822
834
|
description: "Removes a saved journey and all its runs; the name is free to record again.",
|
|
@@ -885,7 +897,7 @@ var BROWSER_ACTION_STAGES = Object.freeze([
|
|
|
885
897
|
var BROWSER_JOURNEY_EMPTY_LISTING = "No journeys are saved; call record to start one.";
|
|
886
898
|
/**
|
|
887
899
|
* Names the journey tools a toolset constructed with `journeys` registers and reserves: `record`,
|
|
888
|
-
* `save`, `journeys`, `edit`, `replay`, and `
|
|
900
|
+
* `save`, `journeys`, `edit`, `replay`, `forget`, and `capture`.
|
|
889
901
|
*/
|
|
890
902
|
var BROWSER_JOURNEY_TOOL_NAMES = Object.freeze([
|
|
891
903
|
"record",
|
|
@@ -893,7 +905,8 @@ var BROWSER_JOURNEY_TOOL_NAMES = Object.freeze([
|
|
|
893
905
|
"journeys",
|
|
894
906
|
"edit",
|
|
895
907
|
"replay",
|
|
896
|
-
"forget"
|
|
908
|
+
"forget",
|
|
909
|
+
"capture"
|
|
897
910
|
]);
|
|
898
911
|
/** Names observation and journey tools that cannot become journey steps. */
|
|
899
912
|
var BROWSER_JOURNEY_NON_STEP_TOOLS = Object.freeze([...BROWSER_OBSERVATION_TOOL_NAMES, ...BROWSER_JOURNEY_TOOL_NAMES]);
|
|
@@ -999,9 +1012,7 @@ var CDPError = class extends BrowserError {
|
|
|
999
1012
|
}
|
|
1000
1013
|
};
|
|
1001
1014
|
/**
|
|
1002
|
-
* Reports that a CDP request could not be sent or completed because the client was not
|
|
1003
|
-
* connectable state — not connected, closed while connecting, or the connection dropped
|
|
1004
|
-
* mid-request — under the code `BROWSER_CDP_CONNECTION_ERROR`.
|
|
1015
|
+
* Reports that a CDP request could not be sent or completed because the client was not connected, closed while connecting, lost its connection, or lost the request's target session, under the code `BROWSER_CDP_CONNECTION_ERROR`.
|
|
1005
1016
|
*/
|
|
1006
1017
|
var CDPConnectionError = class extends BrowserError {
|
|
1007
1018
|
constructor(message, context) {
|
|
@@ -5211,6 +5222,7 @@ var CDPClient = class {
|
|
|
5211
5222
|
const listener = signal === void 0 ? void 0 : this.#abort(id, signal);
|
|
5212
5223
|
this.#pending.set(id, {
|
|
5213
5224
|
method,
|
|
5225
|
+
session: options?.session,
|
|
5214
5226
|
resolve,
|
|
5215
5227
|
reject,
|
|
5216
5228
|
timer,
|
|
@@ -5355,6 +5367,16 @@ var CDPClient = class {
|
|
|
5355
5367
|
const method = parsed["method"];
|
|
5356
5368
|
const rawParams = parsed["params"];
|
|
5357
5369
|
const params = isRecord(rawParams) ? rawParams : Object.freeze({});
|
|
5370
|
+
if (method === "Target.detachedFromTarget" && isString(params["sessionId"])) {
|
|
5371
|
+
const detached = params["sessionId"];
|
|
5372
|
+
for (const [id, entry] of this.#pending) {
|
|
5373
|
+
if (entry.session !== detached) continue;
|
|
5374
|
+
this.#settle(id)?.reject(new CDPConnectionError("CDP session detached", {
|
|
5375
|
+
method: entry.method,
|
|
5376
|
+
session: detached
|
|
5377
|
+
}));
|
|
5378
|
+
}
|
|
5379
|
+
}
|
|
5358
5380
|
const global = this.#subscriptions.get(void 0)?.get(method);
|
|
5359
5381
|
if (global !== void 0) this.#dispatch(global, method, params);
|
|
5360
5382
|
const session = parsed["sessionId"];
|
|
@@ -6450,9 +6472,11 @@ var BrowserPageElement = class {
|
|
|
6450
6472
|
object: result["object"]["objectId"],
|
|
6451
6473
|
context
|
|
6452
6474
|
};
|
|
6453
|
-
} catch {
|
|
6475
|
+
} catch (error) {
|
|
6454
6476
|
options?.signal?.throwIfAborted();
|
|
6455
|
-
|
|
6477
|
+
if (isCDPTimeoutError(error) || isCDPConnectionError(error)) throw error;
|
|
6478
|
+
if (isCDPError(error) && /Could not find node|No node with given id|No node found for given backend id/i.test(error.message)) throw new BrowserElementError(this.reference, "GONE");
|
|
6479
|
+
throw error;
|
|
6456
6480
|
}
|
|
6457
6481
|
}
|
|
6458
6482
|
async #call(declaration, options, target) {
|
|
@@ -6481,7 +6505,7 @@ var BrowserPageElement = class {
|
|
|
6481
6505
|
}
|
|
6482
6506
|
#failure(options, error) {
|
|
6483
6507
|
options?.signal?.throwIfAborted();
|
|
6484
|
-
if (isBrowserElementError(error)) throw error;
|
|
6508
|
+
if (isBrowserElementError(error) || isCDPTimeoutError(error) || isCDPConnectionError(error)) throw error;
|
|
6485
6509
|
const message = (isError(error) ? error.message : String(error)).split("\n", 1)[0] ?? "";
|
|
6486
6510
|
const known = BROWSER_ELEMENT_REFUSALS.get(message.replace(/^Error: /, ""));
|
|
6487
6511
|
if (known !== void 0) throw new BrowserElementError(this.reference, known.reason, known.detail);
|
|
@@ -6513,11 +6537,20 @@ var BrowserPageElement = class {
|
|
|
6513
6537
|
session: this.#input.node.session,
|
|
6514
6538
|
...options
|
|
6515
6539
|
}).catch(this.#failure.bind(this, options));
|
|
6516
|
-
await this.#call(
|
|
6540
|
+
await this.#call(`async function() {
|
|
6541
|
+
await (${compileActionabilityFunction({
|
|
6517
6542
|
visible: true,
|
|
6518
6543
|
enabled: true,
|
|
6519
6544
|
stable: true
|
|
6520
|
-
})
|
|
6545
|
+
})}).call(this)
|
|
6546
|
+
let previous
|
|
6547
|
+
for (;;) {
|
|
6548
|
+
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
6549
|
+
const current = [window.scrollX, window.scrollY]
|
|
6550
|
+
if (previous && current.every((value, index) => value === previous[index])) return true
|
|
6551
|
+
previous = current
|
|
6552
|
+
}
|
|
6553
|
+
}`, options);
|
|
6521
6554
|
const geometry = await this.#geometry(options);
|
|
6522
6555
|
const point = geometry.page.center;
|
|
6523
6556
|
const local = geometry.local.center;
|
|
@@ -6528,6 +6561,10 @@ var BrowserPageElement = class {
|
|
|
6528
6561
|
}, {
|
|
6529
6562
|
session: this.#input.node.session,
|
|
6530
6563
|
...options
|
|
6564
|
+
}).catch((error) => {
|
|
6565
|
+
options?.signal?.throwIfAborted();
|
|
6566
|
+
if (isCDPError(error) && error.context?.["message"] === "No node found at given location") throw new BrowserElementError(this.reference, "OCCLUDED", "hit-test location held no node");
|
|
6567
|
+
throw error;
|
|
6531
6568
|
});
|
|
6532
6569
|
if (!isRecord(hit) || !isInteger(hit["backendNodeId"]) || hit["frameId"] !== void 0 && hit["frameId"] !== this.#input.frame) throw new BrowserElementError(this.reference, "OCCLUDED");
|
|
6533
6570
|
if (hit["backendNodeId"] !== this.#input.backend && await this.#call(compileHitFunction(), options, hit["backendNodeId"]) !== true) {
|
|
@@ -7179,10 +7216,12 @@ var BrowserRegistry = class {
|
|
|
7179
7216
|
for (const frame of new Set([...this.tools(), ...this.#pending].map((entry) => entry.frame))) this.#invalidate(frame);
|
|
7180
7217
|
}
|
|
7181
7218
|
#navigated(params) {
|
|
7219
|
+
if (this.#page.closed || this.#destroying !== void 0) return;
|
|
7182
7220
|
const frame = params["frame"];
|
|
7183
7221
|
if (isRecord(frame) && isString(frame["id"])) this.#invalidate(frame["id"]);
|
|
7184
7222
|
}
|
|
7185
7223
|
#detached(params) {
|
|
7224
|
+
if (this.#page.closed || this.#destroying !== void 0) return;
|
|
7186
7225
|
if (isString(params["frameId"])) this.#invalidate(params["frameId"]);
|
|
7187
7226
|
}
|
|
7188
7227
|
#invalidate(frame) {
|
|
@@ -7196,6 +7235,7 @@ var BrowserRegistry = class {
|
|
|
7196
7235
|
if (removed) this.#emitter.emit("change");
|
|
7197
7236
|
}
|
|
7198
7237
|
#add(session, params) {
|
|
7238
|
+
if (this.#page.closed || this.#destroying !== void 0) return;
|
|
7199
7239
|
if (!isArray(params["tools"])) return;
|
|
7200
7240
|
for (const value of params["tools"]) {
|
|
7201
7241
|
const tool = parseBrowserTool(value);
|
|
@@ -7206,6 +7246,7 @@ var BrowserRegistry = class {
|
|
|
7206
7246
|
this.#emitter.emit("change");
|
|
7207
7247
|
}
|
|
7208
7248
|
#remove(params) {
|
|
7249
|
+
if (this.#page.closed || this.#destroying !== void 0) return;
|
|
7209
7250
|
if (!isArray(params["tools"])) return;
|
|
7210
7251
|
for (const value of params["tools"]) {
|
|
7211
7252
|
const key = parseBrowserRemoval(value);
|
|
@@ -10141,10 +10182,10 @@ var BrowserPage = class BrowserPage extends BrowserFrame {
|
|
|
10141
10182
|
} catch {}
|
|
10142
10183
|
}
|
|
10143
10184
|
async #close() {
|
|
10144
|
-
await this.#release();
|
|
10145
10185
|
try {
|
|
10146
10186
|
await this.#client.send("Target.closeTarget", { targetId: this.#targetId });
|
|
10147
10187
|
} catch {}
|
|
10188
|
+
await this.#release();
|
|
10148
10189
|
}
|
|
10149
10190
|
#release() {
|
|
10150
10191
|
const active = this.#releasing;
|
|
@@ -10445,12 +10486,14 @@ var BrowserPage = class BrowserPage extends BrowserFrame {
|
|
|
10445
10486
|
}
|
|
10446
10487
|
async #attachWorker(session, id, url, category) {
|
|
10447
10488
|
try {
|
|
10448
|
-
|
|
10489
|
+
const enabling = this.#client.send("Runtime.enable", void 0, { session });
|
|
10490
|
+
if (category === "service_worker") this.#resumeTarget(session);
|
|
10491
|
+
await enabling;
|
|
10449
10492
|
if (this.#closed) {
|
|
10450
10493
|
await this.#detachChild(session, this.#sessionId);
|
|
10451
10494
|
return;
|
|
10452
10495
|
}
|
|
10453
|
-
this.#resumeTarget(session);
|
|
10496
|
+
if (category !== "service_worker") this.#resumeTarget(session);
|
|
10454
10497
|
const worker = new BrowserWorker(this.#client, session, id, url, category);
|
|
10455
10498
|
this.#workers.set(id, worker);
|
|
10456
10499
|
this.#emitter.emit("worker", worker);
|
|
@@ -10787,6 +10830,7 @@ var BrowserPage = class BrowserPage extends BrowserFrame {
|
|
|
10787
10830
|
this.#emitter.emit("navigate", params["url"], true);
|
|
10788
10831
|
}
|
|
10789
10832
|
#handleFrameDetached(session, params) {
|
|
10833
|
+
if (this.#closed) return;
|
|
10790
10834
|
const frame = params["frameId"];
|
|
10791
10835
|
if (!isString(frame) || !this.#accepts(session, frame)) return;
|
|
10792
10836
|
const swapped = params["reason"] === "swap";
|
|
@@ -10887,7 +10931,10 @@ var BrowserPage = class BrowserPage extends BrowserFrame {
|
|
|
10887
10931
|
const session = params["sessionId"];
|
|
10888
10932
|
if (!isRecord(target) || !isString(target["targetId"]) || !isString(session)) return;
|
|
10889
10933
|
const category = target["type"];
|
|
10890
|
-
if (owner !== this.#sessionId && category !== "iframe")
|
|
10934
|
+
if (owner !== this.#sessionId && category !== "iframe") {
|
|
10935
|
+
this.#detachChild(session, owner);
|
|
10936
|
+
return;
|
|
10937
|
+
}
|
|
10891
10938
|
if (category === "worker" || category === "service_worker" || category === "shared_worker") {
|
|
10892
10939
|
this.#attachWorker(session, target["targetId"], isString(target["url"]) ? target["url"] : "", category);
|
|
10893
10940
|
return;
|
|
@@ -11195,6 +11242,7 @@ var BrowserContext = class {
|
|
|
11195
11242
|
#publishing = /* @__PURE__ */ new Map();
|
|
11196
11243
|
#observed = /* @__PURE__ */ new WeakSet();
|
|
11197
11244
|
#shutdown;
|
|
11245
|
+
#disposal;
|
|
11198
11246
|
#reference = 0;
|
|
11199
11247
|
constructor(client, id, viewport, writer, emulation, downloads, options) {
|
|
11200
11248
|
this.#client = client;
|
|
@@ -11219,6 +11267,9 @@ var BrowserContext = class {
|
|
|
11219
11267
|
get id() {
|
|
11220
11268
|
return this.#id;
|
|
11221
11269
|
}
|
|
11270
|
+
get disposal() {
|
|
11271
|
+
return this.#disposal;
|
|
11272
|
+
}
|
|
11222
11273
|
get cookies() {
|
|
11223
11274
|
return this.#cookies;
|
|
11224
11275
|
}
|
|
@@ -11261,14 +11312,14 @@ var BrowserContext = class {
|
|
|
11261
11312
|
destroy() {
|
|
11262
11313
|
const active = this.#shutdown;
|
|
11263
11314
|
if (active !== void 0) return active;
|
|
11264
|
-
const shutdown = this.#destroyResources();
|
|
11315
|
+
const shutdown = Promise.resolve().then(() => this.#destroyResources());
|
|
11265
11316
|
this.#shutdown = shutdown;
|
|
11266
11317
|
return shutdown;
|
|
11267
11318
|
}
|
|
11268
11319
|
close() {
|
|
11269
11320
|
const active = this.#shutdown;
|
|
11270
11321
|
if (active !== void 0) return active;
|
|
11271
|
-
const shutdown = this.#closeResources();
|
|
11322
|
+
const shutdown = Promise.resolve().then(() => this.#closeResources());
|
|
11272
11323
|
this.#shutdown = shutdown;
|
|
11273
11324
|
return shutdown;
|
|
11274
11325
|
}
|
|
@@ -11390,9 +11441,15 @@ var BrowserContext = class {
|
|
|
11390
11441
|
let failure = await settleBrowserTeardown(...[...this.#pages.values()].map((page) => () => page.close()));
|
|
11391
11442
|
this.#pages.clear();
|
|
11392
11443
|
const id = this.#id;
|
|
11393
|
-
if (id !== void 0) {
|
|
11394
|
-
|
|
11395
|
-
|
|
11444
|
+
if (id !== void 0) try {
|
|
11445
|
+
await this.#client.send("Target.disposeBrowserContext", { browserContextId: id });
|
|
11446
|
+
this.#disposal = { confirmed: true };
|
|
11447
|
+
} catch (error) {
|
|
11448
|
+
this.#disposal = {
|
|
11449
|
+
confirmed: false,
|
|
11450
|
+
error
|
|
11451
|
+
};
|
|
11452
|
+
failure ??= error;
|
|
11396
11453
|
}
|
|
11397
11454
|
if (failure !== void 0) throw failure;
|
|
11398
11455
|
} finally {
|
|
@@ -12277,13 +12334,13 @@ function createMemoryBrowserRunStore() {
|
|
|
12277
12334
|
//#endregion
|
|
12278
12335
|
//#region src/core/BrowserJourneyToolset.ts
|
|
12279
12336
|
/**
|
|
12280
|
-
* Registers the journey tools `record`, `save`, `journeys`, `edit`, `replay`, and `
|
|
12337
|
+
* Registers the journey tools `record`, `save`, `journeys`, `edit`, `replay`, `forget`, and `capture` over a toolset
|
|
12281
12338
|
* and owns the recording and the active replay.
|
|
12282
12339
|
*
|
|
12283
12340
|
* @remarks
|
|
12284
12341
|
* The journey toolset composes the toolset's public members: `perform` reads the view a receipt
|
|
12285
12342
|
* carries through `look`, `hold` and `emitter` drive the recorder and the replay, `view` converts
|
|
12286
|
-
* an edit's `ref` to a target, and `tools` receives the
|
|
12343
|
+
* an edit's `ref` to a target, and `tools` receives the journey tools at construction, which refuses
|
|
12287
12344
|
* with `BROWSER_TOOLSET_RESERVED` when the manager already holds one of the names. Every refusal
|
|
12288
12345
|
* is a sentence that names the next call, and a reason inside it is a clause without a directive
|
|
12289
12346
|
* or a final period.
|
|
@@ -12299,7 +12356,7 @@ function createMemoryBrowserRunStore() {
|
|
|
12299
12356
|
* by the view after the run.
|
|
12300
12357
|
*
|
|
12301
12358
|
* `destroy()` aborts the active replay and waits for it to finish, stops a recording without
|
|
12302
|
-
* saving it, and removes the
|
|
12359
|
+
* saving it, and removes the journey tools the manager still holds under the instances it added.
|
|
12303
12360
|
*
|
|
12304
12361
|
* @example
|
|
12305
12362
|
* ```ts
|
|
@@ -12340,7 +12397,8 @@ var BrowserJourneyToolset = class {
|
|
|
12340
12397
|
this.#create("journeys", this.#journeys.bind(this)),
|
|
12341
12398
|
this.#create("edit", this.#edit.bind(this)),
|
|
12342
12399
|
this.#create("replay", this.#replayJourney.bind(this)),
|
|
12343
|
-
this.#create("forget", this.#forget.bind(this))
|
|
12400
|
+
this.#create("forget", this.#forget.bind(this)),
|
|
12401
|
+
this.#create("capture", this.#capture.bind(this))
|
|
12344
12402
|
]);
|
|
12345
12403
|
toolset.tools.add(this.#tools);
|
|
12346
12404
|
}
|
|
@@ -12367,6 +12425,22 @@ var BrowserJourneyToolset = class {
|
|
|
12367
12425
|
signal.throwIfAborted();
|
|
12368
12426
|
return handler(args, signal);
|
|
12369
12427
|
}
|
|
12428
|
+
async #capture(args, signal) {
|
|
12429
|
+
const full = args["full"];
|
|
12430
|
+
if (!isBoolean(full)) throw new BrowserError("The full parameter must be true or false.", "BROWSER_TOOLSET_ARGUMENT");
|
|
12431
|
+
this.#idleReplay();
|
|
12432
|
+
const view = this.#toolset.view;
|
|
12433
|
+
if (!view.trusted) throw new BrowserError("This view is untrusted; capture requires a trusted browser view.", "BROWSER_CAPTURE_UNTRUSTED");
|
|
12434
|
+
if (view.screenshot === void 0) throw new BrowserError("This view cannot capture an image.", "BROWSER_CAPTURE_UNAVAILABLE");
|
|
12435
|
+
const runs = this.#runs;
|
|
12436
|
+
if (runs?.snapshot === void 0) throw new BrowserError("Capture requires a runs store with standalone file storage.", "BROWSER_CAPTURE_UNAVAILABLE");
|
|
12437
|
+
const screenshot = await view.screenshot({
|
|
12438
|
+
format: "png",
|
|
12439
|
+
full
|
|
12440
|
+
});
|
|
12441
|
+
signal.throwIfAborted();
|
|
12442
|
+
return runs.snapshot(screenshot.bytes, { signal });
|
|
12443
|
+
}
|
|
12370
12444
|
async #record(args, signal) {
|
|
12371
12445
|
if (this.#readonly) throw new BrowserError(BROWSER_JOURNEY_READONLY_REFUSAL, "BROWSER_JOURNEY_READONLY");
|
|
12372
12446
|
this.#idleReplay();
|