How to script for postman like API in cypress - api

I am new in Cypress,
I wanted to create my first code for API in cypress.
Here is the details
POST
https://www.mywebsite.com/myproject/get-customer-login-url
HEADER
------
KEY: token
VALUE: HKt7854UHTFGR78#78
DESCRIPTION:
KEY: Content-Type
VALUE: application/json
DESCRIPTION:
BODY
-----
RAW:
{
"customerid": "54607"
}
Using above parameters, I got below result and status in Postman.
RESULT:
"{\"url\":\"default.aspx?rootid=843&companyId=54607&eccuserid=0&isloginspecialrole=False&userid=e91zNO%2bBBCI%3d&t=view\",\"code\":\"1\"}"
STATUS"
200 OK
I need to made script for cypress using these POST URL and parameters/key.
And want response like
https://www.mywebsite.com/myproject/default.aspx?rootid=843&companyId=54607&eccuserid=0&isloginspecialrole=False&userid=e91zNO%2bBBCI%3d&t=view
can anyone help me out to my cypress script?.

Here's an example, you might have to adjust it. This example just validates that status of the response is 200 but you can validate response contents as well. Refer cypress docs for details:
describe('Test the api', function() {
it ('status should be 200', () => {
cy.request({
method: 'POST',
url: 'your-url',
followRedirect: false,
headers: {
'token': 'HKt7854UHTFGR78#78',
'Content-Type': 'application/json',
},
body: {"customerid": "54607"},
})
.then((response) => {
expect(response.status).to.equal(200)
})
})
})

Related

How to handle the plain/text POST request in the cypress

I have a postman collection and It's POST call and the request body is type of plain/text and I just want to automate this using cy.request but I'm not sure how to pass the test body in the cy.request body section and it returned 400 bad request if I run the below code.
cy.request({
url: `${url}/user`,
method: "POST",
headers: {
'Content-Type': 'plain/text'
},
body: {
"confirmEmail": "true"
}
}).then(res =>{
cy.task('log',"Email id "+res.body.emailAddress);
return res.body;
});
}
The above request return .json response but the input request if text format and the same working fine in the postman tool.
Passing the request body in the below format in the postman tool and its working fine.
confirmEmail=true
My assumption is in the request body our endpoint is expecting a boolean value, but you are passing a string. So changing "confirmEmail": "true" to "confirmEmail": true should work.
cy.request({
url: `${url}/user`,
method: 'POST',
headers: {
'Content-Type': 'plain/text',
},
body: {
confirmEmail: true,
},
}).then((res) => {
cy.log(res.body.emailAddress) //prints email address from response body
})
In case you need to pass parameters in your URL you can directly use qs
cy.request({
url: `${url}/user`,
method: 'POST',
qs: {
confirmEmail: true,
},
headers: {
'Content-Type': 'plain/text',
},
}).then((res) => {
cy.log(res.body.emailAddress) //prints email address from response body
})

Axios post request results in 400 - Bad request

I test an API with Postman and want to write a request with axios. This is what it looks like in Postman and it works fine.
This is my code in javascript:
axios.post('http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token', null,
{ params: {
grant_type : "password",
username: "test",
password: "password",
client_id: "admin-cli"
},
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
}).then((response) => {
console.log(response)
}).catch((error) => {
console.log(error)
})
This results in the following error:
POST http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token?grant_type=password&username=test&password=password&client_id=admin-cli 400 (Bad Request)
I also tried to use curl, which also works:
curl -X POST http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token -H 'Content-Type: application/x-www-form-urlencoded' -d 'grant_type=password&username=test&password=password&client_id=admin-cli'
I guess there might be an error in my axios code, but I don´t know what might have gone wrong :-(
In your axios request you've send your data as parameters instead of form data.
Have a look at this thread to see how to send form data: axios post request to send form data
You gotta send in the second param exactly what you're sending into params;
So the new request would be something like this:
const data = {
grant_type: "password",
username: "test",
password: "password",
client_id: "admin-cli"
}
const url = 'http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token'
axios.post(
url,
data, // data in the second param
{
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
}).then((response) => {
console.log(response)
}).catch((error) => {
console.log(error)
})

Cypress: Where does the authentication token go for an API request?

I am trying to request data through an API that requires authentification. I have the token and I know how to implement it using a manual tool such as postman...
How do I format the authentication using Cypress?
it('GET - read', () => {
cy.request({
method: 'GET',
url: 'https://mailtrap.io/api/v1/inboxes/123/messages?page=1&last_id=&useremail',
headers: {
Key: 'Api-Token',
Value: '1234'
}
})
})
})
Response:
The response we got was:
Status: 401 - Unauthorized
As per the Mailtrap documentation, sending an header Api-Token: {api_token} should send authenticated requests. You can write:
cy.request({
method: 'GET',
url: 'https://mailtrap.io/api/v1/inboxes/123/messages?page=1&last_id=&useremail',
headers: {
'Api-Token': 'Your Token value' //Replace with real token
},
failOnStatusCode: false
}).then((res) => {
expect(res.status).to.equal(200) //Replace with releveant 2xx response code
})

