diff --git a/src/runtime/plugins/01.plugin.ts b/src/runtime/plugins/01.plugin.ts index 3612b77b..899397fc 100644 --- a/src/runtime/plugins/01.plugin.ts +++ b/src/runtime/plugins/01.plugin.ts @@ -1,7 +1,7 @@ import type { NavigationFailure, RouteLocationNormalizedLoaded, - RouteLocationRaw, + RouteLocationRaw, RouteLocationResolved, RouteLocationResolvedGeneric, Router, } from 'vue-router' @@ -59,7 +59,6 @@ function switchLocaleRoute(fromLocale: string, i18nConfig: ModuleOptionsExtend, i18nRouteParams: I18nRouteParams, ): RouteLocationRaw { - const routeName = getRouteName(route, fromLocale) if (router.hasRoute(`localized-${routeName}-${toLocale}`)) { // const newParams = { ...route.params } @@ -130,7 +129,7 @@ function getLocalizedRoute( i18nConfig: ModuleOptionsExtend, locale?: string, hashLocale?: string | null, -): RouteLocationRaw { +): RouteLocationResolved { const currentLocale = locale || getCurrentLocale(route, i18nConfig, hashLocale) const selectRoute = router.resolve(to) const routeName = getRouteName(selectRoute, currentLocale) @@ -353,7 +352,7 @@ export default defineNuxtPlugin(async (nuxtApp) => { } switchLocale(fromLocale, toLocale, route, router, i18nConfig, i18nRouteParams.value) }, - localeRoute: (to: RouteLocationRaw, locale?: string): RouteLocationRaw => { + localeRoute: (to: RouteLocationRaw, locale?: string): RouteLocationResolved => { const router = useRouter() const route = useRoute() return getLocalizedRoute(to, router, route, i18nConfig, locale, hashLocale) @@ -361,7 +360,7 @@ export default defineNuxtPlugin(async (nuxtApp) => { localePath: (to: RouteLocationRaw, locale?: string): string => { const router = useRouter() const route = useRoute() - let localeRoute = getLocalizedRoute(to, router, route, i18nConfig, locale, hashLocale) + const localeRoute = getLocalizedRoute(to, router, route, i18nConfig, locale, hashLocale) if (typeof localeRoute === 'string') { return localeRoute } @@ -403,7 +402,7 @@ export interface PluginsInjections { $switchLocaleRoute: (locale: string) => RouteLocationRaw $switchLocalePath: (locale: string) => string $switchLocale: (locale: string) => void - $localeRoute: (to: RouteLocationRaw, locale?: string) => RouteLocationRaw + $localeRoute: (to: RouteLocationRaw, locale?: string) => RouteLocationResolved $localePath: (to: RouteLocationRaw, locale?: string) => string $loadPageTranslations: (locale: string, routeName: string) => Promise $setI18nRouteParams: (value: I18nRouteParams) => I18nRouteParams diff --git a/test/basic.test.ts b/test/basic.test.ts index fd6b6f79..bd71a343 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -5,6 +5,10 @@ test.use({ nuxt: { rootDir: fileURLToPath(new URL('./fixtures/basic', import.meta.url)), }, + // launchOptions: { + // headless: false, // Показывать браузер + // slowMo: 500, // Замедлить выполнение шагов (в миллисекундах) для лучшей видимости + // }, }) test('test index', async ({ page, goto }) => { @@ -246,3 +250,132 @@ test('Test globalLocaleRoutes for page2 and unlocalized', async ({ page, goto }) const response = await page.goto('/de/unlocalized', { waitUntil: 'networkidle' }) expect(response?.status()).toBe(404) }) + +test('test navigation and locale switching on news page', async ({ page, goto }) => { + // Переход на страницу /news/1 + await goto('/news/1', { waitUntil: 'hydration' }) + + // Проверяем наличие id и данных news + await expect(page.locator('.news-id')).toHaveText('id: 1') + await expect(page.locator('.news-data')).toBeVisible() + + // Проверяем переходы по ссылкам + await page.click('.link-article-1') + await expect(page).toHaveURL('/articles/1') + + await goto('/news/1', { waitUntil: 'hydration' }) // Возвращаемся на страницу /news/1 + await page.click('.link-news-4') + await expect(page).toHaveURL('/news/4') + + // Проверяем переключение локалей + await page.click('.locale-en') + await expect(page).toHaveURL('/news/4') + + await page.click('.locale-ru') + await expect(page).toHaveURL('/ru/news/4') + + await page.click('.locale-de') + await expect(page).toHaveURL('/de/news/4') +}) + +test('test query parameters and hash on news page', async ({ page, goto }) => { + await goto('/news/2?a=b#tada', { waitUntil: 'hydration' }) + + // Проверяем, что id и query параметры корректно отображаются + await expect(page.locator('.news-id')).toHaveText('id: 2') + await expect(page).toHaveURL('/news/2?a=b#tada') + + // Проверяем, что localeRoute корректно работает с query и hash + await page.click('.link-news-2') + await expect(page).toHaveURL('/news/2?a=b') +}) + +test('test navigation and locale switching on articles page', async ({ page, goto }) => { + // Navigate to the /articles/1 page + await goto('/articles/1', { waitUntil: 'hydration' }) + + // Check the presence of the id and article data + await expect(page.locator('.article-id')).toHaveText('id: 1') + await expect(page.locator('.article-data')).toBeVisible() + + // Check the link transition to the news + await page.click('.link-news-1') + await expect(page).toHaveURL('/news/1') + + // Check locale switching + await goto('/articles/1', { waitUntil: 'hydration' }) // Return to /articles/1 + await page.click('.locale-en') + await expect(page).toHaveURL('/articles/1') + + await page.click('.locale-ru') + await expect(page).toHaveURL('/ru/articles/1') + + await page.click('.locale-de') + await expect(page).toHaveURL('/de/articles/1') +}) + +test('test locale switching and content on locale-conf page', async ({ page, goto }) => { + await goto('/', { waitUntil: 'hydration' }) + await goto('/locale-conf', { waitUntil: 'hydration' }) + + await page.waitForTimeout(500) + + // Check the page title in English + const titleEn = await page.locator('h1').textContent() + expect(titleEn).toBe('Locale Test Page') + + // Check the page content in English + const contentEn = await page.locator('#content').textContent() + expect(contentEn).toBe('This is a content area.') + + const greetingEn = await page.locator('#username').textContent() + expect(greetingEn).toBe('Hello, John!') + + const pluralEn = await page.locator('#plural').textContent() + expect(pluralEn).toBe('You have 2 items.') + + const htmlContentEn = await page.locator('#html-content').innerHTML() + expect(htmlContentEn).toContain('Bold Text with HTML content.') + + const localeRouteEn = await page.locator('.locale-route-data:nth-of-type(1)').textContent() + expect(localeRouteEn).toContain('"fullPath": "/locale-conf"') + expect(localeRouteEn).toContain('"name": "locale-conf"') + expect(localeRouteEn).toContain('"href": "/locale-conf"') + + // Check the first $switchLocaleRoute link in English + const switchLocaleRouteEn = await page.locator('#locale-en').getAttribute('href') + expect(switchLocaleRouteEn).toContain('/locale-conf') + + // Check the second $switchLocaleRoute link in German + const switchLocaleRouteDe = await page.locator('#locale-de').getAttribute('href') + expect(switchLocaleRouteDe).toContain('/de/locale-conf-modif') + + // Click on the element + await page.click('#locale-de') + + await expect(page).toHaveURL('/de/locale-conf-modify') + + // Check the page title in German + const titleDe = await page.locator('h1').textContent() + expect(titleDe).toBe('Sprachtestseite') + + // Check the page content in German + const contentDe = await page.locator('#content').textContent() + expect(contentDe).toBe('Dies ist ein Inhaltsbereich.') + + const greetingDe = await page.locator('#username').textContent() + expect(greetingDe).toBe('Hallo, John!') + + const pluralDe = await page.locator('#plural').textContent() + expect(pluralDe).toBe('Sie haben 2 Artikel.') + + const htmlContentDe = await page.locator('#html-content').innerHTML() + expect(htmlContentDe).toContain('Fetter Text mit HTML-Inhalt.') + + const switchLocaleRouteEnN = await page.locator('#locale-en').getAttribute('href') + expect(switchLocaleRouteEnN).toContain('/locale-conf') + + // Check the second $switchLocaleRoute link in German + const switchLocaleRouteDeN = await page.locator('#locale-de').getAttribute('href') + expect(switchLocaleRouteDeN).toContain('/de/locale-conf-modif') +}) diff --git a/test/fixtures/basic/pages/articles/[id].vue b/test/fixtures/basic/pages/articles/[id].vue new file mode 100644 index 00000000..6a46fe0a --- /dev/null +++ b/test/fixtures/basic/pages/articles/[id].vue @@ -0,0 +1,56 @@ + + + + + diff --git a/test/fixtures/basic/pages/locale-conf.vue b/test/fixtures/basic/pages/locale-conf.vue new file mode 100644 index 00000000..4de7c581 --- /dev/null +++ b/test/fixtures/basic/pages/locale-conf.vue @@ -0,0 +1,83 @@ + + + diff --git a/test/fixtures/basic/pages/news/[id].vue b/test/fixtures/basic/pages/news/[id].vue new file mode 100644 index 00000000..0160b5eb --- /dev/null +++ b/test/fixtures/basic/pages/news/[id].vue @@ -0,0 +1,95 @@ + + + diff --git a/test/fixtures/basic/server/api/getArticles.js b/test/fixtures/basic/server/api/getArticles.js new file mode 100644 index 00000000..e4bbc5ed --- /dev/null +++ b/test/fixtures/basic/server/api/getArticles.js @@ -0,0 +1,8 @@ +import { defineEventHandler, getQuery } from 'h3' + +export default defineEventHandler((event) => { + const { id } = getQuery(event) + return { + id: id, + } +}) diff --git a/test/fixtures/basic/server/api/getNews.js b/test/fixtures/basic/server/api/getNews.js new file mode 100644 index 00000000..5e0238e4 --- /dev/null +++ b/test/fixtures/basic/server/api/getNews.js @@ -0,0 +1,25 @@ +import { defineEventHandler, getQuery } from 'h3' + +export default defineEventHandler((event) => { + const { id } = getQuery(event) + let metadata = null + + if (id === '1' || id.startsWith('1-')) { + metadata = { + en: { id: '1-one' }, + de: { id: '1-eins' }, + ru: { id: '1-odin' }, + } + } + if (id === '2' || id.startsWith('2-')) { + metadata = { + en: { id: '2-two' }, + de: { id: '2-zwei' }, + ru: { id: '2-dva' }, + } + } + return { + id: id, + metadata, + } +}) diff --git a/test/fixtures/basic/server/tsconfig.json b/test/fixtures/basic/server/tsconfig.json new file mode 100644 index 00000000..b9ed69c1 --- /dev/null +++ b/test/fixtures/basic/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +}