@rehearsal-labs/retest 0.2.0 → 0.3.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.
Files changed (218) hide show
  1. package/README.md +6 -5
  2. package/dist/api/source-location.d.ts.map +1 -1
  3. package/dist/api/source-location.js +3 -1
  4. package/dist/browser/builds.d.ts +35 -6
  5. package/dist/browser/builds.d.ts.map +1 -1
  6. package/dist/browser/builds.js +115 -16
  7. package/dist/browser/cdp/transport.d.ts.map +1 -1
  8. package/dist/browser/cdp/transport.js +4 -4
  9. package/dist/browser/chromium-process.d.ts +23 -0
  10. package/dist/browser/chromium-process.d.ts.map +1 -1
  11. package/dist/browser/chromium-process.js +78 -13
  12. package/dist/browser/electron.d.ts +1 -1
  13. package/dist/browser/electron.d.ts.map +1 -1
  14. package/dist/browser/electron.js +6 -3
  15. package/dist/browser/executables.d.ts +16 -1
  16. package/dist/browser/executables.d.ts.map +1 -1
  17. package/dist/browser/executables.js +50 -18
  18. package/dist/browser/firefox/accessible-names.d.ts +5 -4
  19. package/dist/browser/firefox/accessible-names.d.ts.map +1 -1
  20. package/dist/browser/firefox/accessible-names.js +11 -6
  21. package/dist/browser/firefox/bridge.js +3 -2
  22. package/dist/browser/firefox/executable.d.ts +14 -14
  23. package/dist/browser/firefox/executable.d.ts.map +1 -1
  24. package/dist/browser/firefox/executable.js +29 -21
  25. package/dist/browser/firefox/launch.js +1 -1
  26. package/dist/browser/firefox/navigation.d.ts +5 -2
  27. package/dist/browser/firefox/navigation.d.ts.map +1 -1
  28. package/dist/browser/firefox/navigation.js +48 -14
  29. package/dist/browser/firefox/orphans.d.ts.map +1 -1
  30. package/dist/browser/firefox/orphans.js +34 -2
  31. package/dist/browser/firefox/page.d.ts.map +1 -1
  32. package/dist/browser/firefox/page.js +113 -19
  33. package/dist/browser/firefox/process.d.ts +20 -1
  34. package/dist/browser/firefox/process.d.ts.map +1 -1
  35. package/dist/browser/firefox/process.js +124 -22
  36. package/dist/browser/firefox/profile.d.ts +5 -0
  37. package/dist/browser/firefox/profile.d.ts.map +1 -1
  38. package/dist/browser/firefox/profile.js +17 -1
  39. package/dist/browser/firefox/storage.d.ts.map +1 -1
  40. package/dist/browser/firefox/storage.js +4 -2
  41. package/dist/browser/firefox/subscriptions.d.ts +26 -0
  42. package/dist/browser/firefox/subscriptions.d.ts.map +1 -0
  43. package/dist/browser/firefox/subscriptions.js +10 -0
  44. package/dist/browser/launch.d.ts +6 -0
  45. package/dist/browser/launch.d.ts.map +1 -1
  46. package/dist/browser/launch.js +14 -1
  47. package/dist/cli/commands/doctor.js +3 -3
  48. package/dist/cli/commands/inspect.js +3 -2
  49. package/dist/cli/commands/install.d.ts.map +1 -1
  50. package/dist/cli/commands/install.js +26 -13
  51. package/dist/cli/commands/licences.d.ts +22 -0
  52. package/dist/cli/commands/licences.d.ts.map +1 -1
  53. package/dist/cli/commands/licences.js +62 -20
  54. package/dist/cli/commands/run.js +2 -2
  55. package/dist/cli/doctor/checks.js +4 -1
  56. package/dist/cli/inspect/diagnostics.js +3 -3
  57. package/dist/cli/inspect/test-timeline.js +10 -10
  58. package/dist/cli/install/doctor-rows.d.ts.map +1 -1
  59. package/dist/cli/install/doctor-rows.js +5 -4
  60. package/dist/cli/install/file-changes.d.ts +44 -0
  61. package/dist/cli/install/file-changes.d.ts.map +1 -0
  62. package/dist/cli/install/file-changes.js +81 -0
  63. package/dist/cli/install/install-archive.d.ts +3 -1
  64. package/dist/cli/install/install-archive.d.ts.map +1 -1
  65. package/dist/cli/install/install-archive.js +80 -33
  66. package/dist/cli/install/lock.d.ts.map +1 -1
  67. package/dist/cli/install/lock.js +108 -21
  68. package/dist/cli/install/media-doctor.d.ts.map +1 -1
  69. package/dist/cli/install/media-doctor.js +2 -1
  70. package/dist/cli/install/media-install.d.ts.map +1 -1
  71. package/dist/cli/install/media-install.js +38 -19
  72. package/dist/cli/install/media-pins.d.ts +7 -1
  73. package/dist/cli/install/media-pins.d.ts.map +1 -1
  74. package/dist/cli/install/media-pins.js +23 -12
  75. package/dist/cli/install/media-record.d.ts.map +1 -1
  76. package/dist/cli/install/media-record.js +10 -9
  77. package/dist/cli/install/media-report.d.ts +3 -1
  78. package/dist/cli/install/media-report.d.ts.map +1 -1
  79. package/dist/cli/install/media-report.js +7 -5
  80. package/dist/cli/install/media-tools.d.ts.map +1 -1
  81. package/dist/cli/install/media-tools.js +6 -4
  82. package/dist/cli/install/process-start.d.ts +3 -2
  83. package/dist/cli/install/process-start.d.ts.map +1 -1
  84. package/dist/cli/install/process-start.js +4 -0
  85. package/dist/cli/install/report.d.ts.map +1 -1
  86. package/dist/cli/install/report.js +11 -7
  87. package/dist/cli/install/supervisor-install.d.ts +33 -0
  88. package/dist/cli/install/supervisor-install.d.ts.map +1 -0
  89. package/dist/cli/install/supervisor-install.js +158 -0
  90. package/dist/cli/install/supervisor-locate.d.ts +47 -0
  91. package/dist/cli/install/supervisor-locate.d.ts.map +1 -0
  92. package/dist/cli/install/supervisor-locate.js +113 -0
  93. package/dist/cli/install/supervisor-pins.d.ts +21 -0
  94. package/dist/cli/install/supervisor-pins.d.ts.map +1 -0
  95. package/dist/cli/install/supervisor-pins.js +28 -0
  96. package/dist/cli/install/supervisor-record.d.ts +31 -0
  97. package/dist/cli/install/supervisor-record.d.ts.map +1 -0
  98. package/dist/cli/install/supervisor-record.js +104 -0
  99. package/dist/cli/install/supervisor-report.d.ts +11 -0
  100. package/dist/cli/install/supervisor-report.d.ts.map +1 -0
  101. package/dist/cli/install/supervisor-report.js +33 -0
  102. package/dist/cli/install/supervisor-tools.d.ts +43 -0
  103. package/dist/cli/install/supervisor-tools.d.ts.map +1 -0
  104. package/dist/cli/install/supervisor-tools.js +114 -0
  105. package/dist/cli/install/unpack.d.ts +23 -3
  106. package/dist/cli/install/unpack.d.ts.map +1 -1
  107. package/dist/cli/install/unpack.js +124 -10
  108. package/dist/cli/install/zip-member.d.ts +15 -0
  109. package/dist/cli/install/zip-member.d.ts.map +1 -0
  110. package/dist/cli/install/zip-member.js +77 -0
  111. package/dist/cli/interrupt.d.ts +1 -1
  112. package/dist/cli/interrupt.d.ts.map +1 -1
  113. package/dist/cli/interrupt.js +15 -10
  114. package/dist/cli/terminal.d.ts +9 -1
  115. package/dist/cli/terminal.d.ts.map +1 -1
  116. package/dist/cli/terminal.js +14 -0
  117. package/dist/config/define.d.ts +2 -2
  118. package/dist/config/define.js +2 -2
  119. package/dist/diagnostics/firefox-collector.d.ts +11 -10
  120. package/dist/diagnostics/firefox-collector.d.ts.map +1 -1
  121. package/dist/diagnostics/firefox-collector.js +16 -11
  122. package/dist/media/client.d.ts +2 -1
  123. package/dist/media/client.d.ts.map +1 -1
  124. package/dist/media/client.js +16 -5
  125. package/dist/media/host.d.ts +32 -0
  126. package/dist/media/host.d.ts.map +1 -0
  127. package/dist/media/host.js +50 -0
  128. package/dist/media/locate.d.ts.map +1 -1
  129. package/dist/media/locate.js +4 -3
  130. package/dist/native/processes.d.ts.map +1 -1
  131. package/dist/native/processes.js +7 -3
  132. package/dist/protocol/files.d.ts +1 -1
  133. package/dist/protocol/files.d.ts.map +1 -1
  134. package/dist/protocol/files.js +10 -5
  135. package/dist/reporters/commands.d.ts +12 -3
  136. package/dist/reporters/commands.d.ts.map +1 -1
  137. package/dist/reporters/commands.js +29 -11
  138. package/dist/reporters/human-card.js +1 -1
  139. package/dist/reporters/human.d.ts +3 -1
  140. package/dist/reporters/human.d.ts.map +1 -1
  141. package/dist/reporters/human.js +8 -8
  142. package/dist/reporters/style.d.ts +21 -2
  143. package/dist/reporters/style.d.ts.map +1 -1
  144. package/dist/reporters/style.js +11 -2
  145. package/dist/runner/app-server.d.ts +27 -7
  146. package/dist/runner/app-server.d.ts.map +1 -1
  147. package/dist/runner/app-server.js +74 -24
  148. package/dist/runner/child.js +6 -2
  149. package/dist/runner/media-leftovers.d.ts +7 -3
  150. package/dist/runner/media-leftovers.d.ts.map +1 -1
  151. package/dist/runner/media-leftovers.js +27 -6
  152. package/dist/runner/resources.d.ts +8 -0
  153. package/dist/runner/resources.d.ts.map +1 -1
  154. package/dist/runner/resources.js +12 -1
  155. package/dist/runner/run-session.d.ts.map +1 -1
  156. package/dist/runner/run-session.js +9 -4
  157. package/dist/runner/run.d.ts.map +1 -1
  158. package/dist/runner/run.js +2 -1
  159. package/dist/runner/target-drivers.d.ts +5 -2
  160. package/dist/runner/target-drivers.d.ts.map +1 -1
  161. package/dist/runner/target-drivers.js +10 -1
  162. package/dist/runner/test-file-process.d.ts +8 -0
  163. package/dist/runner/test-file-process.d.ts.map +1 -1
  164. package/dist/runner/test-file-process.js +26 -3
  165. package/dist/runner/test-pages.d.ts.map +1 -1
  166. package/dist/runner/test-pages.js +5 -2
  167. package/dist/shared/environment.d.ts +17 -0
  168. package/dist/shared/environment.d.ts.map +1 -0
  169. package/dist/shared/environment.js +27 -0
  170. package/dist/shared/metadata-process-worker.js +15 -7
  171. package/dist/shared/metadata-process.d.ts +5 -0
  172. package/dist/shared/metadata-process.d.ts.map +1 -1
  173. package/dist/shared/metadata-process.js +36 -6
  174. package/dist/shared/posix-path.d.ts +12 -0
  175. package/dist/shared/posix-path.d.ts.map +1 -1
  176. package/dist/shared/posix-path.js +16 -0
  177. package/dist/shared/private-file.d.ts +38 -0
  178. package/dist/shared/private-file.d.ts.map +1 -0
  179. package/dist/shared/private-file.js +132 -0
  180. package/dist/shared/process-ownership.d.ts +52 -2
  181. package/dist/shared/process-ownership.d.ts.map +1 -1
  182. package/dist/shared/process-ownership.js +104 -11
  183. package/dist/shared/process-supervisor.d.ts +309 -0
  184. package/dist/shared/process-supervisor.d.ts.map +1 -0
  185. package/dist/shared/process-supervisor.js +737 -0
  186. package/dist/shared/process-system.d.ts +113 -0
  187. package/dist/shared/process-system.d.ts.map +1 -0
  188. package/dist/shared/process-system.js +254 -0
  189. package/dist/shared/regular-file.d.ts +2 -2
  190. package/dist/shared/regular-file.d.ts.map +1 -1
  191. package/dist/shared/regular-file.js +19 -2
  192. package/dist/store/artifacts.d.ts +5 -4
  193. package/dist/store/artifacts.d.ts.map +1 -1
  194. package/dist/store/artifacts.js +18 -5
  195. package/dist/store/run-store.d.ts +5 -2
  196. package/dist/store/run-store.d.ts.map +1 -1
  197. package/dist/store/run-store.js +48 -4
  198. package/media/Cargo.lock +16 -0
  199. package/media/Cargo.toml +16 -1
  200. package/media/src/encoder.rs +56 -12
  201. package/media/src/frame.rs +7 -1
  202. package/media/src/main.rs +20 -2
  203. package/media/src/place.rs +230 -11
  204. package/media/src/process_ownership_windows.rs +1058 -0
  205. package/media/src/recording.rs +15 -7
  206. package/media/src/replies.rs +55 -0
  207. package/media/src/server.rs +72 -2
  208. package/media/src/store.rs +71 -2
  209. package/package.json +9 -4
  210. package/src/cli/install/media-notices.txt +465 -1
  211. package/supervisor/Cargo.lock +25 -0
  212. package/supervisor/Cargo.toml +22 -0
  213. package/supervisor/NOTICES +464 -0
  214. package/supervisor/build.rs +44 -0
  215. package/supervisor/src/command.rs +612 -0
  216. package/supervisor/src/jobs.rs +1650 -0
  217. package/supervisor/src/main.rs +71 -0
  218. package/supervisor/src/reply.rs +367 -0
