@duckduckgo/autoconsent 2.2.0 → 3.0.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 (74) hide show
  1. package/Jenkinsfile +2 -2
  2. package/dist/addon-firefox/background.bundle.js +1 -1
  3. package/dist/addon-firefox/content.bundle.js +1 -1
  4. package/dist/addon-firefox/manifest.json +2 -2
  5. package/dist/addon-firefox/rules.json +565 -7
  6. package/dist/addon-mv3/background.bundle.js +1 -1
  7. package/dist/addon-mv3/content.bundle.js +1 -1
  8. package/dist/addon-mv3/manifest.json +3 -2
  9. package/dist/addon-mv3/popup.bundle.js +1 -0
  10. package/dist/addon-mv3/popup.html +67 -0
  11. package/dist/addon-mv3/rules.json +565 -7
  12. package/dist/autoconsent.cjs.js +1 -1
  13. package/dist/autoconsent.esm.js +1 -1
  14. package/dist/autoconsent.playwright.js +1 -1
  15. package/lib/cmps/airbnb.ts +57 -0
  16. package/lib/cmps/all.ts +4 -0
  17. package/lib/cmps/base.ts +2 -2
  18. package/lib/cmps/onetrust.ts +3 -3
  19. package/lib/cmps/tiktok.ts +73 -0
  20. package/lib/cmps/trustarc-frame.ts +4 -1
  21. package/lib/cmps/uniconsent.ts +2 -1
  22. package/lib/rule-executors.ts +15 -15
  23. package/lib/rules.ts +1 -1
  24. package/lib/web.ts +14 -1
  25. package/package.json +2 -2
  26. package/playwright/runner.ts +8 -2
  27. package/playwright.config.ts +9 -0
  28. package/readme.md +5 -1
  29. package/rollup.config.js +16 -2
  30. package/rules/autoconsent/amazon.json +20 -0
  31. package/rules/autoconsent/dailymotion.json +22 -0
  32. package/rules/autoconsent/dmgmedia.json +19 -0
  33. package/rules/autoconsent/facebook.json +21 -0
  34. package/rules/autoconsent/google-consent-standalone.json +17 -0
  35. package/rules/autoconsent/google.json +22 -0
  36. package/rules/autoconsent/linkedin.json +23 -0
  37. package/rules/autoconsent/monzo-com.json +1 -6
  38. package/rules/autoconsent/moove.json +1 -1
  39. package/rules/autoconsent/privacymanager.json +30 -0
  40. package/rules/autoconsent/pubtech.json +42 -0
  41. package/rules/autoconsent/reddit.json +22 -0
  42. package/rules/autoconsent/sibbo.json +43 -0
  43. package/rules/autoconsent/twitter.json +22 -0
  44. package/rules/autoconsent/vodafone-de.json +1 -1
  45. package/rules/autoconsent/youtube-desktop.json +23 -0
  46. package/rules/autoconsent/youtube-mobile.json +22 -0
  47. package/rules/rules.json +565 -7
  48. package/tests/airbnb.spec.ts +8 -0
  49. package/tests/amazon.spec.ts +17 -0
  50. package/tests/complianz-banner.spec.ts +0 -2
  51. package/tests/complianz-categories.spec.ts +1 -1
  52. package/tests/dailymotion.spec.ts +14 -0
  53. package/tests/dmgmedia.spec.ts +16 -0
  54. package/tests/facebook.spec.ts +14 -0
  55. package/tests/google.spec.ts +7 -0
  56. package/tests/linkedin.spec.ts +7 -0
  57. package/tests/moove.spec.ts +1 -0
  58. package/tests/oil.spec.ts +3 -2
  59. package/tests/onetrust.spec.ts +2 -2
  60. package/tests/privacymanager.spec.ts +8 -0
  61. package/tests/pubtech.spec.ts +13 -0
  62. package/tests/reddit.spec.ts +8 -0
  63. package/tests/sibbo.spec.ts +15 -0
  64. package/tests/tiktok.spec.ts +14 -0
  65. package/tests/twitter.spec.ts +16 -0
  66. package/tests/wp-cookie-notice.spec.ts +1 -1
  67. package/tests/youtube-desktop.spec.ts +7 -0
  68. package/tests/youtube-mobile.spec.ts +8 -0
  69. package/.vscode/.idea/.vscode.iml +0 -9
  70. package/.vscode/.idea/modules.xml +0 -8
  71. package/.vscode/.idea/workspace.xml +0 -28
  72. package/.vscode/settings.json +0 -7
  73. package/lib/web/consentomatic/index.js +0 -188
  74. package/lib/web/consentomatic/tools.js +0 -177
