So based off Cypress request docs: https://docs.cypress.io/api/commands/request.html
It seems like I should be able to send a POST request with a JSON body pretty easily. So this is what I tried:
cy.fixture('test_create').as('create_test')
cy.request({
method: 'POST',
url: 'http://localhost:8080/widgets',
body: '#create_test',
headers: {
'Authorization': this.token,
'Content-Type': 'application/json;charset=UTF-8'
}
})
However when I look at the "commands" Cypress sends, it's sending the body as literally Body: #create_test
Is it not possible to use a fixture within the body of a POST request? I confirmed the fixture is loading correctly. I confirmed also it works when I paste the entire JSON inside of the body option....but that gets ugly really quick with large JSON bodys.
You get a literal because in the form cy.request(options), options is a plain JS object and unfortunately not parsed by Cypress to interpret the alias.
The request form cy.request(method, url, body) probably does allow an alias for the body param, since cy.route() allows it ref: Accessing Fixture Data
e.g the following should be valid, but does not allow setting headers
cy.fixture('test_create').as('create_test')
cy.request('POST', 'http://localhost:8080/widgets', '#create_test');
So, you can use then()
cy.fixture('test_create').then(myFixture => {
cy.request({
method: 'POST',
url: 'http://localhost:8080/widgets',
body: myFixture,
headers: {
'Authorization': this.token,
'Content-Type': 'application/json;charset=UTF-8'
}
})
});
or
cy.fixture('test_create').as('create_test');
... // some other code between
cy.get('#create_test').then(myFixture => { // retrieve the fixture from alias
cy.request({
method: 'POST',
url: 'http://localhost:8080/widgets',
body: myFixture,
headers: {
'Authorization': this.token,
'Content-Type': 'application/json;charset=UTF-8'
}
})
})
Related
How to send xml file as payload in cypress post request:
When i am trying to send xml file/txt file as post request payload, am not able to do ad getting bad request
This works for me... (pardon the formatting)
it('Post File to URL', () => {
const yourFile = 'C:\\PathToYourFile\\YourFile.xml'
cy
.readFile(yourFile)
.then(function (text) {
cy.log(text)
postXML(text)
}
)})
function postXML(text) {
return cy.request({
url: 'https://yourURL.com',
method: 'POST',
body: text,
headers: {
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
'content-length': '1000',
'connection': 'close',
'soapAction': ''
}
})}
I use Axios in browser to call ajax request. Now I have a problem with some cookie that has high priority than some header. Per request I send a header as AUTHTOKEN but in cookie SESSIONID key stored that high priority than AUTHTOKEN header. In some scenario, I need to ignore cookie. This is my code:
axios({
url:`${sdpBasicUrl}/api/v3/requests/27363`,
method: 'get',
headers: {
'Content-Type': 'application/json'
'AUTHTOKEN': 'GHG23847923HGJ'
}
})
.then(res => {
console.log(res.data);
});
and this is cookie sample:
_z_identity=true; PORTALID=1; csrfcookie=aasdasdjh24234b2bjh4hjl; SESSIONID=ffd68d32a14841c99905e3cf4897e15ec9b4777020854a76821fd7e1eab6db2dcab482eb4cfea2ce7f5a6c47c80271d09f608ed985004e5c85681b2939681b18
What should I do? Do you have any solution to solve my problem?
You are able to pass in cookies through the header like this:
Axios.request({
url: "http://example.com",
method: "get",
headers:{
Cookie: "cookie1=value; cookie2=value; cookie3=value;"
}
}).then...
So if you don't want the value to be there, you could override the values.
https://github.com/axios/axios/issues/943
You can use transformRequest to modify the header for some requests. transformRequest allows changes to the request data and header before it is sent to the server. This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE'.
transformRequest: [function (data, headers) {
// Modify the header here and return the header
return data;
}],
You can get more information about it on https://axios-http.com/docs/req_config
When I'm running cypress e2e tests, application makes XHR requests. How can I log all this requests and responses? I don't want to stub these requests. I with to get an artifact with all requests and responses made during test. Gitlab is used as CI.
Main test code looks like this. All these are user defined commands, interacting with the application. Interacting with the application causes different requests to be made (e.g. I click a button, this causes the request).
it('Log response to a file',function(){
cy.request({
method: 'GET',
url: 'https://<site>/home/payments/currency/confirm/*',
headers: {
'Content-Type': 'application/json',
},
body: {},
}).then((response)=>{
const someResponse = response.body;
console.log("hhhh"+someResponse);
cy.writeFile('cypress/fixtures/testResponse.json', someResponse);
cy.login(login_name, pass)
cy.typeOTPpinpad(secret)
cy.makePayment('Currency', 'amount')
cy.typeToken(secret)
cy.logout()
})
})
Here is how I tried to use regular expression to catch request (id is unique and I need to use regular expressions).
https://<mysite>/home/payments/<currency>/confirm/* - asterisk is payment id.
You could grab the request and response and write to a location as below. I have write the request and response to fixture folder as below: Try the below and let me know
it('Log request to a file',function(){
cy.request({
method: 'GET',
url: 'url_here',
headers: {
'Content-Type': 'application/json',
},
body: {},
}).then((request)=>{
const someRequest = JSON.stringify(request);
console.log("hhhh"+someRequest);
cy.writeFile('cypress/fixtures/testRequest.json', someRequest);
})
})
// The below is for response:
it('Log response to a file',function(){
cy.request({
method: 'GET',
url: 'url_here',
headers: {
'Content-Type': 'application/json',
},
body: {},
}).then((response)=>{
const someResponse = response.body;
console.log("hhhh"+someResponse);
cy.writeFile('cypress/fixtures/testResponse.json', someResponse);
})
})
The testrunner has such information on board:
[
I have a phonegap application that uses
$.ajax(
type: 'POST,
dataType:"json",
url: 'test.com'
data: { mail: 'bob#test.com' }
)
which i get in my glassfish server doing something like
HttpServletRequest request;
request.getParameter('mail');
I'm moving my application in react native so i'm doing
fetch('test.com', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ mail: 'bob#test.com' }),
})
but that doesn't work, my glassfish server doesn't get my parameters.
How should i do ?
It goes without saying that i don't want to make changes on the server side !
In your first example (using $.ajax()) you are not sending a JSON body. You are actually sending a query string. In your react example, you are sending a JSON body which would need to be handled differently by your server.
You will need to either change your server handler to actually accept JSON or you will have to send a query string with react which would look something like:
fetch('test.com', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: $.param({ mail: 'bob#test.com' }),
})
If you don't have access to jQuery you wouldn't be able to use $.param(). For this particular example, the query string you'd want to send would be
body: "mail=bob#test.com"
It is fairly straightforward to serialize data for a query string and creating a function that will do it pretty easy.
As a side note, in order to send a JSON body with an $.ajax() call, you would want to do something like this:
$.ajax(
type: 'POST,
dataType:"json",
url: 'test.com'
data: { mail: 'bob#test.com' }
contentType: "application/json",
)
Note the contentType parameter which actually tells jQuery how to format the body of the request
I'm trying to authenticate users from Trigger.io, ideally via Facebook.
I authenticate the user via Facebook (using the Parse Facebook module), and pass their access token, acess expiry date, and facebook Id to my call to Parse.
It is here things go wrong. Whenever I try and post this data via Ajax to the Parse REST API, I get an error in my forge/Trigger console reading:
{ type: 'EXPECTED_FAILURE', content: '{"code":107,"error":"This
endpoint only supports Content-Type: application/json requests, not
application/x-www-form-urlencoded."}', statusCode: '400', message:
'HTTP error code received from server: 400' }
The code I used to try and post this data is...
function auth(facebookId,accessToken,expirationDate) {
forge.logging.log('auth started');
forge.request.ajax({
url: 'https://api.parse.com/1/users',
headers: {
'X-Parse-Application-Id': config.parseAppId,
'X-Parse-REST-API-Key': config.parseRestKey,
'Content-Type': 'application/json'
},
type: 'POST',
dataType: 'json',
data: {
"authData": {
"facebook": {
"id" : facebookId,
"access_token": accessToken,
"expiration_date": expirationDate
}
}
},
success: function (data) {
forge.logging.log('auth finished 1');
forge.logging.log(data);
},
error: function(error){
forge.logging.log('auth finished 2');
forge.logging.log(error);
}
})//success
} //auth
I can't figure out how to send this as a JSON object/ in the correct format. If anyone has any ideas they'd be much appreciated. Thanks. Josh.
Whenever the data option passed to forge.requests.ajax is an object like in your example, what actually gets posted is a query string that represents the object. The contentType option merely allows you to set the Content-Type header, it does not effect how objects are encoded for the request.
However if the data option is just a string, then this string is used as the body of the request. You can generate a JSON string to use as the body using JSON.parse like so:
forge.request.ajax({
...
contentType: 'application/json',
data: JSON.stringify({
"authData": {
"facebook": {
"id" : facebookId,
"access_token": accessToken,
"expiration_date": expirationDate
}
}
})
});