fix: login match design reference
This commit is contained in:
1 parent
001f9f4774
commit
f1e22f7073
16 files changed
+1183
-57
No files matched your search
@@ -0,0 +1,77 @@
|
||||
import type { Page } from 'playwright'
|
||||
|
||||
export interface ApiMock {
|
||||
status: number
|
||||
body?: unknown
|
||||
headers?: Record<string, string>
|
||||
hang?: boolean
|
||||
}
|
||||
|
||||
export interface VisualState {
|
||||
path: string
|
||||
api?: Record<string, ApiMock>
|
||||
steps?: (page: Page) => Promise<void>
|
||||
}
|
||||
|
||||
const registrationClosed: ApiMock = { status: 200, body: { open: false } }
|
||||
const registrationOpen: ApiMock = { status: 200, body: { open: true } }
|
||||
|
||||
async function fillLogin(page: Page, username: string, password: string) {
|
||||
await page.getByPlaceholder('Your username').fill(username)
|
||||
await page.locator('input[autocomplete="current-password"]').fill(password)
|
||||
}
|
||||
|
||||
function submitLogin(username: string, password: string) {
|
||||
return async (page: Page) => {
|
||||
await fillLogin(page, username, password)
|
||||
await page.getByRole('button', { name: 'Log in', exact: true }).click()
|
||||
}
|
||||
}
|
||||
|
||||
function loginWith(response: ApiMock, path = '/login'): Omit<VisualState, 'steps'> {
|
||||
return {
|
||||
path,
|
||||
api: {
|
||||
'GET /v1/auth/registration': registrationClosed,
|
||||
'POST /v1/auth/login': response,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const visualStates: Record<string, Record<string, VisualState>> = {
|
||||
'log-in': {
|
||||
Default: { path: '/login', api: { 'GET /v1/auth/registration': registrationClosed } },
|
||||
'Fresh install': { path: '/login', api: { 'GET /v1/auth/registration': registrationOpen } },
|
||||
'Validation errors': {
|
||||
...loginWith({ status: 500 }),
|
||||
steps: submitLogin('ma', ''),
|
||||
},
|
||||
Submitting: {
|
||||
...loginWith({ status: 200, hang: true }),
|
||||
steps: submitLogin('marta', 'limewash2026'),
|
||||
},
|
||||
'Wrong credentials (403)': {
|
||||
...loginWith({ status: 403, body: 'forbidden' }),
|
||||
steps: submitLogin('marta', 'limewash2026'),
|
||||
},
|
||||
'Too many attempts (429)': {
|
||||
...loginWith({ status: 429, headers: { 'Retry-After': '42' } }),
|
||||
steps: submitLogin('marta', 'limewash'),
|
||||
},
|
||||
'Session expired': {
|
||||
...loginWith({ status: 500 }, '/login?redirect=/article/12/edit&reason=expired'),
|
||||
steps: async (page) => {
|
||||
await page.getByPlaceholder('Your username').fill('marta')
|
||||
await page.locator('input[autocomplete="current-password"]').focus()
|
||||
},
|
||||
},
|
||||
'Password changed': {
|
||||
path: '/login?reason=password-changed',
|
||||
api: { 'GET /v1/auth/registration': registrationClosed },
|
||||
},
|
||||
'Server or network error': {
|
||||
...loginWith({ status: 500 }),
|
||||
steps: submitLogin('marta', 'limewash2026'),
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in new issue
Block a user