Is there a way to see exactly what a cy.request()
is sending to the web server? I am getting a 400 Bad Request
when I send my request, but a curl <url>
comes back with a 200 OK
.
What I'm hoping to get is a full specification of the request, including headers and so on. I can't see a way to get that out of Cypress documentation.
The cy.request()
yields the response, and lets you log that. I'm not looking for the response, I'm looking to see exactly what was in the request. I can find lots of answers telling me how to see what's in the response, but that is not what I'm looking for.
Is there a way to see exactly what a cy.request()
is sending to the web server? I am getting a 400 Bad Request
when I send my request, but a curl <url>
comes back with a 200 OK
.
What I'm hoping to get is a full specification of the request, including headers and so on. I can't see a way to get that out of Cypress documentation.
The cy.request()
yields the response, and lets you log that. I'm not looking for the response, I'm looking to see exactly what was in the request. I can find lots of answers telling me how to see what's in the response, but that is not what I'm looking for.
If you want to set up an experimental test to see request headers, set a server in cypress.config.js
and add some tasks to grab the data.
(NOTE: generally it's not recommended to setup a server in the Cypress node process, but for this simple experiment it works ok).
cypress.config.js
const { defineConfig } = require("cypress");
// set up the server here
const http = require('http');
const requestHeaders = {}
let requestKey = 'unknown'
http.createServer(function (req, res) {
requestHeaders[requestKey] = req.headers; // save the headers
res.end();
}).listen(8080);
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('task', {
'request:key': (key) => {
requestKey = key
return null
},
'curl': (command) => {
var util = require('util');
var exec = require('child_process').exec;
return new Promise((resolve, reject) => {
child = exec(command, function(error, stdout, stderr) {
if (error) reject(error)
resolve(stdout)
})
})
},
'node:fetch': (url) => {
fetch(url)
return null
},
'request:headers': () => {
return requestHeaders;
}
})
},
},
});
I set up a test that fires the request via cy.request()
, window.fetch
, curl
, and node:fetch
.
spec.cy.js
const url = 'http://localhost:8080'
cy.task('request:key', 'cy.request')
cy.request(url)
cy.task('request:key', 'window.fetch')
cy.intercept(url).as('win:fetch')
cy.window().then(win => win.fetch(url))
cy.wait('@win:fetch')
cy.task('request:key', 'curl')
cy.task('curl', `curl ${url}`)
cy.task('request:key', 'node:fetch')
cy.task('node:fetch', url)
cy.task('request:headers').then(headers => {
console.log(headers)
})
These are the headers recorded
{
"cy.request": {
"connection": "keep-alive",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
"accept": "*/*",
"host": "localhost:8080",
"accept-encoding": "gzip, deflate"
},
"window.fetch": {
"connection": "keep-alive",
"host": "localhost:8080",
"proxy-connection": "keep-alive",
"sec-ch-ua-platform": "\"Windows\"",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
"sec-ch-ua": "\"Not(A:Brand\";v=\"99\", \"Google Chrome\";v=\"133\", \"Chromium\";v=\"133\"",
"sec-ch-ua-mobile": "?0",
"accept": "*/*",
"sec-fetch-site": "same-site",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"accept-encoding": "gzip",
"accept-language": "en-GB,en-US;q=0.9,en;q=0.8"
},
"curl": {
"host": "localhost:8080",
"user-agent": "curl/8.9.1",
"accept": "*/*"
},
"node:fetch": {
"host": "localhost:8080",
"connection": "keep-alive",
"accept": "*/*",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "node",
"accept-encoding": "gzip, deflate"
}
}
The Cypress log isn't the best option. You want to examine the response details in the devtools console.
The first thing to do is add failOnStatusCode
option to allow details to be logged.
In this example I used the cy.request(options)
syntax.
cy.request({
method: 'GET',
url: 'http://localhost:3000',
failOnStatusCode: false, <-- get a response object for failed request
})
.then(response => {
console.log(response) <-- log the response to devtools
})
Here's the server, it just always returns code 400
and adds a message to inform the requester why it rejected the request (your server will obviously vary it's response data).
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
app.get('/', (req, res) => {
res.status(400);
res.send('Current password does not match');
})
server.listen(3000, () => {
console.log('listening on *:3000');
})
Here's the data I get in the console
In the cy.request()
options argument, you can set log: true
, to have the cy.request()
event logged in the command log. (This value is true
by default, so you don't have to explicitly set it to true if you're not changing the value elsewhere.)
cy.request({ url: '/foo', log: true });
Then, you can click on the request in the command log to see the output, as shown in Cypress' documentation. In their example, the request body, headers, URL, and status are all shown.
cy.intercept
Or if that doesn't work for you, you can always set up a network-proxy and inspect your traffic there – derpirscher Commented Jan 30 at 13:15