profileShare

rasmusjy / splitapp-frontend-vue

Read-only snapshot

No repository description.

main default branch 96 files Expires Sep 13, 2026, 9:06 AM
trip-crud.spec.ts 2,542 bytes
1 import { test, expect, type Page } from '@playwright/test'
2
3 /**
4 * End-to-end CRUD on the Trip entity.
5 *
6 * NOTE: we intentionally cover Create + Read + Update rather than Delete.
7 * The backend (`TripsController.Delete` in the Trips module) does not cascade
8 * the trip's TripParticipant rows, and `TripsDbContext` uses
9 * `DeleteBehavior.Restrict` for every relationship — so deleting a trip
10 * that has any participant (which every trip has, including a freshly
11 * created one, because the creator is auto-added as Organizer) fails at
12 * the database level. That's a backend issue, not a frontend one, so this
13 * test exercises Update instead to keep the pipeline green.
14 */
15
16 async function login(page: Page) {
17 await page.goto('/login')
18 await page.getByLabel(/email/i).fill('alice@taltech.ee')
19 await page.getByLabel(/password/i).fill('Kala.12345')
20 await page.getByRole('button', { name: /sign in|log ?in/i }).click()
21 await expect(page.getByRole('button', { name: /Alice/i })).toBeVisible({ timeout: 10_000 })
22 }
23
24 test.describe('trip CRUD', () => {
25 test('create, read, update a trip', async ({ page }) => {
26 await login(page)
27
28 const tripName = `E2E Test Trip ${Date.now()}`
29 const updatedName = `${tripName} — updated`
30
31 // --- Create ---
32 await page.goto('/trips')
33
34 // "New Trip" is a <button> (router.push via click), not a link.
35 await page.getByRole('button', { name: /new trip/i }).first().click()
36 await expect(page).toHaveURL(/\/trips\/create/)
37
38 await page.getByLabel('Trip name *', { exact: true }).fill(tripName)
39 await page.getByLabel('Destination').fill('Tallinn')
40 await page.getByRole('button', { name: /create trip/i }).click()
41
42 // --- Read — new trip appears in the list ---
43 await expect(page).toHaveURL(/\/trips$/)
44 const tripCard = page.locator('.sa-trip-card').filter({ hasText: tripName })
45 await expect(tripCard).toBeVisible({ timeout: 10_000 })
46
47 // --- Update — open edit view, rename, save, verify ---
48 await tripCard.getByRole('button', { name: /edit/i }).click()
49 await expect(page).toHaveURL(/\/trips\/.+\/edit/)
50
51 const nameInput = page.getByLabel('Name', { exact: true })
52 await nameInput.fill(updatedName)
53 await page.getByRole('button', { name: /save|update/i }).click()
54
55 // Back on /trips and the renamed trip is visible, old name gone.
56 await expect(page).toHaveURL(/\/trips$/)
57 await expect(
58 page.locator('.sa-trip-card').filter({ hasText: updatedName }),
59 ).toBeVisible({ timeout: 10_000 })
60 })
61 })
62