1import * as GCP from "@/GCP";
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: GCP.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 "GCP.Website.SolidStart local",
35 { tags: ["provider:gcp", "provider:gcp: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-gcp-local-",
45 tempRoot,
46 entries: fixtureEntries,
47 });
48
49 const deployed = yield* stack.deploy(
50 Effect.gen(function* () {
51 const site = yield* GCP.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
62 yield* stack.destroy();
63 }),
64 {
65 tags: ["provider:gcp", "provider:gcp:website", "live"],
66 timeout: 120_000,
67 },
68 );
69
70 test.provider.skipIf(!runDevSsr)(
71 "dev serves SSR home and API routes",
72 (stack) =>
73 Effect.gen(function* () {
74 yield* stack.destroy();
75
76 const rootDir = yield* cloneFixture(fixtureDir, {
77 prefix: "alchemy-solidstart-gcp-local-ssr-",
78 tempRoot,
79 entries: fixtureEntries,
80 });
81
82 const deployed = yield* stack.deploy(
83 Effect.gen(function* () {
84 const site = yield* GCP.Website.SolidStart("Web", {
85 rootDir,
86 });
87 return { site };
88 }),
89 );
90
91 const url = deployed.site.url;
92 const origin = String(url).replace(/\/+$/, "");
93 yield* expectUrlContains(`${origin}/`, "SOLIDSTART_AWS_PAGE_MARKER", {
94 timeout: "90 seconds",
95 label: "dev home page",
96 });
97 yield* expectUrlContains(
98 `${origin}/api/hello?echo=roundtrip`,
99 "SOLIDSTART_AWS_API_MARKER",
100 { label: "api route (dev)" },
101 );
102 yield* expectUrlContains(
103 `${origin}/prerendered`,
104 "SOLIDSTART_AWS_PRERENDERED_MARKER",
105 { label: "extra route (dev)" },
106 );
107
108 yield* stack.destroy();
109 }),
110 {
111 tags: ["provider:gcp", "provider:gcp:website", "live"],
112 timeout: 120_000,
113 },
114 );
115 },
116);