feat(browser): 增加跨 page orchestration 能力

新增显式跨页 orchestration block,支持开页、切页、关页后执行单页逻辑。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
walker1211andClaude Opus 4.7 committed 2026-04-20 21:03:33 +08:00
1 parent 3c791a467f
commit 1833ed3ad6
2 files changed
+302

No files matched your search

+44
View File
@@ -2638,6 +2638,15 @@ const SUPPORTED_ORCHESTRATION_BLOCK_TYPES = new Set([
'run_replay_sequence',
'assert_query',
'sequence',
'open_page_then_run',
'select_page_then_run',
'close_page_then_continue',
]);
const CROSS_PAGE_BLOCK_TYPES = new Set([
'open_page_then_run',
'select_page_then_run',
'close_page_then_continue',
]);
const SUPPORTED_ASSERTION_OPERATORS = new Set(['equals', 'contains', 'gt', 'gte', 'lt', 'lte']);
@@ -2805,6 +2814,16 @@ function validateSequenceStep(step) {
}
}
function requireCrossPageRunBlock(block) {
if (!block.args || typeof block.args !== 'object' || !block.args.run || typeof block.args.run !== 'object') {
throw new Error('cross-page run block is required');
}
if (CROSS_PAGE_BLOCK_TYPES.has(block.args.run.type)) {
throw new Error('nested cross-page blocks are not supported');
}
return block.args.run;
}
function normalizeRecordedEvent(pageId, event) {
if (!event || typeof event !== 'object') {
return null;
@@ -5208,6 +5227,31 @@ async function handleCancelReplay() {
}
async function executeOrchestrationBlock(session, block) {
if (block.type === 'select_page_then_run') {
const selectResult = await handleSelectPage(block.args.select || {});
const match = /pageId: (.+)/.exec(selectResult);
const selectedPageId = match?.[1]?.trim() || session.pageId;
const runBlock = requireCrossPageRunBlock(block);
const childSession = { ...session, pageId: selectedPageId };
await executeOrchestrationBlock(childSession, runBlock);
return;
}
if (block.type === 'open_page_then_run') {
const openResult = await handleOpenPage(block.args.open || {});
const match = /pageId: (.+)/.exec(openResult);
const openedPageId = match?.[1]?.trim() || session.pageId;
const runBlock = requireCrossPageRunBlock(block);
const childSession = { ...session, pageId: openedPageId };
await executeOrchestrationBlock(childSession, runBlock);
return;
}
if (block.type === 'close_page_then_continue') {
await handleClosePage(block.args.close || {});
return;
}
if (block.type === 'wait_for_then_click') {
await handleWaitFor({ pageId: session.pageId, ...block.args.wait });
await handleClick({ pageId: session.pageId, ...block.args.click });