mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
New lint test_no_raw_goto.py forbids raw `page.goto(...)` in role playwright specs + persona flows (the gotoOnion wrapper in personas/utils is exempt) so navigation retries transient Tor-transport errors over onion. Migrates every raw call across ~75 roles (343 sites) to `gotoOnion(page, ...)` and teaches gotoOnion to detect relative onion URLs (`isOnionCanonical`). gotoOnion is a behaviour-identical drop-in on clearnet (single attempt, same return). Verified: no-raw-goto lint green, eslint 0 errors, make test green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
130 lines
5.3 KiB
JavaScript
130 lines
5.3 KiB
JavaScript
const { test, expect } = require("@playwright/test");
|
|
const { resolveTimeout } = require("../timeouts");
|
|
const { skipUnlessAddonEnabled } = require("../addon-gating");
|
|
const shared = require("../_shared");
|
|
const { gotoOnion } = require("../personas");
|
|
|
|
test.use({ ignoreHTTPSErrors: true });
|
|
|
|
test("spreed addon: Talk HPB signaling/turn backends are configured and coupled", async ({ browser }) => {
|
|
skipUnlessAddonEnabled("spreed");
|
|
test.setTimeout(resolveTimeout(120_000));
|
|
|
|
const unquote = (v) => ((v || "").trim().replace(/^"(.*)"$/, "$1"));
|
|
const expectedSignalingUrl = unquote(process.env.NEXTCLOUD_TALK_EXPECTED_SIGNALING_URL);
|
|
const expectedTurnServer = unquote(process.env.NEXTCLOUD_TALK_EXPECTED_TURN_SERVER);
|
|
const expectedStunServer = unquote(process.env.NEXTCLOUD_TALK_EXPECTED_STUN_SERVER);
|
|
|
|
test.skip(
|
|
!expectedSignalingUrl && !expectedTurnServer,
|
|
"Talk HPB not configured in this env (no signaling/turn server rendered) — nothing to couple",
|
|
);
|
|
|
|
const context = await browser.newContext({ ignoreHTTPSErrors: true });
|
|
const page = await context.newPage();
|
|
|
|
try {
|
|
await shared.loginToStandaloneNextcloud(page);
|
|
|
|
const capabilitiesUrl = new URL(
|
|
"ocs/v2.php/cloud/capabilities?format=json",
|
|
shared.env.nextcloudBaseUrl,
|
|
).toString();
|
|
const capabilitiesResponse = await page.request.get(capabilitiesUrl, {
|
|
headers: { "OCS-APIRequest": "true", Accept: "application/json" },
|
|
});
|
|
expect(capabilitiesResponse.ok(), "the OCS capabilities endpoint must respond").toBeTruthy();
|
|
const capabilitiesBody = await capabilitiesResponse.json();
|
|
const spreedCapabilities = capabilitiesBody?.ocs?.data?.capabilities?.spreed;
|
|
expect(
|
|
spreedCapabilities,
|
|
"Nextcloud must advertise spreed (Talk) capabilities, proving the app is enabled and wired",
|
|
).toBeTruthy();
|
|
expect(
|
|
JSON.stringify(spreedCapabilities?.config ?? {}),
|
|
"spreed must expose a signaling configuration, proving the HPB signaling_servers wiring is live",
|
|
).toMatch(/signaling/i);
|
|
|
|
const talkAdminUrl = new URL("settings/admin/talk", shared.env.nextcloudBaseUrl).toString();
|
|
await gotoOnion(page, talkAdminUrl, { waitUntil: "domcontentloaded", timeout: resolveTimeout(60_000) });
|
|
await shared.dismissBlockingNextcloudModals(page, page);
|
|
|
|
await expect(
|
|
page.getByText(/signaling/i).first(),
|
|
"the Talk admin settings must render the High-Performance Backend (signaling) section",
|
|
).toBeVisible({ timeout: resolveTimeout(60_000) });
|
|
|
|
const collectSettingsText = async () => {
|
|
const bodyText = await page.locator("body").innerText().catch(() => "");
|
|
const formValues = await page
|
|
.locator("input, textarea, select")
|
|
.evaluateAll((els) =>
|
|
els.flatMap((el) => {
|
|
const out = [];
|
|
const value = typeof el.value === "string" ? el.value.trim() : "";
|
|
const text = typeof el.textContent === "string" ? el.textContent.trim() : "";
|
|
if (value) out.push(value);
|
|
if (text) out.push(text);
|
|
return out;
|
|
}),
|
|
)
|
|
.catch(() => []);
|
|
return [bodyText, ...formValues].filter(Boolean).join("\n");
|
|
};
|
|
|
|
if (expectedTurnServer) {
|
|
await expect
|
|
.poll(collectSettingsText, {
|
|
timeout: resolveTimeout(30_000),
|
|
message: `the Talk admin settings must surface the configured HPB TURN server '${expectedTurnServer}' (turn_servers from the spreed addon, pointing at the web-svc-coturn partner host); a stock Talk install without the HPB wiring would not show it`,
|
|
})
|
|
.toContain(expectedTurnServer);
|
|
}
|
|
|
|
if (expectedStunServer) {
|
|
await expect
|
|
.poll(collectSettingsText, {
|
|
timeout: resolveTimeout(30_000),
|
|
message: `the Talk admin settings must surface the configured HPB STUN server '${expectedStunServer}' (stun_servers from the spreed addon)`,
|
|
})
|
|
.toContain(expectedStunServer);
|
|
}
|
|
|
|
if (expectedSignalingUrl) {
|
|
let signalingNeedle;
|
|
try {
|
|
signalingNeedle = new URL(expectedSignalingUrl).host;
|
|
} catch {
|
|
signalingNeedle = expectedSignalingUrl.replace(/^[a-z]+:\/\//i, "").replace(/\/.*$/, "");
|
|
}
|
|
await expect
|
|
.poll(collectSettingsText, {
|
|
timeout: resolveTimeout(30_000),
|
|
message: `the Talk admin settings must surface the configured HPB signaling server '${signalingNeedle}' (signaling_servers from the spreed addon)`,
|
|
})
|
|
.toContain(signalingNeedle);
|
|
}
|
|
|
|
const connectionSpans = page.locator("span.test-connection");
|
|
await connectionSpans
|
|
.first()
|
|
.waitFor({ state: "attached", timeout: resolveTimeout(15_000) })
|
|
.catch(() => {});
|
|
const okRows = (await connectionSpans.allInnerTexts().catch(() => [])).filter((t) =>
|
|
/OK:\s*Running version:\s*\S+/i.test(t),
|
|
);
|
|
if (okRows.length > 0) {
|
|
const errored = (await connectionSpans.allInnerTexts().catch(() => [])).filter((t) =>
|
|
/Error:|seems to be broken/i.test(t),
|
|
);
|
|
expect(
|
|
errored,
|
|
`a Talk backend reported OK yet another row reported a connection error: ${errored.join(" | ")}`,
|
|
).toHaveLength(0);
|
|
}
|
|
} finally {
|
|
await page.close().catch(() => {});
|
|
await context.close().catch(() => {});
|
|
}
|
|
});
|