I'm writing my first Playwright Screenshot-test for a node application. The application makes serverside api requests and I want to mock the api responses so that my test becomes stable, predictable and can be run offline.
I will use nock to setup mocked data, because I've used nock in my old existing test suite (built on mocha + supertest) with great success.
But in my new Playwright-test I can't get nock to apply to my node app, probably because the node app is started as a separate process.
An old successful test file that uses supertest
const supertest = require("supertest");
const app = setupMyEntireNodeExpressApp();
nock("https://my-api.com").get("/").reply(200, { fakeData:true };
supertest(app).get("/").expect(200).end((err, response) => { doSomething(); }) //let supertest start the node app and make a request
The new playwright-test (myTest.spec.js) where the nock does not apply
const { test, expect } = require("@playwright/test");
const http = require("http");
const app = setupMyEntireNodeExpressApp();
test("My test", async ({ page, context }) => {
nock("https://my-api.com").get("/").reply(200, { fakeData:true };
http.createServer(app).listen(); //start node app
await page.goto("/"); //make a request via playwright
await expect(page).toHaveScreenshot("myTest.png", { fullPage: true }); //take screenshot via playwright
}
When I run the playwright test, the nock is not being applied to my node app. The app calls https://my-api.com and receives a response from the actual api rather than my mock data.
My GUESS is that the problem is that nock is running within the myTest.spec.js process but createServer starts my app as a separate process.
PS: in my playwright.config.js I've set webServer.reuseExistingServer:false since I'm starting my node app from the test file.
I tried removing http.createServer(app).listen(); and instead using webServer.reuseExistingServer:true and webServer.command: "node app.js". This is a way to let Playwright start the server via the command. But that caused the same problem. In that case I guess the problem is that myTest.spec.js is a separate process while node app.js starts a new process that doesn't have access to the nocks.
With my old successful test I guess the nock works because I can pass my node app object into supertest(app).request so the app is not started as a separate process, but is running within the same process as the test code where the nock is also running.
I wish there was a way to pass my app object to playwright in a similar way, but after reading their docs it doesn't seem like that's an option.
Is there an easy way to solve this?
Perhaps an alternative way of starting my node app using variants of createServer
In short, you cannot. From
nockdocumentation:What this means is that nock does not actually patch the HTTP server implementation, but it patches the HTTP client instead, and since your HTTP client is whatever the underlying browser Playwright is running, nock has no knowledge of that.
Therefore, in order to test the API, you will need to use Playwright provided methods, e.g.
In this example, we're using the
postandgetmethods provided by theAPIRequestContextclass to send API requests and validate the server state.The next step is to mock the routes themselves:
Whether the request originates from the
APIRequestContextor the application,routewill be able to intercept it.Unfortunately, this means you cannot leverage
nockAPI that you already familiar with, but it achieves the goal of mocking the API.