Reputation: 1502
I am automating Google Calculator. And from time to time Cypress is not able to execute click on button. The tests click on buttons (0 to 9 ) and do some simple math operations. And in 30% chance it can not click on element and the test will fail.
I also recorded a video when issue appears.
My Project is located here: https://github.com/afiliptsov/test-project
To run the test run : "npm run test:e2e:functional"
I tried to use different locator. Initially i was using just ID ex(#cwbt15 ) but after i made more specific locator ( #cwbt15 > .cwbtpl > .cwbts) and still having same issue.
Does anyone knows why it happens and how to avoid such behavior?
The project structure is :
Upvotes: 53
Views: 95613
Reputation: 1502
For me this code worked:
Inside your click methods add : { force: true }
It will make force click.
Also add: cy.wait(150)
to beforeEach or before click where your test fails.
It is just workaround not a solution.
Also i saw this alternative:
cy.get('#query-btn').invoke('width').should('be.gt', 0)
cy.get('#query-btn').invoke('width').should('be. greaterThan', 0)
But it didnt work out for me. Maybe will be useful for someone!
Upvotes: 28
Reputation: 441
if nothing of those works for you :
cy.get('#fileUpload').trigger('mousedown').trigger('mouseup');
cy.get('#fileUpload').click({ force: true });
cy.get('#fileUpload').invoke('click');
try using the 'realClick' event from this package
cy.get('#fileUpload').realClick();
this worked for me.
Upvotes: 0
Reputation: 71
In my case one of web element was being disabled for few time and then being enabled.
Due to that .click() and .click({ force: true }) was not helping to perform the click operation.
Tried:
cy.get('daterange').trigger("click"); -It worked. You can try too.
Upvotes: 0
Reputation: 1524
For those who are using cypress version "6.x.x"
and above
You could use { force: true }
like:
cy.get("YOUR_SELECTOR").click({ force: true });
but this might not solve it ! The problem might be more complex, that's why check below
My solution:
cy.get("YOUR_SELECTOR").trigger("click");
Explanation:
In my case, I needed to watch a bit deeper what's going on. I started by pin the click
action like this:
Then watch the console, and you should see something like:
Now click on line Mouse Events
, it should display a table:
So basically, when Cypress executes the click
function, it triggers all those events but somehow my component behave the way that it is detached the moment where click event
is triggered.
So I just simplified the click by doing:
cy.get("YOUR_SELECTOR").trigger("click");
And it worked 🎉
Hope this will fix your issue or at least help you debug and understand what's wrong.
Upvotes: 54
Reputation: 21
I've worked through many of the answers posted above and it was https://stackoverflow.com/a/70932275/19377357 that gave me the first solution that worked. I stripped each section away to see what was necessary and what wasn't.
Apparently, all the page needed (that I was working on) was a second to load:
cy.get('YOUR-SELECTOR').wait(1000).click();
Upvotes: 2
Reputation: 146
I found that my button's event listeners were loaded but the button was not receiving the focus it needed. It was definitely clickable. I tried using the cypress-pipe
package but to no avail. So, instead of invoking .click()
on it 2 or more times, I ensured it was first set in focus prior to being clicked. This fixed it for me.
cy.get('button').focus().click()
Upvotes: 2
Reputation: 2624
In my case I had to make sure the button is visible(or not disabled), then mouseover, then click:
cy.contains(/activate/i)
.should('be.visible')
.trigger('mouseover')
.click({ force: true });
PS. /***/i
means ignore letter case.
Upvotes: 4
Reputation: 11
I don't know why, but for me this worked:
cy.get('[role="button"][aria-haspopup="listbox"]').trigger('mouseover').wait(1000).click().click({force:true});
Upvotes: 1
Reputation: 2529
I switched my app from being rendered as SPA to using SSR (basically removing ssr: false
from my svelte.config) which started to fail my Cypress tests. Reverting fixed it for my test setup.
Upvotes: 0
Reputation: 616
FWIW: I was having problems submitting/navigating after a Google Places address selection. I believe my component wasn't re-rendering post-address selection.
To solve my issue, after address selection, I selected a random text element, clicked on it (no-op) and then clicked on my continue button and it worked fine.
Upvotes: 0
Reputation: 85
Something I just learned from a colleague after none of the above worked for me and after hours of searching. Just blew my mind. Just add another .click()...
before:
cy.contains('some string').click();
In the left Cypress menu click on the action and you'll see the indicator that it clicks the correct part, but nothing happens. Do it manual in the browser and it works.
Fix:
cy.contains('some string').click().click();
and all of the sudden the string is clicked and test is moving on to the next page
Upvotes: 6
Reputation: 2984
Whoever finds this problem, the official way of handling it is described here: https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/
TLDR:
What @jpvantuyl said, cypress clicks the button before the onclick event is there.
The lib cypress-pipe
will add a .pipe
method that if followed by .should
will retry a function until the condition is true or it times out.
Example:
cy
.get(numbers.result.idLocator)
.pipe($el => $el.click()) // try this
.pipe(
// next line will make assertions on the element returned by this pipe
() => cy.get(calculatorScreen.resultOutput.idLocator)
)
.should("contain", "0"); // until this happens or times out
Upvotes: 9
Reputation: 237
https://github.com/cypress-io/cypress/issues/2928 helped me.
cy.get('[data-qa="select_workers-list"]'.contains('+ New Worker').trigger('mouseover').click();
Upvotes: 21
Reputation: 604
This could be because the application is attaching behaviors to the button via JavaScript. When that script takes a long time to execute it allows Cypress to click the button before the OnClick event is there.
See: https://www.cypress.io/blog/2018/02/05/when-can-the-test-start/
Cypress recommends tracking when the underlying JS is in place with something like:
function waitForAppStart() {
// keeps rechecking "appHasStarted" variable
return new Cypress.Promise((resolve, reject) => {
const isReady = () => {
if (appHasStarted) {
return resolve()
}
setTimeout(isReady, 0)
}
isReady()
})
}
it('greets', () => {
cy.visit('app.html', {
onBeforeLoad: spyOnAddEventListener
}).then(waitForAppStart)
// all other assertion will run only when
// the application has started
cy.get('#name').type('Cypress{enter}')
cy.contains('#answer', 'Cypress')
})
Upvotes: 6