Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 109 additions & 60 deletions integration/vite-dev-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,44 @@ import dedent from "dedent";

import {
reactRouterConfig,
viteConfig,
test,
type TemplateName,
type Files,
} from "./helpers/vite.js";

const tsx = dedent;

const fixtures = [
{
templateName: "vite-5-template",
viteEnvironmentApi: false,
},
{
templateName: "vite-6-template",
viteEnvironmentApi: true,
},
{
templateName: "rsc-vite-framework",
viteEnvironmentApi: true,
},
] as const satisfies ReadonlyArray<{
templateName: TemplateName;
viteEnvironmentApi: boolean;
}>;

test.describe("Vite dev", () => {
[false, true].forEach((viteEnvironmentApi) => {
test.describe(`viteEnvironmentApi: ${viteEnvironmentApi}`, () => {
for (const { templateName, viteEnvironmentApi } of fixtures) {
test.describe(`template: ${templateName} viteEnvironmentApi: ${viteEnvironmentApi}`, () => {
const files: Files = async ({ port }) => ({
"react-router.config.ts": reactRouterConfig({
viteEnvironmentApi,
}),
"vite.config.ts": tsx`
import { defineConfig } from "vite";
import { reactRouter } from "@react-router/dev/vite";
import mdx from "@mdx-js/rollup";

export default defineConfig({
server: {
port: ${port},
strictPort: true,
},
plugins: [
mdx(),
reactRouter(),
],
});
`,
"vite.config.ts": await viteConfig.basic({
port,
templateName,
mdx: true,
}),
"app/root.tsx": tsx`
import { Links, Meta, Outlet, Scripts } from "react-router";

Expand All @@ -58,6 +66,17 @@ test.describe("Vite dev", () => {
}
`,
"app/routes/_index.tsx": tsx`
export default function IndexRoute() {
return (
<div id="index">
<h2 data-title>Index</h2>
<input />
<p data-hmr>HMR updated: no</p>
</div>
);
}
`,
"app/routes/deferred-loader-data.tsx": tsx`
import { Suspense } from "react";
import { Await, useLoaderData } from "react-router";

Expand All @@ -73,9 +92,6 @@ test.describe("Vite dev", () => {

return (
<div id="index">
<h2 data-title>Index</h2>
<input />
<p data-hmr>HMR updated: no</p>
<Suspense fallback={<p data-defer>Defer finished: no</p>}>
<Await resolve={deferred}>{() => <p data-defer>Defer finished: yes</p>}</Await>
</Suspense>
Expand Down Expand Up @@ -159,37 +175,41 @@ test.describe("Vite dev", () => {

<MdxComponent />
`,
".env": `
ENV_VAR_FROM_DOTENV_FILE=Content from .env file
`,
"app/routes/dotenv.tsx": tsx`
import { useState, useEffect } from "react";
import { useLoaderData } from "react-router";

export const loader = () => {
return {
loaderContent: process.env.ENV_VAR_FROM_DOTENV_FILE,
...(!templateName.includes("rsc")
? {
".env": `
ENV_VAR_FROM_DOTENV_FILE=Content from .env file
`,
"app/routes/dotenv.tsx": tsx`
import { useState, useEffect } from "react";
import { useLoaderData } from "react-router";

export const loader = () => {
return {
loaderContent: process.env.ENV_VAR_FROM_DOTENV_FILE,
}
}

export default function DotenvRoute() {
const { loaderContent } = useLoaderData();

const [clientContent, setClientContent] = useState('');
useEffect(() => {
try {
setClientContent("process.env.ENV_VAR_FROM_DOTENV_FILE shouldn't be available on the client, found: " + process.env.ENV_VAR_FROM_DOTENV_FILE);
} catch (err) {
setClientContent("process.env.ENV_VAR_FROM_DOTENV_FILE not available on the client, which is a good thing");
}
}, []);

return <>
<div data-dotenv-route-loader-content>{loaderContent}</div>
<div data-dotenv-route-client-content>{clientContent}</div>
</>
}
`,
}
}

export default function DotenvRoute() {
const { loaderContent } = useLoaderData();

const [clientContent, setClientContent] = useState('');
useEffect(() => {
try {
setClientContent("process.env.ENV_VAR_FROM_DOTENV_FILE shouldn't be available on the client, found: " + process.env.ENV_VAR_FROM_DOTENV_FILE);
} catch (err) {
setClientContent("process.env.ENV_VAR_FROM_DOTENV_FILE not available on the client, which is a good thing");
}
}, []);

return <>
<div data-dotenv-route-loader-content>{loaderContent}</div>
<div data-dotenv-route-client-content>{clientContent}</div>
</>
}
`,
: {}),
"app/routes/error-stacktrace.tsx": tsx`
import { Link, useLocation, type LoaderFunction, type MetaFunction } from "react-router";

Expand Down Expand Up @@ -254,11 +274,7 @@ test.describe("Vite dev", () => {
`,
});

const templateName: TemplateName = viteEnvironmentApi
? "vite-6-template"
: "vite-5-template";

test("renders matching routes", async ({ dev, page }) => {
test("renders matching routes with HMR", async ({ dev, page }) => {
const { cwd, port } = await dev(files, templateName);

await page.goto(`http://localhost:${port}/`, {
Expand All @@ -269,9 +285,6 @@ test.describe("Vite dev", () => {
expect(page.errors).toEqual([]);

await expect(page.locator("#index [data-title]")).toHaveText("Index");
await expect(page.locator("#index [data-defer]")).toHaveText(
"Defer finished: yes",
);

let hmrStatus = page.locator("#index [data-hmr]");
await expect(hmrStatus).toHaveText("HMR updated: no");
Expand All @@ -297,6 +310,27 @@ test.describe("Vite dev", () => {
expect(page.errors).toEqual([]);
});

test("deferred loader data", async ({ dev, page }) => {
test.fixme(
templateName.includes("rsc"),
"RSC doesn't support Await component",
);

const { port } = await dev(files, templateName);
await page.goto(`http://localhost:${port}/deferred-loader-data`, {
waitUntil: "networkidle",
});

// Ensure no errors on page load
expect(page.errors).toEqual([]);

await expect(page.locator("#index [data-defer]")).toHaveText(
"Defer finished: yes",
);
// Ensure no errors after deferred rendering
expect(page.errors).toEqual([]);
});

test("handles multiple set-cookie headers", async ({ dev, page }) => {
const { port } = await dev(files, templateName);

Expand Down Expand Up @@ -357,6 +391,11 @@ test.describe("Vite dev", () => {
});

test("loads .env file", async ({ dev, page }) => {
test.fixme(
templateName.includes("rsc"),
"RSC Framework Mode doesn't load .env files",
);

const { port } = await dev(files, templateName);

await page.goto(`http://localhost:${port}/dotenv`, {
Expand All @@ -379,6 +418,11 @@ test.describe("Vite dev", () => {
dev,
page,
}) => {
test.fixme(
templateName.includes("rsc"),
"Investigate this for RSC Framework Mode",
);

const { port } = await dev(files, templateName);

await page.goto(
Expand All @@ -401,6 +445,11 @@ test.describe("Vite dev", () => {
});

test("handle known route exports with HMR", async ({ dev, page }) => {
test.fixme(
templateName.includes("rsc"),
"Investigate why this is failing in RSC Framework Mode",
);

const { cwd, port } = await dev(files, templateName);

await page.goto(`http://localhost:${port}/known-route-exports`, {
Expand Down Expand Up @@ -450,5 +499,5 @@ test.describe("Vite dev", () => {
expect(page.errors).toEqual([]);
});
});
});
}
});
Loading