e2e) add medium-priority playwright coverage
All checks were successful
PR Checks / lint-test-and-docker-build (pull_request) Successful in 2m18s
All checks were successful
PR Checks / lint-test-and-docker-build (pull_request) Successful in 2m18s
This commit is contained in:
27
e2e/helpers/auth.ts
Normal file
27
e2e/helpers/auth.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { expect, type Page } from '@playwright/test';
|
||||
import { TEST_USERS } from '../setup/test-users.js';
|
||||
|
||||
const LOGIN_URL = '/trips/login';
|
||||
const DASHBOARD_URL = '/trips/dashboard';
|
||||
const PROFILE_URL = '/trips/profile';
|
||||
|
||||
export async function loginAsLocalUser(
|
||||
page: Page,
|
||||
username: string,
|
||||
password: string
|
||||
): Promise<void> {
|
||||
await page.goto(LOGIN_URL);
|
||||
await page.fill('input[name="identifier"]', username);
|
||||
await page.fill('input[name="password"]', password);
|
||||
await page.click('button[type="submit"]:has-text("Sign in locally")');
|
||||
await page.waitForURL(`**${DASHBOARD_URL}`, { timeout: 15_000 });
|
||||
}
|
||||
|
||||
export async function ensureSelfProfile(page: Page, email = TEST_USERS.regular.email): Promise<void> {
|
||||
await page.goto(PROFILE_URL);
|
||||
await page.fill('#first_name', 'E2E');
|
||||
await page.fill('#last_name', 'User');
|
||||
await page.fill('#email', email);
|
||||
await page.getByRole('button', { name: 'Save profile' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'My Profile' })).toBeVisible();
|
||||
}
|
||||
142
e2e/helpers/trip.ts
Normal file
142
e2e/helpers/trip.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import { expect, type Page } from '@playwright/test';
|
||||
|
||||
const NEW_TRIP_URL = '/trips/trips/new';
|
||||
|
||||
export function uniqueSuffix(): string {
|
||||
return `${Date.now()}-${Math.floor(Math.random() * 1000)}`;
|
||||
}
|
||||
|
||||
export async function createTrip(
|
||||
page: Page,
|
||||
values: { name: string; startDate?: string; description?: string }
|
||||
): Promise<{ tripUrl: string; tripId: string }> {
|
||||
await page.goto(NEW_TRIP_URL);
|
||||
await expect(page.getByRole('heading', { name: 'Plan New Trip' })).toBeVisible();
|
||||
await page.getByLabel('Trip name', { exact: false }).fill(values.name);
|
||||
if (values.startDate) {
|
||||
await page.getByLabel('Start date').fill(values.startDate);
|
||||
}
|
||||
if (values.description) {
|
||||
await page.getByLabel('Description').fill(values.description);
|
||||
}
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await page.waitForURL('**/trips/trips/*', { timeout: 15_000 });
|
||||
const tripUrl = page.url();
|
||||
const tripId = tripUrl.split('/').pop() ?? '';
|
||||
return { tripUrl, tripId };
|
||||
}
|
||||
|
||||
export async function openAddToTripMenuItem(page: Page, label: string): Promise<void> {
|
||||
const addToTripButton = page.getByRole('button', { name: 'Add to trip' });
|
||||
if (await addToTripButton.isVisible().catch(() => false)) {
|
||||
await addToTripButton.click();
|
||||
await page.getByRole('button', { name: label, exact: true }).click();
|
||||
return;
|
||||
}
|
||||
await page.getByRole('button', { name: label, exact: true }).click();
|
||||
}
|
||||
|
||||
export async function openAddTraveller(page: Page): Promise<void> {
|
||||
const addToTripButton = page.getByRole('button', { name: 'Add to trip' });
|
||||
if (await addToTripButton.isVisible().catch(() => false)) {
|
||||
await addToTripButton.click();
|
||||
await page.getByRole('button', { name: 'Travellers', exact: true }).click();
|
||||
return;
|
||||
}
|
||||
await page.getByRole('button', { name: "Who's travelling?" }).click();
|
||||
}
|
||||
|
||||
export async function addTraveller(
|
||||
page: Page,
|
||||
values: { firstName: string; lastName: string; email?: string }
|
||||
): Promise<void> {
|
||||
await openAddTraveller(page);
|
||||
const dialog = page.getByRole('dialog', { name: 'Add traveller' });
|
||||
await expect(dialog).toBeVisible();
|
||||
|
||||
const addNewButton = dialog.getByRole('button', { name: 'Add someone new' });
|
||||
if (await addNewButton.isVisible().catch(() => false)) {
|
||||
await addNewButton.click();
|
||||
}
|
||||
|
||||
await dialog.getByLabel('First name', { exact: false }).fill(values.firstName);
|
||||
await dialog.getByLabel('Last name', { exact: false }).fill(values.lastName);
|
||||
if (values.email) {
|
||||
await dialog.getByLabel(/Email/).fill(values.email);
|
||||
}
|
||||
await dialog.getByRole('button', { name: 'Add traveller' }).click();
|
||||
await expect(dialog).toBeHidden();
|
||||
}
|
||||
|
||||
export async function addFlight(
|
||||
page: Page,
|
||||
values: {
|
||||
departureDate: string;
|
||||
airlineCode: string;
|
||||
flightNumber: string;
|
||||
departureAirport: string;
|
||||
arrivalAirport: string;
|
||||
}
|
||||
): Promise<void> {
|
||||
await openAddToTripMenuItem(page, 'Transportation');
|
||||
const dialog = page.getByRole('dialog', { name: 'Add transportation' });
|
||||
await expect(dialog).toBeVisible();
|
||||
|
||||
await dialog.getByRole('button', { name: 'Flight', exact: true }).click();
|
||||
const form = dialog.locator('form');
|
||||
await expect(form.getByLabel('Departure date')).toBeVisible();
|
||||
await form.getByLabel('Departure date').fill(values.departureDate);
|
||||
await form.getByLabel('Airline').fill(values.airlineCode);
|
||||
await form.getByLabel('Flight number').fill(values.flightNumber);
|
||||
await form.getByLabel('Departure airport').fill(values.departureAirport);
|
||||
await form.getByLabel('Arrival airport').fill(values.arrivalAirport);
|
||||
await form.getByRole('button', { name: 'Add transportation' }).click();
|
||||
await expect(dialog).toBeHidden();
|
||||
}
|
||||
|
||||
export async function addLodging(
|
||||
page: Page,
|
||||
values: { name: string; guestNames?: string[] }
|
||||
): Promise<void> {
|
||||
await openAddToTripMenuItem(page, 'Lodgings');
|
||||
const dialog = page.getByRole('dialog', { name: 'Add lodging' });
|
||||
await expect(dialog).toBeVisible();
|
||||
|
||||
await dialog.getByLabel('Name', { exact: false }).fill(values.name);
|
||||
for (const guestName of values.guestNames ?? []) {
|
||||
await dialog.getByRole('checkbox', { name: guestName }).check();
|
||||
}
|
||||
await dialog.getByRole('button', { name: 'Add lodging' }).click();
|
||||
await expect(dialog).toBeHidden();
|
||||
}
|
||||
|
||||
export async function addPackingList(
|
||||
page: Page,
|
||||
values: { name: string; items: string[] }
|
||||
): Promise<void> {
|
||||
await openAddToTripMenuItem(page, 'Packing List');
|
||||
const dialog = page.getByRole('dialog', { name: /Packing list/i });
|
||||
await expect(dialog).toBeVisible();
|
||||
|
||||
await dialog.getByLabel('Name', { exact: false }).fill(values.name);
|
||||
const itemInputs = dialog.getByPlaceholder('Item');
|
||||
await itemInputs.first().fill(values.items[0]);
|
||||
for (const item of values.items.slice(1)) {
|
||||
await dialog.getByRole('button', { name: 'Add item' }).click();
|
||||
await itemInputs.last().fill(item);
|
||||
}
|
||||
await dialog.getByRole('button', { name: 'Add' }).click();
|
||||
await expect(dialog).toBeHidden();
|
||||
}
|
||||
|
||||
export async function addActivity(
|
||||
page: Page,
|
||||
values: { name: string }
|
||||
): Promise<void> {
|
||||
await openAddToTripMenuItem(page, 'Attractions & Activities');
|
||||
const dialog = page.getByRole('dialog', { name: /Attraction & activity/i });
|
||||
await expect(dialog).toBeVisible();
|
||||
await dialog.getByLabel('Name', { exact: false }).fill(values.name);
|
||||
await dialog.getByRole('button', { name: 'Add' }).click();
|
||||
await expect(dialog).toBeHidden();
|
||||
}
|
||||
Reference in New Issue
Block a user