使用Cypress.js测试D3.js拖动事件

7y4bm7vi  于 2022-11-12  发布在  其他
关注(0)|答案(4)|浏览(217)

我有一个SVG对象,它使用d3-zoom来实现缩放和平移功能。它工作得很完美,但是当我开始使用Cypress.js进行集成测试时,问题就出现了。
我尝试在svg元素上使用标准鼠标事件来模拟拖动行为:

cy.get('svg')
  .trigger('mousedown', { which: 1, force: true })
  .trigger('mousemove', { position: 'left' })
  .trigger('mouseup', { position: 'left', force: true });

上面的示例取自Cypress drag and drop recipe,它会在nodrag.js文件中产生以下错误:
无法读取未定义的属性文档
下面您可以看到错误发生的位置(viewundefined):

__webpack_exports__["default"] = (function(view) {
  var root = view.document.documentElement,
  ...

我花了很多时间尝试以另一种方式触发事件,但是没有成功--比如用svg容器尝试上面的代码片段。
请记住,我无法从Cypress测试中访问任何d3.js包,因为它是作为一个NPM包导入到React应用程序中的。
提前感谢您的帮助!

4ngedf3f

4ngedf3f1#

在我不得不继续前进之前,我只能得出一个部分的答案,但也许这可以帮助你,或者其他人,找到最终的解决方案。
要纠正这个错误,必须为mousedown提供一个view属性。这样提供window,可以使D3方法正确触发:

cy.get('svg')
  .trigger('mousedown', { which: 1, force: true, view: window }) // <-- here
  .trigger('mousemove', { position: 'left', view: window })      // <-- here
  .trigger('mouseup', { position: 'left', force: true });

然而,在测试运行期间没有发生拖动或移动,并且由此产生了其他问题。首先...这是与事件沿着发送的正确上下文吗?看起来是这样的,因为window似乎是具有D3预期的属性链的唯一上下文:

view.document.documentElement

或者是反模式的...代码的味道?
分析这些后续问题后,我们发现了一些似乎有意义的观察结果。
第一个问题是D3如何处理鼠标和拖动事件,D3有许多事件监听器和回调函数,它们覆盖了标准事件及其各自的处理程序。
第二,是iframes正在与Cypress测试运行程序一起运行。
是否Cypress的编程触发事件在Cypress iframe中正确触发,但由于D3的激进事件处理,这些事件到应用iframe的转换丢失了?特别是考虑到在测试视口中手动拖动一个圆工作正常。
这又导致了:

  • 是否未在正确的上下文中调用以编程方式触发的事件?
  • 这些事件是否以某种方式被D3的事件处理程序吞噬或冲突?

我选择了Zoomable Force Directed Graph作为我的D3主题,在一个简单的Ember应用程序中,研究这个问题。它完美地再现了提到的错误,所以它肯定是一个D3 + Cypress挑战,与前端框架无关。
我希望这种努力是有帮助的。
继续...
在进一步阅读了Cypress的权衡之后,特别是他们的开放拉取请求对本机浏览器事件的支持之后,似乎D3中的事件处理覆盖在Cypress中还没有完全协调。更简单的实现(如drag and drop example中详细介绍的实现)不会带来第三方库(如D3)引入的事件处理挑战。但是,Cypress团队似乎正在开发这种支持。

qhhrdooz

qhhrdooz2#

试试看:

cy.window().then(win => {
  cy.get('svg')
    .trigger('mousedown', {
      which: 1,
      force: true,
      view: win,
    })
    .trigger('mousemove', {
      clientX: 300,
      clientY: 500,
      force: true,
    })
    .trigger('mouseup', {
      force: true,
      view: win,
    });
});

参考Jennifer Shehane在这个GitHub问题中的回答,cannot read property document of undefined部分的答案是将窗口对象插入到触发器选项中的view中。jacefarm的回答中提到的问题,即没有发生移动,似乎可以通过指定clientX/clientY而不是使用相对于所选元素的位置来解决。

zmeyuzjn

zmeyuzjn3#

我使用的代码与您的代码稍有不同,因此您可以尝试

cy.get('svg')
.trigger('mousedown', { which: 1 })
.trigger('dragstart', {})
.trigger('drag', {});
piah890a

piah890a4#

FWIW我遇到了同样的问题,使用这个库可以与D3元素交互:https://github.com/dmtrKovalenko/cypress-real-events

相关问题