Cypress: cy.click() has inconsistent behavior with Angular CDK overlay

Created on 26 Aug 2018  路  12Comments  路  Source: cypress-io/cypress

Current behavior:

I'm hitting a weird issue where .click() fails because it "is being covered by another element". I can fix the issue using .wait() but I'm not sure why this is the case.

This issue with .click() is producing inconsistent results when I re-run the same test suite.

screen shot 2018-08-25 at 6 14 22 pm

Desired behavior:

The .click() should consistently click the button and hide the overlay as it occasionally does when running the test.

Steps to reproduce:

You can reproduce this error by cloning this application I've setup.

  1. npm install to install project dependencies
  2. ng serve to run the application
  3. Run Cypress tests

Versions

Cypress: 3.1.0
Mac: 10.11.6
Chrome: 68.0.3440.106

actionability question

Most helpful comment

Really relevant post for what @Bkucera is explaining here: https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/

All 12 comments

It may not properly waiting for the dropdown to animate in - as it looks like it's clicking on the 'friday' column - which is directly above it.

I wonder if updating the animationDistanceTreshold would help? https://on.cypress.io/configuration#Animations

Thanks for the quick response!

I've tried updating animationDistanceTreshold to a few different values without any luck.

For what it's worth, the element that covers the button isn't consistent. Sometimes it's the day of the week row as you mentioned, other times it's other days within the calendar.

screen shot 2018-08-27 at 5 08 39 pm

Oh, I see now what you are doing. You are clicking on the button to close the popup and then attempting to click the input behind it. Yeah - this actually would not be affected by the animation threshold, since it checks if the thing you are trying to click on is currently animating (which the input behind it is not).

This is trickier. I wonder if calling cy.get('input[name=endTime]').focus() would work since I believe we recently removed it attempting to click on focus. Am I right @Bkucera

What I would likely to though is just add another guard before going to ensure the popup is closed before clicking the input. Something like:

cy.get('button').click() // Clicking "Set" on datepicker
cy.get('popup-datepicker').should('not.be.visible') // assert the popup closes
cy.get('input[name=endTime]').click() // Cypress will not find the element until assertion above passes

I've tried both of your suggestions, .focus() and a check for .should('not.be.visible'), and the issue still remains.

The assertions for the popup to not be visible fails because the .click() on the "Set" button never registers with the popup still in place.

I added an additional assertion to the button before clicking, .should('have.text', 'Set').click(), with no luck.

I am trying .click({force: true}).clear().type('12/01/2018').should('have.value', '12/01/2018') thats first click then clear and then type the date.

@sampadrout Were you able to successfully run that with the provided repo? There's no way for them to type. The issue is the click event on the "Set" button.

May be related to this issue: https://github.com/cypress-io/cypress/issues/210 If you can, update Cypress when this is released and see if it's resolved.

Hey @atom-morgan were you able to update Cypress? Has this issue been resolved for you?

Hey @jennifer-shehane, I just tested again (3.1.5) with the repo I linked above and I'm hitting the same error.

screen shot 2019-02-20 at 8 29 42 am

Just a heads up: I'm going to be out of the country on vacation until early March beginning tomorrow so if I'm a bit slow to reply that's why.

@atom-morgan

I looked further into this. So we want to click the Set button which will collapse the modal. Using your reproducible I did the following:

  • overrode HTMLElement.prototypeadd.addEventListener to intercept when the click handler is added to the set button
  • as soon as handler is added, start calling this.click() (on the dom element) in a requestAnimationFrame loop, until the modal successfully closes

my findings were that requestAnimationFrame was called nearly 30 times before the handler went from basically a no-op to successfully closing the modal, which took ~700ms from the point of being added as an event handler. Sure, my added code could have slowed the app down, but that's pretty slow.

There's no way for cypress to know how long to wait before clicking the button will actually work.

One thing you could try to click the button again and again _until_ some assertion on the button passes, like not.exist

Here's the code for that, in support/click-until/index.js put:

Cypress.Commands.add('clickUntil',{prevSubject: 'element'} , (subject, ...chainers)=>{
  Cypress.log({
    name: "Click-Until",
    })
    // only click every 5 assertions (no one can click that fast)
    const retryInterval = 5
  let failNum = 0
  cy.wrap(null, {log:false}).should(()=>{
      return cy.now('should', subject, ...chainers)
      .catch((e) => {
      !(failNum%retryInterval) && cy.now('click', subject)
      failNum++
      throw e
    })
  })
})

optional for type completions, in support/click-until/index.d.ts:

/// <reference types="cypress" />

namespace Cypress {

    interface Chainable {
            /**
             * Clicks until the assertion passes.
             */
            clickUntil: Chainer<Subject>
    }
}

then in your spec file:

require('../support/click-until')

it('should display a success message for a valid event', () => {
    cy
      .get('input[formControlName=startTime]').click()
        .get('.owl-dt-calendar-cell-today').click()
        .get('.owl-dt-container-buttons button').last().clickUntil('not.exist')

Really relevant post for what @Bkucera is explaining here: https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/

Closing as resolved. Please comment if you are still having this issue and we will consider reopening.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

scottcrowe picture scottcrowe  路  3Comments

weskor picture weskor  路  3Comments

Francismb picture Francismb  路  3Comments

rbung picture rbung  路  3Comments

tahayk picture tahayk  路  3Comments