test(fase-12): hermetic beforeEach reset for SV-01..03

The full `just test-all` first run surfaced state leakage from prior
suites (tasks tests) into SV-02/SV-03: another spec had left the
collective row's feature_flags populated, so by the time the SV suite
ran the realtime test was hitting a noisy baseline.

Add a symmetric beforeEach + afterEach that resets BOTH user.feature_flags
(Ana + Borja, each via their own context to satisfy RLS) and
collectives.feature_flags (seed collective, via Ana). Cost: ~6s per
spec in setup overhead; benefit: 5 sequential `just test-all` runs
green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 04:45:30 +02:00
parent a59e7e15ea
commit 09cd10692e

View File

@@ -66,24 +66,45 @@ async function tabBarHasSection(page: Page, section: string): Promise<number> {
.count();
}
test.describe('Section visibility', () => {
test.afterEach(async ({ browser }) => {
// Best-effort cleanup as Ana so the collective row resets too. We only
// touch the seed rows — extra collectives created mid-test are left in
// place (the integration suite already covers the cross-collective path
// without leaking, and Playwright's seed.sql is rebuilt by `just db-reset`).
const ctx = await browser.newContext();
const page = await ctx.newPage();
async function resetAllFlags(browser: import('@playwright/test').Browser): Promise<void> {
// Reset the seed rows via Ana (the only user authoritative for both her own
// row AND the seed collective row). Patching another user's row from Ana
// would be blocked by RLS, so we open a second context for Borja.
const anaCtx = await browser.newContext();
const anaPage = await anaCtx.newPage();
try {
await loginAs(page, USERS.ana);
await patchRow(page, 'users', USERS.ana.id, { feature_flags: {} });
await patchRow(page, 'users', USERS.borja.id, { feature_flags: {} });
await patchRow(page, 'collectives', SEED_COLLECTIVE_ID, { feature_flags: {} });
await loginAs(anaPage, USERS.ana);
await patchRow(anaPage, 'users', USERS.ana.id, { feature_flags: {} });
await patchRow(anaPage, 'collectives', SEED_COLLECTIVE_ID, { feature_flags: {} });
} catch {
/* don't mask the original failure */
/* don't mask original failure */
} finally {
await ctx.close();
await anaCtx.close();
}
const borjaCtx = await browser.newContext();
const borjaPage = await borjaCtx.newPage();
try {
await loginAs(borjaPage, USERS.borja);
await patchRow(borjaPage, 'users', USERS.borja.id, { feature_flags: {} });
} catch {
/* don't mask original failure */
} finally {
await borjaCtx.close();
}
}
test.describe('Section visibility', () => {
// Reset BOTH before and after every test. The before-each guards against
// state leakage from prior suites (the broader `just test-all` run shares
// the same Docker database with whatever tasks/lists tests ran before).
// The after-each keeps subsequent suites clean.
test.beforeEach(async ({ browser }) => {
await resetAllFlags(browser);
});
test.afterEach(async ({ browser }) => {
await resetAllFlags(browser);
});
test('SV-01: Ana hides Tasks in /settings — sidebar + tab bar drop it, /tasks redirects to /lists', async ({