mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-13 04:26:16 -08:00
fix(mock): scope /reset by MAC so parallel specs stop wiping each other
The re-authentication test passed locally but failed all three CI
attempts: no request carried a token, because self-hosted.e2e.ts issues
a GLOBAL `POST /reset` against the same mock from a parallel Playwright
worker, destroying the session mid-import. Running only stalker.e2e.ts
locally never triggered it.
Serializing within one file (4b31f7167) could not fix this — the
interference is between files. Mock state is per-MAC, so `/reset` now
accepts `?macAddress=` and clears only that MAC's data, favorites,
session and watchdog counters; the unscoped form is kept for callers
that own the whole server. Both spec files now reset only the MACs they
own, so no worker can disturb another.
Verified: a scoped reset of one MAC leaves another MAC's session intact
(and its own dies), and stalker.e2e.ts + self-hosted.e2e.ts run together
23/23 green — the combination that reproduced the CI failure.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
23d0ca8afd
commit
3a93fef0f3
6 files changed
+89
-13
No files matched your search
@@ -102,7 +102,13 @@ function expectRequestsUseTargetId(requests: string[], path: string): void {
|
||||
|
||||
test.beforeEach(async ({ page, request }) => {
|
||||
await request.post(`${XTREAM_MOCK_SERVER}/reset`);
|
||||
await request.post(`${STALKER_MOCK_SERVER}/reset`);
|
||||
// Scope the Stalker reset to the MAC this file uses: a global reset would
|
||||
// wipe the sessions of stalker.e2e.ts running in a parallel worker.
|
||||
await request.post(
|
||||
`${STALKER_MOCK_SERVER}/reset?macAddress=${encodeURIComponent(
|
||||
DEFAULT_MAC
|
||||
)}`
|
||||
);
|
||||
await installRuntimeConfig(page);
|
||||
await page.goto('/');
|
||||
});
|
||||
|
||||
@@ -106,12 +106,38 @@ async function interceptStalkerRequests(page: Page): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
/** Every MAC this file touches; each is reset individually (see below). */
|
||||
const OWNED_MACS = [
|
||||
DEFAULT_MAC,
|
||||
MINIMAL_MAC,
|
||||
EMBEDDED_SERIES_MAC,
|
||||
LEGACY_PAGINATION_MAC,
|
||||
AUTH_FLOW_MAC,
|
||||
AUTH_REAUTH_MAC,
|
||||
AUTH_REJECTED_MAC,
|
||||
];
|
||||
|
||||
/**
|
||||
* Reset only the MACs this file owns. Mock state is per-MAC and other spec
|
||||
* files (self-hosted.e2e.ts) talk to the same server from a parallel worker,
|
||||
* so a global reset here would wipe their sessions mid-test — and theirs
|
||||
* would wipe ours.
|
||||
*/
|
||||
async function resetMockServer(request: APIRequestContext): Promise<void> {
|
||||
await Promise.all(OWNED_MACS.map((mac) => resetMockServerMac(request, mac)));
|
||||
}
|
||||
|
||||
async function resetMockServerMac(
|
||||
request: APIRequestContext,
|
||||
mac: string
|
||||
): Promise<void> {
|
||||
let lastError: unknown;
|
||||
|
||||
for (let attempt = 0; attempt < 3; attempt += 1) {
|
||||
try {
|
||||
const response = await request.post(`${MOCK_SERVER}/reset`);
|
||||
const response = await request.post(
|
||||
`${MOCK_SERVER}/reset?macAddress=${encodeURIComponent(mac)}`
|
||||
);
|
||||
if (response.ok()) {
|
||||
return;
|
||||
}
|
||||
@@ -630,9 +656,12 @@ test('@stalker mock server reset clears cached state', async ({ request }) => {
|
||||
);
|
||||
expect(before.ok()).toBeTruthy();
|
||||
|
||||
// Reset
|
||||
const reset = await request.post(`${MOCK_SERVER}/reset`);
|
||||
// Scoped reset — a global one would clear MACs owned by parallel specs.
|
||||
const reset = await request.post(
|
||||
`${MOCK_SERVER}/reset?macAddress=${encodeURIComponent(DEFAULT_MAC)}`
|
||||
);
|
||||
expect(reset.ok()).toBeTruthy();
|
||||
expect((await reset.json()).mac).toBe(DEFAULT_MAC);
|
||||
|
||||
// Data is regenerated identically (deterministic seed)
|
||||
const after = await request.get(
|
||||
|
||||
Reference in new issue
Block a user