【发布时间】:2019-08-17 02:14:13
【问题描述】:
我正在努力使用Cypress 和Angular Material Drag and Drop 测试拖放。因此,目标是将“开始工作”从待办事项转移到完成。 我创建了以下测试,应该可以让您轻松重现:
你可以玩 Stackblitz here。
describe('Trying to implement drag-n-drop', () => {
before(() => {
Cypress.config('baseUrl', null);
cy.viewport(1000, 600);
cy.visit('https://angular-oxkc7l-zirwfs.stackblitz.io')
.url().should('contain', 'angular')
.get('h2').should('contain', 'To do');
});
it('Should work, based on this https://stackoverflow.com/a/54119137/3694288', () => {
const dataTransfer = new DataTransfer;
cy.get('#cdk-drop-list-0 > :nth-child(1)')
.trigger('dragstart', { dataTransfer });
cy.get('#cdk-drop-list-1')
.trigger('drop', { dataTransfer });
cy.get('#cdk-drop-list-0 > :nth-child(1)')
.trigger('dragend');
cy.get('#cdk-drop-list-1').should('contain', 'Get to work');
});
it('Should work, with this library https://github.com/4teamwork/cypress-drag-drop', () => {
cy.get('#cdk-drop-list-0 > :nth-child(1)')
.drag('#cdk-drop-list-1');
cy.get('#cdk-drop-list-1').should('contain', 'Get to work');
});
});
运行上述测试的结果如下:
这里是a repo 来开发解决方案。
感谢您的帮助。
事件触发,使用 chrome 调试器找到:
物品
- 指针悬停
- 指针输入
- 鼠标悬停
- 鼠标按下
- 指针移动
- 鼠标移动
- 指针
- 指针离开
- 鼠标移出
- 鼠标离开
拖放区
- 指针悬停
- 指针输入
- 鼠标悬停
- 指针移动
- 鼠标移动
- 指针离开
- 鼠标移出
- 鼠标离开
解决方案
在@Richard Matsen 的精彩回答之后,我最终添加了his answer 作为自定义命令。解决方案是这样的
support/drag-support.ts
export function drag(dragSelector: string, dropSelector: string) {
// Based on this answer: https://stackoverflow.com/a/55436989/3694288
cy.get(dragSelector).should('exist')
.get(dropSelector).should('exist');
const draggable = Cypress.$(dragSelector)[0]; // Pick up this
const droppable = Cypress.$(dropSelector)[0]; // Drop over this
const coords = droppable.getBoundingClientRect();
draggable.dispatchEvent(<any>new MouseEvent('mousedown'));
draggable.dispatchEvent(<any>new MouseEvent('mousemove', {clientX: 10, clientY: 0}));
draggable.dispatchEvent(<any>new MouseEvent('mousemove', {
// I had to add (as any here --> maybe this can help solve the issue??)
clientX: coords.left + 10,
clientY: coords.top + 10 // A few extra pixels to get the ordering right
}));
draggable.dispatchEvent(new MouseEvent('mouseup'));
return cy.get(dropSelector);
}
support/commands.ts
// Add typings for the custom command
declare global {
namespace Cypress {
interface Chainable {
drag: (dragSelector: string, dropSelector: string) => Chainable;
}
}
}
// Finally add the custom command
Cypress.Commands.add('drag', drag);
在规范文件中
it('???? Thx to Stackoverflow, drag and drop support now works ????', () => {
cy.drag('#cdk-drop-list-0 > :nth-child(1)', '#cdk-drop-list-1')
.should('contain', 'Get to work');
});
一个小的 giph,因为我很高兴它终于可以工作了????
CI
现在它也适用于 CI ???? (和本地电子)。使用 CircleCI 2.0 测试。
【问题讨论】:
-
我还没有测试过,但(可能)
function drag中的cy.get(dragSelector).should('exist')不会防止异步加载,命令只是告诉赛普拉斯“将此测试放入队列并尽快运行” ,然后代码继续下一行(同步,因此立即执行)。您可以使用嵌套的then()s 来防止这种情况发生,或者可能是在同步代码周围使用cy.wrap().then()将其变成排队块。 -
感谢@RichardMatsen 的评论。因为赛普拉斯在大多数情况下“正常工作”,所以我的许多测试中通常只有
.get()。感谢您的输入,我将测试拖动方法的异步性质。我也一直在想drag方法实际上应该只有目标作为输入,源应该在chain中提供:) -
这是否已经用 iframe 中的元素进行了测试?
-
否 - 这不是在 iframe 中完成的。
-
这似乎不再起作用了。您是否熟悉最新 Angular 和 Cdk 拖放的任何必要更改?
标签: angular cypress angular-material2