@@ -1,27 +1,137 @@
1
- import { lstat, mkdtemp, realpath, rmdir } from 'node:fs/promises';
1
+ import { createReadStream, createWriteStream } from 'node:fs';
2
+ import { lstat, mkdtemp, open, realpath, rmdir } from 'node:fs/promises';
2
3
  import { tmpdir } from 'node:os';
3
- import { join } from 'node:path';
4
+ import { join, win32 } from 'node:path';
5
+ import { pipeline } from 'node:stream/promises';
4
6
  import { setTimeout as sleep } from 'node:timers/promises';
7
+ import { crc32 } from 'node:zlib';
8
+ import { environmentVariable } from "../../browser/builds.js";
5
9
  import { describeCommand, runCommand } from "../../native/processes.js";
6
10
  import { Deadline } from "../../protocol/deadline.js";
11
+ import { errorMessage } from "../../protocol/failures.js";
7
12
  import { errorCode, isMissingFile } from "../../shared/error-code.js";
8
- export const systemUnpackTools = { ditto: '/usr/bin/ditto', unzip: '/usr/bin/unzip', hdiutil: '/usr/bin/hdiutil' };
13
+ import { removePath } from "./file-changes.js";
14
+ // The tar a Git shell puts first on PATH is GNU tar, which reads neither zip nor 7-Zip, so Windows' own is named by the
15
+ // Windows folder.
16
+ const windowsTar = win32.join(environmentVariable(process.env, 'SystemRoot', 'win32') ?? 'C:\\Windows', 'System32', 'tar.exe');
17
+ export const systemUnpackTools = { ditto: '/usr/bin/ditto', unzip: '/usr/bin/unzip', hdiutil: '/usr/bin/hdiutil', tar: windowsTar };
9
18
  /**
10
19
  * Unpacks a verified archive into an empty folder, and returns why it could not, or undefined once it has. A zip is
11
20
  * unpacked whole, keeping its links and modes; from a disk image, only the app bundle the pin names is copied, and the
12
- * image is detached again whatever happened.
21
+ * image is detached again whatever happened; from a Windows installer, only the folder the pin names is unpacked, out
22
+ * of the 7-Zip archive inside it, and its self-extracting stub never runs.
13
23
  *
14
- * @example await unpackArchive({ archive, format: { format: 'zip' }, into, platform: 'darwin', tools: systemUnpackTools, signal, timeoutMs: 600_000 })
24
+ * @example await unpackArchive({ archive, format: { format: 'zip' }, into, platform: 'darwin', tools: systemUnpackTools, signal, timeoutMs: 600_000, report: console.log })
15
25
  */
16
26
  export async function unpackArchive(request) {
17
27
  if (request.format.format === 'dmg')
18
28
  return request.platform === 'darwin' ? copyFromDiskImage(request, request.format.app) : 'A disk image is unpacked only on macOS.';
29
+ if (request.format.format === 'exe')
30
+ return request.platform === 'win32' ? unpackInstaller(request, request.format.folder) : 'A Windows installer is unpacked only on Windows.';
31
+ if (request.platform === 'win32')
32
+ return unpackWithTar(request, request.archive, []);
19
33
  if (request.platform === 'darwin')
20
34
  return run(request.tools.ditto, ['-x', '-k', request.archive, request.into], request, 'ditto');
21
35
  if (!(await exists(request.tools.unzip)))
22
36
  return `Unpacking a zip on Linux needs unzip at ${request.tools.unzip}. Install it, for example with apt-get install unzip, and run the install again.`;
23
37
  return run(request.tools.unzip, ['-q', request.archive, '-d', request.into], request, 'unzip');
24
38
  }
39
+ // bsdtar refuses a member whose path is absolute or climbs out with `..`, and makes no link a Windows build would need.
40
+ async function unpackWithTar(request, archive, members) {
41
+ if (!(await exists(request.tools.tar)))
42
+ return `Unpacking on Windows needs its own tar.exe at ${request.tools.tar}, which Windows includes from Windows 10 version 1803.`;
43
+ return run(request.tools.tar, ['-x', '-f', archive, '-C', request.into, ...members], request, 'tar');
44
+ }
45
+ // bsdtar names the libraries it was built with in its version line, and reads LZMA only with liblzma among them; asking
46
+ // first names a tar.exe that lacks it, where the unpack itself would only end with an exit code.
47
+ async function lzmaProblem(request) {
48
+ if (!(await exists(request.tools.tar)))
49
+ return undefined;
50
+ const version = await runCommand(request.tools.tar, ['--version'], { timeoutMs: 30_000, signal: request.signal });
51
+ if (version.code !== 0)
52
+ return `Retest could not read which archives ${request.tools.tar} unpacks: ${clause(describeCommand('tar --version', version))}.`;
53
+ if (/\bliblzma\//.test(version.stdout))
54
+ return undefined;
55
+ const named = version.stdout.trim().split('\n')[0] ?? 'tar';
56
+ return `${request.tools.tar} (${named}) cannot unpack this installer, since it was built without LZMA. Update Windows, or give the target an executablePath.`;
57
+ }
58
+ // The installer's stub is a program, and running it would install Firefox the way a person does, so the archive is
59
+ // copied out of it byte for byte and only the named folder is unpacked from the copy. bsdtar finds the archive inside
60
+ // a stub only at some offsets, and the copy has it at the start.
61
+ async function unpackInstaller(request, folder) {
62
+ const start = await sevenZipStart(request.archive);
63
+ if (!start.ok)
64
+ return start.problem;
65
+ const lzma = await lzmaProblem(request);
66
+ if (lzma !== undefined)
67
+ return lzma;
68
+ const workspace = await mkdtemp(join(tmpdir(), 'retest-install-installer-'));
69
+ try {
70
+ const inner = join(workspace, 'installer.7z');
71
+ try {
72
+ await pipeline(createReadStream(request.archive, { start: start.offset }), createWriteStream(inner, { flags: 'wx' }), { signal: request.signal });
73
+ }
74
+ catch (error) {
75
+ return `The archive inside the installer could not be copied out: ${errorMessage(error)}.`;
76
+ }
77
+ const problem = await unpackWithTar(request, inner, [folder]);
78
+ if (problem !== undefined)
79
+ return problem;
80
+ const unpacked = await lstat(join(request.into, folder)).then((stats) => stats.isDirectory(), () => false);
81
+ return unpacked ? undefined : `The installer holds no ${folder} folder.`;
82
+ }
83
+ finally {
84
+ // The copy is of no further use whether the unpack worked or not; one left behind is said, and changes neither.
85
+ const removed = await removePath(workspace, { platform: request.platform, signal: request.signal });
86
+ if (!removed.ok)
87
+ request.report(`Retest could not remove ${workspace}: ${removed.reason}. Remove it by hand.`);
88
+ }
89
+ }
90
+ const sevenZipSignature = Buffer.from([0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c]);
91
+ /** A self-extracting stub is a small program; the archive begins within this many bytes of the file's start. */
92
+ const stubSearchBytes = 4 * 1024 * 1024;
93
+ /** No archive Retest pins has an index near this size. */
94
+ const maximumIndexBytes = 64 * 1024 * 1024;
95
+ /**
96
+ * Where the 7-Zip archive inside a file begins: the first place its signature stands, within the stub's reach, with a
97
+ * start header whose checksum holds and whose index lies inside the file with the checksum the header gives it. A
98
+ * signature that is only bytes of the stub fails those checks and is passed over.
99
+ *
100
+ * @example await sevenZipStart('/…/Firefox Setup 158.0.1.exe') // { ok: true, offset: 131665 }
101
+ */
102
+ export async function sevenZipStart(path) {
103
+ const handle = await open(path, 'r');
104
+ try {
105
+ const { size } = await handle.stat();
106
+ const head = Buffer.alloc(Math.min(size, stubSearchBytes));
107
+ await handle.read(head, 0, head.length, 0);
108
+ for (let at = head.indexOf(sevenZipSignature); at >= 0; at = head.indexOf(sevenZipSignature, at + 1)) {
109
+ if (await isArchiveStart(handle, size, at))
110
+ return { ok: true, offset: at };
111
+ }
112
+ return { ok: false, problem: `The installer holds no 7-Zip archive in its first ${stubSearchBytes / 1024 / 1024} MiB, so Retest cannot unpack it without running it.` };
113
+ }
114
+ finally {
115
+ await handle.close();
116
+ }
117
+ }
118
+ // The start header is the signature, two version bytes, the CRC-32 of the next 20 bytes, then the index's offset from
119
+ // the header's end, its size and its CRC-32, all little-endian.
120
+ async function isArchiveStart(handle, size, at) {
121
+ const header = Buffer.alloc(32);
122
+ if ((await handle.read(header, 0, 32, at)).bytesRead !== 32 || header[6] !== 0)
123
+ return false;
124
+ if (crc32(header.subarray(12, 32)) !== header.readUInt32LE(8))
125
+ return false;
126
+ const indexAt = BigInt(at + 32) + header.readBigUInt64LE(12);
127
+ const indexSize = header.readBigUInt64LE(20);
128
+ if (indexSize === 0n || indexSize > BigInt(maximumIndexBytes) || indexAt + indexSize > BigInt(size))
129
+ return false;
130
+ const index = Buffer.alloc(Number(indexSize));
131
+ if ((await handle.read(index, 0, index.length, Number(indexAt))).bytesRead !== index.length)
132
+ return false;
133
+ return crc32(index) === header.readUInt32LE(28);
134
+ }
25
135
  async function copyFromDiskImage(request, app) {
26
136
  const mountPoint = await mkdtemp(join(tmpdir(), 'retest-install-image-'));
27
137
  // -nobrowse keeps the image out of Finder; with no input, an image that asks for a licence agreement fails rather
@@ -32,7 +142,7 @@ async function copyFromDiskImage(request, app) {
32
142
  // can still finish after hdiutil is gone. Whatever the helper attached from this archive is detached again.
33
143
  const left = await detachLeftAttach(request, mountPoint, attached.timedOut || attached.stopped ? leftAttachWaitMs : 0);
34
144
  const cleanup = left ?? (await removeMountPoint(mountPoint));
35
- return `The disk image could not be attached: ${describeCommand('hdiutil attach', attached)}.${cleanup === undefined ? '' : ` ${cleanup}`}`;
145
+ return `The disk image could not be attached: ${clause(describeCommand('hdiutil attach', attached))}.${cleanup === undefined ? '' : ` ${cleanup}`}`;
36
146
  }
37
147
  let problem;
38
148
  try {
@@ -60,7 +170,7 @@ async function detach(request, target) {
60
170
  const forced = await runCommand(request.tools.hdiutil, ['detach', '-force', target], options);
61
171
  if (forced.code === 0)
62
172
  return undefined;
63
- return `The disk image is still attached at ${target}: ${describeCommand('hdiutil detach -force', forced)}. Detach it with hdiutil detach ${target}.`;
173
+ return `The disk image is still attached at ${target}: ${clause(describeCommand('hdiutil detach -force', forced))}. Detach it with hdiutil detach ${target}.`;
64
174
  }
65
175
  /** How long an empty mount point is tried again after a detach, while the system lets go of the volume. */
66
176
  const mountPointReleaseMs = 2000;
@@ -96,7 +206,7 @@ async function detachLeftAttach(request, mountPoint, waitMs) {
96
206
  for (;;) {
97
207
  const info = await runCommand(request.tools.hdiutil, ['info'], { timeoutMs: 60_000 });
98
208
  if (info.code !== 0)
99
- return `Retest could not read whether the image is still attached: ${describeCommand('hdiutil info', info)}. If hdiutil info lists ${request.archive}, detach it with hdiutil detach.`;
209
+ return `Retest could not read whether the image is still attached: ${clause(describeCommand('hdiutil info', info))}. If hdiutil info lists ${request.archive}, detach it with hdiutil detach.`;
100
210
  const devices = attachedDevices(info.stdout, names);
101
211
  if (devices.length > 0)
102
212
  return detachAll(request, devices);
@@ -118,7 +228,7 @@ async function detachAll(request, devices) {
118
228
  * The whole-disk devices `hdiutil info` lists for images mounted on one of `mountPoints`, or attached from one of
119
229
  * `images` with no mount point at all. An image mounted elsewhere is not counted.
120
230
  *
121
- * @example attachedDevices(text, { images: ['/…/Firefox 133.0.3.dmg'], mountPoints: ['/private/var/…/retest-install-image-a1b2'] }) // ['/dev/disk6']
231
+ * @example attachedDevices(text, { images: ['/…/Firefox 158.0.1.dmg'], mountPoints: ['/private/var/…/retest-install-image-a1b2'] }) // ['/dev/disk6']
122
232
  */
123
233
  export function attachedDevices(info, names) {
124
234
  const devices = [];
@@ -142,7 +252,11 @@ async function bothForms(path) {
142
252
  }
143
253
  async function run(tool, args, request, name) {
144
254
  const result = await runCommand(tool, args, { timeoutMs: request.timeoutMs, signal: request.signal });
145
- return result.code === 0 ? undefined : `Unpacking the archive failed: ${describeCommand(name, result)}.`;
255
+ return result.code === 0 ? undefined : `Unpacking the archive failed: ${clause(describeCommand(name, result))}.`;
256
+ }
257
+ // A command's account as a clause the sentence around it ends, without the full stop its last line may bring.
258
+ function clause(text) {
259
+ return text.replace(/\.+$/, '');
146
260
  }
147
261
  async function exists(path) {
148
262
  return lstat(path).then(() => true, (error) => !isMissingFile(error));
@@ -0,0 +1,15 @@
1
+ /** One member's bytes, or why they were not read. */
2
+ export type ZipMemberReading = {
3
+ readonly ok: true;
4
+ readonly bytes: Buffer;
5
+ } | {
6
+ readonly ok: false;
7
+ readonly problem: string;
8
+ };
9
+ /**
10
+ * The bytes of the member `name` of the zip `archive`, stored or deflated, when they are at most `maximumBytes`.
11
+ *
12
+ * @example readZipMember(omni, 'chrome/toolkit/content/global/license.html', 16 * 1024 * 1024) // { ok: true, bytes }
13
+ */
14
+ export declare function readZipMember(archive: Buffer, name: string, maximumBytes: number): ZipMemberReading;
15
+ //# sourceMappingURL=zip-member.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zip-member.d.ts","sourceRoot":"","sources":["../../../src/cli/install/zip-member.ts"],"names":[],"mappings":"AAOA,qDAAqD;AACrD,MAAM,MAAM,gBAAgB,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAQ/H;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,gBAAgB,CAkBnG"}
@@ -0,0 +1,77 @@
1
+ import { crc32, inflateRawSync } from 'node:zlib';
2
+ const endSignature = 0x06054b50;
3
+ const entrySignature = 0x02014b50;
4
+ const localSignature = 0x04034b50;
5
+ // The end record is 22 bytes and may be followed by a comment of up to 65535.
6
+ const endSearchBytes = 22 + 0xffff;
7
+ /**
8
+ * The bytes of the member `name` of the zip `archive`, stored or deflated, when they are at most `maximumBytes`.
9
+ *
10
+ * @example readZipMember(omni, 'chrome/toolkit/content/global/license.html', 16 * 1024 * 1024) // { ok: true, bytes }
11
+ */
12
+ export function readZipMember(archive, name, maximumBytes) {
13
+ const end = findEnd(archive);
14
+ if (end === undefined)
15
+ return { ok: false, problem: 'it is not a zip archive' };
16
+ const entries = archive.readUInt16LE(end + 10);
17
+ const directorySize = archive.readUInt32LE(end + 12);
18
+ const directoryAt = archive.readUInt32LE(end + 16);
19
+ if (directoryAt + directorySize > end)
20
+ return { ok: false, problem: 'its central directory lies outside it' };
21
+ const wanted = Buffer.from(name, 'utf8');
22
+ let at = directoryAt;
23
+ for (let index = 0; index < entries; index += 1) {
24
+ if (at + 46 > end || archive.readUInt32LE(at) !== entrySignature)
25
+ return { ok: false, problem: 'its central directory is damaged' };
26
+ const nameLength = archive.readUInt16LE(at + 28);
27
+ const next = at + 46 + nameLength + archive.readUInt16LE(at + 30) + archive.readUInt16LE(at + 32);
28
+ if (next > end)
29
+ return { ok: false, problem: 'its central directory is damaged' };
30
+ if (archive.subarray(at + 46, at + 46 + nameLength).equals(wanted))
31
+ return readEntry(archive, at, maximumBytes);
32
+ at = next;
33
+ }
34
+ return { ok: false, problem: `it holds no ${name}` };
35
+ }
36
+ function readEntry(archive, entry, maximumBytes) {
37
+ const flags = archive.readUInt16LE(entry + 8);
38
+ const method = archive.readUInt16LE(entry + 10);
39
+ const crc = archive.readUInt32LE(entry + 16);
40
+ const compressedSize = archive.readUInt32LE(entry + 20);
41
+ const size = archive.readUInt32LE(entry + 24);
42
+ const local = archive.readUInt32LE(entry + 42);
43
+ if ((flags & 1) !== 0)
44
+ return { ok: false, problem: 'the member is encrypted' };
45
+ if (size > maximumBytes)
46
+ return { ok: false, problem: 'the member exceeds its byte limit' };
47
+ if (local + 30 > archive.length || archive.readUInt32LE(local) !== localSignature)
48
+ return { ok: false, problem: "the member's header is damaged" };
49
+ const start = local + 30 + archive.readUInt16LE(local + 26) + archive.readUInt16LE(local + 28);
50
+ if (start + compressedSize > archive.length)
51
+ return { ok: false, problem: 'the member lies outside the archive' };
52
+ const stored = archive.subarray(start, start + compressedSize);
53
+ let bytes;
54
+ if (method === 0)
55
+ bytes = stored;
56
+ else if (method === 8) {
57
+ try {
58
+ bytes = inflateRawSync(stored, { maxOutputLength: Math.max(1, size) });
59
+ }
60
+ catch {
61
+ return { ok: false, problem: 'the member does not inflate' };
62
+ }
63
+ }
64
+ else
65
+ return { ok: false, problem: `the member is packed with method ${method}, which Retest does not read` };
66
+ if (bytes.length !== size || crc32(bytes) !== crc)
67
+ return { ok: false, problem: "the member's checksum does not hold" };
68
+ return { ok: true, bytes };
69
+ }
70
+ // The last end record in the archive whose comment runs exactly to the archive's end.
71
+ function findEnd(archive) {
72
+ for (let at = archive.length - 22; at >= Math.max(0, archive.length - endSearchBytes); at -= 1) {
73
+ if (archive.readUInt32LE(at) === endSignature && at + 22 + archive.readUInt16LE(at + 20) === archive.length)
74
+ return at;
75
+ }
76
+ return undefined;
77
+ }
@@ -2,7 +2,7 @@ import type { Writer } from '../reporters/style.ts';
2
2
  import type { StopSignal } from '../runner/contract.ts';
3
3
  /** Where interrupts come from, such as `process`. */
4
4
  export type InterruptSource = {
5
- on(event: StopSignal, listener: () => void): unknown;
5
+ on(event: StopSignal | 'SIGBREAK', listener: () => void): unknown;
6
6
  };
7
7
  export type InterruptOptions = {
8
8
  source: InterruptSource;
@@ -1 +1 @@
1
- {"version":3,"file":"interrupt.d.ts","sourceRoot":"","sources":["../../src/cli/interrupt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD,qDAAqD;AACrD,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAA;CAAE,CAAA;AAEtF,MAAM,MAAM,gBAAgB,GAAG;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,KAAK,IAAI,CAAA;CAAE,CAAA;AAS3G;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,WAAW,CAavE"}
1
+ {"version":3,"file":"interrupt.d.ts","sourceRoot":"","sources":["../../src/cli/interrupt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAIvD,qDAAqD;AACrD,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAA;CAAE,CAAA;AAEnG,MAAM,MAAM,gBAAgB,GAAG;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,KAAK,IAAI,CAAA;CAAE,CAAA;AAS3G;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,WAAW,CAevE"}
@@ -1,4 +1,5 @@
1
1
  import { stoppedExitCode } from "../runner/outcome.js";
2
+ import { launchesHeldByJob } from "../shared/process-system.js";
2
3
  const stopSignals = ['SIGINT', 'SIGTERM'];
3
4
  const stopping = {
4
5
  SIGINT: '\nStopping. Press Ctrl+C again to quit at once.\n',
@@ -12,15 +13,19 @@ const stopping = {
12
13
  */
13
14
  export function abortOnInterrupt(options) {
14
15
  const controller = new AbortController();
15
- for (const signal of stopSignals) {
16
- options.source.on(signal, () => {
17
- if (controller.signal.aborted) {
18
- options.exit(stoppedExitCode(signal));
19
- return;
20
- }
21
- options.stderr.write(stopping[signal]);
22
- controller.abort(signal);
23
- });
24
- }
16
+ const stop = (signal) => {
17
+ if (controller.signal.aborted) {
18
+ options.exit(stoppedExitCode(signal));
19
+ return;
20
+ }
21
+ options.stderr.write(stopping[signal]);
22
+ controller.abort(signal);
23
+ };
24
+ for (const signal of stopSignals)
25
+ options.source.on(signal, () => stop(signal));
26
+ // Windows sends a console program no SIGTERM. Ctrl+Break, which Node gives as SIGBREAK and which a console cannot be
27
+ // set to ignore as it can Ctrl+C, is how one is asked to stop there, so it stops a run as SIGTERM does.
28
+ if (launchesHeldByJob)
29
+ options.source.on('SIGBREAK', () => stop('SIGTERM'));
25
30
  return controller.signal;
26
31
  }
@@ -1,5 +1,5 @@
1
1
  import type { ExitCode } from '../protocol/events.ts';
2
- import type { Writer } from '../reporters/style.ts';
2
+ import type { Marks, Writer } from '../reporters/style.ts';
3
3
  export type Environment = Readonly<Record<string, string | undefined>>;
4
4
  /** An output stream and whether a person's terminal is on the other end. */
5
5
  export type Terminal = Writer & {
@@ -21,6 +21,14 @@ export type ReportTerminal = {
21
21
  * @example shouldUseColor(stdout, process.env)
22
22
  */
23
23
  export declare function shouldUseColor(terminal: Terminal, env: Environment): boolean;
24
+ /**
25
+ * The marks a terminal draws: the glyphs, except in a Windows console that names no terminal of its own, whose fonts
26
+ * lack ✓, ✗, ⏎ or ▸. Windows Terminal (`WT_SESSION`), an editor's terminal (`TERM_PROGRAM`) and one that sets `TERM`
27
+ * draw them, and output that is not a terminal is UTF-8 for whatever reads it.
28
+ *
29
+ * @example terminalMarks(stdout, process.env).passed // '✓', or '√' in a Windows console
30
+ */
31
+ export declare function terminalMarks(terminal: Terminal, env: Environment, platform?: NodeJS.Platform): Marks;
24
32
  /**
25
33
  * The terminal for the report. A closed pipe does not crash the process; once the stream has failed,
26
34
  * writing throws, so the reporter fails and the run records that nobody could read its report.
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/cli/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAEnD,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;AAEtE,4EAA4E;AAC5E,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAE3D,kGAAkG;AAClG,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;IACxB,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAA;CAC9D,CAAA;AAED,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,IAAI,KAAK,GAAG,SAAS,CAAA;CAAE,CAAA;AAEjF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAG5E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,cAAc,CAWnE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,QAAQ,CAG9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,GAAG,QAAQ,CAEnF"}
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/cli/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAG1D,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;AAEtE,4EAA4E;AAC5E,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAE3D,kGAAkG;AAClG,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;IACxB,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAA;CAC9D,CAAA;AAED,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,IAAI,KAAK,GAAG,SAAS,CAAA;CAAE,CAAA;AAEjF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAG5E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,KAAK,CAIvH;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,cAAc,CAWnE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,QAAQ,CAG9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,GAAG,QAAQ,CAEnF"}
@@ -1,3 +1,4 @@
1
+ import { consoleMarks, unicodeMarks } from "../reporters/style.js";
1
2
  /**
2
3
  * Colour only on a terminal, and never when `NO_COLOR` is set to anything but an empty string.
3
4
  *
@@ -7,6 +8,19 @@ export function shouldUseColor(terminal, env) {
7
8
  const noColor = env['NO_COLOR'];
8
9
  return terminal.isTTY && (noColor === undefined || noColor === '');
9
10
  }
11
+ /**
12
+ * The marks a terminal draws: the glyphs, except in a Windows console that names no terminal of its own, whose fonts
13
+ * lack ✓, ✗, ⏎ or ▸. Windows Terminal (`WT_SESSION`), an editor's terminal (`TERM_PROGRAM`) and one that sets `TERM`
14
+ * draw them, and output that is not a terminal is UTF-8 for whatever reads it.
15
+ *
16
+ * @example terminalMarks(stdout, process.env).passed // '✓', or '√' in a Windows console
17
+ */
18
+ export function terminalMarks(terminal, env, platform = process.platform) {
19
+ if (platform !== 'win32' || !terminal.isTTY)
20
+ return unicodeMarks;
21
+ const named = [env['WT_SESSION'], env['TERM_PROGRAM'], env['TERM']].some((value) => value !== undefined && value !== '');
22
+ return named ? unicodeMarks : consoleMarks;
23
+ }
10
24
  /**
11
25
  * The terminal for the report. A closed pipe does not crash the process; once the stream has failed,
12
26
  * writing throws, so the reporter fails and the run records that nobody could read its report.
@@ -31,7 +31,7 @@ export declare function chromium<const Options extends ChromiumOptions & AppSett
31
31
  readonly browser: 'chromium';
32
32
  };
33
33
  /**
34
- * Google Chrome, found where its channel installs on macOS and Linux.
34
+ * Google Chrome, found where its channel installs on macOS, Linux and Windows.
35
35
  *
36
36
  * @example chrome({ channel: 'beta' })
37
37
  */
@@ -39,7 +39,7 @@ export declare function chrome<const Options extends BrandedOptions & AppSetting
39
39
  readonly browser: 'chrome';
40
40
  };
41
41
  /**
42
- * Microsoft Edge, found where its channel installs on macOS and Linux.
42
+ * Microsoft Edge, found where its channel installs on macOS, Linux and Windows.
43
43
  *
44
44
  * @example edge({ channel: 'dev' })
45
45
  */
@@ -26,7 +26,7 @@ export function chromium(options) {
26
26
  return tagged(options, 'chromium');
27
27
  }
28
28
  /**
29
- * Google Chrome, found where its channel installs on macOS and Linux.
29
+ * Google Chrome, found where its channel installs on macOS, Linux and Windows.
30
30
  *
31
31
  * @example chrome({ channel: 'beta' })
32
32
  */
@@ -34,7 +34,7 @@ export function chrome(options) {
34
34
  return tagged(options, 'chrome');
35
35
  }
36
36
  /**
37
- * Microsoft Edge, found where its channel installs on macOS and Linux.
37
+ * Microsoft Edge, found where its channel installs on macOS, Linux and Windows.
38
38
  *
39
39
  * @example edge({ channel: 'dev' })
40
40
  */
@@ -18,22 +18,23 @@ export type FirefoxCollectorOptions = {
18
18
  maxTrackedRequests?: number;
19
19
  };
20
20
  /**
21
- * Why a Firefox capture holds no console messages or runtime errors. Firefox 133 sends both through one event,
21
+ * Why a Firefox capture holds no console messages or runtime errors. Firefox sends both through one event,
22
22
  * `log.entryAdded`. Strings, numbers, plain data objects and a DOM node left the probe's marker untouched, but logged
23
23
  * objects with enumerable getters changed the page's title before the entry arrived, including nested getters.
24
24
  * Firefox ignores extra serialization fields on subscriptions and session.new, and rejects serialization
25
25
  * capabilities. Filtering delivered entries for primitive arguments is too late to prevent that mutation.
26
- * A depth limit avoids the probed object's getters in script results, not in log events.
26
+ * A depth limit avoids the probed object's getters in script results, not in log events. Firefox 133 and 158 both
27
+ * behave so (`tests/integration/firefox-diagnostics.test.ts`).
27
28
  */
28
- export declare const firefoxConsoleUnavailable = "Firefox 133's console source runs the page's own enumerable getters when it serializes logged objects, before Retest can filter an entry. The log subscription ignores serialization options and offers no primitive-only filter, so Retest does not subscribe and records no console message or runtime error on Firefox.";
29
+ export declare const firefoxConsoleUnavailable = "Firefox's console source runs the page's own enumerable getters when it serializes logged objects, before Retest can filter an entry. The log subscription ignores serialization options and offers no primitive-only filter, so Retest does not subscribe and records no console message or runtime error on Firefox.";
29
30
  /**
30
- * What Firefox's WebDriver BiDi network events cover for a tab, from what Retest exercised on Firefox 133: the tab's
31
- * document and the frames inside it, of its own site and of others, each request named by the browsing context that
32
- * made it. A request a dedicated worker makes is named by the page that started the worker, so it cannot be told from
33
- * the page's own; workers' requests are not claimed, and the reason says they may appear as the page's. Firefox names
34
- * no resource type: a request is a document only when Firefox ties it to a navigation. A response Firefox served from
35
- * its cache says so without naming which cache, so none is named. Console messages and runtime errors are not
36
- * captured at all (`firefoxConsoleUnavailable`).
31
+ * What Firefox's WebDriver BiDi network events cover for a tab, from what Retest exercised on Firefox 133 and 158: the
32
+ * tab's document and the frames inside it, of its own site and of others, each request named by the browsing context
33
+ * that made it. A request a dedicated worker makes is named by the page that started the worker, so it cannot be told
34
+ * from the page's own; workers' requests are not claimed, and the reason says they may appear as the page's. Retest
35
+ * reads no resource type from Firefox: a request is a document only when Firefox ties it to a navigation. A response
36
+ * Firefox served from its cache says so without naming which cache, so none is named. Console messages and runtime
37
+ * errors are not captured at all (`firefoxConsoleUnavailable`).
37
38
  */
38
39
  export declare const firefoxScope: DiagnosticScope;
39
40
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"firefox-collector.d.ts","sourceRoot":"","sources":["../../src/diagnostics/firefox-collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,KAAK,EAAE,eAAe,EAAa,MAAM,4BAA4B,CAAA;AAE5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAe,MAAM,mBAAmB,CAAA;AAI1F,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,UAAU,CAAA;IAClB,8FAA8F;IAC9F,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,cAAc,CAAA;IACpB;;;OAGG;IACH,aAAa,EAAE;QAAE,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;KAAE,CAAA;IACvI,mGAAmG;IACnG,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,+TAA+T,CAAA;AAErW;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,eAY1B,CAAA;AAyBD;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,oBAAoB;;IAC3D,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAe;IAC9C,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAyC;gBAY/E,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAyB,EAAE,EAAE,uBAAuB;IA0BxG,sIAAsI;IAChI,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7C,IAAI,IAAI,IAAI;CAkFb"}
1
+ {"version":3,"file":"firefox-collector.d.ts","sourceRoot":"","sources":["../../src/diagnostics/firefox-collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,KAAK,EAAE,eAAe,EAAa,MAAM,4BAA4B,CAAA;AAE5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAe,MAAM,mBAAmB,CAAA;AAI1F,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,UAAU,CAAA;IAClB,8FAA8F;IAC9F,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,cAAc,CAAA;IACpB;;;OAGG;IACH,aAAa,EAAE;QAAE,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;KAAE,CAAA;IACvI,mGAAmG;IACnG,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,2TAA2T,CAAA;AAEjW;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,eAY1B,CAAA;AAyBD;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,oBAAoB;;IAC3D,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAe;IAC9C,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAyC;gBAY/E,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAyB,EAAE,EAAE,uBAAuB;IA0BxG,sIAAsI;IAChI,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7C,IAAI,IAAI,IAAI;CAqFb"}
@@ -1,22 +1,23 @@
1
1
  import { readBidi } from "../browser/firefox/bidi-client.js";
2
2
  import { s } from "../protocol/schema.js";
3
3
  /**
4
- * Why a Firefox capture holds no console messages or runtime errors. Firefox 133 sends both through one event,
4
+ * Why a Firefox capture holds no console messages or runtime errors. Firefox sends both through one event,
5
5
  * `log.entryAdded`. Strings, numbers, plain data objects and a DOM node left the probe's marker untouched, but logged
6
6
  * objects with enumerable getters changed the page's title before the entry arrived, including nested getters.
7
7
  * Firefox ignores extra serialization fields on subscriptions and session.new, and rejects serialization
8
8
  * capabilities. Filtering delivered entries for primitive arguments is too late to prevent that mutation.
9
- * A depth limit avoids the probed object's getters in script results, not in log events.
9
+ * A depth limit avoids the probed object's getters in script results, not in log events. Firefox 133 and 158 both
10
+ * behave so (`tests/integration/firefox-diagnostics.test.ts`).
10
11
  */
11
- export const firefoxConsoleUnavailable = "Firefox 133's console source runs the page's own enumerable getters when it serializes logged objects, before Retest can filter an entry. The log subscription ignores serialization options and offers no primitive-only filter, so Retest does not subscribe and records no console message or runtime error on Firefox.";
12
+ export const firefoxConsoleUnavailable = "Firefox's console source runs the page's own enumerable getters when it serializes logged objects, before Retest can filter an entry. The log subscription ignores serialization options and offers no primitive-only filter, so Retest does not subscribe and records no console message or runtime error on Firefox.";
12
13
  /**
13
- * What Firefox's WebDriver BiDi network events cover for a tab, from what Retest exercised on Firefox 133: the tab's
14
- * document and the frames inside it, of its own site and of others, each request named by the browsing context that
15
- * made it. A request a dedicated worker makes is named by the page that started the worker, so it cannot be told from
16
- * the page's own; workers' requests are not claimed, and the reason says they may appear as the page's. Firefox names
17
- * no resource type: a request is a document only when Firefox ties it to a navigation. A response Firefox served from
18
- * its cache says so without naming which cache, so none is named. Console messages and runtime errors are not
19
- * captured at all (`firefoxConsoleUnavailable`).
14
+ * What Firefox's WebDriver BiDi network events cover for a tab, from what Retest exercised on Firefox 133 and 158: the
15
+ * tab's document and the frames inside it, of its own site and of others, each request named by the browsing context
16
+ * that made it. A request a dedicated worker makes is named by the page that started the worker, so it cannot be told
17
+ * from the page's own; workers' requests are not claimed, and the reason says they may appear as the page's. Retest
18
+ * reads no resource type from Firefox: a request is a document only when Firefox ties it to a navigation. A response
19
+ * Firefox served from its cache says so without naming which cache, so none is named. Console messages and runtime
20
+ * errors are not captured at all (`firefoxConsoleUnavailable`).
20
21
  */
21
22
  export const firefoxScope = {
22
23
  engine: 'firefox',
@@ -29,7 +30,7 @@ export const firefoxScope = {
29
30
  covered: ['top_level_document', 'same_process_frames', 'out_of_process_frames'],
30
31
  notCovered: ['dedicated_workers', 'shared_workers', 'service_workers'],
31
32
  },
32
- reason: `${firefoxConsoleUnavailable} Firefox names each request by the browsing context that made it, so a dedicated worker's request is recorded as its page's, and it names no resource type beyond a navigation's document.`,
33
+ reason: `${firefoxConsoleUnavailable} Firefox names each request by the browsing context that made it, so a dedicated worker's request is recorded as its page's, and Retest reads no resource type from it beyond a navigation's document.`,
33
34
  };
34
35
  const events = ['network.beforeRequestSent', 'network.responseStarted', 'network.responseCompleted', 'network.fetchError'];
35
36
  const requestSchema = s.object({ request: s.string(), url: s.string(), method: s.string() });
@@ -154,6 +155,10 @@ export class FirefoxCollector {
154
155
  #requestSent({ context, navigation, redirectCount, timestamp, request }) {
155
156
  if (!this.#inTab(context))
156
157
  return;
158
+ // Firefox 158 tells a request for a data: address, such as a page's `<link rel="icon" href="data:,">`, which reaches
159
+ // no network; Firefox 133 and Chrome tell none, and none is recorded.
160
+ if (/^data:/i.test(request.url))
161
+ return;
157
162
  const previous = this.#hops.get(request.request);
158
163
  if (previous === undefined && this.#hops.size >= this.#maxTrackedRequests) {
159
164
  if (this.#sink.limited !== undefined)
@@ -130,7 +130,8 @@ export type EncoderOwnership = {
130
130
  export declare function captureEncoderOwnership(worker: OwnedProcessGroup, encoderPid: number): EncoderOwnership;
131
131
  /**
132
132
  * Retest's media process, `retest-media`, run as a child in a process group of its own; each encoder it starts
133
- * leads a group of its own too. Frames go to it over a pipe with their bytes untouched; each recording ends with
133
+ * leads a group of its own too. On Windows the process is held in a job of its own instead, and its encoders are born
134
+ * in that job. Frames go to it over a pipe with their bytes untouched; each recording ends with
134
135
  * exactly one `Ended` from the process. The client never invents an outcome: if the process ends before a
135
136
  * recording does, the client stops only the encoder processes whose launch ownership it recorded, and the promise
136
137
  * rejects with how the process ended and any file left. Unreadable or changed ownership is a cleanup failure.
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/media/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/media/client.ts"],"names":[],"mappings":"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"}