@skyramp/mcp 0.1.8 → 0.2.0-rc.1
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/build/playwright/registerPlaywrightTools.js +12 -0
- package/build/playwright/traceRecordingPrompt.js +15 -0
- package/build/prompts/test-recommendation/diffExecutionPlan.js +31 -0
- package/build/prompts/test-recommendation/recommendationSections.js +1 -2
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +94 -0
- package/build/prompts/testbot/testbot-prompts.js +115 -11
- package/build/prompts/testbot/testbot-prompts.test.js +79 -0
- package/build/resources/testbotResource.js +1 -1
- package/build/services/ScenarioGenerationService.integration.test.js +158 -0
- package/build/services/ScenarioGenerationService.js +36 -3
- package/build/services/ScenarioGenerationService.test.js +158 -22
- package/build/tools/generate-tests/generateBatchScenarioRestTool.js +16 -4
- package/build/tools/generate-tests/generateIntegrationRestTool.js +2 -0
- package/build/tools/generate-tests/generateUIRestTool.js +2 -0
- package/build/tools/test-management/analyzeChangesTool.js +7 -1
- package/build/utils/routeParsers.js +12 -0
- package/node_modules/playwright/ThirdPartyNotices.txt +6 -6
- package/node_modules/playwright/lib/dom-analyzer/analyze.js +111 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprint.js +1161 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprint.test.js +396 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprintCache.js +57 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprintCache.test.js +57 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprintDiff.js +250 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprintDiff.test.js +298 -0
- package/node_modules/playwright/lib/dom-analyzer/crawler.js +384 -0
- package/node_modules/playwright/lib/dom-analyzer/curatedWidgets.js +73 -0
- package/node_modules/playwright/lib/dom-analyzer/dynamicId.js +43 -0
- package/node_modules/playwright/lib/dom-analyzer/dynamicId.test.js +85 -0
- package/node_modules/playwright/lib/dom-analyzer/fingerprint.js +90 -0
- package/node_modules/playwright/lib/dom-analyzer/fingerprint.test.js +231 -0
- package/node_modules/playwright/lib/dom-analyzer/fingerprintAblation.fixtures.js +145 -0
- package/node_modules/playwright/lib/dom-analyzer/fingerprintAblation.test.js +41 -0
- package/node_modules/playwright/lib/dom-analyzer/graph.js +36 -0
- package/node_modules/playwright/lib/dom-analyzer/liveFingerprints.js +43 -0
- package/node_modules/playwright/lib/dom-analyzer/logicalNameResolver.js +72 -0
- package/node_modules/playwright/lib/dom-analyzer/logicalNameResolver.test.js +182 -0
- package/node_modules/playwright/lib/dom-analyzer/sectionGrouper.js +169 -0
- package/node_modules/playwright/lib/dom-analyzer/sectionGrouper.test.js +269 -0
- package/node_modules/playwright/lib/dom-analyzer/serialization.js +75 -0
- package/node_modules/playwright/lib/dom-analyzer/slug.js +30 -0
- package/node_modules/playwright/lib/dom-analyzer/slug.test.js +84 -0
- package/node_modules/playwright/lib/dom-analyzer/widgetContract.js +127 -0
- package/node_modules/playwright/lib/dom-analyzer/widgetContract.test.js +212 -0
- package/node_modules/playwright/lib/mcp/browser/browserContextFactory.js +3 -1
- package/node_modules/playwright/lib/mcp/browser/config.js +1 -1
- package/node_modules/playwright/lib/mcp/browser/context.js +17 -1
- package/node_modules/playwright/lib/mcp/browser/tab.js +38 -0
- package/node_modules/playwright/lib/mcp/browser/tools/domAnalyzer.js +261 -0
- package/node_modules/playwright/lib/mcp/browser/tools/keyboard.js +3 -3
- package/node_modules/playwright/lib/mcp/browser/tools/pageBlueprint.js +129 -0
- package/node_modules/playwright/lib/mcp/browser/tools/pageBlueprint.test.js +137 -0
- package/node_modules/playwright/lib/mcp/browser/tools/sitemap.js +226 -0
- package/node_modules/playwright/lib/mcp/browser/tools/snapshot.js +2 -2
- package/node_modules/playwright/lib/mcp/browser/tools/widgetContract.js +168 -0
- package/node_modules/playwright/lib/mcp/browser/tools.js +6 -0
- package/node_modules/playwright/lib/mcp/skyramp/traceRecordingBackend.js +52 -12
- package/node_modules/playwright/lib/mcp/test/skyRampExport.js +64 -13
- package/node_modules/playwright/package.json +1 -1
- package/node_modules/playwright/skyramp-playwright-1.58.2-skyramp.8.9.3.tgz +0 -0
- package/package.json +2 -2
|
@@ -66,6 +66,16 @@ function jsonlHeader(browserName, harPath) {
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
function extractLocatorFromCode(code) {
|
|
69
|
+
const extensionFrameMatch = code.match(
|
|
70
|
+
/await\s+page\.frames\(\)\.find\(\s*f\s*=>\s*f\.url\(\)\.includes\(\s*(['"])([^'"]+)\1\s*\)\s*\)!?\.(.*?)\.(click|dblclick|fill|pressSequentially|check|uncheck|selectOption|hover|dragTo)\s*\(/s
|
|
71
|
+
);
|
|
72
|
+
if (extensionFrameMatch) {
|
|
73
|
+
return {
|
|
74
|
+
locatorExpr: extensionFrameMatch[3].trim(),
|
|
75
|
+
framePath: [],
|
|
76
|
+
frameUrlMatch: extensionFrameMatch[2]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
69
79
|
const contentFrameMatch = code.match(/await\s+page\.locator\((['"])(iframe[^\n]*?)\1\)(?:\.contentFrame\(\))+\.(.*?)\.(click|dblclick|fill|pressSequentially|check|uncheck|selectOption|hover|dragTo)\s*\(/s);
|
|
70
80
|
if (contentFrameMatch) {
|
|
71
81
|
return { locatorExpr: contentFrameMatch[3].trim(), framePath: [contentFrameMatch[2]] };
|
|
@@ -206,10 +216,13 @@ function trackedActionToJsonl(action, pageGuid, timestamp) {
|
|
|
206
216
|
if (toolName === "browser_wait_for") {
|
|
207
217
|
const text = args.text;
|
|
208
218
|
const textGone = args.textGone;
|
|
219
|
+
const time = args.time;
|
|
209
220
|
if (text)
|
|
210
221
|
return JSON.stringify({ name: "waitForSelector", selector: `text=${text}`, ...base });
|
|
211
222
|
if (textGone)
|
|
212
223
|
return JSON.stringify({ name: "waitForSelector", selector: `text=${textGone}`, state: "hidden", ...base });
|
|
224
|
+
if (typeof time === "number")
|
|
225
|
+
return JSON.stringify({ name: "waitForTimeout", duration: time * 1e3, ...base });
|
|
213
226
|
return null;
|
|
214
227
|
}
|
|
215
228
|
if (toolName === "browser_press_key")
|
|
@@ -219,9 +232,11 @@ function trackedActionToJsonl(action, pageGuid, timestamp) {
|
|
|
219
232
|
const extracted = extractLocatorFromCode(code);
|
|
220
233
|
if (!extracted)
|
|
221
234
|
return null;
|
|
222
|
-
const { locatorExpr, framePath: codeFramePath } = extracted;
|
|
235
|
+
const { locatorExpr, framePath: codeFramePath, frameUrlMatch } = extracted;
|
|
223
236
|
if (codeFramePath.length > 0)
|
|
224
237
|
base.framePath = codeFramePath;
|
|
238
|
+
if (frameUrlMatch)
|
|
239
|
+
base.frameUrlMatch = frameUrlMatch;
|
|
225
240
|
const parsed = locatorToJsonl(locatorExpr);
|
|
226
241
|
if (!parsed)
|
|
227
242
|
return null;
|
|
@@ -373,18 +388,51 @@ function removeRedundantClicks(actions) {
|
|
|
373
388
|
});
|
|
374
389
|
}
|
|
375
390
|
function deduplicateRetries(actions) {
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
391
|
+
const result = [];
|
|
392
|
+
let lastNavIdx = -1;
|
|
393
|
+
for (const action of actions) {
|
|
394
|
+
if (action.toolName !== "browser_navigate") {
|
|
395
|
+
result.push(action);
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
const url = action.args.url;
|
|
399
|
+
if (lastNavIdx >= 0 && result[lastNavIdx].args.url === url) {
|
|
400
|
+
result.length = lastNavIdx;
|
|
401
|
+
lastNavIdx = -1;
|
|
402
|
+
for (let k = result.length - 1; k >= 0; k--) {
|
|
403
|
+
if (result[k].toolName === "browser_navigate") {
|
|
404
|
+
lastNavIdx = k;
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
result.push(action);
|
|
410
|
+
lastNavIdx = result.length - 1;
|
|
411
|
+
}
|
|
412
|
+
return result;
|
|
413
|
+
}
|
|
414
|
+
function normalizePrimaryPageAlias(actions) {
|
|
415
|
+
const DEFAULT = DEFAULT_PAGE_ALIAS;
|
|
416
|
+
const counts = /* @__PURE__ */ new Map();
|
|
417
|
+
for (const a of actions) {
|
|
418
|
+
const alias = a.pageAlias ?? DEFAULT;
|
|
419
|
+
counts.set(alias, (counts.get(alias) ?? 0) + 1);
|
|
420
|
+
}
|
|
421
|
+
if ((counts.get(DEFAULT) ?? 0) > 0)
|
|
422
|
+
return;
|
|
423
|
+
const candidates = [...counts.keys()].filter((a) => /^page\d+$/.test(a));
|
|
424
|
+
if (candidates.length !== 1)
|
|
425
|
+
return;
|
|
426
|
+
const from = candidates[0];
|
|
427
|
+
for (const a of actions) {
|
|
428
|
+
if (a.pageAlias === from)
|
|
429
|
+
a.pageAlias = DEFAULT;
|
|
430
|
+
if (a.popupAlias === from)
|
|
431
|
+
a.popupAlias = DEFAULT;
|
|
384
432
|
}
|
|
385
|
-
return lastRestartIdx > 0 ? actions.slice(lastRestartIdx) : actions;
|
|
386
433
|
}
|
|
387
434
|
function buildJsonlContent(actions, browserName, harPath) {
|
|
435
|
+
normalizePrimaryPageAlias(actions);
|
|
388
436
|
const deduplicated = removeRedundantClicks(deduplicateRetries(actions));
|
|
389
437
|
const startTime = deduplicated[0]?.timestamp ?? Date.now();
|
|
390
438
|
const pageGuids = /* @__PURE__ */ new Map();
|
|
@@ -416,7 +464,9 @@ function buildJsonlContent(actions, browserName, harPath) {
|
|
|
416
464
|
const obj = JSON.parse(lines[i]);
|
|
417
465
|
if (obj.name === "openPage" || obj.name === "closePage")
|
|
418
466
|
continue;
|
|
419
|
-
if (!obj.pageAlias
|
|
467
|
+
if (!obj.pageAlias)
|
|
468
|
+
continue;
|
|
469
|
+
if (obj.pageAlias !== alias) {
|
|
420
470
|
obj.signals = [...obj.signals || [], { name: "popup", popupAlias: alias }];
|
|
421
471
|
lines[i] = JSON.stringify(obj);
|
|
422
472
|
break;
|
|
@@ -453,7 +503,7 @@ function buildJsonlContent(actions, browserName, harPath) {
|
|
|
453
503
|
}
|
|
454
504
|
const parsed = extractLocatorFromCode(action.code);
|
|
455
505
|
if (parsed) {
|
|
456
|
-
const { locatorExpr, framePath } = parsed;
|
|
506
|
+
const { locatorExpr, framePath, frameUrlMatch } = parsed;
|
|
457
507
|
const locatorInfo = locatorToJsonl(locatorExpr);
|
|
458
508
|
if (locatorInfo) {
|
|
459
509
|
const { selector, locator: locatorObj } = locatorInfo;
|
|
@@ -466,7 +516,8 @@ function buildJsonlContent(actions, browserName, harPath) {
|
|
|
466
516
|
timestamp: String(action.timestamp + 100),
|
|
467
517
|
pageGuid,
|
|
468
518
|
pageAlias: alias,
|
|
469
|
-
framePath
|
|
519
|
+
framePath,
|
|
520
|
+
...frameUrlMatch ? { frameUrlMatch } : {}
|
|
470
521
|
});
|
|
471
522
|
lines.push(pressLine);
|
|
472
523
|
actionCount++;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skyramp/mcp",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.0-rc.1",
|
|
4
4
|
"main": "build/index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./build/index.js",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"dockerode": "^5.0.0",
|
|
60
60
|
"fast-glob": "^3.3.3",
|
|
61
61
|
"js-yaml": "^4.1.1",
|
|
62
|
-
"playwright": "file:vendor/skyramp-playwright-1.58.2-skyramp.8.9.
|
|
62
|
+
"playwright": "file:vendor/skyramp-playwright-1.58.2-skyramp.8.9.4.tgz",
|
|
63
63
|
"simple-git": "^3.30.0",
|
|
64
64
|
"zod": "^3.25.3"
|
|
65
65
|
},
|