You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:36:07