@duckduckgo/autoconsent 16.58.0 → 16.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/lib/regional-testing/harness.mjs +4 -172
- package/.agents/skills/oxylabs-testing/SKILL.md +4 -4
- package/.agents/skills/oxylabs-testing/scripts/oxylabs.mjs +17 -164
- package/.agents/skills/oxylabs-testing/scripts/oxylabs.test.mjs +6 -3
- package/.agents/skills/verify-pr/SKILL.md +1 -1
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +176 -0
- package/Jenkinsfile +36 -1
- package/dist/addon-firefox/background.bundle.js +22 -1
- package/dist/addon-firefox/compact-rules.json +1 -1
- package/dist/addon-firefox/content.bundle.js +253 -93
- package/dist/addon-firefox/manifest.json +1 -1
- package/dist/addon-firefox/popup.bundle.js +1 -1
- package/dist/addon-firefox/rule-index.json +1 -1
- package/dist/addon-firefox/rules.json +1 -1
- package/dist/addon-mv3/background.bundle.js +22 -1
- package/dist/addon-mv3/compact-rules.json +1 -1
- package/dist/addon-mv3/content.bundle.js +253 -93
- package/dist/addon-mv3/manifest.json +1 -1
- package/dist/addon-mv3/popup.bundle.js +1 -1
- package/dist/addon-mv3/rule-index.json +1 -1
- package/dist/addon-mv3/rules.json +1 -1
- package/dist/autoconsent.cjs.js +253 -93
- package/dist/autoconsent.esm.js +253 -93
- package/dist/autoconsent.playwright.js +253 -93
- package/dist/autoconsent.standalone.js +254 -94
- package/dist/heuristics.cjs.js +29 -3
- package/dist/heuristics.mjs +28 -3
- package/dist/types/cmps/onetrust.d.ts +1 -0
- package/dist/types/eval-snippets.d.ts +3 -0
- package/dist/types/heuristic-classify.d.ts +1 -0
- package/dist/types/heuristics.d.ts +10 -1
- package/lib/cmps/onetrust.ts +15 -0
- package/lib/eval-snippets.ts +21 -0
- package/lib/heuristic-classify.ts +6 -0
- package/lib/heuristic-patterns.ts +26 -1
- package/lib/heuristics.ts +256 -104
- package/package.json +4 -6
- package/playwright/isolated-world.mjs +217 -0
- package/playwright/oxylabs.mjs +196 -0
- package/playwright/runner.ts +183 -39
- package/playwright.config.ts +4 -1
- package/rules/autoconsent/123inkt.json +9 -0
- package/rules/autoconsent/aeolservice.json +39 -0
- package/rules/autoconsent/amazon-music.json +13 -0
- package/rules/autoconsent/animatetimes.json +34 -0
- package/rules/autoconsent/annunci69.json +19 -0
- package/rules/autoconsent/arbeidsplassen-nav-no.json +33 -0
- package/rules/autoconsent/asahi-interactive.json +30 -0
- package/rules/autoconsent/att.json +36 -0
- package/rules/autoconsent/auctionet.json +39 -0
- package/rules/autoconsent/autodoc.json +18 -0
- package/rules/autoconsent/avada-privacy-bar-cosmetic.json +28 -0
- package/rules/autoconsent/avada-privacy-bar.json +70 -0
- package/rules/autoconsent/axesor.json +13 -0
- package/rules/autoconsent/bbc.com-orb-cosmetic.json +34 -0
- package/rules/autoconsent/bbc.com.json +8 -5
- package/rules/autoconsent/blitzrechner.json +16 -0
- package/rules/autoconsent/bokadirekt.se.json +50 -0
- package/rules/autoconsent/bouvet-cookiepanel.json +29 -0
- package/rules/autoconsent/brainsum-cookieconsent.json +25 -0
- package/rules/autoconsent/bwr-cookie.json +13 -0
- package/rules/autoconsent/capitalone-ca.json +13 -0
- package/rules/autoconsent/carpetaciudadana.json +51 -0
- package/rules/autoconsent/cf-gdpr-cookie-consent.json +23 -0
- package/rules/autoconsent/chatgpt.json +3 -3
- package/rules/autoconsent/cksmodal.json +9 -0
- package/rules/autoconsent/consent-studio.json +41 -0
- package/rules/autoconsent/cookie-popup-cookieno.json +29 -0
- package/rules/autoconsent/cookie-popup-cookieok.json +25 -0
- package/rules/autoconsent/cookielegit.json +21 -0
- package/rules/autoconsent/cookieman.json +23 -4
- package/rules/autoconsent/cookieprompter.json +21 -0
- package/rules/autoconsent/cookiereports.json +10 -0
- package/rules/autoconsent/cookietractor.json +37 -0
- package/rules/autoconsent/danskebank.json +17 -0
- package/rules/autoconsent/de-volksbank.json +14 -0
- package/rules/autoconsent/dintel.json +13 -0
- package/rules/autoconsent/dpgmedia-nl.json +20 -8
- package/rules/autoconsent/e-grip.json +63 -0
- package/rules/autoconsent/eccmm.json +30 -0
- package/rules/autoconsent/england-nhs-uk.json +18 -0
- package/rules/autoconsent/eon.pl.json +18 -0
- package/rules/autoconsent/erdee-media.json +24 -0
- package/rules/autoconsent/eroticiracconti-it.json +13 -0
- package/rules/autoconsent/ersatzteile-24.json +49 -0
- package/rules/autoconsent/escorteintime.json +15 -0
- package/rules/autoconsent/gays-cruising.json +18 -0
- package/rules/autoconsent/gov-pl-cookies-info.json +28 -0
- package/rules/autoconsent/gravito.json +23 -16
- package/rules/autoconsent/grupa-pracuj.json +73 -0
- package/rules/autoconsent/grupa-rmf.json +21 -0
- package/rules/autoconsent/gsb-cookiebanner-selection.json +12 -0
- package/rules/autoconsent/gwo.json +53 -0
- package/rules/autoconsent/hacon-next-gen.json +41 -0
- package/rules/autoconsent/hsbc-au.json +35 -0
- package/rules/autoconsent/ign-es.json +35 -0
- package/rules/autoconsent/impress-co-jp.json +10 -0
- package/rules/autoconsent/ing-de.json +31 -0
- package/rules/autoconsent/interia.json +1 -4
- package/rules/autoconsent/intesasanpaolo.json +37 -0
- package/rules/autoconsent/iworks-footer-notice.json +19 -0
- package/rules/autoconsent/jobindex.json +40 -0
- package/rules/autoconsent/juzaphoto.json +13 -0
- package/rules/autoconsent/kaspersky-cookies-notification.json +9 -0
- package/rules/autoconsent/lantmateriet.json +13 -0
- package/rules/autoconsent/leukhuis-nl.json +35 -0
- package/rules/autoconsent/lg-cookiecontrol.json +16 -0
- package/rules/autoconsent/libris.nl.json +19 -0
- package/rules/autoconsent/lineagrafica-reject.json +32 -0
- package/rules/autoconsent/mainichi.json +39 -0
- package/rules/autoconsent/mango.json +56 -0
- package/rules/autoconsent/matemaks.json +29 -0
- package/rules/autoconsent/merito.pl.json +44 -0
- package/rules/autoconsent/minitool.json +31 -0
- package/rules/autoconsent/miteco.json +41 -0
- package/rules/autoconsent/mobile-de.json +13 -0
- package/rules/autoconsent/mq-edu-au.json +26 -0
- package/rules/autoconsent/nederlandseloterij.json +35 -0
- package/rules/autoconsent/nordea.json +21 -0
- package/rules/autoconsent/nordnet.json +33 -0
- package/rules/autoconsent/nowaera.json +44 -0
- package/rules/autoconsent/ok.json +4 -12
- package/rules/autoconsent/olvg.json +45 -0
- package/rules/autoconsent/onlineradiobox.json +35 -0
- package/rules/autoconsent/optyczne-pl.json +28 -0
- package/rules/autoconsent/orbys.json +35 -0
- package/rules/autoconsent/payfip.json +36 -0
- package/rules/autoconsent/pdf24.json +48 -0
- package/rules/autoconsent/pe-cookies.json +30 -0
- package/rules/autoconsent/pekao24.json +33 -0
- package/rules/autoconsent/pensionsmyndigheten.json +13 -0
- package/rules/autoconsent/praca-pl.json +17 -0
- package/rules/autoconsent/pro-euclp-cookies-box.json +31 -0
- package/rules/autoconsent/pubfactory.json +45 -0
- package/rules/autoconsent/puesc-gov-pl.json +37 -0
- package/rules/autoconsent/rambler.json +30 -0
- package/rules/autoconsent/rejestr-io.json +36 -0
- package/rules/autoconsent/remove-cookie-notice.json +18 -0
- package/rules/autoconsent/rijksoverheid-notification-bar.json +34 -0
- package/rules/autoconsent/route-inn.json +13 -0
- package/rules/autoconsent/schumacher.com.json +53 -0
- package/rules/autoconsent/sedlak-gdpr-cookie.json +10 -0
- package/rules/autoconsent/seniorweb.json +42 -0
- package/rules/autoconsent/shouldianswer.json +14 -0
- package/rules/autoconsent/shueisha-gigaviewer.json +10 -0
- package/rules/autoconsent/sitevision.json +18 -1
- package/rules/autoconsent/skatteverket-se.json +33 -0
- package/rules/autoconsent/smile-insurances.json +13 -0
- package/rules/autoconsent/snb.ch.json +18 -0
- package/rules/autoconsent/sujetdebac.fr.json +10 -0
- package/rules/autoconsent/svt.se.json +7 -7
- package/rules/autoconsent/swisscom-ecare.json +31 -0
- package/rules/autoconsent/telegram-im.json +36 -0
- package/rules/autoconsent/temu.json +12 -16
- package/rules/autoconsent/thecode.json +21 -0
- package/rules/autoconsent/thomsonlocal.com.json +10 -0
- package/rules/autoconsent/todostuslibros.json +51 -0
- package/rules/autoconsent/turkishairlines.com.json +33 -0
- package/rules/autoconsent/uk-parliament.json +19 -0
- package/rules/autoconsent/usherbrooke.json +16 -0
- package/rules/autoconsent/vdg-cookies.json +36 -0
- package/rules/autoconsent/warszawa19115.pl.json +52 -0
- package/rules/autoconsent/wirtualna-polska.json +41 -0
- package/rules/autoconsent/wojsko-polskie-pl.json +28 -0
- package/rules/autoconsent/xenforo-cookie-consent.json +62 -0
- package/rules/autoconsent/xtb.json +18 -0
- package/rules/autoconsent/zorginstituut-cookiewarning.json +33 -0
- package/rules/autoconsent/zurich-cookies-notification-banner.json +17 -0
- package/rules/compact-rules.json +1 -1
- package/rules/rule-index.json +1 -1
- package/rules/rules.json +1 -1
- package/tests/123inkt.spec.ts +5 -0
- package/tests/aeolservice.spec.ts +5 -0
- package/tests/amazon-music.spec.ts +9 -0
- package/tests/animatetimes.spec.ts +3 -0
- package/tests/annunci69.spec.ts +5 -0
- package/tests/arbeidsplassen-nav-no.spec.ts +3 -0
- package/tests/asahi-interactive.spec.ts +6 -0
- package/tests/att.spec.ts +3 -0
- package/tests/auctionet.spec.ts +3 -0
- package/tests/autodoc.spec.ts +8 -0
- package/tests/avada-privacy-bar-cosmetic.spec.ts +3 -0
- package/tests/avada-privacy-bar.spec.ts +12 -0
- package/tests/axesor.spec.ts +3 -0
- package/tests/bbc.com-orb-cosmetic.spec.ts +8 -0
- package/tests/bbc.com.spec.ts +11 -9
- package/tests/blitzrechner.spec.ts +3 -0
- package/tests/bokadirekt.se.spec.ts +3 -0
- package/tests/bouvet-cookiepanel.spec.ts +9 -0
- package/tests/brainsum-cookieconsent.spec.ts +9 -0
- package/tests/bwr-cookie.spec.ts +3 -0
- package/tests/capitalone-ca.spec.ts +3 -0
- package/tests/carpetaciudadana.spec.ts +6 -0
- package/tests/cf-gdpr-cookie-consent.spec.ts +3 -0
- package/tests/chatgpt.spec.ts +3 -1
- package/tests/cksmodal.spec.ts +3 -0
- package/tests/consent-studio.spec.ts +15 -0
- package/tests/cookie-popup-cookieno.spec.ts +8 -0
- package/tests/cookie-popup-cookieok.spec.ts +9 -0
- package/tests/cookiebot.spec.ts +1 -0
- package/tests/cookielegit.spec.ts +3 -0
- package/tests/cookieman.spec.ts +1 -0
- package/tests/cookieprompter.spec.ts +9 -0
- package/tests/cookiereports.spec.ts +13 -0
- package/tests/cookietractor.spec.ts +12 -0
- package/tests/danskebank.spec.ts +12 -0
- package/tests/de-volksbank.spec.ts +5 -0
- package/tests/dintel.spec.ts +10 -0
- package/tests/dpgmedia-nl.spec.ts +15 -1
- package/tests/e-grip.spec.ts +8 -0
- package/tests/eccmm.spec.ts +6 -0
- package/tests/england-nhs-uk.spec.ts +3 -0
- package/tests/eon.pl.spec.ts +3 -0
- package/tests/erdee-media.spec.ts +3 -0
- package/tests/eroticiracconti-it.spec.ts +3 -0
- package/tests/ersatzteile-24.spec.ts +6 -0
- package/tests/escorteintime.spec.ts +3 -0
- package/tests/gays-cruising.spec.ts +3 -0
- package/tests/gov-pl-cookies-info.spec.ts +3 -0
- package/tests/gravito.spec.ts +7 -1
- package/tests/grupa-pracuj.spec.ts +8 -0
- package/tests/grupa-rmf.spec.ts +5 -0
- package/tests/gsb-cookiebanner-selection.spec.ts +7 -0
- package/tests/gwo.spec.ts +6 -0
- package/tests/hacon-next-gen.spec.ts +6 -0
- package/tests/hsbc-au.spec.ts +6 -0
- package/tests/ign-es.spec.ts +3 -0
- package/tests/impress-co-jp.spec.ts +8 -0
- package/tests/ing-de.spec.ts +3 -0
- package/tests/interia.spec.ts +1 -1
- package/tests/intesasanpaolo.spec.ts +3 -0
- package/tests/iworks-footer-notice.spec.ts +3 -0
- package/tests/jobindex.spec.ts +3 -0
- package/tests/juzaphoto.spec.ts +7 -0
- package/tests/kaspersky-cookies-notification.spec.ts +8 -0
- package/tests/lantmateriet.spec.ts +3 -0
- package/tests/leukhuis-nl.spec.ts +3 -0
- package/tests/lg-cookiecontrol.spec.ts +10 -0
- package/tests/libris.nl.spec.ts +3 -0
- package/tests/lineagrafica-reject.spec.ts +8 -0
- package/tests/mainichi.spec.ts +10 -0
- package/tests/mango.spec.ts +3 -0
- package/tests/matemaks.spec.ts +3 -0
- package/tests/merito.pl.spec.ts +3 -0
- package/tests/minitool.spec.ts +8 -0
- package/tests/miteco.spec.ts +8 -0
- package/tests/mobile-de.spec.ts +3 -0
- package/tests/mq-edu-au.spec.ts +3 -0
- package/tests/nederlandseloterij.spec.ts +9 -0
- package/tests/nordea.spec.ts +6 -0
- package/tests/nordnet.spec.ts +8 -0
- package/tests/nowaera.spec.ts +3 -0
- package/tests/olvg.spec.ts +6 -0
- package/tests/onlineradiobox.spec.ts +5 -0
- package/tests/optyczne-pl.spec.ts +3 -0
- package/tests/orbys.spec.ts +3 -0
- package/tests/payfip.spec.ts +3 -0
- package/tests/pdf24.spec.ts +3 -0
- package/tests/pe-cookies.spec.ts +6 -0
- package/tests/pekao24.spec.ts +3 -0
- package/tests/pensionsmyndigheten.spec.ts +3 -0
- package/tests/praca-pl.spec.ts +3 -0
- package/tests/pro-euclp-cookies-box.spec.ts +8 -0
- package/tests/pubfactory.spec.ts +10 -0
- package/tests/puesc-gov-pl.spec.ts +3 -0
- package/tests/rambler.spec.ts +3 -0
- package/tests/rejestr-io.spec.ts +3 -0
- package/tests/remove-cookie-notice.spec.ts +3 -0
- package/tests/rijksoverheid-notification-bar.spec.ts +3 -0
- package/tests/route-inn.spec.ts +3 -0
- package/tests/schumacher.com.spec.ts +6 -0
- package/tests/sedlak-gdpr-cookie.spec.ts +6 -0
- package/tests/seniorweb.spec.ts +3 -0
- package/tests/shouldianswer.spec.ts +8 -0
- package/tests/shueisha-gigaviewer.spec.ts +3 -0
- package/tests/sitevision-cookie-consent.spec.ts +1 -0
- package/tests/sitevision.spec.ts +7 -0
- package/tests/skatteverket-se.spec.ts +3 -0
- package/tests/smile-insurances.spec.ts +6 -0
- package/tests/snb.ch.spec.ts +3 -0
- package/tests/sujetdebac.fr.spec.ts +3 -0
- package/tests/svt.se.spec.ts +1 -3
- package/tests/swisscom-ecare.spec.ts +7 -0
- package/tests/telegram-im.spec.ts +6 -0
- package/tests/temu.spec.ts +3 -1
- package/tests/thecode.spec.ts +3 -0
- package/tests/thomsonlocal.com.spec.ts +3 -0
- package/tests/todostuslibros.spec.ts +3 -0
- package/tests/turkishairlines.com.spec.ts +3 -0
- package/tests/uk-parliament.spec.ts +8 -0
- package/tests/usherbrooke.spec.ts +6 -0
- package/tests/vdg-cookies.spec.ts +8 -0
- package/tests/warszawa19115.pl.spec.ts +3 -0
- package/tests/wirtualna-polska.spec.ts +8 -0
- package/tests/wojsko-polskie-pl.spec.ts +3 -0
- package/tests/xenforo-cookie-consent.spec.ts +6 -0
- package/tests/xtb.spec.ts +3 -0
- package/tests/zorginstituut-cookiewarning.spec.ts +10 -0
- package/tests/zurich-cookies-notification-banner.spec.ts +3 -0
- package/tests-wtr/heuristics/get-potential-popups.test.ts +330 -9
- package/tests-wtr/heuristics/heuristics-utils.test.ts +98 -0
- package/rules/autoconsent/twitter.json +0 -34
- package/rules/generated/auto_CH_autodoc.de_krd.json +0 -40
- package/rules/generated/auto_CH_svtplay.se_d39.json +0 -40
- package/rules/generated/auto_GB_parliamentlive.tv_r3v.json +0 -28
- package/rules/generated/auto_NL_asnbank.nl_e28.json +0 -40
- package/rules/generated/auto_NL_eurojackpot.nederlandseloterij.nl_7hr.json +0 -40
- package/rules/generated/auto_NL_lotto.nederlandseloterij.nl_7c8.json +0 -40
- package/rules/generated/auto_NL_nederlandseloterij.nl_b60.json +0 -40
- package/rules/generated/auto_NL_staatsloterij.nederlandseloterij.nl_197.json +0 -40
- package/rules/generated/auto_NO_arronet.se_vo5.json +0 -40
- package/rules/generated/auto_NO_liseberg.se_qy4.json +0 -40
- package/rules/generated/auto_NO_nordnet.se_2en.json +0 -40
- package/rules/generated/auto_NO_regeringen.se_uhv.json +0 -40
- package/rules/generated/auto_NO_svtplay.se_ujn.json +0 -40
- package/rules/generated/auto_NO_uu.se_eea.json +0 -40
- package/tests/generated/auto_CH_autodoc.de_krd.spec.ts +0 -2
- package/tests/generated/auto_CH_svtplay.se_d39.spec.ts +0 -2
- package/tests/generated/auto_GB_parliamentlive.tv_r3v.spec.ts +0 -6
- package/tests/generated/auto_NL_asnbank.nl_e28.spec.ts +0 -6
- package/tests/generated/auto_NL_eurojackpot.nederlandseloterij.nl_7hr.spec.ts +0 -6
- package/tests/generated/auto_NL_lotto.nederlandseloterij.nl_7c8.spec.ts +0 -6
- package/tests/generated/auto_NL_nederlandseloterij.nl_b60.spec.ts +0 -6
- package/tests/generated/auto_NL_staatsloterij.nederlandseloterij.nl_197.spec.ts +0 -6
- package/tests/generated/auto_NO_arronet.se_vo5.spec.ts +0 -2
- package/tests/generated/auto_NO_liseberg.se_qy4.spec.ts +0 -2
- package/tests/generated/auto_NO_nordnet.se_2en.spec.ts +0 -2
- package/tests/generated/auto_NO_regeringen.se_uhv.spec.ts +0 -6
- package/tests/generated/auto_NO_svtplay.se_ujn.spec.ts +0 -2
- package/tests/generated/auto_NO_uu.se_eea.spec.ts +0 -2
- package/tests/twitter.spec.ts +0 -10
package/playwright/runner.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { test, expect, Page, Frame, TestInfo } from '@playwright/test';
|
|
5
|
-
import { waitFor } from '../lib/utils';
|
|
4
|
+
import { test as base, expect, Page, Frame, TestInfo, Response } from '@playwright/test';
|
|
6
5
|
import { ContentScriptMessage } from '../lib/messages';
|
|
7
6
|
import { AutoAction, RuleBundle } from '../lib/types';
|
|
8
7
|
import { filterCompactRules } from '../lib/encoding';
|
|
@@ -10,6 +9,8 @@ import compactRules from '../rules/compact-rules.json';
|
|
|
10
9
|
// Full rules include optIn steps that compact rules intentionally omit.
|
|
11
10
|
// We need both formats: compact for optOut tests, full for optIn tests.
|
|
12
11
|
import { autoconsent as fullRules } from '../rules/rules.json';
|
|
12
|
+
import { injectIntoIsolatedWorld } from './isolated-world.mjs';
|
|
13
|
+
import { connectOxylabs, createCaptchaTracker } from './oxylabs.mjs';
|
|
13
14
|
|
|
14
15
|
const LOG_MESSAGES: ContentScriptMessage['type'][] = process.env.CI
|
|
15
16
|
? []
|
|
@@ -17,8 +18,53 @@ const LOG_MESSAGES: ContentScriptMessage['type'][] = process.env.CI
|
|
|
17
18
|
const LOG_PAGE_LOGS = false;
|
|
18
19
|
|
|
19
20
|
const testRegion = (process.env.REGION || 'NA').trim();
|
|
21
|
+
|
|
22
|
+
// OXYLABS=1 runs each test in a fresh Oxylabs Agent Browser session in REGION instead of a local browser.
|
|
23
|
+
const useOxylabs = process.env.OXYLABS === '1';
|
|
24
|
+
// Local runs list the tests that failed on a bot wall here; Oxylabs runs only define the listed tests.
|
|
25
|
+
const oxylabsCandidatesFile = process.env.OXYLABS_CANDIDATES;
|
|
26
|
+
const oxylabsCandidates = useOxylabs && oxylabsCandidatesFile ? readOxylabsCandidates(oxylabsCandidatesFile) : null;
|
|
27
|
+
const recordOxylabsCandidates = !useOxylabs && !!oxylabsCandidatesFile;
|
|
28
|
+
// Pages load slower through remote Oxylabs sessions, so detection gets a longer window there.
|
|
29
|
+
const detectionSlowdown = useOxylabs ? 2 : 1;
|
|
30
|
+
// Status codes that bot protection answers with; other errors (404, 5xx) point to a stale spec URL instead.
|
|
31
|
+
const BOT_WALL_STATUSES = [401, 403, 429, 503];
|
|
32
|
+
// Navigation errors of a dead or misconfigured site rather than a blocked one.
|
|
33
|
+
const DEAD_SITE_ERRORS = /ERR_NAME_NOT_RESOLVED|ERR_SOCKS_CONNECTION_FAILED|ERR_CONNECTION_REFUSED|ERR_ADDRESS_UNREACHABLE|ERR_CERT_/;
|
|
34
|
+
// Page titles of common bot-protection challenge and block pages.
|
|
35
|
+
const BOT_WALL_TITLE =
|
|
36
|
+
/just a moment|attention required|client challenge|access denied|access to this page has been denied|pardon our interruption|request unsuccessful|are you a robot|verify you are human|security check|captcha/i;
|
|
37
|
+
|
|
38
|
+
const test = useOxylabs
|
|
39
|
+
? base.extend({
|
|
40
|
+
page: async ({ browserName }, use) => {
|
|
41
|
+
if (browserName !== 'chromium') {
|
|
42
|
+
throw new Error('Oxylabs runs need a Chromium project');
|
|
43
|
+
}
|
|
44
|
+
const browser = await connectOxylabs(testRegion.toLowerCase());
|
|
45
|
+
try {
|
|
46
|
+
await use(await browser.newPage());
|
|
47
|
+
} finally {
|
|
48
|
+
await browser.close().catch(() => {});
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
: base;
|
|
20
53
|
test.describe.configure({ mode: 'parallel' });
|
|
21
54
|
|
|
55
|
+
// The CMP name keeps tests for the same site in different specs apart.
|
|
56
|
+
function oxylabsCandidateKey(cmp: string, testName: string) {
|
|
57
|
+
return `${cmp} › ${testName}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function readOxylabsCandidates(file: string) {
|
|
61
|
+
try {
|
|
62
|
+
return new Set(fs.readFileSync(file, 'utf8').split('\n').filter(Boolean));
|
|
63
|
+
} catch {
|
|
64
|
+
return new Set<string>();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
22
68
|
type TestOptions = {
|
|
23
69
|
testOptOut: boolean;
|
|
24
70
|
testSelfTest: boolean;
|
|
@@ -30,6 +76,13 @@ type TestOptions = {
|
|
|
30
76
|
expectedRuns: number;
|
|
31
77
|
gpc: boolean;
|
|
32
78
|
};
|
|
79
|
+
// A frame's content script, reached through either the isolated-world transport or a main-world Frame.
|
|
80
|
+
type ContentScriptTarget = {
|
|
81
|
+
send: (message: object) => Promise<unknown>;
|
|
82
|
+
evalInMainWorld: (code: string) => Promise<unknown>;
|
|
83
|
+
isMainFrame: boolean;
|
|
84
|
+
};
|
|
85
|
+
|
|
33
86
|
const defaultOptions: TestOptions = {
|
|
34
87
|
testOptOut: true,
|
|
35
88
|
testOptIn: true,
|
|
@@ -43,7 +96,7 @@ const defaultOptions: TestOptions = {
|
|
|
43
96
|
};
|
|
44
97
|
|
|
45
98
|
const contentScript = fs.readFileSync(path.join(__dirname, '../dist/autoconsent.playwright.js'), 'utf8');
|
|
46
|
-
const screenshotsDir = path.join(__dirname, '../test-results/screenshots');
|
|
99
|
+
const screenshotsDir = path.join(__dirname, '../test-results/screenshots', useOxylabs ? 'oxylabs' : '');
|
|
47
100
|
const deduplicatedRuleLookup = (
|
|
48
101
|
JSON.parse(fs.readFileSync(path.join(__dirname, '../rules/rules.json'), 'utf-8')) as RuleBundle
|
|
49
102
|
).autoconsent.reduce((acc, rule) => {
|
|
@@ -57,6 +110,7 @@ class TestRun {
|
|
|
57
110
|
page: Page;
|
|
58
111
|
testInfo: TestInfo;
|
|
59
112
|
url: string;
|
|
113
|
+
cmp: string;
|
|
60
114
|
expectedCmp: string;
|
|
61
115
|
options: TestOptions;
|
|
62
116
|
autoAction: AutoAction | null;
|
|
@@ -65,12 +119,16 @@ class TestRun {
|
|
|
65
119
|
formFactor: string;
|
|
66
120
|
received: ContentScriptMessage[] = [];
|
|
67
121
|
screenshotCounter = 0;
|
|
68
|
-
|
|
122
|
+
selfTestTarget: ContentScriptTarget | null = null;
|
|
123
|
+
response: Response | null = null;
|
|
124
|
+
// Oxylabs solves captchas on the page; waits pause while it does.
|
|
125
|
+
captcha = useOxylabs ? createCaptchaTracker() : null;
|
|
69
126
|
|
|
70
127
|
constructor(page: Page, testInfo: TestInfo, url: string, expectedCmp: string, options: TestOptions, autoAction: AutoAction | null) {
|
|
71
128
|
this.page = page;
|
|
72
129
|
this.testInfo = testInfo;
|
|
73
130
|
this.url = url;
|
|
131
|
+
this.cmp = expectedCmp;
|
|
74
132
|
// if a rule was deduplicated, update the expectation to the new deduplicate rule name
|
|
75
133
|
if (deduplicatedRuleLookup.has(expectedCmp)) {
|
|
76
134
|
this.expectedCmp = deduplicatedRuleLookup.get(expectedCmp)!;
|
|
@@ -94,15 +152,43 @@ class TestRun {
|
|
|
94
152
|
console.log(` page log:`, msg.text());
|
|
95
153
|
});
|
|
96
154
|
|
|
97
|
-
|
|
155
|
+
// Chromium runs the content script in an isolated world like the extension; other browsers have no CDP for that.
|
|
156
|
+
const useIsolatedWorld = this.page.context().browser()?.browserType().name() === 'chromium';
|
|
157
|
+
if (useIsolatedWorld) {
|
|
158
|
+
await injectIntoIsolatedWorld(
|
|
159
|
+
this.page,
|
|
160
|
+
(transport) => async (msg, frameRef) => {
|
|
161
|
+
if (this.captcha?.handleMessage(msg)) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
await this.messageCallback(msg, {
|
|
165
|
+
send: (message) => transport.sendToContentScript(frameRef, message),
|
|
166
|
+
evalInMainWorld: (code) => transport.evalInMainWorld(frameRef, code),
|
|
167
|
+
isMainFrame: transport.isMainFrame(frameRef),
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
contentScript,
|
|
171
|
+
this.captcha?.script,
|
|
172
|
+
);
|
|
173
|
+
} else {
|
|
174
|
+
await this.page.exposeBinding('autoconsentSendMessage', ({ frame }, msg: ContentScriptMessage) =>
|
|
175
|
+
this.messageCallback(msg, {
|
|
176
|
+
send: (message) => frame.evaluate(`autoconsentReceiveMessage(${JSON.stringify(message)})`),
|
|
177
|
+
evalInMainWorld: (code) => frame.evaluate(code),
|
|
178
|
+
isMainFrame: frame.parentFrame() === null,
|
|
179
|
+
}),
|
|
180
|
+
);
|
|
181
|
+
}
|
|
98
182
|
if (this.options.gpc) {
|
|
99
183
|
await this.enableGpc();
|
|
100
184
|
}
|
|
101
|
-
|
|
185
|
+
try {
|
|
186
|
+
this.response = await this.page.goto(this.url, { waitUntil: 'commit' });
|
|
102
187
|
|
|
103
|
-
|
|
188
|
+
if (!useIsolatedWorld) {
|
|
189
|
+
await this.injectContentScripts();
|
|
190
|
+
}
|
|
104
191
|
|
|
105
|
-
try {
|
|
106
192
|
await this.runAssertions();
|
|
107
193
|
} catch (e) {
|
|
108
194
|
if (e instanceof Error) {
|
|
@@ -115,6 +201,7 @@ class TestRun {
|
|
|
115
201
|
formFactor: this.formFactor,
|
|
116
202
|
testName: this.testInfo.title,
|
|
117
203
|
retry: this.testInfo.retry,
|
|
204
|
+
provider: useOxylabs ? 'oxylabs' : 'local',
|
|
118
205
|
};
|
|
119
206
|
// log the full url in the error message, this will be parsed by the review tool
|
|
120
207
|
console.error(`Autoconsent test failed on ${this.url} failure stats: ${JSON.stringify(failureStats)}`);
|
|
@@ -128,6 +215,34 @@ class TestRun {
|
|
|
128
215
|
}
|
|
129
216
|
}
|
|
130
217
|
|
|
218
|
+
// On the last attempt, list a failed test that hit a bot wall so the Oxylabs pass can rerun it.
|
|
219
|
+
// Called from afterEach, which also runs when the test times out before reaching its own catch.
|
|
220
|
+
async recordOxylabsCandidate() {
|
|
221
|
+
const { status, retry, project, error } = this.testInfo;
|
|
222
|
+
if (status === 'passed' || status === 'skipped' || status === 'interrupted' || retry < project.retries) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (await this.looksBlocked(error?.message ?? '')) {
|
|
226
|
+
fs.appendFileSync(oxylabsCandidatesFile!, `${oxylabsCandidateKey(this.cmp, this.testInfo.title)}\n`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// The site served a bot wall instead of its content: the page never loaded (other than a dead host),
|
|
231
|
+
// or nothing was detected on a bot-wall status code or a challenge page.
|
|
232
|
+
async looksBlocked(errorMessage: string) {
|
|
233
|
+
if (!this.response) {
|
|
234
|
+
return !DEAD_SITE_ERRORS.test(errorMessage);
|
|
235
|
+
}
|
|
236
|
+
if (this.isMessageReceived({ type: 'cmpDetected' })) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
if (BOT_WALL_STATUSES.includes(this.response.status())) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
const title = await this.page.title().catch(() => '');
|
|
243
|
+
return BOT_WALL_TITLE.test(title);
|
|
244
|
+
}
|
|
245
|
+
|
|
131
246
|
// emulate a browser that sends the Global Privacy Control signal
|
|
132
247
|
async enableGpc() {
|
|
133
248
|
await this.page.setExtraHTTPHeaders({ 'Sec-GPC': '1' });
|
|
@@ -159,29 +274,29 @@ class TestRun {
|
|
|
159
274
|
}
|
|
160
275
|
}
|
|
161
276
|
|
|
162
|
-
async messageCallback(
|
|
277
|
+
async messageCallback(msg: ContentScriptMessage, target: ContentScriptTarget) {
|
|
163
278
|
LOG_MESSAGES.includes(msg.type) && console.log(msg);
|
|
164
279
|
this.received.push(msg);
|
|
165
280
|
switch (msg.type) {
|
|
166
281
|
case 'init': {
|
|
167
|
-
const url = frame.url();
|
|
168
|
-
const mainFrame = frame.parentFrame() === null;
|
|
169
282
|
// Use full rules for optIn (compact rules omit optIn steps), compact rules for optOut.
|
|
170
283
|
const rules =
|
|
171
284
|
this.autoAction === 'optIn'
|
|
172
285
|
? { autoconsent: fullRules }
|
|
173
|
-
: { compact: filterCompactRules(compactRules, { url, mainFrame }) };
|
|
174
|
-
await
|
|
175
|
-
|
|
286
|
+
: { compact: filterCompactRules(compactRules, { url: msg.url, mainFrame: target.isMainFrame }) };
|
|
287
|
+
await target.send({
|
|
288
|
+
type: 'initResp',
|
|
289
|
+
config: {
|
|
176
290
|
enabled: true,
|
|
177
291
|
autoAction: this.autoAction,
|
|
178
292
|
disabledCmps: [],
|
|
179
293
|
enablePrehide: false,
|
|
180
|
-
detectRetries: 20,
|
|
294
|
+
detectRetries: 20 * detectionSlowdown,
|
|
181
295
|
enableCosmeticRules: true,
|
|
182
296
|
visualTest: true,
|
|
183
|
-
}
|
|
184
|
-
|
|
297
|
+
},
|
|
298
|
+
rules,
|
|
299
|
+
});
|
|
185
300
|
break;
|
|
186
301
|
}
|
|
187
302
|
case 'cmpDetected': {
|
|
@@ -196,20 +311,25 @@ class TestRun {
|
|
|
196
311
|
case 'optOutResult': {
|
|
197
312
|
await this.takeScreenshot(`${this.screenshotCounter++}-result`);
|
|
198
313
|
if (msg.scheduleSelfTest) {
|
|
199
|
-
this.
|
|
314
|
+
this.selfTestTarget = target;
|
|
200
315
|
}
|
|
201
316
|
break;
|
|
202
317
|
}
|
|
203
318
|
case 'autoconsentDone': {
|
|
204
319
|
await this.takeScreenshot(`${this.screenshotCounter++}-done`);
|
|
205
|
-
if (this.
|
|
206
|
-
await this.
|
|
320
|
+
if (this.selfTestTarget && this.options.testSelfTest) {
|
|
321
|
+
await this.selfTestTarget.send({ type: 'selfTest' });
|
|
207
322
|
}
|
|
208
323
|
break;
|
|
209
324
|
}
|
|
210
325
|
case 'eval': {
|
|
211
|
-
|
|
212
|
-
|
|
326
|
+
let result: unknown = false;
|
|
327
|
+
try {
|
|
328
|
+
result = await target.evalInMainWorld(msg.code);
|
|
329
|
+
} catch {
|
|
330
|
+
// the frame may have navigated or detached
|
|
331
|
+
}
|
|
332
|
+
await target.send({ id: msg.id, type: 'evalResp', result });
|
|
213
333
|
break;
|
|
214
334
|
}
|
|
215
335
|
case 'visualDelay': {
|
|
@@ -240,8 +360,19 @@ class TestRun {
|
|
|
240
360
|
return this.findReceivedMessages(msg).length > 0;
|
|
241
361
|
}
|
|
242
362
|
|
|
243
|
-
waitForMessage(msg: Partial<ContentScriptMessage>, maxTimes = 50, interval = 500) {
|
|
244
|
-
|
|
363
|
+
async waitForMessage(msg: Partial<ContentScriptMessage>, maxTimes = 50, interval = 500) {
|
|
364
|
+
let attempts = 0;
|
|
365
|
+
while (!this.isMessageReceived(msg)) {
|
|
366
|
+
if (attempts >= maxTimes) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
370
|
+
// time spent waiting for the captcha solver doesn't count
|
|
371
|
+
if (!this.captcha?.isSolving()) {
|
|
372
|
+
attempts++;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return true;
|
|
245
376
|
}
|
|
246
377
|
|
|
247
378
|
async assertMessageReceived(
|
|
@@ -282,7 +413,7 @@ class TestRun {
|
|
|
282
413
|
}
|
|
283
414
|
|
|
284
415
|
async runAssertions() {
|
|
285
|
-
await this.assertMessageReceived(`no CMP detected`, { type: 'cmpDetected' });
|
|
416
|
+
await this.assertMessageReceived(`no CMP detected`, { type: 'cmpDetected' }, true, 50 * detectionSlowdown);
|
|
286
417
|
|
|
287
418
|
const expectedCmpDetected: Partial<ContentScriptMessage> = { type: 'cmpDetected', cmp: this.expectedCmp };
|
|
288
419
|
await this.assertMessageReceived(`detected a wrong CMP`, expectedCmpDetected);
|
|
@@ -320,7 +451,7 @@ class TestRun {
|
|
|
320
451
|
await this.assertMessageReceived(`optInResult not received`, { type: 'optInResult' }, true, 1, 300);
|
|
321
452
|
await this.assertMessageReceived(`optInResult received, but failed`, { type: 'optInResult', result: true }, true, 1, 300);
|
|
322
453
|
}
|
|
323
|
-
if (this.options.testSelfTest && this.
|
|
454
|
+
if (this.options.testSelfTest && this.selfTestTarget) {
|
|
324
455
|
await this.assertMessageReceived(`selfTestResult not received`, { type: 'selfTestResult' }, true, 1, 300);
|
|
325
456
|
await this.assertMessageReceived(
|
|
326
457
|
`selfTestResult received, but failed`,
|
|
@@ -340,8 +471,19 @@ class TestRun {
|
|
|
340
471
|
}
|
|
341
472
|
}
|
|
342
473
|
|
|
474
|
+
// Runs by test id, for the afterEach hook that records Oxylabs candidates.
|
|
475
|
+
const testRuns = new Map<string, TestRun>();
|
|
476
|
+
|
|
343
477
|
export default function generateCMPTests(cmp: string, sites: string[], overrideOptions: Partial<TestOptions> = {}) {
|
|
344
478
|
test.describe(cmp, () => {
|
|
479
|
+
if (recordOxylabsCandidates) {
|
|
480
|
+
// eslint-disable-next-line no-empty-pattern
|
|
481
|
+
test.afterEach(async ({}, testInfo) => {
|
|
482
|
+
const testRun = testRuns.get(testInfo.testId);
|
|
483
|
+
testRuns.delete(testInfo.testId);
|
|
484
|
+
await testRun?.recordOxylabsCandidate();
|
|
485
|
+
});
|
|
486
|
+
}
|
|
345
487
|
sites.forEach((url) => {
|
|
346
488
|
const finalOptions = { ...defaultOptions, ...overrideOptions };
|
|
347
489
|
if (finalOptions.onlyRegions && finalOptions.onlyRegions.length > 0 && !finalOptions.onlyRegions.includes(testRegion)) {
|
|
@@ -355,26 +497,28 @@ export default function generateCMPTests(cmp: string, sites: string[], overrideO
|
|
|
355
497
|
const urlHash = crypto.createHash('md5').update(url).digest('hex').slice(0, 4);
|
|
356
498
|
const formFactor = finalOptions.mobile ? 'mobile' : 'desktop';
|
|
357
499
|
|
|
358
|
-
|
|
359
|
-
const testName = `${domain} ${urlHash} .${testRegion}
|
|
500
|
+
const defineTest = (label: string, autoAction: AutoAction | null) => {
|
|
501
|
+
const testName = `${domain} ${urlHash} .${testRegion} ${label} ${formFactor}`;
|
|
502
|
+
if (oxylabsCandidates && !oxylabsCandidates.has(oxylabsCandidateKey(cmp, testName))) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
360
505
|
test(testName, async ({ page }, testInfo) => {
|
|
361
|
-
const testRun = new TestRun(page, testInfo, url, cmp, finalOptions,
|
|
506
|
+
const testRun = new TestRun(page, testInfo, url, cmp, finalOptions, autoAction);
|
|
507
|
+
if (recordOxylabsCandidates) {
|
|
508
|
+
testRuns.set(testInfo.testId, testRun);
|
|
509
|
+
}
|
|
362
510
|
await testRun.run();
|
|
363
511
|
});
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
if (!finalOptions.testOptIn && !finalOptions.testOptOut) {
|
|
515
|
+
defineTest('noaction', null);
|
|
364
516
|
}
|
|
365
517
|
if (finalOptions.testOptIn) {
|
|
366
|
-
|
|
367
|
-
test(testName, async ({ page }, testInfo) => {
|
|
368
|
-
const testRun = new TestRun(page, testInfo, url, cmp, finalOptions, 'optIn');
|
|
369
|
-
await testRun.run();
|
|
370
|
-
});
|
|
518
|
+
defineTest('optIn', 'optIn');
|
|
371
519
|
}
|
|
372
520
|
if (finalOptions.testOptOut) {
|
|
373
|
-
|
|
374
|
-
test(testName, async ({ page }, testInfo) => {
|
|
375
|
-
const testRun = new TestRun(page, testInfo, url, cmp, finalOptions, 'optOut');
|
|
376
|
-
await testRun.run();
|
|
377
|
-
});
|
|
521
|
+
defineTest('optOut', 'optOut');
|
|
378
522
|
}
|
|
379
523
|
});
|
|
380
524
|
});
|
package/playwright.config.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { PlaywrightTestConfig, devices } from '@playwright/test';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// Oxylabs sessions bring their own regional proxy and reject contexts that set another one.
|
|
4
|
+
const proxy = process.env.PROXY_SERVER && process.env.OXYLABS !== '1' ? { server: process.env.PROXY_SERVER } : undefined;
|
|
4
5
|
|
|
5
6
|
const config: PlaywrightTestConfig = {
|
|
6
7
|
forbidOnly: !!process.env.CI,
|
|
7
8
|
retries: process.env.CI ? 2 : 0,
|
|
9
|
+
// Remote Oxylabs sessions load pages more slowly and may wait up to 60s for the captcha solver.
|
|
10
|
+
timeout: process.env.OXYLABS === '1' ? 240000 : undefined,
|
|
8
11
|
testDir: 'tests',
|
|
9
12
|
use: {
|
|
10
13
|
trace: 'off',
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "123inkt",
|
|
3
|
+
"vendorUrl": "https://www.123inkt.nl/",
|
|
4
|
+
"prehideSelectors": [".c-simple-popup:has(.c-cookie-popup)"],
|
|
5
|
+
"detectCmp": [{ "exists": ".c-cookie-popup [data-role=refuse-cookies]" }],
|
|
6
|
+
"detectPopup": [{ "visible": ".c-cookie-popup", "check": "any" }],
|
|
7
|
+
"optIn": [{ "waitForThenClick": ".c-cookie-popup [data-role=accept-cookies]" }],
|
|
8
|
+
"optOut": [{ "waitForThenClick": ".c-cookie-popup [data-role=refuse-cookies]" }]
|
|
9
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aeolservice",
|
|
3
|
+
"vendorUrl": "https://cloud.aeolservice.es/",
|
|
4
|
+
"runContext": {
|
|
5
|
+
"urlPattern": "^https?://cloud\\.aeolservice\\.es/"
|
|
6
|
+
},
|
|
7
|
+
"prehideSelectors": [],
|
|
8
|
+
"detectCmp": [
|
|
9
|
+
{
|
|
10
|
+
"exists": "#cookies_consent_div"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"detectPopup": [
|
|
14
|
+
{
|
|
15
|
+
"visible": "#popup_content.cookies_consent_div .config_cookies"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"optIn": [
|
|
19
|
+
{
|
|
20
|
+
"waitForThenClick": "#popup_content.cookies_consent_div .explanation .aceptar_cokies"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"optOut": [
|
|
24
|
+
{
|
|
25
|
+
"waitForThenClick": "#popup_content.cookies_consent_div .config_cookies"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"waitForVisible": "#popup_content #configurar_cookies"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"click": "#popup_content .cookie_button:not(.cookies_tecnicas) input[type=checkbox]:checked",
|
|
32
|
+
"all": true,
|
|
33
|
+
"optional": true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"waitForThenClick": "#popup_content .not_explanation.aceptar_cokies"
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "amazon-music",
|
|
3
|
+
"vendorUrl": "https://music.amazon.com/",
|
|
4
|
+
"runContext": {
|
|
5
|
+
"urlPattern": "^https?://music\\.amazon\\.[a-z.]+/"
|
|
6
|
+
},
|
|
7
|
+
"prehideSelectors": ["#banner"],
|
|
8
|
+
"detectCmp": [{ "exists": "#banner #bannerFooter music-button" }],
|
|
9
|
+
"detectPopup": [{ "visible": "#banner #bannerFooter" }],
|
|
10
|
+
"optIn": [{ "waitForThenClick": ["#bannerFooter music-button[variant=solid]", "button"] }],
|
|
11
|
+
"optOut": [{ "waitForThenClick": ["#bannerFooter music-button[variant=outline]", "button"] }],
|
|
12
|
+
"test": [{ "waitForVisible": "#banner #bannerFooter", "check": "none", "timeout": 2000 }]
|
|
13
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "animatetimes",
|
|
3
|
+
"vendorUrl": "https://www.animatetimes.com/",
|
|
4
|
+
"runContext": {
|
|
5
|
+
"urlPattern": "^https?://(www\\.)?animatetimes\\.com/"
|
|
6
|
+
},
|
|
7
|
+
"prehideSelectors": ["#cookie-agreement"],
|
|
8
|
+
"detectCmp": [
|
|
9
|
+
{
|
|
10
|
+
"exists": "#cookie-agreement"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"detectPopup": [
|
|
14
|
+
{
|
|
15
|
+
"visible": "#cookie-agreement"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"optIn": [
|
|
19
|
+
{
|
|
20
|
+
"waitForThenClick": "#cookie-agreement .agree"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"optOut": [
|
|
24
|
+
{
|
|
25
|
+
"waitForThenClick": "#cookie-agreement .dismiss"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"test": [
|
|
29
|
+
{
|
|
30
|
+
"visible": "#cookie-agreement",
|
|
31
|
+
"check": "none"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "annunci69.it",
|
|
3
|
+
"vendorUrl": "https://www.annunci69.it/",
|
|
4
|
+
"runContext": {
|
|
5
|
+
"urlPattern": "^https?://(www\\.)?annunci69\\.it/"
|
|
6
|
+
},
|
|
7
|
+
"prehideSelectors": ["#a69-cookie-banner"],
|
|
8
|
+
"detectCmp": [{ "exists": "#a69-cookie-banner #a69-cookie-manage" }],
|
|
9
|
+
"detectPopup": [{ "visible": "#a69-cookie-banner" }],
|
|
10
|
+
"optIn": [{ "waitForThenClick": "#a69-cookie-accept" }],
|
|
11
|
+
"optOut": [
|
|
12
|
+
{ "waitForThenClick": "#a69-cookie-manage" },
|
|
13
|
+
{ "waitForVisible": "#a69-cookie-modal" },
|
|
14
|
+
{ "click": "#a69-cookie-analytics:checked", "optional": true },
|
|
15
|
+
{ "click": "#a69-cookie-save" },
|
|
16
|
+
{ "waitForVisible": "#a69-cookie-banner", "check": "none" }
|
|
17
|
+
],
|
|
18
|
+
"test": [{ "cookieContains": "a69_cookie_preferences=%7B%22analytics%22%3Afalse" }]
|
|
19
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "arbeidsplassen-nav-no",
|
|
3
|
+
"vendorUrl": "https://arbeidsplassen.nav.no/",
|
|
4
|
+
"runContext": {
|
|
5
|
+
"urlPattern": "^https?://arbeidsplassen\\.nav\\.no/"
|
|
6
|
+
},
|
|
7
|
+
"prehideSelectors": ["#arb-cookie-banner-section"],
|
|
8
|
+
"detectCmp": [
|
|
9
|
+
{
|
|
10
|
+
"exists": "#arb-cookie-banner-section button"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"detectPopup": [
|
|
14
|
+
{
|
|
15
|
+
"visible": "#arb-cookie-banner-section"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"optIn": [
|
|
19
|
+
{
|
|
20
|
+
"waitForThenClick": "#arb-cookie-banner-section button:last-of-type"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"optOut": [
|
|
24
|
+
{
|
|
25
|
+
"waitForThenClick": "#arb-cookie-banner-section button:first-of-type"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"test": [
|
|
29
|
+
{
|
|
30
|
+
"cookieContains": "%22analytics%22%3Afalse"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "asahi-interactive",
|
|
3
|
+
"vendorUrl": "https://aiasahi.jp/cookie/",
|
|
4
|
+
"prehideSelectors": ["#gdpr_area"],
|
|
5
|
+
"detectCmp": [
|
|
6
|
+
{
|
|
7
|
+
"exists": "#gdpr_area .gdpr_area_inner"
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"detectPopup": [
|
|
11
|
+
{
|
|
12
|
+
"visible": "#gdpr_area"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"optIn": [
|
|
16
|
+
{
|
|
17
|
+
"waitForThenClick": "#gdpr_area .gdpr_btn_agree, #gdpr_area #gdpr_btn_agree"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"optOut": [
|
|
21
|
+
{
|
|
22
|
+
"waitForThenClick": "#gdpr_area .gdpr_btn_agree, #gdpr_area #gdpr_btn_agree"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"test": [
|
|
26
|
+
{
|
|
27
|
+
"cookieContains": "is_gdpr_agree=1"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "att",
|
|
3
|
+
"vendorUrl": "https://www.att.com/",
|
|
4
|
+
"runContext": {
|
|
5
|
+
"urlPattern": "^https://([a-z0-9-]+\\.)*att\\.com/"
|
|
6
|
+
},
|
|
7
|
+
"prehideSelectors": ["#gpc-banner-container"],
|
|
8
|
+
"detectCmp": [
|
|
9
|
+
{
|
|
10
|
+
"exists": ["#gpc-banner-container", "#declineSave"]
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"detectPopup": [
|
|
14
|
+
{
|
|
15
|
+
"visible": ["#gpc-banner-container", "#declineSave"]
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"optIn": [
|
|
19
|
+
{
|
|
20
|
+
"waitForThenClick": ["#gpc-banner-container", "#acceptAccept"]
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"optOut": [
|
|
24
|
+
{
|
|
25
|
+
"waitForThenClick": ["#gpc-banner-container", "#declineSave"]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"test": [
|
|
29
|
+
{
|
|
30
|
+
"wait": 1000
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"cookieContains": "\"consent\":\"d\""
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "auctionet",
|
|
3
|
+
"vendorUrl": "https://auctionet.com/",
|
|
4
|
+
"runContext": {
|
|
5
|
+
"urlPattern": "^https?://(www\\.)?auctionet\\.(com|se)/"
|
|
6
|
+
},
|
|
7
|
+
"prehideSelectors": ["form.test-cookie-consent"],
|
|
8
|
+
"detectCmp": [
|
|
9
|
+
{
|
|
10
|
+
"exists": "form.test-cookie-consent [data-cookie-consent-target=\"screen1\"]"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"detectPopup": [
|
|
14
|
+
{
|
|
15
|
+
"visible": "form.test-cookie-consent [data-cookie-consent-target=\"screen1\"]"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"optIn": [
|
|
19
|
+
{
|
|
20
|
+
"waitForThenClick": "form.test-cookie-consent [data-cookie-consent-target=\"screen1\"] [data-action=\"cookie-consent#acceptAll\"]"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"optOut": [
|
|
24
|
+
{
|
|
25
|
+
"waitForThenClick": "form.test-cookie-consent [data-action=\"cookie-consent#showSettings\"]"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"waitForThenClick": "form.test-cookie-consent [data-cookie-consent-target=\"screen2\"] [data-action=\"cookie-consent#rejectAll\"]"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"test": [
|
|
32
|
+
{
|
|
33
|
+
"wait": 500
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"cookieContains": "%22ad_storage%22%3Afalse"
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|