WebdriverIO V6 dragAndDrop方法失效求助:Vue.Draggable场景解决方案
解决Vue.Draggable双列表场景下WebdriverIO拖拽失效的问题
我完全懂你遇到的这个痛点——用WebdriverIO自带的dragAndDrop或者performActions操作Vue.Draggable的双列表时,经常会出现拖拽没反应的情况,尤其是这个「Two Lists」场景。主要原因是Vue.Draggable基于SortableJS实现,它的拖拽逻辑依赖自定义的事件监听,原生的拖拽方法往往触发不了组件内部的完整流程。给你分享两个亲测有效的解决方案:
方案一:模拟完整的鼠标拖拽流程(贴近真实用户操作)
这个方法通过手动模拟鼠标按下、移动、释放的全流程,精准触发组件需要的每一个事件,和真实用户操作几乎一致,兼容性最好。
it('should drag item from left to right list in Vue.Draggable', async () => { await browser.url('https://sortablejs.github.io/Vue.Draggable/#/two-lists'); // 定位拖拽元素和目标列表 const dragItem = await $('#two-lists .row div:nth-child(1) .list-group-item:nth-child(1)'); const targetList = await $('#two-lists .row div:nth-child(2) .list-group'); // 计算目标列表的中心坐标作为拖拽终点 const targetPos = await targetList.getLocation(); const targetSize = await targetList.getSize(); const endX = targetPos.x + targetSize.width / 2; const endY = targetPos.y + targetSize.height / 2; // 执行完整的鼠标拖拽动作链 await browser.performActions([{ type: 'pointer', id: 'mouse1', parameters: { pointerType: 'mouse' }, actions: [ // 定位到拖拽元素并按下左键 { type: 'pointerMove', duration: 0, origin: dragItem, x: 0, y: 0 }, { type: 'pointerDown', button: 0 }, // 轻微移动触发拖拽启动(部分组件需要这一步触发拖拽状态) { type: 'pointerMove', duration: 100, origin: dragItem, x: 10, y: 10 }, // 拖拽到目标列表中心 { type: 'pointerMove', duration: 500, x: endX, y: endY, origin: 'viewport' }, // 松开左键完成拖拽 { type: 'pointerUp', button: 0 } ] }]); // 等待组件完成渲染和状态更新 await browser.pause(1000); // 可选:验证拖拽是否成功 const firstTargetItem = await $('#two-lists .row div:nth-child(2) .list-group-item:nth-child(1)'); expect(await firstTargetItem.getText()).toBe(await dragItem.getText()); });
注意点:
- 调整
duration参数可以模拟不同的拖拽速度,太快手可能触发不了组件的事件; - 坐标计算时要注意
origin的取值,确保是基于视口还是元素本身; - 如果拖拽后组件没有即时更新,可以增加
pause时间或者用waitUntil等待元素状态变化。
方案二:直接调用SortableJS的内部API(无UI操作,更稳定)
如果不需要模拟真实用户的UI操作,直接调用组件内部的SortableJS实例方法会更高效稳定。Vue.Draggable会把Sortable实例挂载到列表元素的__vue_sortable__属性上,我们可以直接操作它:
it('should drag item using SortableJS internal API', async () => { await browser.url('https://sortablejs.github.io/Vue.Draggable/#/two-lists'); // 执行浏览器端JS,直接操作Sortable实例 await browser.execute(() => { // 获取左右列表的Sortable实例 const leftList = document.querySelector('#two-lists .row div:nth-child(1) .list-group'); const rightList = document.querySelector('#two-lists .row div:nth-child(2) .list-group'); const leftSortable = leftList.__vue_sortable__; const rightSortable = rightList.__vue_sortable__; // 定位要拖拽的项并获取其索引 const itemToDrag = leftList.querySelector('.list-group-item:nth-child(1)'); const itemIndex = Array.from(leftList.children).indexOf(itemToDrag); // 调用Sortable的move方法,将项从左侧移到右侧末尾 leftSortable.move(itemIndex, rightList.children.length, rightSortable); }); await browser.pause(1000); // 验证拖拽结果 const lastTargetItem = await $('#two-lists .row div:nth-child(2) .list-group-item:last-child'); expect(await lastTargetItem.getText()).toBe('Item 1'); });
注意点:
- 这个方法依赖组件内部的
__vue_sortable__属性,如果Vue.Draggable版本更新可能会有变化,需要测试确认; - 适合只关心最终状态、不需要模拟用户UI交互的测试场景。
内容的提问来源于stack exchange,提问作者Ashok
相关产品推荐
相关产品推荐

