fix(e2e): fix locale cookie httpOnly and add hydration waits
Some checks failed
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
CI / Unit & Component Tests (pull_request) Has been cancelled
CI / Unit & Component Tests (push) Successful in 2m3s
CI / Backend Unit Tests (push) Successful in 2m13s
CI / E2E Tests (push) Successful in 17m49s
Some checks failed
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
CI / Unit & Component Tests (pull_request) Has been cancelled
CI / Unit & Component Tests (push) Successful in 2m3s
CI / Backend Unit Tests (push) Successful in 2m13s
CI / E2E Tests (push) Successful in 17m49s
Paraglide's client-side setLocale writes the locale via document.cookie,
which silently fails for HttpOnly cookies. SvelteKit's cookies.set()
defaults to httpOnly: true, so locale switching never worked in tests.
Fix by setting httpOnly: false on the locale cookie (it's a UI preference,
not a credential — no security concern).
Add waitForSelector('[data-hydrated]') before any click that relies on
SvelteKit JavaScript event handlers. Without this, the click fires before
hydration and the onclick handler is not yet registered.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #16.
This commit is contained in:
@@ -10,6 +10,7 @@ test.describe('Language selector', () => {
|
|||||||
|
|
||||||
test('switching to EN translates the navigation', async ({ page }) => {
|
test('switching to EN translates the navigation', async ({ page }) => {
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
||||||
await expect(page.getByRole('navigation').getByRole('link', { name: 'Documents' })).toBeVisible();
|
await expect(page.getByRole('navigation').getByRole('link', { name: 'Documents' })).toBeVisible();
|
||||||
await expect(page.getByRole('navigation').getByRole('link', { name: 'Persons' })).toBeVisible();
|
await expect(page.getByRole('navigation').getByRole('link', { name: 'Persons' })).toBeVisible();
|
||||||
@@ -17,6 +18,7 @@ test.describe('Language selector', () => {
|
|||||||
|
|
||||||
test('language choice persists after navigation', async ({ page }) => {
|
test('language choice persists after navigation', async ({ page }) => {
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
||||||
await page.goto('/persons');
|
await page.goto('/persons');
|
||||||
await expect(page.getByRole('navigation').getByRole('link', { name: 'Documents' })).toBeVisible();
|
await expect(page.getByRole('navigation').getByRole('link', { name: 'Documents' })).toBeVisible();
|
||||||
@@ -24,6 +26,7 @@ test.describe('Language selector', () => {
|
|||||||
|
|
||||||
test('switching back to DE restores German', async ({ page }) => {
|
test('switching back to DE restores German', async ({ page }) => {
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
||||||
await page.getByRole('banner').getByRole('button', { name: 'DE', exact: true }).click();
|
await page.getByRole('banner').getByRole('button', { name: 'DE', exact: true }).click();
|
||||||
await expect(page.getByRole('navigation').getByRole('link', { name: 'Dokumente' })).toBeVisible();
|
await expect(page.getByRole('navigation').getByRole('link', { name: 'Dokumente' })).toBeVisible();
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ test.describe('Conversations', () => {
|
|||||||
|
|
||||||
test('sort toggle changes the button label', async ({ page }) => {
|
test('sort toggle changes the button label', async ({ page }) => {
|
||||||
await page.goto('/conversations');
|
await page.goto('/conversations');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
const btn = page.getByRole('button', { name: /Sortierung/i });
|
const btn = page.getByRole('button', { name: /Sortierung/i });
|
||||||
await expect(btn).toContainText('Neueste zuerst');
|
await expect(btn).toContainText('Neueste zuerst');
|
||||||
await btn.click();
|
await btn.click();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const handleLocaleDetection: Handle = ({ event, resolve }) => {
|
|||||||
if (!event.cookies.get(cookieName)) {
|
if (!event.cookies.get(cookieName)) {
|
||||||
const locale = detectLocale(event.request.headers.get('accept-language') ?? '');
|
const locale = detectLocale(event.request.headers.get('accept-language') ?? '');
|
||||||
if (locale) {
|
if (locale) {
|
||||||
event.cookies.set(cookieName, locale, { path: '/', sameSite: 'lax', maxAge: cookieMaxAge });
|
event.cookies.set(cookieName, locale, { path: '/', sameSite: 'lax', maxAge: cookieMaxAge, httpOnly: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resolve(event);
|
return resolve(event);
|
||||||
|
|||||||
Reference in New Issue
Block a user