1
1
import {
2
+ act ,
2
3
cleanup ,
3
4
configure ,
4
5
fireEvent ,
@@ -17,6 +18,7 @@ import {
17
18
createRootRoute ,
18
19
createRoute ,
19
20
createRouter ,
21
+ useRouter ,
20
22
} from '../src'
21
23
22
24
import { sleep } from './utils'
@@ -380,7 +382,7 @@ test('reproducer #4245', async () => {
380
382
381
383
render ( < RouterProvider router = { router } /> )
382
384
// We wait for the initial loader to complete
383
- await router . load ( )
385
+ await act ( ( ) => router . load ( ) )
384
386
const fooLink = await screen . findByTestId ( 'link-to-foo' )
385
387
386
388
expect ( fooLink ) . toBeInTheDocument ( )
@@ -389,27 +391,257 @@ test('reproducer #4245', async () => {
389
391
fireEvent . click ( fooLink )
390
392
391
393
// We immediately see the content of the foo route
392
- const indexLink = await screen . findByTestId ( 'link-to-index' )
394
+ const indexLink = await screen . findByTestId ( 'link-to-index' , undefined , {
395
+ timeout : WAIT_TIME ,
396
+ } )
393
397
expect ( indexLink ) . toBeInTheDocument ( )
394
398
395
399
// We navigate to the index route
396
400
fireEvent . click ( indexLink )
397
401
398
402
// We immediately see the content of the index route because the stale data is still available
399
- const fooLink2 = await screen . findByTestId ( 'link-to-foo' )
403
+ const fooLink2 = await screen . findByTestId ( 'link-to-foo' , undefined , {
404
+ timeout : WAIT_TIME ,
405
+ } )
400
406
expect ( fooLink2 ) . toBeInTheDocument ( )
401
407
402
408
// We navigate to the foo route again
403
409
fireEvent . click ( fooLink2 )
404
410
405
411
// We immediately see the content of the foo route
406
- const indexLink2 = await screen . findByTestId ( 'link-to-index' )
412
+ const indexLink2 = await screen . findByTestId ( 'link-to-index' , undefined , {
413
+ timeout : WAIT_TIME ,
414
+ } )
407
415
expect ( indexLink2 ) . toBeInTheDocument ( )
408
416
409
417
// We navigate to the index route again
410
418
fireEvent . click ( indexLink2 )
411
419
412
420
// We now should see the content of the index route immediately because the stale data is still available
413
- const fooLink3 = await screen . findByTestId ( 'link-to-foo' )
421
+ const fooLink3 = await screen . findByTestId ( 'link-to-foo' , undefined , {
422
+ timeout : WAIT_TIME ,
423
+ } )
414
424
expect ( fooLink3 ) . toBeInTheDocument ( )
415
425
} )
426
+
427
+ test ( 'reproducer #4546' , async ( ) => {
428
+ const rootRoute = createRootRoute ( {
429
+ component : ( ) => {
430
+ return (
431
+ < >
432
+ < div className = "p-2 flex gap-2 text-lg" >
433
+ < Link
434
+ data-testid = "link-to-index"
435
+ to = "/"
436
+ activeProps = { {
437
+ className : 'font-bold' ,
438
+ } }
439
+ activeOptions = { { exact : true } }
440
+ >
441
+ Home
442
+ </ Link > { ' ' }
443
+ < Link
444
+ data-testid = "link-to-id"
445
+ to = "$id"
446
+ params = { {
447
+ id : '1' ,
448
+ } }
449
+ activeProps = { {
450
+ className : 'font-bold' ,
451
+ } }
452
+ >
453
+ /1
454
+ </ Link >
455
+ </ div >
456
+ < hr />
457
+ < Outlet />
458
+ </ >
459
+ )
460
+ } ,
461
+ } )
462
+
463
+ let counter = 0
464
+ const appRoute = createRoute ( {
465
+ getParentRoute : ( ) => rootRoute ,
466
+ id : '_app' ,
467
+ beforeLoad : ( ) => {
468
+ counter += 1
469
+ return {
470
+ counter,
471
+ }
472
+ } ,
473
+ component : ( ) => {
474
+ return (
475
+ < div >
476
+ < Header />
477
+ < Outlet />
478
+ </ div >
479
+ )
480
+ } ,
481
+ } )
482
+
483
+ function Header ( ) {
484
+ const router = useRouter ( )
485
+ const { counter } = appRoute . useRouteContext ( )
486
+
487
+ return (
488
+ < div >
489
+ Header Counter: < p data-testid = "header-counter" > { counter } </ p >
490
+ < button
491
+ onClick = { ( ) => {
492
+ router . invalidate ( )
493
+ } }
494
+ data-testid = "invalidate-router"
495
+ style = { {
496
+ border : '1px solid blue' ,
497
+ } }
498
+ >
499
+ Invalidate router
500
+ </ button >
501
+ </ div >
502
+ )
503
+ }
504
+
505
+ const indexRoute = createRoute ( {
506
+ getParentRoute : ( ) => appRoute ,
507
+ path : '/' ,
508
+ loader : ( { context } ) => {
509
+ return {
510
+ counter : context . counter ,
511
+ }
512
+ } ,
513
+
514
+ component : ( ) => {
515
+ const data = indexRoute . useLoaderData ( )
516
+ const ctx = indexRoute . useRouteContext ( )
517
+
518
+ return (
519
+ < div
520
+ style = { {
521
+ display : 'flex' ,
522
+ flexDirection : 'column' ,
523
+ } }
524
+ >
525
+ < div > Index route</ div >
526
+ < div >
527
+ route context:{ ' ' }
528
+ < p data-testid = "index-route-context" > { ctx . counter } </ p >
529
+ </ div >
530
+ < div >
531
+ loader data: < p data-testid = "index-loader-data" > { data . counter } </ p >
532
+ </ div >
533
+ </ div >
534
+ )
535
+ } ,
536
+ } )
537
+ const idRoute = createRoute ( {
538
+ getParentRoute : ( ) => appRoute ,
539
+ path : '$id' ,
540
+ loader : ( { context } ) => {
541
+ return {
542
+ counter : context . counter ,
543
+ }
544
+ } ,
545
+
546
+ component : ( ) => {
547
+ const data = idRoute . useLoaderData ( )
548
+ const ctx = idRoute . useRouteContext ( )
549
+
550
+ return (
551
+ < div
552
+ style = { {
553
+ display : 'flex' ,
554
+ flexDirection : 'column' ,
555
+ } }
556
+ >
557
+ < div > $id route</ div >
558
+ < div >
559
+ route context: < p data-testid = "id-route-context" > { ctx . counter } </ p >
560
+ </ div >
561
+ < div >
562
+ loader data: < p data-testid = "id-loader-data" > { data . counter } </ p >
563
+ </ div >
564
+ </ div >
565
+ )
566
+ } ,
567
+ } )
568
+
569
+ const routeTree = rootRoute . addChildren ( [
570
+ appRoute . addChildren ( [ indexRoute , idRoute ] ) ,
571
+ ] )
572
+ const router = createRouter ( { routeTree } )
573
+
574
+ render ( < RouterProvider router = { router } /> )
575
+
576
+ const indexLink = await screen . findByTestId ( 'link-to-index' )
577
+ expect ( indexLink ) . toBeInTheDocument ( )
578
+
579
+ const idLink = await screen . findByTestId ( 'link-to-id' )
580
+ expect ( idLink ) . toBeInTheDocument ( )
581
+
582
+ const invalidateRouterButton = await screen . findByTestId ( 'invalidate-router' )
583
+ expect ( invalidateRouterButton ) . toBeInTheDocument ( )
584
+
585
+ {
586
+ const headerCounter = await screen . findByTestId ( 'header-counter' )
587
+ expect ( headerCounter ) . toHaveTextContent ( '1' )
588
+
589
+ const routeContext = await screen . findByTestId ( 'index-route-context' )
590
+ expect ( routeContext ) . toHaveTextContent ( '1' )
591
+
592
+ const loaderData = await screen . findByTestId ( 'index-loader-data' )
593
+ expect ( loaderData ) . toHaveTextContent ( '1' )
594
+ }
595
+
596
+ fireEvent . click ( idLink )
597
+
598
+ {
599
+ const headerCounter = await screen . findByTestId ( 'header-counter' )
600
+ expect ( headerCounter ) . toHaveTextContent ( '2' )
601
+
602
+ const routeContext = await screen . findByTestId ( 'id-route-context' )
603
+ expect ( routeContext ) . toHaveTextContent ( '2' )
604
+
605
+ const loaderData = await screen . findByTestId ( 'id-loader-data' )
606
+ expect ( loaderData ) . toHaveTextContent ( '2' )
607
+ }
608
+
609
+ fireEvent . click ( indexLink )
610
+
611
+ {
612
+ const headerCounter = await screen . findByTestId ( 'header-counter' )
613
+ expect ( headerCounter ) . toHaveTextContent ( '3' )
614
+
615
+ const routeContext = await screen . findByTestId ( 'index-route-context' )
616
+ expect ( routeContext ) . toHaveTextContent ( '3' )
617
+
618
+ const loaderData = await screen . findByTestId ( 'index-loader-data' )
619
+ expect ( loaderData ) . toHaveTextContent ( '3' )
620
+ }
621
+
622
+ fireEvent . click ( invalidateRouterButton )
623
+
624
+ {
625
+ const headerCounter = await screen . findByTestId ( 'header-counter' )
626
+ expect ( headerCounter ) . toHaveTextContent ( '4' )
627
+
628
+ const routeContext = await screen . findByTestId ( 'index-route-context' )
629
+ expect ( routeContext ) . toHaveTextContent ( '4' )
630
+
631
+ const loaderData = await screen . findByTestId ( 'index-loader-data' )
632
+ expect ( loaderData ) . toHaveTextContent ( '4' )
633
+ }
634
+
635
+ fireEvent . click ( idLink )
636
+
637
+ {
638
+ const headerCounter = await screen . findByTestId ( 'header-counter' )
639
+ expect ( headerCounter ) . toHaveTextContent ( '5' )
640
+
641
+ const routeContext = await screen . findByTestId ( 'id-route-context' )
642
+ expect ( routeContext ) . toHaveTextContent ( '5' )
643
+
644
+ const loaderData = await screen . findByTestId ( 'id-loader-data' )
645
+ expect ( loaderData ) . toHaveTextContent ( '5' )
646
+ }
647
+ } )
0 commit comments