Cypress click/trigger 未触发 eventListeners
Cypress click/trigger not triggering eventListeners
在过去的几个月里,我一直在为我的 SO 驱动的 SE 教育的最后阶段开发一个工作流建模器。我一直在使用 mxGraph 和 vanilla javascript,我尝试使用 Cypress 设置一些基本的 E2E 测试。
我在(我假设)触发事件侦听器时遇到了一些问题。有些按钮会响应 cypress clicks/triggers 而有些则不会。 None 我的应用程序中的按钮具有 onClick 操作或包含模型或控制器方法的任何其他属性。相反,所有按钮和键都有处理程序和侦听器,由 mxGraph-editor 实用程序创建 class。
我尝试在 mxGraph 的 public 示例上使用相同的 E2E 测试重新创建一些操作(请参阅赛普拉斯代码)。对象的拖动(从菜单到 canvas (#1) & 从 canvas 到 canvas(#4))和对象的选择(#2)遗憾的是没有工作。
双击对象并修改文本 (#3) 确实有效……但我迷路了。我尝试了所有不同的强制、等待、点击和触发方式,但都无济于事。
describe('mxGraph "ports" example', function () {
it('Start ports example', function () {
cy.visit('https://jgraph.github.io/mxgraph/javascript/examples/ports.html')
cy.wait(500)
})
// Example #1 : FAIL
it('#1 Create new object by dragging', function () {
cy.get('div[id="sidebarContainer"]').find('img[title="Drag this to the diagram to create a new vertex"]').first()
.trigger('mousedown', { force: true})
.trigger('mousemove', { clientX: 250, clientY: 250, force: true})
.trigger('mouseup', {force: true})
cy.get('div[id="graphContainer"]').find('svg').trigger('drop', { force: true })
cy.wait(500)
})
})
describe('mxGraph "user object" example', function () {
it('Start userobject example', function () {
cy.visit('https://jgraph.github.io/mxgraph/javascript/examples/userobject.html')
cy.wait(500)
})
// Example #2 : FAIL
it('#2 Single click on object (green highlight should appear)', function () {
cy.get('rect').first().click({ force: true })
cy.wait(500)
})
// Example #3 : PASS
it('#3 Double click & edit object (Text should be modified)', function () {
cy.get('rect').first().dblclick({ force: true })
cy.wait(500)
cy.get('div [class="mxCellEditor mxPlainTextEditor"]').first().type('text modified')
cy.wait(500)
})
// Example #4 : FAIL
it('#4 Drags object to center of canvas (Object should be moved)', function () {
cy.get('rect').first()
.trigger('mousedown', { force: true})
.trigger('mousemove', { clientX: 250, clientY: 250, force: true})
.trigger('mouseup', {force: true})
cy.wait(500)
})
})
非常感谢任何帮助。提前致谢!
您的应用似乎正在使用指针事件,因此请尝试将所有这些事件名称中的 mouse
替换为 pointer
。
另外,这里有一个关于拖放的更完整的抽象:
const dragTo = (subject, to, opts) => {
opts = Cypress._.defaults(opts, {
// delay inbetween steps
delay: 0,
// interpolation between coords
steps: 0,
// >=10 steps
smooth: false,
})
if (opts.smooth) {
opts.steps = Math.max(opts.steps, 10)
}
const win = subject[0].ownerDocument.defaultView
const elFromCoords = (coords) => win.document.elementFromPoint(coords.x, coords.y)
const winMouseEvent = win.MouseEvent
const send = (type, coords, el) => {
el = el || elFromCoords(coords)
if (type.includes('drag') || type === 'drop') {
return el.dispatchEvent(
new Event(type, Object.assign({}, { clientX: coords.x, clientY: coords.y }, { bubbles: true, cancelable: true }))
)
}
el.dispatchEvent(
new winMouseEvent(type, Object.assign({}, { clientX: coords.x, clientY: coords.y }, { bubbles: true, cancelable: true }))
)
}
const toSel = to
function drag (from, to, steps = 1) {
const fromEl = elFromCoords(from)
const _log = Cypress.log({
$el: fromEl,
name: 'drag to',
message: toSel,
})
_log.snapshot('before', { next: 'after', at: 0 })
_log.set({ coords: to })
send('mouseover', from, fromEl)
send('pointerover', from, fromEl)
send('mousedown', from, fromEl)
send('pointerdown', from, fromEl)
send('dragstart', from, fromEl)
cy.then(() => {
return Cypress.Promise.try(() => {
if (steps > 0) {
const dx = (to.x - from.x) / steps
const dy = (to.y - from.y) / steps
return Cypress.Promise.map(Array(steps).fill(), (v, i) => {
i = steps - 1 - i
let _to = {
x: from.x + dx * (i),
y: from.y + dy * (i),
}
send('mousemove', _to, fromEl)
return Cypress.Promise.delay(opts.delay)
}, { concurrency: 1 })
}
})
.then(() => {
send('mousemove', to, fromEl)
send('pointermove', to, fromEl)
send('drag', to, fromEl)
send('mouseover', to)
send('pointerover', to)
send('dragover', to)
send('mousemove', to)
send('pointermove', to)
send('drag', to)
send('mouseup', to)
send('pointerup', to)
send('dragend', to)
send('drop', to)
_log.snapshot('after', { at: 1 }).end()
})
})
}
const $el = subject
const fromCoords = getCoords($el)
const toCoords = getCoords(cy.$$(to))
drag(fromCoords, toCoords, opts.steps)
}
const getCoords = ($el) => {
const domRect = $el[0].getBoundingClientRect()
const coords = { x: domRect.left + (domRect.width / 2 || 0), y: domRect.top + (domRect.height / 2 || 0) }
return coords
}
Cypress.Commands.addAll(
{ prevSubject: 'element' },
{
dragTo,
}
)
以下是您的使用方法:
describe('mxGraph "ports" example', function () {
beforeEach(() => {
cy.visit('https://jgraph.github.io/mxgraph/javascript/examples/ports.html')
cy.get('div#splash').should('not.be.visible')
})
// Example #1 : FAIL
it('#1 Create new object by dragging', function () {
cy.get('div[id="sidebarContainer"]').find('img[title="Drag this to the diagram to create a new vertex"]').first()
.dragTo('div[id="graphContainer"]')
})
})
在过去的几个月里,我一直在为我的 SO 驱动的 SE 教育的最后阶段开发一个工作流建模器。我一直在使用 mxGraph 和 vanilla javascript,我尝试使用 Cypress 设置一些基本的 E2E 测试。
我在(我假设)触发事件侦听器时遇到了一些问题。有些按钮会响应 cypress clicks/triggers 而有些则不会。 None 我的应用程序中的按钮具有 onClick 操作或包含模型或控制器方法的任何其他属性。相反,所有按钮和键都有处理程序和侦听器,由 mxGraph-editor 实用程序创建 class。
我尝试在 mxGraph 的 public 示例上使用相同的 E2E 测试重新创建一些操作(请参阅赛普拉斯代码)。对象的拖动(从菜单到 canvas (#1) & 从 canvas 到 canvas(#4))和对象的选择(#2)遗憾的是没有工作。
双击对象并修改文本 (#3) 确实有效……但我迷路了。我尝试了所有不同的强制、等待、点击和触发方式,但都无济于事。
describe('mxGraph "ports" example', function () {
it('Start ports example', function () {
cy.visit('https://jgraph.github.io/mxgraph/javascript/examples/ports.html')
cy.wait(500)
})
// Example #1 : FAIL
it('#1 Create new object by dragging', function () {
cy.get('div[id="sidebarContainer"]').find('img[title="Drag this to the diagram to create a new vertex"]').first()
.trigger('mousedown', { force: true})
.trigger('mousemove', { clientX: 250, clientY: 250, force: true})
.trigger('mouseup', {force: true})
cy.get('div[id="graphContainer"]').find('svg').trigger('drop', { force: true })
cy.wait(500)
})
})
describe('mxGraph "user object" example', function () {
it('Start userobject example', function () {
cy.visit('https://jgraph.github.io/mxgraph/javascript/examples/userobject.html')
cy.wait(500)
})
// Example #2 : FAIL
it('#2 Single click on object (green highlight should appear)', function () {
cy.get('rect').first().click({ force: true })
cy.wait(500)
})
// Example #3 : PASS
it('#3 Double click & edit object (Text should be modified)', function () {
cy.get('rect').first().dblclick({ force: true })
cy.wait(500)
cy.get('div [class="mxCellEditor mxPlainTextEditor"]').first().type('text modified')
cy.wait(500)
})
// Example #4 : FAIL
it('#4 Drags object to center of canvas (Object should be moved)', function () {
cy.get('rect').first()
.trigger('mousedown', { force: true})
.trigger('mousemove', { clientX: 250, clientY: 250, force: true})
.trigger('mouseup', {force: true})
cy.wait(500)
})
})
非常感谢任何帮助。提前致谢!
您的应用似乎正在使用指针事件,因此请尝试将所有这些事件名称中的 mouse
替换为 pointer
。
另外,这里有一个关于拖放的更完整的抽象:
const dragTo = (subject, to, opts) => {
opts = Cypress._.defaults(opts, {
// delay inbetween steps
delay: 0,
// interpolation between coords
steps: 0,
// >=10 steps
smooth: false,
})
if (opts.smooth) {
opts.steps = Math.max(opts.steps, 10)
}
const win = subject[0].ownerDocument.defaultView
const elFromCoords = (coords) => win.document.elementFromPoint(coords.x, coords.y)
const winMouseEvent = win.MouseEvent
const send = (type, coords, el) => {
el = el || elFromCoords(coords)
if (type.includes('drag') || type === 'drop') {
return el.dispatchEvent(
new Event(type, Object.assign({}, { clientX: coords.x, clientY: coords.y }, { bubbles: true, cancelable: true }))
)
}
el.dispatchEvent(
new winMouseEvent(type, Object.assign({}, { clientX: coords.x, clientY: coords.y }, { bubbles: true, cancelable: true }))
)
}
const toSel = to
function drag (from, to, steps = 1) {
const fromEl = elFromCoords(from)
const _log = Cypress.log({
$el: fromEl,
name: 'drag to',
message: toSel,
})
_log.snapshot('before', { next: 'after', at: 0 })
_log.set({ coords: to })
send('mouseover', from, fromEl)
send('pointerover', from, fromEl)
send('mousedown', from, fromEl)
send('pointerdown', from, fromEl)
send('dragstart', from, fromEl)
cy.then(() => {
return Cypress.Promise.try(() => {
if (steps > 0) {
const dx = (to.x - from.x) / steps
const dy = (to.y - from.y) / steps
return Cypress.Promise.map(Array(steps).fill(), (v, i) => {
i = steps - 1 - i
let _to = {
x: from.x + dx * (i),
y: from.y + dy * (i),
}
send('mousemove', _to, fromEl)
return Cypress.Promise.delay(opts.delay)
}, { concurrency: 1 })
}
})
.then(() => {
send('mousemove', to, fromEl)
send('pointermove', to, fromEl)
send('drag', to, fromEl)
send('mouseover', to)
send('pointerover', to)
send('dragover', to)
send('mousemove', to)
send('pointermove', to)
send('drag', to)
send('mouseup', to)
send('pointerup', to)
send('dragend', to)
send('drop', to)
_log.snapshot('after', { at: 1 }).end()
})
})
}
const $el = subject
const fromCoords = getCoords($el)
const toCoords = getCoords(cy.$$(to))
drag(fromCoords, toCoords, opts.steps)
}
const getCoords = ($el) => {
const domRect = $el[0].getBoundingClientRect()
const coords = { x: domRect.left + (domRect.width / 2 || 0), y: domRect.top + (domRect.height / 2 || 0) }
return coords
}
Cypress.Commands.addAll(
{ prevSubject: 'element' },
{
dragTo,
}
)
以下是您的使用方法:
describe('mxGraph "ports" example', function () {
beforeEach(() => {
cy.visit('https://jgraph.github.io/mxgraph/javascript/examples/ports.html')
cy.get('div#splash').should('not.be.visible')
})
// Example #1 : FAIL
it('#1 Create new object by dragging', function () {
cy.get('div[id="sidebarContainer"]').find('img[title="Drag this to the diagram to create a new vertex"]').first()
.dragTo('div[id="graphContainer"]')
})
})