mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-11 21:26:44 +00:00
personas/utils/interaction.js requires every persona scenario to drive a
real role-specific interaction and refuses to supply a generic fallback,
because a "click any visible link" assertion tests nothing role-specific.
All 47 roles carrying an `adminInteraction` had rebuilt exactly that
fallback. Seven of them now assert admin rights for real; these 40 cannot.
36 declare `PERSONA_ADMINISTRATOR_BLOCKED=true`, and `runAdminFlow` returns
at its first guard long before `runRoleInteraction`, so those callbacks have
never executed in any variant. port-ui is the opposite case: its callback
does run and passes silently, because the role has no admin tier for the
locator to find. Writing a strict assertion into either is worse than the
vacuous one it replaces, because nothing would ever observe it failing.
The same module sanctions passing no callback at all, which leaves the
persona scenario asserting the auth chain it already covers. After this the
number of callbacks describes the coverage that exists instead of implying
one that does not. In 14 specs `expect` and `resolveTimeout` were used only
by the deleted blocks and go with them.
mobilizon's TODO named `mix mobilizon.users.modify --enable-admin`. Upstream
knows only `--admin`, and the converger that will resolve that entry lives
on feature/designer in faee47c6b7, so the bullet points there instead.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
61 lines
2.1 KiB
JavaScript
61 lines
2.1 KiB
JavaScript
const { test, expect } = require("@playwright/test");
|
|
const { resolveTimeout } = require("./timeouts");
|
|
|
|
const {
|
|
expectHstsWhenTls,
|
|
gotoOnion,
|
|
normalizeBaseUrl,
|
|
requireDotenvValue,
|
|
runAdminFlow,
|
|
runBiberFlow,
|
|
runGuestFlow,
|
|
} = require("./personas");
|
|
test.use({ ignoreHTTPSErrors: true });
|
|
|
|
const appBaseUrl = normalizeBaseUrl(process.env.APP_BASE_URL || "");
|
|
const canonicalDomain = requireDotenvValue(process.env.CANONICAL_DOMAIN, "CANONICAL_DOMAIN");
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
expect(appBaseUrl, "APP_BASE_URL must be set").toBeTruthy();
|
|
expect(canonicalDomain, "CANONICAL_DOMAIN must be set").toBeTruthy();
|
|
await page.context().clearCookies();
|
|
});
|
|
|
|
test("phpLDAPadmin front page is served under canonical domain with TLS", async ({ page }) => {
|
|
const response = await gotoOnion(page, `${appBaseUrl}/`);
|
|
expect(response, "Expected phpLDAPadmin response").toBeTruthy();
|
|
expect(response.status(), "Expected phpLDAPadmin front page status < 400").toBeLessThan(400);
|
|
expect(
|
|
response.url().includes(canonicalDomain),
|
|
`Expected canonical domain "${canonicalDomain}" to back the phpLDAPadmin URL`
|
|
).toBe(true);
|
|
const headers = response.headers();
|
|
expectHstsWhenTls(headers, appBaseUrl, "phpLDAPadmin");
|
|
});
|
|
|
|
test("phpLDAPadmin returns HTML content under canonical domain", async ({ request }) => {
|
|
const response = await request.get(`${appBaseUrl}/`, { timeout: resolveTimeout(30_000) });
|
|
expect(response.status(), "Expected phpLDAPadmin front page status < 400").toBeLessThan(400);
|
|
const contentType = response.headers()["content-type"] || "";
|
|
expect(
|
|
contentType.includes("text/html"),
|
|
`Expected HTML content-type, got "${contentType}"`
|
|
).toBe(true);
|
|
});
|
|
|
|
// Persona scenarios.
|
|
// Bodies live in the shared helper roles/test-e2e-playwright/files/personas
|
|
// so every role's persona flow stays consistent.
|
|
|
|
test("guest: public-landing → auth chain → never authenticated", async ({ page }) => {
|
|
await runGuestFlow(page);
|
|
});
|
|
|
|
test("biber: app → universal logout", async ({ page }) => {
|
|
await runBiberFlow(page);
|
|
});
|
|
|
|
test("administrator: app → universal logout", async ({ page }) => {
|
|
await runAdminFlow(page);
|
|
});
|