-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Add integration tests for request structures #4829
Changes from 1 commit
ebd39db
cdacee5
4373bb9
1e1b7d8
d8c78ba
a7e9b36
7a3c205
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
import { test, expect } from "@playwright/test"; | ||
|
||
import { PlaywrightFixture } from "./helpers/playwright-fixture"; | ||
import type { Fixture, AppFixture } from "./helpers/create-fixture"; | ||
import { createAppFixture, createFixture, js } from "./helpers/create-fixture"; | ||
|
||
let fixture: Fixture; | ||
let appFixture: AppFixture; | ||
|
||
test.beforeAll(async () => { | ||
fixture = await createFixture({ | ||
files: { | ||
"app/routes/index.jsx": js` | ||
import { json } from "@remix-run/node"; | ||
import { Form, useLoaderData, useActionData } from "@remix-run/react"; | ||
export async function loader({ request }) { | ||
let text = (await request.text()); | ||
return json({ | ||
method: request.method, | ||
url: request.url, | ||
headers: Object.fromEntries(request.headers.entries()), | ||
text, | ||
}); | ||
} | ||
export async function action({ request }) { | ||
let text = (await request.text()); | ||
return json({ | ||
method: request.method, | ||
url: request.url, | ||
headers: Object.fromEntries(request.headers.entries()), | ||
text, | ||
}); | ||
} | ||
export default function Index() { | ||
let loaderData = useLoaderData(); | ||
let actionData = useActionData(); | ||
return ( | ||
<div> | ||
<button id="set-cookie" onClick={() => { | ||
document.cookie = 'cookie=nomnom; path=/'; | ||
}}> | ||
Set Cookie | ||
</button> | ||
<Form method="get" reloadDocument> | ||
<button type="submit" id="submit-get-ssr" name="type" value="ssr" /> | ||
</Form> | ||
<Form method="get"> | ||
<button type="submit" id="submit-get-csr" name="type" value="csr" /> | ||
</Form> | ||
<Form method="post" reloadDocument> | ||
<button type="submit" id="submit-post-ssr" name="type" value="ssr" /> | ||
</Form> | ||
<Form method="post"> | ||
<button type="submit" id="submit-post-csr" name="type" value="csr" /> | ||
</Form> | ||
<pre id="loader-data">{JSON.stringify(loaderData)}</pre> | ||
{actionData ? | ||
<pre id="action-data">{JSON.stringify(actionData)}</pre> : | ||
null} | ||
</div> | ||
) | ||
} | ||
`, | ||
}, | ||
}); | ||
|
||
appFixture = await createAppFixture(fixture); | ||
}); | ||
|
||
test.afterAll(() => appFixture.close()); | ||
|
||
test("loader request on SSR GET requests", async ({ page }) => { | ||
let app = new PlaywrightFixture(appFixture, page); | ||
await app.goto("/"); | ||
await app.clickElement("#set-cookie"); | ||
|
||
let loaderData = JSON.parse(await page.locator("#loader-data").innerHTML()); | ||
expect(loaderData.method).toEqual("GET"); | ||
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/$/); | ||
expect(loaderData.headers.cookie).toEqual(undefined); | ||
expect(loaderData.text).toEqual(""); | ||
|
||
await app.clickElement("#submit-get-ssr"); | ||
|
||
loaderData = JSON.parse(await page.locator("#loader-data").innerHTML()); | ||
expect(loaderData.method).toEqual("GET"); | ||
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/\?type=ssr$/); | ||
expect(loaderData.headers.cookie).toEqual("cookie=nomnom"); | ||
expect(loaderData.text).toEqual(""); | ||
}); | ||
|
||
test("loader request on CSR GET requests", async ({ page }) => { | ||
let app = new PlaywrightFixture(appFixture, page); | ||
await app.goto("/"); | ||
await app.clickElement("#set-cookie"); | ||
|
||
let loaderData = JSON.parse(await page.locator("#loader-data").innerHTML()); | ||
expect(loaderData.method).toEqual("GET"); | ||
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/$/); | ||
expect(loaderData.headers.cookie).toEqual(undefined); | ||
expect(loaderData.text).toEqual(""); | ||
|
||
await app.clickElement("#submit-get-csr"); | ||
|
||
loaderData = JSON.parse(await page.locator("#loader-data").innerHTML()); | ||
expect(loaderData.method).toEqual("GET"); | ||
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/\?type=csr$/); | ||
expect(loaderData.headers.cookie).toEqual("cookie=nomnom"); | ||
expect(loaderData.text).toEqual(""); | ||
}); | ||
|
||
test("action + loader requests SSR POST requests", async ({ page }) => { | ||
let app = new PlaywrightFixture(appFixture, page); | ||
await app.goto("/"); | ||
await app.clickElement("#set-cookie"); | ||
|
||
let loaderData = JSON.parse(await page.locator("#loader-data").innerHTML()); | ||
expect(loaderData.method).toEqual("GET"); | ||
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/$/); | ||
expect(loaderData.headers.cookie).toEqual(undefined); | ||
expect(loaderData.text).toEqual(""); | ||
|
||
await app.clickElement("#submit-post-ssr"); | ||
|
||
let actionData = JSON.parse(await page.locator("#action-data").innerHTML()); | ||
expect(actionData.method).toEqual("POST"); | ||
expect(actionData.url).toMatch(/^http:\/\/localhost:\d+\/$/); | ||
expect(actionData.headers.cookie).toEqual("cookie=nomnom"); | ||
expect(actionData.text).toEqual("type=ssr"); | ||
|
||
loaderData = JSON.parse(await page.locator("#loader-data").innerHTML()); | ||
expect(loaderData.method).toEqual("POST"); | ||
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/$/); | ||
expect(loaderData.headers.cookie).toEqual("cookie=nomnom"); | ||
expect(loaderData.text).toEqual(""); | ||
}); | ||
|
||
test("action + loader requests on CSR POST requests", async ({ page }) => { | ||
let app = new PlaywrightFixture(appFixture, page); | ||
await app.goto("/"); | ||
await app.clickElement("#set-cookie"); | ||
|
||
let loaderData = JSON.parse(await page.locator("#loader-data").innerHTML()); | ||
expect(loaderData.method).toEqual("GET"); | ||
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/$/); | ||
expect(loaderData.headers.cookie).toEqual(undefined); | ||
expect(loaderData.text).toEqual(""); | ||
|
||
await app.clickElement("#submit-post-csr"); | ||
|
||
let actionData = JSON.parse(await page.locator("#action-data").innerHTML()); | ||
expect(actionData.method).toEqual("POST"); | ||
expect(actionData.url).toMatch(/^http:\/\/localhost:\d+\/$/); | ||
expect(actionData.headers.cookie).toEqual("cookie=nomnom"); | ||
expect(actionData.text).toEqual("type=csr"); | ||
|
||
loaderData = JSON.parse(await page.locator("#loader-data").innerHTML()); | ||
expect(loaderData.method).toEqual("GET"); | ||
expect(loaderData.url).toMatch(/^http:\/\/localhost:\d+\/$/); | ||
expect(loaderData.headers.cookie).toEqual("cookie=nomnom"); | ||
expect(loaderData.text).toEqual(""); | ||
Comment on lines
+157
to
+161
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. During SPA submissions, the loader is called through separate revalidation I think this all makes sense given how Remix is executing loaders differently in MPA/SPA calls, even if it introduces a slight different between them from a DX standpoint. Users shouldn't be branching on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic is implemented in the router here: remix-run/react-router#9721 |
||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During MPA submissions, the loader
request
proxies the action method (POST
) but strips thebody
. This makes sense since there's only a single submission happening.