Files
when/apps/web/e2e/timezone.e2e.ts
eleith ff9c93af97
ci/woodpecker/pr/calendar Pipeline was successful
ci/woodpecker/pr/cli Pipeline was successful
ci/woodpecker/pr/config Pipeline was successful
ci/woodpecker/pr/db Pipeline was successful
ci/woodpecker/pr/jobs Pipeline was successful
ci/woodpecker/pr/video-chat Pipeline was successful
ci/woodpecker/pr/web Pipeline was successful
ci/woodpecker/pr/worker Pipeline was successful
ci/woodpecker/push/calendar Pipeline was successful
ci/woodpecker/push/cli Pipeline was successful
ci/woodpecker/push/config Pipeline was successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/jobs Pipeline was successful
ci/woodpecker/push/video-chat Pipeline was successful
ci/woodpecker/push/web Pipeline was successful
ci/woodpecker/push/worker Pipeline was successful
test(e2e): cover conditional forms and timezone booking contracts
2026-10-25 10:08:03 -07:00

78 lines
3.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { expect, test } from './support/test.ts';
import { readAppointment } from './support/database.ts';
import { CHAT_MEETING } from './support/seed.ts';
import { pickLastBookableDay, pickSlotFromEndOfDay } from './support/wizard.ts';
const timezone = 'Pacific/Kiritimati';
test.use({ timezoneId: timezone, locale: 'en-US' });
test('an absolute slot link books the same instant on the browser timezone’s next day', async ({
page,
context,
browser,
baseURL
}) => {
// Discover a real late UTC slot; availability belongs to the app, not this test.
const discovery = await browser.newPage({ baseURL, timezoneId: 'UTC' });
let slot: string;
try {
await discovery.goto(`/schedule/${CHAT_MEETING.slug}`);
await pickLastBookableDay(discovery);
await pickSlotFromEndOfDay(discovery);
await discovery.getByRole('button', { name: 'Confirm', exact: true }).click();
slot = await discovery.locator('input[name="slot"]').inputValue();
} finally {
await discovery.close();
}
const start = new Date(slot);
const end = new Date(start.getTime() + CHAT_MEETING.durationMinutes * 60_000);
const localFormat = (options: Intl.DateTimeFormatOptions) =>
new Intl.DateTimeFormat('en-US', { ...options, timeZone: timezone });
const compactDate = localFormat({ weekday: 'short', month: 'short', day: 'numeric' }).format(
start
);
const time = localFormat({ hour: '2-digit', minute: '2-digit' });
const shortTime = localFormat({ hour: 'numeric', minute: '2-digit' })
.format(start)
.replace(/\s+/g, '')
.toLowerCase();
const date = localFormat({ year: 'numeric', month: 'numeric', day: 'numeric' }).format(start);
expect(localFormat({ day: 'numeric' }).format(start)).not.toBe(String(start.getUTCDate()));
const initialCookies = await context.cookies();
expect(initialCookies.find((cookie) => cookie.name === 'tz')).toBeUndefined();
await page.goto(`/schedule/${CHAT_MEETING.slug}?slot=${encodeURIComponent(slot)}`);
await expect(page.getByRole('heading', { name: 'Step 3 of 3: Enter your info' })).toBeVisible();
await expect(
page.getByRole('paragraph').filter({ hasText: `${compactDate} at ${shortTime}` })
).toBeVisible();
await expect(page.locator('input[name="slot"]')).toHaveValue(slot);
await expect(page.locator('input[name="timezone"]')).toHaveValue(timezone);
const initializedCookies = await context.cookies();
expect(decodeURIComponent(initializedCookies.find((cookie) => cookie.name === 'tz')!.value)).toBe(
timezone
);
await page.getByLabel('What is your name?').fill('Timezone Guest');
await page.getByLabel('What is your email?').fill('timezone@example.test');
await page.getByRole('button', { name: 'Request', exact: true }).click();
await page.waitForURL(/\/appointment\/[^/?]+\?token=.+/);
await expect(page.getByRole('heading', { name: 'Appointment requested' })).toBeVisible();
const id = new URL(page.url()).pathname.split('/').at(-1)!;
const row = await readAppointment(id);
expect(Date.parse(row.start_time)).toBe(start.getTime());
expect(Date.parse(row.end_time)).toBe(end.getTime());
expect(row.guest_timezone).toBe(timezone);
await expect(page.getByText(date, { exact: true })).toBeVisible();
await expect(
page.getByText(`${time.format(start)} – ${time.format(end)}`, { exact: true })
).toBeVisible();
await page.reload();
await expect(page.getByText(date, { exact: true })).toBeVisible();
await expect(
page.getByText(`${time.format(start)} – ${time.format(end)}`, { exact: true })
).toBeVisible();
});