0
votes

Background:

I'm writing test automation for a React web application, using Cypress. In the application I have a dialog box in which there are elements I need to click. When I try to click any of these elements normally, Cypress gives me an error that the element in not visible because its content is being clipped by one of its parent elements, which has a CSS property of overflow: 'hidden', 'scroll' or 'auto'. Because these DOM elements are generated by some 3rd party React components, I cannot change this, and the only way I can work-around it is to use {force:true} in the click command.

The problem:

Because I have few of these elements and in order to keep the DRY principle, I wanted to create a custom child command named forceClick that simply wraps subject.click({force:true}). However, for some reason, when I do that, Cypress does not perform the click command at all!

Note: For debugging purposes I added a cy.log command to the custom command as well, and strangely enough, I see that this log command is executed and only the click command doesn't.

Here's the code:

Cypress.Commands.add('forceClick', {prevSubject:'element'}, subject => {
    cy.log('forceClick was called!');
    subject.click({force:true})});

And inside my test I have the following line:

cy.get("[data-test='panel-VALUES']").forceClick();

Note that if I change it to the following line, it works as expected:

cy.get("[data-test='panel-VALUES']").click({force:true});

Any idea why the click command isn't executed by the forceClick custom command?

2

2 Answers

1
votes

You are almost there, you just missed that you have to wrap the subject if you want to work with it.

Cypress.Commands.add('forceClick', {prevSubject: 'element'}, (subject, options) => {
  // wrap the existing subject and do something with it
  cy.wrap(subject).click({force:true})
})
0
votes

I never saw a solution with subject.click({force:true}), I'm not saying it won't work, but I just never saw it before. What works anyway is this:

Custom command:

Cypress.Commands.add('forceClick', {prevSubject:'element'}, subject => {
  cy.log('forceClick was called!');
  cy.get(subject)
    .click({force:true})});
}

Test step:

cy.forceClick('[data-test="panel-VALUES"]');

If you only use the forceClick you could even shorten it further to this:

Custom command:

Cypress.Commands.add('forceClick', {prevSubject:'element'}, subject => {
  cy.log('forceClick was called!');
  cy.get(`[data-test=${subject}]`)
    .click({force:true})});
}

Test step:

cy.forceClick('panel-VALUES');