I have a problem with data stubbing in Cypress 6. I am trying to implement the exchange of real data from the server to custom data. I read the docs and came to the conclusion that
describe("test", () => {
it("intercept", () => {
cy.intercept("http://localhost:3000/spoons", (req) => {
req.reply((res) => {
let { body } = res;
body.newProperty = "new";
console.log(res.body);
return body;
});
});
});
});
will be the solution, however... body in networking for request http://localhost:3000/spoons
returns to me
{
"sizes": [
"huge",
"small"
],
"colors": [
"yello",
"brown"
],
"build": {
"back": true,
"front": true
}
}
but in the console.log
as it shows what res.body
has, it gets an empty console.log as if it had nothing res.body
in it.
Edit #1
About internal "server" I made just simple express server with a website which make fetch request to have easy another request in "Networking". It was made just as a battlefield to train intercept
and other stuff. There is the only endpoint to this /spoons
server.js
:
const express = require("express");
const app = express();
const port = 3000;
const path = require("path");
const obj = {
sizes: ["huge", "small"],
colors: ["yello", "brown"],
build: {
back: true,
front: true,
},
};
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname + "/index.html"));
});
app.get("/spoons", (req, res) => {
res.json(obj);
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body></body>
<script>
console.log(fetch("http://localhost:3000/spoons"));
</script>
</html>
It works for intercepting external network requests,
/// <reference types="@cypress/fiddle" />
const test = {
html: `
<script>
fetch('https://jsonplaceholder.typicode.com/todos/1')
</script>
`,
test: `
cy.intercept('https://jsonplaceholder.typicode.com/todos/1', req => {
req.reply((res) => {
let { body } = res;
body.newProperty = "new";
console.log(res.body);
return body;
});
})
`
}
it('test', () => {
cy.runExample(test)
})
This logs
{
completed: false,
id: 1,
newProperty: "new", // added by intercept
title: "delectus aut autem",
userId: 1
}
Can you explain the api server and client ports in more detail?
I set up your server, and found it works ok.
The only thing I changed was to add a no-store header to the server response (stops browser seeing status code '304').
Without it every second refresh of the Cypress test cy.intercept()
did not trigger. That may actually be fixable in the test by adding a full route matcher to cy.intercept()
instead of just the url.
app.use((req, res, next) => {
res.set('Cache-Control', 'no-store')
next()
})
app.get("/", (req, res) => {...
I also modified the script in the app to console.log in .then()
, otherwise you just get the promise object.
<script>
fetch('http://localhost:3000/spoons')
.then(res => res.json())
.then(res => console.log('app', res))
</script>
This is the spec I used.
it('test', () => {
cy.intercept('http://localhost:3000/spoons', req => {
req.reply((res) => {
let { body } = res;
body.newProperty = "new";
console.log('intercept', res.body);
return body;
});
})
cy.visit('../app/intercept-mod-response-local-server-2.html')
})