@duckduckgo/autoconsent 14.0.1 → 14.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/actions/setup-release-scripts/action.yml +1 -1
- package/.github/workflows/checks.yml +4 -4
- package/.github/workflows/release.yml +2 -2
- package/.github/workflows/update-filterlist.yml +2 -2
- package/CHANGELOG.md +43 -0
- package/api.md +1 -0
- package/dist/addon-firefox/background.bundle.js +11 -2
- package/dist/addon-firefox/content.bundle.js +510 -347
- package/dist/addon-firefox/manifest.json +1 -1
- package/dist/addon-firefox/rules.json +1 -1
- package/dist/addon-mv3/background.bundle.js +11 -2
- package/dist/addon-mv3/content.bundle.js +510 -347
- package/dist/addon-mv3/manifest.json +1 -1
- package/dist/addon-mv3/popup.bundle.js +19 -1
- package/dist/addon-mv3/popup.html +14 -0
- package/dist/addon-mv3/rules.json +1 -1
- package/dist/autoconsent.cjs.js +353 -219
- package/dist/autoconsent.esm.js +354 -219
- package/dist/autoconsent.extra.cjs.js +519 -347
- package/dist/autoconsent.extra.esm.js +520 -347
- package/dist/autoconsent.playwright.js +520 -348
- package/lib/cmps/admiral.ts +6 -6
- package/lib/cmps/base.ts +43 -8
- package/lib/cmps/consentmanager.ts +8 -7
- package/lib/cmps/cookiebot.ts +4 -4
- package/lib/cmps/evidon.ts +2 -2
- package/lib/cmps/klaro.ts +8 -8
- package/lib/cmps/onetrust.ts +6 -6
- package/lib/cmps/sourcepoint-frame.ts +12 -12
- package/lib/cmps/tiktok.ts +3 -3
- package/lib/cmps/trustarc-frame.ts +11 -11
- package/lib/cmps/trustarc-top.ts +2 -6
- package/lib/dom-actions.ts +6 -6
- package/lib/eval-snippets.ts +6 -1
- package/lib/filterlist-engine.ts +2 -2
- package/lib/messages.ts +6 -0
- package/lib/types.ts +3 -2
- package/lib/utils.ts +49 -0
- package/lib/web.ts +50 -37
- package/package.json +2 -2
- package/playwright/runner.ts +1 -1
- package/readme.md +1 -1
- package/rules/autoconsent/cookie-law-info.json +16 -5
- package/rules/autoconsent/cookiehub.json +61 -0
- package/rules/autoconsent/eu-cookie-compliance.json +13 -12
- package/rules/compact-rules.json +1 -1
- package/rules/filterlist.txt +221 -202
- package/rules/rules.json +1 -1
- package/tests/{cookielawinfo.spec.ts → cookie-law-info.spec.ts} +4 -1
- package/tests/cookiehub.spec.ts +8 -0
- package/tests/eu-cookie-compliance-banner.spec.ts +1 -1
- package/tests-wtr/dom-actions/dom-actions.click.ts +14 -14
- package/tests-wtr/utils/highlight.test.ts +166 -0
package/lib/messages.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type BackgroundMessage = InitResponseMessage | EvalResponseMessage | OptO
|
|
|
7
7
|
export type ContentScriptMessage =
|
|
8
8
|
| InitMessage
|
|
9
9
|
| EvalMessage
|
|
10
|
+
| DelayMessage
|
|
10
11
|
| DetectedMessage
|
|
11
12
|
| FoundMessage
|
|
12
13
|
| OptOutResultMessage
|
|
@@ -32,6 +33,11 @@ export type EvalMessage = {
|
|
|
32
33
|
snippetId?: keyof typeof snippets;
|
|
33
34
|
};
|
|
34
35
|
|
|
36
|
+
export type DelayMessage = {
|
|
37
|
+
type: 'visualDelay';
|
|
38
|
+
timeout: number;
|
|
39
|
+
};
|
|
40
|
+
|
|
35
41
|
export type DetectedMessage = {
|
|
36
42
|
type: 'cmpDetected';
|
|
37
43
|
cmp: string;
|
package/lib/types.ts
CHANGED
|
@@ -24,7 +24,7 @@ export interface AutoCMP {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export interface DomActionsProvider {
|
|
27
|
-
click(selector: ElementSelector, all: boolean): boolean
|
|
27
|
+
click(selector: ElementSelector, all: boolean): Promise<boolean>;
|
|
28
28
|
elementExists(selector: ElementSelector): boolean;
|
|
29
29
|
elementVisible(selector: ElementSelector, check: VisibilityCheck): boolean;
|
|
30
30
|
waitForElement(selector: ElementSelector, timeout?: number): Promise<boolean>;
|
|
@@ -59,6 +59,7 @@ export type Config = {
|
|
|
59
59
|
prehideTimeout: number;
|
|
60
60
|
enableFilterList: boolean;
|
|
61
61
|
enableHeuristicDetection: boolean;
|
|
62
|
+
visualTest: boolean; // If true, the script will delay before every click action
|
|
62
63
|
logs: {
|
|
63
64
|
lifecycle: boolean;
|
|
64
65
|
rulesteps: boolean;
|
|
@@ -97,5 +98,5 @@ export type ConsentState = {
|
|
|
97
98
|
detectedPopups: string[]; // Names of CMP rules where `detectPopup` returned true.
|
|
98
99
|
heuristicPatterns: string[]; // Matched heuristic patterns
|
|
99
100
|
heuristicSnippets: string[]; // Matched heuristic snippets
|
|
100
|
-
selfTest: boolean; // null if no self test was run, otherwise it holds the result of the self test.
|
|
101
|
+
selfTest: boolean | null; // null if no self test was run, otherwise it holds the result of the self test.
|
|
101
102
|
};
|
package/lib/utils.ts
CHANGED
|
@@ -61,6 +61,7 @@ export function isElementVisible(elem: HTMLElement): boolean {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export function copyObject(data: any) {
|
|
64
|
+
// @ts-expect-error - globalThis.structuredClone may be undefined
|
|
64
65
|
if (globalThis.structuredClone) {
|
|
65
66
|
return structuredClone(data);
|
|
66
67
|
}
|
|
@@ -79,6 +80,7 @@ export function normalizeConfig(providedConfig: any): Config {
|
|
|
79
80
|
isMainWorld: false,
|
|
80
81
|
prehideTimeout: 2000,
|
|
81
82
|
enableFilterList: false,
|
|
83
|
+
visualTest: false,
|
|
82
84
|
logs: {
|
|
83
85
|
lifecycle: false,
|
|
84
86
|
rulesteps: false,
|
|
@@ -101,9 +103,56 @@ export function normalizeConfig(providedConfig: any): Config {
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
export function scheduleWhenIdle(callback: () => void, timeout = 500) {
|
|
106
|
+
// @ts-expect-error - globalThis.requestIdleCallback may be undefined
|
|
104
107
|
if (globalThis.requestIdleCallback) {
|
|
105
108
|
requestIdleCallback(callback, { timeout });
|
|
106
109
|
} else {
|
|
107
110
|
setTimeout(callback, 0);
|
|
108
111
|
}
|
|
109
112
|
}
|
|
113
|
+
|
|
114
|
+
export function highlightNode(node: HTMLElement) {
|
|
115
|
+
if (!node.style) return;
|
|
116
|
+
if (node.__oldStyles !== undefined) {
|
|
117
|
+
return; // already highlighted
|
|
118
|
+
}
|
|
119
|
+
if (node.hasAttribute('style')) {
|
|
120
|
+
node.__oldStyles = node.style.cssText;
|
|
121
|
+
}
|
|
122
|
+
node.style.animation = 'pulsate .5s infinite';
|
|
123
|
+
node.style.outline = 'solid red';
|
|
124
|
+
|
|
125
|
+
let styleTag = document.querySelector('style#autoconsent-debug-styles');
|
|
126
|
+
if (!styleTag) {
|
|
127
|
+
styleTag = document.createElement('style');
|
|
128
|
+
styleTag.id = 'autoconsent-debug-styles';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
styleTag.textContent = `
|
|
132
|
+
@keyframes pulsate {
|
|
133
|
+
0% {
|
|
134
|
+
outline-width: 8px;
|
|
135
|
+
outline-offset: -4px;
|
|
136
|
+
}
|
|
137
|
+
50% {
|
|
138
|
+
outline-width: 4px;
|
|
139
|
+
outline-offset: -2px;
|
|
140
|
+
}
|
|
141
|
+
100% {
|
|
142
|
+
outline-width: 8px;
|
|
143
|
+
outline-offset: -4px;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
`;
|
|
147
|
+
document.head.appendChild(styleTag);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function unhighlightNode(node: HTMLElement) {
|
|
151
|
+
if (!node.style || !node.hasAttribute('style')) return;
|
|
152
|
+
if (node.__oldStyles !== undefined) {
|
|
153
|
+
node.style.cssText = node.__oldStyles;
|
|
154
|
+
delete node.__oldStyles;
|
|
155
|
+
} else {
|
|
156
|
+
node.removeAttribute('style');
|
|
157
|
+
}
|
|
158
|
+
}
|
package/lib/web.ts
CHANGED
|
@@ -28,8 +28,8 @@ function filterCMPs(rules: AutoCMP[], config: Config) {
|
|
|
28
28
|
export default class AutoConsent {
|
|
29
29
|
id = getRandomID();
|
|
30
30
|
rules: AutoCMP[] = [];
|
|
31
|
-
config
|
|
32
|
-
foundCmp
|
|
31
|
+
#config?: Config;
|
|
32
|
+
foundCmp?: AutoCMP;
|
|
33
33
|
state: ConsentState = {
|
|
34
34
|
cosmeticFiltersOn: false,
|
|
35
35
|
filterListReported: false,
|
|
@@ -43,12 +43,12 @@ export default class AutoConsent {
|
|
|
43
43
|
selfTest: null,
|
|
44
44
|
};
|
|
45
45
|
domActions: DomActions;
|
|
46
|
-
filtersEngine
|
|
47
|
-
|
|
48
|
-
protected cosmeticStyleSheet
|
|
49
|
-
protected focusedElement
|
|
46
|
+
filtersEngine?: FiltersEngine;
|
|
47
|
+
sendContentMessage: MessageSender;
|
|
48
|
+
protected cosmeticStyleSheet?: CSSStyleSheet;
|
|
49
|
+
protected focusedElement?: HTMLElement;
|
|
50
50
|
|
|
51
|
-
constructor(sendContentMessage: MessageSender, config: Partial<Config> = null, declarativeRules: RuleBundle = null) {
|
|
51
|
+
constructor(sendContentMessage: MessageSender, config: Partial<Config> | null = null, declarativeRules: RuleBundle | null = null) {
|
|
52
52
|
evalState.sendContentMessage = sendContentMessage;
|
|
53
53
|
this.sendContentMessage = sendContentMessage;
|
|
54
54
|
this.rules = [];
|
|
@@ -72,10 +72,17 @@ export default class AutoConsent {
|
|
|
72
72
|
this.domActions = new DomActions(this);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
get config() {
|
|
76
|
+
if (!this.#config) {
|
|
77
|
+
throw new Error('AutoConsent is not initialized yet');
|
|
78
|
+
}
|
|
79
|
+
return this.#config;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
initialize(config: Partial<Config>, declarativeRules: RuleBundle | null) {
|
|
76
83
|
const normalizedConfig = normalizeConfig(config);
|
|
77
84
|
normalizedConfig.logs.lifecycle && console.log('autoconsent init', window.location.href);
|
|
78
|
-
this
|
|
85
|
+
this.#config = normalizedConfig;
|
|
79
86
|
if (!normalizedConfig.enabled) {
|
|
80
87
|
normalizedConfig.logs.lifecycle && console.log('autoconsent is disabled');
|
|
81
88
|
return;
|
|
@@ -85,9 +92,9 @@ export default class AutoConsent {
|
|
|
85
92
|
this.parseDeclarativeRules(declarativeRules);
|
|
86
93
|
}
|
|
87
94
|
|
|
88
|
-
if (config.enableFilterList) {
|
|
95
|
+
if (BUNDLE_FILTERLIST && config.enableFilterList) {
|
|
89
96
|
try {
|
|
90
|
-
if (
|
|
97
|
+
if (serializedEngine && serializedEngine.length > 0) {
|
|
91
98
|
this.filtersEngine = deserializeFilterList(serializedEngine);
|
|
92
99
|
}
|
|
93
100
|
} catch (e) {
|
|
@@ -104,7 +111,7 @@ export default class AutoConsent {
|
|
|
104
111
|
|
|
105
112
|
this.rules = filterCMPs(this.rules, normalizedConfig);
|
|
106
113
|
|
|
107
|
-
if (
|
|
114
|
+
if (this.shouldPrehide) {
|
|
108
115
|
if (document.documentElement) {
|
|
109
116
|
this.prehideElements(); // prehide as early as possible to prevent flickering
|
|
110
117
|
} else {
|
|
@@ -130,6 +137,10 @@ export default class AutoConsent {
|
|
|
130
137
|
this.updateState({ lifecycle: 'initialized' });
|
|
131
138
|
}
|
|
132
139
|
|
|
140
|
+
get shouldPrehide() {
|
|
141
|
+
return this.config.enablePrehide && !this.config.visualTest;
|
|
142
|
+
}
|
|
143
|
+
|
|
133
144
|
saveFocus() {
|
|
134
145
|
this.focusedElement = document.activeElement as HTMLElement;
|
|
135
146
|
if (this.focusedElement) {
|
|
@@ -145,7 +156,7 @@ export default class AutoConsent {
|
|
|
145
156
|
} catch (e) {
|
|
146
157
|
this.config.logs.errors && console.warn('error restoring focus', e);
|
|
147
158
|
}
|
|
148
|
-
this.focusedElement =
|
|
159
|
+
this.focusedElement = undefined;
|
|
149
160
|
}
|
|
150
161
|
}
|
|
151
162
|
|
|
@@ -157,9 +168,9 @@ export default class AutoConsent {
|
|
|
157
168
|
|
|
158
169
|
parseDeclarativeRules(declarativeRules: RuleBundle) {
|
|
159
170
|
if (declarativeRules.consentomatic) {
|
|
160
|
-
Object.
|
|
161
|
-
this.addConsentomaticCMP(name,
|
|
162
|
-
}
|
|
171
|
+
for (const [name, rule] of Object.entries(declarativeRules.consentomatic)) {
|
|
172
|
+
this.addConsentomaticCMP(name, rule);
|
|
173
|
+
}
|
|
163
174
|
}
|
|
164
175
|
|
|
165
176
|
if (declarativeRules.autoconsent) {
|
|
@@ -202,7 +213,7 @@ export default class AutoConsent {
|
|
|
202
213
|
this.updateState({ detectedCmps: foundCmps.map((c) => c.name) });
|
|
203
214
|
if (foundCmps.length === 0) {
|
|
204
215
|
logsConfig.lifecycle && console.log('no CMP found', location.href);
|
|
205
|
-
if (this.
|
|
216
|
+
if (this.shouldPrehide) {
|
|
206
217
|
this.undoPrehide();
|
|
207
218
|
}
|
|
208
219
|
|
|
@@ -236,7 +247,7 @@ export default class AutoConsent {
|
|
|
236
247
|
|
|
237
248
|
if (foundPopups.length === 0) {
|
|
238
249
|
logsConfig.lifecycle && console.log('no popup found');
|
|
239
|
-
if (this.
|
|
250
|
+
if (this.shouldPrehide) {
|
|
240
251
|
this.undoPrehide();
|
|
241
252
|
}
|
|
242
253
|
return false;
|
|
@@ -395,11 +406,11 @@ export default class AutoConsent {
|
|
|
395
406
|
|
|
396
407
|
async handlePopup(cmp: AutoCMP): Promise<boolean> {
|
|
397
408
|
this.updateState({ lifecycle: 'openPopupDetected' });
|
|
398
|
-
if (this.
|
|
409
|
+
if (this.shouldPrehide && !this.state.prehideOn) {
|
|
399
410
|
// prehide might have timeouted by this time, apply it again
|
|
400
411
|
this.prehideElements();
|
|
401
412
|
}
|
|
402
|
-
if (this.state.cosmeticFiltersOn) {
|
|
413
|
+
if (BUNDLE_FILTERLIST && this.state.cosmeticFiltersOn) {
|
|
403
414
|
// cancel cosmetic filters if we have a rule for this popup
|
|
404
415
|
this.undoCosmetics();
|
|
405
416
|
}
|
|
@@ -431,7 +442,7 @@ export default class AutoConsent {
|
|
|
431
442
|
logsConfig.lifecycle && console.log(`${this.foundCmp.name}: opt out result ${optOutResult}`);
|
|
432
443
|
}
|
|
433
444
|
|
|
434
|
-
if (this.
|
|
445
|
+
if (this.shouldPrehide) {
|
|
435
446
|
this.undoPrehide();
|
|
436
447
|
}
|
|
437
448
|
|
|
@@ -439,15 +450,15 @@ export default class AutoConsent {
|
|
|
439
450
|
type: 'optOutResult',
|
|
440
451
|
cmp: this.foundCmp ? this.foundCmp.name : 'none',
|
|
441
452
|
result: optOutResult,
|
|
442
|
-
scheduleSelfTest: this.foundCmp && this.foundCmp.hasSelfTest,
|
|
453
|
+
scheduleSelfTest: Boolean(this.foundCmp && this.foundCmp.hasSelfTest),
|
|
443
454
|
url: location.href,
|
|
444
455
|
});
|
|
445
456
|
|
|
446
|
-
if (optOutResult && !this.foundCmp.isIntermediate) {
|
|
457
|
+
if (optOutResult && this.foundCmp && !this.foundCmp.isIntermediate) {
|
|
447
458
|
this.sendContentMessage({
|
|
448
459
|
type: 'autoconsentDone',
|
|
449
|
-
cmp: this.foundCmp
|
|
450
|
-
isCosmetic: this.foundCmp
|
|
460
|
+
cmp: this.foundCmp?.name,
|
|
461
|
+
isCosmetic: this.foundCmp?.isCosmetic,
|
|
451
462
|
url: location.href,
|
|
452
463
|
});
|
|
453
464
|
this.updateState({ lifecycle: 'done' });
|
|
@@ -474,7 +485,7 @@ export default class AutoConsent {
|
|
|
474
485
|
logsConfig.lifecycle && console.log(`${this.foundCmp.name}: opt in result ${optInResult}`);
|
|
475
486
|
}
|
|
476
487
|
|
|
477
|
-
if (this.
|
|
488
|
+
if (this.shouldPrehide) {
|
|
478
489
|
this.undoPrehide();
|
|
479
490
|
}
|
|
480
491
|
|
|
@@ -486,7 +497,7 @@ export default class AutoConsent {
|
|
|
486
497
|
url: location.href,
|
|
487
498
|
});
|
|
488
499
|
|
|
489
|
-
if (optInResult && !this.foundCmp.isIntermediate) {
|
|
500
|
+
if (optInResult && this.foundCmp && !this.foundCmp.isIntermediate) {
|
|
490
501
|
this.sendContentMessage({
|
|
491
502
|
type: 'autoconsentDone',
|
|
492
503
|
cmp: this.foundCmp.name,
|
|
@@ -547,12 +558,12 @@ export default class AutoConsent {
|
|
|
547
558
|
|
|
548
559
|
const selectors = this.rules
|
|
549
560
|
.filter((rule) => rule.prehideSelectors && rule.checkRunContext())
|
|
550
|
-
.reduce((selectorList, rule) => [...selectorList, ...rule.prehideSelectors], globalHidden);
|
|
561
|
+
.reduce((selectorList, rule) => [...(selectorList || []), ...(rule.prehideSelectors || [])], globalHidden);
|
|
551
562
|
|
|
552
563
|
this.updateState({ prehideOn: true });
|
|
553
564
|
setTimeout(() => {
|
|
554
565
|
// unhide things if we are still looking for a pop-up
|
|
555
|
-
if (this.
|
|
566
|
+
if (this.shouldPrehide && this.state.prehideOn && !['runningOptOut', 'runningOptIn'].includes(this.state.lifecycle)) {
|
|
556
567
|
logsConfig.lifecycle && console.log('Process is taking too long, unhiding elements');
|
|
557
568
|
this.undoPrehide();
|
|
558
569
|
}
|
|
@@ -570,11 +581,11 @@ export default class AutoConsent {
|
|
|
570
581
|
* @returns true if the filters were applied, false otherwise
|
|
571
582
|
*/
|
|
572
583
|
async applyCosmeticFilters(styles?: string) {
|
|
573
|
-
if (!this.filtersEngine) {
|
|
584
|
+
if (!BUNDLE_FILTERLIST || !this.filtersEngine) {
|
|
574
585
|
return false;
|
|
575
586
|
}
|
|
576
|
-
const logsConfig = this.config
|
|
577
|
-
if (
|
|
587
|
+
const logsConfig = this.config.logs;
|
|
588
|
+
if (!styles) {
|
|
578
589
|
styles = getCosmeticStylesheet(this.filtersEngine);
|
|
579
590
|
}
|
|
580
591
|
|
|
@@ -606,9 +617,11 @@ export default class AutoConsent {
|
|
|
606
617
|
}
|
|
607
618
|
|
|
608
619
|
undoCosmetics() {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
620
|
+
if (BUNDLE_FILTERLIST) {
|
|
621
|
+
this.updateState({ cosmeticFiltersOn: false });
|
|
622
|
+
this.config.logs.lifecycle && console.log('[undocosmetics]', this.cosmeticStyleSheet, location.href);
|
|
623
|
+
this.domActions.removeStyleSheet(this.cosmeticStyleSheet);
|
|
624
|
+
}
|
|
612
625
|
}
|
|
613
626
|
|
|
614
627
|
reportFilterlist() {
|
|
@@ -636,7 +649,7 @@ export default class AutoConsent {
|
|
|
636
649
|
// this may be a false positive: sometimes filters hide unrelated elements that are not cookie pop-ups
|
|
637
650
|
const cosmeticFiltersWorked = this.domActions.elementVisible(getFilterlistSelectors(cosmeticStyles), 'any');
|
|
638
651
|
|
|
639
|
-
const logsConfig = this.config
|
|
652
|
+
const logsConfig = this.config.logs;
|
|
640
653
|
|
|
641
654
|
if (!cosmeticFiltersWorked) {
|
|
642
655
|
logsConfig?.lifecycle && console.log("Cosmetic filters didn't work, removing them", location.href);
|
|
@@ -681,7 +694,7 @@ export default class AutoConsent {
|
|
|
681
694
|
}
|
|
682
695
|
|
|
683
696
|
async receiveMessageCallback(message: BackgroundMessage) {
|
|
684
|
-
const logsConfig = this
|
|
697
|
+
const logsConfig = this.#config?.logs;
|
|
685
698
|
if (logsConfig?.messages) {
|
|
686
699
|
console.log('received from background', message, window.location.href);
|
|
687
700
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duckduckgo/autoconsent",
|
|
3
|
-
"version": "14.0
|
|
3
|
+
"version": "14.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@esm-bundle/chai": "^4.3.4-fix.0",
|
|
52
52
|
"@playwright/test": "^1.17.1",
|
|
53
53
|
"@types/chai": "^5.0.0",
|
|
54
|
-
"@types/chrome": "^0.0.
|
|
54
|
+
"@types/chrome": "^0.0.326",
|
|
55
55
|
"@types/eslint": "^9.6.1",
|
|
56
56
|
"@types/mocha": "^10.0.1",
|
|
57
57
|
"@types/sinon": "^17.0.4",
|
package/playwright/runner.ts
CHANGED
|
@@ -73,7 +73,7 @@ export function generateTest(url: string, expectedCmp: string, options: TestOpti
|
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
let selfTestFrame: Frame = null;
|
|
76
|
+
let selfTestFrame: Frame | null = null;
|
|
77
77
|
async function messageCallback({ frame }: { frame: Frame }, msg: ContentScriptMessage) {
|
|
78
78
|
LOG_MESSAGES.includes(msg.type) && console.log(msg);
|
|
79
79
|
received.push(msg);
|
package/readme.md
CHANGED
|
@@ -174,7 +174,7 @@ Returns true if the given selector matches one or more elements.
|
|
|
174
174
|
"check": "any" | "all" | "none"
|
|
175
175
|
}
|
|
176
176
|
```
|
|
177
|
-
Returns true if elements matched by ElementSelector are currently visible on the page. If `check` is `all
|
|
177
|
+
Returns true if elements matched by ElementSelector are currently visible on the page. If `check` is `all` (default), every element must be visible. If `check` is `none`, no element should be visible. Visibility check is a CSS-based heuristic.
|
|
178
178
|
|
|
179
179
|
### Wait for element
|
|
180
180
|
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cookie-law-info",
|
|
3
|
-
"prehideSelectors": ["#cookie-law-info-bar, #cookie-law-bg"],
|
|
3
|
+
"prehideSelectors": ["#cookie-law-info-bar, #cookie-law-bg, .cli-popupbar-overlay"],
|
|
4
4
|
"detectCmp": [{ "exists": "#cookie-law-info-bar" }, { "eval": "EVAL_COOKIE_LAW_INFO_DETECT" }],
|
|
5
|
-
"detectPopup": [{ "visible": "#cookie-law-info-bar
|
|
6
|
-
"optIn": [
|
|
5
|
+
"detectPopup": [{ "visible": "#cookie-law-info-bar" }],
|
|
6
|
+
"optIn": [
|
|
7
|
+
{
|
|
8
|
+
"click": "[data-cli_action=\"accept\"]"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
7
11
|
"optOut": [
|
|
8
|
-
{
|
|
12
|
+
{
|
|
13
|
+
"hide": "#cookie-law-info-bar, #cookie-law-bg, .cli-popupbar-overlay"
|
|
14
|
+
},
|
|
9
15
|
{
|
|
10
16
|
"eval": "EVAL_COOKIE_LAW_INFO_0"
|
|
11
17
|
}
|
|
12
18
|
],
|
|
13
|
-
"test": [
|
|
19
|
+
"test": [
|
|
20
|
+
{
|
|
21
|
+
"cookieContains": "cookielawinfo-checkbox-non-necessary=yes",
|
|
22
|
+
"negated": true
|
|
23
|
+
}
|
|
24
|
+
]
|
|
14
25
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cookiehub",
|
|
3
|
+
"vendorUrl": "https://www.cookiehub.com/",
|
|
4
|
+
"prehideSelectors": [".ch2-container"],
|
|
5
|
+
"detectCmp": [
|
|
6
|
+
{
|
|
7
|
+
"exists": ".ch2-dialog"
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"detectPopup": [
|
|
11
|
+
{
|
|
12
|
+
"visible": ".ch2-dialog"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"optIn": [
|
|
16
|
+
{
|
|
17
|
+
"waitForThenClick": ".ch2-allow-all-btn"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"optOut": [
|
|
21
|
+
{
|
|
22
|
+
"if": { "exists": ".ch2-open-settings-btn, .ch2-open-personal-data-btn" },
|
|
23
|
+
"then": [
|
|
24
|
+
{
|
|
25
|
+
"click": ".ch2-open-settings-btn, .ch2-open-personal-data-btn"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"waitForVisible": ".ch2-settings"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"if": { "exists": ".ch2-deny-all-btn" },
|
|
32
|
+
"then": [
|
|
33
|
+
{
|
|
34
|
+
"click": ".ch2-deny-all-btn"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"else": [
|
|
38
|
+
{
|
|
39
|
+
"click": ".ch2-settings input[type=checkbox]:not([disabled]):checked",
|
|
40
|
+
"all": true,
|
|
41
|
+
"optional": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"click": ".ch2-save-settings-btn"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"else": [
|
|
50
|
+
{
|
|
51
|
+
"hide": ".ch2-container"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"test": [
|
|
57
|
+
{
|
|
58
|
+
"cookieContains": "cookiehub="
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
"name": "eu-cookie-compliance-banner",
|
|
3
3
|
"detectCmp": [{ "exists": "body.eu-cookie-compliance-popup-open" }],
|
|
4
4
|
"detectPopup": [{ "exists": "body.eu-cookie-compliance-popup-open" }],
|
|
5
|
-
"optIn": [
|
|
5
|
+
"optIn": [
|
|
6
|
+
{
|
|
7
|
+
"click": ".eu-cookie-compliance-banner .agree-button, .eu-cookie-compliance-banner .accept-all"
|
|
8
|
+
}
|
|
9
|
+
],
|
|
6
10
|
"optOut": [
|
|
7
11
|
{
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
},
|
|
11
|
-
"then": [
|
|
12
|
-
{
|
|
13
|
-
"click": ".decline-button,.eu-cookie-compliance-save-preferences-button"
|
|
14
|
-
}
|
|
15
|
-
]
|
|
16
|
-
},
|
|
17
|
-
{ "hide": ".eu-cookie-compliance-banner-info, #sliding-popup" }
|
|
12
|
+
"click": ".eu-cookie-compliance-banner .decline-button, .eu-cookie-compliance-banner .accept-necessary, .eu-cookie-compliance-save-preferences-button"
|
|
13
|
+
}
|
|
18
14
|
],
|
|
19
|
-
"test": [
|
|
15
|
+
"test": [
|
|
16
|
+
{
|
|
17
|
+
"cookieContains": "cookie-agreed=2",
|
|
18
|
+
"negated": true
|
|
19
|
+
}
|
|
20
|
+
]
|
|
20
21
|
}
|