cypress wait for redirection after login - javascript

I am testing a web app with cypress.
I sign in in my beforeEach function. Then, in my different tests, I begin with cy.visit('mysite.com/url').
My problem is that after sign in, the website redirects to a specific page of the website. This redirection happens after the cy.visit of my tests. Therefore, my tests run on the redirection page, they fail.
The redirection seems to be not linked with any request I could wait for.
I end up with cy.wait(3000) but it is not very satisfying. My tests failed sometimes because the redirection might take more than 3 seconds. I do not want to increase that time because it would take too long to run my tests.
Is there a way to do something like:
while (!cy.url().eq('mysite.com/redirection-url')) {
cy.wait(300);
}

Cypress provides retry abilities on assertion. You can resolve the waiting issue for the redirection URL with the below change
cy.url().should('contain', '/redirection-url')
OR
cy.url().should('eq', 'mysite.com/redirection-url')
Here should assertion will wait till 4 seconds by default and retries cy.url()
You can change the default timeout by updating parameter in cypress.json file
{
"defaultCommandTimeout": 30000
}
Hope this will solve your issue.

If the redirect is to a different server, simply using cy.url does not work.
We solved the problem with the following code:
cy.origin('https://localhost:7256/',() => {
cy.url().should(
'contains',
'account/login');
})
where https://localhost:7256/ is the base URL of the server to which we are redirected.

Related

Conditional E2E tests with Cypress for a payment processor

We are using GoPay.com for payments in our app. It runs in two modes, full redirect to their site or iframe based solution to show the payment form inline. The conditions for display either of those is not exactly clear and might vary per a browser and who knows what else.
I need to interact with the payment form in tests to go through with it, but I am struggling how to do that. There is a sandbox environment, so it's ok to do test (free) payments.
Basically, I tried the following, but Cypress is not waiting for that page to load and fails right away.
cy.window().then(win => {
if (win.location.host.includes('gopay.com')) {
return win.document.querySelector('.main-body')
} else {
return // find form in iframe somehow
}
})
Also, I am unsure how to tackle the finding that form in the iframe.

Spring controller is getting called twice at test environment

I have been facing an issue with spring controller for a long time. Even after a lot of research over this spring controller redirection issues that didn't give any solution.
Issue: We are doing some payment integrations such as Sofort, AliPay and PayPal using Spring. Everything working fine in local machine(PC desktop) whereas it causes the issue with PayPal at test enviroments(Cloud deployment servers);however, remaining all other payment types are working fine.
There is the PayPal response handler url(Controller) at merchant server where it handles the paypal payment response, the handler url is getting called twice. Therefore, its not giving appriopriate results as it should get called only once.
PayPal Response Handler URL:
us/en-us/checkout/payment/paypal/handleResponse?token=EC-XXXXXXXXXXXX&PayerID=XXXXXX
Observations:
a) Whenever we have such kind of issues that is url getting called twice. At network tab of chrome, JS could be the issue. But, we haven't found such kind of history at there.
b) We use load balancer at our test environments. At sometimes, load balancer would make the url to get called twice. But, we didn't find a such kind of calls at loadbalancer.
c) Spring Handler method as below.
#RequestMapping(path = "/handleResponse", method = RequestMethod.GET)
public String handleResponse(#RequestParam(name = "token")
final String token, #RequestParam(name = "PayerID")
final String payerId)
d) There is no issue with PayPal configurations or PayPal servers. If I would hit the browser with the sample url below it is getting called twice, eventhough its not sending from PayPal. Hence, there is no issue with PayPal.
https://ABCDMERCHANT.com/us/en-us/checkout/payment/paypal/handleResponse?token=EC-XXXXXXXXXXX&PayerID=XXXXXXXXXXX
Guys, If could you give any suggestions to trace it down the root cause of it. that will be helpful for me.
Thanks InAdvance!!
We had given fixes to handle the second call however, during further tests even still it was failed and found the root cause and given the fix.
Root Cause: PayPal test environment, takes more than 45 seconds to complete set, get, authorize/capture and place order requests but the Application server time out is 10 seconds there its failed hence it makes second call.
Fix: we have increased the server time out to 50 seconds and its stopped making second request.