How do i get the status of my response when using fetch in react-native?

I am making Log In page for my react native application. My api sends different response when my username and password are valid and invalid. So I want to track and save the status of my response in some state variable and then later perform function accordingly. Please suggest me way to do that.
doSignUp() {
console.log("inside post api");
fetch('MyApiUrl', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
password: this.state.password,
email:this.state.email,
name: this.state.firstname,
last_name :this.state.last_name,
mobile:this.state.mobile,
ssn:"2222222"
})
}).then((response) => {console.log('response:',response.status);
response.json()}
.then((responseData) => {
console.log("inside responsejson");
console.log('response object:',responseData)
console.log('refresh token:',responseData[0].token.refresh_token)
console.log('access token:',responseData[0].token.access_token);
}).done();
}
As far as I understand you want to know the http status code of your fetch request.
Usually your response object includes a "status" property. So you should be able to receive the status code by using this:
response.status
In case of a successful request this will return 200.

fetch: Getting cookies from fetch response

I'm trying to implement client login using fetch on react.
I'm using passport for authentication. The reason I'm using fetch and not regular form.submit(), is because I want to be able to recieve error messages from my express server, like: "username or password is wrong".
I know that passport can send back messages using flash messages, but flash requires sessions and I would like to avoid them.
This is my code:
fetch('/login/local', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password,
}),
}).then(res => {
console.log(res.headers.get('set-cookie')); // undefined
console.log(document.cookie); // nope
return res.json();
}).then(json => {
if (json.success) {
this.setState({ error: '' });
this.context.router.push(json.redirect);
}
else {
this.setState({ error: json.error });
}
});
The server sends the cookies just fine, as you can see on chrome's dev tools:
But chrome doesn't set the cookies, in Application -> Cookies -> localhost:8080: "The site has no cookies".
Any idea how to make it work?
The problem turned out to be with the fetch option credentials: same-origin/include not being set.
As the fetch documentation mentions this option to be required for sending cookies on the request, it failed to mention this when reading a cookie.
So I just changed my code to be like this:
fetch('/login/local', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
credentials: 'same-origin',
body: JSON.stringify({
username: this.state.username,
password: this.state.password,
}),
}).then(res => {
return res.json();
}).then(json => {
if (json.success) {
this.setState({ error: '' });
this.context.router.push(json.redirect);
}
else {
this.setState({ error: json.error });
}
});
From Differences from jQuery section of the Fetch API on Mozilla:
fetch() won't receive cross-site cookies. You can’t establish a cross
site session using fetch(). Set-Cookie headers from other sites are
silently ignored.
fetch() won’t send cookies, unless you set the
credentials init option. Since Aug 25, 2017: The spec changed the
default credentials policy to same-origin. Firefox changed since
61.0b13.)
I spent a long time but nothing worked for me.
after trying several solutions online this one worked for me.
Hopefully it will work for you too.
{
method: "POST",
headers: {
"content-type": "API-Key",
},
credentials: "include",
}
I had to include credentials: 'include' in the fetch options:
fetch('...', {
...
credentials: 'include', // Need to add this header.
});