diff --git a/contributors.yml b/contributors.yml
index 5dd438f6282..e42fdd3ef9f 100644
--- a/contributors.yml
+++ b/contributors.yml
@@ -283,6 +283,7 @@
- IshanKBG
- itsMapleLeaf
- izznatsir
+- jabrks
- jacargentina
- jack-r-warren
- jackhkmatthews
diff --git a/integration/bug-report-test.ts b/integration/bug-report-test.ts
index adc4beb59ae..386642f1744 100644
--- a/integration/bug-report-test.ts
+++ b/integration/bug-report-test.ts
@@ -1,15 +1,15 @@
import { test, expect } from "@playwright/test";
+import type { Readable } from "node:stream";
+import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
+import getPort from "get-port";
+import waitOn from "wait-on";
-import { PlaywrightFixture } from "./helpers/playwright-fixture.js";
-import type { Fixture, AppFixture } from "./helpers/create-fixture.js";
-import {
- createAppFixture,
- createFixture,
- js,
-} from "./helpers/create-fixture.js";
+import { createFixtureProject, js } from "./helpers/create-fixture.js";
+import { killtree } from "./helpers/killtree.js";
-let fixture: Fixture;
-let appFixture: AppFixture;
+let projectDir: string;
+let devProc: ChildProcessWithoutNullStreams;
+let devPort: number;
////////////////////////////////////////////////////////////////////////////////
// 💿 👋 Hola! It's me, Dora the Remix Disc, I'm here to help you write a great
@@ -52,28 +52,44 @@ test.beforeEach(async ({ context }) => {
});
test.beforeAll(async () => {
- fixture = await createFixture({
+ devPort = await getPort();
+ projectDir = await createFixtureProject({
////////////////////////////////////////////////////////////////////////////
// 💿 Next, add files to this object, just like files in a real app,
// `createFixture` will make an app and run your tests against it.
////////////////////////////////////////////////////////////////////////////
+ compiler: "vite",
files: {
- "app/routes/_index.tsx": js`
- import { json } from "@remix-run/node";
- import { useLoaderData, Link } from "@remix-run/react";
+ "vite.config.ts": js`
+ import { defineConfig } from "vite";
+ import { vitePlugin as remix } from "@remix-run/dev";
+ export default defineConfig({
+ server: {
+ port: ${devPort},
+ strictPort: true,
+ },
+ plugins: [
+ remix({
+ future: {
+ v3_lazyRouteDiscovery: true,
+ }
+ }),
+ ],
+ });
+ `,
- export function loader() {
- return json("pizza");
- }
+ "app/routes/_index.tsx": js`
+ import { useNavigate } from "@remix-run/react";
+ import { useEffect } from "react";
export default function Index() {
- let data = useLoaderData();
- return (
-
- {data}
- Other Route
-
- )
+ let navigate = useNavigate();
+
+ useEffect(() => {
+ navigate("/burgers");
+ }, [navigate]);
+
+ return null;
}
`,
@@ -85,12 +101,36 @@ test.beforeAll(async () => {
},
});
- // This creates an interactive app using playwright.
- appFixture = await createAppFixture(fixture);
+ let nodeBin = process.argv[0];
+ let remixBin = "node_modules/@remix-run/dev/dist/cli.js";
+ devProc = spawn(nodeBin, [remixBin, "vite:dev"], {
+ cwd: projectDir,
+ env: process.env,
+ stdio: "pipe",
+ });
+ let devStdout = bufferize(devProc.stdout);
+ let devStderr = bufferize(devProc.stderr);
+
+ await waitOn({
+ resources: [`http://localhost:${devPort}/`],
+ timeout: 10000,
+ }).catch((err) => {
+ let stdout = devStdout();
+ let stderr = devStderr();
+ throw new Error(
+ [
+ err.message,
+ "",
+ "exit code: " + devProc.exitCode,
+ "stdout: " + stdout ? `\n${stdout}\n` : "",
+ "stderr: " + stderr ? `\n${stderr}\n` : "",
+ ].join("\n")
+ );
+ });
});
-test.afterAll(() => {
- appFixture.close();
+test.afterAll(async () => {
+ devProc.pid && (await killtree(devProc.pid));
});
////////////////////////////////////////////////////////////////////////////////
@@ -98,24 +138,23 @@ test.afterAll(() => {
// add a good description for what you expect Remix to do 👇🏽
////////////////////////////////////////////////////////////////////////////////
-test("[description of what you expect it to do]", async ({ page }) => {
- let app = new PlaywrightFixture(appFixture, page);
- // You can test any request your app might get using `fixture`.
- let response = await fixture.requestDocument("/");
- expect(await response.text()).toMatch("pizza");
+test("should successfully navigate to the burgers route on load", async ({
+ page,
+}) => {
+ await page.goto(`http://localhost:${devPort}/`, {
+ waitUntil: "networkidle",
+ });
- // If you need to test interactivity use the `app`
- await app.goto("/");
- await app.clickLink("/burgers");
+ await expect(page.getByText("404 Not Found")).not.toBeVisible();
await page.waitForSelector("text=cheeseburger");
-
- // If you're not sure what's going on, you can "poke" the app, it'll
- // automatically open up in your browser for 20 seconds, so be quick!
- // await app.poke(20);
-
- // Go check out the other tests to see what else you can do.
});
////////////////////////////////////////////////////////////////////////////////
// 💿 Finally, push your changes to your fork of Remix and open a pull request!
////////////////////////////////////////////////////////////////////////////////
+
+let bufferize = (stream: Readable): (() => string) => {
+ let buffer = "";
+ stream.on("data", (data) => (buffer += data.toString()));
+ return () => buffer;
+};