Finding the UI element in protractor is not consistent. Working with localhost and not with the server

Here is the code I am using expect(element(by.id('title')).getAttribute('value')).toMatch('Sample Title')
in local machine it is working perfectly fine and on server it is not with the following error.
Failed: Timed out waiting for asynchronous Angular tasks to finish after 11 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
While waiting for element with locator - Locator: By(css selector, *[id="title"])
and surprisingly sometimes these tests are working on server when I execute them alone.
to add to the question. I observed that protractor is able to find only one element in the tests and all the remaining are ignored with the error as above.
what could be the solution for this?
That could be application issue. Sometimes it happens that angular never reports to protractor that all tasks are done, so you might get this timeout error that you have.
http://www.protractortest.org/#/timeouts
AngularJS If your AngularJS application continuously polls $timeout or
$http, Protractor will wait indefinitely and time out. You should use
the $interval for anything that polls continuously (introduced in
Angular 1.2rc3).
Angular For Angular apps, Protractor will wait until the Angular Zone
stabilizes. This means long running async operations will block your
test from continuing. To work around this, run these tasks outside the
Angular zone. For example:
this.ngZone.runOutsideAngular(() => { setTimeout(() => {
// Changes here will not propagate into your view.
this.ngZone.run(() => {
// Run inside the ngZone to trigger change detection.
}); }, REALLY_LONG_DELAY); }); As an alternative to either of these options, you could disable waiting for Angular, see below.
As said in the error, it seems your app is not an angular. Isn't it?
If so, you need to use it:
browser.waitForAngularEnabled(false);

Stopping network calls without stopping javascript execution

Context
We're running some functional unit tests using theintern.io. Unfortunately, third party network calls randomly cause the page to time out, thus causing all of our unit tests to fail.
At a certain point, I'd like to cut the cord on all network calls to prevent the browser from hanging / tests from failing. I've tried window.stop(), but this causes the test to hang.
Question
How can I stop all network calls without also stopping javascript execution of my functional tests?
Firstly, window.stop won't stop javascript execution, in your case it might look like its doing so, if the tests are getting loaded dynamically.
window.stop is same as click stop button on your browser's address bar (Source: https://developer.mozilla.org/en-US/docs/Web/API/Window/stop).
Now coming to your questions, there are multiple ways to handle this, my suggestion would be to mock all the network calls. (Assuming the third party calls that you mentioned are all AJAX). This is also a good practice while writing unit tests. You can use sinon for this. (Source: http://sinonjs.org/)
You can give an expected response, or just give a 404 or anything else, and respond immediately to the requests. That way, your tests won't timeout. Hope it helps
{
beforeEach() {
server = sinon.fakeServer.create();
},
afterEach() {
server.restore()
},
tests: {
testA() {
server.respondWith("GET", /<regexPattern>/,[200, {"Content-Type": "text/plain"},""]);
server.respondImmediately = true;
}
}
}

Error: Timed out waiting for Protractor to synchronize with the page after 11001ms." when user browser.getCurrentUrl()

I am testing login and logout functionality, below is my test cases
it('should redirect to login page on click of logout',function(){
signInPage.email.sendKeys('zahid.afaque#meltwater.com');
signInPage.password.sendKeys(1234);
signInPage.loginButton.click();
expect(browser.getCurrentUrl()).toMatch(/\/collections/);
signInPage.profileImage.click();
signInPage.logout.click();
browser.waitForAngular();
expect(browser.getCurrentUrl()).toMatch(/\/login/);
});
When i run above test its failing and below is the error message
Error: Timed out waiting for Protractor to synchronize with the page after 11001ms. Please see https://github.com/angular/protractor/blob/master/docs/faq.md
i tried using browser.waitForAngular(); but it does not help. When i removed expect "expect(browser.getCurrentUrl()).toMatch(/\/login/);" then it is getting passed. Anyone have come across with same problem, any help is appricated
Maybe you are facing the same issue as I did. For me the app was constantly sending requests and thus was never finished.
Adding the following line after the "click()" fixed it for me:
browser.ignoreSynchronization = true;
Link to my question
ptor.sleep(1000) instead of wait for angular not ideal but works for me

Categories

Resources