1import * as Railway from "@/Railway";
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: Railway.providers(), dev: true });
10
11const fixtureDir = pathe.resolve(
12 import.meta.dirname,
13 "../../../../../examples/cloudflare-website-vocs",
14);
15const tempRoot = pathe.resolve(import.meta.dirname, "../../../.tmp");
16const fixtureEntries = [
17 "package.json",
18 "public",
19 "src",
20 "tsconfig.json",
21 "vocs.config.ts",
22];
23
24describe(
25 "Railway.Website.Vocs local",
26 { tags: ["provider:railway", "provider:railway:website", "local"] },
27 () => {
28 // Vocs' vite plugin reads `src/pages` from process.cwd() rather than
29 // the project `root`, so alchemy-test (cwd = packages/alchemy) cannot
30 // host the cloned fixture. Cloudflare.Website.Vocs local uses the
31 // Worker source provider instead.
32 test.provider.skipIf(true)(
33 "dev runs the framework server with no cloud resources",
34 (stack) =>
35 Effect.gen(function* () {
36 yield* stack.destroy();
37
38 const rootDir = yield* cloneFixture(fixtureDir, {
39 prefix: "alchemy-vocs-railway-local-",
40 tempRoot,
41 entries: fixtureEntries,
42 });
43
44 const deployed = yield* stack.deploy(
45 Effect.gen(function* () {
46 const site = yield* Railway.Website.Vocs("Web", {
47 rootDir,
48 });
49 return { site };
50 }),
51 );
52
53 const url = deployed.site.url;
54 expect(url).toMatch(/^http:\/\/(localhost|127\.0\.0\.1):\d+\/?$/);
55 expect(deployed.site.service).toBeUndefined();
56 expect(deployed.site.project).toBeUndefined();
57
58 yield* expectUrlContains(`${url}/`, "Alchemy with Vocs", {
59 timeout: "90 seconds",
60 label: "dev home page",
61 });
62
63 yield* stack.destroy();
64 }),
65 { timeout: 180_000 },
66 );
67 },
68);