This is a great, detailed report! What you’re running into is a known issue with Cypress 14.1.0+ (especially with Firefox), Livewire, and how Cypress handles network requests and page navigation. Here’s what’s happening and how you can work around it:
What's Happening?
- Livewire uses AJAX requests for form submissions.
- Cypress 14.1.0+ introduced changes to how it intercepts and manages network requests, especially with Firefox.
- After clicking the login button, Livewire sends an AJAX request. If the login is successful, the server responds with a redirect, and Livewire updates the page.
- Cypress may not detect the navigation as a "real" page load, so
cy.location()might not update as expected. - The JSON parse error is likely because Cypress is interfering with or double-intercepting Livewire's AJAX requests, causing malformed responses.
Solutions
1. Use cy.url().should('include', '/dashboard') Instead
Sometimes, cy.location() can be less reliable with Livewire. Try:
cy.url().should('include', '/dashboard')
2. Add a Wait for the Dashboard Content
Instead of relying solely on the URL, assert that dashboard content is present:
cy.get('[data-test-id="dashboard-content"]').should('be.visible')
Make sure you add a unique data-test-id to something on your dashboard page.
3. Ignore Uncaught Exceptions (Temporary Workaround)
You can tell Cypress to ignore these exceptions, so your test doesn't fail due to Livewire's AJAX errors:
Cypress.on('uncaught:exception', (err, runnable) => {
// Ignore Livewire JSON parse errors
if (err.message.includes('JSON.parse')) {
return false
}
})
Add this to your cypress/support/e2e.js or cypress/support/index.js.
4. Use Chrome Instead of Firefox
This issue is more prevalent in Firefox. Try running your tests in Chrome:
npx cypress run --browser chrome
5. Downgrade to Cypress 14.0.3
If the above workarounds don't suit you, stick with 14.0.3 until the Cypress team resolves this regression.
Example Test (with Workarounds)
Cypress.on('uncaught:exception', (err, runnable) => {
if (err.message.includes('JSON.parse')) {
return false
}
})
it('should sign a user in', () => {
cy.visit('/login')
cy.get('[data-test-id="email"]').type('[email protected]')
cy.get('[data-test-id="password"]').type('password')
cy.get('[data-test-id="login"]').click()
// Wait for dashboard content, not just URL
cy.get('[data-test-id="dashboard-content"]').should('be.visible')
cy.url().should('include', '/dashboard')
})
References
Summary:
This is a Cypress regression with Livewire and AJAX navigation. Use the workarounds above, and consider reporting your findings to the Cypress team with a minimal reproduction if you haven't already. You're not alone—many are running into this with Livewire and SPA-like navigation!