@@ -4,7 +4,7 @@ import AutoConsentCMPBase from "./base";
4
4
 
5
5
  export default class Onetrust extends AutoConsentCMPBase {
6
6
 
7
- prehideSelectors = ["#onetrust-banner-sdk,#onetrust-consent-sdk,.optanon-alert-box-wrapper,.onetrust-pc-dark-filter,.js-consent-banner"]
7
+ prehideSelectors = ["#onetrust-banner-sdk,#onetrust-consent-sdk,.onetrust-pc-dark-filter,.js-consent-banner"]
8
8
 
9
9
  constructor() {
10
10
  super("Onetrust");
@@ -19,11 +19,11 @@ export default class Onetrust extends AutoConsentCMPBase {
19
19
  }
20
20
 
21
21
  async detectCmp() {
22
- return elementExists("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
22
+ return elementExists("#onetrust-banner-sdk");
23
23
  }
24
24
 
25
25
  async detectPopup() {
26
- return elementVisible("#onetrust-banner-sdk,.optanon-alert-box-wrapper", 'all');
26
+ return elementVisible("#onetrust-banner-sdk", 'all');
27
27
  }
28
28
 
29
29
  async optOut() {
@@ -0,0 +1,73 @@
1
+ import { enableLogs } from "../config";
2
+ import { elementExists } from "../rule-executors";
3
+ import { RunContext } from "../rules";
4
+ import { isElementVisible } from "../utils";
5
+ import AutoConsentCMPBase from "./base";
6
+
7
+ export default class Tiktok extends AutoConsentCMPBase {
8
+ constructor() {
9
+ super("tiktok.com");
10
+ }
11
+
12
+ runContext: RunContext = {
13
+ urlPattern: 'tiktok'
14
+ }
15
+
16
+ get hasSelfTest(): boolean {
17
+ return true;
18
+ }
19
+
20
+ get isIntermediate(): boolean {
21
+ return false;
22
+ }
23
+
24
+ getShadowRoot() {
25
+ const container = document.querySelector('tiktok-cookie-banner');
26
+ if (!container) {
27
+ return null;
28
+ }
29
+ return container.shadowRoot;
30
+ }
31
+
32
+ async detectCmp() {
33
+ return elementExists("tiktok-cookie-banner");
34
+ }
35
+
36
+ async detectPopup() {
37
+ const banner = this.getShadowRoot().querySelector('.tiktok-cookie-banner') as HTMLElement;
38
+ return isElementVisible(banner);
39
+ }
40
+
41
+ async optOut() {
42
+ const declineButton = this.getShadowRoot().querySelector('.button-wrapper button:first-child') as HTMLElement;
43
+ if (declineButton) {
44
+ enableLogs && console.log("[clicking]", declineButton);
45
+ declineButton.click();
46
+ return true;
47
+ } else {
48
+ enableLogs && console.log("no decline button found");
49
+ return false;
50
+ }
51
+ }
52
+
53
+ async optIn() {
54
+ const acceptButton = this.getShadowRoot().querySelector('.button-wrapper button:last-child') as HTMLElement;
55
+ if (acceptButton) {
56
+ enableLogs && console.log("[clicking]", acceptButton);
57
+ acceptButton.click();
58
+ return true;
59
+ } else {
60
+ enableLogs && console.log("no accept button found");
61
+ return false;
62
+ }
63
+ }
64
+
65
+ async test() {
66
+ const match = document.cookie.match(/cookie-consent=([^;]+)/);
67
+ if (!match) {
68
+ return false;
69
+ }
70
+ const value = JSON.parse(decodeURIComponent(match[1]));
71
+ return Object.values(value).every(x => typeof x !== 'boolean' || x === false);
72
+ }
73
+ }
@@ -11,7 +11,7 @@ export default class TrustArcFrame extends AutoConsentCMPBase {
11
11
  runContext: RunContext = {
12
12
  main: false,
13
13
  frame: true,
14
- url: "https://consent-pref.trustarc.com/?",
14
+ urlPattern: "^https://consent-pref\\.trustarc\\.com/\\?",
15
15
  }
16
16
 
17
17
  get hasSelfTest(): boolean {
@@ -100,6 +100,9 @@ export default class TrustArcFrame extends AutoConsentCMPBase {
100
100
  }
101
101
 
102
102
  async optIn() {
103
+ if (click('.call')) {
104
+ return true;
105
+ }
103
106
  await this.navigateToSettings();
104
107
  click(".switch span:nth-child(2)", true);
105
108
 
@@ -7,7 +7,7 @@ export default class Uniconsent extends AutoConsentCMPBase {
7
7
  }
8
8
 
9
9
  get prehideSelectors(): string[] {
10
- return ['.unic'];
10
+ return ['.unic', '.modal:has(.unic)'];
11
11
  }
12
12
 
13
13
  get hasSelfTest(): boolean {
@@ -49,6 +49,7 @@ export default class Uniconsent extends AutoConsentCMPBase {
49
49
  for (const pattern of ['Confirm Choices', 'Save Choices', 'Auswahl speichern']) {
50
50
  if (text.includes(pattern)) {
51
51
  b.click();
52
+ await wait(500); // give it some time to close the popup
52
53
  return true;
53
54
  }
54
55
  }
@@ -31,21 +31,21 @@ export function elementExists(selector: string): boolean {
31
31
 
32
32
  export function elementVisible(selector: string, check: VisibilityCheck): boolean {
33
33
  const elem = document.querySelectorAll<HTMLElement>(selector);
34
- const results = new Array(elem.length);
35
- elem.forEach((e, i) => {
36
- // check for display: none
37
- results[i] = isElementVisible(e);
38
- });
39
- // enableLogs && console.log("[visible?]", selector, check, elem, results);
40
- if (results.length === 0) {
41
- return false;
42
- } else if (check === "any") {
43
- return results.some(r => r);
44
- } else if (check === "none") {
45
- return results.every(r => !r);
46
- }
47
- // all
48
- return results.every(r => r);
34
+ const results = new Array(elem.length);
35
+ elem.forEach((e, i) => {
36
+ // check for display: none
37
+ results[i] = isElementVisible(e);
38
+ });
39
+ // enableLogs && console.log("[visible?]", selector, check, elem, results);
40
+ if (check === "none") {
41
+ return results.every(r => !r);
42
+ } else if (results.length === 0) {
43
+ return false;
44
+ } else if (check === "any") {
45
+ return results.some(r => r);
46
+ }
47
+ // all
48
+ return results.every(r => r);
49
49
  }
50
50
 
51
51
  export function waitForElement(selector: string, timeout = 10000): Promise<boolean> {
package/lib/rules.ts CHANGED
@@ -14,7 +14,7 @@ export type AutoConsentCMPRule = {
14
14
  export type RunContext = {
15
15
  main?: boolean,
16
16
  frame?: boolean,
17
- url?: string,
17
+ urlPattern?: string,
18
18
  }
19
19
 
20
20
  export type AutoConsentRuleStep = { optional?: boolean } & Partial<
package/lib/web.ts CHANGED
@@ -134,7 +134,17 @@ export default class AutoConsent {
134
134
  }));
135
135
  }
136
136
 
137
- const somethingOpen = await Promise.any(popupLookups).catch(() => false);
137
+ // could use `somethingOpen = await Promise.any(popupLookups).catch(() => false)`, but Promise.any is often unavailable in polyfilled environments
138
+ let somethingOpen = false;
139
+ for (const popupLookup of popupLookups) {
140
+ try {
141
+ await popupLookup;
142
+ somethingOpen = true;
143
+ break;
144
+ } catch (e) {
145
+ continue;
146
+ }
147
+ }
138
148
 
139
149
  if (!somethingOpen) {
140
150
  enableLogs && console.log('no popup found');
@@ -324,6 +334,9 @@ export default class AutoConsent {
324
334
  case 'initResp':
325
335
  this.initialize(message.config, message.rules);
326
336
  break;
337
+ case 'optIn':
338
+ await this.doOptIn();
339
+ break;
327
340
  case 'optOut':
328
341
  await this.doOptOut();
329
342
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duckduckgo/autoconsent",
3
- "version": "2.2.0",
3
+ "version": "3.0.0",
4
4
  "description": "",
5
5
  "main": "dist/autoconsent.cjs.js",
6
6
  "module": "dist/autoconsent.esm.js",
@@ -36,7 +36,7 @@
36
36
  "chai": "^4.2.0",
37
37
  "eslint-config-airbnb": "^19.0.4",
38
38
  "mocha": "^10.0.0",
39
- "rollup": "^2.73.0",
39
+ "rollup": "^2.79.1",
40
40
  "rollup-plugin-copy": "^3.4.0",
41
41
  "rollup-plugin-terser": "^7.0.2",
42
42
  "tslib": "^2.4.0",
@@ -14,6 +14,7 @@ type TestOptions = {
14
14
  testOptIn: boolean;
15
15
  skipRegions?: string[];
16
16
  onlyRegions?: string[];
17
+ mobile: boolean;
17
18
  };
18
19
  const defaultOptions: TestOptions = {
19
20
  testOptOut: true,
@@ -21,6 +22,7 @@ const defaultOptions: TestOptions = {
21
22
  testSelfTest: true,
22
23
  skipRegions: [],
23
24
  onlyRegions: [],
25
+ mobile: false,
24
26
  };
25
27
 
26
28
  const contentScript = fs.readFileSync(
@@ -33,7 +35,7 @@ export async function injectContentScript(page: Page | Frame) {
33
35
  await page.evaluate(contentScript);
34
36
  } catch (e) {
35
37
  // frame was detached
36
- // console.log(e);
38
+ // console.trace(e);
37
39
  }
38
40
  }
39
41
 
@@ -43,13 +45,17 @@ export function generateTest(
43
45
  options: TestOptions = defaultOptions
44
46
  ) {
45
47
  function genTest(autoAction: AutoAction) {
46
- test(`${url.split("://")[1]} .${testRegion} ${autoAction}`, async ({ page }) => {
48
+ test(`${url.split("://")[1]} .${testRegion} ${autoAction} ${options.mobile ? 'mobile' : ''}`, async ({ page }, { project }) => {
47
49
  if (options.onlyRegions && options.onlyRegions.length > 0 && !options.onlyRegions.includes(testRegion)) {
48
50
  test.skip();
49
51
  }
50
52
  if (options.skipRegions && options.skipRegions.includes(testRegion)) {
51
53
  test.skip();
52
54
  }
55
+ if (options.mobile && !project.use.isMobile || !options.mobile && project.use.isMobile) {
56
+ test.skip();
57
+ }
58
+
53
59
  enableLogs && page.on('console', async msg => {
54
60
  console.log(` page log:`, msg.text());
55
61
  });
@@ -19,6 +19,15 @@ const config: PlaywrightTestConfig = {
19
19
  userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15',
20
20
  },
21
21
  },
22
+ {
23
+ name: 'iphoneSE',
24
+ use: {
25
+ ...devices['iPhone SE'],
26
+ proxy,
27
+ screenshot: 'only-on-failure',
28
+ userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
29
+ },
30
+ },
22
31
  {
23
32
  name: 'firefox',
24
33
  use: {
package/readme.md CHANGED
@@ -71,7 +71,7 @@ Both JSON and class implementations have the following components:
71
71
  * (optional) `runContext` - an object describing when this rule should be tried:
72
72
  * `main` - boolean, set to `true` if the rule should be executed in top-level documents (default: `true`)
73
73
  * `frame` - boolean, set to `true` if the rule should be executed in nested frames (default: `false`)
74
- * `url` - string, specifies a string prefix that should match the page URL (default: empty)
74
+ * `urlPattern` - string, specifies a regular expression that should match the page URL (default: empty)
75
75
  * (optional) `test` - a list of actions to verify a successful opt-out. This is currently only used in Playwright tests.
76
76
 
77
77
 
@@ -192,3 +192,7 @@ See [this document](/api.md) for more details on internal APIs.
192
192
  ## License
193
193
 
194
194
  MPLv2.
195
+
196
+ ## Manual Testing
197
+
198
+ To test the extension / addon with Firefox, open the `about:debugging`, navigate to "This Firefox" on the menu and under "Temporary Extensions" click on "Load Temporary Addon". Select the `manifest.json` file from the `dist/firefox` directory. You will need to build the extension before as described above. The extension should then be active and you can test it manually by simply visiting websites.
package/rollup.config.js CHANGED
@@ -44,9 +44,13 @@ export default [{
44
44
  copy({
45
45
  targets: [
46
46
  {
47
- src: ['./addon/icons', './rules/rules.json'],
47
+ src: ['./addon/icons', './rules/rules.json'],
48
48
  dest: ['./dist/addon-firefox/', './dist/addon-mv3/']
49
49
  },
50
+ {
51
+ src: ['./addon/popup.html'],
52
+ dest: ['./dist/addon-mv3/']
53
+ },
50
54
  {
51
55
  src: './addon/manifest.mv3.json',
52
56
  dest: './dist/addon-mv3',
@@ -73,4 +77,14 @@ export default [{
73
77
  typescript(),
74
78
  terser(),
75
79
  ],
76
- }];
80
+ }, {
81
+ input: './addon/popup.ts',
82
+ output: [{
83
+ file: './dist/addon-mv3/popup.bundle.js',
84
+ format: 'iife',
85
+ }],
86
+ plugins: [
87
+ typescript(),
88
+ terser(),
89
+ ],
90
+ }];
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "amazon.com",
3
+ "prehideSelectors": ["span[data-action=\"sp-cc\"][data-sp-cc*=\"rejectAllAction\"]"],
4
+ "detectCmp": [
5
+ { "exists": "span[data-action=\"sp-cc\"][data-sp-cc*=\"rejectAllAction\"]" }
6
+ ],
7
+ "detectPopup": [
8
+ { "visible": "span[data-action=\"sp-cc\"][data-sp-cc*=\"rejectAllAction\"]" }
9
+ ],
10
+ "optIn": [
11
+ { "waitForVisible": "#sp-cc-accept" },
12
+ { "wait": 500 },
13
+ { "click": "#sp-cc-accept" }
14
+ ],
15
+ "optOut": [
16
+ { "waitForVisible": "#sp-cc-rejectall-link" },
17
+ { "wait": 500 },
18
+ { "click": "#sp-cc-rejectall-link" }
19
+ ]
20
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "dailymotion.com",
3
+ "runContext": {
4
+ "urlPattern": "^https://(www\\.)?dailymotion\\.com/"
5
+ },
6
+ "prehideSelectors": ["div[class*=\"Overlay__container\"]:has(div[class*=\"TCF2Popup\"])"],
7
+ "detectCmp": [
8
+ { "exists": "div[class*=\"TCF2Popup\"]" }
9
+ ],
10
+ "detectPopup": [
11
+ { "visible": "[class*=\"TCF2Popup\"] a[href^=\"https://www.dailymotion.com/legal/cookiemanagement\"]" }
12
+ ],
13
+ "optIn": [
14
+ { "waitForThenClick": "button[class*=\"TCF2Popup__button\"]:not([class*=\"TCF2Popup__personalize\"])" }
15
+ ],
16
+ "optOut": [
17
+ { "waitForThenClick": "button[class*=\"TCF2ContinueWithoutAcceptingButton\"]" }
18
+ ],
19
+ "test": [
20
+ { "eval": "!!document.cookie.match('dm-euconsent-v2')" }
21
+ ]
22
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "dmgmedia",
3
+ "prehideSelectors": ["[data-project=\"mol-fe-cmp\"]"],
4
+ "detectCmp": [
5
+ { "exists": "[data-project=\"mol-fe-cmp\"]" }
6
+ ],
7
+ "detectPopup": [
8
+ { "visible": "[data-project=\"mol-fe-cmp\"]" }
9
+ ],
10
+ "optIn": [
11
+ { "waitForThenClick": "[data-project=\"mol-fe-cmp\"] button[class*=primary]" }
12
+ ],
13
+ "optOut": [
14
+ { "waitForThenClick": "[data-project=\"mol-fe-cmp\"] button[class*=basic]" },
15
+ { "waitForVisible": "[data-project=\"mol-fe-cmp\"] div[class*=\"tabContent\"]" },
16
+ { "waitForThenClick": "[data-project=\"mol-fe-cmp\"] div[class*=\"toggle\"][class*=\"enabled\"]", "all": true },
17
+ { "waitForThenClick": "[data-project=\"mol-fe-cmp\"] button[class*=white]" }
18
+ ]
19
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "facebook",
3
+ "runContext": {
4
+ "urlPattern": "^https://([a-z0-9-]+\\.)?facebook\\.com/"
5
+ },
6
+ "prehideSelectors": ["div[data-testid=\"cookie-policy-manage-dialog\"]"],
7
+ "detectCmp": [
8
+ { "exists": "div[data-testid=\"cookie-policy-manage-dialog\"]" }
9
+ ],
10
+ "detectPopup": [
11
+ { "visible": "div[data-testid=\"cookie-policy-manage-dialog\"]" }
12
+ ],
13
+ "optIn": [
14
+ { "waitForThenClick": "button[data-cookiebanner=\"accept_button\"]" },
15
+ { "waitForVisible": "div[data-testid=\"cookie-policy-manage-dialog\"]", "check": "none" }
16
+ ],
17
+ "optOut": [
18
+ { "waitForThenClick": "button[data-cookiebanner=\"accept_only_essential_button\"]" },
19
+ { "waitForVisible": "div[data-testid=\"cookie-policy-manage-dialog\"]", "check": "none" }
20
+ ]
21
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "google-consent-standalone",
3
+ "prehideSelectors": [],
4
+ "detectCmp": [
5
+ { "exists": "a[href^=\"https://policies.google.com/technologies/cookies\"" },
6
+ { "exists": "form[action^=\"https://consent.\"][action$=\".com/save\"]" }
7
+ ],
8
+ "detectPopup": [
9
+ { "visible": "a[href^=\"https://policies.google.com/technologies/cookies\"" }
10
+ ],
11
+ "optIn": [
12
+ { "waitForThenClick": "form[action^=\"https://consent.\"][action$=\".com/save\"]:has(input[name=set_eom][value=false]) button" }
13
+ ],
14
+ "optOut": [
15
+ { "waitForThenClick": "form[action^=\"https://consent.\"][action$=\".com/save\"]:has(input[name=set_eom][value=true]) button" }
16
+ ]
17
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "google.com",
3
+ "prehideSelectors": [".HTjtHe#xe7COe"],
4
+ "detectCmp": [
5
+ { "exists": ".HTjtHe#xe7COe" },
6
+ { "exists": ".HTjtHe#xe7COe a[href^=\"https://policies.google.com/technologies/cookies\"]" }
7
+ ],
8
+ "detectPopup": [
9
+ { "visible": ".HTjtHe#xe7COe button#W0wltc" }
10
+ ],
11
+ "optIn": [
12
+ { "waitForThenClick": ".HTjtHe#xe7COe button#L2AGLb" }
13
+ ],
14
+ "optOut": [
15
+ {
16
+ "waitForThenClick": ".HTjtHe#xe7COe button#W0wltc"
17
+ }
18
+ ],
19
+ "test": [
20
+ { "eval": "!!document.cookie.match(/SOCS=CAE/)" }
21
+ ]
22
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "linkedin.com",
3
+ "prehideSelectors": [".artdeco-global-alert[type=COOKIE_CONSENT]"],
4
+ "detectCmp": [
5
+ { "exists": ".artdeco-global-alert[type=COOKIE_CONSENT]" }
6
+ ],
7
+ "detectPopup": [
8
+ { "visible": ".artdeco-global-alert[type=COOKIE_CONSENT]" }
9
+ ],
10
+ "optIn": [
11
+ { "waitForVisible": ".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=ACCEPT]" },
12
+ { "wait": 500 },
13
+ { "waitForThenClick": ".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=ACCEPT]" }
14
+ ],
15
+ "optOut": [
16
+ { "waitForVisible": ".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=DENY]" },
17
+ { "wait": 500 },
18
+ { "waitForThenClick": ".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=DENY]" }
19
+ ],
20
+ "test": [
21
+ { "waitForVisible": ".artdeco-global-alert[type=COOKIE_CONSENT]", "check": "none" }
22
+ ]
23
+ }
@@ -8,15 +8,10 @@
8
8
  {
9
9
  "exists": "a[href*=\"monzo\"]"
10
10
  }
11
- ],
11
+ ],
12
12
  "detectPopup": [{ "visible": ".cookie-alert__content" }],
13
13
  "optIn": [{ "click": ".js-accept-cookie-policy" }],
14
14
  "optOut": [
15
15
  {"click": ".js-decline-cookie-policy"}
16
- ],
17
- "test": [
18
- {
19
- "eval": "document.cookie.includes('_cookies_banner_dismissed=true') && !document.cookie.includes('_cookie_advertising_accepted')"
20
- }
21
16
  ]
22
17
  }
@@ -14,7 +14,7 @@
14
14
  "then": [
15
15
  { "click": "#moove_gdpr_cookie_info_bar .change-settings-button" },
16
16
  { "waitForVisible": "#moove_gdpr_cookie_modal" },
17
- { "eval": "document.querySelectorAll('#moove_gdpr_cookie_modal input').forEach(i => { if (!i.disabled) i.checked = false }) || true" },
17
+ { "eval": "document.querySelectorAll('#moove_gdpr_cookie_modal input').forEach(i => { if (!i.disabled && i.name !== 'moove_gdpr_strict_cookies') i.checked = false }) || true" },
18
18
  { "click": ".moove-gdpr-modal-save-settings" }
19
19
  ],
20
20
  "else": [
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "privacymanager.io",
3
+ "prehideSelectors": ["#gdpr-consent-tool-wrapper", "iframe[src^=\"https://cmp-consent-tool.privacymanager.io\"]"],
4
+ "runContext": {
5
+ "urlPattern": "^https://cmp-consent-tool\\.privacymanager\\.io/",
6
+ "main": false,
7
+ "frame": true
8
+ },
9
+ "detectCmp": [{ "exists": "button#save" }],
10
+ "detectPopup": [{ "visible": "button#save" }],
11
+ "optIn": [{
12
+ "click": "button#save"
13
+ }],
14
+ "optOut": [
15
+ {
16
+ "if": { "exists": "#denyAll" },
17
+ "then": [
18
+ { "click": "#denyAll" },
19
+ { "waitForThenClick": ".okButton" }
20
+ ],
21
+ "else": [
22
+ { "waitForThenClick": "#manageSettings" },
23
+ { "waitFor": ".purposes-overview-list" },
24
+ { "waitFor": "button#saveAndExit" },
25
+ { "click": "span[role=checkbox][aria-checked=true]", "all": true, "optional": true },
26
+ { "click": "button#saveAndExit" }
27
+ ]
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "pubtech",
3
+ "prehideSelectors": ["#pubtech-cmp"],
4
+ "detectCmp": [
5
+ {
6
+ "exists": "#pubtech-cmp"
7
+ }
8
+ ],
9
+ "detectPopup": [
10
+ {
11
+ "visible": "#pubtech-cmp #pt-actions"
12
+ }
13
+ ],
14
+ "optIn": [
15
+ {
16
+ "if": {
17
+ "exists": "#pt-accept-all"
18
+ },
19
+ "then": [
20
+ {
21
+ "click": "#pubtech-cmp #pt-actions #pt-accept-all"
22
+ }
23
+ ],
24
+ "else": [
25
+ {
26
+ "click": "#pubtech-cmp #pt-actions button:nth-of-type(2)"
27
+ }
28
+ ]
29
+ }
30
+ ],
31
+ "optOut": [
32
+
33
+ {
34
+ "click": "#pubtech-cmp #pt-close"
35
+ }
36
+ ],
37
+ "test": [
38
+ {
39
+ "eval": "document.cookie.includes('euconsent-v2') && (document.cookie.match(/.YAAAAAAAAAAA/) || document.cookie.match(/.aAAAAAAAAAAA/) || document.cookie.match(/.YAAACFgAAAAA/)) "
40
+ }
41
+ ]
42
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "reddit.com",
3
+ "runContext": {
4
+ "urlPattern": "^https://www\\.reddit\\.com/"
5
+ },
6
+ "prehideSelectors": ["section:has(section > span > a[href^=\"https://www.reddit.com/policies/cookies\"])"],
7
+ "detectCmp": [
8
+ { "exists": "section:has(> span > a[href^=\"https://www.reddit.com/policies/cookies\"])" }
9
+ ],
10
+ "detectPopup": [
11
+ { "visible": "section:has(> span > a[href^=\"https://www.reddit.com/policies/cookies\"])" }
12
+ ],
13
+ "optIn": [
14
+ { "waitForThenClick": "section:has(> span > a[href^=\"https://www.reddit.com/policies/cookies\"]) section form:last-child button" }
15
+ ],
16
+ "optOut": [
17
+ { "waitForThenClick": "section:has(> span > a[href^=\"https://www.reddit.com/policies/cookies\"]) section form:first-child button" }
18
+ ],
19
+ "test": [
20
+ {"eval": "document.cookie.includes('eu_cookie={%22opted%22:true%2C%22nonessential%22:false}')"}
21
+ ]
22
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "sibbo",
3
+ "prehideSelectors": ["sibbo-cmp-layout"],
4
+ "detectCmp": [{ "exists": "sibbo-cmp-layout" }],
5
+ "detectPopup": [{ "visible": "sibbo-cmp-layout" }],
6
+ "optIn": [{ "click": "sibbo-cmp-layout [data-accept-all]" }],
7
+ "optOut": [
8
+ {
9
+ "click": ".sibbo-panel__aside__buttons a[data-nav=\"purposes\"]"
10
+ },
11
+ {
12
+ "click": ".sibbo-panel__main__header__actions a[data-focusable=\"reject-all\"]"
13
+ },
14
+ {
15
+ "if": {
16
+ "exists": "[data-view=purposes] .sibbo-panel__main__footer__actions [data-save-and-exit]"
17
+ },
18
+ "then": [],
19
+ "else": [
20
+ {
21
+ "waitFor": ".sibbo-panel__main__footer__actions a[data-focusable=\"next\"]:not(.sibbo-cmp-button--disabled)"
22
+ },
23
+ {
24
+ "click": ".sibbo-panel__main__footer__actions a[data-focusable=\"next\"]"
25
+ },
26
+ {
27
+ "click": ".sibbo-panel__main div[data-view=\"purposesLegInt\"] a[data-focusable=\"reject-all\"]"
28
+ }
29
+ ]
30
+ },
31
+ {
32
+ "waitFor": ".sibbo-panel__main__footer__actions [data-save-and-exit]:not(.sibbo-cmp-button--disabled)"
33
+ },
34
+ {
35
+ "click": ".sibbo-panel__main__footer__actions [data-save-and-exit]:not(.sibbo-cmp-button--disabled)"
36
+ }
37
+ ],
38
+ "test": [
39
+ {
40
+ "eval": "!!window.localStorage.getItem('euconsent-v2')"
41
+ }
42
+ ]
43
+ }