@duckduckgo/autoconsent 12.7.0 → 12.8.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/data/coverage.json +1335 -1389
  3. package/dist/addon-firefox/background.bundle.js +9 -1
  4. package/dist/addon-firefox/content.bundle.js +21 -3
  5. package/dist/addon-firefox/manifest.json +1 -1
  6. package/dist/addon-firefox/rules.json +381 -53
  7. package/dist/addon-mv3/background.bundle.js +9 -1
  8. package/dist/addon-mv3/content.bundle.js +21 -3
  9. package/dist/addon-mv3/manifest.json +1 -1
  10. package/dist/addon-mv3/popup.bundle.js +1 -1
  11. package/dist/addon-mv3/rules.json +381 -53
  12. package/dist/autoconsent.cjs.js +19 -1
  13. package/dist/autoconsent.esm.js +19 -1
  14. package/dist/autoconsent.extra.cjs.js +21 -3
  15. package/dist/autoconsent.extra.esm.js +21 -3
  16. package/dist/autoconsent.playwright.js +402 -56
  17. package/lib/cmps/sourcepoint-frame.ts +13 -0
  18. package/lib/eval-snippets.ts +14 -0
  19. package/lib/filterlist-engine.ts +2 -2
  20. package/lib/rules.ts +2 -1
  21. package/package.json +6 -3
  22. package/rules/autoconsent/civic-cookie-control.json +23 -12
  23. package/rules/autoconsent/dsgvo.json +1 -1
  24. package/rules/autoconsent/gov-uk.json +19 -5
  25. package/rules/autoconsent/gravito.json +44 -0
  26. package/rules/autoconsent/johnlewis.json +1 -1
  27. package/rules/autoconsent/opera.com.json +7 -10
  28. package/rules/autoconsent/postnl.json +34 -0
  29. package/rules/autoconsent/privado.json +48 -0
  30. package/rules/autoconsent/quantcast.json +22 -4
  31. package/rules/autoconsent/shopify.json +31 -0
  32. package/rules/autoconsent/squiz.json +39 -0
  33. package/rules/autoconsent/tccCmpAlert.json +25 -0
  34. package/rules/autoconsent/termly.json +2 -2
  35. package/rules/autoconsent/true-car.json +1 -1
  36. package/rules/autoconsent/twitter.json +1 -2
  37. package/rules/autoconsent/womenshealthmag-us.json +31 -0
  38. package/rules/filterlist.txt +73 -211
  39. package/rules/rules.json +381 -53
  40. package/scripts/get-text-for-xpath.ts +5 -2
  41. package/scripts/validate-json-rules.js +45 -0
  42. package/tests/civic-cookie-control.spec.ts +7 -3
  43. package/tests/gravito.spec.ts +3 -0
  44. package/tests/postnl.spec.ts +3 -0
  45. package/tests/privado.spec.ts +3 -0
  46. package/tests/shopify.spec.ts +7 -0
  47. package/tests/squiz.spec.ts +3 -0
  48. package/tests/tccCmpAlert.spec.ts +3 -0
  49. package/tests/termly.spec.ts +11 -1
  50. package/tests/womenshealthmag-us.spec.ts +3 -0
package/lib/rules.ts CHANGED
@@ -14,6 +14,7 @@ export type AutoConsentCMPRule = {
14
14
  optIn: AutoConsentRuleStep[];
15
15
  openCmp?: AutoConsentRuleStep[];
16
16
  test?: AutoConsentRuleStep[];
17
+ comment?: string;
17
18
  };
18
19
 
