add EXAMPLE=folder-name support for tests & basic-host (#292)
* add EXAMPLE=folder-name support for tests & basic-host * style: format e2e test files * style: format threejs-server files
This commit is contained in:
parent
6c5aa52c95
commit
801e1b043a
8 changed files with 177 additions and 41 deletions
|
|
@ -6,6 +6,9 @@
|
||||||
* bun examples/run-all.ts start - Build and start all examples
|
* bun examples/run-all.ts start - Build and start all examples
|
||||||
* bun examples/run-all.ts dev - Run all examples in dev/watch mode
|
* bun examples/run-all.ts dev - Run all examples in dev/watch mode
|
||||||
* bun examples/run-all.ts build - Build all examples
|
* bun examples/run-all.ts build - Build all examples
|
||||||
|
*
|
||||||
|
* Environment:
|
||||||
|
* EXAMPLE=<folder> - Run only a single example (e.g., EXAMPLE=say-server)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { readdirSync, statSync, existsSync } from "fs";
|
import { readdirSync, statSync, existsSync } from "fs";
|
||||||
|
|
@ -14,21 +17,36 @@ import concurrently from "concurrently";
|
||||||
const BASE_PORT = 3101;
|
const BASE_PORT = 3101;
|
||||||
const BASIC_HOST = "basic-host";
|
const BASIC_HOST = "basic-host";
|
||||||
|
|
||||||
|
// Optional: filter to a single example via EXAMPLE env var (folder name)
|
||||||
|
const EXAMPLE_FILTER = process.env.EXAMPLE;
|
||||||
|
|
||||||
// Find all example directories except basic-host that have a package.json,
|
// Find all example directories except basic-host that have a package.json,
|
||||||
// assign ports, and build URL list
|
// assign ports, and build URL list
|
||||||
const servers = readdirSync("examples")
|
const allServers = readdirSync("examples")
|
||||||
.filter(
|
.filter(
|
||||||
(d) =>
|
(d) =>
|
||||||
d !== BASIC_HOST &&
|
d !== BASIC_HOST &&
|
||||||
statSync(`examples/${d}`).isDirectory() &&
|
statSync(`examples/${d}`).isDirectory() &&
|
||||||
existsSync(`examples/${d}/package.json`),
|
existsSync(`examples/${d}/package.json`),
|
||||||
)
|
)
|
||||||
.sort() // Sort for consistent port assignment
|
.sort(); // Sort for consistent port assignment
|
||||||
.map((dir, i) => ({
|
|
||||||
dir,
|
// Filter servers if EXAMPLE is specified
|
||||||
port: BASE_PORT + i,
|
const filteredDirs = EXAMPLE_FILTER
|
||||||
url: `http://localhost:${BASE_PORT + i}/mcp`,
|
? allServers.filter((d) => d === EXAMPLE_FILTER)
|
||||||
}));
|
: allServers;
|
||||||
|
|
||||||
|
if (EXAMPLE_FILTER && filteredDirs.length === 0) {
|
||||||
|
console.error(`Error: No example found matching EXAMPLE=${EXAMPLE_FILTER}`);
|
||||||
|
console.error(`Available examples: ${allServers.join(", ")}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const servers = filteredDirs.map((dir, i) => ({
|
||||||
|
dir,
|
||||||
|
port: BASE_PORT + i,
|
||||||
|
url: `http://localhost:${BASE_PORT + i}/mcp`,
|
||||||
|
}));
|
||||||
|
|
||||||
const COMMANDS = ["start", "dev", "build"];
|
const COMMANDS = ["start", "dev", "build"];
|
||||||
|
|
||||||
|
|
@ -43,6 +61,9 @@ if (!command || !COMMANDS.includes(command)) {
|
||||||
const serversEnv = JSON.stringify(servers.map((s) => s.url));
|
const serversEnv = JSON.stringify(servers.map((s) => s.url));
|
||||||
|
|
||||||
console.log(`Running command: ${command}`);
|
console.log(`Running command: ${command}`);
|
||||||
|
if (EXAMPLE_FILTER) {
|
||||||
|
console.log(`Filtering to single example: ${EXAMPLE_FILTER}`);
|
||||||
|
}
|
||||||
console.log(
|
console.log(
|
||||||
`Server examples: ${servers.map((s) => `${s.dir}:${s.port}`).join(", ")}`,
|
`Server examples: ${servers.map((s) => `${s.dir}:${s.port}`).join(", ")}`,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,11 @@ This is transparent to user code - just use `requestAnimationFrame` normally.
|
||||||
Supports alpha transparency for seamless host UI integration:
|
Supports alpha transparency for seamless host UI integration:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
|
const renderer = new THREE.WebGLRenderer({
|
||||||
|
canvas,
|
||||||
|
antialias: true,
|
||||||
|
alpha: true,
|
||||||
|
});
|
||||||
renderer.setClearColor(0x000000, 0); // Fully transparent
|
renderer.setClearColor(0x000000, 0); // Fully transparent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,9 @@ export default function ThreeJSApp({
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const animControllerRef = useRef<ReturnType<typeof createAnimationController> | null>(null);
|
const animControllerRef = useRef<ReturnType<
|
||||||
|
typeof createAnimationController
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
const height = toolInputs?.height ?? toolInputsPartial?.height ?? 400;
|
const height = toolInputs?.height ?? toolInputsPartial?.height ?? 400;
|
||||||
const code = toolInputs?.code || DEFAULT_THREEJS_CODE;
|
const code = toolInputs?.code || DEFAULT_THREEJS_CODE;
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,8 @@
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
"test:e2e:update": "playwright test --update-snapshots",
|
"test:e2e:update": "playwright test --update-snapshots",
|
||||||
"test:e2e:ui": "playwright test --ui",
|
"test:e2e:ui": "playwright test --ui",
|
||||||
"test:e2e:docker": "docker run --rm -v $(pwd):/work -w /work -it mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test'",
|
"test:e2e:docker": "docker run --rm -e EXAMPLE -v $(pwd):/work -w /work -it mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test'",
|
||||||
"test:e2e:docker:update": "npm run build:all && docker run --rm -v $(pwd):/work -w /work -it mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test --update-snapshots'",
|
"test:e2e:docker:update": "npm run build:all && docker run --rm -e EXAMPLE -v $(pwd):/work -w /work -it mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test --update-snapshots'",
|
||||||
"preexamples:build": "npm run build",
|
"preexamples:build": "npm run build",
|
||||||
"examples:build": "bun examples/run-all.ts build",
|
"examples:build": "bun examples/run-all.ts build",
|
||||||
"examples:start": "NODE_ENV=development npm run build && bun examples/run-all.ts start",
|
"examples:start": "NODE_ENV=development npm run build && bun examples/run-all.ts start",
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
"prepare": "node scripts/setup-bun.mjs && npm run build && husky",
|
"prepare": "node scripts/setup-bun.mjs && npm run build && husky",
|
||||||
"docs": "typedoc",
|
"docs": "typedoc",
|
||||||
"docs:watch": "typedoc --watch",
|
"docs:watch": "typedoc --watch",
|
||||||
"generate:screenshots": "npm run build:all && docker run --rm -v $(pwd):/work -w /work mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test tests/e2e/generate-grid-screenshots.spec.ts'",
|
"generate:screenshots": "npm run build:all && docker run --rm -e EXAMPLE -v $(pwd):/work -w /work mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test tests/e2e/generate-grid-screenshots.spec.ts'",
|
||||||
"prettier": "prettier -u \"**/*.{js,jsx,ts,tsx,mjs,json,md,yml,yaml}\" --check",
|
"prettier": "prettier -u \"**/*.{js,jsx,ts,tsx,mjs,json,md,yml,yaml}\" --check",
|
||||||
"prettier:fix": "prettier -u \"**/*.{js,jsx,ts,tsx,mjs,json,md,yml,yaml}\" --write",
|
"prettier:fix": "prettier -u \"**/*.{js,jsx,ts,tsx,mjs,json,md,yml,yaml}\" --write",
|
||||||
"check:versions": "node scripts/check-versions.mjs"
|
"check:versions": "node scripts/check-versions.mjs"
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// Run examples server before tests
|
// Run examples server before tests
|
||||||
|
// Supports EXAMPLE=<folder> env var to run a single example (e.g., EXAMPLE=say-server npm run test:e2e)
|
||||||
webServer: {
|
webServer: {
|
||||||
command: "npm run examples:start",
|
command: "npm run examples:start",
|
||||||
url: "http://localhost:8080",
|
url: "http://localhost:8080",
|
||||||
|
|
@ -34,6 +35,11 @@ export default defineConfig({
|
||||||
reuseExistingServer: false,
|
reuseExistingServer: false,
|
||||||
// 3 minutes to allow uv to download Python dependencies on first run
|
// 3 minutes to allow uv to download Python dependencies on first run
|
||||||
timeout: 180000,
|
timeout: 180000,
|
||||||
|
// Pass through EXAMPLE env var to filter to a single server
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
EXAMPLE: process.env.EXAMPLE ?? "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
// Snapshot configuration
|
// Snapshot configuration
|
||||||
expect: {
|
expect: {
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,11 @@ const SKIP_SERVERS = new Set([
|
||||||
"video-resource", // Uses custom screenshot from PR comment
|
"video-resource", // Uses custom screenshot from PR comment
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Optional: filter to a single example via EXAMPLE env var (folder name)
|
||||||
|
const EXAMPLE_FILTER = process.env.EXAMPLE;
|
||||||
|
|
||||||
// Server configurations (excludes integration-server which is for E2E testing)
|
// Server configurations (excludes integration-server which is for E2E testing)
|
||||||
const SERVERS = [
|
const ALL_SERVERS = [
|
||||||
{
|
{
|
||||||
key: "basic-react",
|
key: "basic-react",
|
||||||
name: "Basic MCP App Server (React)",
|
name: "Basic MCP App Server (React)",
|
||||||
|
|
@ -55,7 +58,6 @@ const SERVERS = [
|
||||||
{ key: "map-server", name: "Map Server", dir: "map-server" },
|
{ key: "map-server", name: "Map Server", dir: "map-server" },
|
||||||
{ key: "pdf-server", name: "PDF Server", dir: "pdf-server" },
|
{ key: "pdf-server", name: "PDF Server", dir: "pdf-server" },
|
||||||
{ key: "qr-server", name: "QR Code Server", dir: "qr-server" },
|
{ key: "qr-server", name: "QR Code Server", dir: "qr-server" },
|
||||||
{ key: "say-server", name: "Say Demo", dir: "say-server" },
|
|
||||||
{
|
{
|
||||||
key: "scenario-modeler",
|
key: "scenario-modeler",
|
||||||
name: "SaaS Scenario Modeler",
|
name: "SaaS Scenario Modeler",
|
||||||
|
|
@ -82,6 +84,11 @@ const SERVERS = [
|
||||||
{ key: "wiki-explorer", name: "Wiki Explorer", dir: "wiki-explorer-server" },
|
{ key: "wiki-explorer", name: "Wiki Explorer", dir: "wiki-explorer-server" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Filter servers if EXAMPLE is specified
|
||||||
|
const SERVERS = EXAMPLE_FILTER
|
||||||
|
? ALL_SERVERS.filter((s) => s.dir === EXAMPLE_FILTER)
|
||||||
|
: ALL_SERVERS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for the MCP App to load inside nested iframes.
|
* Wait for the MCP App to load inside nested iframes.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,24 @@
|
||||||
* Note: True cross-origin attack testing would require a multi-origin test
|
* Note: True cross-origin attack testing would require a multi-origin test
|
||||||
* setup. These tests verify the security infrastructure is in place and
|
* setup. These tests verify the security infrastructure is in place and
|
||||||
* functioning correctly for valid communication paths.
|
* functioning correctly for valid communication paths.
|
||||||
|
*
|
||||||
|
* Note: These tests require the integration-server. When using EXAMPLE filter,
|
||||||
|
* set EXAMPLE=integration-server to run these tests.
|
||||||
*/
|
*/
|
||||||
import { test, expect, type Page, type ConsoleMessage } from "@playwright/test";
|
import { test, expect, type Page, type ConsoleMessage } from "@playwright/test";
|
||||||
|
|
||||||
|
// Optional: filter to a single example via EXAMPLE env var (folder name)
|
||||||
|
// Security tests require integration-server, skip if filtering to a different example
|
||||||
|
const EXAMPLE_FILTER = process.env.EXAMPLE;
|
||||||
|
const SKIP_SECURITY_TESTS =
|
||||||
|
EXAMPLE_FILTER && EXAMPLE_FILTER !== "integration-server";
|
||||||
|
|
||||||
|
// Skip all security tests if filtering to a non-integration example
|
||||||
|
test.skip(
|
||||||
|
() => !!SKIP_SECURITY_TESTS,
|
||||||
|
"Skipped: security tests require integration-server",
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capture console messages matching a pattern
|
* Capture console messages matching a pattern
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -35,30 +35,92 @@ const SLOW_SERVERS: Record<string, number> = {
|
||||||
threejs: 2000, // Three.js WebGL initialization
|
threejs: 2000, // Three.js WebGL initialization
|
||||||
};
|
};
|
||||||
|
|
||||||
// Server configurations (key is used for screenshot filenames, name is the MCP server name)
|
// Servers to skip in CI (require special resources like GPU, large ML models)
|
||||||
const SERVERS = [
|
const SKIP_SERVERS = new Set<string>([
|
||||||
{ key: "integration", name: "Integration Test Server" },
|
// None currently - say-server widget works without TTS model for screenshots
|
||||||
{ key: "basic-preact", name: "Basic MCP App Server (Preact)" },
|
]);
|
||||||
{ key: "basic-react", name: "Basic MCP App Server (React)" },
|
|
||||||
{ key: "basic-solid", name: "Basic MCP App Server (Solid)" },
|
// Optional: filter to a single example via EXAMPLE env var (folder name)
|
||||||
{ key: "basic-svelte", name: "Basic MCP App Server (Svelte)" },
|
const EXAMPLE_FILTER = process.env.EXAMPLE;
|
||||||
{ key: "basic-vanillajs", name: "Basic MCP App Server (Vanilla JS)" },
|
|
||||||
{ key: "basic-vue", name: "Basic MCP App Server (Vue)" },
|
// Server configurations (key is used for screenshot filenames, name is the MCP server name, dir is the folder name)
|
||||||
{ key: "budget-allocator", name: "Budget Allocator Server" },
|
const ALL_SERVERS = [
|
||||||
{ key: "cohort-heatmap", name: "Cohort Heatmap Server" },
|
{
|
||||||
{ key: "customer-segmentation", name: "Customer Segmentation Server" },
|
key: "integration",
|
||||||
{ key: "map-server", name: "Map Server" },
|
name: "Integration Test Server",
|
||||||
{ key: "pdf-server", name: "PDF Server" },
|
dir: "integration-server",
|
||||||
{ key: "qr-server", name: "QR Code Server" },
|
},
|
||||||
{ key: "scenario-modeler", name: "SaaS Scenario Modeler" },
|
{
|
||||||
{ key: "shadertoy", name: "ShaderToy Server" },
|
key: "basic-preact",
|
||||||
{ key: "sheet-music", name: "Sheet Music Server" },
|
name: "Basic MCP App Server (Preact)",
|
||||||
{ key: "system-monitor", name: "System Monitor Server" },
|
dir: "basic-server-preact",
|
||||||
{ key: "threejs", name: "Three.js Server" },
|
},
|
||||||
{ key: "transcript", name: "Transcript Server" },
|
{
|
||||||
{ key: "wiki-explorer", name: "Wiki Explorer" },
|
key: "basic-react",
|
||||||
|
name: "Basic MCP App Server (React)",
|
||||||
|
dir: "basic-server-react",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "basic-solid",
|
||||||
|
name: "Basic MCP App Server (Solid)",
|
||||||
|
dir: "basic-server-solid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "basic-svelte",
|
||||||
|
name: "Basic MCP App Server (Svelte)",
|
||||||
|
dir: "basic-server-svelte",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "basic-vanillajs",
|
||||||
|
name: "Basic MCP App Server (Vanilla JS)",
|
||||||
|
dir: "basic-server-vanillajs",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "basic-vue",
|
||||||
|
name: "Basic MCP App Server (Vue)",
|
||||||
|
dir: "basic-server-vue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "budget-allocator",
|
||||||
|
name: "Budget Allocator Server",
|
||||||
|
dir: "budget-allocator-server",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "cohort-heatmap",
|
||||||
|
name: "Cohort Heatmap Server",
|
||||||
|
dir: "cohort-heatmap-server",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "customer-segmentation",
|
||||||
|
name: "Customer Segmentation Server",
|
||||||
|
dir: "customer-segmentation-server",
|
||||||
|
},
|
||||||
|
{ key: "map-server", name: "Map Server", dir: "map-server" },
|
||||||
|
{ key: "pdf-server", name: "PDF Server", dir: "pdf-server" },
|
||||||
|
{ key: "qr-server", name: "QR Code Server", dir: "qr-server" },
|
||||||
|
{ key: "say-server", name: "Say Demo", dir: "say-server" },
|
||||||
|
{
|
||||||
|
key: "scenario-modeler",
|
||||||
|
name: "SaaS Scenario Modeler",
|
||||||
|
dir: "scenario-modeler-server",
|
||||||
|
},
|
||||||
|
{ key: "shadertoy", name: "ShaderToy Server", dir: "shadertoy-server" },
|
||||||
|
{ key: "sheet-music", name: "Sheet Music Server", dir: "sheet-music-server" },
|
||||||
|
{
|
||||||
|
key: "system-monitor",
|
||||||
|
name: "System Monitor Server",
|
||||||
|
dir: "system-monitor-server",
|
||||||
|
},
|
||||||
|
{ key: "threejs", name: "Three.js Server", dir: "threejs-server" },
|
||||||
|
{ key: "transcript", name: "Transcript Server", dir: "transcript-server" },
|
||||||
|
{ key: "wiki-explorer", name: "Wiki Explorer", dir: "wiki-explorer-server" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Filter servers if EXAMPLE is specified
|
||||||
|
const SERVERS = EXAMPLE_FILTER
|
||||||
|
? ALL_SERVERS.filter((s) => s.dir === EXAMPLE_FILTER)
|
||||||
|
: ALL_SERVERS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to get the app frame locator (nested: sandbox > app)
|
* Helper to get the app frame locator (nested: sandbox > app)
|
||||||
*/
|
*/
|
||||||
|
|
@ -129,12 +191,23 @@ test.describe("Host UI", () => {
|
||||||
|
|
||||||
// Define tests for each server using forEach to avoid for-loop issues
|
// Define tests for each server using forEach to avoid for-loop issues
|
||||||
SERVERS.forEach((server) => {
|
SERVERS.forEach((server) => {
|
||||||
|
// Skip servers that require special resources (GPU, large ML models)
|
||||||
|
const shouldSkip = SKIP_SERVERS.has(server.key);
|
||||||
|
|
||||||
test.describe(server.name, () => {
|
test.describe(server.name, () => {
|
||||||
test("loads app UI", async ({ page }) => {
|
test("loads app UI", async ({ page }) => {
|
||||||
|
if (shouldSkip) {
|
||||||
|
test.skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
await loadServer(page, server.name);
|
await loadServer(page, server.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("screenshot matches golden", async ({ page }) => {
|
test("screenshot matches golden", async ({ page }) => {
|
||||||
|
if (shouldSkip) {
|
||||||
|
test.skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
await loadServer(page, server.name);
|
await loadServer(page, server.name);
|
||||||
|
|
||||||
// Some servers (WebGL, tile-based) need extra stabilization time
|
// Some servers (WebGL, tile-based) need extra stabilization time
|
||||||
|
|
@ -153,12 +226,20 @@ SERVERS.forEach((server) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Interaction tests for integration server (tests all SDK communication APIs)
|
// Interaction tests for integration server (tests all SDK communication APIs)
|
||||||
const integrationServer = SERVERS.find((s) => s.key === "integration")!;
|
// Only run if integration-server is included (either no filter or EXAMPLE=integration-server)
|
||||||
|
const integrationServer = SERVERS.find((s) => s.key === "integration");
|
||||||
|
const integrationServerName =
|
||||||
|
integrationServer?.name ?? "Integration Test Server";
|
||||||
|
|
||||||
|
test.describe(`Integration Test Server - Interactions`, () => {
|
||||||
|
test.skip(
|
||||||
|
() => !integrationServer,
|
||||||
|
"Skipped: integration-server not in EXAMPLE filter",
|
||||||
|
);
|
||||||
|
|
||||||
test.describe(`${integrationServer.name} - Interactions`, () => {
|
|
||||||
test("Send Message button triggers host callback", async ({ page }) => {
|
test("Send Message button triggers host callback", async ({ page }) => {
|
||||||
const logs = captureHostLogs(page);
|
const logs = captureHostLogs(page);
|
||||||
await loadServer(page, integrationServer.name);
|
await loadServer(page, integrationServerName);
|
||||||
|
|
||||||
const appFrame = getAppFrame(page);
|
const appFrame = getAppFrame(page);
|
||||||
await appFrame.locator('button:has-text("Send Message")').click();
|
await appFrame.locator('button:has-text("Send Message")').click();
|
||||||
|
|
@ -171,7 +252,7 @@ test.describe(`${integrationServer.name} - Interactions`, () => {
|
||||||
|
|
||||||
test("Send Log button triggers host callback", async ({ page }) => {
|
test("Send Log button triggers host callback", async ({ page }) => {
|
||||||
const logs = captureHostLogs(page);
|
const logs = captureHostLogs(page);
|
||||||
await loadServer(page, integrationServer.name);
|
await loadServer(page, integrationServerName);
|
||||||
|
|
||||||
const appFrame = getAppFrame(page);
|
const appFrame = getAppFrame(page);
|
||||||
await appFrame.locator('button:has-text("Send Log")').click();
|
await appFrame.locator('button:has-text("Send Log")').click();
|
||||||
|
|
@ -185,7 +266,7 @@ test.describe(`${integrationServer.name} - Interactions`, () => {
|
||||||
|
|
||||||
test("Open Link button triggers host callback", async ({ page }) => {
|
test("Open Link button triggers host callback", async ({ page }) => {
|
||||||
const logs = captureHostLogs(page);
|
const logs = captureHostLogs(page);
|
||||||
await loadServer(page, integrationServer.name);
|
await loadServer(page, integrationServerName);
|
||||||
|
|
||||||
const appFrame = getAppFrame(page);
|
const appFrame = getAppFrame(page);
|
||||||
await appFrame.locator('button:has-text("Open Link")').click();
|
await appFrame.locator('button:has-text("Open Link")').click();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue