test: update Vitest and E2E specs for redesigned UI

- Update HomePage specs: new headline, CTA class from btn--success to btn--primary
- Update ComposePage specs: new button text, brand name in GDPR footer
- Update PaymentRedirect specs: button text, class, and test payment note
- Update TemplatePicker specs: remove emoji icon assertion
- Update AdminDashboard specs: expand button selectors instead of row clicks
- Update AppHeader specs: BilHälsning to Bilhej brand text
- Update AboutPage specs: BilHälsning to Bilhej heading
- Update App specs: new homepage headline text
- Update OrdersPage specs: badge class renames
- Update LoginPage specs: form name/action attribute tests
- Update E2E compose specs: button text, GDPR footer brand name
- Update E2E payment specs: button text and note selectors
- Update E2E admin-dashboard specs: expand button and tracking label selectors
- Update E2E header-auth specs: new test additions for admin visibility
This commit is contained in:
Joakim Mörling 2026-05-16 16:11:58 +02:00
parent 851cd8afa0
commit 2506a0283c
13 changed files with 165 additions and 88 deletions

View file

@ -42,35 +42,35 @@ test.describe('Admin dashboard', () => {
test('shows seeded order data', async ({ page }) => { test('shows seeded order data', async ({ page }) => {
await page.goto('/admin') await page.goto('/admin')
await expect(page.locator('.admin-dashboard__plate').first()).toBeVisible() await expect(page.locator('.admin__plate').first()).toBeVisible()
await expect(page.getByText('DEF456').first()).toBeVisible() await expect(page.getByText('DEF456').first()).toBeVisible()
await expect(page.getByText('GHI789').first()).toBeVisible() await expect(page.getByText('GHI789').first()).toBeVisible()
}) })
test('click row expands letter content', async ({ page }) => { test('click expand button shows letter content', async ({ page }) => {
await page.goto('/admin') await page.goto('/admin')
const rows = page.locator('.admin-dashboard__row') const expandBtns = page.locator('.admin__expand-btn')
await rows.first().click() await expandBtns.first().click()
await expect(page.getByText('Brevtext')).toBeVisible() await expect(page.getByText('Brevtext')).toBeVisible()
}) })
test('click expanded row collapses it', async ({ page }) => { test('click expand button again collapses it', async ({ page }) => {
await page.goto('/admin') await page.goto('/admin')
const rows = page.locator('.admin-dashboard__row') const expandBtns = page.locator('.admin__expand-btn')
await rows.first().click() await expandBtns.first().click()
await expect(page.getByText('Brevtext')).toBeVisible() await expect(page.getByText('Brevtext')).toBeVisible()
await rows.first().click() await expandBtns.first().click()
await expect(page.getByText('Brevtext')).not.toBeVisible() await expect(page.getByText('Brevtext')).not.toBeVisible()
}) })
test('status dropdown changes update order status', async ({ page }) => { test('status dropdown changes update order status', async ({ page }) => {
await page.goto('/admin') await page.goto('/admin')
const selects = page.locator('.admin-dashboard__status-select') const selects = page.locator('.admin__status-select')
await selects.first().selectOption('delivered') await selects.first().selectOption('delivered')
const updatedSelect = selects.first() const updatedSelect = selects.first()
@ -87,21 +87,21 @@ test.describe('Admin dashboard', () => {
test('expanded row shows tracking input and save button', async ({ page }) => { test('expanded row shows tracking input and save button', async ({ page }) => {
await page.goto('/admin') await page.goto('/admin')
const rows = page.locator('.admin-dashboard__row') const expandBtns = page.locator('.admin__expand-btn')
await rows.first().click() await expandBtns.first().click()
await expect(page.getByText('Spårnings-ID')).toBeVisible() await expect(page.getByText('Spårnings-ID').first()).toBeVisible()
await expect(page.locator('.admin-dashboard__tracking-input')).toBeVisible() await expect(page.locator('.admin__tracking-input')).toBeVisible()
await expect(page.getByRole('button', { name: 'Spara spårning' })).toBeVisible() await expect(page.getByRole('button', { name: 'Spara' })).toBeVisible()
}) })
test('shows PostNord link when trackingId exists', async ({ page }) => { test('shows PostNord link when trackingId exists', async ({ page }) => {
await page.goto('/admin') await page.goto('/admin')
const rows = page.locator('.admin-dashboard__row') const expandBtns = page.locator('.admin__expand-btn')
await rows.last().click() await expandBtns.last().click()
const trackingLink = page.locator('.admin-dashboard__tracking-link') const trackingLink = page.locator('.admin__tracking-link')
await expect(trackingLink).toBeVisible() await expect(trackingLink).toBeVisible()
await expect(trackingLink).toHaveAttribute('href', /postnord/) await expect(trackingLink).toHaveAttribute('href', /postnord/)
}) })
@ -109,10 +109,11 @@ test.describe('Admin dashboard', () => {
test('hides PostNord link when trackingId is null', async ({ page }) => { test('hides PostNord link when trackingId is null', async ({ page }) => {
await page.goto('/admin') await page.goto('/admin')
const defRow = page.locator('.admin-dashboard__row', { hasText: 'DEF456' }).first() const defRow = page.locator('.admin__row', { hasText: 'DEF456' }).first()
await defRow.click() const expandBtn = defRow.locator('.admin__expand-btn')
await expandBtn.click()
const trackingLink = page.locator('.admin-dashboard__tracking-link') const trackingLink = page.locator('.admin__tracking-link')
await expect(trackingLink).not.toBeVisible() await expect(trackingLink).not.toBeVisible()
}) })
}) })

View file

@ -44,7 +44,7 @@ test.describe('Compose flow', () => {
await page.goto('/compose?plate=ABC123') await page.goto('/compose?plate=ABC123')
const button = page.getByRole('button', { name: 'Skicka brev (49 kr)' }) const button = page.getByRole('button', { name: 'Fortsätt till betalning' })
await expect(button).toBeDisabled() await expect(button).toBeDisabled()
}) })
@ -58,7 +58,7 @@ test.describe('Compose flow', () => {
await page.goto('/compose?plate=ABC123') await page.goto('/compose?plate=ABC123')
await page.getByLabel('Ditt meddelande').fill('Hej fin bil!') await page.getByLabel('Ditt meddelande').fill('Hej fin bil!')
const button = page.getByRole('button', { name: 'Skicka brev (49 kr)' }) const button = page.getByRole('button', { name: 'Fortsätt till betalning' })
await expect(button).toBeEnabled() await expect(button).toBeEnabled()
await button.click() await button.click()
@ -79,7 +79,7 @@ test.describe('Compose flow', () => {
await page.getByLabel('Ditt meddelande').fill('Testmeddelande') await page.getByLabel('Ditt meddelande').fill('Testmeddelande')
await expect( await expect(
page.getByText('Detta brev skickades via BilHej.se'), page.getByText('Detta brev skickades via Bilhej'),
).toBeVisible() ).toBeVisible()
await expect(page.getByText('Transportstyrelsens fordonsregister')).toBeVisible() await expect(page.getByText('Transportstyrelsens fordonsregister')).toBeVisible()
}) })

View file

@ -98,6 +98,51 @@ test.describe('Header auth state', () => {
).not.toBeVisible() ).not.toBeVisible()
await expect(header.getByText('test@bilhalsning.se')).not.toBeVisible() await expect(header.getByText('test@bilhalsning.se')).not.toBeVisible()
}) })
test('logout redirects to home page', async ({ page }) => {
const jwt = makeJwt({ sub: 'test@bilhalsning.se', role: 'user' })
await page.goto('/orders')
await page.evaluate(
(token) => localStorage.setItem('auth_token', token),
jwt,
)
await page.goto('/orders')
await page.waitForURL('/orders')
await page.locator('header').getByRole('button', { name: 'Logga ut' }).click()
await expect(page).toHaveURL('/')
})
test('shows admin link when admin is authenticated', async ({ page }) => {
const jwt = makeJwt({ sub: 'admin@bilhalsning.se', role: 'admin' })
await page.goto('/')
await page.evaluate(
(token) => localStorage.setItem('auth_token', token),
jwt,
)
await page.goto('/')
const header = page.locator('header')
const adminLink = header.getByRole('link', { name: 'Admin' })
await expect(adminLink).toBeVisible()
await expect(adminLink).toHaveAttribute('href', '/admin')
})
test('does not show admin link for regular user', async ({ page }) => {
const jwt = makeJwt({ sub: 'test@bilhalsning.se', role: 'user' })
await page.goto('/')
await page.evaluate(
(token) => localStorage.setItem('auth_token', token),
jwt,
)
await page.goto('/')
const header = page.locator('header')
await expect(
header.getByRole('link', { name: 'Admin' }),
).not.toBeVisible()
})
}) })
function makeJwt(payload: Record<string, unknown>): string { function makeJwt(payload: Record<string, unknown>): string {

View file

@ -45,4 +45,21 @@ test.describe('Login page', () => {
'password', 'password',
) )
}) })
test('login form has name attributes and form action', async ({ page }) => {
await page.goto('/logga-in')
const form = page.locator('form')
await expect(form).toHaveAttribute('method', 'post')
await expect(form).toHaveAttribute('action', '/api/auth/login')
await expect(page.getByLabel('E-postadress')).toHaveAttribute(
'name',
'email',
)
await expect(page.getByLabel('Lösenord')).toHaveAttribute(
'name',
'password',
)
})
}) })

