Skip to content

Commit b3628d2

Browse files
committed
Merge branch 'main' into 2025-09-22_test_npm_run_build
2 parents 524bffa + 25363ce commit b3628d2

File tree

9 files changed

+275
-22
lines changed

9 files changed

+275
-22
lines changed

package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515
},
1616
"license": "SEE LICENSE IN LICENSE",
1717
"scripts": {
18-
"server": "node tests/server.mjs",
19-
"compress": "node utils/compress.mjs",
20-
"decompress": "node utils/compress.mjs --decompress --keep ",
21-
"lint:check": "eslint **/*.{js,mjs,jsx,ts,tsx}",
22-
"pretty:check": "prettier --check ./",
23-
"pretty:format": "prettier --write ./",
24-
"format:check": "npm run pretty:check && npm run lint:check",
25-
"test:prepare": "npm run decompress -- --quiet",
18+
"prepare": "node utils/version-check.mjs",
19+
"server": "npm run prepare --silent && node tests/server.mjs",
20+
"compress": "npm run prepare --silent && node utils/compress.mjs",
21+
"decompress": "npm run prepare --silent && node utils/compress.mjs --decompress --keep ",
22+
"lint:check": "npm run prepare --silent && eslint **/*.{js,mjs,jsx,ts,tsx}",
23+
"pretty:check": "npm run prepare --silent && prettier --check ./",
24+
"pretty:format": "npm run prepare --silent && prettier --write ./",
25+
"format:check": "npm run prepare --silent && npm run pretty:check && npm run lint:check",
26+
"test:prepare": "npm run prepare --silent && npm run decompress -- --quiet",
2627
"test:chrome": "npm run test:prepare && node tests/run-browser.mjs --browser chrome",
2728
"test:firefox": "npm run test:prepare && node tests/run-browser.mjs --browser firefox",
2829
"test:safari": "npm run test:prepare && node tests/run-browser.mjs --browser safari",

params.js

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,36 @@ class Params {
8282
this.startDelay = 100;
8383
}
8484

85-
for (const paramKey of ["tag", "tags", "test", "tests"]) {
86-
this.testList = this._parseTestListParam(sourceParams, paramKey);
87-
}
88-
89-
this.testIterationCount = this._parseIntParam(sourceParams, "iterationCount", 1);
90-
this.testWorstCaseCount = this._parseIntParam(sourceParams, "worstCaseCount", 1);
85+
this.testList = this._parseOneOf(sourceParams, ["testList", "tag", "tags", "test", "tests"], this._parseTestListParam);
86+
this.testIterationCount = this._parseOneOf(sourceParams, ["testIterationCount", "iterationCount", "iterations" ], this._parseIntParam, 1);
87+
this.testWorstCaseCount = this._parseOneOf(sourceParams, ["testWorstCaseCount", "worstCaseCount", "worst"], this._parseIntParam, 1);
9188

9289
const unused = Array.from(sourceParams.keys());
9390
if (unused.length > 0)
9491
console.error("Got unused source params", unused);
9592
}
9693

94+
_parseOneOf(sourceParams, paramKeys, parseFunction, ...args) {
95+
const defaultParamKey = paramKeys[0]
96+
let result = undefined;
97+
let parsedParamKey = undefined;
98+
for (const paramKey of paramKeys) {
99+
if (!sourceParams.has(paramKey)) {
100+
continue;
101+
}
102+
const parseResult = parseFunction.call(this, sourceParams, paramKey, ...args);
103+
if (parsedParamKey) {
104+
throw new Error(`Cannot parse ${paramKey}, overriding previous "${parsedParamKey}" value ${JSON.stringify(result)} with ${JSON.stringify(parseResult)}`)
105+
}
106+
parsedParamKey = paramKey;
107+
result = parseResult;
108+
}
109+
if (!parsedParamKey) {
110+
return DefaultJetStreamParams[defaultParamKey];
111+
}
112+
return result;
113+
}
114+
97115
_parseTestListParam(sourceParams, key) {
98116
if (!sourceParams.has(key))
99117
return this.testList;
@@ -108,9 +126,6 @@ class Params {
108126
}
109127
testList = testList.map(each => each.trim());
110128
sourceParams.delete(key);
111-
if (this.testList.length > 0 && testList.length > 0) {
112-
throw new Error(`Overriding previous testList='${this.testList.join()}' with ${key} url-parameter.`);
113-
}
114129
return testList;
115130
}
116131

