Fix locale-related bugs and test it with screenshots
All checks were successful
/ check-changes (push) Successful in 5s
/ build (push) Successful in 3m20s

This commit is contained in:
Djuri Baars 2024-12-20 18:57:36 +01:00
parent 23529dbd4b
commit 924be8fc2e
6 changed files with 102 additions and 25 deletions

View file

@ -34,9 +34,17 @@ export default defineConfig({
}
},
{
name: 'MacBook Pro 14 inch',
name: 'MacBook Pro 14 inch NL locale',
use: {
viewport: { width: 1512, height: 982 }
viewport: { width: 1512, height: 982 },
locale: 'nl'
}
},
{
name: 'MacBook Pro 14 inch nl-NL locale',
use: {
viewport: { width: 1512, height: 982 },
locale: 'nl-NL'
}
},
{

View file

@ -8,11 +8,23 @@ register('nl', () => import('../locales/nl.json'));
register('es', () => import('../locales/es.json'));
register('de', () => import('../locales/de.json'));
const getInitialLocale = () => {
if (!browser) return defaultLocale;
// Check localStorage first
const storedLocale = localStorage.getItem('locale');
if (storedLocale) return storedLocale;
// Get browser locale and normalize it
const browserLocale = window.navigator.language;
const normalizedLocale = browserLocale.split('-')[0].toLowerCase();
// Check if we support this locale
const supportedLocales = ['en', 'nl', 'es', 'de'];
return supportedLocales.includes(normalizedLocale) ? normalizedLocale : defaultLocale;
};
init({
fallbackLocale: defaultLocale,
initialLocale: browser
? browser && localStorage.getItem('locale')
? localStorage.getItem('locale')
: window.navigator.language.slice(0, 2)
: defaultLocale
initialLocale: getInitialLocale()
});

View file

@ -17,6 +17,7 @@
import { page } from '$app/stores';
import { locale, locales, isLoading } from 'svelte-i18n';
import { ColorSchemeSwitcher } from '$lib/components';
import { derived } from 'svelte/store';
export const setLocale = (lang: string) => () => {
locale.set(lang);
@ -45,13 +46,14 @@
let languageNames = {};
locale.subscribe(() => {
if ($locale) {
let newLanguageNames = new Intl.DisplayNames([$locale], { type: 'language' });
const currentLocale = derived(locale, ($locale) => $locale || 'en');
for (let l of $locales) {
languageNames[l] = newLanguageNames.of(l);
}
locale.subscribe(() => {
const localeToUse = $locale || 'en';
let newLanguageNames = new Intl.DisplayNames([localeToUse], { type: 'language' });
for (let l of $locales) {
languageNames[l] = newLanguageNames.of(l) || l;
}
});
@ -95,7 +97,10 @@
</Nav>
{#if !$isLoading}
<Dropdown id="nav-language-dropdown" inNavbar class="me-3">
<DropdownToggle nav caret>{getFlagEmoji($locale)} {languageNames[$locale]}</DropdownToggle>
<DropdownToggle nav caret
>{getFlagEmoji($currentLocale)}
{languageNames[$currentLocale] || 'English'}</DropdownToggle
>
<DropdownMenu end>
{#each $locales as locale}
<DropdownItem on:click={setLocale(locale)}

View file

@ -6,10 +6,15 @@ import { locale, waitLocale } from 'svelte-i18n';
import type { LayoutLoad } from './$types';
export const load: LayoutLoad = async () => {
if (browser && localStorage.getItem('locale')) {
locale.set(localStorage.getItem('locale'));
} else if (browser) {
locale.set(window.navigator.language);
if (browser) {
if (localStorage.getItem('locale')) {
locale.set(localStorage.getItem('locale'));
} else {
// Normalize the browser locale
const browserLocale = window.navigator.language.split('-')[0].toLowerCase();
const supportedLocales = ['en', 'nl', 'es', 'de'];
locale.set(supportedLocales.includes(browserLocale) ? browserLocale : 'en');
}
}
await waitLocale();
};

View file

@ -4,11 +4,47 @@ import { initMock, settingsJson, statusJson } from '../shared';
test.beforeEach(initMock);
// Define the translations for the headings
const headings = {
en: {
control: 'Control',
status: 'Status',
settings: 'Settings',
language: 'English'
},
de: {
control: 'Steuerung',
status: 'Status',
settings: 'Einstellungen',
language: 'Deutsch'
},
nl: {
control: 'Besturing',
status: 'Status',
settings: 'Instellingen',
language: 'Nederlands'
},
es: {
control: 'Control',
status: 'Estado',
settings: 'Ajustes',
language: 'Español'
}
};
test('capture screenshots across devices', async ({ page }, testInfo) => {
// Get the locale from the browser or default to 'en'
const locale = testInfo.project.use?.locale?.split('-')[0].toLowerCase() || 'en';
const translations = headings[locale] || headings.en;
await page.goto('/');
await expect(page.getByRole('heading', { name: 'Control' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Status' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Settings' })).toBeVisible();
await expect(page.getByRole('heading', { name: translations.control })).toBeVisible();
await expect(page.getByRole('heading', { name: translations.status })).toBeVisible();
await expect(page.getByRole('heading', { name: translations.settings })).toBeVisible();
if (await page.locator('#nav-language-dropdown').isVisible()) {
await expect(page.getByRole('link', { name: translations.language })).toBeVisible();
}
const screenshot = await page.screenshot({
path: `./test-results/screenshots/default-${test.info().project.name.toLowerCase().replace(' ', '_')}.png`
@ -21,6 +57,9 @@ test('capture screenshots across devices', async ({ page }, testInfo) => {
});
test('capture screenshots across devices with bitaxe screens', async ({ page }, testInfo) => {
const locale = testInfo.project.use?.locale?.split('-')[0].toLowerCase() || 'en';
const translations = headings[locale] || headings.en;
settingsJson.screens = [
{
id: 0,
@ -73,9 +112,14 @@ test('capture screenshots across devices with bitaxe screens', async ({ page },
statusJson.rendered = ['mdi:bitaxe', '', 'mdi:pickaxe', '6', '3', '7', 'GH/S'];
await page.goto('/');
await expect(page.getByRole('heading', { name: 'Control' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Status' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Settings' })).toBeVisible();
await expect(page.getByRole('heading', { name: translations.control })).toBeVisible();
await expect(page.getByRole('heading', { name: translations.status })).toBeVisible();
await expect(page.getByRole('heading', { name: translations.settings })).toBeVisible();
if (await page.locator('#nav-language-dropdown').isVisible()) {
await expect(page.getByRole('link', { name: translations.language })).toBeVisible();
}
await page.screenshot({
path: `./test-results/screenshots/bitaxe-${test.info().project.name.toLowerCase().replace(' ', '_')}.png`

View file

@ -1,5 +1,5 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
import { defineConfig } from 'vite';
import GithubActionsReporter from 'vitest-github-actions-reporter';
// import { visualizer } from 'rollup-plugin-visualizer';
@ -102,5 +102,8 @@ export default defineConfig({
globals: true,
environment: 'jsdom',
reporters: process.env.GITHUB_ACTIONS ? ['default', new GithubActionsReporter()] : 'default'
},
define: {
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}
});