88 lines
2.8 KiB
JavaScript
88 lines
2.8 KiB
JavaScript
import { execFileSync } from "node:child_process";
|
|
import { readdirSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import {
|
|
classifyTest,
|
|
ownedFilesByRole,
|
|
parseListedTests,
|
|
titleRules,
|
|
} from "../../scripts/run-playwright-full-slice.mjs";
|
|
|
|
const root = process.cwd();
|
|
const playwrightCliPath = join(root, "node_modules", "@playwright", "test", "cli.js");
|
|
const titleRuleFiles = new Set(titleRules.map((rule) => rule.file));
|
|
const e2eSpecFiles = readdirSync(join(root, "tests/e2e"))
|
|
.filter((file) => /\.spec\.(?:js|ts)$/u.test(file))
|
|
.sort();
|
|
|
|
describe("Playwright full-slice ownership", () => {
|
|
it("assigns every top-level e2e spec to one role or a title rule", () => {
|
|
const directOwners = new Map();
|
|
|
|
for (const [role, files] of Object.entries(ownedFilesByRole)) {
|
|
for (const file of files) {
|
|
if (directOwners.has(file)) {
|
|
throw new Error(`${file} is owned by both ${directOwners.get(file)} and ${role}.`);
|
|
}
|
|
|
|
directOwners.set(file, role);
|
|
}
|
|
}
|
|
|
|
const coveredFiles = new Set([...directOwners.keys(), ...titleRuleFiles]);
|
|
const uncoveredFiles = e2eSpecFiles.filter((file) => !coveredFiles.has(file));
|
|
|
|
expect(uncoveredFiles).toEqual([]);
|
|
});
|
|
|
|
it("keeps shared and infrastructure specs in their intended shards", () => {
|
|
expect(ownedFilesByRole.admin).toEqual(expect.arrayContaining(["default-mobile-redirect.spec.ts"]));
|
|
expect(ownedFilesByRole.superuser).toEqual(
|
|
expect.arrayContaining([
|
|
"coolify-infrastructure.spec.js",
|
|
"errorReports.spec.ts",
|
|
"failover-config.source.spec.ts",
|
|
"release-manager.spec.js",
|
|
"session-bootstrap.spec.ts",
|
|
"superuser-users.spec.ts",
|
|
])
|
|
);
|
|
expect(ownedFilesByRole.customer).toEqual(
|
|
expect.arrayContaining([
|
|
"guest-book-wash-mobile.spec.ts",
|
|
"i18n-catalog-switch.spec.ts",
|
|
"i18n-v2-integrity.spec.ts",
|
|
"release-bootstrap.spec.js",
|
|
"release-channel-switched.spec.js",
|
|
"release-channel-unavailable.spec.js",
|
|
"release-update-widget.spec.js",
|
|
"session-release-runtime.spec.ts",
|
|
])
|
|
);
|
|
});
|
|
|
|
it("classifies every listed test before role filtering", () => {
|
|
const listOutput = execFileSync(
|
|
process.execPath,
|
|
[playwrightCliPath, "test", "--list", "--project=chromium-desktop"],
|
|
{
|
|
cwd: root,
|
|
encoding: "utf8",
|
|
maxBuffer: 64 * 1024 * 1024,
|
|
}
|
|
);
|
|
const classificationErrors = [];
|
|
|
|
for (const testEntry of parseListedTests(listOutput)) {
|
|
try {
|
|
classifyTest(testEntry);
|
|
} catch (error) {
|
|
classificationErrors.push(error.message);
|
|
}
|
|
}
|
|
|
|
expect(classificationErrors).toEqual([]);
|
|
});
|
|
});
|