Probar plugins en sandbox

En esta página

@emdash-cms/plugin-test construye un plugin en sandbox y ejecuta sus pruebas dentro de workerd. Las pruebas usan el wrapper del sandbox de producción de Cloudflare de EmDash y PluginBridge, con bindings locales de D1 y Worker Loader proporcionados por @cloudflare/vitest-plugin.

Los proyectos creados con emdash-plugin init incluyen esta configuración. Los proyectos de plugins existentes pueden instalar el host de pruebas como dependencia de desarrollo:

pnpm add -D @emdash-cms/plugin-test vitest

Si el proyecto restringe los scripts de compilación de dependencias, permite que workerd instale su binario de plataforma. La política de pnpm generada incluye esta entrada:

allowBuilds:
  workerd: true

Configurar Vitest

Agrega el plugin de pruebas de EmDash a la configuración de Vitest del proyecto:

import { emdashPluginTest } from "@emdash-cms/plugin-test/config";
import { defineConfig } from "vitest/config";

export default defineConfig({
	plugins: [emdashPluginTest()],
});

emdashPluginTest() ejecuta la compilación del plugin antes de que Vitest inicie. Lee el runtime y el manifiesto generados, crea una base de datos D1 aislada y un binding de Worker Loader, y exporta el mismo PluginBridge usado por las implementaciones de Cloudflare. Pasa { dir: "./packages/gallery" } cuando la configuración de Vitest está fuera del directorio del plugin.

Probar una ruta

Crea y destruye un host en cada prueba. La destrucción detiene el plugin y reinicia sus bindings de prueba:

import { afterEach, describe, expect, it } from "vitest";

import { createPluginTestHost, type PluginTestHost } from "@emdash-cms/plugin-test";

let host: PluginTestHost | undefined;

afterEach(async () => {
	await host?.dispose();
	host = undefined;
});

describe("health route", () => {
	it("identifies the plugin", async () => {
		host = await createPluginTestHost();

		await expect(host.invokeRoute("health")).resolves.toEqual({
			ok: true,
			plugin: "save-log",
		});
	});
});

invokeRoute() acepta un valor de entrada y propiedades de solicitud opcionales. La solicitud predeterminada es un POST a la ruta del plugin con cabeceras vacías y metadatos de solicitud.

Probar hooks y almacenamiento

Invoca hooks con la forma de evento que reciben de EmDash. Los lectores de almacenamiento y KV inspeccionan el estado escrito a través del bridge:

host = await createPluginTestHost();

await host.invokeHook("content:afterSave", {
	collection: "posts",
	content: { id: "post-1", title: "First post" },
});

const events = await host.storage("events").list();
expect(events).toHaveLength(1);
expect(events[0]?.data).toMatchObject({
	collection: "posts",
	contentId: "post-1",
});

Las llamadas de almacenamiento siguen aplicando las colecciones declaradas en emdash-plugin.jsonc. Las llamadas de contenido, medios, usuario, correo electrónico y red siguen aplicando las capacidades declaradas y los hosts permitidos del plugin.

Sembrar contenido

Crea una colección y siembra entradas antes de invocar una ruta o hook que lea contenido del sitio:

host = await createPluginTestHost();
await host.createCollection({
	slug: "posts",
	label: "Posts",
	fields: [{ slug: "title", label: "Title", type: "string" }],
});
await host.seedContent("posts", [{ title: "First" }, { title: "Second" }]);

await expect(host.invokeRoute("post-count")).resolves.toEqual({ count: 2 });

La colección y las entradas usan el registro de esquemas y el repositorio de contenido reales de EmDash contra D1.

Límites de las pruebas

El host cubre el plugin construido, el límite de aislamiento, la serialización de llamadas a procedimientos remotos, el comportamiento de D1, las verificaciones de capacidades, hooks, rutas, KV y el almacenamiento declarado. No renderiza la aplicación de administración de EmDash ni reproduce los límites de CPU, memoria y sub-solicitudes de las implementaciones de Cloudflare. Usa un sitio EmDash desechable para recorridos de navegador y verifica el comportamiento sensible a límites en una implementación de vista previa o staging de Cloudflare.

Para manejadores de Block Kit, invoca la ruta admin del plugin y verifica el documento de bloques devuelto. Usa el Block Playground o un recorrido de navegador para verificar el diseño renderizado y las interacciones.