I am able to use cy.intercept() to intercept a backend API. But this backend API internally makes a call to a third party server. I want to intercept this internal call and stub it, but it's not happening. This internal call cannot be 'seen' in the Network requests of a browser, but it's definitely happening since it's coded in the backend API.
So to summarize, I can intercept a request but not the second request that the first request makes internally. How do I intercept this second internal request?
Many thanks in advance!
You cannot with Cypress commands, they will only work with requests sent from the browser.
Cypress sets up a network proxy in the browser and catch requests made from the app and response back to the browser.
You can add a mock reply to the frontend intercept in order to cut out the backend API altogether.
This makes sense if you are testing the browser app, since you do not care what happens outside browser.
If you also wish to test then backend API, then call it directly (in a different test) and check it's response. See Example API Test
context("GET /users", () => {
it("gets a list of users", () => {
cy.request("GET", "/users").then((response) => {
expect(response.status).to.eq(200)
expect(response.body.results).length.to.be.greaterThan(1)
})
})
})
See the discussion here which asks the same question.
Related
In my Cypress test, I am trying to wait for a GET request & validate it's response. However, the test is timing out as the request never occurs.
Here is the request I am trying to wait for:
Here are some details around the test:
The URL of the app I am visiting in the test is https://ts-e2e-challenge.netlify.app/list.
In my test, an action is performed that sends a GET request to the URL https://bookshelf.jk/api/list-items, as you can see in the screenshot.
And here is my test code:
cy.intercept('GET', '/list-items').as('getListItems')
cy.wait('#getListItems').then((interception) => {
});
Full error message:
Timed out retrying after 5000ms: cy.wait() timed out waiting 5000ms
for the 1st request to the route: getListItems. No request ever occurred
I assume the URL that I am trying to intercept is incorrect, but I have tried to update it to the full path https://bookshelf.jk/api/list-items, but the request is still not being made.
Can someone please point out what the request URL should be based on the above screenshot?
I think the issue here is your request is not intercepted properly, You can try this:
cy.intercept('GET', '**/api/list-items').as('getListItems')
cy.wait('#getListItems').then((interception) => {
//Do something
})
There's a service worker intercepting the network requests before Cypress can intercept them.
If you put https://bookshelf.jk/api/list-items into a normal browser, it can't be reached. That's because the service worker is acting like the (non-existing) API server.
For the record, the full URL https://bookshelf.jk/api/list-items should work. Also /api/list-items would work if your baseUrl was common to the web page and the api (as you surmised).
As far as I can see, there's no simple adjustment to fix it. You may be able to hack the loading of the service worker but if you're just trying out cy.intercept() it's not worth the effort.
I'd look for another site to test against, https://jsonplaceholder.typicode.com is a good one.
When calling cy.visit("https://my-page.com") my page will fetch a number of external libraries/scripts. One of them is for sentry.io. Sometimes this particular fetch will just hang forever. The website is perfectly usable without it. Is there a way to make cy.visit not wait for these fetch requests from certain domains?
Some things to try, depends on how the app responds
Controlling the response
req.destroy() - destroy the request and respond with a network error
cy.intercept('https://sentry.io/*', req => req.destroy())
req.reply() - stub out a response requiring no dependency on a real back-end
cy.intercept('https://sentry.io/*', {}) // stubbed, never goes to the server
You may have to tweak {} to include fake properties if the app expects them.
When people create real-time web apps, they are leaving a ajax request open/long running.
how do they do this in javascript?
There is really no difference from a normal ajax request. A callback is associated with the XMLHttpRequest. Once the request is complete the callback is invoked. The difference is on the server-side where the request is held open until data is ready for the client, or a timeout occurs. On the browser side, the callback is invoked as each successive request is answered. The callback must process the data from the server and initiate another request. The request is handled asynchronously, so the browser is not blocked.
A really good example of the whole thing is the chat demo included in Tornado.
I want to use mootools and SqueezBox class to handle a request to a RESTful service. I don't want to use any server-side script. I am using AJAX. I send a request to the following url using GET method.
http://www.idevcenter.com/api/v1/links/links-upcoming.json
but I receive a 404 error. Is it because cross-site scripting? here is my code:
SqueezeBox.initialize({handler:'url',ajaxOptions:{method:'GET'}});
$('a.modal').addEvent('click',function(e){
new Event(e).stop();
SqueezeBox.fromElement($('a.modal'));
});
In Firebug console, sometimes 'aborted' is shown and sometimes '404'.what is wrong with that?
XMLHttpRequest is subject to the Same Origin Policy; if the document your JavaScript is running within is not from the same origin as the service you're trying to call, the call will be disallowed for security reasons.
There is now a proposed standard for cross-origin resource sharing to address this. It may be that the service you're trying to use supports it; if so, using a browser that implements CORS (recent versions of Firefox and Chrome do, as do some others) may work. IE8 supports it but requires that you do extra work.
You cannot use XMLHttpRequest (that is, ordinary "ajax") to call a service on a server that is not in your domain.
You can, however, use the JSONP trick, which takes advantage of the fact that the browser will load Javascript from other domains. However, the service has to know that you're going to do that, and it has to understand the protocol. That particular service seems perfectly willing to give me a JSON response, but it doesn't pay attention when I give it a "callback" parameter. (I've tried both "callback" and "jsonp" and the JSON blob that comes back is the same, without a function call wrapper.)
I'm been reading up on Ajax and would like to see from the stackoverflow community if I'm understanding everything correctly.
So the normal client server interaction is a user pulls up a web browser types in a url and a HTTP request is sent to the server requesting the page and resources( css, pics ) from the web server. The web server responds to the client via HTTP the page/resources requested and the browser renders the html/JavaScript for the user to view the page.
1) So would it be safe to say that XMLHttpRequest( XHR ) object is doing the same process as the browser except your not requesting html from the server, your requesting text in some type of format?
2) Is it true that a XHR object is much like a regular object that can be manipulated by the program creating the object( like a normal object ), but also sends and receives data with another program( web server ) via HTTP?
3) So in my mind when a XHR is created it is loaded into memory and we setup some of the objects arguments when we do the request.open(“GET”, url, true). Once we do a request.send(null) the object basically attempts to “GET” the url via HTTP and once we get the data back from the server it is put in the responseText argument. Am I understanding this correctly?
4) Also synchronous vs asynchronous. When I think of synchronous I think of steps having to be followed in order. For example, I push a button, data gets sent to server, and I have to wait for data to come back before I can do anything else. With asynchronous connections I would push button, data gets sent to server, I do what ever I want while data gets sent back. Is this a good analogy?
1) Nope. The XMLHttpRequest object does exactly what its name implies -- it initiates an HTTP request. This request can be in XML, or HTML, or PHP. At the end of the day, the browser doesn't care, because in an AJAX request, it doesn't parse the request -- you have to do it yourself. So it doesn't automatically render the HTML from an AJAX request.
2) I'm not sure about manipulation (the XHR object may be immutable) but possibly. Would you ever need to extend it or manipulate it?
Yes, you can change properties of the object and so on. I apologize. I didn't understand you at first :)
3) Yep.
4) That's a great analogy. It's exactly what happens. Another analogy is a 4 lane highway is to asynchronous as a one-way street is to synchronous. If one car breaks down on the 4 lane highway, the rest can keep moving at their normal speed -- but if one breaks down on the one-way road, everything freezes. :)
Here I leave you a good graphic to see clearly the behavior differences between the synchronous and asynchronous application models:
(source: adaptivepath.com)
It would appear that you have a job grasp of how AJAX works. I can't see much to disagree with in your summary of the plumbing of an AJAX application.
I would say however that with the XMLHttpRequest object you aren't restricted to GET. You can also use POST and other HTTP verbs.
With async calls you register a callback function, the XMLHttpRequest object calls your method when the async request completes.
Seems ok to me.
Your first point though is not entirely correct, you can request html from the server using ajax is doesn't have to text, json or xml like most examples show.