使用柏树,按下 ctrl 键但在单击事件后未触发 keyup

With cypress, control key pressed but keyup not trigerred after click event

我在 table 中有多个单元格的 selection,而必须按下控制键才能 select 所有单击的单元格:

cy.get("[data-cy=cell-1],[data-cy=cell-5],[data-cy=cell-32]")
  .click({ multiple: true, ctrlKey: true})

效果很好,我看到多个 selection,因为 selected 细胞有不同的背景颜色。我对页面进行了编码,因此当控制键上的 window:keyup 事件发生时,将打开一个对话框以编辑单元格内容。这在 dev 上工作得很好,但是对于 cypress,.click({ multiple: true, ctrlKey: true}) 不会触发我的对话框,如果我之后有一个手动 .type({ctrl}),它会触发对话框但是多个 selection丢失

cy.get("[data-cy=cell-1],[data-cy=cell-5],[data-cy=cell-32]")
  .click({ multiple: true, ctrlKey: true})
cy.get("#my-table-container").type("{ctrl}")

它就像我的第一个 click({multiple: true, ctrlKey: true}) 控制键按下但从未松开。你知道我怎么能使用点击倍数和控制但在最后触发 keyup 吗?

更新:@HostListener 设置 我在 Angular 12,这正是我使用 @HostListener 设置按键事件的方式(我还听转义键以清除单元格 selection):

@HostListener("window:keyup", ["$event"])
handleKeyDown(event: KeyboardEvent) {
    switch(event.key){
      case "Escape": this.clearSelection(); break;
      case "Control":this.openEditDialog(); break;
      }
    }

由于您正在使用 window:keyup 事件,您可以尝试触发该事件,假设它是在 ctrl 键(代码 17)上触发的。

cy.get("[data-cy=cell-1],[data-cy=cell-5],[data-cy=cell-32]")
  .click({ multiple: true, ctrlKey: true})
cy.get("#my-table-container").trigger('keyup', { keyCode: 17 })

另外,keydown/keyup 组合可能效果更好(尝试在 .click() 上使用或不使用 ctrlKey 修饰符)

cy.get('#my-table-container').trigger('keydown', { keyCode: 17 })
cy.get('[data-cy=cell-1]').click({ctrlKey: true})
cy.get('[data-cy=cell-5]').click({ctrlKey: true})
cy.get('[data-cy=cell-32]').click({ctrlKey: true})
cy.get('#my-table-container').trigger('keyup', { keyCode: 17 })

最后,.trigger() 的目标可能需要是 #my-table-container 以外的其他内容,具体取决于调用 addEventListener() 的方式。需要查看更多 HTML 和来源才能确定。


Angular @HostListener

如果你有一个由 @HostListener 装饰器设置的事件监听器,如下所示

@HostListener("window:keyup", ["$event"])
onKeyup(event: KeyboardEvent): void {
  event.preventDefault();
  console.log('keyup', event)
}

当您查看 console.log 时,事件的路径为 属性 path: (4) [body, html, document, Window],这意味着您可以在 <body>.

上触发它

检查一下,以下测试通过

it('triggers keyup set by @HostListener on window', () => {
  let ev;
  cy.visit('http://localhost:4200').then(win => {
    cy.stub(win.console, 'log', (eventName, event) => {
      ev = event
    }).as('consoleLog')
  })

  cy.get('body').trigger('keyup', {keyCode:17})

  cy.get('@consoleLog')
    .should(() => {
      expect(ev.type).to.equal('keyup')
      expect(ev.keyCode).to.equal(17)
    })
})

所以要触发对话框

cy.get("[data-cy=cell-1],[data-cy=cell-5],[data-cy=cell-32]")
  .click({ multiple: true, ctrlKey: true})
cy.get('body')
  .focus()
  .trigger('keyup', { keyCode: 17 })

看来 Cypress 并没有像使用 event.key 而不是 event.keyCode(已弃用)的 HostListener 设置那样做出预期的反应。我在我的组件中修改了 @HostListener 以使用 event.keyCode === 17 并且它有效。