Phase 18: Auto timezone detection and ability to change timezone #21
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* timezone-verify.spec.ts — 18-04 round-trip verification
|
||||
*
|
||||
* Verifies the admin Timezone section with the real 18-02 API endpoints.
|
||||
* Runs on desktop profile only (admin UI is desktop-focused).
|
||||
*
|
||||
* NOTE: the IANA picker input is type="text" with list="iana-zones" which gives
|
||||
* it the ARIA combobox role (not textbox) in Chromium.
|
||||
*/
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('Admin Timezone section — 18-04 round-trip', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/admin');
|
||||
await expect(page.getByRole('heading', { name: 'Admin Settings' })).toBeVisible();
|
||||
// Wait for the Timezone section to load (requires the 18-02 GET endpoint)
|
||||
const tzSection = page.getByRole('region', { name: 'Timezone' });
|
||||
await expect(tzSection).toBeVisible({ timeout: 15_000 });
|
||||
});
|
||||
|
||||
test('Timezone section is visible on /admin', async ({ page }) => {
|
||||
await expect(page.getByRole('region', { name: 'Timezone' })).toBeVisible();
|
||||
});
|
||||
|
||||
test('Timezone input (combobox) is visible and pre-filled', async ({ page }) => {
|
||||
// ARIA role for <input type="text" list="iana-zones"> is combobox
|
||||
const input = page.getByRole('combobox', { name: 'Household timezone' });
|
||||
await expect(input).toBeVisible();
|
||||
const val = await input.inputValue();
|
||||
expect(val.length, 'Input should have a non-empty timezone').toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('Save button is disabled when timezone is unchanged', async ({ page }) => {
|
||||
const tzSection = page.getByRole('region', { name: 'Timezone' });
|
||||
const saveBtn = tzSection.getByRole('button', { name: /Save|Saving/ });
|
||||
await expect(saveBtn).toBeVisible();
|
||||
await expect(saveBtn).toBeDisabled();
|
||||
});
|
||||
|
||||
test('Changing the input enables Save', async ({ page }) => {
|
||||
const tzSection = page.getByRole('region', { name: 'Timezone' });
|
||||
const input = page.getByRole('combobox', { name: 'Household timezone' });
|
||||
await input.fill('America/Chicago');
|
||||
const saveBtn = tzSection.getByRole('button', { name: /Save/ });
|
||||
await expect(saveBtn).toBeEnabled();
|
||||
});
|
||||
|
||||
test('Save persists timezone across reload', async ({ page }) => {
|
||||
const input = page.getByRole('combobox', { name: 'Household timezone' });
|
||||
const tzSection = page.getByRole('region', { name: 'Timezone' });
|
||||
|
||||
// Set to a known value
|
||||
await input.fill('America/Chicago');
|
||||
const saveBtn = tzSection.getByRole('button', { name: /^Save$/ });
|
||||
await expect(saveBtn).toBeEnabled();
|
||||
await saveBtn.click();
|
||||
// Wait for save to complete (button re-disables when stored === input)
|
||||
await expect(saveBtn).toBeDisabled({ timeout: 15_000 });
|
||||
|
||||
// Reload and verify persistence
|
||||
await page.reload();
|
||||
await expect(page.getByRole('heading', { name: 'Admin Settings' })).toBeVisible();
|
||||
await expect(tzSection).toBeVisible({ timeout: 15_000 });
|
||||
const inputAfterReload = page.getByRole('combobox', { name: 'Household timezone' });
|
||||
await expect(inputAfterReload).toHaveValue('America/Chicago');
|
||||
|
||||
// system-default note should be gone after explicit set
|
||||
await expect(tzSection.getByText('Using system default')).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('"Use detected" affordance sets input to browser zone', async ({ page }) => {
|
||||
const tzSection = page.getByRole('region', { name: 'Timezone' });
|
||||
const detectedBtn = tzSection.getByRole('button', { name: /Use detected:/ });
|
||||
|
||||
// The button is only visible when detected TZ != stored TZ
|
||||
const count = await detectedBtn.count();
|
||||
if (count === 0) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the detected zone from the button label
|
||||
const btnText = await detectedBtn.textContent();
|
||||
const match = btnText?.match(/Use detected:\s*(.+)/);
|
||||
const detectedZone = match?.[1]?.trim();
|
||||
expect(detectedZone, 'Detected zone should be non-empty').toBeTruthy();
|
||||
|
||||
await detectedBtn.click();
|
||||
const input = page.getByRole('combobox', { name: 'Household timezone' });
|
||||
await expect(input).toHaveValue(detectedZone!);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user