Add the frontend login page (LoginPage.vue) with email and password fields, Swedish UI strings, and integration with the backend login endpoint. Also sets up Playwright as the E2E testing framework with browser tests for both login and registration flows. Frontend login implementation: - Add LoginPage.vue with form validation, error handling, and link to registration page - Add login() API function in auth.ts - Add loginUser() method to authStore that stores JWT token - Add /logga-in route to Vue Router - Add 'Logga in' nav link to AppHeader alongside existing 'Registrera' - Add 10 unit tests for LoginPage component - Add 4 unit tests for loginUser auth store method - Add 1 route resolution test and 1 AppHeader link test Playwright E2E setup and tests: - Install @playwright/test and configure playwright.config.ts - Add npm scripts: test:e2e (local) and test:e2e:ci (Docker CI) - Exclude e2e/ directory from Vitest to prevent test runner conflicts - Add .gitignore entries for test-results/ and playwright-report/ - Add 5 E2E tests for login (navigation, invalid credentials, success redirect, navigation to register, input types) - Add 6 E2E tests for register (navigation, success redirect, validation errors for invalid email/short password/mismatched passwords, navigation to login)
48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
|
|
|
test.describe('Login page', () => {
|
|
test('can navigate to login page', async ({ page }) => {
|
|
await page.goto('/logga-in')
|
|
await expect(page.getByRole('heading', { name: 'Logga in' })).toBeVisible()
|
|
})
|
|
|
|
test('shows error for invalid credentials', async ({ page }) => {
|
|
await page.goto('/logga-in')
|
|
await page.getByLabel('E-postadress').fill('user@example.com')
|
|
await page.getByLabel('Lösenord').fill('wrongpassword')
|
|
await page.getByRole('button', { name: 'Logga in' }).click()
|
|
|
|
await expect(page.getByText('Felaktig e-post eller lösenord')).toBeVisible()
|
|
})
|
|
|
|
test('redirects to home after successful login', async ({ page }) => {
|
|
await page.goto('/logga-in')
|
|
await page.getByLabel('E-postadress').fill('test@example.com')
|
|
await page.getByLabel('Lösenord').fill('password123')
|
|
await page.getByRole('button', { name: 'Logga in' }).click()
|
|
|
|
await expect(page).toHaveURL('/')
|
|
})
|
|
|
|
test('can navigate from login to register', async ({ page }) => {
|
|
await page.goto('/logga-in')
|
|
await page.getByRole('link', { name: 'Skapa konto' }).click()
|
|
|
|
await expect(page).toHaveURL('/registrera')
|
|
await expect(
|
|
page.getByRole('heading', { name: 'Skapa konto' }),
|
|
).toBeVisible()
|
|
})
|
|
|
|
test('login form has correct input types', async ({ page }) => {
|
|
await page.goto('/logga-in')
|
|
await expect(page.getByLabel('E-postadress')).toHaveAttribute(
|
|
'type',
|
|
'email',
|
|
)
|
|
await expect(page.getByLabel('Lösenord')).toHaveAttribute(
|
|
'type',
|
|
'password',
|
|
)
|
|
})
|
|
})
|