playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature] setExtraHTTPHeaders overwrites headers on multiple calls

Open chasestarr opened this issue 2 years ago • 8 comments

I have a couple different fixtures which set http headers and I noticed that in test-case code, key/values set in the fixtures are overwritten. View the example script below.

I can imagine that simply changing the behavior to merge would be undesirable. Would creating a new method be reasonable? I think if we had a getExtraHTTPHeaders method, then I could implement this myself.

import { chromium } from "playwright";

async function main() {
  const browser = await chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.setExtraHTTPHeaders({ firstkey: "firstvalue" });
  await page.goto("https://manytools.org/http-html-text/http-request-headers/");
  await page.getByText("firstkey").waitFor();
  await page.getByText("firstvalue").waitFor();

  await page.setExtraHTTPHeaders({ secondkey: "secondvalue" });
  await page.goto("https://manytools.org/http-html-text/http-request-headers/");
  await page.getByText("secondkey").waitFor();
  await page.getByText("secondvalue").waitFor();
  
  // this fails since the second call clobbers the first call
  await page.getByText("firstkey").waitFor({ timeout: 1000 });
  await page.getByText("firstvalue").waitFor({ timeout: 1000 });

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

main();

chasestarr avatar Aug 28 '23 18:08 chasestarr

I worked around this by refactoring the setExtraHTTPHeaders calls within fixtures to page.route calls

chasestarr avatar Aug 30 '23 19:08 chasestarr

I was finding that page.route redirects were an issue for me and reverted back to looking for a setExtraHTTPHeaders solution. I wrote a fixture like below. Would this be reasonable to add into the playwright api?

const updateContextExtraHTTPHeaders = async ({ context }, use) => {
  let headers = {};

  async function handler(nextHeaders: { [key: string]: string }) {
    headers = { ...headers, ...nextHeaders };
    await context.setExtraHTTPHeaders(headers);
  }

  await use(handler);
};

chasestarr avatar Oct 06 '23 16:10 chasestarr

@chasestarr That's a great workaround with the fixture that you have. I'll leave this feature request for prioritizaiton.

dgozman avatar Oct 09 '23 15:10 dgozman

FYI I ran into this issue with next.js https://github.com/vercel/next.js/issues/54706, they also fixed it using page.route.

joshuajaco avatar Oct 09 '23 15:10 joshuajaco

@chasestarr I tried calling your handler twice and it still over-rode the headers. I'm using custom fixtures and two fixtures make the calls seperately. Note: Both fixtures use the context fixture. Call1: const headers = { 'X-CSRF-TOKEN': x_csrf_token, 'Content-Type': 'application/json' // Add any other custom headers as needed }; cookies.forEach((cookie) => { headers['Cookie'] = headers['Cookie'] ? ${headers['Cookie']}; ${cookie.name}=${cookie.value} : ${cookie.name}=${cookie.value}; }); await updateContextExtraHTTPHeaders({ context }, async (handler) => { // Define the headers you want to add or update // Call the handler with the custom headers await handler(headers); }); Call2: await updateContextExtraHTTPHeaders({ context }, async (handler) => { // Define the headers you want to add or update const customHeaders = { "Authorization": Bearer ${token_value} // Add any other custom headers as needed };

      // Call the handler with the custom headers
      await handler(customHeaders);
    });

Looks like Call2 overrode the headers set in call1. Could you give tell me what I'm doing wrong?

sprasanna2593 avatar Oct 26 '23 08:10 sprasanna2593

Hi im experimenting the following issue: I set my header on playwright.config.js as: { name: 'noUserAgent', use: { ...devices['Desktop Chrome'], extraHTTPHeaders: {'x-px-access-token' : 'someToken'} }, },

and when I enter debug mode and check for the request on network tab on request headers comes like this: image

ZhouZhengCarlos avatar Feb 15 '24 21:02 ZhouZhengCarlos

Hi im experimenting the following issue: I set my header on playwright.config.js as: { name: 'noUserAgent', use: { ...devices['Desktop Chrome'], extraHTTPHeaders: {'x-px-access-token' : 'someToken'} }, },

and when I enter debug mode and check for the request on network tab on request headers comes like this: image

Want to know if Im implementing this the wrong way or is there an issue with this feature?

ZhouZhengCarlos avatar Feb 15 '24 21:02 ZhouZhengCarlos

Also tried adding the header with page.setExtraHttpHeaders but it has the same result

ZhouZhengCarlos avatar Feb 15 '24 21:02 ZhouZhengCarlos