1

How can I set the Accept-Language header for one test call in Playwright ?

E.g.:

import { test, expect } from '@playwright/test';

test( 'language is interpreted correctly', async function({ page, context }) {

    // -----
    // HERE: Set the `Accept-Language` header to 'de-DE,de;q=0.9,en;q=0.8' somehow ?
    // -----
    
    const response = await page.goto( 'http://example.com' );
    const acceptLanguageHeader = await response.request().headerValue('Accept-Language');
    expect( acceptLanguageHeader ).toBe( 'de-DE,de;q=0.9,en;q=0.8' );
    expect( somethingThatDependsOnTheLanguage ).toBe( true );
});

What I found, which doesn't work:

I know I can set extra headers with page.setExtraHTTPHeaders(), but that apparently doesn't overwrite the Accept-Language header.

I know I can configure TestOptions with:

but I want to test different settings in each test() call.

E.g. this doesn't work:

test( 'try modified accept-language header', async function({ page, context }) {

    await context.setExtraHTTPHeaders({
        'Accept-Language': 'de-DE,de;q=0.9,en;q=0.8',
        'some-extra-header': 'some extra header value from context',
    });

    await page.setExtraHTTPHeaders({
        'Accept-Language': 'de-DE,de;q=0.9,en;q=0.8',
        'some-extra-header': 'some extra header value from page',
    });

    const response = await page.goto( 'http://example.com' );

    console.log('headers:', response.request().headers()); // <-- 'accept-language' is 'en-US',

    const acceptLanguageHeader = await response.request().headerValue('Accept-Language');
    expect( acceptLanguageHeader ).toBe( 'de-DE,de;q=0.9,en;q=0.8' ); // <-- Received: "en-US"
});

I have seen the answers to "How to add custom headers ..." and "How to change default language ..." and other examples, but

  • they are creating their own browser and browser.context (like const context = await browser.newContext( ... )), and
  • they are not using a test call, and
  • don't show where they get the browser instance from.
  • (Probably they are not using the playwright test-runner. I don't know how they are running their tests)
kca
  • 4,856
  • 1
  • 20
  • 41

1 Answers1

0

You can use browserContext.route() to modify network requests in each test individually.

E.g.:

test( 'Example for browserContext.route()', async function({ page, context }) {

    // -- modify the request
    await context.route('**/*', (route, request) => {
        route.continue({
            headers: {
                ...request.headers(),
                'accept-language': 'de-DE,de;q=0.9,en;q=0.8',
            }
        });
    });

    // -- navigate
    await page.goto( urlOfMyWebsite );
    
    // -- test if language of accept-header is correctly used
    expect( someContent ).toBe( translatedToGerman );
});

RegExp is also allowed to match the url, e.g.:

await context.route(/^\/[-a-z]+$/, (route, request) => { ...

Note that the header name seems to be case-sensitive, and might behave weird. I found different tests behave in different ways, for example (I could not always reproduce this in different environments):

  • setting only 'Accept-Language': 'de-DE' might result in e.g. Received: "en-US, de-DE".
  • setting both: 'Accept-Language': 'de-DE', 'accept-language': 'de-DE' might result in Received: "de-DE, de-DE".
kca
  • 4,856
  • 1
  • 20
  • 41