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')
I have the following:
describe('Page not authenticated', () => {
it('Page has authentication', () => {
cy.visit('https://myauthsite.com/logout');
cy.visit('/', { failOnStatusCode: true });
cy.url().should('include', 'https://myauthsite.com/');
});
})
For internal reasons, the package is set up so that it always has a persistent session, so I need a test to visit a specific URL that would explicitly logout and "kill" the session and then visit the main page that I'm trying to test to ensure that it does redirect me to the right page. However, I'm running into this error
You may only `cy.visit()` same-origin URLs within a single test.
The previous URL you visited was:
> 'https://myauthsite.com'
You're attempting to visit this URL:
> 'https://myactualsite.com'
You may need to restructure some of your test code to avoid this problem.
https://on.cypress.io/cannot-visit-different-origin-domain
A lot of the workarounds that's listed mostly addresses checking for the attribute instead of visiting the url, or splitting the visits into two different test case, but in my case I really need it to be in its own encapsulated test, is that not possible?
cy.request() isn't bound by the same cross-origin request policies, so if you can log out via an HTTP request that should work.
I tried using chromeWebSecurity=false, but that didn't help.
I'm currently using the API login, setting the cookies, and later read "Google Sign in with Cypress"''
cy.request({
method:"POST",
url:API_URL,
headers: {
'Content-Type': 'application/json',
},
body: api_body}).then((response =>{
cy.log(response.body)
cy.setCookie("token_name",response.body['token']);
cy.visit(destination_url);
}))
API_URL is your API login URL:
token_name: Login manually to UI, Using the web developer tool you can get the required token_name
This resolved my multi-domain login issue, and you can use it for multi-domain navigation.
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.
I want to test some URLs in a web application I'm working on. For that I would like to manually create HTTP POST requests (meaning I can add whatever parameters I like).
Is there any functionality in Chrome and/or Firefox that I'm missing?
I have been making a Chrome app called Postman for this type of stuff. All the other extensions seemed a bit dated so made my own. It also has a bunch of other features which have been helpful for documenting our own API here.
Postman now also has native apps (i.e. standalone) for Windows, Mac and Linux! It is more preferable now to use native apps, read more here.
CURL is awesome to do what you want! It's a simple, but effective, command line tool.
REST implementation test commands:
curl -i -X GET http://rest-api.io/items
curl -i -X GET http://rest-api.io/items/5069b47aa892630aae059584
curl -i -X DELETE http://rest-api.io/items/5069b47aa892630aae059584
curl -i -X POST -H 'Content-Type: application/json' -d '{"name": "New item", "year": "2009"}' http://rest-api.io/items
curl -i -X PUT -H 'Content-Type: application/json' -d '{"name": "Updated item", "year": "2010"}' http://rest-api.io/items/5069b47aa892630aae059584
Firefox
Open Network panel in Developer Tools by pressing Ctrl+Shift+E or by going Menubar -> Tools -> Web Developer -> Network. Select a row corresponding to a request.
Newer versions
Look for a resend button in the far right. Then a new editing form would open in the left. Edit it.
Older versions
Then Click on small door icon on top-right (in expanded form in the screenshot, you'll find it just left of the highlighted Headers), second row (if you don't see it then reload the page) -> Edit and resend whatever request you want
Forget the browser and try CLI. HTTPie is a great tool!
CLI HTTP clients:
HTTPie
Curlie
HTTP Prompt
Curl
wget
If you insist on a browser extension then:
Chrome:
Postman - REST Client (deprecated, now has a desktop program)
Advanced REST client
Talend API Tester - Free Edition
Firefox:
RESTClient
Having been greatly inspired by Postman for Chrome, I decided to write something similar for Firefox.
REST Easy* is a restartless Firefox add-on that aims to provide as much control as possible over requests. The add-on is still in an experimental state (it hasn't even been reviewed by Mozilla yet) but development is progressing nicely.
The project is open source, so if anyone feels compelled to help with development, that would be awesome: https://github.com/nathan-osman/Rest-Easy
* the add-on available from http://addons.mozilla.org will always be slightly behind the code available on GitHub
You specifically asked for "extension or functionality in Chrome and/or Firefox", which the answers you have already received provide, but I do like the simplicity of oezi's answer to the closed question "How can I send a POST request with a web browser?" for simple parameters. oezi says:
With a form, just set method to "post"
<form action="blah.php" method="post">
<input type="text" name="data" value="mydata" />
<input type="submit" />
</form>
I.e., build yourself a very simple page to test the POST actions.
I think that Benny Neugebauer's comment on the OP question about the Fetch API should be presented here as an answer since the OP was looking for a functionality in Chrome to manually create HTTP POST requests and that is exactly what the fetch command does.
There is a nice simple example of the Fetch API here:
// Make sure you run it from the domain 'https://jsonplaceholder.typicode.com/'. (cross-origin-policy)
fetch('https://jsonplaceholder.typicode.com/posts',{method: 'POST', headers: {'test': 'TestPost'} })
.then(response => response.json())
.then(json => console.log(json))
Some of the advantages of the fetch command are really precious:
It's simple, short, fast, available and even as a console command it stored on your chrome console and can be used later.
The simplicity of pressing F12, write the command in the console tab (or press the up key if you used it before) then press Enter, see it pending and returning the response is what making it really useful for simple POST requests tests.
Of course, the main disadvantage here is that, unlike Postman, this won't pass the cross-origin-policy, but still I find it very useful for testing in local environment or other environments where I can enable CORS manually.
Here's the Advanced REST Client extension for Chrome.
It works great for me -- do remember that you can still use the debugger with it. The Network pane is particularly useful; it'll give you rendered JSON objects and error pages.
For Firefox there is also an extension called RESTClient which is quite nice:
RESTClient, a debugger for RESTful web services
It may not be directly related to browsers, but Fiddler is another good software.
You could also use Watir or WatiN to automate browsers. Watir is written for Ruby and Watin is for .NET languages. I am not sure if it's what you are looking for, though.
http://watin.sourceforge.net/
http://watir.com/
There have been some other clients born since the rise of Postman that is worth mentioning here:
Insomnia: with both desktop application and Chrome plugin
Hoppscotch: previously known as Postwoman, and with a Chrome plugin available as well. You can also make it work locally with docker if you want to get funny
Paw: if you are on Mac
Advanced Rest Client: already mentioned as a Chrome plugin, but it is worth pointing out that it also has a desktop application
soapUI: written in Java and with lots of testing functionality
Boomerang: yet another way to test APIs. It comes with SOAP integration and it also has a Chrome plugin available
Thunder Client: if you use VS Code as your text editor then you should go and check out this awesome extension
Try Runscope. A free tool sampling their service is provided at https://www.hurl.it/.
You can set the method, authentication, headers, parameters, and body. The response shows status code, headers, and body. The response body can be formatted from JSON with a collapsable hierarchy.
Paid accounts can automate test API calls and use return data to build new test calls.
COI disclosure: I have no relationship to Runscope.
Check out http-tool for Firefox...
Aimed at web developers who need to debug HTTP requests and responses.
Can be extremely useful while developing REST based API.
Features:
GET
HEAD
POST
PUT
DELETE
Add header(s) to request.
Add body content to request.
View header(s) in response.
View body content in response.
View status code of response.
View status text of response.
So it occurs to me that you can use the console, create a function, and just easily send requests from the console, which will have the correct cookies, etc.
so I just grabbed this from here: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options
// Example POST method implementation:
async function postData(url = '', data = {}, options = {}) {
// Default options are marked with *
let defaultOptions = {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
}
// update the default options with specific options (e.g. { "method": "GET" } )
const requestParams = Object.assign(defaultOptions, options);
const response = await fetch(url, requestParams);
return response.text(); // displays the simplest form of the output in the console. Maybe changed to response.json() if you wish
}
IF YOU WANT TO MAKE GET REQUESTS, you can just put them in your browser address bar!
if you paste that into your console, then you can make POST requests by repeatedly calling your function like this:
postData('https://example.com/answer', { answer: 42 })
.then(data => {
console.log(data); // you might want to use JSON.parse on this
});
and the server output will be printed in the console (as well as all the data available in the network tab)
This function assumes you are sending JSON data. If you are not, you will need to change it to suite your needs
You can post requests directly from the browser with ReqBin.
No plugin or desktop application is required.
I tried to use postman app, had some auth issues.
If you have to do it exclusively using browser, go to network tab, right click on the call, say edit and send response. There is a similar ans on here about Firefox, this right click worked for me on edge and pretty sure it would work for chrome too
Windows CLI solution
In PowerShell you can use Invoke-WebRequest. Example syntax:
Invoke-WebRequest -Uri http://localhost:3000 -Method POST -Body #{ username='clever_name', password='hunter2' } -UseBasicParsing
On systems without Internet Explorer, you need the -UseBasicParsing flag.
The question being 12 years old now, it is easy to understand why the author asked a solution for Firefox or Chrome back then. After 12 years though, there are also other browsers and the best one which does not involve any add-ons or additional tools is Microsoft Edge.
Just open devtools (F12) and then Network Console tab (not the Network or Console tab. Click on + sign and open it, if it is not visible.).
And here is the official guide:
https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/network-console/network-console-tool
Have fun!
I want use $.ajax to read some infomation from xml file,here is my js code :
$.ajax({
type: "get",
url: "Database/App_all.xml",
dataType: "xml",
timeout: 2000,
beforeSend: function () {
},
success: function (xml) {
$(xml).find("app[id='id-1']").appendTo($("#contain"));
},
error: function () {
alert("ajax failed!");
}
});
However, the code only work great in firefox and opera.
It doesn't work in chrome(7.0.517.24 ) and safari(5.0.1),failed without any alert,not even the alert("ajax failed").
Is there any bug in $.ajax in chrome and safari?so how to solve the problem?
thank you very much:)
You should use chrome's or safari's built-in developer tools (ctrl+shift+i) to track JS errors and track actual AJAX requests.
Is your code wrapped in document.ready? Is there any erros in javascript console? Also try to output something after success callback line.
Another cause for this could be incorrect mime-type for your XML file returned by server. It should be [Content-type: text/xml]. You can check that in chrome's or safari's built-in developer tools - just look for headers tab when xml resource is selected. If it 's actual problem, you may need to tweak web-server configuration (main config or .htaccess for apache) to return correct mime-type.
First thank you gajendra.bang and Māris Kiseļovs give me your advices,I have konw what's wrong with my code,after I get a bad resault ,I trying to know what the $.ajax get from xml exactly,so I use firebug check the div#contain I found that:
<div id="contain">
<auther>cocept</auther>
</div>
yes,I think the <auther></auther> must the problem,I don't even konw the $.ajax would get the tagname as well
so I rewrite it :
success: function (xml) {
$("#contain").html($(xml).find("app[id='id-1']").find("auther").text());
}
then the div$contain is:
<div id="contain">
cocept
</div>
so ,the chrome and safari could show again!
I suppose you have problem with reading of the local file per ajax. Ajax can be used to read a file from the same web server, but there are some security restriction if you read it not per HTTP.
In firefox and opera you can read local files (with url like file:///C:/Program%20Files/My/Database/App_all.xml) per ajax without any problem.
In Internet Explorer you should use dataType: 'text' and then convert the text to XML (read more here).
To be able to read local files in Chrome you have to restart chrome with another parameters:
chrome.exe --allow-file-access-from-files
(Be sure that all other instances of chorme closed before starting Chrome.exe in the way).
This is a problem for local files... You should try uploading them on a web server and check from there
$(xml).find("app[id='id-1']").appendTo($("#contain"));
what is xml basically returning, an element with "#" like "#mydiv" or class like ".mydiv"
I think you are trying to access an element and if you are not returning it with "#", try
$("#"+xml).find("app[id='id-1']").appendTo($("#contain"));