trip) add day/week trip views (#52)
All checks were successful
Build and Push Image / docker-build-and-push (push) Successful in 2m19s

Reviewed-on: #52
Co-authored-by: AI Agent <ai-agent@campbellwireless.net>
Co-committed-by: AI Agent <ai-agent@campbellwireless.net>
This commit was merged in pull request #52.
This commit is contained in:
2026-02-24 20:17:26 +00:00
committed by shaun
parent 2003a1aada
commit 4aabf47108
9 changed files with 500 additions and 49 deletions

View File

@@ -12,7 +12,7 @@ export function uniqueSuffix(): string {
export async function createTrip(
page: Page,
values: { name: string; startDate?: string; description?: string }
values: { name: string; startDate?: string; endDate?: string; description?: string }
): Promise<{ tripUrl: string; tripId: string }> {
await page.goto(NEW_TRIP_URL);
await expect(page.getByRole('heading', { name: 'Plan New Trip' })).toBeVisible();
@@ -22,6 +22,9 @@ export async function createTrip(
} else {
await form.getByRole('checkbox', { name: "I don't know yet" }).first().check();
}
if (values.endDate) {
await form.getByLabel('End date').fill(values.endDate);
}
if (values.description) {
await form.getByLabel('Description').fill(values.description);
}

View File

@@ -10,7 +10,17 @@ import { TEST_USERS } from './test-users.js';
dotenvConfig({ path: resolve(process.cwd(), '.env.test'), override: true });
const DB_PATH = resolve(process.cwd(), 'trips.test.db');
function resolveDatabasePath(): string {
const rawUrl = process.env.DATABASE_URL;
if (rawUrl && rawUrl.startsWith('file:')) {
const rawPath = rawUrl.slice('file:'.length);
if (!rawPath) return resolve(process.cwd(), 'trips.test.db');
return rawPath.startsWith('/') ? rawPath : resolve(process.cwd(), rawPath);
}
return resolve(process.cwd(), 'trips.test.db');
}
const DB_PATH = resolveDatabasePath();
// Delete any existing test DB so we start clean each run
for (const ext of ['', '-shm', '-wal']) {
@@ -20,6 +30,7 @@ for (const ext of ['', '-shm', '-wal']) {
}
}
console.log(`[e2e] Using test database at ${DB_PATH}`);
const db = new BunSqlite(DB_PATH);
db.exec('PRAGMA foreign_keys = ON');
@@ -40,6 +51,7 @@ const dbWrapper = {
}
};
console.log('[e2e] Running migrations...');
const { runMigrations } = await import('../../src/lib/server/db/migrations.js');
runMigrations(dbWrapper);
console.log('[e2e] Migrations complete.');
@@ -53,6 +65,7 @@ async function hashPassword(password: string): Promise<string> {
});
}
console.log('[e2e] Creating test users...');
const regularId = randomUUID();
dbWrapper.run(
`INSERT INTO users (id, username, full_name, email, auth_source) VALUES (?, ?, ?, ?, ?)`,

View File

@@ -0,0 +1,70 @@
import { test, expect } from '@playwright/test';
import { TEST_USERS } from './setup/test-users.js';
import { loginAsLocalUser, ensureSelfProfile } from './helpers/auth.js';
import { createTrip, openAddToTripMenuItem, uniqueSuffix } from './helpers/trip.js';
function formatDate(offsetDays: number): string {
const date = new Date();
date.setDate(date.getDate() + offsetDays);
return date.toISOString().slice(0, 10);
}
async function addActivity(
page: import('@playwright/test').Page,
values: { name: string; startDate: string; startTime: string }
) {
await openAddToTripMenuItem(page, 'Attractions & Activities');
const dialog = page
.locator('[role="dialog"]')
.filter({ has: page.getByRole('heading', { name: /Attraction & activity/i }) })
.first();
await expect(dialog).toBeVisible();
await dialog.getByLabel('Name', { exact: false }).fill(values.name);
await dialog.getByLabel('Start date').fill(values.startDate);
await dialog.getByLabel('Start time', { exact: true }).fill(values.startTime);
await dialog.getByRole('button', { name: 'Add' }).click();
await expect(dialog).toBeHidden();
}
test.beforeEach(async ({ context }) => {
await context.clearCookies();
});
test('day and week views filter itinerary items', async ({ page }) => {
const suffix = uniqueSuffix();
const startDate = formatDate(0);
const endDate = formatDate(9);
const dayOneActivity = `Museum visit ${suffix}`;
const dayEightActivity = `Harbor walk ${suffix}`;
await loginAsLocalUser(page, TEST_USERS.regular.username, TEST_USERS.regular.password);
await ensureSelfProfile(page);
await createTrip(page, {
name: `E2E Date Views Trip ${suffix}`,
startDate,
endDate,
description: 'Date view coverage'
});
await addActivity(page, { name: dayOneActivity, startDate, startTime: '09:00' });
await addActivity(page, { name: dayEightActivity, startDate: formatDate(7), startTime: '11:00' });
await page.reload();
await expect(page.getByText(dayOneActivity)).toBeVisible();
await page.getByRole('button', { name: 'Day' }).click();
await expect(page.getByText('Day 1')).toBeVisible();
await expect(page.getByText(dayOneActivity)).toBeVisible();
await expect(page.getByText(dayEightActivity)).toBeHidden();
await page.getByRole('button', { name: 'Week' }).click();
await expect(page.getByText('Week 1')).toBeVisible();
await expect(page.getByText(dayOneActivity)).toBeVisible();
await expect(page.getByText(dayEightActivity)).toBeHidden();
await page.getByRole('button', { name: 'Next week' }).click();
await expect(page.getByText('Week 2')).toBeVisible();
await expect(page.getByText(dayEightActivity)).toBeVisible();
await expect(page.getByText(dayOneActivity)).toBeHidden();
});