@frontmcp/testing 1.8.7 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/mcp-test-client.d.ts.map +1 -1
- package/esm/fixtures/index.mjs +524 -31
- package/esm/index.mjs +525 -31
- package/esm/matchers/index.mjs +3 -0
- package/esm/package.json +8 -6
- package/esm/perf/index.mjs +466 -7
- package/esm/perf/perf-setup.mjs +3 -0
- package/esm/playwright/index.mjs +3 -0
- package/esm/setup.mjs +3 -0
- package/fixtures/fixture-types.d.ts +19 -6
- package/fixtures/fixture-types.d.ts.map +1 -1
- package/fixtures/index.d.ts +1 -1
- package/fixtures/index.d.ts.map +1 -1
- package/fixtures/index.js +521 -31
- package/fixtures/test-fixture.d.ts.map +1 -1
- package/index.d.ts +2 -1
- package/index.d.ts.map +1 -1
- package/index.js +523 -31
- package/package.json +8 -6
- package/perf/index.js +463 -7
- package/transport/index.d.ts +1 -0
- package/transport/index.d.ts.map +1 -1
- package/transport/sse.transport.d.ts +80 -0
- package/transport/sse.transport.d.ts.map +1 -0
package/esm/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/testing",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "E2E testing framework for FrontMCP servers - MCP client, auth mocks, Playwright integration",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -87,9 +87,9 @@
|
|
|
87
87
|
"./esm": null
|
|
88
88
|
},
|
|
89
89
|
"peerDependencies": {
|
|
90
|
-
"@frontmcp/lazy-zod": "1.
|
|
91
|
-
"@frontmcp/sdk": "1.
|
|
92
|
-
"@frontmcp/ui": "1.
|
|
90
|
+
"@frontmcp/lazy-zod": "1.9.0",
|
|
91
|
+
"@frontmcp/sdk": "1.9.0",
|
|
92
|
+
"@frontmcp/ui": "1.9.0",
|
|
93
93
|
"@jest/globals": "^29.0.0 || ^30.0.0",
|
|
94
94
|
"@playwright/test": "^1.40.0",
|
|
95
95
|
"jest": "^29.0.0 || ^30.0.0"
|
|
@@ -112,8 +112,10 @@
|
|
|
112
112
|
"node": ">=24.0.0"
|
|
113
113
|
},
|
|
114
114
|
"dependencies": {
|
|
115
|
-
"@frontmcp/protocol": "1.
|
|
116
|
-
"@frontmcp/utils": "1.
|
|
115
|
+
"@frontmcp/protocol": "1.9.0",
|
|
116
|
+
"@frontmcp/utils": "1.9.0",
|
|
117
|
+
"@swc/core": "~1.15.41",
|
|
118
|
+
"@swc/jest": "~0.2.38",
|
|
117
119
|
"jose": "^6.0.11",
|
|
118
120
|
"tslib": "^2.3.0"
|
|
119
121
|
},
|
package/esm/perf/index.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
|
|
2
|
+
const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
|
|
3
|
+
// __frontmcpCreateRequire
|
|
1
4
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
5
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
6
|
}) : x)(function(x) {
|
|
@@ -1256,8 +1259,453 @@ function isInterceptedError(err) {
|
|
|
1256
1259
|
return typeof err === "object" && err !== null && interceptedErrors.has(err);
|
|
1257
1260
|
}
|
|
1258
1261
|
|
|
1259
|
-
// libs/testing/src/transport/
|
|
1262
|
+
// libs/testing/src/transport/sse.transport.ts
|
|
1260
1263
|
var DEFAULT_TIMEOUT = 3e4;
|
|
1264
|
+
var SseTransport = class {
|
|
1265
|
+
baseUrl;
|
|
1266
|
+
entryPath;
|
|
1267
|
+
timeout;
|
|
1268
|
+
authHeaders;
|
|
1269
|
+
publicMode;
|
|
1270
|
+
debug;
|
|
1271
|
+
clientInfo;
|
|
1272
|
+
notificationHandler;
|
|
1273
|
+
interceptors;
|
|
1274
|
+
elicitationHandler;
|
|
1275
|
+
state = "disconnected";
|
|
1276
|
+
authToken;
|
|
1277
|
+
sessionId;
|
|
1278
|
+
messageEndpoint;
|
|
1279
|
+
stream;
|
|
1280
|
+
pending = /* @__PURE__ */ new Map();
|
|
1281
|
+
connectionCount = 0;
|
|
1282
|
+
reconnectCount = 0;
|
|
1283
|
+
lastRequestHeaders = {};
|
|
1284
|
+
constructor(config) {
|
|
1285
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
1286
|
+
this.entryPath = config.entryPath;
|
|
1287
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
1288
|
+
this.authHeaders = config.auth?.headers ?? {};
|
|
1289
|
+
this.authToken = config.auth?.token;
|
|
1290
|
+
this.publicMode = config.publicMode ?? false;
|
|
1291
|
+
this.debug = config.debug ?? false;
|
|
1292
|
+
this.clientInfo = config.clientInfo;
|
|
1293
|
+
this.notificationHandler = config.notificationHandler;
|
|
1294
|
+
this.interceptors = config.interceptors;
|
|
1295
|
+
this.elicitationHandler = config.elicitationHandler;
|
|
1296
|
+
}
|
|
1297
|
+
async connect() {
|
|
1298
|
+
this.state = "connecting";
|
|
1299
|
+
this.connectionCount++;
|
|
1300
|
+
try {
|
|
1301
|
+
if (!this.publicMode && !this.authToken) {
|
|
1302
|
+
await this.requestAnonymousToken();
|
|
1303
|
+
}
|
|
1304
|
+
await this.openStream();
|
|
1305
|
+
this.state = "connected";
|
|
1306
|
+
this.log(`Connected; messages go to ${this.messageEndpoint}`);
|
|
1307
|
+
} catch (error) {
|
|
1308
|
+
this.state = "error";
|
|
1309
|
+
this.stream?.abort();
|
|
1310
|
+
this.stream = void 0;
|
|
1311
|
+
throw error;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
async request(message) {
|
|
1315
|
+
this.ensureConnected();
|
|
1316
|
+
const startTime = Date.now();
|
|
1317
|
+
if (this.interceptors) {
|
|
1318
|
+
const intercepted = await this.interceptors.processRequest(message, {
|
|
1319
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1320
|
+
transport: "sse",
|
|
1321
|
+
sessionId: this.sessionId
|
|
1322
|
+
});
|
|
1323
|
+
switch (intercepted.type) {
|
|
1324
|
+
case "mock":
|
|
1325
|
+
return await this.interceptors.processResponse(
|
|
1326
|
+
message,
|
|
1327
|
+
intercepted.response,
|
|
1328
|
+
Date.now() - startTime
|
|
1329
|
+
);
|
|
1330
|
+
case "error":
|
|
1331
|
+
throw markInterceptedError(intercepted.error);
|
|
1332
|
+
case "continue":
|
|
1333
|
+
message = intercepted.request;
|
|
1334
|
+
break;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
let response;
|
|
1338
|
+
if (message.id === void 0) {
|
|
1339
|
+
await this.post(JSON.stringify(message));
|
|
1340
|
+
response = { jsonrpc: "2.0", id: null, result: void 0 };
|
|
1341
|
+
} else {
|
|
1342
|
+
response = await this.postAndAwait(message.id, JSON.stringify(message));
|
|
1343
|
+
}
|
|
1344
|
+
if (this.interceptors) {
|
|
1345
|
+
response = await this.interceptors.processResponse(message, response, Date.now() - startTime);
|
|
1346
|
+
}
|
|
1347
|
+
return response;
|
|
1348
|
+
}
|
|
1349
|
+
async notify(message) {
|
|
1350
|
+
this.ensureConnected();
|
|
1351
|
+
const result = await this.post(JSON.stringify(message));
|
|
1352
|
+
if (!result.ok) this.log(`HTTP ${result.status} on notification: ${result.body}`);
|
|
1353
|
+
}
|
|
1354
|
+
async sendRaw(data) {
|
|
1355
|
+
this.ensureConnected();
|
|
1356
|
+
let id;
|
|
1357
|
+
try {
|
|
1358
|
+
const parsed = JSON.parse(data);
|
|
1359
|
+
if (typeof parsed.id === "string" || typeof parsed.id === "number") id = parsed.id;
|
|
1360
|
+
} catch {
|
|
1361
|
+
}
|
|
1362
|
+
if (id !== void 0) return this.postAndAwait(id, data);
|
|
1363
|
+
const result = await this.post(data);
|
|
1364
|
+
if (!result.ok) {
|
|
1365
|
+
return { jsonrpc: "2.0", id: null, error: { code: -32700, message: "Parse error", data: result.body } };
|
|
1366
|
+
}
|
|
1367
|
+
return { jsonrpc: "2.0", id: null, result: void 0 };
|
|
1368
|
+
}
|
|
1369
|
+
async close() {
|
|
1370
|
+
this.closeStream("Transport closed");
|
|
1371
|
+
this.state = "disconnected";
|
|
1372
|
+
this.sessionId = void 0;
|
|
1373
|
+
this.messageEndpoint = void 0;
|
|
1374
|
+
this.log("SSE transport closed");
|
|
1375
|
+
}
|
|
1376
|
+
isConnected() {
|
|
1377
|
+
return this.state === "connected";
|
|
1378
|
+
}
|
|
1379
|
+
getState() {
|
|
1380
|
+
return this.state;
|
|
1381
|
+
}
|
|
1382
|
+
getSessionId() {
|
|
1383
|
+
return this.sessionId;
|
|
1384
|
+
}
|
|
1385
|
+
setAuthToken(token) {
|
|
1386
|
+
this.authToken = token;
|
|
1387
|
+
}
|
|
1388
|
+
setTimeout(ms) {
|
|
1389
|
+
this.timeout = ms;
|
|
1390
|
+
}
|
|
1391
|
+
getMessageEndpoint() {
|
|
1392
|
+
return this.messageEndpoint;
|
|
1393
|
+
}
|
|
1394
|
+
getConnectionCount() {
|
|
1395
|
+
return this.connectionCount;
|
|
1396
|
+
}
|
|
1397
|
+
getReconnectCount() {
|
|
1398
|
+
return this.reconnectCount;
|
|
1399
|
+
}
|
|
1400
|
+
getLastRequestHeaders() {
|
|
1401
|
+
return { ...this.lastRequestHeaders };
|
|
1402
|
+
}
|
|
1403
|
+
setInterceptors(interceptors2) {
|
|
1404
|
+
this.interceptors = interceptors2;
|
|
1405
|
+
}
|
|
1406
|
+
getInterceptors() {
|
|
1407
|
+
return this.interceptors;
|
|
1408
|
+
}
|
|
1409
|
+
setElicitationHandler(handler) {
|
|
1410
|
+
this.elicitationHandler = handler;
|
|
1411
|
+
}
|
|
1412
|
+
async simulateDisconnect() {
|
|
1413
|
+
this.closeStream("Simulated disconnect");
|
|
1414
|
+
this.state = "disconnected";
|
|
1415
|
+
this.sessionId = void 0;
|
|
1416
|
+
this.messageEndpoint = void 0;
|
|
1417
|
+
}
|
|
1418
|
+
async waitForReconnect(timeoutMs) {
|
|
1419
|
+
this.reconnectCount++;
|
|
1420
|
+
let timer;
|
|
1421
|
+
try {
|
|
1422
|
+
await Promise.race([
|
|
1423
|
+
this.connect(),
|
|
1424
|
+
new Promise((_, reject) => {
|
|
1425
|
+
timer = setTimeout(() => reject(new Error("Timeout waiting for reconnection")), timeoutMs);
|
|
1426
|
+
})
|
|
1427
|
+
]);
|
|
1428
|
+
} finally {
|
|
1429
|
+
clearTimeout(timer);
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
1433
|
+
// STREAM
|
|
1434
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
1435
|
+
/** Open `GET <entry>/sse` and wait for the `endpoint` event. */
|
|
1436
|
+
async openStream() {
|
|
1437
|
+
const controller = new AbortController();
|
|
1438
|
+
this.stream = controller;
|
|
1439
|
+
const url = this.sseUrl();
|
|
1440
|
+
const { "Content-Type": _contentType, ...headers } = this.buildHeaders();
|
|
1441
|
+
this.log(`GET ${url}`);
|
|
1442
|
+
const connectTimer = setTimeout(() => controller.abort(), this.timeout);
|
|
1443
|
+
let response;
|
|
1444
|
+
try {
|
|
1445
|
+
response = await fetch(url, {
|
|
1446
|
+
method: "GET",
|
|
1447
|
+
headers: { ...headers, Accept: "text/event-stream" },
|
|
1448
|
+
signal: controller.signal
|
|
1449
|
+
});
|
|
1450
|
+
} catch (error) {
|
|
1451
|
+
clearTimeout(connectTimer);
|
|
1452
|
+
throw new Error(
|
|
1453
|
+
isAbortError(error) ? `SSE connection to ${url} timed out after ${this.timeout}ms` : `SSE connection to ${url} failed: ${errorMessage(error)}`,
|
|
1454
|
+
{ cause: error }
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1457
|
+
const isEventStream = response.headers.get("content-type")?.includes("text/event-stream") ?? false;
|
|
1458
|
+
if (!response.ok || !response.body || !isEventStream) {
|
|
1459
|
+
clearTimeout(connectTimer);
|
|
1460
|
+
const body = await response.text().catch(() => "");
|
|
1461
|
+
throw new Error(
|
|
1462
|
+
`SSE connection to ${url} failed: HTTP ${response.status} ${response.statusText}${body ? ` \u2014 ${body}` : ""}. The legacy HTTP+SSE transport needs a server that serves it (@FrontMcp({ transport: { protocol: { legacy: true } } })).`
|
|
1463
|
+
);
|
|
1464
|
+
}
|
|
1465
|
+
const endpoint = new Promise((resolve, reject) => {
|
|
1466
|
+
const reader = response.body?.getReader();
|
|
1467
|
+
if (!reader) {
|
|
1468
|
+
reject(new Error(`SSE connection to ${url} has no body`));
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
void this.readStream(controller, reader, resolve, reject);
|
|
1472
|
+
});
|
|
1473
|
+
try {
|
|
1474
|
+
const data = await endpoint;
|
|
1475
|
+
const messageUrl = new URL(data, url);
|
|
1476
|
+
this.messageEndpoint = messageUrl.toString();
|
|
1477
|
+
this.sessionId = messageUrl.searchParams.get("sessionId") ?? void 0;
|
|
1478
|
+
} finally {
|
|
1479
|
+
clearTimeout(connectTimer);
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
async readStream(controller, reader, onEndpoint, onEndpointError) {
|
|
1483
|
+
const decoder = new TextDecoder();
|
|
1484
|
+
let buffer = "";
|
|
1485
|
+
let endpointSeen = false;
|
|
1486
|
+
try {
|
|
1487
|
+
for (let chunk = await reader.read(); !chunk.done; chunk = await reader.read()) {
|
|
1488
|
+
const { completeEvents, remainder } = splitSSEEvents(buffer + decoder.decode(chunk.value, { stream: true }));
|
|
1489
|
+
buffer = remainder;
|
|
1490
|
+
for (const text of completeEvents) {
|
|
1491
|
+
const event = parseSSEEvent(text);
|
|
1492
|
+
if (!event) continue;
|
|
1493
|
+
if (event.type === "endpoint") {
|
|
1494
|
+
if (!endpointSeen) {
|
|
1495
|
+
endpointSeen = true;
|
|
1496
|
+
onEndpoint(event.data);
|
|
1497
|
+
}
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
await this.handleMessage(event.data);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
} catch (error) {
|
|
1504
|
+
if (!controller.signal.aborted) this.log("SSE stream failed:", error);
|
|
1505
|
+
} finally {
|
|
1506
|
+
reader.releaseLock();
|
|
1507
|
+
}
|
|
1508
|
+
if (!endpointSeen) {
|
|
1509
|
+
onEndpointError(
|
|
1510
|
+
new Error(
|
|
1511
|
+
controller.signal.aborted ? `SSE stream at ${this.sseUrl()} sent no endpoint event within ${this.timeout}ms` : `SSE stream at ${this.sseUrl()} ended before the server sent its endpoint`
|
|
1512
|
+
)
|
|
1513
|
+
);
|
|
1514
|
+
}
|
|
1515
|
+
if (this.stream === controller) {
|
|
1516
|
+
this.stream = void 0;
|
|
1517
|
+
this.rejectPending("SSE stream closed by the server");
|
|
1518
|
+
if (this.state === "connected") this.state = "disconnected";
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
async handleMessage(data) {
|
|
1522
|
+
let message;
|
|
1523
|
+
try {
|
|
1524
|
+
message = JSON.parse(data);
|
|
1525
|
+
} catch {
|
|
1526
|
+
this.log("Ignoring SSE event that is not JSON:", data);
|
|
1527
|
+
return;
|
|
1528
|
+
}
|
|
1529
|
+
if (!message || typeof message !== "object") return;
|
|
1530
|
+
if (typeof message.method === "string") {
|
|
1531
|
+
const request = message;
|
|
1532
|
+
if (request.id === void 0 || request.id === null) {
|
|
1533
|
+
this.notificationHandler?.(request);
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1536
|
+
await this.answerServerRequest(request);
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
if (message.id !== void 0 && message.id !== null) {
|
|
1540
|
+
const pending = this.pending.get(message.id);
|
|
1541
|
+
if (pending) {
|
|
1542
|
+
clearTimeout(pending.timer);
|
|
1543
|
+
this.pending.delete(message.id);
|
|
1544
|
+
pending.resolve(message);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
/** Server→client requests: elicitation goes to the handler, `ping` is answered, the rest refused. */
|
|
1549
|
+
async answerServerRequest(request) {
|
|
1550
|
+
const id = request.id;
|
|
1551
|
+
let reply;
|
|
1552
|
+
if (request.method === "elicitation/create") {
|
|
1553
|
+
reply = { jsonrpc: "2.0", id, result: await this.elicit(request.params) };
|
|
1554
|
+
} else if (request.method === "ping") {
|
|
1555
|
+
reply = { jsonrpc: "2.0", id, result: {} };
|
|
1556
|
+
} else {
|
|
1557
|
+
reply = { jsonrpc: "2.0", id, error: { code: -32601, message: `Method not found: ${request.method}` } };
|
|
1558
|
+
}
|
|
1559
|
+
const result = await this.post(JSON.stringify(reply));
|
|
1560
|
+
if (!result.ok) this.log(`HTTP ${result.status} answering ${request.method}: ${result.body}`);
|
|
1561
|
+
}
|
|
1562
|
+
async elicit(params) {
|
|
1563
|
+
if (!this.elicitationHandler) return { action: "decline" };
|
|
1564
|
+
try {
|
|
1565
|
+
return await this.elicitationHandler(params);
|
|
1566
|
+
} catch (error) {
|
|
1567
|
+
this.log("Elicitation handler error:", error);
|
|
1568
|
+
return { action: "cancel" };
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
closeStream(reason) {
|
|
1572
|
+
const controller = this.stream;
|
|
1573
|
+
this.stream = void 0;
|
|
1574
|
+
controller?.abort();
|
|
1575
|
+
this.rejectPending(reason);
|
|
1576
|
+
}
|
|
1577
|
+
rejectPending(reason) {
|
|
1578
|
+
for (const [id, pending] of this.pending) {
|
|
1579
|
+
clearTimeout(pending.timer);
|
|
1580
|
+
pending.resolve({ jsonrpc: "2.0", id, error: { code: -32e3, message: reason } });
|
|
1581
|
+
}
|
|
1582
|
+
this.pending.clear();
|
|
1583
|
+
}
|
|
1584
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
1585
|
+
// POSTING
|
|
1586
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
1587
|
+
/** POST a message and resolve with the response the stream carries for `id`. */
|
|
1588
|
+
async postAndAwait(id, body) {
|
|
1589
|
+
const answer = new Promise((resolve) => {
|
|
1590
|
+
const timer = setTimeout(() => {
|
|
1591
|
+
this.pending.delete(id);
|
|
1592
|
+
resolve({ jsonrpc: "2.0", id, error: { code: -32e3, message: `Request timeout after ${this.timeout}ms` } });
|
|
1593
|
+
}, this.timeout);
|
|
1594
|
+
this.pending.set(id, { resolve, timer });
|
|
1595
|
+
});
|
|
1596
|
+
const result = await this.post(body);
|
|
1597
|
+
if (!result.ok) {
|
|
1598
|
+
const pending = this.pending.get(id);
|
|
1599
|
+
if (pending) {
|
|
1600
|
+
clearTimeout(pending.timer);
|
|
1601
|
+
this.pending.delete(id);
|
|
1602
|
+
}
|
|
1603
|
+
return {
|
|
1604
|
+
jsonrpc: "2.0",
|
|
1605
|
+
id,
|
|
1606
|
+
error: { code: -32e3, message: `HTTP ${result.status}: ${result.statusText}`, data: result.body }
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
return answer;
|
|
1610
|
+
}
|
|
1611
|
+
async post(body) {
|
|
1612
|
+
const endpoint = this.messageEndpoint;
|
|
1613
|
+
if (!endpoint) throw new Error("SSE transport has no message endpoint. Call connect() first.");
|
|
1614
|
+
const headers = this.buildHeaders();
|
|
1615
|
+
this.lastRequestHeaders = headers;
|
|
1616
|
+
this.log(`POST ${endpoint}`, body);
|
|
1617
|
+
const controller = new AbortController();
|
|
1618
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
1619
|
+
try {
|
|
1620
|
+
const response = await fetch(endpoint, { method: "POST", headers, body, signal: controller.signal });
|
|
1621
|
+
const text = await response.text();
|
|
1622
|
+
return { ok: response.ok, status: response.status, statusText: response.statusText, body: text };
|
|
1623
|
+
} catch (error) {
|
|
1624
|
+
if (isAbortError(error)) {
|
|
1625
|
+
return { ok: false, status: 0, statusText: `timeout after ${this.timeout}ms`, body: "" };
|
|
1626
|
+
}
|
|
1627
|
+
throw error;
|
|
1628
|
+
} finally {
|
|
1629
|
+
clearTimeout(timer);
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
1633
|
+
// HELPERS
|
|
1634
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
1635
|
+
async requestAnonymousToken() {
|
|
1636
|
+
const url = new URL(this.baseUrl);
|
|
1637
|
+
url.pathname = `${url.pathname.replace(/\/+$/, "")}/oauth/token`;
|
|
1638
|
+
url.search = "";
|
|
1639
|
+
const tokenUrl = url.toString();
|
|
1640
|
+
try {
|
|
1641
|
+
const response = await fetch(tokenUrl, {
|
|
1642
|
+
method: "POST",
|
|
1643
|
+
headers: { "Content-Type": "application/json" },
|
|
1644
|
+
body: JSON.stringify({ grant_type: "anonymous", client_id: crypto.randomUUID(), resource: this.baseUrl })
|
|
1645
|
+
});
|
|
1646
|
+
if (!response.ok) {
|
|
1647
|
+
this.log(`No anonymous token (HTTP ${response.status})`);
|
|
1648
|
+
return;
|
|
1649
|
+
}
|
|
1650
|
+
const token = await response.json();
|
|
1651
|
+
if (token.access_token) this.authToken = token.access_token;
|
|
1652
|
+
} catch (error) {
|
|
1653
|
+
this.log("Error requesting anonymous token:", error);
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
/** `<baseUrl><entryPath>/sse`, built from URL parts so query params on `baseUrl` survive. */
|
|
1657
|
+
sseUrl() {
|
|
1658
|
+
const url = new URL(this.baseUrl);
|
|
1659
|
+
const entry = (this.entryPath ?? "").replace(/^\/+|\/+$/g, "");
|
|
1660
|
+
const basePath = url.pathname.replace(/\/+$/, "");
|
|
1661
|
+
url.pathname = entry ? `${basePath}/${entry}/sse` : `${basePath}/sse`;
|
|
1662
|
+
return url.toString();
|
|
1663
|
+
}
|
|
1664
|
+
buildHeaders() {
|
|
1665
|
+
const headers = {
|
|
1666
|
+
"Content-Type": "application/json",
|
|
1667
|
+
Accept: "application/json, text/event-stream"
|
|
1668
|
+
};
|
|
1669
|
+
if (this.clientInfo) headers["User-Agent"] = `${this.clientInfo.name}/${this.clientInfo.version}`;
|
|
1670
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
1671
|
+
if (this.sessionId) headers["mcp-session-id"] = this.sessionId;
|
|
1672
|
+
Object.assign(headers, this.authHeaders);
|
|
1673
|
+
return headers;
|
|
1674
|
+
}
|
|
1675
|
+
ensureConnected() {
|
|
1676
|
+
if (this.state !== "connected") {
|
|
1677
|
+
throw new Error("Transport not connected. Call connect() first.");
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
log(message, data) {
|
|
1681
|
+
if (this.debug) {
|
|
1682
|
+
console.log(`[SSE] ${message}`, data ?? "");
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
};
|
|
1686
|
+
function splitSSEEvents(buffer) {
|
|
1687
|
+
const endsWithCarriageReturn = buffer.endsWith("\r");
|
|
1688
|
+
const normalized = (endsWithCarriageReturn ? buffer.slice(0, -1) : buffer).replace(/\r\n?/g, "\n");
|
|
1689
|
+
const completeEvents = normalized.split("\n\n");
|
|
1690
|
+
const remainder = completeEvents.pop() ?? "";
|
|
1691
|
+
return { completeEvents, remainder: endsWithCarriageReturn ? `${remainder}\r` : remainder };
|
|
1692
|
+
}
|
|
1693
|
+
function parseSSEEvent(text) {
|
|
1694
|
+
let type = "message";
|
|
1695
|
+
const data = [];
|
|
1696
|
+
for (const line of text.split("\n")) {
|
|
1697
|
+
if (line.startsWith(":")) continue;
|
|
1698
|
+
const colon = line.indexOf(":");
|
|
1699
|
+
const field = colon === -1 ? line : line.slice(0, colon);
|
|
1700
|
+
const value = colon === -1 ? "" : line.slice(colon + 1).replace(/^ /, "");
|
|
1701
|
+
if (field === "event") type = value;
|
|
1702
|
+
else if (field === "data") data.push(value);
|
|
1703
|
+
}
|
|
1704
|
+
return data.length > 0 ? { type, data: data.join("\n") } : void 0;
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
// libs/testing/src/transport/streamable-http.transport.ts
|
|
1708
|
+
var DEFAULT_TIMEOUT2 = 3e4;
|
|
1261
1709
|
var NOTIFICATION_STREAM_REOPEN_DELAY_MS = 250;
|
|
1262
1710
|
var StreamableHttpTransport = class {
|
|
1263
1711
|
config;
|
|
@@ -1279,7 +1727,7 @@ var StreamableHttpTransport = class {
|
|
|
1279
1727
|
baseUrl: config.baseUrl.replace(/\/$/, ""),
|
|
1280
1728
|
// Remove trailing slash
|
|
1281
1729
|
entryPath: config.entryPath,
|
|
1282
|
-
timeout: config.timeout ??
|
|
1730
|
+
timeout: config.timeout ?? DEFAULT_TIMEOUT2,
|
|
1283
1731
|
auth: config.auth ?? {},
|
|
1284
1732
|
publicMode: config.publicMode ?? false,
|
|
1285
1733
|
debug: config.debug ?? false,
|
|
@@ -1619,7 +2067,7 @@ var StreamableHttpTransport = class {
|
|
|
1619
2067
|
let buffer = "";
|
|
1620
2068
|
try {
|
|
1621
2069
|
for (let chunk = await reader.read(); !chunk.done; chunk = await reader.read()) {
|
|
1622
|
-
const { completeEvents, remainder } =
|
|
2070
|
+
const { completeEvents, remainder } = splitSSEEvents2(buffer + decoder.decode(chunk.value, { stream: true }));
|
|
1623
2071
|
buffer = remainder;
|
|
1624
2072
|
for (const eventText of completeEvents) {
|
|
1625
2073
|
for (const event of this.parseSSEEvents(eventText, void 0).events) {
|
|
@@ -1953,7 +2401,7 @@ var StreamableHttpTransport = class {
|
|
|
1953
2401
|
};
|
|
1954
2402
|
}
|
|
1955
2403
|
};
|
|
1956
|
-
function
|
|
2404
|
+
function splitSSEEvents2(buffer) {
|
|
1957
2405
|
const endsWithCarriageReturn = buffer.endsWith("\r");
|
|
1958
2406
|
const normalized = (endsWithCarriageReturn ? buffer.slice(0, -1) : buffer).replace(/\r\n?/g, "\n");
|
|
1959
2407
|
const completeEvents = normalized.split("\n\n");
|
|
@@ -2191,7 +2639,7 @@ var McpTestClientBuilder = class {
|
|
|
2191
2639
|
};
|
|
2192
2640
|
|
|
2193
2641
|
// libs/testing/src/client/mcp-test-client.ts
|
|
2194
|
-
var
|
|
2642
|
+
var DEFAULT_TIMEOUT3 = 3e4;
|
|
2195
2643
|
var DEFAULT_PROTOCOL_VERSION = "2025-06-18";
|
|
2196
2644
|
var UNSUPPORTED_PROTOCOL_VERSIONS = ["2026-07-28"];
|
|
2197
2645
|
var DEFAULT_CLIENT_INFO = {
|
|
@@ -2261,7 +2709,7 @@ var McpTestClient = class {
|
|
|
2261
2709
|
transport: config.transport ?? "streamable-http",
|
|
2262
2710
|
auth: config.auth ?? {},
|
|
2263
2711
|
publicMode: config.publicMode ?? false,
|
|
2264
|
-
timeout: config.timeout ??
|
|
2712
|
+
timeout: config.timeout ?? DEFAULT_TIMEOUT3,
|
|
2265
2713
|
debug: config.debug ?? false,
|
|
2266
2714
|
protocolVersion: config.protocolVersion ?? DEFAULT_PROTOCOL_VERSION,
|
|
2267
2715
|
clientInfo: config.clientInfo ?? DEFAULT_CLIENT_INFO,
|
|
@@ -3027,7 +3475,18 @@ var McpTestClient = class {
|
|
|
3027
3475
|
notificationHandler: this.recordNotification
|
|
3028
3476
|
});
|
|
3029
3477
|
case "sse":
|
|
3030
|
-
|
|
3478
|
+
return new SseTransport({
|
|
3479
|
+
baseUrl,
|
|
3480
|
+
entryPath: this.config.entryPath,
|
|
3481
|
+
timeout: this.config.timeout,
|
|
3482
|
+
auth: this.config.auth,
|
|
3483
|
+
publicMode: this.config.publicMode,
|
|
3484
|
+
debug: this.config.debug,
|
|
3485
|
+
interceptors: this._interceptors,
|
|
3486
|
+
clientInfo: this.config.clientInfo,
|
|
3487
|
+
elicitationHandler: this._elicitationHandler,
|
|
3488
|
+
notificationHandler: this.recordNotification
|
|
3489
|
+
});
|
|
3031
3490
|
default:
|
|
3032
3491
|
throw new Error(`Unknown transport type: ${this.config.transport}`);
|
|
3033
3492
|
}
|
package/esm/perf/perf-setup.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
|
|
2
|
+
const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
|
|
3
|
+
// __frontmcpCreateRequire
|
|
1
4
|
// libs/testing/src/perf/metrics-collector.ts
|
|
2
5
|
function isGcAvailable() {
|
|
3
6
|
return typeof global.gc === "function";
|
package/esm/playwright/index.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
|
|
2
|
+
const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
|
|
3
|
+
// __frontmcpCreateRequire
|
|
1
4
|
// libs/testing/src/playwright/index.ts
|
|
2
5
|
var playwrightIntegration = {
|
|
3
6
|
version: "0.4.0",
|
package/esm/setup.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
|
|
2
|
+
const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
|
|
3
|
+
// __frontmcpCreateRequire
|
|
1
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
5
|
var __esm = (fn, res, err) => function __init() {
|
|
3
6
|
if (err) throw err[0];
|
|
@@ -193,6 +193,11 @@ export interface ServerFixture {
|
|
|
193
193
|
* Test function that receives fixtures
|
|
194
194
|
*/
|
|
195
195
|
export type TestFn = (fixtures: TestFixtures) => Promise<void> | void;
|
|
196
|
+
/**
|
|
197
|
+
* `test.beforeEach` / `test.afterEach`: `fn` receives the test's fixtures when it declares a
|
|
198
|
+
* parameter. Jest's `done` callback style is not supported here; use Jest's own hooks for that.
|
|
199
|
+
*/
|
|
200
|
+
export type FixtureEachHook = (fn: (fixtures: TestFixtures) => unknown, timeout?: number) => void;
|
|
196
201
|
/**
|
|
197
202
|
* Enhanced test function with fixture support
|
|
198
203
|
*/
|
|
@@ -205,13 +210,21 @@ export interface TestWithFixtures {
|
|
|
205
210
|
use(config: TestConfig): void;
|
|
206
211
|
/** Create a describe block */
|
|
207
212
|
describe: typeof describe;
|
|
208
|
-
/** Run before all tests in the file */
|
|
213
|
+
/** Run before all tests in the file (a plain Jest hook: it receives no fixtures) */
|
|
209
214
|
beforeAll: typeof beforeAll;
|
|
210
|
-
/**
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
+
/**
|
|
216
|
+
* Run before each test. A callback that takes a parameter receives the test's fixtures
|
|
217
|
+
* (`test.beforeEach(async ({ mcp }) => …)`) — the same `mcp`, `server` and `auth` the test gets —
|
|
218
|
+
* and runs inside every `test(...)` of the enclosing block, outer blocks first. A callback without
|
|
219
|
+
* parameters is a plain Jest `beforeEach` (`timeout` applies only to that form).
|
|
220
|
+
*/
|
|
221
|
+
beforeEach: FixtureEachHook;
|
|
222
|
+
/**
|
|
223
|
+
* Run after each test, with the same fixtures as `beforeEach` (inner blocks first). Fixtures are
|
|
224
|
+
* torn down after the last `afterEach`. A callback without parameters is a plain Jest `afterEach`.
|
|
225
|
+
*/
|
|
226
|
+
afterEach: FixtureEachHook;
|
|
227
|
+
/** Run after all tests in the file (a plain Jest hook: it receives no fixtures) */
|
|
215
228
|
afterAll: typeof afterAll;
|
|
216
229
|
/** Skip a named test. */
|
|
217
230
|
skip(name: string, fn: TestFn): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixture-types.d.ts","sourceRoot":"","sources":["../../src/fixtures/fixture-types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"fixture-types.d.ts","sourceRoot":"","sources":["../../src/fixtures/fixture-types.ts"],"names":[],"mappings":"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"}
|
package/fixtures/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* @description Barrel exports for test fixtures
|
|
4
4
|
*/
|
|
5
5
|
export { test } from './test-fixture';
|
|
6
|
-
export type { TestConfig, TestFixtures, AuthFixture, ServerFixture, TestFn, TestWithFixtures, TestUser, } from './fixture-types';
|
|
6
|
+
export type { TestConfig, TestFixtures, AuthFixture, ServerFixture, TestFn, FixtureEachHook, TestWithFixtures, TestUser, } from './fixture-types';
|
|
7
7
|
export { createTestFixtures, cleanupTestFixtures, initializeSharedResources, cleanupSharedResources, } from './test-fixture';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
package/fixtures/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,YAAY,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,MAAM,EACN,gBAAgB,EAChB,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,YAAY,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,MAAM,EACN,eAAe,EACf,gBAAgB,EAChB,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC"}
|