microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
67.27k stars 3.7k forks source link

[BUG] Modifying response creates two HAR entries #17802

Closed smckee-r7 closed 2 years ago

smckee-r7 commented 2 years ago

Context:

Code Snippet

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({
    headless: false,
    slowMo: 5000
  });
  const context = await browser.newContext({ recordHar: { path: './harFile.har' } });
  const page = await context.newPage();

  await page.route('**/*', async route => {
    // Fetch original response.
    const req = route.request();
    const response = await page.request.fetch(req, { headers: { ...req.headers(), ...{ 'inject-header': 'request' } } });

    // Add a prefix to the title.
    let body = await response.text();
    body = body.replace('<title>', '<title>My prefix:');
    route.fulfill({
      response,
      body,
      headers: { ...response.headers(), ...{ 'inject-header': 'response' } }
    });
  });

  await page.goto('https://www.google.com/');

  page.close();
  context.close();
  browser.close();
})();

Describe the bug The documentation explains how you can intercept and modify a response. This way of modifying the response correctly sends only 1 request to the server but the HAR file contains 2 entries for the same URL. It seems that the first HAR entry is for the original request (which never gets sent) and the second is for the fetch. This causes the correct request and expected response information to be split between the 2 har entries; use the code snippet above and look at the request & response inject-headers in the HAR data. I don't know what the correct behaviour should be but I doubt there should be 2 complete har entries per single network request.

yury-s commented 2 years ago

This is working as intended. You see one request that actually hit the network and the one that was sent by the page and fulfilled via interception, the latter has pageref the former doesn't.