@duckduckgo/autoconsent 8.1.0 → 9.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 (40) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/build.sh +1 -0
  3. package/dist/addon-firefox/background.bundle.js +60 -43
  4. package/dist/addon-firefox/content.bundle.js +484 -382
  5. package/dist/addon-firefox/manifest.json +1 -1
  6. package/dist/addon-mv3/background.bundle.js +60 -43
  7. package/dist/addon-mv3/content.bundle.js +484 -382
  8. package/dist/addon-mv3/manifest.json +1 -1
  9. package/dist/addon-mv3/popup.bundle.js +71 -33
  10. package/dist/addon-mv3/popup.html +28 -0
  11. package/dist/autoconsent.cjs.js +484 -382
  12. package/dist/autoconsent.esm.js +484 -382
  13. package/dist/autoconsent.playwright.js +1 -1
  14. package/dist/autoconsent.unit.js +10370 -0
  15. package/lib/cmps/airbnb.ts +5 -6
  16. package/lib/cmps/base.ts +97 -41
  17. package/lib/cmps/consentmanager.ts +13 -14
  18. package/lib/cmps/conversant.ts +8 -9
  19. package/lib/cmps/cookiebot.ts +8 -9
  20. package/lib/cmps/evidon.ts +7 -8
  21. package/lib/cmps/klaro.ts +13 -14
  22. package/lib/cmps/onetrust.ts +15 -16
  23. package/lib/cmps/sourcepoint-frame.ts +25 -26
  24. package/lib/cmps/tiktok.ts +7 -7
  25. package/lib/cmps/trustarc-frame.ts +27 -28
  26. package/lib/cmps/trustarc-top.ts +5 -6
  27. package/lib/cmps/uniconsent.ts +9 -10
  28. package/lib/dom-actions.ts +145 -0
  29. package/lib/eval-snippets.ts +17 -2
  30. package/lib/types.ts +24 -1
  31. package/lib/utils.ts +32 -1
  32. package/lib/web.ts +46 -34
  33. package/package.json +4 -4
  34. package/playwright/runner.ts +11 -3
  35. package/playwright/unit.ts +15 -0
  36. package/readme.md +1 -1
  37. package/tests/{rule-executors.spec.ts → dom-actions.spec.ts} +20 -21
  38. package/tests/klaro.spec.ts +1 -0
  39. package/lib/config.ts +0 -2
  40. package/lib/rule-executors.ts +0 -147
@@ -1,4 +1,3 @@
1
- import { elementExists, elementVisible, waitForThenClick } from "../rule-executors";
2
1
  import { RunContext } from "../rules";
3
2
  import { waitFor } from "../utils";
4
3
  import AutoConsentCMPBase from "./base";
@@ -28,25 +27,25 @@ export default class Airbnb extends AutoConsentCMPBase {
28
27
  }
29
28
 
30
29
  async detectCmp() {
31
- return elementExists('div[data-testid=main-cookies-banner-container]');
30
+ return this.elementExists('div[data-testid=main-cookies-banner-container]');
32
31
  }
33
32
 
34
33
  async detectPopup() {
35
- return elementVisible('div[data-testid=main-cookies-banner-container', 'any');
34
+ return this.elementVisible('div[data-testid=main-cookies-banner-container', 'any');
36
35
  }
37
36
 
38
37
  async optOut() {
39
- await waitForThenClick('div[data-testid=main-cookies-banner-container] button._snbhip0');
38
+ await this.waitForThenClick('div[data-testid=main-cookies-banner-container] button._snbhip0');
40
39
  let check;
41
40
  // eslint-disable-next-line no-cond-assign
42
41
  while (check = document.querySelector('[data-testid=modal-container] button[aria-checked=true]:not([disabled])') as HTMLElement) { // each click may toggle multiple checkboxes
43
42
  check.click();
44
43
  }
45
- return waitForThenClick('button[data-testid=save-btn]');
44
+ return this.waitForThenClick('button[data-testid=save-btn]');
46
45
  }
47
46
 
