Open ekrapfl opened 1 month ago
I've encountered the same issues on my test project, leading to your report.
However, I got all assertions to pass from your sample by firing change detection manually and using then(()=>..
.
cy.mount(FailComponent, {
providers: [provideAngularQuery(new QueryClient())],
}).then(({fixture})=>{
fixture.detectChanges()
cy.get('.first').should('have.class', 'selected');
cy.get('.second').click().then(()=>{
fixture.detectChanges()
cy.get('.second').should('have.class', 'selected');
});
cy.get('.third').click().then(()=>{
fixture.detectChanges()
cy.get('.third').should('have.class', 'selected');
});
I know this doesn't solve the issue but it may help with the investigations.
Yep, that is totally true. If I strategically fire change detection manually all over the place in my tests, it will work. It's like something has broken something with change detection itself, though, and it doesn't happen automatically anymore.
Just curious, is the Cypress team looking into this at all?
@ekrapfl We're not currently looking into this problem at the moment. Our project board is generally up to date on what we're working on: https://github.com/orgs/cypress-io/projects/13
Thanks for the update, @jennifer-shehane. Is there any way to get that bumped up in priority at all? My company is a paying customer. Is there a support channel I should go through instead?
I would be very interested in anyone's thoughts on a workaround for this as well. I have tried sprinkling tons of manual change detection checks into the tests, but nothing seems to jar it loose completely.
Not necessarily a workaround, but instead of sprinkling change detection checks everywhere in your tests, Cypress does allow you to overwrite built-in commands, so you could do something like:
Cypress.Commands.overwrite('should', function (originalFn, ...args) {
cy.window().its('cdr').invoke('detectChanges').then(() => {
return originalFn.apply(this, args)
})
})
Now, whenever you do .should(...)
in a test, it will first run detectChanges
.
I took a look into this recently, and for whatever reason, whenStable
is never achieved when tanstack queries are used in the component, which means autoDetectChanges is never called inside Cypress. I'm hesitant to remove the line currently because I am not fully aware of the consequences, but you could try to either:
@cypress/angular-signals
to comment out that lineautoDetectChanges
on the fixture, like this:// ./cypress/support/component.ts
import { mount } from 'cypress/angular-signals'
// Augment the Cypress namespace to include type definitions for
// your custom command.
// Alternatively, can be defined in cypress/support/component.d.ts
// with a <reference path="./component" /> at the top of your spec.
declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount
}
}
}
Cypress.Commands.add('mount', function (...args) {
mount(...args).then(({ fixture }) => {
fixture.autoDetectChanges(true)
})
})
@ekrapfl would you mind trying this work around? I am able to get all tests to pass in the test-component.component.cy.ts
with this change. I created a PR against your fork to try https://github.com/cg-roling/cypress-component-testing-apps/pull/1
Wow, great call! That does seem to work to fix all of the tests I had failing for this reason, but it also breaks some others that were previously working. I am thinking that I might be able to work around it for now by doing something like:
cy.mount(MyComponent).then(({ fixture }) => fixture.autoDetectChanges(true));
And I would only do that for the problematic components. Not ideal, but neither is the whole situation. Does that seem like potentially a good workaround for the moment?
@ekrapfl, yes, that seems like a good workaround. You would also try setting up a mount
command that accepts a parameter to autoDetectChangesAfterMount
.
An interesting note for the Cypress mount command. I agree that there is some issue with whenStable
while using TanStack Query. I was finding some similar oddities with Jasmine unit tests while using TanStack Query. But I found a very simple workaround in Jasmine tests: make sure to run compileComponents
on the TestBed
. Once I did that, whenStable
seemed to work properly, as did any other quirks I was seeing. Normally, that shouldn't be necessary when running via ng test
according to the docs, but in my case, that definitely fixed the issue.
I was curious if I could apply that change to the Cypress mount command and globally have it compileComponents
, but I struggled to get that plugged in properly. Is that something Cypress would want to investigate to see if it fixes this kind of issue? Calling .compileComponents
on the TestBed
during mount
, that is?
I was curious if I could apply that change to the Cypress mount command and globally have it
compileComponents
, but I struggled to get that plugged in properly. Is that something Cypress would want to investigate to see if it fixes this kind of issue? Calling.compileComponents
on theTestBed
duringmount
, that is?
I don't see why we couldn't. It looks to be harmless according to the Angular docs, and we could just add the call in initTestBed. The only weirdness would be that the call my be async, which would make the mount
function async
. Either way, its likely worth looking into.
Current behavior
We are using Angular Query (TanStack Query's Angular port) in our project, and we have noticed that it can interfere with our Cypress component tests in some cases. To illustrate this, we have made a simple modification to the Cypress component testing sample app for standalone Angular. If you pull it down and run the
test-component
spec, you will see that none of the tests pass. It appears as though change detection is not running properly once the TanStack Query (TSQ) is injected in the component file. To see the tests work again, comment out thequery
property intest-component.component.ts
.Reproduction fork
Notes:
Desired behavior
I would expect that injecting a simple TSQ would not affect change detection in Cypress component tests.
Test code to reproduce
cypress-component-testing-apps Reproduction fork
angular-standalone
->test-component
Simple Angular Repro
npm ci
npx cypress open
Cypress Version
13.15
Node version
20.11.0
Operating System
MacOS 15.0
Debug Logs
No response
Other
No response