1import * as Fly from "@/Fly";
2import * as Test from "@/Test/Alchemy";
3import { describe, expect } from "alchemy-test";
4import * as Effect from "effect/Effect";
5import * as pathe from "pathe";
6import { cloneFixture } from "../../Cloudflare/Utils/Fixture.ts";
7import { expectUrlContains } from "../../Cloudflare/Utils/Http.ts";
8
9const { test } = Test.make({ providers: Fly.providers(), dev: true });
10
11/**
12 * SolidStart 2's dev SSR does not run under Bun (`srvx/node` writes
13 * `[object Object]`). Body assertions stay gated; identity (localhost,
14 * no cloud rows) is asserted unconditionally. Set
15 * `ALCHEMY_TEST_SOLIDSTART_DEV_SSR=1` to run the body assertions on a
16 * Node-hosted sidecar.
17 */
18const runDevSsr = process.env.ALCHEMY_TEST_SOLIDSTART_DEV_SSR === "1";
19
20const fixtureDir = pathe.resolve(
21 import.meta.dirname,
22 "../../AWS/Website/fixtures/solidstart-app",
23);
24const tempRoot = pathe.resolve(import.meta.dirname, "../../../.tmp");
25const fixtureEntries = [
26 ".gitignore",
27 "package.json",
28 "vite.config.ts",
29 "src",
30 "public",
31];
32
33describe(
34 "Fly.Website.SolidStart local",
35 { tags: ["provider:fly", "provider:fly:website", "local"] },
36 () => {
37 test.provider(
38 "dev runs the framework server with no cloud resources",
39 (stack) =>
40 Effect.gen(function* () {
41 yield* stack.destroy();
42
43 const rootDir = yield* cloneFixture(fixtureDir, {
44 prefix: "alchemy-solidstart-fly-local-",
45 tempRoot,
46 entries: fixtureEntries,
47 });
48
49 const deployed = yield* stack.deploy(
50 Effect.gen(function* () {
51 const site = yield* Fly.Website.SolidStart("Web", {
52 rootDir,
53 });
54 return { site };
55 }),
56 );
57
58 const url = deployed.site.url;
59 expect(url).toMatch(/^http:\/\/(localhost|127\.0\.0\.1):\d+\/?$/);
60 expect(deployed.site.service).toBeUndefined();
61 expect(deployed.site.app).toBeUndefined();
62 expect(deployed.site.ip).toBeUndefined();
63
64 yield* stack.destroy();
65 }),
66 { timeout: 120_000 },
67 );
68
69 test.provider.skipIf(!runDevSsr)(
70 "dev serves SSR home and API routes",
71 (stack) =>
72 Effect.gen(function* () {
73 yield* stack.destroy();
74
75 const rootDir = yield* cloneFixture(fixtureDir, {
76 prefix: "alchemy-solidstart-fly-local-ssr-",
77 tempRoot,
78 entries: fixtureEntries,
79 });
80
81 const deployed = yield* stack.deploy(
82 Effect.gen(function* () {
83 const site = yield* Fly.Website.SolidStart("Web", {
84 rootDir,
85 });
86 return { site };
87 }),
88 );
89
90 const url = deployed.site.url;
91 const origin = String(url).replace(/\/+$/, "");
92 yield* expectUrlContains(`${origin}/`, "SOLIDSTART_AWS_PAGE_MARKER", {
93 timeout: "90 seconds",
94 label: "dev home page",
95 });
96 yield* expectUrlContains(
97 `${origin}/api/hello?echo=roundtrip`,
98 "SOLIDSTART_AWS_API_MARKER",
99 { label: "api route (dev)" },
100 );
101 yield* expectUrlContains(
102 `${origin}/prerendered`,
103 "SOLIDSTART_AWS_PRERENDERED_MARKER",
104 { label: "extra route (dev)" },
105 );
106
107 yield* stack.destroy();
108 }),
109 { timeout: 120_000 },
110 );
111 },
112);