Skip to content

Commit

Permalink
QueryRef tests wih preloadQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas committed Feb 11, 2025
1 parent 6ac9152 commit 7fbcdec
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 241 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

3 changes: 3 additions & 0 deletions integration-test/playwright/src/cc-dynamic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ test.describe("CC dynamic", () => {
}
);
});

test.fixme("useSuspenseQuery with @defer", { tag: ["@tanstack"] }, () => {});

test.describe("useSuspenseQuery with a nonce", () => {
test(
"invalid: logs an error",
Expand Down
157 changes: 87 additions & 70 deletions integration-test/playwright/src/preloadQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,48 @@ const reactErr419 = /(Minified React error #419|Switched to client rendering)/;
const base = matchesTag("@nextjs")
? "/rsc/dynamic/PreloadQuery"
: "/preloadQuery";
test.describe(
"PreloadQuery",
{
tag: ["@nextjs"],
},
() => {
for (const [description, path] of [
["with useSuspenseQuery", "useSuspenseQuery"],
["with queryRef and useReadQuery", "queryRef-useReadQuery"],
] as const) {
test.describe(description, () => {
test("query resolves on the server", async ({ page, blockRequest }) => {
await page.goto(`${base}/${path}?errorIn=ssr,browser`, {

const originatesIn = matchesTag("@nextjs") ? "RSC" : "SSR";
const otherEnvs = matchesTag("@nextjs") ? "ssr,browser" : "browser";

test.describe("PreloadQuery", () => {
for (const [description, path] of [
["with useSuspenseQuery", "useSuspenseQuery"],
// ["with queryRef and useReadQuery", "queryRef-useReadQuery"],
] as const) {
test.describe(description, () => {
test(
"query resolves on the server",
{
tag: ["@nextjs", "@tanstack"],
},
async ({ page, blockRequest }) => {
await page.goto(`${base}/${path}?errorIn=${otherEnvs}`, {
waitUntil: "commit",
});

await expect(page).toBeInitiallyLoading(true);
await expect(page.getByText("loading")).not.toBeVisible();
await expect(page.getByText("Soft Warm Apollo Beanie")).toBeVisible();
await expect(
page.getByText("Queried in RSC environment")
page.getByText(`Queried in ${originatesIn} environment`)
).toBeVisible();
});

test("link chain errors on the server, restarts in the browser", async ({
page,
}) => {
}
);

test(
"link chain errors on the server, restarts in the browser",
{
tag: ["@nextjs", "@tanstack"],
},
async ({ page }) => {
page.allowErrors?.();
await page.goto(`${base}/${path}?errorIn=rsc,network_error`, {
waitUntil: "commit",
});
await page.goto(
`${base}/${path}?errorIn=${originatesIn.toLowerCase()},network_error`,
{
waitUntil: "commit",
}
);

await expect(page).toBeInitiallyLoading(true);

Expand All @@ -50,19 +61,26 @@ test.describe(
await expect(
page.getByText("Queried in Browser environment")
).toBeVisible();
});

if (path === "queryRef-useReadQuery") {
// this only works for `useReadQuery`, because `useSuspenseQuery` won't attach
// to the exact same suspenseCache entry and as a result, it won't get the
// error message from the ReadableStream.
test("graphqlError on the server, transported to the browser, can be restarted", async ({
page,
}) => {
}
);

if (path === "queryRef-useReadQuery") {
// this only works for `useReadQuery`, because `useSuspenseQuery` won't attach
// to the exact same suspenseCache entry and as a result, it won't get the
// error message from the ReadableStream.
test(
"graphqlError on the server, transported to the browser, can be restarted",
{
tag: ["@nextjs"],
},
async ({ page }) => {
page.allowErrors?.();
await page.goto(`${base}/${path}?errorIn=rsc`, {
waitUntil: "commit",
});
await page.goto(
`${base}/${path}?errorIn=${originatesIn.toLowerCase()}`,
{
waitUntil: "commit",
}
);

await expect(page).toBeInitiallyLoading(true);

Expand All @@ -79,21 +97,28 @@ test.describe(
await expect(
page.getByText("Queried in Browser environment")
).toBeVisible();
});
} else {
// instead, `useSuspenseQuery` will behave as if nothing had been transported
// and rerun the query in the browser.
// there is a chance it will also rerun the query during SSR, that's a timing
// question that might need further investigation
// the bottom line: `PreloadQuery` with `useSuspenseQuery` works in the happy
// path, but it's not as robust as `queryRef` with `useReadQuery`.
test("graphqlError on the server, restarts in the browser", async ({
page,
}) => {
}
);
} else {
// instead, `useSuspenseQuery` will behave as if nothing had been transported
// and rerun the query in the browser.
// there is a chance it will also rerun the query during SSR, that's a timing
// question that might need further investigation
// the bottom line: `PreloadQuery` with `useSuspenseQuery` works in the happy
// path, but it's not as robust as `queryRef` with `useReadQuery`.
test(
"graphqlError on the server, restarts in the browser",
{
tag: ["@nextjs", "@tanstack"],
},
async ({ page }) => {
page.allowErrors?.();
await page.goto(`${base}/${path}?errorIn=rsc`, {
waitUntil: "commit",
});
await page.goto(
`${base}/${path}?errorIn=${originatesIn.toLowerCase()}`,
{
waitUntil: "commit",
}
);

await expect(page).toBeInitiallyLoading(true);

Expand All @@ -108,12 +133,18 @@ test.describe(
await expect(
page.getByText("Queried in Browser environment")
).toBeVisible();
});
}
});
}
}
);
}
});
}

test("queryRef works with useQueryRefHandlers", async ({ page }) => {
test(
"queryRef works with useQueryRefHandlers",
{
tag: ["@nextjs"],
},
async ({ page }) => {
await page.goto(`${base}/queryRef-useReadQuery`, {
waitUntil: "commit",
});
Expand All @@ -127,20 +158,6 @@ test.describe(
await expect(
page.getByText("Queried in Browser environment")
).toBeVisible();
});

test.skip("queryRef: assumptions about referential equality", async ({
page,
}) => {
await page.goto(`${base}/queryRef-refTest`, {
waitUntil: "commit",
});

await page.getByRole("spinbutton").nth(11).waitFor();

for (let i = 0; i < 12; i++) {
await expect(page.getByRole("spinbutton").nth(i)).toHaveClass("valid");
}
});
}
);
}
);
});
1 change: 1 addition & 0 deletions integration-test/shared/errorLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const errorLink = new ApolloLink((operation, forward) => {
} satisfies GraphQLFormattedError as GraphQLError,
],
});
subscriber.complete();
}
});
}
Expand Down
Loading

0 comments on commit 7fbcdec

Please sign in to comment.