Stabilize shared E2E runtime state

Contract-Neutral: E2E harness reliability fix; no deployment or installability runtime contract changes
This commit is contained in:
rcourtman 2026-07-19 23:24:21 +01:00
parent 4fcca0993b
commit d7eb4457c4
2 changed files with 26 additions and 1 deletions

View file

@ -80,6 +80,12 @@ async function setWebhookAllowlist(page: any, cidrs: string) {
test.describe('MSP isolation E2E', () => {
test.setTimeout(180_000);
test.beforeEach(({}, testInfo) => {
test.skip(
testInfo.project.name !== 'chromium',
'Cross-layer server and API coverage runs once under desktop Chromium',
);
});
test('org-bound token is scoped away from other orgs and the default org', async ({ page }) => {
await ensureAuthenticated(page);

View file

@ -811,7 +811,12 @@ export async function ensureFirstRunExperience(
setup = await completeFirstRunViaAPI(page, bootstrapToken);
usedAPIFallback = true;
} else {
await page.goto("/");
// completeSetupWizard starts every attempt at the root route. Do not
// issue another navigation here: the app can still be finishing its
// auth-driven redirect after setup was reset, and competing root
// navigations leave the shared backend in first-run state when the
// retry is interrupted.
await page.waitForLoadState("domcontentloaded").catch(() => {});
continue;
}
}
@ -1019,6 +1024,20 @@ export async function login(page: Page, credentials = E2E_CREDENTIALS) {
async function authenticateWithPrimaryAPIToken(page: Page): Promise<boolean> {
for (const candidate of primaryAPITokenCandidates()) {
// A URL-token navigation reaches an authenticated route before the app's
// first API request has validated the token. Reject stale runtime tokens
// up front so that transient route is never mistaken for a live session.
const probe = await apiRequest(page, "/api/state", {
headers: { "X-API-Token": candidate.token },
timeout: 10_000,
}).catch(() => null);
if (!probe?.ok()) {
if (probe && (probe.status() === 401 || probe.status() === 403)) {
forgetRejectedPrimaryAPIToken(candidate);
}
continue;
}
await page.goto(`/?token=${encodeURIComponent(candidate.token)}`, {
waitUntil: "domcontentloaded",
});