Can't intercept same service multiple times cypress.io - cypress

cy.intercept({
pathname: '/myService'
}).as('myServiceIntercept');
I would like to call:
cy.wait('#myServiceIntercept')
multiple times in my test but it only works the first time.
I also tried doing something like this:
cy.intercept({
pathname: '/myService'
}).as('myServiceIntercept2');
and then calling a wait:
cy.wait('#myServiceIntercept2')
but it seems like i can't override the first intercept and those wait basically won't work.
Can someone please help me getting on the right track?
Thanks!

Related

How to wait all similar requests in cypress?

When start page of app are loading I have a lot of requests on locize api.
requests count
When I try to write a test for it, I need to wait when all of them finished and then start to get an DOM elements.
I do it like this:
cy.intercept({
method: "GET",
url: "https://api.locize.app/**",
}).as("languages");
cy.visit("/");
cy.wait("#languages")
but this code wait only 1st request.
test log
I was try to do it with cy.get("#languages.all")
but it's haven’t any effect.
So the question is, how can I get waiting for all requests before it's go further?
P.S. I'm pretty new in cypress, so I'll be really appreciated for any help.
One of the solution that I found is library cypress-network-idle.
https://www.npmjs.com/package/cypress-network-idle
Basically it helped me solve the problem
If you know the calls for the language, then you can store them in an array and iterate over it to create unique intercepts and wait on them. However, this would be brittle to changes in your app calls.
const enGBItems = ['Objects', 'Locations', ... ]
Cypress._.forEach(enGBItems, function(item){
cy.intercept({
method: "GET",
url: `https://api.locize.app/**/en-GB/${item}`,
}).as(item)
})
cy.visit("/")
Cypress._.forEach(enGBItems, function(item){
cy.wait(`#${item}`)
})

Cypress: Switching from cy.route() to cy.intercept()

It seems that most people I read about experence zero trouble with this. I, on the other hand, have a test suite which someone else wrote, in which I'm trying to replace route() with intercept(). The API intercepts are done to handle button clicks etc., and about 99.9% percent of them fails if I just replace it. So, there's obviously some syntax in/use of intercept() I've not found a description for.
Example:
This works:
cy.route('POST', getApiPrefix() + '/prosjektfinansiering/'+ pfId +'/eiendom', result);
This does not work. The button click is not executed:
cy.intercept('POST', getApiPrefix() + '/prosjektfinansiering/'+ pfId +'/eiendom', result);
I've tried adding '**' in front of "/prosjekt...", and I've tried removing 'POST', with no luck.
Any ideas? I'll gladly post more info if necessary.
UPDATE:
Futher attempts:
Getting some hints here and there, it seems that this is a more correct way of using intercept():
return cy.intercept('POST', getApiPrefix() + '/prosjektfinansiering/'+ pfId +'/eiendom', {
body: result
});
This doesn't work, either.
The variables result in these examples is an object describing what is sent back to the frontend of the POST-request in the route matches the api path.
For troubleshooting, I can see that when using intercept(), there is ONE route that is not working when using intercept (the bottom one in the picture). However, I cannot for the life of me see why, and how the route match can be written differently?
Most likely, you're mixing the old use of cy.route() and cy.server(). In my experience, those two won't work well together. It's easier when you're starting fresh with just cy.intercept().
Your update is correct too; You have to encapsulate the return value you want mocked in {body: value}.
from what I am seeing in your circled screenshot, the API is not called after you try to intercept it. (the count under # column is -)
You need to track when the API is to be called and ensure you intercept before the call is made. Cypres can help you with this. You can go through the run steps in the cypress window.
You could also share this if you don't mind.
If you are 100% certain the button makes the call. Steps should be:
cy.intercept()
cy.get('button').click()
In the cypress window, right after the click, you should see the API being called.

How do I properly use asyncScheduler to know data was processed in rxjs?

I have some basic code like this:
this.events$
.pipe(
observeOn(asyncScheduler),
...
).subscribe(anotherObservable$);
This works fine in my app, but I am having a funny issue with a unit test. I put a couple of debug consoles like this:
this.events$
.pipe()
.subscribe(console.log.bind(null, 'sanity check inside without async'));
this.events$
.pipe(observeOn(asyncScheduler))
.subscribe(console.log.bind(null, 'sanity check inside with async'));
If I do from(events).subscribe(events$); in my test, the "without async" log fires.
If I do scheduled(events, asyncScheduler).subscribe(events$);, nothing fires.
I can't seem to fake the input to get my pipe on the async scheduler to fire. My test just needs that pipe to fire to see that something was called.
Realized right after posting:
scheduled(events, asyncScheduler).subscribe(events$);
await lastValueFrom(events$)

Wait until element has disappeared in Cypress

please, tell me what methods to use to wait for a loading screen element to disappear? PS. I'm not using an API request.
I tried to use two methods, but it doesn't work properly:
1. cy.get('#loading', { timeout: 30000 }).should('not.be.visible');
I get the error: -- Timed out retrying after 30000ms: Expected to find element: #loading, but never found it.
2. Used plugin (cypress-wait-until) like so cy.waitUntil(() => {document.querySelector('#loading') === null};
This approach doesn't find the element at all.
If you are trying to retrieve an element that is not in the DOM, use not.exist instead:
cy.get('#loading').should('not.exist');
In cases where you do need to wait, you can try using cy.wait:
An example use case for this might be if Cypress has to route to your page first and you want to ensure the page loads before you start testing:
cy.wait(200);

cypress.io waiting for same alias

cy.server();
cy.route('POST', 'my/api').as('myApi');
...
cy.wait('#myApi');
...
cy.route('POST', 'my/api').as('myApi');
cy.wait('#myApi');
When my app calls the same API twice within the same test, from the above code, the 2nd cy.wait finishes immediately since it sees that the first API is already finished. To get around this, I append a random number behind all my route aliases. Is this the correct way?
You might be able to do better. The cy.route() command is just a definition, so you should group all your routes at the top of the file. Routes only need to be defined once. Then try chaining your waits, as in cy.wait().otherStuff().wait() or at least chaining your waits with other stuff that has to succeed first.
Thank you for the question! I think the previous answer is totally right. By default, cypress routing is just aliasing. You could find a similar example in the cypress documentation here.
So, you code should be something like that:
cy.server();
cy.route('POST', 'my/api').as('myApi');
cy.wait('#myApi').then(() => {
// You probably want to add some assertions here
});
// Do your stuff here
cy.wait('#myApi').then(() => {
// Second assertion. Probably, something should be changed in the second request.
});
In this case, for the second wait, you can try the following.
cy.server();
cy.route('POST', 'my/api').as('myApi');
cy.wait('#myApi').then(() => {
// You probably want to add some assertions here
});
// Do your stuff here
cy.wait(['#myApi', '#myApi']).then(() => {
// Second assertion. Probably, something should be changed in the second request.
});

Resources