From 704d22d35a9e5a58032bb455523f1a70678f876a Mon Sep 17 00:00:00 2001 From: Anastasiia Balenko Date: Wed, 8 Jul 2026 14:45:45 +0100 Subject: [PATCH 1/3] unskip test --- dotcom-rendering/playwright/tests/banner.e2e.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotcom-rendering/playwright/tests/banner.e2e.spec.ts b/dotcom-rendering/playwright/tests/banner.e2e.spec.ts index 830c2f02899..eec4277d670 100644 --- a/dotcom-rendering/playwright/tests/banner.e2e.spec.ts +++ b/dotcom-rendering/playwright/tests/banner.e2e.spec.ts @@ -178,7 +178,7 @@ test.describe('Banner browserId targeting', function () { }); // Skip this test because it doesn't work in the github actions run. It does however work locally - test.skip('does not send browserId when user has not consented, even if in the auxia variant', async ({ + test('does not send browserId when user has not consented, even if in the auxia variant', async ({ page, context, }) => { From 8306b5a277e71339ab36439aba17f6cf4fcbbe7e Mon Sep 17 00:00:00 2001 From: Anastasiia Balenko Date: Thu, 9 Jul 2026 10:07:36 +0100 Subject: [PATCH 2/3] CMP ready gate added --- .../playwright/tests/banner.e2e.spec.ts | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/dotcom-rendering/playwright/tests/banner.e2e.spec.ts b/dotcom-rendering/playwright/tests/banner.e2e.spec.ts index eec4277d670..813bb7c9a4d 100644 --- a/dotcom-rendering/playwright/tests/banner.e2e.spec.ts +++ b/dotcom-rendering/playwright/tests/banner.e2e.spec.ts @@ -16,6 +16,50 @@ const ARTICLE_PATH = '/Article/https://www.theguardian.com/politics/2019/nov/20/jeremy-corbyn-boris-johnson-tv-debate-watched-by-67-million-people'; const RR_BANNER_URL = 'https://contributions.guardianapis.com/banner'; +const isCmpReady = async (page: Page, timeoutMs = 5000): Promise => { + const result = await page + .evaluate( + ({ timeoutMs: timeout }) => + new Promise((resolve) => { + const start = Date.now(); + type TcfApi = ( + command: string, + version: number, + callback: (ping: unknown, success: boolean) => void, + ) => void; + + const check = () => { + const tcfApi = ( + window as unknown as Record + )['__tcfapi']; + + if (typeof tcfApi !== 'function') { + if (Date.now() - start >= timeout) { + resolve(false); + return; + } + setTimeout(check, 100); + return; + } + + (tcfApi as TcfApi)( + 'ping', + 2, + (_ping: unknown, pingSuccess: boolean) => { + resolve(pingSuccess); + }, + ); + }; + + check(); + }), + { timeoutMs }, + ) + .catch(() => false); + + return result; +}; + const requestBodyHasProperties = ( request: Request, url: string | RegExp, @@ -149,6 +193,12 @@ test.describe('Banner browserId targeting', function () { preventSupportBanner: false, }); + const cmpReady = await isCmpReady(page); + expect( + cmpReady, + 'CMP should be ready before running banner consent assertions.', + ).toBe(true); + if (acceptConsent) { await cmpAcceptAll(page); } else { @@ -177,7 +227,6 @@ test.describe('Banner browserId targeting', function () { expect(browserId).toBe('test-browser-id'); }); - // Skip this test because it doesn't work in the github actions run. It does however work locally test('does not send browserId when user has not consented, even if in the auxia variant', async ({ page, context, From c9b1c7ad2eae196efbaee47afe402c7422d5b7b1 Mon Sep 17 00:00:00 2001 From: Anastasiia Balenko Date: Thu, 9 Jul 2026 13:48:40 +0100 Subject: [PATCH 3/3] force geo-location for banner e2e tests --- .../playwright/tests/banner.e2e.spec.ts | 68 +++++-------------- 1 file changed, 18 insertions(+), 50 deletions(-) diff --git a/dotcom-rendering/playwright/tests/banner.e2e.spec.ts b/dotcom-rendering/playwright/tests/banner.e2e.spec.ts index 813bb7c9a4d..0715aaed426 100644 --- a/dotcom-rendering/playwright/tests/banner.e2e.spec.ts +++ b/dotcom-rendering/playwright/tests/banner.e2e.spec.ts @@ -16,50 +16,6 @@ const ARTICLE_PATH = '/Article/https://www.theguardian.com/politics/2019/nov/20/jeremy-corbyn-boris-johnson-tv-debate-watched-by-67-million-people'; const RR_BANNER_URL = 'https://contributions.guardianapis.com/banner'; -const isCmpReady = async (page: Page, timeoutMs = 5000): Promise => { - const result = await page - .evaluate( - ({ timeoutMs: timeout }) => - new Promise((resolve) => { - const start = Date.now(); - type TcfApi = ( - command: string, - version: number, - callback: (ping: unknown, success: boolean) => void, - ) => void; - - const check = () => { - const tcfApi = ( - window as unknown as Record - )['__tcfapi']; - - if (typeof tcfApi !== 'function') { - if (Date.now() - start >= timeout) { - resolve(false); - return; - } - setTimeout(check, 100); - return; - } - - (tcfApi as TcfApi)( - 'ping', - 2, - (_ping: unknown, pingSuccess: boolean) => { - resolve(pingSuccess); - }, - ); - }; - - check(); - }), - { timeoutMs }, - ) - .catch(() => false); - - return result; -}; - const requestBodyHasProperties = ( request: Request, url: string | RegExp, @@ -102,6 +58,11 @@ test.describe('The banner', function () { waitUntil: 'domcontentloaded', region: 'GB', preventSupportBanner: false, + overrides: { + switchOverrides: { + consentManagement: true, + }, + }, }); await cmpAcceptAll(page); @@ -191,14 +152,15 @@ test.describe('Banner browserId targeting', function () { waitUntil: 'domcontentloaded', region: 'GB', preventSupportBanner: false, + overrides: { + switchOverrides: { + consentManagement: true, + }, + }, + queryParamsOn: true, + queryParams: { _sp_geo_override: 'GB-XX' }, }); - const cmpReady = await isCmpReady(page); - expect( - cmpReady, - 'CMP should be ready before running banner consent assertions.', - ).toBe(true); - if (acceptConsent) { await cmpAcceptAll(page); } else { @@ -238,6 +200,12 @@ test.describe('Banner browserId targeting', function () { inAuxiaVariant: true, }); + // CI/CD runs these tests with US geolocation, and fixing the origin to GB in loadPage is not enough for CMP initialization to conclude that the country is GDPR-applied. + // If gdprApplies is false, TCData is allowed to be minimal. If GDPR does not apply to this user in this context then only gdprApplies, tcfPolicyVersion, cmpId and cmpVersion shall exist in the object. (If GDPR does not apply to this user in this context then only gdprApplies, tcfPolicyVersion, cmpId and cmpVersion shall exist in the object.) + // @Guardian/content-management-platform uses the _sp_geo_override query parameter to override geo location in non-production environments. + const currentUrl = new URL(page.url()); + expect(currentUrl.searchParams.get('_sp_geo_override')).toBe('GB-XX'); + const browserId = getBannerRequestField( bannerRequest, RR_BANNER_URL,