@reddoorla/maintenance 0.10.4 → 0.10.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.
- package/README.md +34 -16
- package/dist/cli/bin.js +77 -12
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.js +77 -12
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/index.js +77 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -397,6 +397,32 @@ async function readSiteConfig(sitePath) {
|
|
|
397
397
|
return out;
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
+
// src/util/free-port.ts
|
|
401
|
+
import { createServer } from "net";
|
|
402
|
+
async function findFreePort() {
|
|
403
|
+
return new Promise((resolve, reject) => {
|
|
404
|
+
const server = createServer();
|
|
405
|
+
server.unref();
|
|
406
|
+
server.on("error", reject);
|
|
407
|
+
server.listen(0, "127.0.0.1", () => {
|
|
408
|
+
const addr = server.address();
|
|
409
|
+
if (typeof addr === "object" && addr) {
|
|
410
|
+
const port = addr.port;
|
|
411
|
+
server.close(() => resolve(port));
|
|
412
|
+
} else {
|
|
413
|
+
server.close();
|
|
414
|
+
reject(new Error("findFreePort: could not determine assigned port from socket"));
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
function withFreePort(url, port) {
|
|
420
|
+
const u = new URL(url);
|
|
421
|
+
u.hostname = "localhost";
|
|
422
|
+
u.port = String(port);
|
|
423
|
+
return u.toString();
|
|
424
|
+
}
|
|
425
|
+
|
|
400
426
|
// src/audits/lighthouse.ts
|
|
401
427
|
async function readJsonMaybe(path) {
|
|
402
428
|
try {
|
|
@@ -437,13 +463,19 @@ async function lighthouseAudit(ctx) {
|
|
|
437
463
|
const site = ctx.site;
|
|
438
464
|
const label = siteLabel(site);
|
|
439
465
|
const siteCfg = await readSiteConfig(site.path);
|
|
440
|
-
const
|
|
466
|
+
const port = await findFreePort();
|
|
467
|
+
const baseUrl = siteCfg.lighthouseUrl ?? lighthouseConfig.ci.collect.url[0];
|
|
468
|
+
const resolvedConfig = {
|
|
441
469
|
...lighthouseConfig,
|
|
442
470
|
ci: {
|
|
443
471
|
...lighthouseConfig.ci,
|
|
444
|
-
collect: {
|
|
472
|
+
collect: {
|
|
473
|
+
...lighthouseConfig.ci.collect,
|
|
474
|
+
url: [withFreePort(baseUrl, port)],
|
|
475
|
+
startServerCommand: `npm run vite:dev -- --port ${port} --strictPort`
|
|
476
|
+
}
|
|
445
477
|
}
|
|
446
|
-
}
|
|
478
|
+
};
|
|
447
479
|
const configDir = await mkdtemp(join4(tmpdir(), "reddoor-lhci-"));
|
|
448
480
|
const configPath = join4(configDir, "lighthouserc.json");
|
|
449
481
|
await writeFile(configPath, JSON.stringify(resolvedConfig), "utf-8");
|
|
@@ -554,6 +586,32 @@ async function readJsonMaybe2(path) {
|
|
|
554
586
|
return null;
|
|
555
587
|
}
|
|
556
588
|
}
|
|
589
|
+
function buildPlaywrightConfig(port) {
|
|
590
|
+
return `import { defineConfig } from "@playwright/test";
|
|
591
|
+
|
|
592
|
+
export default defineConfig({
|
|
593
|
+
testDir: ".",
|
|
594
|
+
testMatch: /.*\\.spec\\.ts$/,
|
|
595
|
+
fullyParallel: true,
|
|
596
|
+
forbidOnly: !!process.env.CI,
|
|
597
|
+
retries: process.env.CI ? 2 : 0,
|
|
598
|
+
reporter: process.env.CI ? "github" : "list",
|
|
599
|
+
use: {
|
|
600
|
+
baseURL: "http://localhost:${port}",
|
|
601
|
+
trace: "on-first-retry",
|
|
602
|
+
},
|
|
603
|
+
webServer: {
|
|
604
|
+
// --strictPort: refuse to bump to a different port if ours is taken,
|
|
605
|
+
// so the audit fails loudly instead of probing a zombie.
|
|
606
|
+
// reuseExistingServer:false: never reuse \u2014 we control the lifecycle.
|
|
607
|
+
command: "npm run vite:dev -- --port ${port} --strictPort",
|
|
608
|
+
url: "http://localhost:${port}/dev/a11y-fixtures",
|
|
609
|
+
reuseExistingServer: false,
|
|
610
|
+
timeout: 120_000,
|
|
611
|
+
},
|
|
612
|
+
});
|
|
613
|
+
`;
|
|
614
|
+
}
|
|
557
615
|
function buildSpec() {
|
|
558
616
|
return `import { test, expect } from "@playwright/test";
|
|
559
617
|
import AxeBuilder from "@axe-core/playwright";
|
|
@@ -607,19 +665,26 @@ async function a11yAudit(ctx) {
|
|
|
607
665
|
const specDir = await mkdtemp2(join5(tmpdir2(), "reddoor-a11y-spec-"));
|
|
608
666
|
const specPath = join5(specDir, "a11y.spec.ts");
|
|
609
667
|
await writeFile2(specPath, buildSpec(), "utf-8");
|
|
668
|
+
const port = await findFreePort();
|
|
669
|
+
const configPath = join5(specDir, "playwright.config.ts");
|
|
670
|
+
await writeFile2(configPath, buildPlaywrightConfig(port), "utf-8");
|
|
610
671
|
const resultsPath = join5(site.path, RESULTS_REL);
|
|
611
672
|
await rm2(join5(site.path, ".reddoor-a11y"), { recursive: true, force: true });
|
|
612
673
|
let raw;
|
|
613
674
|
try {
|
|
614
|
-
raw = await spawn2(
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
675
|
+
raw = await spawn2(
|
|
676
|
+
"npx",
|
|
677
|
+
["--yes", "playwright", "test", `--config=${configPath}`, "--reporter=line", specPath],
|
|
678
|
+
{
|
|
679
|
+
cwd: site.path,
|
|
680
|
+
env: { ...process.env, REDDOOR_A11Y_OUTPUT: resultsPath },
|
|
681
|
+
// playwright on a cold tree downloads Chrome, boots the site's dev
|
|
682
|
+
// server, and runs axe over every configured route. The shared 30 s
|
|
683
|
+
// default in runAudits is fine for deps/lint/security but starves
|
|
684
|
+
// playwright (mirrors the lighthouse fix shipped earlier).
|
|
685
|
+
timeoutMs: 5 * 6e4
|
|
686
|
+
}
|
|
687
|
+
);
|
|
623
688
|
} catch (err) {
|
|
624
689
|
await rm2(specDir, { recursive: true, force: true });
|
|
625
690
|
const e = err;
|