@@ -14,7 +14,9 @@ import {
1414 fetchViaHTTP ,
1515 File ,
1616 launchApp ,
17+ check ,
1718} from 'next-test-utils'
19+ import assert from 'assert'
1820
1921const appDir = join ( __dirname , '../' )
2022const nextConfig = new File ( join ( appDir , 'next.config.js' ) )
@@ -291,121 +293,187 @@ describe('i18n Support', () => {
291293 } )
292294
293295 describe ( 'with trailingSlash: true' , ( ) => {
294- const curCtx = {
295- ...ctx ,
296- isDev : true ,
297- }
298- beforeAll ( async ( ) => {
299- await fs . remove ( join ( appDir , '.next' ) )
300- nextConfig . replace ( '// trailingSlash' , 'trailingSlash' )
301-
302- curCtx . appPort = await findPort ( )
303- curCtx . app = await launchApp ( appDir , curCtx . appPort )
304- } )
305- afterAll ( async ( ) => {
306- nextConfig . restore ( )
307- await killApp ( curCtx . app )
308- } )
296+ const runSlashTests = ( curCtx ) => {
297+ if ( ! curCtx . isDev ) {
298+ it ( 'should preload all locales data correctly' , async ( ) => {
299+ const browser = await webdriver (
300+ curCtx . appPort ,
301+ `${ curCtx . basePath } /mixed`
302+ )
309303
310- it ( 'should redirect correctly' , async ( ) => {
311- for ( const locale of nonDomainLocales ) {
312- const res = await fetchViaHTTP ( curCtx . appPort , '/' , undefined , {
313- redirect : 'manual' ,
314- headers : {
315- 'accept-language' : locale ,
316- } ,
304+ await browser . eval ( `(function() {
305+ document.querySelector('#to-gsp-en-us').scrollIntoView()
306+ document.querySelector('#to-gsp-nl-nl').scrollIntoView()
307+ document.querySelector('#to-gsp-fr').scrollIntoView()
308+ })()` )
309+
310+ await check ( async ( ) => {
311+ const hrefs = await browser . eval (
312+ `Object.keys(window.next.router.sdc)`
313+ )
314+ hrefs . sort ( )
315+
316+ assert . deepEqual (
317+ hrefs . map ( ( href ) =>
318+ new URL ( href ) . pathname
319+ . replace ( ctx . basePath , '' )
320+ . replace ( / ^ \/ _ n e x t \/ d a t a \/ [ ^ / ] + / , '' )
321+ ) ,
322+ [ '/en-US/gsp.json' , '/fr.json' , '/fr/gsp.json' , '/nl-NL/gsp.json' ]
323+ )
324+ return 'yes'
325+ } , 'yes' )
317326 } )
327+ }
318328
319- if ( locale === 'en-US' ) {
320- expect ( res . status ) . toBe ( 200 )
321- } else {
322- expect ( res . status ) . toBe ( 307 )
329+ it ( 'should redirect correctly' , async ( ) => {
330+ for ( const locale of nonDomainLocales ) {
331+ const res = await fetchViaHTTP ( curCtx . appPort , '/' , undefined , {
332+ redirect : 'manual' ,
333+ headers : {
334+ 'accept-language' : locale ,
335+ } ,
336+ } )
323337
324- const parsed = url . parse ( res . headers . get ( 'location' ) , true )
325- expect ( parsed . pathname ) . toBe ( `/${ locale } ` )
326- expect ( parsed . query ) . toEqual ( { } )
338+ if ( locale === 'en-US' ) {
339+ expect ( res . status ) . toBe ( 200 )
340+ } else {
341+ expect ( res . status ) . toBe ( 307 )
342+
343+ const parsed = url . parse ( res . headers . get ( 'location' ) , true )
344+ expect ( parsed . pathname ) . toBe ( `/${ locale } ` )
345+ expect ( parsed . query ) . toEqual ( { } )
346+ }
327347 }
328- }
329- } )
348+ } )
330349
331- it ( 'should serve pages correctly with locale prefix' , async ( ) => {
332- for ( const locale of nonDomainLocales ) {
333- for ( const [ pathname , asPath ] of [
334- [ '/' , '/' ] ,
335- [ '/links' , '/links/' ] ,
336- [ '/auto-export' , '/auto-export/' ] ,
337- [ '/gsp' , '/gsp/' ] ,
338- [ '/gsp/fallback/[slug]' , '/gsp/fallback/always/' ] ,
339- [ '/gssp' , '/gssp/' ] ,
340- [ '/gssp/[slug]' , '/gssp/first/' ] ,
341- ] ) {
342- const res = await fetchViaHTTP (
343- curCtx . appPort ,
344- `${ locale === 'en-US' ? '' : `/${ locale } ` } ${ asPath } ` ,
345- undefined ,
346- {
347- redirect : 'manual' ,
348- }
349- )
350- expect ( res . status ) . toBe ( 200 )
350+ it ( 'should serve pages correctly with locale prefix' , async ( ) => {
351+ for ( const locale of nonDomainLocales ) {
352+ for ( const [ pathname , asPath ] of [
353+ [ '/' , '/' ] ,
354+ [ '/links' , '/links/' ] ,
355+ [ '/auto-export' , '/auto-export/' ] ,
356+ [ '/gsp' , '/gsp/' ] ,
357+ [ '/gsp/fallback/[slug]' , '/gsp/fallback/always/' ] ,
358+ [ '/gssp' , '/gssp/' ] ,
359+ [ '/gssp/[slug]' , '/gssp/first/' ] ,
360+ ] ) {
361+ const res = await fetchViaHTTP (
362+ curCtx . appPort ,
363+ `${ locale === 'en-US' ? '' : `/${ locale } ` } ${ asPath } ` ,
364+ undefined ,
365+ {
366+ redirect : 'manual' ,
367+ }
368+ )
369+ expect ( res . status ) . toBe ( 200 )
370+
371+ const $ = cheerio . load ( await res . text ( ) )
372+
373+ expect ( $ ( '#router-pathname' ) . text ( ) ) . toBe ( pathname )
374+ expect ( $ ( '#router-as-path' ) . text ( ) ) . toBe ( asPath )
375+ expect ( $ ( '#router-locale' ) . text ( ) ) . toBe ( locale )
376+ expect ( JSON . parse ( $ ( '#router-locales' ) . text ( ) ) ) . toEqual ( locales )
377+ expect ( $ ( '#router-default-locale' ) . text ( ) ) . toBe ( 'en-US' )
378+ }
379+ }
380+ } )
351381
352- const $ = cheerio . load ( await res . text ( ) )
382+ it ( 'should navigate between pages correctly' , async ( ) => {
383+ for ( const locale of nonDomainLocales ) {
384+ const localePath = `/${ locale !== 'en-US' ? `${ locale } /` : '' } `
385+ const browser = await webdriver ( curCtx . appPort , localePath )
353386
354- expect ( $ ( '#router-pathname' ) . text ( ) ) . toBe ( pathname )
355- expect ( $ ( '#router-as-path' ) . text ( ) ) . toBe ( asPath )
356- expect ( $ ( '#router-locale' ) . text ( ) ) . toBe ( locale )
357- expect ( JSON . parse ( $ ( '#router-locales' ) . text ( ) ) ) . toEqual ( locales )
358- expect ( $ ( '#router-default-locale' ) . text ( ) ) . toBe ( 'en-US' )
359- }
360- }
361- } )
387+ await browser . eval ( 'window.beforeNav = 1' )
388+ await browser . elementByCss ( '#to-gsp' ) . click ( )
389+ await browser . waitForElementByCss ( '#gsp' )
362390
363- it ( 'should navigate between pages correctly' , async ( ) => {
364- for ( const locale of nonDomainLocales ) {
365- const localePath = `/${ locale !== 'en-US' ? `${ locale } /` : '' } `
366- const browser = await webdriver ( curCtx . appPort , localePath )
391+ expect ( await browser . elementByCss ( '#router-pathname' ) . text ( ) ) . toBe (
392+ '/gsp'
393+ )
394+ expect ( await browser . elementByCss ( '#router-as-path' ) . text ( ) ) . toBe (
395+ '/gsp/'
396+ )
397+ expect ( await browser . elementByCss ( '#router-locale' ) . text ( ) ) . toBe (
398+ locale
399+ )
400+ expect ( await browser . eval ( 'window.beforeNav' ) ) . toBe ( 1 )
401+ expect ( await browser . eval ( 'window.location.pathname' ) ) . toBe (
402+ `${ localePath } gsp/`
403+ )
367404
368- await browser . eval ( 'window.beforeNav = 1' )
369- await browser . elementByCss ( '#to-gsp' ) . click ( )
370- await browser . waitForElementByCss ( '#gsp' )
405+ await browser . back ( ) . waitForElementByCss ( '#index' )
371406
372- expect ( await browser . elementByCss ( '#router-pathname' ) . text ( ) ) . toBe (
373- '/gsp '
374- )
375- expect ( await browser . elementByCss ( '#router-as-path' ) . text ( ) ) . toBe (
376- '/gsp/'
377- )
378- expect ( await browser . elementByCss ( '#router-locale' ) . text ( ) ) . toBe ( locale )
379- expect ( await browser . eval ( 'window.beforeNav' ) ) . toBe ( 1 )
380- expect ( await browser . eval ( 'window.location.pathname' ) ) . toBe (
381- `${ localePath } gsp/ `
382- )
407+ expect ( await browser . elementByCss ( '#router-pathname' ) . text ( ) ) . toBe (
408+ '/ '
409+ )
410+ expect ( await browser . elementByCss ( '#router-as-path' ) . text ( ) ) . toBe ( '/' )
411+ expect ( await browser . elementByCss ( '#router-locale' ) . text ( ) ) . toBe (
412+ locale
413+ )
414+ expect ( await browser . eval ( 'window.beforeNav' ) ) . toBe ( 1 )
415+ expect ( await browser . eval ( 'window.location.pathname' ) ) . toBe (
416+ `${ localePath } `
417+ )
383418
384- await browser . back ( ) . waitForElementByCss ( '#index' )
419+ await browser . elementByCss ( '#to-gssp-slug' ) . click ( )
420+ await browser . waitForElementByCss ( '#gssp' )
385421
386- expect ( await browser . elementByCss ( '#router-pathname' ) . text ( ) ) . toBe ( '/' )
387- expect ( await browser . elementByCss ( '#router-as-path' ) . text ( ) ) . toBe ( '/' )
388- expect ( await browser . elementByCss ( '#router-locale' ) . text ( ) ) . toBe ( locale )
389- expect ( await browser . eval ( 'window.beforeNav' ) ) . toBe ( 1 )
390- expect ( await browser . eval ( 'window.location.pathname' ) ) . toBe (
391- `${ localePath } `
392- )
422+ expect ( await browser . elementByCss ( '#router-pathname' ) . text ( ) ) . toBe (
423+ '/gssp/[slug]'
424+ )
425+ expect ( await browser . elementByCss ( '#router-as-path' ) . text ( ) ) . toBe (
426+ '/gssp/first/'
427+ )
428+ expect ( await browser . elementByCss ( '#router-locale' ) . text ( ) ) . toBe (
429+ locale
430+ )
431+ expect ( await browser . eval ( 'window.beforeNav' ) ) . toBe ( 1 )
432+ expect ( await browser . eval ( 'window.location.pathname' ) ) . toBe (
433+ `${ localePath } gssp/first/`
434+ )
435+ }
436+ } )
437+ }
393438
394- await browser . elementByCss ( '#to-gssp-slug' ) . click ( )
395- await browser . waitForElementByCss ( '#gssp' )
439+ describe ( 'dev mode' , ( ) => {
440+ const curCtx = {
441+ ...ctx ,
442+ isDev : true ,
443+ }
444+ beforeAll ( async ( ) => {
445+ await fs . remove ( join ( appDir , '.next' ) )
446+ nextConfig . replace ( '// trailingSlash' , 'trailingSlash' )
396447
397- expect ( await browser . elementByCss ( '#router-pathname' ) . text ( ) ) . toBe (
398- '/gssp/[slug]'
399- )
400- expect ( await browser . elementByCss ( '#router-as-path' ) . text ( ) ) . toBe (
401- '/gssp/first/'
402- )
403- expect ( await browser . elementByCss ( '#router-locale' ) . text ( ) ) . toBe ( locale )
404- expect ( await browser . eval ( 'window.beforeNav' ) ) . toBe ( 1 )
405- expect ( await browser . eval ( 'window.location.pathname' ) ) . toBe (
406- `${ localePath } gssp/first/`
407- )
448+ curCtx . appPort = await findPort ( )
449+ curCtx . app = await launchApp ( appDir , curCtx . appPort )
450+ } )
451+ afterAll ( async ( ) => {
452+ nextConfig . restore ( )
453+ await killApp ( curCtx . app )
454+ } )
455+
456+ runSlashTests ( curCtx )
457+ } )
458+
459+ describe ( 'production mode' , ( ) => {
460+ const curCtx = {
461+ ...ctx ,
408462 }
463+ beforeAll ( async ( ) => {
464+ await fs . remove ( join ( appDir , '.next' ) )
465+ nextConfig . replace ( '// trailingSlash' , 'trailingSlash' )
466+
467+ await nextBuild ( appDir )
468+ curCtx . appPort = await findPort ( )
469+ curCtx . app = await nextStart ( appDir , curCtx . appPort )
470+ } )
471+ afterAll ( async ( ) => {
472+ nextConfig . restore ( )
473+ await killApp ( curCtx . app )
474+ } )
475+
476+ runSlashTests ( curCtx )
409477 } )
410478 } )
411479} )
0 commit comments