@checksum-ai/runtime 4.18.1 → 5.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +1 -1
- package/checksum-progress-reporter.js +1 -1
- package/cli.js +71 -71
- package/index.js +60 -60
- package/package.json +2 -2
- package/scripts/patch.js +43 -26
- package/scripts/playwright_patches/1.62.1.js +34 -0
- package/scripts/playwright_patches/1.63.0.js +600 -0
- package/test-run-monitor.js +2 -2
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Checksum.ai test runtime",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@playwright/test": "1.
|
|
6
|
+
"@playwright/test": "1.63.0",
|
|
7
7
|
"dotenv": "17.4.2",
|
|
8
8
|
"jsdom": "30.0.1",
|
|
9
9
|
"playwright-extra": "4.3.6",
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"url": "https://github.com/checksum-ai/checksum-ai-monorepo/issues"
|
|
46
46
|
},
|
|
47
47
|
"homepage": "https://github.com/checksum-ai/checksum-ai-monorepo/tree/main/packages/runtime#readme",
|
|
48
|
-
"version": "
|
|
48
|
+
"version": "5.0.0-beta.1"
|
|
49
49
|
}
|
package/scripts/patch.js
CHANGED
|
@@ -6,14 +6,19 @@ function getPlaywrightPatchesDirectory() {
|
|
|
6
6
|
return join(__dirname, "playwright_patches");
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
function availablePatchVersions() {
|
|
10
|
+
return fs
|
|
11
|
+
.readdirSync(getPlaywrightPatchesDirectory())
|
|
12
|
+
.map((patchFile) => path.basename(patchFile, ".js"))
|
|
13
|
+
.sort();
|
|
14
|
+
}
|
|
13
15
|
|
|
14
|
-
function findSuitablePatchVersion(
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
function findSuitablePatchVersion(
|
|
17
|
+
version,
|
|
18
|
+
available = availablePatchVersions()
|
|
19
|
+
) {
|
|
20
|
+
let suitablePatchVersion = available[0];
|
|
21
|
+
for (const patchVersion of available) {
|
|
17
22
|
if (version >= patchVersion) {
|
|
18
23
|
suitablePatchVersion = patchVersion;
|
|
19
24
|
} else {
|
|
@@ -23,26 +28,38 @@ function findSuitablePatchVersion(version) {
|
|
|
23
28
|
return suitablePatchVersion;
|
|
24
29
|
}
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
function patchAll() {
|
|
32
|
+
const projectRootFromEnv = process.env.PROJECT_ROOT;
|
|
33
|
+
const projectPaths = projectRootFromEnv
|
|
34
|
+
? [projectRootFromEnv]
|
|
35
|
+
: [".", "../", "../.."].map((project) => join(process.cwd(), project));
|
|
30
36
|
|
|
31
|
-
for (const projectPath of projectPaths) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
for (const projectPath of projectPaths) {
|
|
38
|
+
try {
|
|
39
|
+
if (fs.existsSync(join(projectPath, "node_modules", "playwright"))) {
|
|
40
|
+
const absolutePathToPackageJSON = resolve(
|
|
41
|
+
join(projectPath, "node_modules", "playwright", "package.json")
|
|
42
|
+
);
|
|
43
|
+
const packageJSON = require(absolutePathToPackageJSON);
|
|
44
|
+
const playwrightVersion = packageJSON.version;
|
|
45
|
+
const patchVersion = findSuitablePatchVersion(playwrightVersion);
|
|
46
|
+
const patchPath = resolve(
|
|
47
|
+
join(getPlaywrightPatchesDirectory(), `${patchVersion}.js`)
|
|
48
|
+
);
|
|
49
|
+
require(patchPath)(projectPath);
|
|
50
|
+
}
|
|
51
|
+
} catch (e) {
|
|
52
|
+
// Patching is best-effort: a failure here must not block the install.
|
|
44
53
|
}
|
|
45
|
-
} catch (e) {
|
|
46
|
-
// Patching is best-effort: a failure here must not block the install.
|
|
47
54
|
}
|
|
48
55
|
}
|
|
56
|
+
|
|
57
|
+
// Guarded like playwright_pins.js: the runtime always spawns this as
|
|
58
|
+
// `node patch.js`, so requiring it must not patch anything as a side effect —
|
|
59
|
+
// that is what lets playwright_patches.spec.ts test the real selection logic
|
|
60
|
+
// instead of keeping a copy of it in sync by hand.
|
|
61
|
+
if (require.main === module) {
|
|
62
|
+
patchAll();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = { availablePatchVersions, findSuitablePatchVersion };
|
|
@@ -525,6 +525,39 @@ function htmlReporter(projectRoot) {
|
|
|
525
525
|
replaceContent(file, originalContent, newContent);
|
|
526
526
|
}
|
|
527
527
|
|
|
528
|
+
// -------- [Shutdown safety] -------- //
|
|
529
|
+
|
|
530
|
+
// Playwright leaves two teardown fixtures at `timeout: 0`, and TimeoutManager
|
|
531
|
+
// reads that as `deadline = kMaxDeadline` — unbounded, not "use the default".
|
|
532
|
+
// Every other phase is capped at the project timeout, so these are the only two
|
|
533
|
+
// ways a worker can stop reporting for good: an unreaped browser leaves
|
|
534
|
+
// `browser.close()` awaiting a `close` event that never arrives, which is how
|
|
535
|
+
// run cc44a300 went silent for 10h42m until the k8s job deadline killed the pod.
|
|
536
|
+
// Playwright's own 5-minute worker watchdog cannot catch it — heartbeats run on
|
|
537
|
+
// an interval independent of any pending await, so a wedged worker keeps
|
|
538
|
+
// heartbeating and the deadline slides forever.
|
|
539
|
+
//
|
|
540
|
+
// `> 0 ? : ` rather than `||`: a zero, negative or unparseable override must
|
|
541
|
+
// fall back to the default, never restore the unbounded wait.
|
|
542
|
+
function boundUnboundedFixtures(projectRoot) {
|
|
543
|
+
const file = join(projectRoot, "node_modules/playwright/lib/index.js");
|
|
544
|
+
if (!doesFileExist(file)) {
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
let originalContent, newContent;
|
|
549
|
+
|
|
550
|
+
// ArtifactsRecorder.didFinishTest(): screenshot, trace stop, aria snapshot.
|
|
551
|
+
originalContent = `}, { auto: "all-hooks-included", title: "trace recording", box: true, timeout: 0 }],`;
|
|
552
|
+
newContent = `}, { auto: "all-hooks-included", title: "trace recording", box: true, timeout: Number(process.env["CHECKSUM_PW_ARTIFACTS_TIMEOUT_MS"]) > 0 ? Number(process.env["CHECKSUM_PW_ARTIFACTS_TIMEOUT_MS"]) : 120000 }],`;
|
|
553
|
+
replaceContent(file, originalContent, newContent);
|
|
554
|
+
|
|
555
|
+
// The `browser` fixture: launch on setup, `browser.close()` on teardown.
|
|
556
|
+
originalContent = `}, { scope: "worker", timeout: 0 }],`;
|
|
557
|
+
newContent = `}, { scope: "worker", timeout: Number(process.env["CHECKSUM_PW_BROWSER_FIXTURE_TIMEOUT_MS"]) > 0 ? Number(process.env["CHECKSUM_PW_BROWSER_FIXTURE_TIMEOUT_MS"]) : 180000 }],`;
|
|
558
|
+
replaceContent(file, originalContent, newContent);
|
|
559
|
+
}
|
|
560
|
+
|
|
528
561
|
// -------- [Run] -------- //
|
|
529
562
|
|
|
530
563
|
const isRuntime = true || process.env.RUNTIME === "true";
|
|
@@ -549,6 +582,7 @@ function run(projectPath) {
|
|
|
549
582
|
reportTraceFile(projectPath);
|
|
550
583
|
}
|
|
551
584
|
htmlReporter(projectPath);
|
|
585
|
+
boundUnboundedFixtures(projectPath);
|
|
552
586
|
}
|
|
553
587
|
} else {
|
|
554
588
|
console.warn("Project path not found", projectPath);
|