19
20
  export type RunContext = {
@@ -24,7 +25,7 @@ export type RunContext = {
24
25
 
25
26
  export type ElementSelector = string | string[];
26
27
 
27
- export type AutoConsentRuleStep = { optional?: boolean } & Partial<ElementExistsRule> &
28
+ export type AutoConsentRuleStep = { optional?: boolean; comment?: string } & Partial<ElementExistsRule> &
28
29
  Partial<ElementVisibleRule> &
29
30
  Partial<EvalRule> &
30
31
  Partial<WaitForRule> &
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duckduckgo/autoconsent",
3
- "version": "12.7.0",
3
+ "version": "12.8.0",
4
4
  "description": "",
5
5
  "exports": {
6
6
  ".": {
@@ -18,8 +18,9 @@
18
18
  },
19
19
  "scripts": {
20
20
  "clean": "rm -r dist",
21
- "lint": "eslint . && prettier . --check",
21
+ "lint": "eslint . && prettier . --check && npm run rule-syntax-check",
22
22
  "bundle": "./build.sh",
23
+ "rule-syntax-check": "node scripts/validate-json-rules.js",
23
24
  "watch": "npm run prepublish && chokidar \"lib\" \"addon\" \"rules/autoconsent\" \"rules/filterlist.txt\" --ignore 'lib/filterlist-engine.ts' -c \"npm run prepublish\"",
24
25
  "create-rule": "node rules/create-rule.mjs",
25
26
  "test": "playwright test",
@@ -47,12 +48,13 @@
47
48
  "@esm-bundle/chai": "^4.3.4-fix.0",
48
49
  "@playwright/test": "^1.17.1",
49
50
  "@types/chai": "^5.0.0",
50
- "@types/chrome": "^0.0.287",
51
+ "@types/chrome": "^0.0.300",
51
52
  "@types/eslint__js": "^8.42.3",
52
53
  "@types/mocha": "^10.0.1",
53
54
  "@web/dev-server-esbuild": "^1.0.2",
54
55
  "@web/test-runner": "^0.19.0",
55
56
  "@web/test-runner-playwright": "^0.11.0",
57
+ "ajv": "^8.17.1",
56
58
  "asana": "^1.0.2",
57
59
  "auto": "^11.0.1",
58
60
  "bulma": "^1.0.2",
@@ -66,6 +68,7 @@
66
68
  "mocha": "^11.0.1",
67
69
  "prettier": "3.4.2",
68
70
  "sinon": "^19.0.2",
71
+ "ts-json-schema-generator": "^2.3.0",
69
72
  "ts-node": "^10.9.2",
70
73
  "tslib": "^2.4.0",
71
74
  "typescript": "^5.1.6",
@@ -6,22 +6,33 @@
6
6
  "detectPopup": [{ "visible": "#ccc" }, { "visible": "#ccc-module,#ccc-notify" }],
7
7
  "optOut": [
8
8
  {
9
- "if": { "exists": "#ccc-notify" },
10
- "then": [
9
+ "if": { "visible": ".ccc-reject-button" },
10
+ "then": [{ "waitForThenClick": ".ccc-reject-button" }],
11
+ "else": [
11
12
  {
12
- "waitForThenClick": [
13
- "#ccc #ccc-notify .ccc-notify-buttons",
14
- "xpath///button[contains(., 'Settings') or contains(., 'Cookie Preferences')]"
13
+ "if": {
14
+ "exists": [
15
+ "#ccc #ccc-notify .ccc-notify-buttons",
16
+ "xpath///button[contains(., 'Settings') or contains(., 'Cookie Preferences') or contains(., 'Einstellungen️')]"
17
+ ]
18
+ },
19
+ "then": [
20
+ {
21
+ "waitForThenClick": [
22
+ "#ccc #ccc-notify .ccc-notify-buttons",
23
+ "xpath///button[contains(., 'Settings') or contains(., 'Cookie Preferences') or contains(., 'Einstellungen️')]"
24
+ ]
25
+ },
26
+ { "waitForVisible": "#ccc-module" }
15
27
  ]
16
28
  },
17
- { "waitForVisible": "#ccc-module" }
29
+ {
30
+ "if": { "visible": ".ccc-reject-button" },
31
+ "then": [{ "waitForThenClick": ".ccc-reject-button" }],
32
+ "else": [{ "waitForThenClick": "#ccc-dismiss-button" }]
33
+ }
18
34
  ]
19
- },
20
- {
21
- "if": { "exists": "#ccc-reject-settings" },
22
- "then": [{ "waitForThenClick": "#ccc-reject-settings" }],
23
- "else": [{ "waitForThenClick": "#ccc-dismiss-button" }]
24
35
  }
25
36
  ],
26
- "optIn": [{ "waitForThenClick": "#ccc-recommended-settings,#ccc-notify-accept" }]
37
+ "optIn": [{ "waitForThenClick": "#ccc-recommended-settings,#ccc-notify-accept,.ccc-accept-button" }]
27
38
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "WP DSGVO Tools",
3
- "link": "https://wordpress.org/plugins/shapepress-dsgvo/",
3
+ "vendorUrl": "https://wordpress.org/plugins/shapepress-dsgvo/",
4
4
  "prehideSelectors": [".sp-dsgvo"],
5
5
  "cosmetic": true,
6
6
  "detectCmp": [{ "exists": ".sp-dsgvo.sp-dsgvo-popup-overlay" }],
@@ -1,10 +1,24 @@
1
1
  {
2
2
  "name": "gov.uk",
3
- "detectCmp": [{ "exists": "#global-cookie-message" }],
4
- "detectPopup": [{ "exists": "#global-cookie-message" }],
5
- "optIn": [{ "click": "button[data-accept-cookies=true]" }],
3
+ "detectCmp": [{ "exists": ".govuk-cookie-banner__message" }],
4
+ "detectPopup": [{ "exists": ".govuk-cookie-banner__message .govuk-button" }],
5
+ "optIn": [{ "click": [".govuk-cookie-banner__message", "xpath///button[contains(., 'Accept')] | //a[contains(., 'Accept')]"] }],
6
6
  "optOut": [
7
- { "click": "button[data-reject-cookies=true],#reject-cookies" },
8
- { "click": "button[data-hide-cookie-banner=true],#hide-cookie-decision" }
7
+ {
8
+ "if": {
9
+ "exists": [".govuk-cookie-banner__message", "xpath///button[contains(., 'Reject')] | //a[contains(., 'Reject')]"]
10
+ },
11
+ "then": [
12
+ {
13
+ "click": [".govuk-cookie-banner__message", "xpath///button[contains(., 'Reject')] | //a[contains(., 'Reject')]"]
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "if": {
19
+ "exists": [".govuk-cookie-banner__message", "xpath///button[contains(., 'Hide')] | //a[contains(., 'Hide')]"]
20
+ },
21
+ "then": [{ "click": [".govuk-cookie-banner__message", "xpath///button[contains(., 'Hide')] | //a[contains(., 'Hide')]"] }]
22
+ }
9
23
  ]
10
24
  }
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "gravito",
3
+ "vendorUrl": "https://www.gravito.net/cmp/",
4
+ "prehideSelectors": [".gravitoCMP-background-overlay"],
5
+ "detectCmp": [
6
+ {
7
+ "exists": ".gravitoCMP-background-overlay"
8
+ }
9
+ ],
10
+ "detectPopup": [
11
+ {
12
+ "visible": ".gravitoCMP-background-overlay"
13
+ }
14
+ ],
15
+ "optIn": [
16
+ {
17
+ "waitForThenClick": "#modalConfirmBtn.gravitoCMP-button"
18
+ }
19
+ ],
20
+ "optOut": [
21
+ {
22
+ "waitForThenClick": "#modalSettingBtn.gravitoCMP-button"
23
+ },
24
+ {
25
+ "waitFor": "#allRejectBtn"
26
+ },
27
+ {
28
+ "waitFor": ".gravitoCMP-content-section"
29
+ },
30
+ {
31
+ "click": ".gravitoCMP-content input[type=checkbox]:checked",
32
+ "all": true,
33
+ "optional": true
34
+ },
35
+ {
36
+ "waitForThenClick": "#allRejectBtn"
37
+ }
38
+ ],
39
+ "test": [
40
+ {
41
+ "eval": "EVAL_GRAVITO_TEST"
42
+ }
43
+ ]
44
+ }
@@ -5,7 +5,7 @@
5
5
  "detectPopup": [{ "exists": "div[class^=pecr-cookie-banner-]" }],
6
6
  "optOut": [
7
7
  { "click": "button[data-test^=manage-cookies]" },
8
- { "wait": "500" },
8
+ { "wait": 500 },
9
9
  {
10
10
  "click": "label[data-test^=toggle][class*=checked]:not([class*=disabled])",
11
11
  "all": true,
@@ -1,31 +1,28 @@
1
1
  {
2
2
  "name": "opera.com",
3
- "vendorUrl": "https://unknown",
3
+ "vendorUrl": "https://opera.com",
4
4
  "cosmetic": false,
5
5
  "runContext": {
6
- "main": true,
7
- "frame": false
6
+ "urlPattern": "^https?://(www\\.|)?opera\\.com/"
8
7
  },
9
- "intermediate": false,
10
- "prehideSelectors": [],
8
+ "prehideSelectors": ["#cookie-consent"],
11
9
  "detectCmp": [
12
10
  {
13
- "exists": "#cookie-consent .manage-cookies__btn"
11
+ "exists": "#cookie-consent .cookie-all__btn"
14
12
  }
15
13
  ],
16
14
  "detectPopup": [
17
15
  {
18
- "visible": "#cookie-consent .cookie-basic-consent__btn"
16
+ "visible": "#cookie-consent .cookie-all__btn"
19
17
  }
20
18
  ],
21
19
  "optIn": [
22
20
  {
23
- "waitForThenClick": "#cookie-consent .cookie-basic-consent__btn"
21
+ "waitForThenClick": "#cookie-consent .cookie-all__btn"
24
22
  }
25
23
  ],
26
24
  "optOut": [
27
- { "waitForThenClick": "#cookie-consent .manage-cookies__btn" },
28
- { "waitForThenClick": "#cookie-consent .active.marketing_option_switch.cookie-consent__switch", "all": true },
25
+ { "waitForThenClick": "#cookie-consent .cookie-consent__switch:not(.always_on)", "all": true },
29
26
  { "waitForThenClick": "#cookie-consent .cookie-selection__btn" }
30
27
  ],
31
28
  "test": [{ "eval": "EVAL_OPERA_0" }]
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "postnl",
3
+ "vendorUrl": "https://postnl.nl",
4
+ "cosmetic": false,
5
+ "runContext": {
6
+ "urlPattern": "^https://([^.]+\\.)?postnl\\.nl/"
7
+ },
8
+ "prehideSelectors": ["pnl-cookie-wall-widget"],
9
+ "detectCmp": [
10
+ {
11
+ "exists": "pnl-cookie-wall-widget"
12
+ }
13
+ ],
14
+ "detectPopup": [
15
+ {
16
+ "visible": "pnl-cookie-wall-widget"
17
+ }
18
+ ],
19
+ "optIn": [
20
+ {
21
+ "waitForThenClick": ["pnl-cookie-wall-widget", "button.pci-button--primary"]
22
+ }
23
+ ],
24
+ "optOut": [
25
+ {
26
+ "waitForThenClick": ["pnl-cookie-wall-widget", "button.pci-button--secondary"]
27
+ }
28
+ ],
29
+ "test": [
30
+ {
31
+ "eval": "EVAL_POSTNL_TEST"
32
+ }
33
+ ]
34
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "privado",
3
+ "vendorUrl": "https://www.privado.ai/cookie-consent",
4
+ "cosmetic": false,
5
+ "runContext": {
6
+ "main": true,
7
+ "frame": false
8
+ },
9
+ "prehideSelectors": ["#cookie-consent-banner"],
10
+ "detectCmp": [
11
+ {
12
+ "exists": "#cookie-consent-banner #accept-button"
13
+ }
14
+ ],
15
+ "detectPopup": [
16
+ {
17
+ "visible": "#cookie-consent-banner #accept-button"
18
+ }
19
+ ],
20
+ "optIn": [
21
+ {
22
+ "waitForThenClick": "#cookie-consent-banner #accept-button"
23
+ }
24
+ ],
25
+ "optOut": [
26
+ {
27
+ "if": {
28
+ "exists": "#cookie-consent-banner #deny-button"
29
+ },
30
+ "then": [
31
+ {
32
+ "waitForThenClick": "#cookie-consent-banner #deny-button"
33
+ }
34
+ ],
35
+ "else": [
36
+ {
37
+ "waitForThenClick": "#cookie-consent-banner #manage-settings-button"
38
+ },
39
+ {
40
+ "waitForVisible": "#manage-cookies #save-button"
41
+ },
42
+ {
43
+ "waitForThenClick": "#manage-cookies #save-button"
44
+ }
45
+ ]
46
+ }
47
+ ]
48
+ }
@@ -10,12 +10,30 @@
10
10
  "then": [{ "click": ".qc-cmp2-summary-buttons > button[mode=\"secondary\"]:nth-of-type(2)" }],
11
11
  "else": [
12
12
  { "click": ".qc-cmp2-summary-buttons > button[mode=\"secondary\"]:nth-of-type(1)" },
13
- { "waitFor": "#qc-cmp2-ui" },
13
+ { "waitForVisible": "#qc-cmp2-ui .qc-cmp2-consent-info" },
14
14
  { "click": ".qc-cmp2-toggle-switch > button[aria-checked=\"true\"]", "all": true, "optional": true },
15
- { "click": ".qc-cmp2-main button[aria-label=\"REJECT ALL\"]", "optional": true },
16
15
  {
17
- "waitForThenClick": ".qc-cmp2-main button[aria-label=\"SAVE & EXIT\"],.qc-cmp2-buttons-desktop > button[mode=\"primary\"]",
18
- "timeout": 5000
16
+ "click": [
17
+ ".qc-cmp2-main",
18
+ "xpath///button[contains(., 'REJECT ALL') or contains(., 'ALLE VERWERPEN') or contains(., 'ΑΠΟΡΡΙΠΤΩ ΤΑ ΠΑΝΤΑ') or contains(., 'RESPINGERE TOTALĂ') or contains(., 'ALLE ABLEHNEN') or contains(., 'ODRZUCENIE') or contains(., 'BLOQUEAR TODO') or contains(., 'REJEITAR TODOS') or contains(., 'RIFIUTA TUTTO') or contains(., 'TOUT REFUSER') or contains(., 'ОТКЛОНИТЬ ВСЕХ')]"
19
+ ],
20
+ "optional": true
21
+ },
22
+ {
23
+ "wait": 500
24
+ },
25
+ {
26
+ "if": { "exists": ".qc-cmp2-buttons-desktop > button[mode=primary]" },
27
+ "then": [{ "click": ".qc-cmp2-buttons-desktop > button[mode=primary]" }],
28
+ "else": [
29
+ {
30
+ "waitForThenClick": [
31
+ ".qc-cmp2-main",
32
+ "xpath///button[contains(.,'SAVE & EXIT') or contains(.,'SALVA ED ESCI') or contains(.,'GUARDAR Y SALIR') or contains(.,'SPEICHERN & VERLASSEN')"
33
+ ],
34
+ "timeout": 5000
35
+ }
36
+ ]
19
37
  }
20
38
  ]
21
39
  }
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "shopify",
3
+ "vendorUrl": "https://shopify.dev/docs/api/customer-privacy",
4
+ "cosmetic": false,
5
+ "prehideSelectors": ["#shopify-pc__banner"],
6
+ "detectCmp": [
7
+ {
8
+ "exists": "#shopify-pc__banner"
9
+ }
10
+ ],
11
+ "detectPopup": [
12
+ {
13
+ "visible": "#shopify-pc__banner"
14
+ }
15
+ ],
16
+ "optIn": [
17
+ {
18
+ "waitForThenClick": "#shopify-pc__banner__btn-accept"
19
+ }
20
+ ],
21
+ "optOut": [
22
+ {
23
+ "waitForThenClick": "#shopify-pc__banner__btn-decline"
24
+ }
25
+ ],
26
+ "test": [
27
+ {
28
+ "eval": "EVAL_SHOPIFY_TEST"
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "squiz",
3
+ "vendorUrl": "https://www.squiz.net/webinars/cdp",
4
+ "cosmetic": false,
5
+ "runContext": {
6
+ "main": true,
7
+ "frame": false,
8
+ "urlPattern": ""
9
+ },
10
+ "prehideSelectors": ["#cookie-consent-banner"],
11
+ "detectCmp": [
12
+ {
13
+ "exists": "#cookie-consent-banner #accept-cdp-cookie"
14
+ }
15
+ ],
16
+ "detectPopup": [
17
+ {
18
+ "visible": "#cookie-consent-banner #accept-cdp-cookie"
19
+ }
20
+ ],
21
+ "optIn": [
22
+ {
23
+ "waitForThenClick": "#accept-cdp-cookie"
24
+ }
25
+ ],
26
+ "optOut": [
27
+ {
28
+ "waitForThenClick": "#reject-cdp-cookie"
29
+ }
30
+ ],
31
+ "test": [
32
+ {
33
+ "wait": 500
34
+ },
35
+ {
36
+ "eval": "EVAL_SQUIZ_TEST"
37
+ }
38
+ ]
39
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "tccCmpAlert",
3
+ "vendorUrl": "https://unknown",
4
+ "prehideSelectors": ["#tccCmpAlert"],
5
+ "detectCmp": [
6
+ {
7
+ "exists": "#tccCmpAlert"
8
+ }
9
+ ],
10
+ "detectPopup": [
11
+ {
12
+ "visible": "#tccCmpAlert"
13
+ }
14
+ ],
15
+ "optIn": [
16
+ {
17
+ "waitForThenClick": "xpath///span[contains(.,'Accetta tutto')]"
18
+ }
19
+ ],
20
+ "optOut": [
21
+ {
22
+ "waitForThenClick": "xpath///span[contains(.,'Accetta solo cookie necessari')]"
23
+ }
24
+ ]
25
+ }
@@ -9,8 +9,8 @@
9
9
  "if": { "exists": "[data-tid=\"banner-decline\"]" },
10
10
  "then": [{ "click": "[data-tid=\"banner-decline\"]" }],
11
11
  "else": [
12
- { "click": ".t-preference-button" },
13
- { "wait": 500 },
12
+ { "waitForThenClick": ".t-preference-button,[data-testid=\"preferences-link\"]" },
13
+ { "waitFor": ".t-declineAllButton", "timeout": 700 },
14
14
  {
15
15
  "if": { "exists": ".t-declineAllButton" },
16
16
  "then": [{ "click": ".t-declineAllButton" }],
@@ -4,7 +4,7 @@
4
4
  "urlPattern": "^https://www\\.truecar\\.com/"
5
5
  },
6
6
  "cosmetic": true,
7
- "prehideSelectors": [["div[aria-labelledby=\"cookie-banner-heading\"]"]],
7
+ "prehideSelectors": ["div[aria-labelledby=\"cookie-banner-heading\"]"],
8
8
  "detectCmp": [{ "exists": "div[aria-labelledby=\"cookie-banner-heading\"]" }],
9
9
  "detectPopup": [{ "visible": "div[aria-labelledby=\"cookie-banner-heading\"]" }],
10
10
  "optIn": [{ "click": "div[aria-labelledby=\"cookie-banner-heading\"] > button[aria-label=\"Close\"]" }],
@@ -15,6 +15,5 @@
15
15
  {
16
16
  "waitForThenClick": "[data-testid=\"BottomBar\"] > div:has(>div:first-child>div:last-child>button[role=button]>span) > div:last-child > button[role=button]:last-child"
17
17
  }
18
- ],
19
- "TODOtest": [{ "eval": "EVAL_document.cookie.includes('d_prefs=MjoxLGNvbnNlbnRfdmVyc2lvbjoy')" }]
18
+ ]
20
19
  }
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "womenshealthmag-us",
3
+ "vendorUrl": "https://womenshealthmag.com",
4
+ "cosmetic": true,
5
+ "runContext": {
6
+ "main": true,
7
+ "frame": false,
8
+ "urlPattern": "^https://(www\\.)?womenshealthmag\\.com/"
9
+ },
10
+ "prehideSelectors": ["[status=open]:has([aria-label=\"Privacy Disclosure\"])"],
11
+ "detectCmp": [
12
+ {
13
+ "exists": "[status=open]:has([aria-label=\"Privacy Disclosure\"])"
14
+ }
15
+ ],
16
+ "detectPopup": [
17
+ {
18
+ "visible": "[status=open]:has([aria-label=\"Privacy Disclosure\"])"
19
+ }
20
+ ],
21
+ "optIn": [
22
+ {
23
+ "waitForThenClick": "[status=open]:has([aria-label=\"Privacy Disclosure\"]) button"
24
+ }
25
+ ],
26
+ "optOut": [
27
+ {
28
+ "hide": "[status=open]:has([aria-label=\"Privacy Disclosure\"])"
29
+ }
30
+ ]
31
+ }