-
Notifications
You must be signed in to change notification settings - Fork 462
/
basic_usage.spec.ts
357 lines (271 loc) · 14.6 KB
/
basic_usage.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
import { test, expect } from 'vitest'
import { fileURLToPath } from 'node:url'
import { setup, $fetch } from './utils'
import { assetLocaleHead, getData, getText, gotoPath, renderPage, waitForURL, getDom } from './helper'
await setup({
rootDir: fileURLToPath(new URL(`./fixtures/basic_usage`, import.meta.url)),
browser: true,
// prerender: true,
// overrides
nuxtConfig: {}
})
test('basic usage', async () => {
const { page } = await renderPage('/')
// vue-i18n using
expect(await getText(page, '#vue-i18n-usage p')).toEqual('Welcome')
// URL path localizing with `useLocalePath`
expect(await page.locator('#locale-path-usages .name a').getAttribute('href')).toEqual('/')
expect(await page.locator('#locale-path-usages .path a').getAttribute('href')).toEqual('/')
expect(await page.locator('#locale-path-usages .named-with-locale a').getAttribute('href')).toEqual('/fr')
expect(await page.locator('#locale-path-usages .nest-path a').getAttribute('href')).toEqual('/user/profile')
expect(await page.locator('#locale-path-usages .nest-named a').getAttribute('href')).toEqual('/user/profile')
expect(await page.locator('#locale-path-usages .object-with-named a').getAttribute('href')).toEqual(
'/category/nintendo'
)
// URL path localizing with `NuxtLinkLocale`
expect(await page.locator('#nuxt-link-locale-usages .name a').getAttribute('href')).toEqual('/')
expect(await page.locator('#nuxt-link-locale-usages .path a').getAttribute('href')).toEqual('/')
expect(await page.locator('#nuxt-link-locale-usages .named-with-locale a').getAttribute('href')).toEqual('/fr')
expect(await page.locator('#nuxt-link-locale-usages .nest-path a').getAttribute('href')).toEqual('/user/profile')
expect(await page.locator('#nuxt-link-locale-usages .nest-named a').getAttribute('href')).toEqual('/user/profile')
expect(await page.locator('#nuxt-link-locale-usages .object-with-named a').getAttribute('href')).toEqual(
'/category/nintendo'
)
expect(await page.locator('#nuxt-link-locale-usages .external-url a').getAttribute('href')).toEqual(
'https://nuxt.com/'
)
// Language switching path localizing with `useSwitchLocalePath`
expect(await page.locator('#switch-locale-path-usages .switch-to-en a').getAttribute('href')).toEqual('/')
expect(await page.locator('#switch-locale-path-usages .switch-to-fr a').getAttribute('href')).toEqual('/fr')
// URL path with Route object with `useLocaleRoute`
const button = await page.locator('#locale-route-usages button')
await button.click()
// await page.waitForURL('**/user/profile?foo=1')
expect(await getText(page, '#profile-page')).toEqual('This is profile page')
expect(await page.url()).include('/user/profile?foo=1')
})
test('register module hook', async () => {
const { page } = await renderPage('/')
expect(await getText(page, '#register-module')).toEqual('This is a merged module layer locale key')
// click `fr` lang switch link
await page.locator('.switch-to-fr a').click()
await waitForURL(page, '/fr')
expect(await getText(page, '#register-module')).toEqual('This is a merged module layer locale key in French')
})
test('vueI18n config file can access runtimeConfig', async () => {
const { page } = await renderPage('/')
expect(await getText(page, '#runtime-config')).toEqual('Hello from runtime config!')
})
test('layer provides locale `nl` and translation for key `hello`', async () => {
const { page } = await renderPage('/layer-page')
expect(await getText(page, '#i18n-layer-target')).toEqual('Hello world!')
expect(await page.locator('#i18n-layer-parent-link').getAttribute('href')).toEqual('/layer-parent')
expect(await page.locator('#i18n-layer-parent-child-link').getAttribute('href')).toEqual('/layer-parent/layer-child')
await gotoPath(page, '/nl/layer-page')
expect(await getText(page, '#i18n-layer-target')).toEqual('Hallo wereld!')
expect(await page.locator('#i18n-layer-parent-link').getAttribute('href')).toEqual('/nl/layer-ouder')
expect(await page.locator('#i18n-layer-parent-child-link').getAttribute('href')).toEqual('/nl/layer-ouder/layer-kind')
})
test('layer vueI18n options provides `nl` message', async () => {
const { page } = await renderPage('/nl')
expect(await getText(page, '#layer-message')).toEqual('Bedankt!')
})
test('layer vueI18n options properties are merge and override by priority', async () => {
const { page } = await renderPage('/')
expect(await getText(page, '#snake-case')).toEqual('About-this-site')
expect(await getText(page, '#pascal-case')).toEqual('AboutThisSite')
await page.click(`#switch-locale-path-usages .switch-to-fr a`)
await waitForURL(page, '/fr')
expect(await getText(page, '#snake-case')).toEqual('À-propos-de-ce-site')
expect(await getText(page, '#pascal-case')).toEqual('ÀProposDeCeSite')
expect(await getText(page, '#fallback-message')).toEqual('Unique translation')
})
test('load option successfully', async () => {
const { page } = await renderPage('/')
// click `fr` lang switch link
await page.locator('#switch-locale-path-usages .switch-to-fr a').click()
await waitForURL(page, '/fr')
expect(await getText(page, '#home-header')).toEqual('Bonjour-le-monde!')
// click `en` lang switch link
await page.locator('#switch-locale-path-usages .switch-to-en a').click()
await waitForURL(page, '/')
expect(await getText(page, '#home-header')).toEqual('Hello-world!')
})
test('(#1740) should be loaded vue-i18n related modules', async () => {
const { page } = await renderPage('/')
expect(await getText(page, '#app-config-name')).toEqual('This is Nuxt layer')
})
test('fallback to target lang', async () => {
const { page } = await renderPage('/')
// `en` rendering
expect(await getText(page, '#locale-path-usages .name a')).toEqual('Homepage')
expect(await getText(page, 'title')).toEqual('Page - Homepage')
expect(await getText(page, '#fallback-key')).toEqual('This is the fallback message!')
// click `nl` lang switch with `<NuxtLink>`
await page.locator('#switch-locale-path-usages .switch-to-nl a').click()
await waitForURL(page, '/nl')
// fallback to en content translation
expect(await getText(page, '#locale-path-usages .name a')).toEqual('Homepage')
expect(await getText(page, 'title')).toEqual('Page - Homepage')
expect(await getText(page, '#fallback-key')).toEqual('This is the fallback message!')
// page path
expect(await getData(page, '#home-use-async-data')).toMatchObject({ aboutPath: '/nl/about' })
// current locale
expect(await getText(page, '#lang-switcher-current-locale code')).toEqual('nl')
})
test('(#2525) localePath should keep hash', async () => {
const { page } = await renderPage('/')
expect(await page.locator('#link-about-hash').getAttribute('href')).toEqual('/about#my-hash')
expect(await page.locator('#link-about-hash-object').getAttribute('href')).toEqual('/about#my-hash')
expect(await page.locator('#link-about-query-hash').getAttribute('href')).toEqual('/about?foo=bar#my-hash')
expect(await page.locator('#link-about-query-hash-object').getAttribute('href')).toEqual('/about?foo=bar#my-hash')
// click `nl` lang switch with `<NuxtLink>`
await page.locator('#switch-locale-path-usages .switch-to-nl a').click()
await waitForURL(page, '/nl')
expect(await page.locator('#link-about-hash').getAttribute('href')).toEqual('/nl/about#my-hash')
expect(await page.locator('#link-about-hash-object').getAttribute('href')).toEqual('/nl/about#my-hash')
expect(await page.locator('#link-about-query-hash').getAttribute('href')).toEqual('/nl/about?foo=bar#my-hash')
expect(await page.locator('#link-about-query-hash-object').getAttribute('href')).toEqual('/nl/about?foo=bar#my-hash')
})
test('(#2523) localePath should not double encode paths', async () => {
const { page } = await renderPage('/')
const encodedPath = encodeURI('page with spaces')
expect(await page.locator('#link-page-with-spaces').getAttribute('href')).toEqual(`/${encodedPath}`)
expect(await page.locator('#link-page-with-spaces-encoded').getAttribute('href')).toEqual(`/${encodedPath}`)
// click `nl` lang switch with `<NuxtLink>`
await page.locator('#switch-locale-path-usages .switch-to-nl a').click()
await waitForURL(page, '/nl')
expect(await page.locator('#link-page-with-spaces').getAttribute('href')).toEqual(`/nl/${encodedPath}`)
expect(await page.locator('#link-page-with-spaces-encoded').getAttribute('href')).toEqual(`/nl/${encodedPath}`)
})
test('(#2476) Parametrized messages can be overwritten', async () => {
const { page } = await renderPage('/')
expect(await getText(page, '#module-layer-base-key')).toEqual('Layer base key overwritten!')
expect(await getText(page, '#module-layer-base-key-named')).toEqual('Layer base key overwritten, greetings bar!')
})
test('(#2338) should be extended API', async () => {
const { page } = await renderPage('/')
const globalData = await getData(page, '#global-scope-properties')
expect(globalData.code).toEqual('en')
const localeData = await getData(page, '#local-scope-properties')
expect(localeData.code).toEqual('en')
})
test('<NuxtLink> triggers runtime hooks', async () => {
const { page, consoleLogs } = await renderPage('/kr')
// click `fr` lang switch with `<NuxtLink>`
await page.locator('#nuxt-locale-link-fr').click()
await waitForURL(page, '/fr')
// click `kr` lang switch with `<NuxtLink>`
await page.locator('#nuxt-locale-link-kr').click()
await waitForURL(page, '/kr')
expect(consoleLogs.find(log => log.text.includes('onBeforeLanguageSwitch kr fr true'))).toBeTruthy()
expect(consoleLogs.find(log => log.text.includes('onBeforeLanguageSwitch fr kr false'))).toBeTruthy()
expect(consoleLogs.find(log => log.text.includes('onLanguageSwitched kr fr'))).toBeTruthy()
// current locale
expect(await getText(page, '#lang-switcher-current-locale code')).toEqual('fr')
// navigate to about page
await page.locator('#link-about').click()
await waitForURL(page, '/fr/about')
// navigate to home page
await page.locator('#link-home').click()
await waitForURL(page, '/fr')
})
test('setLocale triggers runtime hooks', async () => {
const { page, consoleLogs } = await renderPage('/kr')
// click `fr` lang switch link
await page.locator('#set-locale-link-fr').click()
// click `kr` lang switch link
// Hook prevents locale change to `kr`, stays `fr`
await page.locator('#set-locale-link-kr').click()
expect(consoleLogs.find(log => log.text.includes('onBeforeLanguageSwitch kr fr true'))).toBeTruthy()
expect(consoleLogs.find(log => log.text.includes('onLanguageSwitched kr fr'))).toBeTruthy()
expect(consoleLogs.find(log => log.text.includes('onBeforeLanguageSwitch fr kr false'))).toBeTruthy()
// current locale
expect(await getText(page, '#lang-switcher-current-locale code')).toEqual('fr')
})
test('render with meta components', async () => {
const { page } = await renderPage('/')
/**
* default locale
*/
// title tag
expect(await getText(page, 'title')).toMatch('Page - Homepage')
await waitForURL(page, '/')
// html tag `lang` attribute
expect(await page.getAttribute('html', 'lang')).toMatch('en')
// html tag `dir` attribute
expect(await page.getAttribute('html', 'dir')).toMatch('ltr')
// rendering link tag and meta tag in head tag
await assetLocaleHead(page, '#layout-use-locale-head')
/**
* change locale
*/
// click `fr` lang switch link
await page.locator('#nuxt-locale-link-fr').click()
await waitForURL(page, '/fr')
// title tag
expect(await getText(page, 'title')).toMatch('Page - Accueil')
// html tag `lang` attribute
expect(await page.getAttribute('html', 'lang')).toMatch('fr')
// rendering link tag and meta tag in head tag
await assetLocaleHead(page, '#layout-use-locale-head')
/**
* access to other page
*/
// click about page
await page.locator('#link-about').click()
await waitForURL(page, '/fr/about')
// title tag
expect(await getText(page, 'title')).toMatch('Page - À propos')
// html tag `lang` attribute
expect(await page.getAttribute('html', 'lang')).toMatch('fr')
// rendering link tag and meta tag in head tag
await assetLocaleHead(page, '#layout-use-locale-head')
})
test('server integration extended from `layers/layer-server`', async () => {
const res = await $fetch('/api/server', { query: { key: 'snakeCaseText' } })
expect(res?.snakeCaseText).toMatch('About-this-site')
// LocaleDetector: header
const resHeader = await $fetch('/api/server', {
query: { key: 'snakeCaseText' },
headers: { 'Accept-Language': 'fr' }
})
expect(resHeader?.snakeCaseText).toMatch('À-propos-de-ce-site')
// LocaleDetector: cookie
const resCookie = await $fetch('/api/server', {
query: { key: 'snakeCaseText' },
headers: { cookie: 'i18n_locale=fr;' }
})
expect(resCookie?.snakeCaseText).toMatch('À-propos-de-ce-site')
// LocaleDetector: query
const resQuery = await $fetch('/api/server', { query: { key: 'snakeCaseText', locale: 'fr' } })
expect(resQuery?.snakeCaseText).toMatch('À-propos-de-ce-site')
// yaml, json5 resource
const enRes = await $fetch('/api/server', { query: { key: 'server-key', locale: 'en' } })
expect(enRes?.['server-key']).toMatch('Hello!')
const jaRes = await $fetch('/api/server', { query: { key: 'server-key', locale: 'ja' } })
expect(jaRes?.['server-key']).toMatch('こんにちは!')
})
test('dynamic parameters', async () => {
const { page } = await renderPage('/products/big-chair')
expect(await page.locator('#nuxt-locale-link-nl').getAttribute('href')).toEqual('/nl/products/grote-stoel')
await gotoPath(page, '/nl/products/rode-mok')
await page.waitForFunction(
() => document.querySelector('#nuxt-locale-link-en')?.getAttribute('href') === '/products/red-mug'
)
expect(await page.locator('#nuxt-locale-link-en').getAttribute('href')).toEqual('/products/red-mug')
// Translated params are not lost on query changes
await page.locator('#params-add-query').click()
await waitForURL(page, '/nl/products/rode-mok?test=123')
expect(await page.locator('#nuxt-locale-link-en').getAttribute('href')).toEqual('/products/red-mug?test=123')
await page.locator('#params-remove-query').click()
await waitForURL(page, '/nl/products/rode-mok')
expect(await page.locator('#nuxt-locale-link-en').getAttribute('href')).toEqual('/products/red-mug')
// head tags - alt links are updated server side
const product1Html = await $fetch('/products/big-chair')
const product1Dom = getDom(product1Html)
expect(product1Dom.querySelector('#i18n-alt-nl').href).toEqual('/nl/products/grote-stoel')
const product2Html = await $fetch('/nl/products/rode-mok')
const product2dom = getDom(product2Html)
expect(product2dom.querySelector('#i18n-alt-en').href).toEqual('/products/red-mug')
})