@duckduckgo/autoconsent 1.0.6 → 2.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 (165) hide show
  1. package/.eslintrc.cjs +14 -0
  2. package/.vscode/settings.json +7 -0
  3. package/Jenkinsfile +68 -39
  4. package/api.md +104 -0
  5. package/dist/autoconsent.cjs.js +1 -1371
  6. package/dist/autoconsent.esm.js +1 -1363
  7. package/dist/autoconsent.playwright.js +1 -0
  8. package/dist/autoconsent.standalone.js +1 -0
  9. package/lib/cmps/all.ts +15 -10
  10. package/lib/cmps/base.ts +91 -91
  11. package/lib/cmps/consentmanager.ts +31 -19
  12. package/lib/cmps/consentomatic.ts +89 -0
  13. package/lib/cmps/cookiebot.ts +62 -53
  14. package/lib/cmps/evidon.ts +29 -18
  15. package/lib/cmps/onetrust.ts +37 -19
  16. package/lib/cmps/sourcepoint-frame.ts +102 -0
  17. package/lib/cmps/sourcepoint-top.ts +47 -0
  18. package/lib/cmps/trustarc-frame.ts +115 -0
  19. package/lib/cmps/trustarc-top.ts +91 -0
  20. package/lib/consentomatic/index.ts +233 -70
  21. package/lib/{web/consentomatic → consentomatic}/tools.ts +0 -0
  22. package/lib/eval-handler.ts +58 -0
  23. package/lib/index.ts +0 -2
  24. package/lib/messages.ts +100 -0
  25. package/lib/rule-executors.ts +108 -0
  26. package/lib/rules.ts +82 -0
  27. package/lib/types.ts +35 -0
  28. package/lib/utils.ts +64 -0
  29. package/lib/web.ts +283 -74
  30. package/package.json +17 -14
  31. package/playwright/content.ts +27 -0
  32. package/playwright/runner.ts +131 -0
  33. package/playwright/standalone.ts +36 -0
  34. package/playwright.config.ts +7 -0
  35. package/readme.md +57 -47
  36. package/rollup.config.js +23 -15
  37. package/rules/autoconsent/192.json +17 -0
  38. package/rules/autoconsent/ausopen.json +7 -0
  39. package/rules/autoconsent/aws-amazon.json +1 -1
  40. package/rules/autoconsent/baden-wuerttemberg-de.json +7 -3
  41. package/rules/autoconsent/bing.json +14 -0
  42. package/rules/autoconsent/bundesregierung-de.json +6 -2
  43. package/rules/autoconsent/cc-banner.json +0 -1
  44. package/rules/autoconsent/cookie-notice.json +0 -1
  45. package/rules/autoconsent/cookieconsent.json +5 -6
  46. package/rules/autoconsent/destatis-de.json +0 -1
  47. package/rules/autoconsent/dunelm.json +18 -0
  48. package/rules/autoconsent/etsy.json +3 -2
  49. package/rules/autoconsent/eu-cookie-compliance.json +0 -1
  50. package/rules/autoconsent/gov-uk.json +10 -0
  51. package/rules/autoconsent/hl-co-uk.json +8 -9
  52. package/rules/autoconsent/johnlewis.json +5 -2
  53. package/rules/autoconsent/marksandspencer.json +7 -0
  54. package/rules/autoconsent/notice-cookie.json +0 -1
  55. package/rules/autoconsent/osano.json +0 -1
  56. package/rules/autoconsent/{paypal-de.json → paypal.json} +6 -2
  57. package/rules/autoconsent/tealium.json +4 -5
  58. package/rules/autoconsent/uswitch.json +8 -0
  59. package/rules/autoconsent/waitrose.json +28 -0
  60. package/rules/autoconsent/wetransfer.json +7 -0
  61. package/rules/rules.json +314 -39
  62. package/tests/192.spec.ts +7 -0
  63. package/tests/arzt-auskunft.spec.ts +1 -1
  64. package/tests/asus.spec.ts +1 -1
  65. package/tests/ausopen.spec.ts +7 -0
  66. package/tests/aws.amazon.spec.ts +1 -1
  67. package/tests/baden-wuerttemberg.spec.ts +1 -1
  68. package/tests/borlabs.spec.ts +1 -1
  69. package/tests/bundesregierung.spec.ts +5 -2
  70. package/tests/ccbanner.spec.ts +1 -1
  71. package/tests/consentmanager.spec.ts +3 -3
  72. package/tests/cookiebot.spec.ts +8 -1
  73. package/tests/cookieconsent.spec.ts +1 -1
  74. package/tests/cookielawinfo.spec.ts +1 -1
  75. package/tests/cookienotice.spec.ts +1 -1
  76. package/tests/corona-in-zahlen.spec.ts +1 -1
  77. package/tests/deepl.spec.ts +1 -1
  78. package/tests/destatis.spec.ts +1 -1
  79. package/tests/didomi.spec.ts +6 -2
  80. package/tests/drupal.spec.ts +8 -0
  81. package/tests/dunelm.spec.ts +7 -0
  82. package/tests/etsy.spec.ts +1 -1
  83. package/tests/eu-cookie-compliance-banner.spec.ts +1 -1
  84. package/tests/evidon.spec.ts +1 -1
  85. package/tests/fundingchoices.spec.ts +2 -1
  86. package/tests/gov-uk.spec.ts +9 -0
  87. package/tests/hl-co-uk.spec.ts +1 -1
  88. package/tests/hubspot.spec.ts +1 -1
  89. package/tests/ionos.spec.ts +1 -1
  90. package/tests/johnlewis.spec.ts +2 -2
  91. package/tests/klaro.spec.ts +1 -1
  92. package/tests/marksandspencer.spec.ts +7 -0
  93. package/tests/mediamarkt.spec.ts +1 -1
  94. package/tests/metoffice-gov-uk.spec.ts +1 -1
  95. package/tests/microsoft.spec.ts +1 -1
  96. package/tests/moneysavingexpert.spec.ts +1 -1
  97. package/tests/motor-talk.spec.ts +1 -1
  98. package/tests/national-lottery.spec.ts +1 -1
  99. package/tests/netflix.spec.ts +1 -1
  100. package/tests/nhs.spec.ts +1 -1
  101. package/tests/notice-cookie.spec.ts +1 -1
  102. package/tests/obi.spec.ts +1 -1
  103. package/tests/oil.spec.ts +1 -1
  104. package/tests/onetrust.spec.ts +10 -1
  105. package/tests/osano.spec.ts +1 -1
  106. package/tests/otto.spec.ts +1 -1
  107. package/tests/paypal.spec.ts +8 -6
  108. package/tests/quantcast.spec.ts +4 -1
  109. package/tests/snigel.spec.ts +1 -1
  110. package/tests/sourcepoint.spec.ts +8 -8
  111. package/tests/springer.spec.ts +1 -1
  112. package/tests/steampowered.spec.ts +1 -1
  113. package/tests/tealium.spec.ts +1 -1
  114. package/tests/testcmp.spec.ts +1 -1
  115. package/tests/thalia.spec.ts +1 -1
  116. package/tests/thefreedictionary.spec.ts +1 -1
  117. package/tests/trustarc.spec.ts +25 -3
  118. package/tests/usercentrics-1.spec.ts +1 -1
  119. package/tests/uswitch.spec.ts +7 -0
  120. package/tests/vodafone.spec.ts +1 -1
  121. package/tests/waitrose.spec.ts +7 -0
  122. package/tests/wetransfer.spec.ts +7 -0
  123. package/tests/wordpressgdpr.spec.ts +1 -1
  124. package/tests/xing.spec.ts +1 -1
  125. package/tsconfig.json +2 -2
  126. package/.eslintrc +0 -12
  127. package/cosmetics/rules.json +0 -110
  128. package/dist/autoconsent.puppet.js +0 -1072
  129. package/lib/cmps/all.js +0 -19
  130. package/lib/cmps/base.js +0 -174
  131. package/lib/cmps/consentmanager.js +0 -31
  132. package/lib/cmps/cookiebot.js +0 -73
  133. package/lib/cmps/evidon.js +0 -26
  134. package/lib/cmps/onetrust.js +0 -32
  135. package/lib/cmps/sourcepoint.js +0 -82
  136. package/lib/cmps/sourcepoint.ts +0 -95
  137. package/lib/cmps/trustarc.js +0 -106
  138. package/lib/cmps/trustarc.ts +0 -147
  139. package/lib/config.js +0 -1
  140. package/lib/consentomatic/index.js +0 -52
  141. package/lib/detector.js +0 -33
  142. package/lib/detector.ts +0 -34
  143. package/lib/hider.js +0 -13
  144. package/lib/hider.ts +0 -16
  145. package/lib/index.js +0 -4
  146. package/lib/messages.d.ts +0 -61
  147. package/lib/node.js +0 -35
  148. package/lib/node.ts +0 -43
  149. package/lib/puppet/tab.js +0 -121
  150. package/lib/puppet/tab.ts +0 -146
  151. package/lib/rules.d.ts +0 -80
  152. package/lib/tabwrapper.js +0 -67
  153. package/lib/tabwrapper.ts +0 -74
  154. package/lib/types.d.ts +0 -61
  155. package/lib/web/consentomatic/index.js +0 -188
  156. package/lib/web/consentomatic/index.ts +0 -249
  157. package/lib/web/consentomatic/tools.js +0 -177
  158. package/lib/web/content-utils.js +0 -29
  159. package/lib/web/content-utils.ts +0 -31
  160. package/lib/web/content.js +0 -79
  161. package/lib/web/content.ts +0 -71
  162. package/lib/web/tab.js +0 -112
  163. package/lib/web/tab.ts +0 -178
  164. package/lib/web.js +0 -95
  165. package/tests/runner.ts +0 -61
