- Fix Next.js build failure: remove duplicate route at (dashboard)/listings/[id] that conflicted with (public)/listings/[id] (same URL path in two route groups) - Fix 772 ESLint errors: auto-fix import ordering (import-x/order), remove unused imports/variables, convert empty interfaces to type aliases, replace require() with ESM imports, fix consistent-type-imports violations - Add CLAUDE.md for developer onboarding documentation - All checks pass: 0 lint errors, typecheck clean, 230 tests passing, build success Co-Authored-By: Paperclip <noreply@paperclip.ing>
83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
import { test as base, type APIRequestContext } from '@playwright/test';
|
|
|
|
/** Shape returned by POST /auth/register and POST /auth/login */
|
|
export interface TokenPair {
|
|
accessToken: string;
|
|
refreshToken: string;
|
|
}
|
|
|
|
/** Generates a unique test user payload for each test run. */
|
|
export function createTestUser(suffix = Date.now()) {
|
|
return {
|
|
phone: `09${String(suffix).slice(-8).padStart(8, '0')}`,
|
|
password: 'Test@1234!',
|
|
fullName: `Test User ${suffix}`,
|
|
email: `testuser${suffix}@goodgo.test`,
|
|
};
|
|
}
|
|
|
|
/** Registers a new user via the API and returns the token pair. */
|
|
export async function registerUser(
|
|
request: APIRequestContext,
|
|
user = createTestUser(),
|
|
): Promise<TokenPair & { user: ReturnType<typeof createTestUser> }> {
|
|
const res = await request.post('/auth/register', { data: user });
|
|
if (!res.ok()) {
|
|
const body = await res.text();
|
|
throw new Error(`Register failed (${res.status()}): ${body}`);
|
|
}
|
|
const tokens: TokenPair = await res.json();
|
|
return { ...tokens, user };
|
|
}
|
|
|
|
/** Logs in an existing user and returns the token pair. */
|
|
export async function loginUser(
|
|
request: APIRequestContext,
|
|
phone: string,
|
|
password: string,
|
|
): Promise<TokenPair> {
|
|
const res = await request.post('/auth/login', {
|
|
data: { phone, password },
|
|
});
|
|
if (!res.ok()) {
|
|
const body = await res.text();
|
|
throw new Error(`Login failed (${res.status()}): ${body}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
/**
|
|
* Extended test fixture that provides a pre-authenticated API context.
|
|
*
|
|
* Usage:
|
|
* import { test } from '../fixtures/auth.fixture';
|
|
* test('my test', async ({ authedRequest, testTokens }) => { ... });
|
|
*/
|
|
export const test = base.extend<{
|
|
testUser: ReturnType<typeof createTestUser>;
|
|
testTokens: TokenPair;
|
|
authedRequest: APIRequestContext;
|
|
}>({
|
|
testUser: async (_fixtures, use) => {
|
|
await use(createTestUser());
|
|
},
|
|
|
|
testTokens: async ({ request, testUser }, use) => {
|
|
const { accessToken, refreshToken } = await registerUser(request, testUser);
|
|
await use({ accessToken, refreshToken });
|
|
},
|
|
|
|
authedRequest: async ({ playwright, testTokens, baseURL }, use) => {
|
|
const ctx = await playwright.request.newContext({
|
|
baseURL,
|
|
extraHTTPHeaders: {
|
|
Authorization: `Bearer ${testTokens.accessToken}`,
|
|
},
|
|
});
|
|
await use(ctx);
|
|
await ctx.dispose();
|
|
},
|
|
});
|
|
|
|
export { expect } from '@playwright/test';
|