119 lines
3.0 KiB
TypeScript
119 lines
3.0 KiB
TypeScript
import { test as base, type Page, type Route } from "@playwright/test"
|
|
|
|
const DEFAULT_USER = {
|
|
id: "00000000-0000-0000-0000-000000000001",
|
|
username: "testuser",
|
|
email: "test@example.com",
|
|
first_name: "Test",
|
|
last_name: "User",
|
|
phone_number: null,
|
|
avatar: null,
|
|
email_verified: true,
|
|
phone_verified: false,
|
|
is_active: true,
|
|
is_staff: false,
|
|
is_superuser: false,
|
|
date_joined: "2025-01-01T00:00:00Z",
|
|
}
|
|
|
|
const DEFAULT_TOKENS = {
|
|
access: "fake-access-jwt",
|
|
refresh: "fake-refresh-jwt",
|
|
}
|
|
|
|
interface LoginPage {
|
|
page: Page
|
|
login(username: string, password: string): Promise<void>
|
|
mockLoginSuccess(userData?: Record<string, unknown>): Promise<void>
|
|
mockLoginError(status: number, body?: Record<string, unknown>): Promise<void>
|
|
mockLoginNetworkError(): Promise<void>
|
|
mockLoginDelayed(delayMs?: number): Promise<void>
|
|
}
|
|
|
|
export const test = base.extend<{ loginPage: LoginPage }>({
|
|
loginPage: async ({ page }, use) => {
|
|
await page.goto("/login")
|
|
await page.getByRole("heading", { name: "Вход" }).waitFor()
|
|
|
|
const loginPage: LoginPage = {
|
|
page,
|
|
|
|
async login(username: string, password: string) {
|
|
await page.getByRole("textbox", { name: "Логин" }).fill(username)
|
|
await page.getByRole("textbox", { name: "Пароль" }).fill(password)
|
|
await page.getByRole("button", { name: "Войти" }).click()
|
|
},
|
|
|
|
async mockLoginSuccess(userData?: Record<string, unknown>) {
|
|
const mockUser = { ...DEFAULT_USER, ...userData }
|
|
|
|
await page.route("**/auth/login", async (route: Route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
user: mockUser,
|
|
...DEFAULT_TOKENS,
|
|
}),
|
|
})
|
|
})
|
|
|
|
await page.route("**/api/users/me/", async (route: Route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(mockUser),
|
|
})
|
|
})
|
|
|
|
await page.route("**/api/projects/*", async (route: Route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify([]),
|
|
})
|
|
})
|
|
},
|
|
|
|
async mockLoginError(
|
|
status: number,
|
|
body?: Record<string, unknown>,
|
|
) {
|
|
await page.route("**/auth/login", async (route: Route) => {
|
|
await route.fulfill({
|
|
status,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(
|
|
body ?? { detail: "Invalid credentials" },
|
|
),
|
|
})
|
|
})
|
|
},
|
|
|
|
async mockLoginNetworkError() {
|
|
await page.route("**/auth/login", async (route: Route) => {
|
|
await route.abort()
|
|
})
|
|
},
|
|
|
|
async mockLoginDelayed(delayMs = 2000) {
|
|
await page.route("**/auth/login", async (route: Route) => {
|
|
await new Promise((r) => setTimeout(r, delayMs))
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
user: DEFAULT_USER,
|
|
...DEFAULT_TOKENS,
|
|
}),
|
|
})
|
|
})
|
|
},
|
|
}
|
|
|
|
await use(loginPage)
|
|
},
|
|
})
|
|
|
|
export { expect } from "@playwright/test"
|