Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to intercept XHR request on page with Puppeteer and return mock response

I need to be able to intercept XHR requests on page loaded with Puppeteer and return mock responses in order to organize backendless testing for my web app. What's the best way to do this?

like image 688
s.ermakovich Avatar asked Sep 22 '17 13:09

s.ermakovich


3 Answers

It seems that the way to go is request.respond() indeed, but still, I couldn't find a concrete example in the web on how to use it. The way I did it was like this:

// Intercept API response and pass mock data for Puppeteer
await page.setRequestInterception(true);
page.on('request', request => {
    if (request.url() === constants.API) {
        request.respond({
            content: 'application/json',
            headers: {"Access-Control-Allow-Origin": "*"},
            body: JSON.stringify(constants.biddersMock)
        });
    }
    else {
        request.continue();
    }
});

What happens here exactly?

  1. Firstly, all requests are intercepted with page.setRequestInterception()
  2. Then, for each request I look for the one I am interested in, by matching it by URL with if (request.url() === constants.API) where constants.API is just the endpoint I need to match.
  3. If found, I pass my own response with request.respond(), otherwise I just let the request continue with request.continue()

Two more points:

  • constants.biddersMock above is an array
  • CORS header is important or access to your mock data will not be allowed

Please comment or refer to resources with better example(s).

like image 121
Kostas Siabanis Avatar answered Nov 02 '22 02:11

Kostas Siabanis


Well. In the newest puppeteer,it provide the request.respond() method to handle this situation.

like image 11
X Rene Avatar answered Nov 02 '22 03:11

X Rene


If anyone is interested I ended up creating special app build for my testing needs, which adds Pretender to the page. And I communicate with Pretender server using Puppeteer's evaluate method.

This is not ideal, but I couldn't find a way to achieve what I need with Puppeteer only. There is a way to intercept requests with Puppeteer, but seems to be no way to provide fake response for a given request.

UPDATE:

As X Rene mentioned there is now native support for this in Puppeteer v0.13.0 using request.respond() method. I'm going to rewrite my tests to use it instead of Pretender, since this will simplify many things for me.

UPDATE 2:

There is pptr-mock-server available now to accomplish this. Internally it relies on request interception and request.respond() method. Library is pretty minimal, and may not fit your needs, but it at least provides an example how to implement backendless testing using Puppeteer. Disclaimer: I'm an author of it.

like image 7
s.ermakovich Avatar answered Nov 02 '22 02:11

s.ermakovich