diff --git a/packages/fingerprint-injector/src/fingerprint-injector.ts b/packages/fingerprint-injector/src/fingerprint-injector.ts index 41a0353d..8ed4f82c 100644 --- a/packages/fingerprint-injector/src/fingerprint-injector.ts +++ b/packages/fingerprint-injector/src/fingerprint-injector.ts @@ -62,6 +62,7 @@ export class FingerprintInjector { ): Record { const requestHeaders = [ 'accept-encoding', + 'accept-language', 'accept', 'cache-control', 'pragma', @@ -341,10 +342,11 @@ export async function newInjectedContext( options?.fingerprint ?? generator.getFingerprint(options?.fingerprintOptions); - const { fingerprint, headers } = fingerprintWithHeaders; + const { fingerprint } = fingerprintWithHeaders; const context = await browser.newContext({ userAgent: fingerprint.navigator.userAgent, colorScheme: 'dark', + locale: fingerprint.navigator.language, ...options?.newContextOptions, viewport: { width: fingerprint.screen.width, @@ -352,7 +354,6 @@ export async function newInjectedContext( ...options?.newContextOptions?.viewport, }, extraHTTPHeaders: { - 'accept-language': headers['accept-language'], ...options?.newContextOptions?.extraHTTPHeaders, }, }); diff --git a/test/fingerprint-injector/fingerprint-injector.test.ts b/test/fingerprint-injector/fingerprint-injector.test.ts index 59b0c4b7..f1bec796 100644 --- a/test/fingerprint-injector/fingerprint-injector.test.ts +++ b/test/fingerprint-injector/fingerprint-injector.test.ts @@ -17,6 +17,7 @@ import { describe, expect, test, + vi, beforeEach, afterAll, beforeAll, @@ -91,6 +92,57 @@ describe('FingerprintInjector', () => { // eslint-disable-next-line dot-notation expect(fpInjector['utilsJs']).toBeTruthy(); }); + + test('does not inject accept-language as an extra HTTP header', () => { + const filteredHeaders = fpInjector['onlyInjectableHeaders']({ + 'accept-language': 'cs-CZ,cs;q=0.9', + 'user-agent': 'Mozilla/5.0 Test', + }); + + expect(filteredHeaders).not.toHaveProperty('accept-language'); + expect(filteredHeaders['user-agent']).toBe('Mozilla/5.0 Test'); + }); + + test('creates Playwright contexts with native locale instead of injected accept-language', async () => { + const fingerprintWithHeaders = new FingerprintGenerator({ + devices: ['desktop'], + operatingSystems: ['linux'], + browsers: [{ name: 'chrome', minVersion: 90 }], + locales: ['cs-CZ'], + }).getFingerprint(); + const setExtraHTTPHeaders = vi.fn(); + const context = { + browser: () => ({ + browserType: () => ({ + name: () => 'chromium', + }), + }), + setExtraHTTPHeaders, + on: vi.fn(), + addInitScript: vi.fn(), + } as unknown as import('playwright').BrowserContext; + const newContext = vi.fn().mockResolvedValue(context); + const browser = { + newContext, + } as unknown as PWBrowser; + + await newInjectedContext(browser, { + fingerprint: fingerprintWithHeaders, + }); + + const newContextOptions = newContext.mock.calls[0][0]; + + expect(newContextOptions.locale).toBe( + fingerprintWithHeaders.fingerprint.navigator.language, + ); + expect(newContextOptions.extraHTTPHeaders).not.toHaveProperty( + 'accept-language', + ); + expect(setExtraHTTPHeaders.mock.calls[0][0]).not.toHaveProperty( + 'accept-language', + ); + }); + // @ts-expect-error test only describe.each(cases)('%s', (frameworkName, testCases) => { // @ts-expect-error test only @@ -368,13 +420,6 @@ describe('FingerprintInjector', () => { }); test('should override locales', async () => { - response = await page.goto(`https://crawlee.dev`); - const requestHeaders = response.request().headers(); - - expect( - requestHeaders['accept-language']?.includes('cs'), - ).toBe(true); - const { navigator: { language }, } = fingerprint;