48
47
  async optIn() {
49
- return waitForThenClick('div[data-testid=main-cookies-banner-container] button._148dgdpk');
48
+ return this.waitForThenClick('div[data-testid=main-cookies-banner-container] button._148dgdpk');
50
49
  }
51
50
 
52
51
  async test() {
package/lib/cmps/base.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  /* eslint-disable no-restricted-syntax,no-await-in-loop,no-underscore-dangle */
2
2
 
3
- import { AutoCMP } from "../types";
4
- import { AutoConsentCMPRule, AutoConsentRuleStep, RunContext } from "../rules";
5
- import { enableLogs } from "../config";
6
- import { click, elementExists, elementVisible, hide, wait, waitForElement, waitForThenClick, waitForVisible } from "../rule-executors";
3
+ import { AutoCMP, DomActionsProvider } from "../types";
4
+ import { AutoConsentCMPRule, AutoConsentRuleStep, ElementSelector, HideMethod, RunContext, VisibilityCheck } from "../rules";
7
5
  import { requestEval } from "../eval-handler";
8
6
  import AutoConsent from "../web";
9
7
  import { getFunctionBody, snippets } from "../eval-snippets";
@@ -22,7 +20,7 @@ export const defaultRunContext: RunContext = {
22
20
  urlPattern: "",
23
21
  }
24
22
 
25
- export default class AutoConsentCMPBase implements AutoCMP {
23
+ export default class AutoConsentCMPBase implements AutoCMP, DomActionsProvider {
26
24
  name: string
27
25
  runContext: RunContext = defaultRunContext;
28
26
  autoconsent: AutoConsent;
@@ -49,23 +47,24 @@ export default class AutoConsentCMPBase implements AutoCMP {
49
47
  console.warn('Snippet not found', snippetId);
50
48
  return Promise.resolve(false);
51
49
  }
50
+ const logsConfig = this.autoconsent.config.logs;
52
51
 
53
52
  if (this.autoconsent.config.isMainWorld) {
54
- enableLogs && console.log('inline eval:', snippetId, snippet);
53
+ logsConfig.evals && console.log('inline eval:', snippetId, snippet);
55
54
  let result = false;
56
55
  try {
57
56
  result = !!snippet.call(globalThis);
58
57
  } catch (e) {
59
58
  // ignore exceptions
60
- enableLogs && console.error('error evaluating rule', snippetId, e);
59
+ logsConfig.evals && console.error('error evaluating rule', snippetId, e);
61
60
  }
62
61
  return Promise.resolve(result);
63
62
  }
64
63
 
65
64
  const snippetSrc = getFunctionBody(snippet);
66
- enableLogs && console.log('async eval:', snippetId, snippetSrc);
65
+ logsConfig.evals && console.log('async eval:', snippetId, snippetSrc);
67
66
  return requestEval(snippetSrc, snippetId).catch((e) => {
68
- enableLogs && console.error('error evaluating rule', snippetId, e);
67
+ logsConfig.evals && console.error('error evaluating rule', snippetId, e);
69
68
  return false;
70
69
  });
71
70
  }
@@ -116,105 +115,161 @@ export default class AutoConsentCMPBase implements AutoCMP {
116
115
  // try IAB by default
117
116
  return Promise.resolve(true);
118
117
  }
118
+
119
+ // Implementing DomActionsProvider below:
120
+ click(selector: ElementSelector, all = false) {
121
+ return this.autoconsent.domActions.click(selector, all);
122
+ }
123
+
124
+ elementExists(selector: ElementSelector) {
125
+ return this.autoconsent.domActions.elementExists(selector);
126
+ }
127
+
128
+ elementVisible(selector: ElementSelector, check: VisibilityCheck) {
129
+ return this.autoconsent.domActions.elementVisible(selector, check);
130
+ }
131
+
132
+ waitForElement(selector: ElementSelector, timeout?: number) {
133
+ return this.autoconsent.domActions.waitForElement(selector, timeout);
134
+ }
135
+
136
+ waitForVisible(selector: ElementSelector, timeout?: number, check?: VisibilityCheck) {
137
+ return this.autoconsent.domActions.waitForVisible(selector, timeout, check);
138
+ }
139
+
140
+ waitForThenClick(selector: ElementSelector, timeout?: number, all?: boolean) {
141
+ return this.autoconsent.domActions.waitForThenClick(selector, timeout, all);
142
+ }
143
+
144
+ wait(ms: number) {
145
+ return this.autoconsent.domActions.wait(ms);
146
+ }
147
+
148
+ hide(selector: string, method: HideMethod) {
149
+ return this.autoconsent.domActions.hide(selector, method);
150
+ }
151
+
152
+ prehide(selector: string) {
153
+ return this.autoconsent.domActions.prehide(selector);
154
+ }
155
+
156
+ undoPrehide() {
157
+ return this.autoconsent.domActions.undoPrehide();
158
+ }
159
+
160
+ querySingleReplySelector(selector: string, parent?: any) {
161
+ return this.autoconsent.domActions.querySingleReplySelector(selector, parent);
162
+ }
163
+
164
+ querySelectorChain(selectors: string[]) {
165
+ return this.autoconsent.domActions.querySelectorChain(selectors);
166
+ }
167
+
168
+ elementSelector(selector: ElementSelector) {
169
+ return this.autoconsent.domActions.elementSelector(selector);
170
+ }
119
171
  }
120
172
 
121
173
  export class AutoConsentCMP extends AutoConsentCMPBase {
122
174
 
123
- constructor(public config: AutoConsentCMPRule, autoconsentInstance: AutoConsent) {
175
+ constructor(public rule: AutoConsentCMPRule, autoconsentInstance: AutoConsent) {
124
176
  super(autoconsentInstance);
125
- this.name = config.name;
126
- this.runContext = config.runContext || defaultRunContext;
177
+ this.name = rule.name;
178
+ this.runContext = rule.runContext || defaultRunContext;
127
179
  }
128
180
 
129
181
  get hasSelfTest(): boolean {
130
- return !!this.config.test;
182
+ return !!this.rule.test;
131
183
  }
132
184
 
133
185
  get isIntermediate(): boolean {
134
- return !!this.config.intermediate;
186
+ return !!this.rule.intermediate;
135
187
  }
136
188
 
137
189
  get isCosmetic(): boolean {
138
- return !!this.config.cosmetic;
190
+ return !!this.rule.cosmetic;
139
191
  }
140
192
 
141
193
  get prehideSelectors(): string[] {
142
- return this.config.prehideSelectors;
194
+ return this.rule.prehideSelectors;
143
195
  }
144
196
 
145
197
  async detectCmp() {
146
- if (this.config.detectCmp) {
147
- return this._runRulesParallel(this.config.detectCmp);
198
+ if (this.rule.detectCmp) {
199
+ return this._runRulesParallel(this.rule.detectCmp);
148
200
  }
149
201
  return false;
150
202
  }
151
203
 
152
204
  async detectPopup() {
153
- if (this.config.detectPopup) {
154
- return this._runRulesSequentially(this.config.detectPopup);
205
+ if (this.rule.detectPopup) {
206
+ return this._runRulesSequentially(this.rule.detectPopup);
155
207
  }
156
208
  return false;
157
209
  }
158
210
 
159
211
  async optOut() {
160
- if (this.config.optOut) {
161
- enableLogs && console.log('Initiated optOut()', this.config.optOut);
162
- return this._runRulesSequentially(this.config.optOut);
212
+ const logsConfig = this.autoconsent.config.logs;
213
+ if (this.rule.optOut) {
214
+ logsConfig.lifecycle && console.log('Initiated optOut()', this.rule.optOut);
215
+ return this._runRulesSequentially(this.rule.optOut);
163
216
  }
164
217
  return false;
165
218
  }
166
219
 
167
220
  async optIn() {
168
- if (this.config.optIn) {
169
- enableLogs && console.log('Initiated optIn()', this.config.optIn);
170
- return this._runRulesSequentially(this.config.optIn);
221
+ const logsConfig = this.autoconsent.config.logs;
222
+ if (this.rule.optIn) {
223
+ logsConfig.lifecycle && console.log('Initiated optIn()', this.rule.optIn);
224
+ return this._runRulesSequentially(this.rule.optIn);
171
225
  }
172
226
  return false;
173
227
  }
174
228
 
175
229
  async openCmp() {
176
- if (this.config.openCmp) {
177
- return this._runRulesSequentially(this.config.openCmp);
230
+ if (this.rule.openCmp) {
231
+ return this._runRulesSequentially(this.rule.openCmp);
178
232
  }
179
233
  return false;
180
234
  }
181
235
 
182
236
  async test() {
183
237
  if (this.hasSelfTest) {
184
- return this._runRulesSequentially(this.config.test);
238
+ return this._runRulesSequentially(this.rule.test);
185
239
  }
186
240
  return super.test();
187
241
  }
188
242
 
189
243
  async evaluateRuleStep(rule: AutoConsentRuleStep) {
190
244
  const results = [];
245
+ const logsConfig = this.autoconsent.config.logs;
191
246
  if (rule.exists) {
192
- results.push(elementExists(rule.exists));
247
+ results.push(this.elementExists(rule.exists));
193
248
  }
194
249
  if (rule.visible) {
195
- results.push(elementVisible(rule.visible, rule.check));
250
+ results.push(this.elementVisible(rule.visible, rule.check));
196
251
  }
197
252
  if (rule.eval) {
198
253
  const res = this.mainWorldEval(rule.eval)
199
254
  results.push(res);
200
255
  }
201
256
  if (rule.waitFor) {
202
- results.push(waitForElement(rule.waitFor, rule.timeout));
257
+ results.push(this.waitForElement(rule.waitFor, rule.timeout));
203
258
  }
204
259
  if (rule.waitForVisible) {
205
- results.push(waitForVisible(rule.waitForVisible, rule.timeout, rule.check));
260
+ results.push(this.waitForVisible(rule.waitForVisible, rule.timeout, rule.check));
206
261
  }
207
262
  if (rule.click) {
208
- results.push(click(rule.click, rule.all));
263
+ results.push(this.click(rule.click, rule.all));
209
264
  }
210
265
  if (rule.waitForThenClick) {
211
- results.push(waitForThenClick(rule.waitForThenClick, rule.timeout, rule.all));
266
+ results.push(this.waitForThenClick(rule.waitForThenClick, rule.timeout, rule.all));
212
267
  }
213
268
  if (rule.wait) {
214
- results.push(wait(rule.wait));
269
+ results.push(this.wait(rule.wait));
215
270
  }
216
271
  if (rule.hide) {
217
- results.push(hide(rule.hide, rule.method));
272
+ results.push(this.hide(rule.hide, rule.method));
218
273
  }
219
274
  if (rule.if) {
220
275
  if (!rule.if.exists && !rule.if.visible) {
@@ -222,7 +277,7 @@ export class AutoConsentCMP extends AutoConsentCMPBase {
222
277
  return false;
223
278
  }
224
279
  const condition = await this.evaluateRuleStep(rule.if);
225
- enableLogs && console.log('Condition is', condition);
280
+ logsConfig.rulesteps && console.log('Condition is', condition);
226
281
  if (condition) {
227
282
  results.push(this._runRulesSequentially(rule.then));
228
283
  } else if (rule.else) {
@@ -239,7 +294,7 @@ export class AutoConsentCMP extends AutoConsentCMPBase {
239
294
  }
240
295
 
241
296
  if (results.length === 0) {
242
- enableLogs && console.warn('Unrecognized rule', rule);
297
+ logsConfig.errors && console.warn('Unrecognized rule', rule);
243
298
  return false;
244
299
  }
245
300
 
@@ -255,10 +310,11 @@ export class AutoConsentCMP extends AutoConsentCMPBase {
255
310
  }
256
311
 
257
312
  async _runRulesSequentially(rules: AutoConsentRuleStep[]): Promise<boolean> {
313
+ const logsConfig = this.autoconsent.config.logs;
258
314
  for (const rule of rules) {
259
- enableLogs && console.log('Running rule...', rule);
315
+ logsConfig.rulesteps && console.log('Running rule...', rule);
260
316
  const result = await this.evaluateRuleStep(rule);
261
- enableLogs && console.log('...rule result', result);
317
+ logsConfig.rulesteps && console.log('...rule result', result);
262
318
  if (!result && !rule.optional) {
263
319
  return false;
264
320
  }
@@ -1,4 +1,3 @@
1
- import { click, elementExists, elementVisible, wait, waitForElement } from "../rule-executors";
2
1
  import AutoConsentCMPBase from "./base";
3
2
 
4
3
  // Note: JS API is also available:
@@ -24,7 +23,7 @@ export default class ConsentManager extends AutoConsentCMPBase {
24
23
  async detectCmp() {
25
24
  this.apiAvailable = await this.mainWorldEval('EVAL_CONSENTMANAGER_1');
26
25
  if (!this.apiAvailable) {
27
- return elementExists("#cmpbox");
26
+ return this.elementExists("#cmpbox");
28
27
  } else {
29
28
  return true;
30
29
  }
@@ -34,32 +33,32 @@ export default class ConsentManager extends AutoConsentCMPBase {
34
33
  if (this.apiAvailable) {
35
34
  // wait before making this check because early in the page lifecycle this may incorrectly return
36
35
  // true, causing an opt-out when it is not needed.
37
- await wait(500);
36
+ await this.wait(500);
38
37
  return await this.mainWorldEval('EVAL_CONSENTMANAGER_2');
39
38
  }
40
- return elementVisible("#cmpbox .cmpmore", 'any');
39
+ return this.elementVisible("#cmpbox .cmpmore", 'any');
41
40
  }
42
41
 
43
42
  async optOut() {
44
- await wait(500);
43
+ await this.wait(500);
45
44
  if (this.apiAvailable) {
46
45
  return await this.mainWorldEval('EVAL_CONSENTMANAGER_3');
47
46
  }
48
47
 
49
- if (click(".cmpboxbtnno")) {
48
+ if (this.click(".cmpboxbtnno")) {
50
49
  return true;
51
50
  }
52
51
 
53
- if (elementExists(".cmpwelcomeprpsbtn")) {
54
- click(".cmpwelcomeprpsbtn > a[aria-checked=true]", true);
55
- click(".cmpboxbtnsave");
52
+ if (this.elementExists(".cmpwelcomeprpsbtn")) {
53
+ this.click(".cmpwelcomeprpsbtn > a[aria-checked=true]", true);
54
+ this.click(".cmpboxbtnsave");
56
55
  return true;
57
56
  }
58
57
 
59
- click(".cmpboxbtncustom");
60
- await waitForElement(".cmptblbox", 2000);
61
- click(".cmptdchoice > a[aria-checked=true]", true);
62
- click(".cmpboxbtnyescustomchoices");
58
+ this.click(".cmpboxbtncustom");
59
+ await this.waitForElement(".cmptblbox", 2000);
60
+ this.click(".cmptdchoice > a[aria-checked=true]", true);
61
+ this.click(".cmpboxbtnyescustomchoices");
63
62
  return true;
64
63
  }
65
64
 
@@ -67,7 +66,7 @@ export default class ConsentManager extends AutoConsentCMPBase {
67
66
  if (this.apiAvailable) {
68
67
  return await this.mainWorldEval('EVAL_CONSENTMANAGER_4');
69
68
  }
70
- return click(".cmpboxbtnyes");
69
+ return this.click(".cmpboxbtnyes");
71
70
  }
72
71
 
73
72
  async test() {
@@ -1,4 +1,3 @@
1
- import { click, elementExists, elementVisible, waitForElement, waitForThenClick } from "../rule-executors";
2
1
  import { waitFor } from "../utils";
3
2
  import AutoConsentCMPBase from "./base";
4
3
 
@@ -20,24 +19,24 @@ export default class Conversant extends AutoConsentCMPBase {
20
19
  }
21
20
 
22
21
  async detectCmp() {
23
- return elementExists(".cmp-root .cmp-receptacle");
22
+ return this.elementExists(".cmp-root .cmp-receptacle");
24
23
  }
25
24
 
26
25
  async detectPopup() {
27
- return elementVisible(".cmp-root .cmp-receptacle", 'any');
26
+ return this.elementVisible(".cmp-root .cmp-receptacle", 'any');
28
27
  }
29
28
 
30
29
  async optOut() {
31
- if (!(await waitForThenClick(".cmp-main-button:not(.cmp-main-button--primary)"))) {
30
+ if (!(await this.waitForThenClick(".cmp-main-button:not(.cmp-main-button--primary)"))) {
32
31
  return false;
33
32
  }
34
33
 
35
- if (!(await waitForElement(".cmp-view-tab-tabs"))) {
34
+ if (!(await this.waitForElement(".cmp-view-tab-tabs"))) {
36
35
  return false;
37
36
  }
38
37
 
39
- await waitForThenClick(".cmp-view-tab-tabs > :first-child");
40
- await waitForThenClick(".cmp-view-tab-tabs > .cmp-view-tab--active:first-child");
38
+ await this.waitForThenClick(".cmp-view-tab-tabs > :first-child");
39
+ await this.waitForThenClick(".cmp-view-tab-tabs > .cmp-view-tab--active:first-child");
41
40
 
42
41
  for (const item of Array.from(document.querySelectorAll('.cmp-accordion-item'))) {
43
42
  (<HTMLElement>item.querySelector('.cmp-accordion-item-title')).click();
@@ -47,12 +46,12 @@ export default class Conversant extends AutoConsentCMPBase {
47
46
  content.querySelectorAll('.cmp-toggle-actions .cmp-toggle-checkbox:not(.cmp-toggle-checkbox--active)').forEach((e: HTMLElement) => e.click());
48
47
  // await waitFor(() => !item.querySelector('.cmp-toggle-deny--active,.cmp-toggle-checkbox--active'), 5, 50); // this may take a long time
49
48
  }
50
- await click(".cmp-main-button:not(.cmp-main-button--primary)");
49
+ await this.click(".cmp-main-button:not(.cmp-main-button--primary)");
51
50
  return true;
52
51
  }
53
52
 
54
53
  async optIn() {
55
- return waitForThenClick(".cmp-main-button.cmp-main-button--primary");
54
+ return this.waitForThenClick(".cmp-main-button.cmp-main-button--primary");
56
55
  }
57
56
 
58
57
  async test() {
@@ -1,4 +1,3 @@
1
- import { click, elementExists, wait } from '../rule-executors';
2
1
  import AutoConsentCMPBase from './base';
3
2
 
4
3
  export default class Cookiebot extends AutoConsentCMPBase {
@@ -26,26 +25,26 @@ export default class Cookiebot extends AutoConsentCMPBase {
26
25
  }
27
26
 
28
27
  async optOut() {
29
- await wait(500);
28
+ await this.wait(500);
30
29
  let res = await this.mainWorldEval('EVAL_COOKIEBOT_3'); // withdraw
31
- await wait(500); // prevent race conditions
30
+ await this.wait(500); // prevent race conditions
32
31
  res = res && await this.mainWorldEval('EVAL_COOKIEBOT_4'); // hide
33
32
  return res;
34
33
  }
35
34
 
36
35
  async optIn() {
37
- if (elementExists('#dtcookie-container')) {
38
- return click('.h-dtcookie-accept');
36
+ if (this.elementExists('#dtcookie-container')) {
37
+ return this.click('.h-dtcookie-accept');
39
38
  }
40
39
 
41
- click('.CybotCookiebotDialogBodyLevelButton:not(:checked):enabled', true);
42
- click('#CybotCookiebotDialogBodyLevelButtonAccept');
43
- click('#CybotCookiebotDialogBodyButtonAccept');
40
+ this.click('.CybotCookiebotDialogBodyLevelButton:not(:checked):enabled', true);
41
+ this.click('#CybotCookiebotDialogBodyLevelButtonAccept');
42
+ this.click('#CybotCookiebotDialogBodyButtonAccept');
44
43
  return true;
45
44
  }
46
45
 
47
46
  async test() {
48
- await wait(500);
47
+ await this.wait(500);
49
48
  return await this.mainWorldEval('EVAL_COOKIEBOT_5');
50
49
  }
51
50
  }
@@ -1,4 +1,3 @@
1
- import { click, elementExists, elementVisible, waitForElement } from "../rule-executors";
2
1
  import { getStyleElement, hideElements } from "../utils";
3
2
  import AutoConsentCMPBase from "./base";
4
3
 
@@ -18,28 +17,28 @@ export default class Evidon extends AutoConsentCMPBase {
18
17
  }
19
18
 
20
19
  async detectCmp() {
21
- return elementExists("#_evidon_banner");
20
+ return this.elementExists("#_evidon_banner");
22
21
  }
23
22
 
24
23
  async detectPopup() {
25
- return elementVisible("#_evidon_banner", 'any');
24
+ return this.elementVisible("#_evidon_banner", 'any');
26
25
  }
27
26
 
28
27
  async optOut() {
29
- if (click("#_evidon-decline-button")) {
28
+ if (this.click("#_evidon-decline-button")) {
30
29
  return true;
31
30
  }
32
31
 
33
32
  hideElements(getStyleElement(), "#evidon-prefdiag-overlay,#evidon-prefdiag-background");
34
- click("#_evidon-option-button");
33
+ this.click("#_evidon-option-button");
35
34
 
36
- await waitForElement("#evidon-prefdiag-overlay", 5000);
35
+ await this.waitForElement("#evidon-prefdiag-overlay", 5000);
37
36
 
38
- click("#evidon-prefdiag-decline");
37
+ this.click("#evidon-prefdiag-decline");
39
38
  return true;
40
39
  }
41
40
 
42
41
  async optIn() {
43
- return click("#_evidon-accept-button");
42
+ return this.click("#_evidon-accept-button");
44
43
  }
45
44
  }
package/lib/cmps/klaro.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { click, elementExists, elementVisible, waitForElement } from "../rule-executors";
2
1
  import AutoConsentCMPBase from "./base";
3
2
 
4
3
  export default class Klaro extends AutoConsentCMPBase {
@@ -19,45 +18,45 @@ export default class Klaro extends AutoConsentCMPBase {
19
18
  }
20
19
 
21
20
  async detectCmp() {
22
- if (elementExists('.klaro > .cookie-modal')) {
21
+ if (this.elementExists('.klaro > .cookie-modal')) {
23
22
  this.settingsOpen = true;
24
23
  return true;
25
24
  }
26
- return elementExists(".klaro > .cookie-notice");
25
+ return this.elementExists(".klaro > .cookie-notice");
27
26
  }
28
27
 
29
28
  async detectPopup() {
30
- return elementVisible(".klaro > .cookie-notice,.klaro > .cookie-modal", 'any');
29
+ return this.elementVisible(".klaro > .cookie-notice,.klaro > .cookie-modal", 'any');
31
30
  }
32
31
 
33
32
  async optOut() {
34
- if (click('.klaro .cn-decline')) {
33
+ if (this.click('.klaro .cn-decline')) {
35
34
  return true;
36
35
  }
37
36
 
38
37
  if (!this.settingsOpen) {
39
- click('.klaro .cn-learn-more');
40
- await waitForElement('.klaro > .cookie-modal', 2000);
38
+ this.click('.klaro .cn-learn-more,.klaro .cm-button-manage');
39
+ await this.waitForElement('.klaro > .cookie-modal', 2000);
41
40
  this.settingsOpen = true;
42
41
  }
43
42
 
44
- if (click('.klaro .cn-decline')) {
43
+ if (this.click('.klaro .cn-decline')) {
45
44
  return true;
46
45
  }
47
46
 
48
- click('.cm-purpose:not(.cm-toggle-all) > input:not(.half-checked)', true);
49
- return click('.cm-btn-accept');
47
+ this.click('.cm-purpose:not(.cm-toggle-all) > input:not(.half-checked,.required,.only-required),.cm-purpose:not(.cm-toggle-all) > div > input:not(.half-checked,.required,.only-required)', true);
48
+ return this.click('.cm-btn-accept,.cm-button');
50
49
  }
51
50
 
52
51
  async optIn() {
53
- if (click('.klaro .cm-btn-accept-all')) {
52
+ if (this.click('.klaro .cm-btn-accept-all')) {
54
53
  return true;
55
54
  }
56
55
  if (this.settingsOpen) {
57
- click('.cm-purpose:not(.cm-toggle-all) > input.half-checked', true);
58
- return click('.cm-btn-accept');
56
+ this.click('.cm-purpose:not(.cm-toggle-all) > input.half-checked', true);
57
+ return this.click('.cm-btn-accept');
59
58
  }
60
- return click('.klaro .cookie-notice .cm-btn-success');
59
+ return this.click('.klaro .cookie-notice .cm-btn-success');
61
60
  }
62
61
 
63
62
  async test() {
@@ -1,4 +1,3 @@
1
- import { click, elementExists, elementVisible, wait, waitForElement, waitForVisible } from "../rule-executors";
2
1
  import { RunContext } from "../rules";
3
2
  import { waitFor } from "../utils";
4
3
  import AutoConsentCMPBase from "./base";
@@ -24,39 +23,39 @@ export default class Onetrust extends AutoConsentCMPBase {
24
23
  }
25
24
 
26
25
  async detectCmp() {
27
- return elementExists("#onetrust-banner-sdk");
26
+ return this.elementExists("#onetrust-banner-sdk");
28
27
  }
29
28
 
30
29
  async detectPopup() {
31
- return elementVisible("#onetrust-banner-sdk", 'all');
30
+ return this.elementVisible("#onetrust-banner-sdk", 'all');
32
31
  }
33
32
 
34
33
  async optOut() {
35
- if (elementVisible("#onetrust-reject-all-handler,.js-reject-cookies", 'any')) { // 'reject all' shortcut
36
- return click("#onetrust-reject-all-handler,.js-reject-cookies");
34
+ if (this.elementVisible("#onetrust-reject-all-handler,.js-reject-cookies", 'any')) { // 'reject all' shortcut
35
+ return this.click("#onetrust-reject-all-handler,.js-reject-cookies");
37
36
  }
38
37
 
39
- if (elementExists("#onetrust-pc-btn-handler")) { // "show purposes" button inside a popup
40
- click("#onetrust-pc-btn-handler");
38
+ if (this.elementExists("#onetrust-pc-btn-handler")) { // "show purposes" button inside a popup
39
+ this.click("#onetrust-pc-btn-handler");
41
40
  } else { // otherwise look for a generic "show settings" button
42
- click(".ot-sdk-show-settings,button.js-cookie-settings");
41
+ this.click(".ot-sdk-show-settings,button.js-cookie-settings");
43
42
  }
44
43
 
45
- await waitForElement('#onetrust-consent-sdk', 2000);
46
- await wait(1000); // ideally we want to wait for popup visivility, but it's tricky on e.g. stackoverflow.com
47
- click("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked", true); // optional step
44
+ await this.waitForElement('#onetrust-consent-sdk', 2000);
45
+ await this.wait(1000); // ideally we want to wait for popup visivility, but it's tricky on e.g. stackoverflow.com
46
+ this.click("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked", true); // optional step
48
47
 
49
- await wait(1000); // ideally we want to wait for popup visivility, but it's tricky on e.g. stackoverflow.com
50
- await waitForElement(".save-preference-btn-handler,.js-consent-save", 2000);
51
- click(".save-preference-btn-handler,.js-consent-save");
48
+ await this.wait(1000); // ideally we want to wait for popup visivility, but it's tricky on e.g. stackoverflow.com
49
+ await this.waitForElement(".save-preference-btn-handler,.js-consent-save", 2000);
50
+ this.click(".save-preference-btn-handler,.js-consent-save");
52
51
 
53
52
  // popup doesn't disappear immediately
54
- await waitForVisible("#onetrust-banner-sdk", 5000, 'none');
53
+ await this.waitForVisible("#onetrust-banner-sdk", 5000, 'none');
55
54
  return true;
56
55
  }
57
56
 
58
57
  async optIn() {
59
- return click("#onetrust-accept-btn-handler,.js-accept-cookies");
58
+ return this.click("#onetrust-accept-btn-handler,.js-accept-cookies");
60
59
  }
61
60
 
62
61
  async test() {