question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Turbolinks issues when clicking links.

See original GitHub issue

Current behavior:

I use Turbolinks in my application. If I click on two links after each other, where the link is present on both pages like a “Next” link, I get “xhr aborted” and it fails. It seems as cypress clicks the same link twice (not waiting for the xhr to finish)… If I add a cy.wait(0) between the clicks it seems to work. But it’s a bit of a hack 😃

Desired behavior:

It should wait for the next page and click the correct link.

Steps to reproduce:

Create a page with Turbolinks which links to another page (like a “Next” link in a pagination). On this other page, add the same link to a “Next” page.

Now, run a Cypress test where you click on the “Next” link twice. This will fail (might be a bit random).

Adding cy.wait(0) between the clicks seem to solve the problem for some reason.

Versions

Cypress: 3.0.1 Macos 10.13.4

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:14 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
carlobeltramecommented, Jun 14, 2019

For anyone still having issues with turbolinks and Cypress, I solved mine by using the following implementation of the above suggestions (goes into support/commands.js):

// Overwrite the Cypress .click() function
Cypress.Commands.overwrite("click", (originalFn, subject, ...args) => {
    var lastArg = args.length ? (args[args.length - 1]) : {}
    // Check if turbolinks could be active for this click event - could be improved
    if ((typeof lastArg !== 'object' || !lastArg['noWaiting']) && subject[0].tagName === 'A' && subject[0].getAttribute('href')) {
        // Wait for turbolinks to finish loading the page before proceeding with the next Cypress instructions.
        // First, get the document
        cy.document({ log: false }).then($document => {
            Cypress.log({ $el: subject, name: 'click', displayName: 'click', message: 'click and wait for page to load', consoleProps: () => ({ subject: subject })})
            // Make Cypress wait for this promise which waits for the turbolinks:load event
            return new Cypress.Promise(resolve => {
                // Once we receive the event,
                const onTurbolinksLoad = () => {
                    // clean up
                    $document.removeEventListener('turbolinks:load', onTurbolinksLoad)
                    // signal to Cypress that we're done
                    resolve()
                }
                // Add our logic as event listener
                $document.addEventListener('turbolinks:load', onTurbolinksLoad)
                // Finally, we are ready to perform the actual click operation
                originalFn(subject, ...args)
            })
        })
    } else {
        // Not a normal click on an <a href> tag, turbolinks will not interfere here
        return originalFn(subject, ...args)
    }
})

Alternatively, you can disable turbolinks while running in Cypress, by canceling each turbolinks:click event (this goes into support/index.js):

Cypress.on('window:load', $window => {
    $window.document.addEventListener('turbolinks:click', event => {
        event.preventDefault()
    })
})
0reactions
sasavukcommented, May 10, 2022

@carlobeltrame Thank you, that’s a great solution. Our team is using it by passing turbo as an option like so:

Cypress.Commands.overwrite("click", (originalFn, subject, options) => {
  // Check if turbo could be active for this click event - could be improved
  if (options?.turbo) {
    // Wait for turbo to finish loading the page before proceeding with the next Cypress instructions.
    // First, get the document
    cy.document({ log: false }).then(($document) => {
      Cypress.log({
        $el: subject,
        name: "click",
        displayName: "click",
        message: "click and wait for page to load",
        consoleProps: () => ({ subject: subject }),
      });
      // Make Cypress wait for this promise which waits for the turbo:load event
      return new Cypress.Promise((resolve) => {
        // Once we receive the event,
        const onTurboLoad = () => {
          // clean up
          $document.removeEventListener("turbo:load", onTurboLoad);
          // signal to Cypress that we're done
          resolve();
        };
        // Add our logic as event listener
        $document.addEventListener("turbo:load", onTurboLoad);
        // Finally, we are ready to perform the actual click operation
        originalFn(subject, options);
      });
    });
  } else {
    return originalFn(subject, options);
  }
});
cy.get("whatever").click({turbo: true});
Read more comments on GitHub >

github_iconTop Results From Across the Web

Prevent Turbolinks from reloading the page when clicking ...
Turbolinks sends another server request when clicking an anchor link that points to the same page. For example, when you're in the ...
Read more >
Turbolinks causes a link with href="#" to trigger page refresh
When I remove Turbolinks, the link behaves properly (does not cause page refresh). Links with "#" as the URL cause a reload on...
Read more >
Livewire with turbolinks problems with wire:click - Laracasts
I have this problem: when i reload the page livewire wire:click does not work with turbolinks. But if i access the page with...
Read more >
Cloudflare Web Analytics and Turbolinks causing problems
The URL in the browser bar would not update when clicking links, even tho the page content was loaded correctly · Some redirects...
Read more >
Working with JavaScript in Rails - Ruby on Rails Guides
When clicked, the link background will become red. Here's the problem: what happens when we have lots of JavaScript we want to execute...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found