Files
wehub-resource-sync 70bf21e064
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:11 +08:00

361 lines
10 KiB
TypeScript

import { execSync } from "child_process";
import { randomUUID } from "crypto";
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
/* eslint-disable workers-sdk/no-vitest-import-expect -- uses expect in helper functions and beforeAll */
import {
afterAll,
assert,
beforeAll,
beforeEach,
describe,
expect,
test,
vi,
} from "vitest";
/* eslint-enable workers-sdk/no-vitest-import-expect */
import { getPlatformProxy } from "wrangler";
import type { KVNamespace } from "@cloudflare/workers-types/experimental";
import type { DispatchFetch, Response } from "miniflare";
type Fetcher = { fetch: DispatchFetch };
const workersDomain =
process.env.E2E_ACCOUNT_WORKERS_DEV_DOMAIN ??
"devprod-testing7928.workers.dev";
const auth = getAuthenticatedEnv();
const execOptions = {
encoding: "utf8",
env: { ...process.env, ...auth },
} as const;
const remoteWorkerName = `preserve-e2e-get-platform-proxy-remote`;
const remoteStagingWorkerName = `preserve-e2e-get-platform-proxy-remote-staging`;
const remoteKvName = `tmp-e2e-kv${Date.now()}-test-remote-bindings-${randomUUID().split("-")[0]}`;
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
if (auth) {
describe("getPlatformProxy - remote bindings", { timeout: 50_000 }, () => {
let remoteKvId: string;
beforeAll(async () => {
const deployedUrl = `https://preserve-e2e-get-platform-proxy-remote.${workersDomain}/`;
try {
assert((await fetch(deployedUrl)).status !== 404);
} catch (e) {
execSync(
`pnpm wrangler deploy remote-worker.js --name ${remoteWorkerName} --compatibility-date 2025-06-19`,
execOptions
);
await vi.waitFor(
async () => {
const response = await fetch(deployedUrl);
expect(response.status).toBe(200);
},
{ timeout: 5000, interval: 500 }
);
}
const stagingDeployedUrl = `https://preserve-e2e-get-platform-proxy-remote-staging.${workersDomain}/`;
try {
assert((await fetch(stagingDeployedUrl)).status !== 404);
} catch {
execSync(
`pnpm wrangler deploy remote-worker.staging.js --name ${remoteStagingWorkerName} --compatibility-date 2025-06-19`,
execOptions
);
await vi.waitFor(
async () => {
const response = await fetch(stagingDeployedUrl);
expect(response.status).toBe(200);
},
{ timeout: 5000, interval: 500 }
);
}
const kvAddOut = execSync(
`pnpm wrangler kv namespace create ${remoteKvName}`,
execOptions
);
const createdKvRegexMatch = kvAddOut.match(/"id": "(?<id>[^"]*?)"/);
const maybeRemoteKvId = createdKvRegexMatch?.groups?.["id"];
assert(maybeRemoteKvId, `Failed to create remote kv ${remoteKvName}`);
remoteKvId = maybeRemoteKvId;
execSync(
`pnpm wrangler kv key put test-key remote-kv-value --namespace-id=${remoteKvId} --remote`,
execOptions
);
rmSync("./.tmp", { recursive: true, force: true });
mkdirSync("./.tmp");
}, 35_000);
afterAll(() => {
try {
execSync(
`pnpm wrangler kv namespace delete --namespace-id=${remoteKvId}`,
execOptions
);
} catch {}
try {
rmSync("./.tmp", {
recursive: true,
force: true,
maxRetries: 10,
retryDelay: 100,
});
} catch {}
}, 35_000);
beforeEach(() => {
errorSpy.mockReset();
});
describe("normal usage", () => {
beforeAll(async () => {
mkdirSync("./.tmp/normal-usage");
writeFileSync(
"./.tmp/normal-usage/wrangler.json",
JSON.stringify(
{
name: "get-platform-proxy-fixture-test",
compatibility_date: "2025-06-01",
services: [
{
binding: "MY_WORKER",
service: remoteWorkerName,
remote: true,
},
],
kv_namespaces: [
{
binding: "MY_KV",
id: remoteKvId,
remote: true,
},
],
env: {
staging: {
services: [
{
binding: "MY_WORKER",
service: remoteStagingWorkerName,
remote: true,
},
],
kv_namespaces: [
{
binding: "MY_KV",
id: remoteKvId,
remote: true,
},
],
},
},
},
undefined,
2
),
"utf8"
);
});
test("getPlatformProxy works with remote bindings", async () => {
vi.stubEnv("CLOUDFLARE_ACCOUNT_ID", auth.CLOUDFLARE_ACCOUNT_ID);
vi.stubEnv("CLOUDFLARE_API_TOKEN", auth.CLOUDFLARE_API_TOKEN);
const { env, dispose } = await getPlatformProxy<{
MY_WORKER: Fetcher;
MY_KV: KVNamespace;
}>({
configPath: "./.tmp/normal-usage/wrangler.json",
});
const response = await fetchFromWorker(env.MY_WORKER, "OK");
const workerText = await response?.text();
expect(workerText).toEqual(
"Hello from a remote Worker part of the getPlatformProxy remote bindings fixture!"
);
const kvValue = await env.MY_KV.get("test-key");
expect(kvValue).toEqual("remote-kv-value");
await dispose();
});
test("getPlatformProxy works with remote bindings specified in an environment", async () => {
vi.stubEnv("CLOUDFLARE_ACCOUNT_ID", auth.CLOUDFLARE_ACCOUNT_ID);
vi.stubEnv("CLOUDFLARE_API_TOKEN", auth.CLOUDFLARE_API_TOKEN);
const { env, dispose } = await getPlatformProxy<{
MY_WORKER: Fetcher;
MY_KV: KVNamespace;
}>({
configPath: "./.tmp/normal-usage/wrangler.json",
environment: "staging",
});
const workerText = await (
await env.MY_WORKER.fetch("http://example.com")
).text();
expect(workerText).toEqual(
"Hello from a remote Worker, defined for the staging environment, part of the getPlatformProxy remote bindings fixture!"
);
const kvValue = await env.MY_KV.get("test-key");
expect(kvValue).toEqual("remote-kv-value");
await dispose();
});
});
describe("account id taken from the wrangler config", () => {
vi.stubEnv("CLOUDFLARE_ACCOUNT_ID", undefined);
vi.stubEnv("CLOUDFLARE_API_TOKEN", auth.CLOUDFLARE_API_TOKEN);
test("usage with a wrangler config file with an invalid account id", async () => {
mkdirSync("./.tmp/config-with-invalid-account-id");
writeFileSync(
"./.tmp/config-with-invalid-account-id/wrangler.json",
JSON.stringify(
{
name: "get-platform-proxy-fixture-test",
account_id: "NOT a valid account id",
compatibility_date: "2025-06-01",
services: [
{
binding: "MY_WORKER",
service: remoteWorkerName,
remote: true,
},
],
},
undefined,
2
),
"utf8"
);
await expect(
getPlatformProxy<{
MY_WORKER: Fetcher;
}>({
configPath: "./.tmp/config-with-invalid-account-id/wrangler.json",
})
).rejects.toMatchInlineSnapshot(
`[Error: Failed to start the remote proxy session. Error reloading remote server: A request to the Cloudflare API (/accounts/NOT a valid account id/workers/subdomain/edge-preview) failed.]`
);
expect(errorSpy).toHaveBeenCalledOnce();
expect(
`${errorSpy.mock.calls?.[0]?.[0]}`
// Windows gets a different marker for ✘, so let's normalize it here
// so that this test can be platform independent
.replaceAll("✘", "X")
).toMatchInlineSnapshot(`
"X [ERROR] A request to the Cloudflare API (/accounts/NOT a valid account id/workers/subdomain/edge-preview) failed.
"
`);
});
test("usage with a wrangler config file with a valid account id", async () => {
mkdirSync("./.tmp/config-with-no-account-id");
writeFileSync(
"./.tmp/config-with-no-account-id/wrangler.json",
JSON.stringify(
{
name: "get-platform-proxy-fixture-test",
account_id: auth.CLOUDFLARE_ACCOUNT_ID,
compatibility_date: "2025-06-01",
services: [
{
binding: "MY_WORKER",
service: remoteWorkerName,
remote: true,
},
],
},
undefined,
2
),
"utf8"
);
const { env, dispose } = await getPlatformProxy<{
MY_WORKER: Fetcher;
}>({
configPath: "./.tmp/config-with-no-account-id/wrangler.json",
});
const response = await fetchFromWorker(env.MY_WORKER, "OK");
const workerText = await response?.text();
expect(workerText).toEqual(
"Hello from a remote Worker part of the getPlatformProxy remote bindings fixture!"
);
await dispose();
});
});
});
} else {
test.skip("getPlatformProxy - remote bindings (no auth credentials)");
}
/**
* Tries to fetch from a worker multiple times until a response is returned which matches a specified
* statusText. Each fetch has a timeout signal making sure that it can't simply get stuck.
*
* This utility is used, instead of directly fetching from the Worker in order to prevent flakiness.
*
* @param worker The Worker to fetch from.
* @param expectedStatusText The response's expected statusText.
* @returns The successful Worker's response or null if no such response was obtained.
*/
async function fetchFromWorker(
worker: Fetcher,
expectedStatusText: string,
timeout = 30_000
): Promise<Response | undefined> {
return vi.waitFor(
async () => {
try {
const response = await worker.fetch("http://example.com", {
signal: AbortSignal.timeout(5_000),
});
expect(response.statusText).toEqual(expectedStatusText);
return response;
} catch {}
},
{ timeout, interval: 500 }
);
}
/**
* Gets an env object containing Cloudflare credentials or undefined if not authenticated.
*
* In the Github actions we convert the TEST_CLOUDFLARE_ACCOUNT_ID and TEST_CLOUDFLARE_API_TOKEN env variables.
* In local development we can rely on CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN env variables directly.
*/
function getAuthenticatedEnv() {
const CLOUDFLARE_ACCOUNT_ID =
process.env.TEST_CLOUDFLARE_ACCOUNT_ID || process.env.CLOUDFLARE_ACCOUNT_ID;
const CLOUDFLARE_API_TOKEN =
process.env.TEST_CLOUDFLARE_API_TOKEN || process.env.CLOUDFLARE_API_TOKEN;
if (CLOUDFLARE_ACCOUNT_ID && CLOUDFLARE_API_TOKEN) {
return {
CLOUDFLARE_API_TOKEN,
CLOUDFLARE_ACCOUNT_ID,
};
}
console.warn(
"Skipping vitest-pool-workers remote bindings tests because the environment is not authenticated with Cloudflare."
);
}