Cypress verify API request - cypress

I want to verify if the API request contains what it needs to contain, but not sure what I am doing wrong as I have always this error:
cy.wait() timed out waiting 5000ms for the 1st request to the route: apiCheck. No request ever occurred.
I have a link in the main menu, after clicking that link the new page opens and API call is iniciated immediately http://localhost:8081/currencies
So in Cypress I have this:
cy.get('ul li[title="Menu item"]>a').click();
cy.intercept({
method: 'GET',
url: '/currencies',
}).as('apiCheck')
cy.wait('#apiCheck').then((interception) => {
expect(interception.response.statusCode).to.equal(200);
expect(interception.response.body[0]).to.have.property('geographyName', 'EMEA')
})
As you can see from Cypress test runner screenshot, the request is there and has status 200, but still it says no request ever occurred.

ah, well, seems I need to call cy.intercept before the link is clicked, then it seems working.

Related

How to get POST API response in Cypress?

I am working on a project to automate using Cypress. In this project, I need to create an order for a patient. When I click on the submit button it will call the following API https://ibis-dev.droicelabs.us/api/dispenser/orders/ using the POST method and return one unique order that I want to get.
I have registered cy.intercept on top of my test like this:
cy.intercept({
method: 'POST',
url: 'https://ibis-dev.droicelabs.us/api/dispenser/orders/',
}).as('ordersCall')
And when the submit button is clicked I have used:
cy.clickOnElementUsingXpath(practicePageSelectors.submit_CreateOrderButton); // click on submit button
cy.wait('#ordersCall')
.its('response.body')
.then((body) => {
// parsing might be not needed always, depends on the api response
const bodyData = JSON.parse(body)
cy.log(bodyData)
})
But it returns the following error:
Timed out retrying after 5000ms: cy.wait() timed out waiting 5000ms for the 1st request to the route: ordersCall. No request ever occurred in cy.wait('#ordersCall')
Can anyone help me to get an orderID? Is there any other way to get the orderID?
After checking the provided images in the question comments, the error is as follows: Your intercept command in your Cypress test is waiting for requests to be made to your DEV environment, but looking at your last image from the console in the Cypress test runner your requests are being made to the QA environment.
So you either have to adjust your Interceptor like this:
cy.intercept({
method: 'POST',
url: 'https://ibis-qa.droicelabs.us/api/dispenser/orders/',
}).as('ordersCall')
or think about using relative paths for API calls to be independent from the environment:
cy.intercept({
method: 'POST',
url: '/api/dispenser/orders/',
}).as('ordersCall')

NetworkError: Failed to execute 'send' on 'XMLHttpRequest' with Chrome Browser - Ext JS

I am getting an error on logging out from an application via Chrome browser only.
Chrome browser version 86.0
Blocked alert('Uncaught NetworkError: Failed to execute 'send' on
'XMLHttpRequest': Failed to load
'https://host-name/web/base/logout?id=40dee37f-cf1d-40f9-b01d-2a414d446a77&tenant=ABC&isFrameMode=true&_dc=1602665141328':
Synchronous XHR in page dismissal. See
https://www.chromestatus.com/feature/4664843055398912 for more
details.. line: 1. url:
https://hostname/web/base/abc/app.js?_dc=20161213063112') during
unload.
Code that is being used to logout from Application :
var vRequest = { url: vUrl, async: false },
Ext.Ajax.request(vRequest);
Have tried changing the async attribute value from false to true but now the request status is being displayed as canceled in Developer Tools.
The problem is not the ajax call. The problem is the call is, based on the error your are getting, happening during an event that is no longer allowed, beforeunload, unload, pagehide, visibilitychange... etc
Here are some alternate ways to return data to the server on logout.

Stubbing network request with cypress

I am trying to mock a server in some UI tests that I am writing using cypress. I am probably making some basic mistake and might not be understanding how cypress is stubbing requests. Here is an example app that I copied straight from expressjs -
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => res.send('Hello from /'));
app.get('/user', (req, res) => res.send('Hello from /user'));
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
And then wrote a simple test using cypress -
describe('Stubbed request', () => {
it('sends whatever response you want', () => {
cy.visit('http://localhost:3000/');
cy.server();
cy.route({
method: 'GET',
url: '/user',
response: [],
}).as('bar');
cy.visit('http://localhost:3000/user'); // cy.request() has same behavior
cy.wait('#bar');
})
})
I was hoping that instead of 'Hello from user/', I should get an empty response since I have stubbed it with cypress. Even cy.wait fails with message - "CypressError: Timed out retrying: cy.wait() timed out waiting 5000ms for the 1st request to the route: 'bar'. No request ever occurred." I am obviously doing something wrong. Can someone please help me understand what am I doing wrong? Thanks in advance.
You can only stub/spy XHR requests that are created within your app. cy.visit will never make such a xhr request. neither you can stub a request made with cy.request because thise requests are intended to work indepentent from all active network stubs.
This means, you are able to stub /users but in your test you can make a real request to that route by using cy.request.
In your case, you must deliver a static html site with express that e.g. contains a button. And after the button is clicked, you can execute e.g. $.get(' /user'). Then this request will be stubbed.
Currently I am not at home so I can not provide a runnable example. But with the hints above you should be able to do this. Let me know if you need further assistance.
Also you can take a look at cypress XHR API call validation in test cases . Here I have provided a runnable example fir stubbing and spying.

