fix(e2e): rebuild auth helpers + tune playwright config
Login helpers now hit dev endpoints via APIRequestContext instead of page.goto, eliminating the loginAsAdmin networkidle race that was masking real test failures. Adjusted parallelism + retries to reduce cross-file contention on shared dev DB state.
This commit is contained in:
parent
33ba082b82
commit
b9fa9f603c
2 changed files with 26 additions and 30 deletions
|
|
@ -1,36 +1,32 @@
|
|||
/**
|
||||
* Login helpers using dev endpoints.
|
||||
* These set real httpOnly JWT cookies so all middleware works naturally.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Login as admin via the dev test-login endpoint.
|
||||
* Creates a test admin user if none exists and sets the auth cookie.
|
||||
* Waits for networkidle so the client-side auth check (admin middleware +
|
||||
* auth-init plugin) completes before the test navigates anywhere.
|
||||
*
|
||||
* Implementation note: hits the dev endpoints via the APIRequestContext
|
||||
* (no page navigation). The Set-Cookie response writes auth-token to the
|
||||
* BrowserContext's cookie jar, so any subsequent page.goto() is authed.
|
||||
* Avoids the Nuxt-dev networkidle race that made page.goto-based login flaky.
|
||||
*/
|
||||
export async function loginAsAdmin(page) {
|
||||
await page.goto('/api/dev/test-login', { waitUntil: 'domcontentloaded' })
|
||||
|
||||
// The endpoint sets the cookie and redirects to /admin.
|
||||
// waitForURL fires as soon as the URL changes — not when JS finishes.
|
||||
// waitForLoadState('networkidle') ensures the auth-init plugin and admin
|
||||
// middleware have both completed their checkMemberStatus() calls before
|
||||
// the test proceeds.
|
||||
try {
|
||||
await page.waitForURL(/\/admin/, { timeout: 15000 })
|
||||
await page.waitForLoadState('networkidle')
|
||||
} catch {
|
||||
// Cookie should be set even if redirect failed — navigate manually
|
||||
await page.goto('/admin', { waitUntil: 'networkidle' })
|
||||
await page.waitForURL(/\/admin/)
|
||||
const res = await page.context().request.get('/api/dev/test-login', { maxRedirects: 0 })
|
||||
if (res.status() !== 302) {
|
||||
throw new Error(`/api/dev/test-login returned ${res.status()}; expected 302`)
|
||||
}
|
||||
const cookies = await page.context().cookies()
|
||||
if (!cookies.find((c) => c.name === 'auth-token')) {
|
||||
throw new Error('/api/dev/test-login did not set auth-token cookie')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Login as a specific member by email via the dev member-login endpoint.
|
||||
*/
|
||||
export async function loginAsMember(page, email) {
|
||||
await page.goto(`/api/dev/member-login?email=${encodeURIComponent(email)}`, { waitUntil: 'domcontentloaded' })
|
||||
await page.waitForURL(/\/member\//)
|
||||
const res = await page.context().request.get(
|
||||
`/api/dev/member-login?email=${encodeURIComponent(email)}`,
|
||||
{ maxRedirects: 0 }
|
||||
)
|
||||
if (res.status() !== 302) {
|
||||
throw new Error(`/api/dev/member-login returned ${res.status()}; expected 302`)
|
||||
}
|
||||
const cookies = await page.context().cookies()
|
||||
if (!cookies.find((c) => c.name === 'auth-token')) {
|
||||
throw new Error('/api/dev/member-login did not set auth-token cookie')
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ export default defineConfig({
|
|||
testDir: "./e2e",
|
||||
outputDir: "e2e/test-results",
|
||||
snapshotDir: "e2e/__screenshots__",
|
||||
fullyParallel: true,
|
||||
fullyParallel: false,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 1 : 0,
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
retries: process.env.CI ? 1 : 1,
|
||||
workers: process.env.CI ? 1 : 4,
|
||||
reporter: "html",
|
||||
timeout: 60000,
|
||||
use: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue