Files
computer-playbook/roles/web-app-openwebui/files/playwright/playwright.spec.js
kevinveenbirkenbachandClaude Opus 5 60a9dca2b1 test(openwebui): make the MCP client open the connection, not just record it
GET /api/v1/tools/ builds its answer for an MCP server out of stored config alone - routers/tools.py:125-126 reads info off the connection row and never touches the network. So the three specs that read it pass unchanged against a provider that is down, refuses the deployed bearer, or serves nothing. What they establish is registration and the OIDC group to access-grant chain, not that the bridge carries.

POST /api/v1/configs/tool_servers/verify is the one route in 0.11.0 that does a real MCP initialize plus tools/list without an LLM, and it authenticates with the key in the body it is handed. The spec reads the stored connection and echoes it back, so the handshake runs over the deployed URL with the deployed credential through Open WebUI's own client, and asserts three things per server: it answers, it serves at least one tool, and the tool set contains the read probe its meta/mcp.yml declares.

Only bearer connections are verified. A system_oauth one resolves the caller's own upstream token per request and the administrator holds none, so it would fail on the caller rather than on the bridge; no provider declares auth: oidc today, but the filter keeps the spec honest when one does. The per-test budget scales with the number of registered servers instead of a fixed guess.

MCP_EXPECTED_TOOLS carries the declared read probe per server. Its rendering is unit-tested by extracting the block from the template itself rather than restating it, and decoded the way a spec decodes it - dotenv_quote emits an escaped JSON string that decodeDotenvQuotedValue unwraps before the spec parses the payload, so comparing after one decode would test a value no spec ever sees.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 21:58:54 +02:00

22 lines
797 B
JavaScript

const { test } = require("@playwright/test");
const shared = require("./_shared");
test.use({ ignoreHTTPSErrors: true });
test.beforeEach(shared.beforeEach);
require("./test-csp").register(shared);
require("./test-admin-oidc-login").register(shared);
require("./test-biber-oidc-login").register(shared);
require("./test-admin-native-login").register(shared);
require("./test-admin-ldap-login").register(shared);
require("./test-biber-ldap-login").register(shared);
require("./test-guest-persona").register(shared);
require("./test-litellm-chat").register(shared);
require("./test-mcp-servers").register(shared);
require("./test-mcp-bridge").register(shared);
require("./test-mcp-non-member").register(shared);
require("./test-mcp-grant-via-lam").register(shared);
require("./test-seaweedfs");