tests/helper.mjs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
// Copyright (C) 2007-2025 Apple Inc. All rights reserved.
2+
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions
5+
// are met:
6+
// 1. Redistributions of source code must retain the above copyright
7+
// notice, this list of conditions and the following disclaimer.
8+
// 2. Redistributions in binary form must reproduce the above copyright
9+
// notice, this list of conditions and the following disclaimer in the
10+
// documentation and/or other materials provided with the distribution.
11+
12+
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16+
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22+
// THE POSSIBILITY OF SUCH DAMAGE.
23+
24+
import { styleText } from "node:util";
125
import core from "@actions/core";
226
import { spawn } from "child_process";
327
import commandLineUsage from "command-line-usage";

tests/run-browser.mjs

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
11
#! /usr/bin/env node
22
/* eslint-disable-next-line no-unused-vars */
3+
4+
// Copyright (C) 2007-2025 Apple Inc. All rights reserved.
5+
6+
// Redistribution and use in source and binary forms, with or without
7+
// modification, are permitted provided that the following conditions
8+
// are met:
9+
// 1. Redistributions of source code must retain the above copyright
10+
// notice, this list of conditions and the following disclaimer.
11+
// 2. Redistributions in binary form must reproduce the above copyright
12+
// notice, this list of conditions and the following disclaimer in the
13+
// documentation and/or other materials provided with the distribution.
14+
15+
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19+
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25+
// THE POSSIBILITY OF SUCH DAMAGE.
26+
327
import serve from "./server.mjs";
4-
import { Builder, Capabilities } from "selenium-webdriver";
28+
import { Builder, Capabilities, logging } from "selenium-webdriver";
529
import commandLineArgs from "command-line-args";
30+
import { promises as fs } from "fs";
31+
import path from "path";
32+
import os from "os";
633

734
import {logInfo, logError, printHelp, runTest} from "./helper.mjs";
835

@@ -12,7 +39,6 @@ const optionDefinitions = [
1239
{ name: "help", alias: "h", description: "Print this help text." },
1340
];
1441

15-
1642
const options = commandLineArgs(optionDefinitions);
1743

1844
if ("help" in options)
@@ -26,6 +52,7 @@ let capabilities;
2652
switch (BROWSER) {
2753
case "safari":
2854
capabilities = Capabilities.safari();
55+
capabilities.set("safari:diagnose", true);
2956
break;
3057

3158
case "firefox": {
@@ -78,13 +105,15 @@ async function runEnd2EndTest(name, params) {
78105

79106
async function testEnd2End(params) {
80107
const driver = await new Builder().withCapabilities(capabilities).build();
108+
const sessionId = (await driver.getSession()).getId();
81109
const driverCapabilities = await driver.getCapabilities();
82110
logInfo(`Browser: ${driverCapabilities.getBrowserName()} ${driverCapabilities.getBrowserVersion()}`);
83111
const urlParams = Object.assign({
84112
worstCaseCount: 2,
85113
iterationCount: 3
86114
}, params);
87115
let results;
116+
let success = true;
88117
try {
89118
const url = new URL(`http://localhost:${PORT}/index.html`);
90119
url.search = new URLSearchParams(urlParams).toString();
@@ -102,9 +131,13 @@ async function testEnd2End(params) {
102131
results = await benchmarkResults(driver);
103132
// FIXME: validate results;
104133
} catch(e) {
134+
success = false;
105135
throw e;
106136
} finally {
107-
driver.quit();
137+
await driver.quit();
138+
if (!success) {
139+
await printLogs(sessionId);
140+
}
108141
}
109142
}
110143

@@ -128,7 +161,6 @@ class JetStreamTestError extends Error {
128161
super(`Tests failed: ${errors.map(e => e.stack).join(", ")}`);
129162
this.errors = errors;
130163
}
131-
132164
}
133165

134166
const UPDATE_INTERVAL = 250;
@@ -163,4 +195,28 @@ function logIncrementalResult(previousResults, benchmarkResults) {
163195
}
164196
}
165197

198+
function printLogs(sessionId) {
199+
if (BROWSER === "safari" && sessionId)
200+
return printSafariLogs(sessionId);
201+
}
202+
203+
async function printSafariLogs(sessionId) {
204+
const sessionLogDir = path.join(os.homedir(), "Library", "Logs", "com.apple.WebDriver", sessionId);
205+
try {
206+
const files = await fs.readdir(sessionLogDir);
207+
const logFiles = files.filter(f => f.startsWith("safaridriver.") && f.endsWith(".txt"));
208+
if (logFiles.length === 0) {
209+
logInfo(`No safaridriver log files found in session directory: ${sessionLogDir}`);
210+
return;
211+
}
212+
for (const file of logFiles) {
213+
const logPath = path.join(sessionLogDir, file);
214+
const logContent = await fs.readFile(logPath, "utf8");
215+
logGroup(`SafariDriver Log: ${file}`, () => console.log(logContent));
216+
}
217+
} catch (err) {
218+
logError("Error reading SafariDriver logs:", err);
219+
}
220+
}
221+
166222
setImmediate(runTests);

tests/run-shell.mjs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
#! /usr/bin/env node
22

3+
// Copyright (C) 2007-2025 Apple Inc. All rights reserved.
4+
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions
7+
// are met:
8+
// 1. Redistributions of source code must retain the above copyright
9+
// notice, this list of conditions and the following disclaimer.
10+
// 2. Redistributions in binary form must reproduce the above copyright
11+
// notice, this list of conditions and the following disclaimer in the
12+
// documentation and/or other materials provided with the distribution.
13+
14+
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18+
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24+
// THE POSSIBILITY OF SUCH DAMAGE.
25+
326
import commandLineArgs from "command-line-args";
427
import * as fs from "fs";
528
import * as os from "os";

tests/server.mjs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
// Copyright (C) 2007-2025 Apple Inc. All rights reserved.
2+
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions
5+
// are met:
6+
// 1. Redistributions of source code must retain the above copyright
7+
// notice, this list of conditions and the following disclaimer.
8+
// 2. Redistributions in binary form must reproduce the above copyright
9+
// notice, this list of conditions and the following disclaimer in the
10+
// documentation and/or other materials provided with the distribution.
11+
12+
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16+
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22+
// THE POSSIBILITY OF SUCH DAMAGE.
23+
124
// Simple local server
225
import * as path from "path";
326
import commandLineArgs from "command-line-args";

tests/unit-tests.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
// Copyright (C) 2007-2025 Apple Inc. All rights reserved.
2+
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions
5+
// are met:
6+
// 1. Redistributions of source code must retain the above copyright
7+
// notice, this list of conditions and the following disclaimer.
8+
// 2. Redistributions in binary form must reproduce the above copyright
9+
// notice, this list of conditions and the following disclaimer in the
10+
// documentation and/or other materials provided with the distribution.
11+
12+
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16+
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22+
// THE POSSIBILITY OF SUCH DAMAGE.
23+
124
load("shell-config.js");
225
load("params.js");
326
load("startup-helper/StartupBenchmark.js");
@@ -28,7 +51,7 @@ function assertThrows(message, func) {
2851
} catch (e) {
2952
didThrow = true;
3053
}
31-
assertTrue(didThrow, message);
54+
assertTrue(didThrow, `Test did not throw: ${message}`);
3255
}
3356

3457
(function testTagsAreLowerCaseStrings() {
@@ -276,3 +299,20 @@ async function testStartupBenchmarkInnerTests() {
276299
}
277300
);
278301
})();
302+
303+
304+
(function testParseIterationCount() {
305+
assertThrows("Cannot parse negative iterationCounts",
306+
() => {
307+
const sourceParams = new Map(Object.entries({ iterationCount: -123, }));
308+
new Params(sourceParams);
309+
});
310+
assertThrows("Cannot parse multiple iterationCounts",
311+
() => {
312+
const sourceParams = new Map(Object.entries({ iterationCount: 123, testIterationCount: 10 }));
313+
new Params(sourceParams);
314+
});
315+
let sourceParams = new Map(Object.entries({ iterationCount: 123 }));
316+
let params = new Params(sourceParams);
317+
assertEquals(params.testIterationCount, 123);
318+
})();

utils/compress.mjs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
// Copyright (C) 2007-2025 Apple Inc. All rights reserved.
2+
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions
5+
// are met:
6+
// 1. Redistributions of source code must retain the above copyright
7+
// notice, this list of conditions and the following disclaimer.
8+
// 2. Redistributions in binary form must reproduce the above copyright
9+
// notice, this list of conditions and the following disclaimer in the
10+
// documentation and/or other materials provided with the distribution.
11+
12+
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16+
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22+
// THE POSSIBILITY OF SUCH DAMAGE.
23+
24+
125
import commandLineArgs from 'command-line-args';
226
import commandLineUsage from 'command-line-usage';
327
import { globSync } from 'glob';

0 commit comments

Comments
 (0)