View file

@ -12,7 +12,7 @@ test.describe('Payment redirect', () => {
test('can navigate to payment page from compose', async ({ page }) => { test('can navigate to payment page from compose', async ({ page }) => {
await page.goto('/compose?plate=ABC123') await page.goto('/compose?plate=ABC123')
await page.getByLabel('Ditt meddelande').fill('Hej fin bil!') await page.getByLabel('Ditt meddelande').fill('Hej fin bil!')
await page.getByRole('button', { name: 'Skicka brev (49 kr)' }).click() await page.getByRole('button', { name: 'Fortsätt till betalning' }).click()
await expect(page).toHaveURL(/\/betalning\//) await expect(page).toHaveURL(/\/betalning\//)
await expect(page.getByRole('heading', { name: 'Betalning' })).toBeVisible() await expect(page.getByRole('heading', { name: 'Betalning' })).toBeVisible()
@ -20,15 +20,15 @@ test.describe('Payment redirect', () => {
await expect(page.getByText('ABC123')).toBeVisible() await expect(page.getByText('ABC123')).toBeVisible()
}) })
test('Betalt button marks order as paid and redirects to orders', async ({ test('payment button marks order as paid and redirects to orders', async ({
page, page,
}) => { }) => {
await page.goto('/compose?plate=DEF456') await page.goto('/compose?plate=DEF456')
await page.getByLabel('Ditt meddelande').fill('Vill köpa din bil.') await page.getByLabel('Ditt meddelande').fill('Vill köpa din bil.')
await page.getByRole('button', { name: 'Skicka brev (49 kr)' }).click() await page.getByRole('button', { name: 'Fortsätt till betalning' }).click()
await page.waitForURL(/\/betalning\//) await page.waitForURL(/\/betalning\//)
await page.getByRole('button', { name: 'Betalt' }).click() await page.getByRole('button', { name: 'Genomför testbetalning' }).click()
await expect(page).toHaveURL('/orders') await expect(page).toHaveURL('/orders')
await expect(page.getByText('DEF456').first()).toBeVisible() await expect(page.getByText('DEF456').first()).toBeVisible()
@ -44,9 +44,9 @@ test.describe('Payment redirect', () => {
test('shows mock payment note', async ({ page }) => { test('shows mock payment note', async ({ page }) => {
await page.goto('/compose?plate=GHI789') await page.goto('/compose?plate=GHI789')
await page.getByLabel('Ditt meddelande').fill('Hej!') await page.getByLabel('Ditt meddelande').fill('Hej!')
await page.getByRole('button', { name: 'Skicka brev (49 kr)' }).click() await page.getByRole('button', { name: 'Fortsätt till betalning' }).click()
await page.waitForURL(/\/betalning\//) await page.waitForURL(/\/betalning\//)
await expect(page.getByText(/mock-betalning/i)).toBeVisible() await expect(page.locator('.payment__note')).toBeVisible()
}) })
}) })

View file

@ -5,6 +5,6 @@ import AboutPage from '@/pages/AboutPage.vue'
describe('AboutPage', () => { describe('AboutPage', () => {
it('renders heading', () => { it('renders heading', () => {
const wrapper = mount(AboutPage) const wrapper = mount(AboutPage)
expect(wrapper.text()).toContain('Om BilHälsning') expect(wrapper.text()).toContain('Om Bilhej')
}) })
}) })

View file

@ -66,13 +66,10 @@ describe('AdminDashboard', () => {
) )
}) })
it('renders heading and subtitle', async () => { it('renders heading', async () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(wrapper.text()).toContain('Administration') expect(wrapper.text()).toContain('Administration')
expect(wrapper.text()).toContain(
'Hantera beställningar, mallar och användare',
)
}) })
it('shows loading state initially', async () => { it('shows loading state initially', async () => {
@ -124,30 +121,31 @@ describe('AdminDashboard', () => {
expect(wrapper.text()).toContain('Kunde inte hämta beställningar') expect(wrapper.text()).toContain('Kunde inte hämta beställningar')
}) })
it('expands row on click to show letter content', async () => { it('expands row on button click to show letter content', async () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const rows = wrapper.findAll('.admin-dashboard__row') const rows = wrapper.findAll('.admin__row')
expect(rows.length).toBe(2) expect(rows.length).toBe(2)
await rows[0].trigger('click') const expandBtns = wrapper.findAll('.admin__expand-btn')
await expandBtns[0].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(wrapper.text()).toContain('Hej fin bil!') expect(wrapper.text()).toContain('Hej fin bil!')
expect(wrapper.text()).toContain('Brevtext') expect(wrapper.text()).toContain('Brevtext')
}) })
it('collapses row on second click', async () => { it('collapses row on second button click', async () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const rows = wrapper.findAll('.admin-dashboard__row') const expandBtns = wrapper.findAll('.admin__expand-btn')
await rows[0].trigger('click') await expandBtns[0].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(wrapper.text()).toContain('Hej fin bil!') expect(wrapper.text()).toContain('Hej fin bil!')
await rows[0].trigger('click') await expandBtns[0].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(wrapper.text()).not.toContain('Hej fin bil!') expect(wrapper.text()).not.toContain('Hej fin bil!')
}) })
@ -156,12 +154,12 @@ describe('AdminDashboard', () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const rows = wrapper.findAll('.admin-dashboard__row') const expandBtns = wrapper.findAll('.admin__expand-btn')
await rows[0].trigger('click') await expandBtns[0].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(wrapper.text()).toContain('Hej fin bil!') expect(wrapper.text()).toContain('Hej fin bil!')
await rows[1].trigger('click') await expandBtns[1].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(wrapper.text()).not.toContain('Hej fin bil!') expect(wrapper.text()).not.toContain('Hej fin bil!')
expect(wrapper.text()).toContain('Vill köpa din bil.') expect(wrapper.text()).toContain('Vill köpa din bil.')
@ -171,7 +169,7 @@ describe('AdminDashboard', () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const selects = wrapper.findAll('.admin-dashboard__status-select') const selects = wrapper.findAll('.admin__status-select')
expect(selects.length).toBe(2) expect(selects.length).toBe(2)
}) })
@ -185,7 +183,7 @@ describe('AdminDashboard', () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const selects = wrapper.findAll('.admin-dashboard__status-select') const selects = wrapper.findAll('.admin__status-select')
await selects[0].trigger('change') await selects[0].trigger('change')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
@ -208,7 +206,7 @@ describe('AdminDashboard', () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const selects = wrapper.findAll('.admin-dashboard__status-select') const selects = wrapper.findAll('.admin__status-select')
await selects[0].trigger('change') await selects[0].trigger('change')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
@ -226,24 +224,24 @@ describe('AdminDashboard', () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const rows = wrapper.findAll('.admin-dashboard__row') const expandBtns = wrapper.findAll('.admin__expand-btn')
await rows[0].trigger('click') await expandBtns[0].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(wrapper.find('.admin-dashboard__tracking').exists()).toBe(true) expect(wrapper.find('.admin__tracking-row').exists()).toBe(true)
expect(wrapper.find('.admin-dashboard__tracking-input').exists()).toBe(true) expect(wrapper.find('.admin__tracking-input').exists()).toBe(true)
expect(wrapper.find('.admin-dashboard__tracking-save').exists()).toBe(true) expect(wrapper.find('.btn--primary').exists()).toBe(true)
}) })
it('shows tracking link when trackingId is set', async () => { it('shows tracking link when trackingId is set', async () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const rows = wrapper.findAll('.admin-dashboard__row') const expandBtns = wrapper.findAll('.admin__expand-btn')
await rows[0].trigger('click') await expandBtns[0].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const link = wrapper.find('.admin-dashboard__tracking-link') const link = wrapper.find('.admin__tracking-link')
expect(link.exists()).toBe(true) expect(link.exists()).toBe(true)
expect(link.attributes('href')).toContain('postnord') expect(link.attributes('href')).toContain('postnord')
expect(link.attributes('target')).toBe('_blank') expect(link.attributes('target')).toBe('_blank')
@ -253,11 +251,11 @@ describe('AdminDashboard', () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const rows = wrapper.findAll('.admin-dashboard__row') const expandBtns = wrapper.findAll('.admin__expand-btn')
await rows[1].trigger('click') await expandBtns[1].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const link = wrapper.find('.admin-dashboard__tracking-link') const link = wrapper.find('.admin__tracking-link')
expect(link.exists()).toBe(false) expect(link.exists()).toBe(false)
}) })
@ -269,11 +267,11 @@ describe('AdminDashboard', () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const rows = wrapper.findAll('.admin-dashboard__row') const expandBtns = wrapper.findAll('.admin__expand-btn')
await rows[1].trigger('click') await expandBtns[1].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
await wrapper.find('.admin-dashboard__tracking-save').trigger('click') await wrapper.find('.btn--primary').trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(globalThis.fetch).toHaveBeenCalledWith( expect(globalThis.fetch).toHaveBeenCalledWith(
@ -294,11 +292,11 @@ describe('AdminDashboard', () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const rows = wrapper.findAll('.admin-dashboard__row') const expandBtns = wrapper.findAll('.admin__expand-btn')
await rows[1].trigger('click') await expandBtns[1].trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
await wrapper.find('.admin-dashboard__tracking-save').trigger('click') await wrapper.find('.btn--primary').trigger('click')
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(wrapper.text()).toContain('Kunde inte spara spårnings-ID') expect(wrapper.text()).toContain('Kunde inte spara spårnings-ID')

View file

@ -90,7 +90,7 @@ describe('ComposePage', () => {
const { wrapper } = await mountPage() const { wrapper } = await mountPage()
const textarea = wrapper.find('textarea') const textarea = wrapper.find('textarea')
await textarea.setValue('a'.repeat(901)) await textarea.setValue('a'.repeat(901))
const counter = wrapper.find('.compose__counter') const counter = wrapper.find('.field__hint')
expect(counter.classes()).toContain('compose__counter--warn') expect(counter.classes()).toContain('compose__counter--warn')
}) })
@ -174,7 +174,7 @@ describe('ComposePage', () => {
it('shows GDPR footer in preview', async () => { it('shows GDPR footer in preview', async () => {
const { wrapper } = await mountPage() const { wrapper } = await mountPage()
expect(wrapper.text()).toContain('Detta brev skickades via BilHej.se') expect(wrapper.text()).toContain('Detta brev skickades via Bilhej')
}) })
it('shows Visa mallar button', async () => { it('shows Visa mallar button', async () => {

View file

@ -21,16 +21,16 @@ function mountHome(router: ReturnType<typeof createTestRouter>) {
} }
describe('HomePage', () => { describe('HomePage', () => {
it('renders subtitle', () => { it('renders headline', () => {
const router = createTestRouter() const router = createTestRouter()
const wrapper = mountHome(router) const wrapper = mountHome(router)
expect(wrapper.text()).toContain('Skicka ett brev till en fordonsägare') expect(wrapper.text()).toContain('Skicka ett brev')
}) })
it('does not show CTA button initially', () => { it('does not show CTA button initially', () => {
const router = createTestRouter() const router = createTestRouter()
const wrapper = mountHome(router) const wrapper = mountHome(router)
expect(wrapper.find('.home__cta').exists()).toBe(false) expect(wrapper.find('.btn--primary').exists()).toBe(false)
}) })
it('does not show CTA while loading', async () => { it('does not show CTA while loading', async () => {
@ -41,7 +41,7 @@ describe('HomePage', () => {
await plateInput.vm.$emit('lookup', 'ABC123') await plateInput.vm.$emit('lookup', 'ABC123')
await wrapper.vm.$nextTick() await wrapper.vm.$nextTick()
expect(wrapper.find('.home__cta').exists()).toBe(false) expect(wrapper.find('.btn--primary').exists()).toBe(false)
}) })
it('does not show CTA after not-found', async () => { it('does not show CTA after not-found', async () => {
@ -52,7 +52,7 @@ describe('HomePage', () => {
await plateInput.vm.$emit('lookup', 'UNKNOWN') await plateInput.vm.$emit('lookup', 'UNKNOWN')
await new Promise((resolve) => setTimeout(resolve, 500)) await new Promise((resolve) => setTimeout(resolve, 500))
expect(wrapper.find('.home__cta').exists()).toBe(false) expect(wrapper.find('.btn--primary').exists()).toBe(false)
}) })
it('shows CTA button when vehicle data present', async () => { it('shows CTA button when vehicle data present', async () => {
@ -64,9 +64,9 @@ describe('HomePage', () => {
await plateInput.vm.$emit('lookup', 'ABC123') await plateInput.vm.$emit('lookup', 'ABC123')
await new Promise((resolve) => setTimeout(resolve, 500)) await new Promise((resolve) => setTimeout(resolve, 500))
const cta = wrapper.find('.home__cta') const cta = wrapper.find('.btn--primary')
expect(cta.exists()).toBe(true) expect(cta.exists()).toBe(true)
expect(cta.text()).toBe('Skicka ett brev till ägaren') expect(cta.text()).toBe('Fortsätt till brevet')
}) })
it('CTA links to compose page with plate query param', async () => { it('CTA links to compose page with plate query param', async () => {
@ -78,7 +78,7 @@ describe('HomePage', () => {
await plateInput.vm.$emit('lookup', 'ABC123') await plateInput.vm.$emit('lookup', 'ABC123')
await new Promise((resolve) => setTimeout(resolve, 500)) await new Promise((resolve) => setTimeout(resolve, 500))
const cta = wrapper.find('.home__cta') const cta = wrapper.find('.btn--primary')
const href = cta.attributes('href') const href = cta.attributes('href')
expect(href).toBe('/compose?plate=ABC123') expect(href).toBe('/compose?plate=ABC123')
}) })

View file

@ -70,6 +70,23 @@ describe('LoginPage', () => {
expect(wrapper.find('#confirm-password').exists()).toBe(false) expect(wrapper.find('#confirm-password').exists()).toBe(false)
}) })
it('form element has method post and action', async () => {
const { wrapper } = mountPage()
const form = wrapper.find('form')
expect(form.attributes('method')).toBe('post')
expect(form.attributes('action')).toBe('/api/auth/login')
})
it('email input has name attribute', async () => {
const { wrapper } = mountPage()
expect(wrapper.find('#email').attributes('name')).toBe('email')
})
it('password input has name attribute', async () => {
const { wrapper } = mountPage()
expect(wrapper.find('#password').attributes('name')).toBe('password')
})
it('disables submit when fields are empty', async () => { it('disables submit when fields are empty', async () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
const button = wrapper.find('button[type="submit"]') const button = wrapper.find('button[type="submit"]')

View file

@ -136,7 +136,7 @@ describe('OrdersPage', () => {
vi.mocked(globalThis.fetch).mockResolvedValue(mockFetchResponse(200, [])) vi.mocked(globalThis.fetch).mockResolvedValue(mockFetchResponse(200, []))
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
expect(wrapper.text()).toContain('Du har inga beställningar ännu') expect(wrapper.text()).toContain('Inga beställningar ännu')
}) })
it('shows error state on API failure', async () => { it('shows error state on API failure', async () => {
@ -151,8 +151,8 @@ describe('OrdersPage', () => {
it('applies correct badge class for status', async () => { it('applies correct badge class for status', async () => {
const { wrapper } = mountPage() const { wrapper } = mountPage()
await new Promise((r) => setTimeout(r, 50)) await new Promise((r) => setTimeout(r, 50))
const badges = wrapper.findAll('.orders__badge') const badges = wrapper.findAll('.badge')
expect(badges[0].classes()).toContain('badge--green') expect(badges[0].classes()).toContain('badge--success')
expect(badges[1].classes()).toContain('badge--gray') expect(badges[1].classes()).toContain('badge--muted')
}) })
}) })

View file

@ -66,16 +66,16 @@ describe('PaymentRedirect', () => {
expect(wrapper.text()).toContain('ABC123') expect(wrapper.text()).toContain('ABC123')
}) })
it('shows Betalt button', async () => { it('shows payment button', async () => {
const { wrapper } = await mountPage() const { wrapper } = await mountPage()
const button = wrapper.find('.payment__button') const button = wrapper.find('.btn--primary')
expect(button.exists()).toBe(true) expect(button.exists()).toBe(true)
expect(button.text()).toBe('Betalt') expect(button.text()).toBe('Genomför testbetalning')
}) })
it('shows mock payment note', async () => { it('shows test payment note', async () => {
const { wrapper } = await mountPage() const { wrapper } = await mountPage()
expect(wrapper.text()).toContain('mock-betalning') expect(wrapper.text()).toContain('testbetalning')
}) })
it('calls payOrder on button click', async () => { it('calls payOrder on button click', async () => {
@ -89,7 +89,7 @@ describe('PaymentRedirect', () => {
}) })
const { wrapper } = await mountPage() const { wrapper } = await mountPage()
await wrapper.find('.payment__button').trigger('click') await wrapper.find('.btn--primary').trigger('click')
expect(mockPayOrder).toHaveBeenCalledWith('order-1') expect(mockPayOrder).toHaveBeenCalledWith('order-1')
}) })
@ -105,7 +105,7 @@ describe('PaymentRedirect', () => {
}) })
const { wrapper, router } = await mountPage() const { wrapper, router } = await mountPage()
await wrapper.find('.payment__button').trigger('click') await wrapper.find('.btn--primary').trigger('click')
await vi.waitFor(() => { await vi.waitFor(() => {
expect(router.currentRoute.value.name).toBe('orders') expect(router.currentRoute.value.name).toBe('orders')
@ -116,7 +116,7 @@ describe('PaymentRedirect', () => {
mockPayOrder.mockRejectedValue(new Error('Network error')) mockPayOrder.mockRejectedValue(new Error('Network error'))
const { wrapper } = await mountPage() const { wrapper } = await mountPage()
await wrapper.find('.payment__button').trigger('click') await wrapper.find('.btn--primary').trigger('click')
await vi.waitFor(() => { await vi.waitFor(() => {
expect(wrapper.text()).toContain('Kunde inte genomföra betalningen') expect(wrapper.text()).toContain('Kunde inte genomföra betalningen')
@ -127,7 +127,7 @@ describe('PaymentRedirect', () => {
mockPayOrder.mockImplementation(() => new Promise(() => {})) mockPayOrder.mockImplementation(() => new Promise(() => {}))
const { wrapper } = await mountPage() const { wrapper } = await mountPage()
const button = wrapper.find('.payment__button') const button = wrapper.find('.btn--primary')
await button.trigger('click') await button.trigger('click')
expect(button.attributes('disabled')).toBeDefined() expect(button.attributes('disabled')).toBeDefined()

View file

@ -24,7 +24,6 @@ describe('TemplatePicker', () => {
expect(wrapper.emitted('select')).toHaveLength(1) expect(wrapper.emitted('select')).toHaveLength(1)
expect(wrapper.emitted('select')![0][0]).toMatchObject({ expect(wrapper.emitted('select')![0][0]).toMatchObject({
name: 'Komplimang', name: 'Komplimang',
icon: '🌟',
}) })
}) })