@vforsh/argus-watcher 0.5.3 → 0.5.5

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.
Files changed (70) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/cdp/ffmpeg.d.ts +22 -6
  3. package/dist/cdp/ffmpeg.d.ts.map +1 -1
  4. package/dist/cdp/ffmpeg.js +90 -30
  5. package/dist/cdp/ffmpeg.js.map +1 -1
  6. package/dist/cdp/navigation.d.ts +82 -0
  7. package/dist/cdp/navigation.d.ts.map +1 -0
  8. package/dist/cdp/navigation.js +186 -0
  9. package/dist/cdp/navigation.js.map +1 -0
  10. package/dist/cdp/protocol.d.ts +24 -0
  11. package/dist/cdp/protocol.d.ts.map +1 -1
  12. package/dist/cdp/recording.d.ts +3 -1
  13. package/dist/cdp/recording.d.ts.map +1 -1
  14. package/dist/cdp/recording.js +237 -132
  15. package/dist/cdp/recording.js.map +1 -1
  16. package/dist/cdp/recordingSession.d.ts +97 -0
  17. package/dist/cdp/recordingSession.d.ts.map +1 -0
  18. package/dist/cdp/recordingSession.js +157 -0
  19. package/dist/cdp/recordingSession.js.map +1 -0
  20. package/dist/cdp/scenarioBridge.d.ts +2 -0
  21. package/dist/cdp/scenarioBridge.d.ts.map +1 -1
  22. package/dist/cdp/scenarioBridge.js +49 -3
  23. package/dist/cdp/scenarioBridge.js.map +1 -1
  24. package/dist/cdp/screenshot.d.ts.map +1 -1
  25. package/dist/cdp/screenshot.js +3 -2
  26. package/dist/cdp/screenshot.js.map +1 -1
  27. package/dist/cdp/visualCapture.d.ts +20 -0
  28. package/dist/cdp/visualCapture.d.ts.map +1 -1
  29. package/dist/cdp/visualCapture.js +53 -42
  30. package/dist/cdp/visualCapture.js.map +1 -1
  31. package/dist/cdp/watcher.d.ts.map +1 -1
  32. package/dist/cdp/watcher.js +55 -1
  33. package/dist/cdp/watcher.js.map +1 -1
  34. package/dist/http/endpoints.d.ts +1 -1
  35. package/dist/http/endpoints.d.ts.map +1 -1
  36. package/dist/http/endpoints.js +3 -0
  37. package/dist/http/endpoints.js.map +1 -1
  38. package/dist/http/routes/getStatus.js +1 -0
  39. package/dist/http/routes/getStatus.js.map +1 -1
  40. package/dist/http/routes/index.d.ts.map +1 -1
  41. package/dist/http/routes/index.js +4 -0
  42. package/dist/http/routes/index.js.map +1 -1
  43. package/dist/http/routes/postDomClick.d.ts.map +1 -1
  44. package/dist/http/routes/postDomClick.js +15 -9
  45. package/dist/http/routes/postDomClick.js.map +1 -1
  46. package/dist/http/routes/postDomKeydown.d.ts.map +1 -1
  47. package/dist/http/routes/postDomKeydown.js +4 -2
  48. package/dist/http/routes/postDomKeydown.js.map +1 -1
  49. package/dist/http/routes/postEval.d.ts.map +1 -1
  50. package/dist/http/routes/postEval.js +1 -0
  51. package/dist/http/routes/postEval.js.map +1 -1
  52. package/dist/http/routes/postNavigate.d.ts +12 -0
  53. package/dist/http/routes/postNavigate.d.ts.map +1 -0
  54. package/dist/http/routes/postNavigate.js +51 -0
  55. package/dist/http/routes/postNavigate.js.map +1 -0
  56. package/dist/http/routes/postNavigateHistory.d.ts +9 -0
  57. package/dist/http/routes/postNavigateHistory.d.ts.map +1 -0
  58. package/dist/http/routes/postNavigateHistory.js +35 -0
  59. package/dist/http/routes/postNavigateHistory.js.map +1 -0
  60. package/dist/http/routes/postRecord.d.ts.map +1 -1
  61. package/dist/http/routes/postRecord.js +9 -0
  62. package/dist/http/routes/postRecord.js.map +1 -1
  63. package/dist/internal.d.ts +1 -0
  64. package/dist/internal.d.ts.map +1 -1
  65. package/dist/internal.js +1 -0
  66. package/dist/internal.js.map +1 -1
  67. package/dist/sources/extension-session-events.d.ts.map +1 -1
  68. package/dist/sources/extension-session-events.js +21 -0
  69. package/dist/sources/extension-session-events.js.map +1 -1
  70. package/package.json +1 -1
@@ -4,16 +4,19 @@ import type { RecordFormat } from '@vforsh/argus-core';
4
4
  import type { VisualCaptureClip, VisualCaptureViewport } from './visualCapture.js';
5
5
  /**
6
6
  * The ffmpeg side of screen recording: spawning the encoder, building its arguments, and reading
7
- * the PNG frame headers that size its filter graph.
7
+ * the frame headers that size its filter graph.
8
8
  *
9
9
  * Split out of `recording.ts` because none of it touches CDP — the recorder pipes frames into a
10
10
  * child process, and that process's argument construction, stderr ring, and ENOENT phrasing are a
11
11
  * separate concern from screencast frame pacing.
12
12
  */
