drag_by_uid_to_uid
Simulate HTML5 drag-and-drop interactions between web elements using unique identifiers for browser automation and testing.
Instructions
Drag element to another (HTML5 drag events).
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| fromUid | Yes | Source element UID | |
| toUid | Yes | Target element UID |
Implementation Reference
- src/tools/input.ts:219-248 (handler)MCP tool handler: validates input arguments, retrieves Firefox instance, performs drag operation via firefox.dragByUidToUid, handles UID staleness errorsexport async function handleDragByUidToUid(args: unknown): Promise<McpToolResponse> { try { const { fromUid, toUid } = args as { fromUid: string; toUid: string }; if (!fromUid || typeof fromUid !== 'string') { throw new Error('fromUid parameter is required and must be a string'); } if (!toUid || typeof toUid !== 'string') { throw new Error('toUid parameter is required and must be a string'); } const { getFirefox } = await import('../index.js'); const firefox = await getFirefox(); try { await firefox.dragByUidToUid(fromUid, toUid); return successResponse(`✅ drag ${fromUid}→${toUid}`); } catch (error) { // Check both UIDs for staleness const errorMsg = (error as Error).message; if (errorMsg.includes('stale') || errorMsg.includes('Snapshot') || errorMsg.includes('UID')) { throw new Error(`UIDs stale/invalid. Call take_snapshot first.`); } throw error; } } catch (error) { return errorResponse(error as Error); } }
- src/tools/input.ts:81-98 (schema)Tool schema definition including input validation for fromUid and toUid parametersexport const dragByUidToUidTool = { name: 'drag_by_uid_to_uid', description: 'Drag element to another (HTML5 drag events).', inputSchema: { type: 'object', properties: { fromUid: { type: 'string', description: 'Source element UID', }, toUid: { type: 'string', description: 'Target element UID', }, }, required: ['fromUid', 'toUid'], }, };
- src/index.ts:103-147 (registration)Main MCP server registration: maps tool name 'drag_by_uid_to_uid' to its handler functionconst toolHandlers = new Map< string, (input: unknown) => Promise<{ content: Array<{ type: string; text: string }>; isError?: boolean }> >([ // Pages ['list_pages', tools.handleListPages], ['new_page', tools.handleNewPage], ['navigate_page', tools.handleNavigatePage], ['select_page', tools.handleSelectPage], ['close_page', tools.handleClosePage], // Script evaluation - DISABLED (see docs/future-features.md) // ['evaluate_script', tools.handleEvaluateScript], // Console ['list_console_messages', tools.handleListConsoleMessages], ['clear_console_messages', tools.handleClearConsoleMessages], // Network ['list_network_requests', tools.handleListNetworkRequests], ['get_network_request', tools.handleGetNetworkRequest], // Snapshot ['take_snapshot', tools.handleTakeSnapshot], ['resolve_uid_to_selector', tools.handleResolveUidToSelector], ['clear_snapshot', tools.handleClearSnapshot], // Input ['click_by_uid', tools.handleClickByUid], ['hover_by_uid', tools.handleHoverByUid], ['fill_by_uid', tools.handleFillByUid], ['drag_by_uid_to_uid', tools.handleDragByUidToUid], ['fill_form_by_uid', tools.handleFillFormByUid], ['upload_file_by_uid', tools.handleUploadFileByUid], // Screenshot ['screenshot_page', tools.handleScreenshotPage], ['screenshot_by_uid', tools.handleScreenshotByUid], // Utilities ['accept_dialog', tools.handleAcceptDialog], ['dismiss_dialog', tools.handleDismissDialog], ['navigate_history', tools.handleNavigateHistory], ['set_viewport_size', tools.handleSetViewportSize], ]);
- src/index.ts:150-191 (registration)MCP server tool list registration: includes dragByUidToUidTool for listTools endpointconst allTools = [ // Pages tools.listPagesTool, tools.newPageTool, tools.navigatePageTool, tools.selectPageTool, tools.closePageTool, // Script evaluation - DISABLED (see docs/future-features.md) // tools.evaluateScriptTool, // Console tools.listConsoleMessagesTool, tools.clearConsoleMessagesTool, // Network tools.listNetworkRequestsTool, tools.getNetworkRequestTool, // Snapshot tools.takeSnapshotTool, tools.resolveUidToSelectorTool, tools.clearSnapshotTool, // Input tools.clickByUidTool, tools.hoverByUidTool, tools.fillByUidTool, tools.dragByUidToUidTool, tools.fillFormByUidTool, tools.uploadFileByUidTool, // Screenshot tools.screenshotPageTool, tools.screenshotByUidTool, // Utilities tools.acceptDialogTool, tools.dismissDialogTool, tools.navigateHistoryTool, tools.setViewportSizeTool, ];
- src/firefox/dom.ts:189-229 (helper)Core implementation: resolves UIDs to elements, dispatches HTML5 DragEvents (dragstart, dragenter, etc.) via executeScript for drag-and-dropasync dragByUidToUid(fromUid: string, toUid: string): Promise<void> { if (!this.resolveUid) { throw new Error( 'dragByUidToUid: resolveUid callback not set. Ensure snapshot is initialized.' ); } const fromEl = await this.resolveUid(fromUid); const toEl = await this.resolveUid(toUid); // Use JS drag events fallback for compatibility (Actions DnD not used) await this.driver.executeScript( (srcEl: Element, tgtEl: Element) => { if (!srcEl || !tgtEl) { throw new Error('dragAndDrop: element not found'); } function dispatch(type: string, target: Element, dataTransfer?: DataTransfer) { const evt = new DragEvent(type, { bubbles: true, cancelable: true, dataTransfer, } as DragEventInit); return target.dispatchEvent(evt); } // Create DataTransfer if available const dt = typeof DataTransfer !== 'undefined' ? new DataTransfer() : undefined; dispatch('dragstart', srcEl, dt); dispatch('dragenter', tgtEl, dt); dispatch('dragover', tgtEl, dt); dispatch('drop', tgtEl, dt); dispatch('dragend', srcEl, dt); }, fromEl, toEl ); // Wait for events to propagate await this.waitForEventsAfterAction(); }