package/lib/cmps/all.js DELETED
@@ -1,19 +0,0 @@
1
- import { AutoConsent } from './base';
2
- import TrustArc from './trustarc';
3
- import CookieBot from './cookiebot';
4
- import SourcePoint from './sourcepoint';
5
- import ContentManager from './consentmanager';
6
- import Evidon from './evidon';
7
- import Onetrust from './onetrust';
8
- const rules = [
9
- new TrustArc(),
10
- new CookieBot(),
11
- new SourcePoint(),
12
- new ContentManager(),
13
- new Evidon(),
14
- new Onetrust(),
15
- ];
16
- export function createAutoCMP(config) {
17
- return new AutoConsent(config);
18
- }
19
- export default rules;
package/lib/cmps/base.js DELETED
@@ -1,174 +0,0 @@
1
- /* eslint-disable no-restricted-syntax,no-await-in-loop,no-underscore-dangle */
2
- import { enableLogs } from "../config";
3
- export async function waitFor(predicate, maxTimes, interval) {
4
- let result = await predicate();
5
- if (!result && maxTimes > 0) {
6
- return new Promise((resolve) => {
7
- setTimeout(async () => {
8
- resolve(waitFor(predicate, maxTimes - 1, interval));
9
- }, interval);
10
- });
11
- }
12
- return Promise.resolve(result);
13
- }
14
- export async function success(action) {
15
- const result = await action;
16
- if (!result) {
17
- throw new Error(`Action failed: ${action} ${result}`);
18
- }
19
- return result;
20
- }
21
- export default class AutoConsentBase {
22
- constructor(name) {
23
- this.hasSelfTest = true;
24
- this.name = name;
25
- }
26
- detectCmp(tab) {
27
- throw new Error('Not Implemented');
28
- }
29
- async detectPopup(tab) {
30
- return false;
31
- }
32
- detectFrame(tab, frame) {
33
- return false;
34
- }
35
- optOut(tab) {
36
- throw new Error('Not Implemented');
37
- }
38
- optIn(tab) {
39
- throw new Error('Not Implemented');
40
- }
41
- openCmp(tab) {
42
- throw new Error('Not Implemented');
43
- }
44
- async test(tab) {
45
- // try IAB by default
46
- return Promise.resolve(true);
47
- }
48
- }
49
- async function evaluateRule(rule, tab) {
50
- if (rule.frame && !tab.frame) {
51
- await waitFor(() => Promise.resolve(!!tab.frame), 10, 500);
52
- }
53
- const frameId = rule.frame && tab.frame ? tab.frame.id : undefined;
54
- const results = [];
55
- if (rule.exists) {
56
- results.push(tab.elementExists(rule.exists, frameId));
57
- }
58
- if (rule.visible) {
59
- results.push(tab.elementsAreVisible(rule.visible, rule.check, frameId));
60
- }
61
- if (rule.eval) {
62
- results.push(new Promise(async (resolve) => {
63
- // catch eval error silently
64
- try {
65
- resolve(await tab.eval(rule.eval, frameId));
66
- }
67
- catch (e) {
68
- resolve(false);
69
- }
70
- }));
71
- }
72
- if (rule.waitFor) {
73
- results.push(tab.waitForElement(rule.waitFor, rule.timeout || 10000, frameId));
74
- }
75
- if (rule.click) {
76
- if (rule.all === true) {
77
- results.push(tab.clickElements(rule.click, frameId));
78
- }
79
- else {
80
- results.push(tab.clickElement(rule.click, frameId));
81
- }
82
- }
83
- if (rule.waitForThenClick) {
84
- results.push(tab.waitForElement(rule.waitForThenClick, rule.timeout || 10000, frameId)
85
- .then(() => tab.clickElement(rule.waitForThenClick, frameId)));
86
- }
87
- if (rule.wait) {
88
- results.push(tab.wait(rule.wait));
89
- }
90
- if (rule.goto) {
91
- results.push(tab.goto(rule.goto));
92
- }
93
- if (rule.hide) {
94
- results.push(tab.hideElements(rule.hide, frameId));
95
- }
96
- if (rule.undoHide) {
97
- results.push(tab.undoHideElements(frameId));
98
- }
99
- if (rule.waitForFrame) {
100
- results.push(waitFor(() => !!tab.frame, 40, 500));
101
- }
102
- // boolean and of results
103
- return (await Promise.all(results)).reduce((a, b) => a && b, true);
104
- }
105
- export class AutoConsent extends AutoConsentBase {
106
- constructor(config) {
107
- super(config.name);
108
- this.config = config;
109
- }
110
- get prehideSelectors() {
111
- return this.config.prehideSelectors;
112
- }
113
- get isHidingRule() {
114
- return this.config.isHidingRule;
115
- }
116
- async _runRulesParallel(tab, rules) {
117
- const detections = await Promise.all(rules.map(rule => evaluateRule(rule, tab)));
118
- return detections.every(r => !!r);
119
- }
120
- async _runRulesSequentially(tab, rules) {
121
- for (const rule of rules) {
122
- enableLogs && console.log('Running rule...', rule, tab.id);
123
- const result = await evaluateRule(rule, tab);
124
- enableLogs && console.log('...rule result', result);
125
- if (!result && !rule.optional) {
126
- return false;
127
- }
128
- }
129
- return true;
130
- }
131
- async detectCmp(tab) {
132
- if (this.config.detectCmp) {
133
- return this._runRulesParallel(tab, this.config.detectCmp);
134
- }
135
- return false;
136
- }
137
- async detectPopup(tab) {
138
- if (this.config.detectPopup) {
139
- return this._runRulesParallel(tab, this.config.detectPopup);
140
- }
141
- return false;
142
- }
143
- detectFrame(tab, frame) {
144
- if (this.config.frame) {
145
- return frame.url.startsWith(this.config.frame);
146
- }
147
- return false;
148
- }
149
- async optOut(tab) {
150
- if (this.config.optOut) {
151
- enableLogs && console.log('Initiated optOut()', this.config.optOut);
152
- return this._runRulesSequentially(tab, this.config.optOut);
153
- }
154
- return false;
155
- }
156
- async optIn(tab) {
157
- if (this.config.optIn) {
158
- return this._runRulesSequentially(tab, this.config.optIn);
159
- }
160
- return false;
161
- }
162
- async openCmp(tab) {
163
- if (this.config.openCmp) {
164
- return this._runRulesSequentially(tab, this.config.openCmp);
165
- }
166
- return false;
167
- }
168
- async test(tab) {
169
- if (this.config.test) {
170
- return this._runRulesSequentially(tab, this.config.test);
171
- }
172
- return super.test(tab);
173
- }
174
- }
@@ -1,31 +0,0 @@
1
- import AutoConsentBase from "./base";
2
- // Note: JS API is also available:
3
- // https://help.consentmanager.net/books/cmp/page/javascript-api
4
- export default class ConsentManager extends AutoConsentBase {
5
- constructor() {
6
- super("consentmanager.net");
7
- this.prehideSelectors = ["#cmpbox,#cmpbox2"];
8
- }
9
- detectCmp(tab) {
10
- return tab.elementExists("#cmpbox");
11
- }
12
- detectPopup(tab) {
13
- return tab.elementsAreVisible("#cmpbox .cmpmore", "any");
14
- }
15
- async optOut(tab) {
16
- if (await tab.elementExists(".cmpboxbtnno")) {
17
- return tab.clickElement(".cmpboxbtnno");
18
- }
19
- if (await tab.elementExists(".cmpwelcomeprpsbtn")) {
20
- await tab.clickElements(".cmpwelcomeprpsbtn > a[aria-checked=true]");
21
- return await tab.clickElement(".cmpboxbtnsave");
22
- }
23
- await tab.clickElement(".cmpboxbtncustom");
24
- await tab.waitForElement(".cmptblbox", 2000);
25
- await tab.clickElements(".cmptdchoice > a[aria-checked=true]");
26
- return tab.clickElement(".cmpboxbtnyescustomchoices");
27
- }
28
- async optIn(tab) {
29
- return tab.clickElement(".cmpboxbtnyes");
30
- }
31
- }
@@ -1,73 +0,0 @@
1
- import AutoConsentBase from './base';
2
- export default class Cookiebot extends AutoConsentBase {
3
- constructor() {
4
- super('Cybotcookiebot');
5
- this.prehideSelectors = ["#CybotCookiebotDialog,#dtcookie-container,#cookiebanner"];
6
- }
7
- async detectCmp(tab) {
8
- try {
9
- return await tab.eval('typeof window.CookieConsent === "object" && typeof window.CookieConsent.name === "string"');
10
- }
11
- catch (e) {
12
- return false;
13
- }
14
- }
15
- detectPopup(tab) {
16
- return tab.elementExists('#CybotCookiebotDialog,#dtcookie-container,#cookiebanner');
17
- }
18
- async optOut(tab) {
19
- if (await tab.elementExists('.cookie-alert-extended-detail-link')) {
20
- await tab.clickElement('.cookie-alert-extended-detail-link');
21
- await tab.waitForElement('.cookie-alert-configuration', 1000);
22
- await tab.clickElements('.cookie-alert-configuration-input:checked');
23
- return tab.clickElement('.cookie-alert-extended-button-secondary');
24
- }
25
- if (await tab.elementExists('#dtcookie-container')) {
26
- return tab.clickElement('.h-dtcookie-decline');
27
- }
28
- if (await tab.elementExists('.cookiebot__button--settings')) {
29
- await tab.clickElement('.cookiebot__button--settings');
30
- }
31
- if (await tab.elementsAreVisible('#CybotCookiebotDialogBodyButtonDecline', 'all')) {
32
- return await tab.clickElement('#CybotCookiebotDialogBodyButtonDecline');
33
- }
34
- if (await tab.elementExists('.cookiebanner__link--details')) {
35
- await tab.clickElement('.cookiebanner__link--details');
36
- }
37
- await tab.clickElements('.CybotCookiebotDialogBodyLevelButton:checked:enabled,input[id*="CybotCookiebotDialogBodyLevelButton"]:checked:enabled');
38
- if (await tab.elementExists('#CybotCookiebotDialogBodyButtonDecline')) {
39
- await tab.clickElement('#CybotCookiebotDialogBodyButtonDecline');
40
- }
41
- if (await tab.elementExists('input[id^=CybotCookiebotDialogBodyLevelButton]:checked')) {
42
- await tab.clickElements('input[id^=CybotCookiebotDialogBodyLevelButton]:checked');
43
- }
44
- if (await tab.elementExists('#CybotCookiebotDialogBodyButtonAcceptSelected')) {
45
- await tab.clickElement('#CybotCookiebotDialogBodyButtonAcceptSelected');
46
- }
47
- else {
48
- await tab.clickElements('#CybotCookiebotDialogBodyLevelButtonAccept,#CybotCookiebotDialogBodyButtonAccept,#CybotCookiebotDialogBodyLevelButtonLevelOptinAllowallSelection');
49
- }
50
- // some sites have custom submit buttons with no obvious selectors. In this case we just call the submitConsent API.
51
- if (await tab.eval('CookieConsent.hasResponse !== true')) {
52
- await tab.eval('Cookiebot.dialog.submitConsent() || true');
53
- await tab.wait(500);
54
- }
55
- return true;
56
- }
57
- async optIn(tab) {
58
- if (await tab.elementExists('#dtcookie-container')) {
59
- return tab.clickElement('.h-dtcookie-accept');
60
- }
61
- await tab.clickElements('.CybotCookiebotDialogBodyLevelButton:not(:checked):enabled');
62
- await tab.clickElement('#CybotCookiebotDialogBodyLevelButtonAccept');
63
- await tab.clickElement('#CybotCookiebotDialogBodyButtonAccept');
64
- return true;
65
- }
66
- async openCmp(tab) {
67
- await tab.eval('CookieConsent.renew() || true');
68
- return tab.waitForElement('#CybotCookiebotDialog', 10000);
69
- }
70
- async test(tab) {
71
- return tab.eval('CookieConsent.declined === true');
72
- }
73
- }
@@ -1,26 +0,0 @@
1
- import AutoConsentBase from "./base";
2
- // Note: JS API is also available:
3
- // https://help.consentmanager.net/books/cmp/page/javascript-api
4
- export default class Evidon extends AutoConsentBase {
5
- constructor() {
6
- super("Evidon");
7
- }
8
- detectCmp(tab) {
9
- return tab.elementExists("#_evidon_banner");
10
- }
11
- detectPopup(tab) {
12
- return tab.elementsAreVisible("#_evidon_banner");
13
- }
14
- async optOut(tab) {
15
- if (await tab.elementExists("#_evidon-decline-button")) {
16
- return tab.clickElement("#_evidon-decline-button");
17
- }
18
- tab.hideElements(["#evidon-prefdiag-overlay", "#evidon-prefdiag-background"]);
19
- await tab.clickElement("#_evidon-option-button");
20
- await tab.waitForElement("#evidon-prefdiag-overlay", 5000);
21
- return tab.clickElement("#evidon-prefdiag-decline");
22
- }
23
- async optIn(tab) {
24
- return tab.clickElement("#_evidon-accept-button");
25
- }
26
- }
@@ -1,32 +0,0 @@
1
- import AutoConsentBase, { success } from "./base";
2
- export default class Onetrust extends AutoConsentBase {
3
- constructor() {
4
- super("Onetrust");
5
- this.prehideSelectors = ["#onetrust-banner-sdk,#onetrust-consent-sdk,.optanon-alert-box-wrapper,.onetrust-pc-dark-filter,.js-consent-banner"];
6
- }
7
- detectCmp(tab) {
8
- return tab.elementExists("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
9
- }
10
- detectPopup(tab) {
11
- return tab.elementsAreVisible("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
12
- }
13
- async optOut(tab) {
14
- if (await tab.elementExists("#onetrust-pc-btn-handler")) { // "show purposes" button inside a popup
15
- await success(tab.clickElement("#onetrust-pc-btn-handler"));
16
- }
17
- else { // otherwise look for a generic "show settings" button
18
- await success(tab.clickElement(".ot-sdk-show-settings,button.js-cookie-settings"));
19
- }
20
- await success(tab.waitForElement("#onetrust-consent-sdk", 2000));
21
- await success(tab.wait(1000));
22
- await tab.clickElements("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked"); // optional step
23
- await success(tab.waitForThenClick(".save-preference-btn-handler,.js-consent-save", 1000));
24
- return true;
25
- }
26
- async optIn(tab) {
27
- return tab.clickElement("onetrust-accept-btn-handler,js-accept-cookies");
28
- }
29
- async test(tab) {
30
- return tab.eval("window.OnetrustActiveGroups.split(',').filter(s => s.length > 0).length <= 1");
31
- }
32
- }
@@ -1,82 +0,0 @@
1
- import AutoConsentBase, { success, waitFor } from "./base";
2
- export default class SourcePoint extends AutoConsentBase {
3
- constructor() {
4
- super("Sourcepoint");
5
- this.ccpaMode = false;
6
- this.prehideSelectors = ["div[id^='sp_message_container_'],.message-overlay"];
7
- }
8
- detectFrame(_, frame) {
9
- try {
10
- const url = new URL(frame.url);
11
- if (url.searchParams.has('message_id') && url.hostname === 'ccpa-notice.sp-prod.net') {
12
- this.ccpaMode = true;
13
- return true;
14
- }
15
- return (url.pathname === '/index.html' || url.pathname === '/privacy-manager/index.html')
16
- && url.searchParams.has('message_id') && url.searchParams.has('requestUUID');
17
- }
18
- catch (e) {
19
- return false;
20
- }
21
- }
22
- async detectCmp(tab) {
23
- return await tab.elementExists("div[id^='sp_message_container_']") || !!tab.frame;
24
- }
25
- async detectPopup(tab) {
26
- return await tab.elementsAreVisible("div[id^='sp_message_container_']");
27
- }
28
- async optIn(tab) {
29
- return tab.clickElement(".sp_choice_type_11", tab.frame.id);
30
- }
31
- isManagerOpen(tab) {
32
- return tab.frame && new URL(tab.frame.url).pathname === "/privacy-manager/index.html";
33
- }
34
- async optOut(tab) {
35
- try {
36
- tab.hideElements(["div[id^='sp_message_container_']"]);
37
- if (!this.isManagerOpen(tab)) {
38
- if (!await waitFor(() => !!tab.frame, 30, 100)) {
39
- throw "Frame never opened";
40
- }
41
- if (!await tab.elementExists("button.sp_choice_type_12", tab.frame.id)) {
42
- // do not sell button
43
- return tab.clickElement('button.sp_choice_type_13', tab.frame.id);
44
- }
45
- await success(tab.clickElement("button.sp_choice_type_12", tab.frame.id));
46
- await waitFor(() => new URL(tab.frame.url).pathname === "/privacy-manager/index.html", 200, 100);
47
- }
48
- await tab.waitForElement('.type-modal', 20000, tab.frame.id);
49
- // reject all button is offered by some sites
50
- try {
51
- const path = await Promise.race([
52
- tab.waitForElement('.sp_choice_type_REJECT_ALL', 2000, tab.frame.id).then(r => 0),
53
- tab.waitForElement('.reject-toggle', 2000, tab.frame.id).then(() => 1),
54
- tab.waitForElement('.pm-features', 2000, tab.frame.id).then(r => 2),
55
- ]);
56
- if (path === 0) {
57
- await tab.wait(1000);
58
- return await success(tab.clickElement('.sp_choice_type_REJECT_ALL', tab.frame.id));
59
- }
60
- else if (path === 1) {
61
- await tab.clickElement('.reject-toggle', tab.frame.id);
62
- }
63
- else {
64
- await tab.waitForElement('.pm-features', 10000, tab.frame.id);
65
- await tab.clickElements('.checked > span', tab.frame.id);
66
- if (await tab.elementExists('.chevron', tab.frame.id)) {
67
- await tab.clickElement('.chevron', tab.frame.id);
68
- }
69
- }
70
- }
71
- catch (e) { }
72
- return await tab.clickElement('.sp_choice_type_SAVE_AND_EXIT', tab.frame.id);
73
- }
74
- finally {
75
- tab.undoHideElements();
76
- }
77
- }
78
- async test(tab) {
79
- await tab.eval("__tcfapi('getTCData', 2, r => window.__rcsResult = r)");
80
- return tab.eval("Object.values(window.__rcsResult.purpose.consents).every(c => !c)");
81
- }
82
- }
@@ -1,95 +0,0 @@
1
- import AutoConsentBase, { success, waitFor } from "./base";
2
- import { TabActor } from "../types";
3
-
4
- export default class SourcePoint extends AutoConsentBase {
5
-
6
- ccpaMode = false;
7
- prehideSelectors = ["div[id^='sp_message_container_'],.message-overlay"]
8
-
9
- constructor() {
10
- super("Sourcepoint");
11
- }
12
-
13
- detectFrame(_: TabActor, frame: { url: string }) {
14
- try {
15
- const url = new URL(frame.url);
16
- if (url.searchParams.has('message_id') && url.hostname === 'ccpa-notice.sp-prod.net') {
17
- this.ccpaMode = true;
18
- return true;
19
- }
20
- return (url.pathname === '/index.html' || url.pathname === '/privacy-manager/index.html')
21
- && url.searchParams.has('message_id') && url.searchParams.has('requestUUID');
22
- } catch (e) {
23
- return false;
24
- }
25
- }
26
-
27
- async detectCmp(tab: TabActor) {
28
- return await tab.elementExists("div[id^='sp_message_container_']") || !!tab.frame
29
- }
30
-
31
- async detectPopup(tab: TabActor) {
32
- return await tab.elementsAreVisible("div[id^='sp_message_container_']");
33
- }
34
-
35
- async optIn(tab: TabActor) {
36
- return tab.clickElement(".sp_choice_type_11", tab.frame.id);
37
- }
38
-
39
- isManagerOpen(tab: TabActor) {
40
- return tab.frame && new URL(tab.frame.url).pathname === "/privacy-manager/index.html";
41
- }
42
-
43
- async optOut(tab: TabActor) {
44
- try {
45
- tab.hideElements(["div[id^='sp_message_container_']"])
46
- if (!this.isManagerOpen(tab)) {
47
- if (!await waitFor(() => !!tab.frame, 30, 100)) {
48
- throw "Frame never opened";
49
- }
50
- if (!await tab.elementExists("button.sp_choice_type_12", tab.frame.id)) {
51
- // do not sell button
52
- return tab.clickElement('button.sp_choice_type_13', tab.frame.id);
53
- }
54
- await success(tab.clickElement("button.sp_choice_type_12", tab.frame.id));
55
- await waitFor(
56
- () =>
57
- new URL(tab.frame.url).pathname === "/privacy-manager/index.html",
58
- 200,
59
- 100
60
- );
61
- }
62
- await tab.waitForElement('.type-modal', 20000, tab.frame.id);
63
- // reject all button is offered by some sites
64
- try {
65
- const path = await Promise.race([
66
- tab.waitForElement('.sp_choice_type_REJECT_ALL', 2000, tab.frame.id).then(r => 0),
67
- tab.waitForElement('.reject-toggle', 2000, tab.frame.id).then(() => 1),
68
- tab.waitForElement('.pm-features', 2000, tab.frame.id).then(r => 2),
69
- ]);
70
- if (path === 0) {
71
- await tab.wait(1000);
72
- return await success(tab.clickElement('.sp_choice_type_REJECT_ALL', tab.frame.id))
73
- } else if (path === 1) {
74
- await tab.clickElement('.reject-toggle', tab.frame.id)
75
- } else {
76
- await tab.waitForElement('.pm-features', 10000, tab.frame.id);
77
- await tab.clickElements('.checked > span', tab.frame.id);
78
- if (await tab.elementExists('.chevron', tab.frame.id)) {
79
- await tab.clickElement('.chevron', tab.frame.id)
80
- }
81
- }
82
- } catch(e) {}
83
- return await tab.clickElement('.sp_choice_type_SAVE_AND_EXIT', tab.frame.id);
84
- } finally {
85
- tab.undoHideElements();
86
- }
87
- }
88
-
89
- async test(tab: TabActor) {
90
- await tab.eval("__tcfapi('getTCData', 2, r => window.__rcsResult = r)");
91
- return tab.eval(
92
- "Object.values(window.__rcsResult.purpose.consents).every(c => !c)"
93
- );
94
- }
95
- }
@@ -1,106 +0,0 @@
1
- import AutoConsentBase, { waitFor } from "./base";
2
- export default class TrustArc extends AutoConsentBase {
3
- constructor() {
4
- super("TrustArc");
5
- this.prehideSelectors = [
6
- ".trustarc-banner-container",
7
- ".truste_popframe,.truste_overlay,.truste_box_overlay,#truste-consent-track",
8
- ];
9
- }
10
- detectFrame(_, frame) {
11
- return frame.url.startsWith("https://consent-pref.trustarc.com/?");
12
- }
13
- async detectCmp(tab) {
14
- if (tab.frame &&
15
- tab.frame.url.startsWith("https://consent-pref.trustarc.com/?")) {
16
- return true;
17
- }
18
- return tab.elementExists("#truste-show-consent");
19
- }
20
- async detectPopup(tab) {
21
- return ((await tab.elementsAreVisible("#truste-consent-content,#trustarc-banner-overlay")) ||
22
- (tab.frame &&
23
- (await tab.waitForElement("#defaultpreferencemanager", 5000, tab.frame.id))));
24
- }
25
- async openFrame(tab) {
26
- if (await tab.elementExists("#truste-show-consent")) {
27
- await tab.clickElement("#truste-show-consent");
28
- }
29
- }
30
- async navigateToSettings(tab, frameId) {
31
- // wait for it to load
32
- await waitFor(async () => {
33
- return ((await tab.elementExists(".shp", frameId)) ||
34
- (await tab.elementsAreVisible(".advance", "any", frameId)) ||
35
- tab.elementExists(".switch span:first-child", frameId));
36
- }, 10, 500);
37
- // splash screen -> hit more information
38
- if (await tab.elementExists(".shp", frameId)) {
39
- await tab.clickElement(".shp", frameId);
40
- }
41
- await tab.waitForElement(".prefPanel", 5000, frameId);
42
- // go to advanced settings if not yet shown
43
- if (await tab.elementsAreVisible(".advance", "any", frameId)) {
44
- await tab.clickElement(".advance", frameId);
45
- }
46
- // takes a while to load the opt-in/opt-out buttons
47
- return await waitFor(() => tab.elementsAreVisible(".switch span:first-child", "any", frameId), 5, 1000);
48
- }
49
- async optOut(tab) {
50
- // await tab.hideElements(['.truste_overlay', '.truste_box_overlay', '.trustarc-banner', '.truste-banner']);
51
- if (await tab.elementExists("#truste-consent-required")) {
52
- return tab.clickElement("#truste-consent-required");
53
- }
54
- if (!tab.frame) {
55
- await tab.clickElement("#truste-show-consent");
56
- await waitFor(async () => !!tab.frame &&
57
- (await tab.elementsAreVisible(".mainContent", "any", tab.frame.id)), 50, 100);
58
- }
59
- const frameId = tab.frame.id;
60
- await waitFor(() => tab.eval("document.readyState === 'complete'", frameId), 20, 100);
61
- tab.hideElements([".truste_popframe", ".truste_overlay", ".truste_box_overlay", "#truste-consent-track"]);
62
- if (await tab.elementExists('.rejectAll', frameId)) {
63
- return tab.clickElement('.rejectAll', frameId);
64
- }
65
- if (await tab.waitForElement('#catDetails0', 1000, frameId)) {
66
- await tab.clickElement("#catDetails0", frameId);
67
- return tab.clickElement(".submit", frameId);
68
- }
69
- if (await tab.elementExists(".required", frameId)) {
70
- await tab.clickElement(".required", frameId);
71
- }
72
- else {
73
- await this.navigateToSettings(tab, frameId);
74
- await tab.clickElements(".switch span:nth-child(1):not(.active)", frameId);
75
- await tab.clickElement(".submit", frameId);
76
- }
77
- try {
78
- await tab.waitForThenClick("#gwt-debug-close_id", 20000, tab.frame.id);
79
- }
80
- catch (e) {
81
- // ignore frame disappearing
82
- }
83
- return true;
84
- }
85
- async optIn(tab) {
86
- if (!tab.frame) {
87
- await this.openFrame(tab);
88
- await waitFor(() => !!tab.frame, 10, 200);
89
- }
90
- const frameId = tab.frame.id;
91
- await this.navigateToSettings(tab, frameId);
92
- await tab.clickElements(".switch span:nth-child(2)", frameId);
93
- await tab.clickElement(".submit", frameId);
94
- await waitFor(() => tab.elementExists("#gwt-debug-close_id", frameId), 300, 1000);
95
- await tab.clickElement("#gwt-debug-close_id", frameId);
96
- return true;
97
- }
98
- async openCmp(tab) {
99
- await tab.eval("truste.eu.clickListener()");
100
- return true;
101
- }
102
- async test() {
103
- // TODO: find out how to test TrustArc
104
- return true;
105
- }
106
- }