13
- /** Dimensions read from a PNG screencast frame. */
14
- export type PngSize = {
13
+ /** Wire format of the screencast frames piped into ffmpeg. */
14
+ export type FrameCodec = 'png' | 'jpeg';
15
+ /** Dimensions and encoding read from a screencast frame. */
16
+ export type FrameInfo = {
15
17
  width: number;
16
18
  height: number;
19
+ codec: FrameCodec;
17
20
  };
18
21
  type FfmpegChild = ChildProcessByStdio<Writable, null, Readable>;
19
22
  /** A running ffmpeg encoder and a promise for its exit. */
@@ -22,16 +25,29 @@ export type FfmpegProcess = {
22
25
  /** Resolves on a clean exit; rejects with the tail of stderr otherwise. */
23
26
  completion: Promise<void>;
24
27
  };
25
- /** Spawn ffmpeg to encode a PNG frame stream, resolving once the child has actually spawned. */
28
+ /** Spawn ffmpeg to encode a screencast frame stream, resolving once the child has actually spawned. */
26
29
  export declare const startFfmpeg: (options: {
27
30
  absolutePath: string;
28
31
  fps: number;
29
32
  format: RecordFormat;
30
33
  clip: VisualCaptureClip | undefined;
31
34
  viewport: VisualCaptureViewport | undefined;
32
- frameSize: PngSize;
35
+ frame: FrameInfo;
33
36
  }) => Promise<FfmpegProcess>;
34
- export declare const readPngSize: (buffer: Buffer) => PngSize;
37
+ /**
38
+ * Read the encoding and pixel dimensions of a screencast frame.
39
+ *
40
+ * The codec is *detected*, never assumed from the `Page.startScreencast` request: ffmpeg is told
41
+ * up front which decoder sits on the pipe, and if that disagrees with the bytes it gets, every
42
+ * frame fails to decode and the encode dies with an empty file. Chrome is not the only producer
43
+ * here — test fakes and future capture paths feed this too — so the frames are the authority.
44
+ *
45
+ * The size matters because a CSS-pixel crop rectangle has to be translated into encoder
46
+ * coordinates, and the screencast reports no device pixel ratio worth trusting across DPR changes.
47
+ *
48
+ * @throws {Error} When the buffer is not a recognizable PNG or JPEG.
49
+ */
50
+ export declare const readFrameInfo: (buffer: Buffer) => FrameInfo;
35
51
  export declare const formatFfmpegError: (error: unknown) => Error;
36
52
  export {};
37
53
  //# sourceMappingURL=ffmpeg.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ffmpeg.d.ts","sourceRoot":"","sources":["../../src/cdp/ffmpeg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAElF;;;;;;;GAOG;AAEH,mDAAmD;AACnD,MAAM,MAAM,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD,KAAK,WAAW,GAAG,mBAAmB,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;AAEhE,2DAA2D;AAC3D,MAAM,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,WAAW,CAAA;IAClB,2EAA2E;IAC3E,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB,CAAA;AAED,gGAAgG;AAChG,eAAO,MAAM,WAAW,GAAU,SAAS;IAC1C,YAAY,EAAE,MAAM,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,YAAY,CAAA;IACpB,IAAI,EAAE,iBAAiB,GAAG,SAAS,CAAA;IACnC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,CAAA;IAC3C,SAAS,EAAE,OAAO,CAAA;CAClB,KAAG,OAAO,CAAC,aAAa,CA+CxB,CAAA;AAgCD,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,KAAG,OAmB5C,CAAA;AAOD,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,KAMlD,CAAA"}
1
+ {"version":3,"file":"ffmpeg.d.ts","sourceRoot":"","sources":["../../src/cdp/ffmpeg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAElF;;;;;;;GAOG;AAEH,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,CAAA;AAEvC,4DAA4D;AAC5D,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAA;AAE5E,KAAK,WAAW,GAAG,mBAAmB,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;AAEhE,2DAA2D;AAC3D,MAAM,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,WAAW,CAAA;IAClB,2EAA2E;IAC3E,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB,CAAA;AAED,uGAAuG;AACvG,eAAO,MAAM,WAAW,GAAU,SAAS;IAC1C,YAAY,EAAE,MAAM,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,YAAY,CAAA;IACpB,IAAI,EAAE,iBAAiB,GAAG,SAAS,CAAA;IACnC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,CAAA;IAC3C,KAAK,EAAE,SAAS,CAAA;CAChB,KAAG,OAAO,CAAC,aAAa,CA8CxB,CAAA;AAqDD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,KAAG,SAW9C,CAAA;AAsDD,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,KAMlD,CAAA"}
@@ -1,8 +1,7 @@
1
1
  import { spawn } from 'node:child_process';
2
- /** Spawn ffmpeg to encode a PNG frame stream, resolving once the child has actually spawned. */
2
+ /** Spawn ffmpeg to encode a screencast frame stream, resolving once the child has actually spawned. */
3
3
  export const startFfmpeg = async (options) => {
4
4
  const ffmpeg = process.env.ARGUS_FFMPEG?.trim() || 'ffmpeg';
5
- const filter = buildVideoFilter(options);
6
5
  const args = [
7
6
  '-hide_banner',
8
7
  '-loglevel',
@@ -12,12 +11,12 @@ export const startFfmpeg = async (options) => {
12
11
  '-framerate',
13
12
  String(options.fps),
14
13
  '-vcodec',
15
- 'png',
14
+ options.frame.codec === 'jpeg' ? 'mjpeg' : 'png',
16
15
  '-i',
17
16
  'pipe:0',
18
17
  '-an',
19
18
  '-vf',
20
- filter,
19
+ buildVideoFilter(options),
21
20
  ...buildEncoderArgs(options.format),
22
21
  '-y',
23
22
  options.absolutePath,
@@ -46,43 +45,104 @@ export const startFfmpeg = async (options) => {
46
45
  return { child, completion };
47
46
  };
48
47
  const buildVideoFilter = (options) => {
49
- if (!options.clip) {
50
- return 'scale=trunc(iw/2)*2:trunc(ih/2)*2,format=yuv420p';
48
+ const geometry = options.clip ? buildCropFilter(options.clip, options.viewport, options.frame) : 'scale=trunc(iw/2)*2:trunc(ih/2)*2';
49
+ if (options.format !== 'gif') {
50
+ return `${geometry},format=yuv420p`;
51
51
  }
52
- if (!options.viewport) {
52
+ /**
53
+ * One-pass palette generation, because the frames arrive on a pipe.
54
+ *
55
+ * The usual high-quality GIF recipe runs `palettegen` over the whole file and only then
56
+ * `paletteuse`, which needs two passes over a seekable input. A live screencast has neither,
57
+ * so this builds a palette per frame (`stats_mode=single`) and tells `paletteuse` to expect a
58
+ * new one each time (`new=1`). Slightly larger files than a global palette, no second pass,
59
+ * and no banding on the gradients that make up most app UI.
60
+ */
61
+ return `${geometry},split[gifsrc][gifpal];[gifpal]palettegen=stats_mode=single[pal];[gifsrc][pal]paletteuse=new=1:dither=sierra2_4a`;
62
+ };
63
+ const buildCropFilter = (clip, viewport, frameSize) => {
64
+ if (!viewport) {
53
65
  throw new Error('Unable to compute viewport size for recording crop');
54
66
  }
55
- const ratioX = options.frameSize.width / options.viewport.width;
56
- const ratioY = options.frameSize.height / options.viewport.height;
57
- const x = clampEven(options.clip.x * ratioX, 0, options.frameSize.width - 2);
58
- const y = clampEven(options.clip.y * ratioY, 0, options.frameSize.height - 2);
59
- const width = clampEven(options.clip.width * ratioX, 2, options.frameSize.width - x);
60
- const height = clampEven(options.clip.height * ratioY, 2, options.frameSize.height - y);
61
- return `crop=${width}:${height}:${x}:${y},format=yuv420p`;
67
+ const ratioX = frameSize.width / viewport.width;
68
+ const ratioY = frameSize.height / viewport.height;
69
+ const x = clampEven(clip.x * ratioX, 0, frameSize.width - 2);
70
+ const y = clampEven(clip.y * ratioY, 0, frameSize.height - 2);
71
+ const width = clampEven(clip.width * ratioX, 2, frameSize.width - x);
72
+ const height = clampEven(clip.height * ratioY, 2, frameSize.height - y);
73
+ return `crop=${width}:${height}:${x}:${y}`;
62
74
  };
63
75
  const buildEncoderArgs = (format) => {
76
+ if (format === 'gif') {
77
+ return ['-loop', '0', '-f', 'gif'];
78
+ }
64
79
  if (format === 'webm') {
65
- return ['-c:v', 'libvpx', '-deadline', 'realtime', '-cpu-used', '5', '-b:v', '1M', '-f', 'webm'];
80
+ // VP9 at constant quality: the old flat 1M VP8 bitrate smeared any 2x-DPR canvas.
81
+ return ['-c:v', 'libvpx-vp9', '-deadline', 'realtime', '-cpu-used', '5', '-crf', '32', '-b:v', '0', '-row-mt', '1', '-f', 'webm'];
66
82
  }
67
83
  // yuv420p + H.264 keeps files playable in Finder, QuickTime, iOS Photos, Slack, and browsers.
68
84
  return ['-c:v', 'libx264', '-preset', 'veryfast', '-crf', '23', '-movflags', '+faststart', '-f', 'mp4'];
69
85
  };
70
- export const readPngSize = (buffer) => {
71
- if (buffer.length < 24 ||
72
- buffer[0] !== 0x89 ||
73
- buffer[1] !== 0x50 ||
74
- buffer[2] !== 0x4e ||
75
- buffer[3] !== 0x47 ||
76
- buffer[4] !== 0x0d ||
77
- buffer[5] !== 0x0a ||
78
- buffer[6] !== 0x1a ||
79
- buffer[7] !== 0x0a) {
80
- throw new Error('Expected PNG screencast frame');
86
+ /**
87
+ * Read the encoding and pixel dimensions of a screencast frame.
88
+ *
89
+ * The codec is *detected*, never assumed from the `Page.startScreencast` request: ffmpeg is told
90
+ * up front which decoder sits on the pipe, and if that disagrees with the bytes it gets, every
91
+ * frame fails to decode and the encode dies with an empty file. Chrome is not the only producer
92
+ * here — test fakes and future capture paths feed this too — so the frames are the authority.
93
+ *
94
+ * The size matters because a CSS-pixel crop rectangle has to be translated into encoder
95
+ * coordinates, and the screencast reports no device pixel ratio worth trusting across DPR changes.
96
+ *
97
+ * @throws {Error} When the buffer is not a recognizable PNG or JPEG.
98
+ */
99
+ export const readFrameInfo = (buffer) => {
100
+ if (isPng(buffer)) {
101
+ return { width: buffer.readUInt32BE(16), height: buffer.readUInt32BE(20), codec: 'png' };
102
+ }
103
+ const jpegSize = readJpegSize(buffer);
104
+ if (jpegSize) {
105
+ return { ...jpegSize, codec: 'jpeg' };
106
+ }
107
+ throw new Error('Expected a PNG or JPEG screencast frame');
108
+ };
109
+ const isPng = (buffer) => buffer.length >= 24 &&
110
+ buffer[0] === 0x89 &&
111
+ buffer[1] === 0x50 &&
112
+ buffer[2] === 0x4e &&
113
+ buffer[3] === 0x47 &&
114
+ buffer[4] === 0x0d &&
115
+ buffer[5] === 0x0a &&
116
+ buffer[6] === 0x1a &&
117
+ buffer[7] === 0x0a;
118
+ /** Frame-header markers (SOF0-SOF15) that carry dimensions, minus the four that are not frame headers. */
119
+ const JPEG_NON_SOF_MARKERS = new Set([0xc4, 0xc8, 0xcc]);
120
+ const readJpegSize = (buffer) => {
121
+ if (buffer.length < 4 || buffer[0] !== 0xff || buffer[1] !== 0xd8) {
122
+ return null;
123
+ }
124
+ let offset = 2;
125
+ while (offset + 3 < buffer.length) {
126
+ if (buffer[offset] !== 0xff) {
127
+ offset += 1;
128
+ continue;
129
+ }
130
+ const marker = buffer[offset + 1];
131
+ // Padding fill bytes and the standalone markers carry no length field.
132
+ if (marker === 0xff || marker === 0x01 || (marker >= 0xd0 && marker <= 0xd9)) {
133
+ offset += 2;
134
+ continue;
135
+ }
136
+ const segmentLength = buffer.readUInt16BE(offset + 2);
137
+ if (marker >= 0xc0 && marker <= 0xcf && !JPEG_NON_SOF_MARKERS.has(marker)) {
138
+ if (offset + 9 > buffer.length) {
139
+ return null;
140
+ }
141
+ return { width: buffer.readUInt16BE(offset + 7), height: buffer.readUInt16BE(offset + 5) };
142
+ }
143
+ offset += 2 + segmentLength;
81
144
  }
82
- return {
83
- width: buffer.readUInt32BE(16),
84
- height: buffer.readUInt32BE(20),
85
- };
145
+ return null;
86
146
  };
87
147
  const clampEven = (value, min, max) => {
88
148
  const clamped = Math.min(max, Math.max(min, Math.floor(value)));
@@ -1 +1 @@
1
- {"version":3,"file":"ffmpeg.js","sourceRoot":"","sources":["../../src/cdp/ffmpeg.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ffmpeg.js","sourceRoot":"","sources":["../../src/cdp/ffmpeg.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { type LogEpoch, type NavigationDirection, type NavigationSummary, type NavigationWait, type NavigationWaitOptions } from '@vforsh/argus-core';
2
+ import type { CdpSessionHandle } from './connection.js';
3
+ /**
4
+ * Waiting for a navigation to finish, for every command that causes one.
5
+ *
6
+ * The hard part is not sending `Page.navigate` — it is knowing when the answer is safe to
7
+ * send back. A load event on its own proves nothing: it may belong to the document that was
8
+ * already there when the command was issued. So a wait only counts a `domContentEventFired`
9
+ * or `loadEventFired` that arrives *after* the top-frame `Page.frameNavigated`, and — when
10
+ * Chrome told us which loader it started — for that loader.
11
+ *
12
+ * Handlers are attached before the navigating command is sent, never after, so a fast
13
+ * same-origin load cannot slip through the gap between the send and the subscribe.
14
+ */
15
+ /** A primed navigation wait. Always `dispose()` it, including on the failure path. */
16
+ export type NavigationWaiter = {
17
+ /**
18
+ * Wait for the requested phase, resolving to the URL navigated to, or `null` when nothing
19
+ * navigated (which is what `wait: 'none'` always reports).
20
+ *
21
+ * @param expectedLoaderId Loader id from the navigating command, when it reported one. A load
22
+ * event for a different loader (a redirect chain's earlier hop, a concurrent reload) is ignored.
23
+ * @throws A `navigation_timeout` coded error when the phase does not arrive in time.
24
+ */
25
+ settle: (expectedLoaderId?: string | null) => Promise<string | null>;
26
+ dispose: () => void;
27
+ };
28
+ /** Subscribe to the navigation lifecycle before issuing the command that triggers it. */
29
+ export declare const armNavigationWaiter: (session: CdpSessionHandle, options: {
30
+ wait: NavigationWait;
31
+ timeoutMs: number;
32
+ }) => NavigationWaiter;
33
+ /** Result of a completed `Page.navigate`. */
34
+ export type NavigatePageResult = {
35
+ url: string;
36
+ loaderId: string | null;
37
+ };
38
+ /**
39
+ * Navigate the page and wait for the requested phase.
40
+ *
41
+ * @throws A `navigation_failed` coded error when Chrome refuses the URL (bad host, blocked
42
+ * scheme); `navigation_timeout` when the load does not complete in time. Both are the
43
+ * request's fault or the network's, so they are reported as such rather than as CDP errors.
44
+ */
45
+ export declare const navigatePage: (session: CdpSessionHandle, options: {
46
+ url: string;
47
+ wait: NavigationWait;
48
+ timeoutMs: number;
49
+ }) => Promise<NavigatePageResult>;
50
+ /** Result of a completed history navigation. */
51
+ export type NavigateHistoryResult = {
52
+ url: string;
53
+ index: number;
54
+ length: number;
55
+ };
56
+ /**
57
+ * Move through the session history and wait for the requested phase.
58
+ *
59
+ * @throws A `no_history` coded error when the requested step falls outside the history, which
60
+ * is what "already at the first entry" looks like — not a transport failure.
61
+ */
62
+ export declare const navigateHistory: (session: CdpSessionHandle, options: {
63
+ direction: NavigationDirection;
64
+ steps: number;
65
+ wait: NavigationWait;
66
+ timeoutMs: number;
67
+ }) => Promise<NavigateHistoryResult>;
68
+ /**
69
+ * Run an interaction that may navigate, and report whether it did.
70
+ *
71
+ * A click on a plain button navigates nowhere, and that is the common case — so a timeout here
72
+ * is a `navigated: false` summary, not an error. Only a **top-frame** navigation counts: an
73
+ * iframe that navigates internally reports `navigated: false`.
74
+ *
75
+ * @param beginEpoch Opens a log epoch just before the interaction, so the caller can read the
76
+ * new page's console output without racing it. Only called when a wait was requested.
77
+ */
78
+ export declare const withNavigationWait: <T>(session: CdpSessionHandle, options: NavigationWaitOptions, beginEpoch: () => LogEpoch, act: () => Promise<T>) => Promise<{
79
+ result: T;
80
+ navigation?: NavigationSummary;
81
+ }>;
82
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/cdp/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAGvD;;;;;;;;;;;GAWG;AAEH,sFAAsF;AACtF,MAAM,MAAM,gBAAgB,GAAG;IAC9B;;;;;;;OAOG;IACH,MAAM,EAAE,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACpE,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB,CAAA;AAED,yFAAyF;AACzF,eAAO,MAAM,mBAAmB,GAAI,SAAS,gBAAgB,EAAE,SAAS;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAAG,gBA2FrH,CAAA;AAED,6CAA6C;AAC7C,MAAM,MAAM,kBAAkB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAEzE;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GACxB,SAAS,gBAAgB,EACzB,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAC/D,OAAO,CAAC,kBAAkB,CAc5B,CAAA;AAED,gDAAgD;AAChD,MAAM,MAAM,qBAAqB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAElF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC3B,SAAS,gBAAgB,EACzB,SAAS;IAAE,SAAS,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KACjG,OAAO,CAAC,qBAAqB,CAuB/B,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAAU,CAAC,EACzC,SAAS,gBAAgB,EACzB,SAAS,qBAAqB,EAC9B,YAAY,MAAM,QAAQ,EAC1B,KAAK,MAAM,OAAO,CAAC,CAAC,CAAC,KACnB,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,iBAAiB,CAAA;CAAE,CAiBvD,CAAA"}
@@ -0,0 +1,186 @@
1
+ import { DEFAULT_INTERACTION_NAV_TIMEOUT_MS, } from '@vforsh/argus-core';
2
+ import { codedError, hasErrorCode } from '../errors.js';
3
+ /** Subscribe to the navigation lifecycle before issuing the command that triggers it. */
4
+ export const armNavigationWaiter = (session, options) => {
5
+ let topFrameId = null;
6
+ let navigatedUrl = null;
7
+ let navigatedLoaderId = null;
8
+ let domFired = false;
9
+ let loadFired = false;
10
+ // Set when the navigation completed but no dom/load event will ever follow it: a hash change
11
+ // or pushState (same document), and a back/forward-cache restore (the document is resumed,
12
+ // not parsed). Waiting for `load` in either case would burn the whole timeout on a page that
13
+ // is already there.
14
+ let settledWithoutLoadUrl = null;
15
+ let notify = null;
16
+ // The top frame's id, so a same-document navigation inside an iframe cannot settle the wait.
17
+ // Fire-and-forget: a detached session fails the navigating command with its own error.
18
+ void session
19
+ .sendAndWait('Page.getFrameTree')
20
+ .then((result) => {
21
+ topFrameId = result.frameTree?.frame.id ?? null;
22
+ })
23
+ .catch(() => { });
24
+ const isSettled = (expectedLoaderId) => {
25
+ if (settledWithoutLoadUrl != null)
26
+ return true;
27
+ if (navigatedUrl == null)
28
+ return false;
29
+ if (expectedLoaderId != null && navigatedLoaderId != null && navigatedLoaderId !== expectedLoaderId)
30
+ return false;
31
+ return options.wait === 'domcontentloaded' ? domFired || loadFired : loadFired;
32
+ };
33
+ const removers = [
34
+ // A child target's events carry a sessionId; only the top frame's do not.
35
+ session.onEvent('Page.frameNavigated', (params, meta) => {
36
+ const frame = params.frame;
37
+ if (meta.sessionId || !frame || frame.parentId)
38
+ return;
39
+ topFrameId = frame.id;
40
+ navigatedUrl = frame.url ?? '';
41
+ navigatedLoaderId = frame.loaderId ?? null;
42
+ domFired = false;
43
+ loadFired = false;
44
+ settledWithoutLoadUrl = params.type === 'BackForwardCacheRestore' ? navigatedUrl : null;
45
+ notify?.();
46
+ }),
47
+ session.onEvent('Page.domContentEventFired', (_params, meta) => {
48
+ if (meta.sessionId)
49
+ return;
50
+ domFired = true;
51
+ notify?.();
52
+ }),
53
+ session.onEvent('Page.loadEventFired', (_params, meta) => {
54
+ if (meta.sessionId)
55
+ return;
56
+ loadFired = true;
57
+ notify?.();
58
+ }),
59
+ session.onEvent('Page.navigatedWithinDocument', (params, meta) => {
60
+ if (meta.sessionId || !params.url)
61
+ return;
62
+ if (topFrameId != null && params.frameId !== topFrameId)
63
+ return;
64
+ settledWithoutLoadUrl = params.url;
65
+ notify?.();
66
+ }),
67
+ ];
68
+ let timer = null;
69
+ const dispose = () => {
70
+ for (const remove of removers)
71
+ remove();
72
+ if (timer)
73
+ clearTimeout(timer);
74
+ timer = null;
75
+ notify = null;
76
+ };
77
+ const settle = async (expectedLoaderId = null) => {
78
+ if (options.wait === 'none') {
79
+ return null;
80
+ }
81
+ if (!isSettled(expectedLoaderId)) {
82
+ await new Promise((resolve, reject) => {
83
+ notify = () => {
84
+ if (!isSettled(expectedLoaderId))
85
+ return;
86
+ notify = null;
87
+ resolve();
88
+ };
89
+ timer = setTimeout(() => {
90
+ notify = null;
91
+ reject(codedError('navigation_timeout', `Navigation did not reach "${options.wait}" within ${options.timeoutMs}ms.`));
92
+ }, options.timeoutMs);
93
+ });
94
+ }
95
+ return settledWithoutLoadUrl ?? navigatedUrl;
96
+ };
97
+ return { settle, dispose };
98
+ };
99
+ /**
100
+ * Navigate the page and wait for the requested phase.
101
+ *
102
+ * @throws A `navigation_failed` coded error when Chrome refuses the URL (bad host, blocked
103
+ * scheme); `navigation_timeout` when the load does not complete in time. Both are the
104
+ * request's fault or the network's, so they are reported as such rather than as CDP errors.
105
+ */
106
+ export const navigatePage = async (session, options) => {
107
+ const waiter = armNavigationWaiter(session, options);
108
+ try {
109
+ const result = await session.sendAndWait('Page.navigate', { url: options.url });
110
+ if (result.errorText) {
111
+ throw codedError('navigation_failed', `Navigation to ${options.url} failed: ${result.errorText}`);
112
+ }
113
+ const loaderId = result.loaderId ?? null;
114
+ const settledUrl = await waiter.settle(loaderId);
115
+ return { url: settledUrl ?? options.url, loaderId };
116
+ }
117
+ finally {
118
+ waiter.dispose();
119
+ }
120
+ };
121
+ /**
122
+ * Move through the session history and wait for the requested phase.
123
+ *
124
+ * @throws A `no_history` coded error when the requested step falls outside the history, which
125
+ * is what "already at the first entry" looks like — not a transport failure.
126
+ */
127
+ export const navigateHistory = async (session, options) => {
128
+ const history = await session.sendAndWait('Page.getNavigationHistory');
129
+ const entries = history.entries ?? [];
130
+ const currentIndex = history.currentIndex ?? 0;
131
+ const targetIndex = currentIndex + (options.direction === 'back' ? -options.steps : options.steps);
132
+ const entry = entries[targetIndex];
133
+ if (!entry) {
134
+ const step = options.steps === 1 ? '' : ` ${options.steps} entries`;
135
+ throw codedError('no_history', `Cannot go ${options.direction}${step}: at entry ${currentIndex + 1} of ${entries.length} in the session history.`);
136
+ }
137
+ const waiter = armNavigationWaiter(session, options);
138
+ try {
139
+ await session.sendAndWait('Page.navigateToHistoryEntry', { entryId: entry.id });
140
+ const settledUrl = await waiter.settle();
141
+ return { url: settledUrl ?? entry.url, index: targetIndex, length: entries.length };
142
+ }
143
+ finally {
144
+ waiter.dispose();
145
+ }
146
+ };
147
+ /**
148
+ * Run an interaction that may navigate, and report whether it did.
149
+ *
150
+ * A click on a plain button navigates nowhere, and that is the common case — so a timeout here
151
+ * is a `navigated: false` summary, not an error. Only a **top-frame** navigation counts: an
152
+ * iframe that navigates internally reports `navigated: false`.
153
+ *
154
+ * @param beginEpoch Opens a log epoch just before the interaction, so the caller can read the
155
+ * new page's console output without racing it. Only called when a wait was requested.
156
+ */
157
+ export const withNavigationWait = async (session, options, beginEpoch, act) => {
158
+ if (!options.waitNav) {
159
+ return { result: await act() };
160
+ }
161
+ const epoch = beginEpoch();
162
+ const waiter = armNavigationWaiter(session, {
163
+ wait: options.waitNav,
164
+ timeoutMs: options.navTimeoutMs ?? DEFAULT_INTERACTION_NAV_TIMEOUT_MS,
165
+ });
166
+ try {
167
+ const result = await act();
168
+ return { result, navigation: await summarizeNavigation(waiter, epoch) };
169
+ }
170
+ finally {
171
+ waiter.dispose();
172
+ }
173
+ };
174
+ /** Settle a `--wait-nav` waiter, turning its timeout into a "nothing navigated" summary. */
175
+ const summarizeNavigation = async (waiter, epoch) => {
176
+ try {
177
+ const url = await waiter.settle();
178
+ return { navigated: url != null, url, epoch };
179
+ }
180
+ catch (error) {
181
+ if (!hasErrorCode(error, 'navigation_timeout'))
182
+ throw error;
183
+ return { navigated: false, url: null, epoch };
184
+ }
185
+ };
186
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/cdp/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,kCAAkC,GAMlC,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AA6BvD,yFAAyF;AACzF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAyB,EAAE,OAAoD,EAAoB,EAAE;IACxI,IAAI,UAAU,GAAkB,IAAI,CAAA;IACpC,IAAI,YAAY,GAAkB,IAAI,CAAA;IACtC,IAAI,iBAAiB,GAAkB,IAAI,CAAA;IAC3C,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,6FAA6F;IAC7F,2FAA2F;IAC3F,6FAA6F;IAC7F,oBAAoB;IACpB,IAAI,qBAAqB,GAAkB,IAAI,CAAA;IAC/C,IAAI,MAAM,GAAwB,IAAI,CAAA;IAEtC,6FAA6F;IAC7F,uFAAuF;IACvF,KAAK,OAAO;SACV,WAAW,CAAC,mBAAmB,CAAC;SAChC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QAChB,UAAU,GAAG,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,IAAI,IAAI,CAAA;IAChD,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAEjB,MAAM,SAAS,GAAG,CAAC,gBAA+B,EAAW,EAAE;QAC9D,IAAI,qBAAqB,IAAI,IAAI;YAAE,OAAO,IAAI,CAAA;QAC9C,IAAI,YAAY,IAAI,IAAI;YAAE,OAAO,KAAK,CAAA;QACtC,IAAI,gBAAgB,IAAI,IAAI,IAAI,iBAAiB,IAAI,IAAI,IAAI,iBAAiB,KAAK,gBAAgB;YAAE,OAAO,KAAK,CAAA;QACjH,OAAO,OAAO,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAC/E,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG;QAChB,0EAA0E;QAC1E,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;YACvD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;YAC1B,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ;gBAAE,OAAM;YACtD,UAAU,GAAG,KAAK,CAAC,EAAE,CAAA;YACrB,YAAY,GAAG,KAAK,CAAC,GAAG,IAAI,EAAE,CAAA;YAC9B,iBAAiB,GAAG,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAA;YAC1C,QAAQ,GAAG,KAAK,CAAA;YAChB,SAAS,GAAG,KAAK,CAAA;YACjB,qBAAqB,GAAG,MAAM,CAAC,IAAI,KAAK,yBAAyB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAA;YACvF,MAAM,EAAE,EAAE,CAAA;QACX,CAAC,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,2BAA2B,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;YAC9D,IAAI,IAAI,CAAC,SAAS;gBAAE,OAAM;YAC1B,QAAQ,GAAG,IAAI,CAAA;YACf,MAAM,EAAE,EAAE,CAAA;QACX,CAAC,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;YACxD,IAAI,IAAI,CAAC,SAAS;gBAAE,OAAM;YAC1B,SAAS,GAAG,IAAI,CAAA;YAChB,MAAM,EAAE,EAAE,CAAA;QACX,CAAC,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,8BAA8B,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;YAChE,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,GAAG;gBAAE,OAAM;YACzC,IAAI,UAAU,IAAI,IAAI,IAAI,MAAM,CAAC,OAAO,KAAK,UAAU;gBAAE,OAAM;YAC/D,qBAAqB,GAAG,MAAM,CAAC,GAAG,CAAA;YAClC,MAAM,EAAE,EAAE,CAAA;QACX,CAAC,CAAC;KACF,CAAA;IAED,IAAI,KAAK,GAA0B,IAAI,CAAA;IACvC,MAAM,OAAO,GAAG,GAAS,EAAE;QAC1B,KAAK,MAAM,MAAM,IAAI,QAAQ;YAAE,MAAM,EAAE,CAAA;QACvC,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAA;QAC9B,KAAK,GAAG,IAAI,CAAA;QACZ,MAAM,GAAG,IAAI,CAAA;IACd,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,KAAK,EAAE,mBAAkC,IAAI,EAA0B,EAAE;QACvF,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAA;QACZ,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,MAAM,GAAG,GAAG,EAAE;oBACb,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;wBAAE,OAAM;oBACxC,MAAM,GAAG,IAAI,CAAA;oBACb,OAAO,EAAE,CAAA;gBACV,CAAC,CAAA;gBACD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvB,MAAM,GAAG,IAAI,CAAA;oBACb,MAAM,CAAC,UAAU,CAAC,oBAAoB,EAAE,6BAA6B,OAAO,CAAC,IAAI,YAAY,OAAO,CAAC,SAAS,KAAK,CAAC,CAAC,CAAA;gBACtH,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;YACtB,CAAC,CAAC,CAAA;QACH,CAAC;QAED,OAAO,qBAAqB,IAAI,YAAY,CAAA;IAC7C,CAAC,CAAA;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;AAC3B,CAAC,CAAA;AAKD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAChC,OAAyB,EACzB,OAAiE,EACnC,EAAE;IAChC,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACpD,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAC/E,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,UAAU,CAAC,mBAAmB,EAAE,iBAAiB,OAAO,CAAC,GAAG,YAAY,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;QAClG,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAA;QACxC,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAChD,OAAO,EAAE,GAAG,EAAE,UAAU,IAAI,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAA;IACpD,CAAC;YAAS,CAAC;QACV,MAAM,CAAC,OAAO,EAAE,CAAA;IACjB,CAAC;AACF,CAAC,CAAA;AAKD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EACnC,OAAyB,EACzB,OAAmG,EAClE,EAAE;IACnC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAA;IACtE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAA;IACrC,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,CAAA;IAE9C,MAAM,WAAW,GAAG,YAAY,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAClG,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,UAAU,CAAA;QACnE,MAAM,UAAU,CACf,YAAY,EACZ,aAAa,OAAO,CAAC,SAAS,GAAG,IAAI,cAAc,YAAY,GAAG,CAAC,OAAO,OAAO,CAAC,MAAM,0BAA0B,CAClH,CAAA;IACF,CAAC;IAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACpD,IAAI,CAAC;QACJ,MAAM,OAAO,CAAC,WAAW,CAAC,6BAA6B,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;QAC/E,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAA;QACxC,OAAO,EAAE,GAAG,EAAE,UAAU,IAAI,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAA;IACpF,CAAC;YAAS,CAAC;QACV,MAAM,CAAC,OAAO,EAAE,CAAA;IACjB,CAAC;AACF,CAAC,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACtC,OAAyB,EACzB,OAA8B,EAC9B,UAA0B,EAC1B,GAAqB,EACoC,EAAE;IAC3D,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACtB,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,EAAE,EAAE,CAAA;IAC/B,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,EAAE,CAAA;IAC1B,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,EAAE;QAC3C,IAAI,EAAE,OAAO,CAAC,OAAO;QACrB,SAAS,EAAE,OAAO,CAAC,YAAY,IAAI,kCAAkC;KACrE,CAAC,CAAA;IAEF,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE,CAAA;QAC1B,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAA;IACxE,CAAC;YAAS,CAAC;QACV,MAAM,CAAC,OAAO,EAAE,CAAA;IACjB,CAAC;AACF,CAAC,CAAA;AAED,4FAA4F;AAC5F,MAAM,mBAAmB,GAAG,KAAK,EAAE,MAAwB,EAAE,KAAe,EAA8B,EAAE;IAC3G,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAA;QACjC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,oBAAoB,CAAC;YAAE,MAAM,KAAK,CAAA;QAC3D,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IAC9C,CAAC;AACF,CAAC,CAAA"}
@@ -64,6 +64,15 @@ export type CdpFrame = {
64
64
  parentId?: string;
65
65
  url?: string;
66
66
  name?: string;
67
+ /** Identifies the navigation that produced this frame state. Used to match load events to a navigation. */
68
+ loaderId?: string;
69
+ };
70
+ /** One entry in the `Page.getNavigationHistory` response. */
71
+ export type CdpNavigationHistoryEntry = {
72
+ id: number;
73
+ url: string;
74
+ title: string;
75
+ transitionType?: string;
67
76
  };
68
77
  /** A node in the `Page.getFrameTree` response. */
69
78
  export type CdpFrameTreeNode = {
@@ -369,6 +378,10 @@ export type CdpCommandMap = {
369
378
  cssVisualViewport?: CdpVisualViewport;
370
379
  visualViewport?: CdpVisualViewport;
371
380
  }>;
381
+ 'Page.getNavigationHistory': Command<NoParams, {
382
+ currentIndex?: number;
383
+ entries?: CdpNavigationHistoryEntry[];
384
+ }>;
372
385
  'Page.handleJavaScriptDialog': Command<{
373
386
  accept: boolean;
374
387
  promptText?: string;
@@ -381,6 +394,9 @@ export type CdpCommandMap = {
381
394
  loaderId?: string;
382
395
  errorText?: string;
383
396
  }>;
397
+ 'Page.navigateToHistoryEntry': Command<{
398
+ entryId: number;
399
+ }, unknown>;
384
400
  'Page.reload': Command<{
385
401
  ignoreCache?: boolean;
386
402
  scriptToEvaluateOnLoad?: string;
@@ -547,11 +563,19 @@ export type CdpEventMap = {
547
563
  };
548
564
  'Page.frameNavigated': {
549
565
  frame?: CdpFrame;
566
+ type?: 'Navigation' | 'BackForwardCacheRestore';
550
567
  };
551
568
  'Page.javascriptDialogClosed': {
552
569
  result?: boolean;
553
570
  userInput?: string;
554
571
  };
572
+ 'Page.loadEventFired': {
573
+ timestamp?: number;
574
+ };
575
+ 'Page.navigatedWithinDocument': {
576
+ frameId?: string;
577
+ url?: string;
578
+ };
555
579
  'Page.javascriptDialogOpening': {
556
580
  url?: string;
557
581
  message?: string;