Skip to content

Commit dae1b3d

Browse files
committed
Add e2e tests
1 parent 7fdd10f commit dae1b3d

File tree

1 file changed

+226
-0
lines changed

1 file changed

+226
-0
lines changed

integration/single-fetch-test.ts

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,232 @@ test.describe("single-fetch", () => {
837837
expect(urls).toEqual([]);
838838
});
839839

840+
test("supports call-site revalidation opt-out on submissions (w/o shouldRevalidate)", async ({
841+
page,
842+
}) => {
843+
let fixture = await createFixture({
844+
files: {
845+
...files,
846+
"app/routes/action.tsx": js`
847+
import { Form } from 'react-router';
848+
849+
let count = 0;
850+
export function loader() {
851+
return { count: ++count };
852+
}
853+
854+
export function action() {
855+
return { count: ++count };
856+
}
857+
858+
export default function Comp({ loaderData, actionData }) {
859+
return (
860+
<Form method="post" unstable_defaultShouldRevalidate={false}>
861+
<button type="submit" name="name" value="value">Submit</button>
862+
<p id="data">{loaderData.count}</p>
863+
{actionData ? <p id="action-data">{actionData.count}</p> : null}
864+
</Form>
865+
);
866+
}
867+
`,
868+
},
869+
});
870+
871+
let urls: string[] = [];
872+
page.on("request", (req) => {
873+
if (req.method() === "GET" && req.url().includes(".data")) {
874+
urls.push(req.url());
875+
}
876+
});
877+
878+
console.error = () => {};
879+
880+
let appFixture = await createAppFixture(fixture);
881+
let app = new PlaywrightFixture(appFixture, page);
882+
await app.goto("/action");
883+
expect(await app.getHtml("#data")).toContain("1");
884+
expect(urls).toEqual([]);
885+
886+
await page.click('button[name="name"][value="value"]');
887+
await page.waitForSelector("#action-data");
888+
expect(await app.getHtml("#action-data")).toContain("2");
889+
expect(await app.getHtml("#data")).toContain("1");
890+
expect(urls).toEqual([]);
891+
});
892+
893+
test("supports call-site revalidation opt-in on 4xx/5xx action responses (w/o shouldRevalidate)", async ({
894+
page,
895+
}) => {
896+
let fixture = await createFixture({
897+
files: {
898+
...files,
899+
"app/routes/action.tsx": js`
900+
import { Form, Link, useNavigation, data } from 'react-router';
901+
902+
export async function action({ request }) {
903+
throw data("Thrown 500", { status: 500 });
904+
}
905+
906+
let count = 0;
907+
export function loader() {
908+
return { count: ++count };
909+
}
910+
911+
export default function Comp({ loaderData }) {
912+
let navigation = useNavigation();
913+
return (
914+
<Form method="post" unstable_defaultShouldRevalidate={true}>
915+
<button type="submit" name="throw" value="5xx">Throw 5xx</button>
916+
<p id="data">{loaderData.count}</p>
917+
{navigation.state === "idle" ? <p id="idle">idle</p> : null}
918+
</Form>
919+
);
920+
}
921+
922+
export function ErrorBoundary() {
923+
return <h1 id="error">Error</h1>
924+
}
925+
`,
926+
},
927+
});
928+
929+
let urls: string[] = [];
930+
page.on("request", (req) => {
931+
if (req.method() === "GET" && req.url().includes(".data")) {
932+
urls.push(req.url());
933+
}
934+
});
935+
936+
console.error = () => {};
937+
938+
let appFixture = await createAppFixture(fixture);
939+
let app = new PlaywrightFixture(appFixture, page);
940+
await app.goto("/action");
941+
expect(await app.getHtml("#data")).toContain("1");
942+
expect(urls).toEqual([]);
943+
944+
await page.click('button[name="throw"][value="5xx"]');
945+
await page.waitForSelector("#error");
946+
expect(urls).toEqual([expect.stringMatching(/\/action\.data$/)]);
947+
});
948+
949+
test("supports call-site revalidation opt-out on submissions (w/ shouldRevalidate)", async ({
950+
page,
951+
}) => {
952+
let fixture = await createFixture({
953+
files: {
954+
...files,
955+
"app/routes/action.tsx": js`
956+
import { Form } from 'react-router';
957+
958+
let count = 0;
959+
export function loader() {
960+
return { count: ++count };
961+
}
962+
963+
export function action() {
964+
return { count: ++count };
965+
}
966+
967+
export function shouldRevalidate({ defaultShouldRevalidate }) {
968+
return defaultShouldRevalidate;
969+
}
970+
971+
export default function Comp({ loaderData, actionData }) {
972+
return (
973+
<Form method="post" unstable_defaultShouldRevalidate={false}>
974+
<button type="submit" name="name" value="value">Submit</button>
975+
<p id="data">{loaderData.count}</p>
976+
{actionData ? <p id="action-data">{actionData.count}</p> : null}
977+
</Form>
978+
);
979+
}
980+
`,
981+
},
982+
});
983+
984+
let urls: string[] = [];
985+
page.on("request", (req) => {
986+
if (req.method() === "GET" && req.url().includes(".data")) {
987+
urls.push(req.url());
988+
}
989+
});
990+
991+
console.error = () => {};
992+
993+
let appFixture = await createAppFixture(fixture);
994+
let app = new PlaywrightFixture(appFixture, page);
995+
await app.goto("/action");
996+
expect(await app.getHtml("#data")).toContain("1");
997+
expect(urls).toEqual([]);
998+
999+
await page.click('button[name="name"][value="value"]');
1000+
await page.waitForSelector("#action-data");
1001+
expect(await app.getHtml("#action-data")).toContain("2");
1002+
expect(await app.getHtml("#data")).toContain("1");
1003+
expect(urls).toEqual([]);
1004+
});
1005+
1006+
test("supports call-site revalidation opt-in on 4xx/5xx action responses (w shouldRevalidate)", async ({
1007+
page,
1008+
}) => {
1009+
let fixture = await createFixture({
1010+
files: {
1011+
...files,
1012+
"app/routes/action.tsx": js`
1013+
import { Form, Link, useNavigation, data } from 'react-router';
1014+
1015+
export async function action({ request }) {
1016+
throw data("Thrown 500", { status: 500 });
1017+
}
1018+
1019+
let count = 0;
1020+
export function loader() {
1021+
return { count: ++count };
1022+
}
1023+
1024+
export function shouldRevalidate({ defaultShouldRevalidate }) {
1025+
return defaultShouldRevalidate;
1026+
}
1027+
1028+
export default function Comp({ loaderData }) {
1029+
let navigation = useNavigation();
1030+
return (
1031+
<Form method="post" unstable_defaultShouldRevalidate={true}>
1032+
<button type="submit" name="throw" value="5xx">Throw 5xx</button>
1033+
<p id="data">{loaderData.count}</p>
1034+
{navigation.state === "idle" ? <p id="idle">idle</p> : null}
1035+
</Form>
1036+
);
1037+
}
1038+
1039+
export function ErrorBoundary() {
1040+
return <h1 id="error">Error</h1>
1041+
}
1042+
`,
1043+
},
1044+
});
1045+
1046+
let urls: string[] = [];
1047+
page.on("request", (req) => {
1048+
if (req.method() === "GET" && req.url().includes(".data")) {
1049+
urls.push(req.url());
1050+
}
1051+
});
1052+
1053+
console.error = () => {};
1054+
1055+
let appFixture = await createAppFixture(fixture);
1056+
let app = new PlaywrightFixture(appFixture, page);
1057+
await app.goto("/action");
1058+
expect(await app.getHtml("#data")).toContain("1");
1059+
expect(urls).toEqual([]);
1060+
1061+
await page.click('button[name="throw"][value="5xx"]');
1062+
await page.waitForSelector("#error");
1063+
expect(urls).toEqual([expect.stringMatching(/\/action\.data$/)]);
1064+
});
1065+
8401066
test("returns headers correctly for singular loader and action calls", async () => {
8411067
let fixture = await createFixture({
8421068
files: {

0 commit comments

Comments
 (0)