Signin request failing due to invalid csrf

I am testing a signin page for keystonejs (http://demo.keystonejs.com/) and cannot get the request to succeed with cypress. A signin request without cypress has the following request headers:
while a request with a cypress test has the following request headers:
The only difference I can see is that the cookie is not set in the cypress test request. And because of that the request gets a 403. I am actually using a local version of that server in which I have the email/password configured as the one in the images. The demo site uses a different set provided in that page.
The test is simply:
describe('The Keystone Admin UI Signin Page', function () {
before(function() {
cy.visit('http://localhost:3000/keystone/signin')
})
it('should signin successfully with valid email/password', function () {
cy.get('#signin-view input[name=email]').clear().type('user#test.e2e');
cy.get('#signin-view input[name=password]').clear().type('test');
cy.get('#signin-view button[type=submit]').click();
cy.get('#react-root').should('be.visible');
})
})
Anyway to get around this?
I know this is an older question but I'll post this in case it helps anyone.
The key to fixing this issue for me was that Cypress clears all cookies before each test (https://docs.cypress.io/api/commands/clearcookies.html#).
So in the example above (and in my experience):
The first test (loading the page) is run and passes fine - at this point the browser has set the csrftoken cookie
The second test (submitting the form) runs but before this happens Cypress has deleted the csrftoken cookie - hence the error
To fix this I had to whitelist the csrftoken cookie in Cypress config which means that it will be exempt from this clearing process:
Cypress.Cookies.defaults({
whitelist: "csrftoken"
})
You can do this inline in your test file but the docs recommend using a support file:
A great place to put this configuration is in your cypress/support/index.js file, since it is loaded before any test files are evaluated.
Hope this helps, Stephen.
Following on from FlatSteve's answer, using with Laravel and updated prop names use;
Cypress.Cookies.defaults({
preserve: ["XSRF-TOKEN", "your_laravel_session_name", "remember_token"]
});

Symfony2, jQuery Ajax request, web debug toolbar, 500 Internal Server Error

I am developing an application with Symfony2 platform that, at one moment, makes a simple AJAX request on document ready.
jQuery.ajax({
url: 'test.php',
type: 'POST',
data: {
'test': 'test'
},
success: function( response ){
jQuery( 'div#container' ).html( response );
}
});
The problem is that on app_dev.php, where the debug toolbar is loaded, an 500 error is throwed.
More precisely, the AJAX response from the 'test.php' file is received and loaded in the div container, but then, when it tries to load the toolbar, I receive an alert message:
"An error occured while loading the web debug toolbar (500: Internal
Server Error). Do you want to open the profiler?"
If I open profiler, I don't see anything wrong.
If I open the xhr request for the toolbar, a FastCGI 500 error is displayed:
Module FastCgiModule
Notification ExecuteRequestHandler
Handler PHP54_via_FastCGI
Error Code 0x000000ff
If I don't try to make the AJAX request, the toolbar is loaded with no problem.
If I make the request by hand (event on a button) after the toolbar is loaded, again, no problem. If I make the request by hand (event on a button) before the toolbar is loaded the error is throwed.
Notes:
This error occur only on the local machine (with ISS 7.5, PHP 5.4.14). On the production server (IIS server 8.0, same and PHP) the AJAX request is made, and the toolbar is loaded with no problems. I have replaced the php.ini on the local machine with the php.ini from the production server - same problem.
Initialy AJAX request was loading the result of a simple bundle controller method, but then I have tried with a simple PHP file 'test.php', same problem.
I have tried with post and get methods to make the request.
Does anyone have any ideea what goes wrong?
This is not a serious problem since I have multiple options the develop this app, but is bugging me, and I already lost a enough time with this.
PS: if it make any difference, on same machine I have developed an application - no framework - that makes, multiple simultaneos ajax requests.
The following will not fix your error, but provides an alternative way to possibly achieve your need. It seems you want to load asynchronously a part of your website, Symfony2 provides a solution for that: ESI render.
The doc is here: http://symfony.com/doc/current/book/templating.html#asynchronous-content-with-hinclude-js
This method will create an ajax call only then your page will be rendered.

Resources