@@ -655,256 +655,6 @@ test.describe("ErrorBoundary", () => {
655655 } ) ;
656656} ) ;
657657
658- test . describe ( "loaderData in ErrorBoundary" , ( ) => {
659- let fixture : Fixture ;
660- let appFixture : AppFixture ;
661- let consoleErrors : string [ ] ;
662- let oldConsoleError : ( ) => void ;
663-
664- test . beforeAll ( async ( ) => {
665- fixture = await createFixture ( {
666- files : {
667- "app/root.tsx" : js `
668- import { Links, Meta, Outlet, Scripts } from "react-router";
669-
670- export default function Root() {
671- return (
672- <html lang="en">
673- <head>
674- <Meta />
675- <Links />
676- </head>
677- <body>
678- <main>
679- <Outlet />
680- </main>
681- <Scripts />
682- </body>
683- </html>
684- );
685- }
686- ` ,
687-
688- "app/routes/parent.tsx" : js `
689- import { Outlet, useLoaderData, useMatches, useRouteError } from "react-router";
690-
691- export function loader() {
692- return "PARENT";
693- }
694-
695- export default function () {
696- return (
697- <div>
698- <p id="parent-data">{useLoaderData()}</p>
699- <Outlet />
700- </div>
701- )
702- }
703-
704- export function ErrorBoundary() {
705- let error = useRouteError();
706- return (
707- <>
708- <p id="parent-data">{useLoaderData()}</p>
709- <p id="parent-matches-data">
710- {useMatches().find(m => m.id === 'routes/parent').data}
711- </p>
712- <p id="parent-error">{error.message}</p>
713- </>
714- );
715- }
716- ` ,
717-
718- "app/routes/parent.child-with-boundary.tsx" : js `
719- import { Form, useLoaderData, useRouteError } from "react-router";
720-
721- export function loader() {
722- return "CHILD";
723- }
724-
725- export function action() {
726- throw new Error("Broken!");
727- }
728-
729- export default function () {
730- return (
731- <>
732- <p id="child-data">{useLoaderData()}</p>
733- <Form method="post">
734- <button type="submit" name="key" value="value">
735- Submit
736- </button>
737- </Form>
738- </>
739- )
740- }
741-
742- export function ErrorBoundary() {
743- let error = useRouteError();
744- return (
745- <>
746- <p id="child-data">{useLoaderData()}</p>
747- <p id="child-error">{error.message}</p>
748- </>
749- );
750- }
751- ` ,
752-
753- "app/routes/parent.child-without-boundary.tsx" : js `
754- import { Form, useLoaderData } from "react-router";
755-
756- export function loader() {
757- return "CHILD";
758- }
759-
760- export function action() {
761- throw new Error("Broken!");
762- }
763-
764- export default function () {
765- return (
766- <>
767- <p id="child-data">{useLoaderData()}</p>
768- <Form method="post">
769- <button type="submit" name="key" value="value">
770- Submit
771- </button>
772- </Form>
773- </>
774- )
775- }
776- ` ,
777- } ,
778- } ) ;
779-
780- appFixture = await createAppFixture ( fixture , ServerMode . Development ) ;
781- } ) ;
782-
783- test . afterAll ( ( ) => {
784- appFixture . close ( ) ;
785- } ) ;
786-
787- test . beforeEach ( ( { page } ) => {
788- oldConsoleError = console . error ;
789- console . error = ( ) => { } ;
790- consoleErrors = [ ] ;
791- // Listen for all console events and handle errors
792- page . on ( "console" , ( msg ) => {
793- if ( msg . type ( ) === "error" ) {
794- consoleErrors . push ( msg . text ( ) ) ;
795- }
796- } ) ;
797- } ) ;
798-
799- test . afterEach ( ( ) => {
800- console . error = oldConsoleError ;
801- } ) ;
802-
803- test . describe ( "without JavaScript" , ( ) => {
804- test . use ( { javaScriptEnabled : false } ) ;
805- runBoundaryTests ( ) ;
806- } ) ;
807-
808- test . describe ( "with JavaScript" , ( ) => {
809- test . use ( { javaScriptEnabled : true } ) ;
810- runBoundaryTests ( ) ;
811- } ) ;
812-
813- function runBoundaryTests ( ) {
814- test ( "Prevents useLoaderData in self ErrorBoundary" , async ( {
815- page,
816- javaScriptEnabled,
817- } ) => {
818- let app = new PlaywrightFixture ( appFixture , page ) ;
819- await app . goto ( "/parent/child-with-boundary" ) ;
820-
821- expect ( await app . getHtml ( "#parent-data" ) ) . toEqual (
822- '<p id="parent-data">PARENT</p>'
823- ) ;
824- expect ( await app . getHtml ( "#child-data" ) ) . toEqual (
825- '<p id="child-data">CHILD</p>'
826- ) ;
827- expect ( consoleErrors ) . toEqual ( [ ] ) ;
828-
829- await app . clickSubmitButton ( "/parent/child-with-boundary" ) ;
830- await page . waitForSelector ( "#child-error" ) ;
831-
832- expect ( await app . getHtml ( "#child-error" ) ) . toEqual (
833- '<p id="child-error">Broken!</p>'
834- ) ;
835- expect ( await app . getHtml ( "#parent-data" ) ) . toEqual (
836- '<p id="parent-data">PARENT</p>'
837- ) ;
838- expect ( await app . getHtml ( "#child-data" ) ) . toEqual (
839- '<p id="child-data"></p>'
840- ) ;
841-
842- // Only look for this message. Chromium browsers will also log the
843- // network error but firefox does not
844- // "Failed to load resource: the server responded with a status of 500 (Internal Server Error)",
845- let msg =
846- "You cannot `useLoaderData` in an errorElement (routeId: routes/parent.child-with-boundary)" ;
847- if ( javaScriptEnabled ) {
848- expect ( consoleErrors . filter ( ( m ) => m === msg ) ) . toEqual ( [ msg ] ) ;
849- } else {
850- // We don't get the useLoaderData message in the client when JS is disabled
851- expect ( consoleErrors . filter ( ( m ) => m === msg ) ) . toEqual ( [ ] ) ;
852- }
853- } ) ;
854-
855- test ( "Prevents useLoaderData in bubbled ErrorBoundary" , async ( {
856- page,
857- javaScriptEnabled,
858- } ) => {
859- let app = new PlaywrightFixture ( appFixture , page ) ;
860- await app . goto ( "/parent/child-without-boundary" ) ;
861-
862- expect ( await app . getHtml ( "#parent-data" ) ) . toEqual (
863- '<p id="parent-data">PARENT</p>'
864- ) ;
865- expect ( await app . getHtml ( "#child-data" ) ) . toEqual (
866- '<p id="child-data">CHILD</p>'
867- ) ;
868- expect ( consoleErrors ) . toEqual ( [ ] ) ;
869-
870- await app . clickSubmitButton ( "/parent/child-without-boundary" ) ;
871- await page . waitForSelector ( "#parent-error" ) ;
872-
873- expect ( await app . getHtml ( "#parent-error" ) ) . toEqual (
874- '<p id="parent-error">Broken!</p>'
875- ) ;
876- if ( javaScriptEnabled ) {
877- // This data remains in single fetch with JS because we don't revalidate
878- // due to the 500 action response
879- expect ( await app . getHtml ( "#parent-matches-data" ) ) . toEqual (
880- '<p id="parent-matches-data">PARENT</p>'
881- ) ;
882- } else {
883- // But without JS document requests call all loaders up to the
884- // boundary route so parent's data clears out
885- expect ( await app . getHtml ( "#parent-matches-data" ) ) . toEqual (
886- '<p id="parent-matches-data"></p>'
887- ) ;
888- }
889- expect ( await app . getHtml ( "#parent-data" ) ) . toEqual (
890- '<p id="parent-data"></p>'
891- ) ;
892-
893- // Only look for this message. Chromium browsers will also log the
894- // network error but firefox does not
895- // "Failed to load resource: the server responded with a status of 500 (Internal Server Error)",
896- let msg =
897- "You cannot `useLoaderData` in an errorElement (routeId: routes/parent)" ;
898- if ( javaScriptEnabled ) {
899- expect ( consoleErrors . filter ( ( m ) => m === msg ) ) . toEqual ( [ msg ] ) ;
900- } else {
901- // We don't get the useLoaderData message in the client when JS is disabled
902- expect ( consoleErrors . filter ( ( m ) => m === msg ) ) . toEqual ( [ ] ) ;
903- }
904- } ) ;
905- }
906- } ) ;
907-
908658test . describe ( "Default ErrorBoundary" , ( ) => {
909659 let fixture : Fixture ;
910660 let appFixture : AppFixture ;
0 commit comments