@duckduckgo/autoconsent 1.0.8 → 2.1.1
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/.eslintrc.cjs +14 -0
- package/.vscode/.idea/.vscode.iml +9 -0
- package/.vscode/.idea/modules.xml +8 -0
- package/.vscode/.idea/workspace.xml +28 -0
- package/.vscode/settings.json +7 -0
- package/Jenkinsfile +68 -39
- package/api.md +104 -0
- package/dist/addon-firefox/background.bundle.js +1 -0
- package/dist/addon-firefox/content.bundle.js +1 -0
- package/dist/addon-firefox/icons/cog.png +0 -0
- package/dist/addon-firefox/icons/cookie-idle.png +0 -0
- package/dist/addon-firefox/icons/cookie.png +0 -0
- package/dist/addon-firefox/icons/party.png +0 -0
- package/dist/addon-firefox/icons/tick.png +0 -0
- package/dist/addon-firefox/icons/verified.png +0 -0
- package/dist/addon-firefox/manifest.json +32 -0
- package/dist/addon-firefox/rules.json +4167 -0
- package/dist/addon-mv3/background.bundle.js +1 -0
- package/dist/addon-mv3/content.bundle.js +1 -0
- package/dist/addon-mv3/icons/cog.png +0 -0
- package/dist/addon-mv3/icons/cookie-idle.png +0 -0
- package/dist/addon-mv3/icons/cookie.png +0 -0
- package/dist/addon-mv3/icons/party.png +0 -0
- package/dist/addon-mv3/icons/tick.png +0 -0
- package/dist/addon-mv3/icons/verified.png +0 -0
- package/dist/addon-mv3/manifest.json +34 -0
- package/dist/addon-mv3/rules.json +4167 -0
- package/dist/autoconsent.cjs.js +1 -1387
- package/dist/autoconsent.esm.js +1 -1379
- package/dist/autoconsent.playwright.js +1 -0
- package/lib/cmps/all.ts +15 -10
- package/lib/cmps/base.ts +95 -90
- package/lib/cmps/consentmanager.ts +31 -19
- package/lib/cmps/consentomatic.ts +89 -0
- package/lib/cmps/cookiebot.ts +58 -55
- package/lib/cmps/evidon.ts +29 -18
- package/lib/cmps/onetrust.ts +32 -20
- package/lib/cmps/sourcepoint-frame.ts +104 -0
- package/lib/cmps/sourcepoint-top.ts +47 -0
- package/lib/cmps/trustarc-frame.ts +115 -0
- package/lib/cmps/trustarc-top.ts +97 -0
- package/lib/consentomatic/index.ts +233 -70
- package/lib/{web/consentomatic → consentomatic}/tools.ts +0 -0
- package/lib/eval-handler.ts +58 -0
- package/lib/index.ts +0 -2
- package/lib/messages.ts +100 -0
- package/lib/rule-executors.ts +108 -0
- package/lib/rules.ts +82 -0
- package/lib/types.ts +35 -0
- package/lib/utils.ts +64 -0
- package/lib/web.ts +288 -74
- package/package.json +20 -16
- package/playwright/content.ts +21 -0
- package/playwright/runner.ts +162 -0
- package/playwright.config.ts +7 -0
- package/readme.md +61 -47
- package/rollup.config.js +38 -16
- package/rules/autoconsent/ausopen.json +2 -1
- package/rules/autoconsent/baden-wuerttemberg-de.json +7 -3
- package/rules/autoconsent/bundesregierung-de.json +5 -1
- package/rules/autoconsent/cc-banner.json +0 -1
- package/rules/autoconsent/cookie-law-info.json +1 -1
- package/rules/autoconsent/cookie-notice.json +1 -2
- package/rules/autoconsent/cookieconsent.json +5 -6
- package/rules/autoconsent/destatis-de.json +2 -2
- package/rules/autoconsent/dunelm.json +1 -1
- package/rules/autoconsent/etsy.json +4 -3
- package/rules/autoconsent/eu-cookie-compliance.json +0 -1
- package/rules/autoconsent/hl-co-uk.json +8 -9
- package/rules/autoconsent/johnlewis.json +5 -2
- package/rules/autoconsent/marksandspencer.json +2 -1
- package/rules/autoconsent/mediamarkt-de.json +1 -1
- package/rules/autoconsent/microsoft.json +1 -1
- package/rules/autoconsent/notice-cookie.json +0 -1
- package/rules/autoconsent/osano.json +4 -2
- package/rules/autoconsent/snigel.json +2 -1
- package/rules/autoconsent/tealium.json +4 -5
- package/rules/autoconsent/thefreedictionary.json +1 -1
- package/rules/rules.json +79 -45
- package/tests/192.spec.ts +1 -1
- package/tests/arzt-auskunft.spec.ts +1 -1
- package/tests/asus.spec.ts +1 -1
- package/tests/ausopen.spec.ts +1 -1
- package/tests/aws.amazon.spec.ts +1 -1
- package/tests/baden-wuerttemberg.spec.ts +1 -1
- package/tests/borlabs.spec.ts +1 -1
- package/tests/bundesregierung.spec.ts +5 -2
- package/tests/ccbanner.spec.ts +1 -1
- package/tests/consentmanager.spec.ts +3 -3
- package/tests/cookiebot.spec.ts +8 -2
- package/tests/cookieconsent.spec.ts +1 -1
- package/tests/cookielawinfo.spec.ts +1 -1
- package/tests/cookienotice.spec.ts +1 -1
- package/tests/corona-in-zahlen.spec.ts +1 -1
- package/tests/deepl.spec.ts +1 -1
- package/tests/destatis.spec.ts +1 -1
- package/tests/didomi.spec.ts +7 -3
- package/tests/drupal.spec.ts +8 -0
- package/tests/dunelm.spec.ts +1 -1
- package/tests/etsy.spec.ts +1 -1
- package/tests/eu-cookie-compliance-banner.spec.ts +1 -1
- package/tests/evidon.spec.ts +7 -2
- package/tests/fundingchoices.spec.ts +2 -1
- package/tests/gov-uk.spec.ts +1 -1
- package/tests/hl-co-uk.spec.ts +1 -1
- package/tests/hubspot.spec.ts +1 -1
- package/tests/ionos.spec.ts +1 -1
- package/tests/johnlewis.spec.ts +2 -2
- package/tests/klaro.spec.ts +1 -1
- package/tests/marksandspencer.spec.ts +1 -1
- package/tests/mediamarkt.spec.ts +1 -1
- package/tests/metoffice-gov-uk.spec.ts +1 -1
- package/tests/microsoft.spec.ts +1 -1
- package/tests/moneysavingexpert.spec.ts +1 -1
- package/tests/motor-talk.spec.ts +1 -1
- package/tests/national-lottery.spec.ts +1 -1
- package/tests/netflix.spec.ts +1 -1
- package/tests/nhs.spec.ts +1 -1
- package/tests/notice-cookie.spec.ts +1 -1
- package/tests/obi.spec.ts +1 -1
- package/tests/oil.spec.ts +2 -2
- package/tests/onetrust.spec.ts +27 -2
- package/tests/osano.spec.ts +1 -1
- package/tests/otto.spec.ts +1 -1
- package/tests/paypal.spec.ts +1 -1
- package/tests/quantcast.spec.ts +5 -2
- package/tests/snigel.spec.ts +1 -1
- package/tests/sourcepoint.spec.ts +8 -8
- package/tests/springer.spec.ts +2 -2
- package/tests/steampowered.spec.ts +1 -1
- package/tests/tealium.spec.ts +1 -1
- package/tests/testcmp.spec.ts +1 -1
- package/tests/thalia.spec.ts +1 -1
- package/tests/thefreedictionary.spec.ts +1 -1
- package/tests/trustarc.spec.ts +26 -4
- package/tests/usercentrics-1.spec.ts +1 -1
- package/tests/uswitch.spec.ts +1 -1
- package/tests/vodafone.spec.ts +1 -1
- package/tests/waitrose.spec.ts +1 -1
- package/tests/wetransfer.spec.ts +1 -1
- package/tests/wordpressgdpr.spec.ts +2 -2
- package/tests/xing.spec.ts +1 -1
- package/tsconfig.json +2 -2
- package/update_version.js +10 -6
- package/.eslintrc +0 -12
- package/cosmetics/rules.json +0 -110
- package/dist/autoconsent.puppet.js +0 -1078
- package/lib/cmps/all.js +0 -19
- package/lib/cmps/base.js +0 -174
- package/lib/cmps/consentmanager.js +0 -31
- package/lib/cmps/cookiebot.js +0 -77
- package/lib/cmps/evidon.js +0 -26
- package/lib/cmps/onetrust.js +0 -34
- package/lib/cmps/sourcepoint.js +0 -82
- package/lib/cmps/sourcepoint.ts +0 -95
- package/lib/cmps/trustarc.js +0 -106
- package/lib/cmps/trustarc.ts +0 -147
- package/lib/config.js +0 -1
- package/lib/consentomatic/index.js +0 -52
- package/lib/detector.js +0 -33
- package/lib/detector.ts +0 -34
- package/lib/hider.js +0 -13
- package/lib/hider.ts +0 -16
- package/lib/index.js +0 -4
- package/lib/messages.d.ts +0 -61
- package/lib/node.js +0 -35
- package/lib/node.ts +0 -43
- package/lib/puppet/tab.js +0 -121
- package/lib/puppet/tab.ts +0 -146
- package/lib/rules.d.ts +0 -80
- package/lib/tabwrapper.js +0 -67
- package/lib/tabwrapper.ts +0 -74
- package/lib/types.d.ts +0 -61
- package/lib/web/consentomatic/index.ts +0 -249
- package/lib/web/content-utils.js +0 -29
- package/lib/web/content-utils.ts +0 -31
- package/lib/web/content.js +0 -89
- package/lib/web/content.ts +0 -80
- package/lib/web/tab.js +0 -112
- package/lib/web/tab.ts +0 -178
- package/lib/web.js +0 -95
- package/tests/runner.ts +0 -61
package/lib/web/content-utils.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { HideMethod } from "../messages";
|
|
2
|
-
|
|
3
|
-
// get or create a style container for CSS overrides
|
|
4
|
-
export function getStyleElementUtil(): HTMLStyleElement {
|
|
5
|
-
const styleOverrideElementId = "autoconsent-css-rules";
|
|
6
|
-
const styleSelector = `style#${styleOverrideElementId}`;
|
|
7
|
-
const existingElement = document.querySelector(styleSelector);
|
|
8
|
-
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
9
|
-
return existingElement;
|
|
10
|
-
} else {
|
|
11
|
-
const parent = document.head ||
|
|
12
|
-
document.getElementsByTagName("head")[0] ||
|
|
13
|
-
document.documentElement;
|
|
14
|
-
const css = document.createElement("style");
|
|
15
|
-
css.id = styleOverrideElementId;
|
|
16
|
-
parent.appendChild(css);
|
|
17
|
-
return css;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// hide elements with a CSS rule
|
|
22
|
-
export function hideElementsUtil(selectors: string[], method: HideMethod): boolean {
|
|
23
|
-
const hidingSnippet = method === 'display' ? `display: none` : `opacity: 0`;
|
|
24
|
-
const rule = `${selectors.join(",")} { ${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important; } `;
|
|
25
|
-
const styleEl = getStyleElementUtil();
|
|
26
|
-
if (styleEl instanceof HTMLStyleElement) {
|
|
27
|
-
styleEl.innerText += rule;
|
|
28
|
-
return selectors.length > 0;
|
|
29
|
-
}
|
|
30
|
-
return false;
|
|
31
|
-
}
|
package/lib/web/content.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { matches, executeAction } from "./consentomatic/index";
|
|
2
|
-
import { hideElementsUtil, getStyleElementUtil } from "./content-utils";
|
|
3
|
-
let actionQueue = Promise.resolve(null);
|
|
4
|
-
export default function handleMessage(message, debug = false) {
|
|
5
|
-
if (message.type === "click") {
|
|
6
|
-
const elem = document.querySelectorAll(message.selector);
|
|
7
|
-
debug && console.log("[click]", message.selector, elem);
|
|
8
|
-
if (elem.length > 0) {
|
|
9
|
-
if (message.all === true) {
|
|
10
|
-
elem.forEach(e => e.click());
|
|
11
|
-
}
|
|
12
|
-
else {
|
|
13
|
-
elem[0].click();
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
return elem.length > 0;
|
|
17
|
-
}
|
|
18
|
-
else if (message.type === "elemExists") {
|
|
19
|
-
const exists = document.querySelector(message.selector) !== null;
|
|
20
|
-
debug && console.log("[exists?]", message.selector, exists);
|
|
21
|
-
return exists;
|
|
22
|
-
}
|
|
23
|
-
else if (message.type === "elemVisible") {
|
|
24
|
-
const elem = document.querySelectorAll(message.selector);
|
|
25
|
-
const results = new Array(elem.length);
|
|
26
|
-
elem.forEach((e, i) => {
|
|
27
|
-
// check for display: none
|
|
28
|
-
results[i] = false;
|
|
29
|
-
if (e.offsetParent !== null) {
|
|
30
|
-
results[i] = true;
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
const css = window.getComputedStyle(e);
|
|
34
|
-
if (css.position === 'fixed' && css.display !== "none") { // fixed elements may be visible even if the parent is not
|
|
35
|
-
results[i] = true;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
debug && console.log("[visible?]", message.selector, elem, results);
|
|
40
|
-
if (results.length === 0) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
else if (message.check === "any") {
|
|
44
|
-
return results.some(r => r);
|
|
45
|
-
}
|
|
46
|
-
else if (message.check === "none") {
|
|
47
|
-
return results.every(r => !r);
|
|
48
|
-
}
|
|
49
|
-
// all
|
|
50
|
-
return results.every(r => r);
|
|
51
|
-
}
|
|
52
|
-
else if (message.type === "getAttribute") {
|
|
53
|
-
const elem = document.querySelector(message.selector);
|
|
54
|
-
debug && console.log("[getAttribute]", message.selector, elem);
|
|
55
|
-
if (!elem) {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
return elem.getAttribute(message.attribute);
|
|
59
|
-
}
|
|
60
|
-
else if (message.type === "eval") {
|
|
61
|
-
// TODO: chrome support
|
|
62
|
-
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
|
|
63
|
-
const result = window.eval(message.script); // eslint-disable-line no-eval
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
else if (message.type === "hide") {
|
|
67
|
-
debug && console.log("[hide]", message.selectors);
|
|
68
|
-
return hideElementsUtil(message.selectors, message.method);
|
|
69
|
-
}
|
|
70
|
-
else if (message.type === "undohide") {
|
|
71
|
-
const existingElement = getStyleElementUtil();
|
|
72
|
-
debug && console.log("[unhide]", !!existingElement);
|
|
73
|
-
if (existingElement) {
|
|
74
|
-
existingElement.remove();
|
|
75
|
-
}
|
|
76
|
-
return !!existingElement;
|
|
77
|
-
}
|
|
78
|
-
else if (message.type === "matches") {
|
|
79
|
-
const matched = matches(message.config);
|
|
80
|
-
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
|
|
81
|
-
return matched;
|
|
82
|
-
}
|
|
83
|
-
else if (message.type === "executeAction") {
|
|
84
|
-
debug && console.log("[executeAction]", message);
|
|
85
|
-
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
return null;
|
|
89
|
-
}
|
package/lib/web/content.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { matches, executeAction } from "./consentomatic/index";
|
|
2
|
-
import { ContentScriptMessage } from "../messages";
|
|
3
|
-
import { hideElementsUtil, getStyleElementUtil } from "./content-utils";
|
|
4
|
-
|
|
5
|
-
let actionQueue = Promise.resolve(null);
|
|
6
|
-
|
|
7
|
-
export default function handleMessage(message: ContentScriptMessage, debug = false) {
|
|
8
|
-
if (message.type === "click") {
|
|
9
|
-
const elem = document.querySelectorAll<HTMLElement>(message.selector);
|
|
10
|
-
debug && console.log("[click]", message.selector, elem);
|
|
11
|
-
if (elem.length > 0) {
|
|
12
|
-
if (message.all === true) {
|
|
13
|
-
elem.forEach(e => e.click());
|
|
14
|
-
} else {
|
|
15
|
-
elem[0].click();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return elem.length > 0;
|
|
19
|
-
} else if (message.type === "elemExists") {
|
|
20
|
-
const exists = document.querySelector(message.selector) !== null;
|
|
21
|
-
debug && console.log("[exists?]", message.selector, exists);
|
|
22
|
-
return exists;
|
|
23
|
-
} else if (message.type === "elemVisible") {
|
|
24
|
-
const elem = document.querySelectorAll<HTMLElement>(message.selector);
|
|
25
|
-
const results = new Array(elem.length);
|
|
26
|
-
elem.forEach((e, i) => {
|
|
27
|
-
// check for display: none
|
|
28
|
-
results[i] = false;
|
|
29
|
-
if (e.offsetParent !== null) {
|
|
30
|
-
results[i] = true;
|
|
31
|
-
} else {
|
|
32
|
-
const css = window.getComputedStyle(e);
|
|
33
|
-
if (css.position === 'fixed' && css.display !== "none") { // fixed elements may be visible even if the parent is not
|
|
34
|
-
results[i] = true;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
debug && console.log("[visible?]", message.selector, elem, results);
|
|
39
|
-
if (results.length === 0) {
|
|
40
|
-
return false;
|
|
41
|
-
} else if (message.check === "any") {
|
|
42
|
-
return results.some(r => r);
|
|
43
|
-
} else if (message.check === "none") {
|
|
44
|
-
return results.every(r => !r);
|
|
45
|
-
}
|
|
46
|
-
// all
|
|
47
|
-
return results.every(r => r);
|
|
48
|
-
} else if (message.type === "getAttribute") {
|
|
49
|
-
const elem = document.querySelector(message.selector);
|
|
50
|
-
debug && console.log("[getAttribute]", message.selector, elem);
|
|
51
|
-
if (!elem) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
return elem.getAttribute(message.attribute);
|
|
55
|
-
} else if (message.type === "eval") {
|
|
56
|
-
// TODO: chrome support
|
|
57
|
-
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
|
|
58
|
-
const result = window.eval(message.script); // eslint-disable-line no-eval
|
|
59
|
-
return result;
|
|
60
|
-
} else if (message.type === "hide") {
|
|
61
|
-
debug && console.log("[hide]", message.selectors);
|
|
62
|
-
return hideElementsUtil(message.selectors, message.method);
|
|
63
|
-
} else if (message.type === "undohide") {
|
|
64
|
-
const existingElement = getStyleElementUtil();
|
|
65
|
-
debug && console.log("[unhide]", !!existingElement);
|
|
66
|
-
if (existingElement) {
|
|
67
|
-
existingElement.remove();
|
|
68
|
-
}
|
|
69
|
-
return !!existingElement
|
|
70
|
-
} else if (message.type === "matches") {
|
|
71
|
-
const matched = matches(message.config);
|
|
72
|
-
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
|
|
73
|
-
return matched;
|
|
74
|
-
} else if (message.type === "executeAction") {
|
|
75
|
-
debug && console.log("[executeAction]", message);
|
|
76
|
-
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
return null;
|
|
80
|
-
}
|
package/lib/web/tab.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { waitFor } from "../cmps/base";
|
|
2
|
-
import { enableLogs } from "../config";
|
|
3
|
-
export default class TabActions {
|
|
4
|
-
constructor(tabId, frame, sendContentMessage, browser) {
|
|
5
|
-
this.frame = frame;
|
|
6
|
-
this.sendContentMessage = sendContentMessage;
|
|
7
|
-
this.browser = browser;
|
|
8
|
-
this.id = tabId;
|
|
9
|
-
}
|
|
10
|
-
async elementExists(selector, frameId = 0) {
|
|
11
|
-
return this.sendContentMessage(this.id, {
|
|
12
|
-
type: "elemExists",
|
|
13
|
-
selector
|
|
14
|
-
}, {
|
|
15
|
-
frameId
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
async clickElement(selector, frameId = 0) {
|
|
19
|
-
enableLogs && console.log(`click element ${selector} in tab ${this.id}`);
|
|
20
|
-
return this.sendContentMessage(this.id, {
|
|
21
|
-
type: "click",
|
|
22
|
-
selector
|
|
23
|
-
}, {
|
|
24
|
-
frameId
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
async clickElements(selector, frameId = 0) {
|
|
28
|
-
enableLogs && console.log(`click elements ${selector} in tab ${this.id}`);
|
|
29
|
-
return this.sendContentMessage(this.id, {
|
|
30
|
-
type: "click",
|
|
31
|
-
all: true,
|
|
32
|
-
selector
|
|
33
|
-
}, {
|
|
34
|
-
frameId
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
async elementsAreVisible(selector, check, frameId = 0) {
|
|
38
|
-
return this.sendContentMessage(this.id, {
|
|
39
|
-
type: "elemVisible",
|
|
40
|
-
selector,
|
|
41
|
-
check
|
|
42
|
-
}, {
|
|
43
|
-
frameId
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
async getAttribute(selector, attribute, frameId = 0) {
|
|
47
|
-
return this.sendContentMessage(this.id, {
|
|
48
|
-
type: "getAttribute",
|
|
49
|
-
selector,
|
|
50
|
-
attribute
|
|
51
|
-
}, { frameId });
|
|
52
|
-
}
|
|
53
|
-
async eval(script, frameId = 0) {
|
|
54
|
-
// console.log(`run ${script} in tab ${this.id}`);
|
|
55
|
-
return await this.sendContentMessage(this.id, {
|
|
56
|
-
type: "eval",
|
|
57
|
-
script
|
|
58
|
-
}, { frameId });
|
|
59
|
-
}
|
|
60
|
-
async waitForElement(selector, timeout, frameId = 0) {
|
|
61
|
-
const interval = 200;
|
|
62
|
-
const times = Math.ceil(timeout / interval);
|
|
63
|
-
return waitFor(() => this.elementExists(selector, frameId), times, interval);
|
|
64
|
-
}
|
|
65
|
-
async waitForThenClick(selector, timeout, frameId = 0) {
|
|
66
|
-
if (await this.waitForElement(selector, timeout, frameId)) {
|
|
67
|
-
return await this.clickElement(selector, frameId);
|
|
68
|
-
}
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
async hideElements(selectors, frameId = 0, method = 'display') {
|
|
72
|
-
enableLogs && console.log('Sending hide elements to', this.id, selectors);
|
|
73
|
-
return this.sendContentMessage(this.id, {
|
|
74
|
-
type: "hide",
|
|
75
|
-
selectors,
|
|
76
|
-
method,
|
|
77
|
-
}, { frameId });
|
|
78
|
-
}
|
|
79
|
-
async undoHideElements(frameId = 0) {
|
|
80
|
-
return this.sendContentMessage(this.id, {
|
|
81
|
-
type: "undohide",
|
|
82
|
-
}, { frameId });
|
|
83
|
-
}
|
|
84
|
-
async getBrowserTab() {
|
|
85
|
-
return this.browser.tabs.get(this.id);
|
|
86
|
-
}
|
|
87
|
-
async goto(url) {
|
|
88
|
-
return this.browser.tabs.update(this.id, { url });
|
|
89
|
-
}
|
|
90
|
-
wait(ms) {
|
|
91
|
-
enableLogs && console.log(`waiting for ${ms}ms in tab ${this.id}`);
|
|
92
|
-
return new Promise(resolve => {
|
|
93
|
-
setTimeout(() => {
|
|
94
|
-
enableLogs && console.log(`done waiting in tab ${this.id}`);
|
|
95
|
-
resolve(true);
|
|
96
|
-
}, ms);
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
matches(matcherConfig) {
|
|
100
|
-
return this.sendContentMessage(this.id, {
|
|
101
|
-
type: "matches",
|
|
102
|
-
config: matcherConfig
|
|
103
|
-
}, { frameId: 0 });
|
|
104
|
-
}
|
|
105
|
-
executeAction(config, param) {
|
|
106
|
-
return this.sendContentMessage(this.id, {
|
|
107
|
-
type: "executeAction",
|
|
108
|
-
config,
|
|
109
|
-
param
|
|
110
|
-
}, { frameId: 0 });
|
|
111
|
-
}
|
|
112
|
-
}
|
package/lib/web/tab.ts
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import { waitFor } from "../cmps/base";
|
|
2
|
-
import { enableLogs } from "../config";
|
|
3
|
-
import { HideMethod } from "../messages";
|
|
4
|
-
import { TabActor, MessageSender, Browser } from "../types";
|
|
5
|
-
|
|
6
|
-
export default class TabActions implements TabActor {
|
|
7
|
-
id: number;
|
|
8
|
-
|
|
9
|
-
constructor(
|
|
10
|
-
tabId: number,
|
|
11
|
-
public frame: any,
|
|
12
|
-
private sendContentMessage: MessageSender,
|
|
13
|
-
private browser: Browser
|
|
14
|
-
) {
|
|
15
|
-
this.id = tabId;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async elementExists(selector: string, frameId = 0) {
|
|
19
|
-
return this.sendContentMessage(
|
|
20
|
-
this.id,
|
|
21
|
-
{
|
|
22
|
-
type: "elemExists",
|
|
23
|
-
selector
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
frameId
|
|
27
|
-
}
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async clickElement(selector: string, frameId = 0) {
|
|
32
|
-
enableLogs && console.log(`click element ${selector} in tab ${this.id}`);
|
|
33
|
-
return this.sendContentMessage(
|
|
34
|
-
this.id,
|
|
35
|
-
{
|
|
36
|
-
type: "click",
|
|
37
|
-
selector
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
frameId
|
|
41
|
-
}
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async clickElements(selector: string, frameId = 0) {
|
|
46
|
-
enableLogs && console.log(`click elements ${selector} in tab ${this.id}`);
|
|
47
|
-
return this.sendContentMessage(
|
|
48
|
-
this.id,
|
|
49
|
-
{
|
|
50
|
-
type: "click",
|
|
51
|
-
all: true,
|
|
52
|
-
selector
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
frameId
|
|
56
|
-
}
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async elementsAreVisible(selector: string, check?: 'all' | 'any' | 'none', frameId = 0) {
|
|
61
|
-
return this.sendContentMessage(
|
|
62
|
-
this.id,
|
|
63
|
-
{
|
|
64
|
-
type: "elemVisible",
|
|
65
|
-
selector,
|
|
66
|
-
check
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
frameId
|
|
70
|
-
}
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async getAttribute(selector: string, attribute: string, frameId = 0) {
|
|
75
|
-
return this.sendContentMessage(
|
|
76
|
-
this.id,
|
|
77
|
-
{
|
|
78
|
-
type: "getAttribute",
|
|
79
|
-
selector,
|
|
80
|
-
attribute
|
|
81
|
-
},
|
|
82
|
-
{ frameId }
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async eval(script: string, frameId = 0) {
|
|
87
|
-
// console.log(`run ${script} in tab ${this.id}`);
|
|
88
|
-
return await this.sendContentMessage(
|
|
89
|
-
this.id,
|
|
90
|
-
{
|
|
91
|
-
type: "eval",
|
|
92
|
-
script
|
|
93
|
-
},
|
|
94
|
-
{ frameId }
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
async waitForElement(selector: string, timeout: number, frameId = 0) {
|
|
99
|
-
const interval = 200;
|
|
100
|
-
const times = Math.ceil(timeout / interval);
|
|
101
|
-
return waitFor(
|
|
102
|
-
() => this.elementExists(selector, frameId),
|
|
103
|
-
times,
|
|
104
|
-
interval
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
async waitForThenClick(selector: string, timeout: number, frameId = 0) {
|
|
109
|
-
if (await this.waitForElement(selector, timeout, frameId)) {
|
|
110
|
-
return await this.clickElement(selector, frameId);
|
|
111
|
-
}
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async hideElements(selectors: string[], frameId = 0, method: HideMethod = 'display') {
|
|
116
|
-
enableLogs && console.log('Sending hide elements to', this.id, selectors);
|
|
117
|
-
return this.sendContentMessage(
|
|
118
|
-
this.id,
|
|
119
|
-
{
|
|
120
|
-
type: "hide",
|
|
121
|
-
selectors,
|
|
122
|
-
method,
|
|
123
|
-
},
|
|
124
|
-
{ frameId }
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async undoHideElements(frameId = 0): Promise<boolean> {
|
|
129
|
-
return this.sendContentMessage(
|
|
130
|
-
this.id,
|
|
131
|
-
{
|
|
132
|
-
type: "undohide",
|
|
133
|
-
},
|
|
134
|
-
{ frameId }
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async getBrowserTab() {
|
|
139
|
-
return this.browser.tabs.get(this.id);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async goto(url: string) {
|
|
143
|
-
return this.browser.tabs.update(this.id, { url });
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
wait(ms: number): Promise<true> {
|
|
147
|
-
enableLogs && console.log(`waiting for ${ms}ms in tab ${this.id}`);
|
|
148
|
-
return new Promise(resolve => {
|
|
149
|
-
setTimeout(() => {
|
|
150
|
-
enableLogs && console.log(`done waiting in tab ${this.id}`);
|
|
151
|
-
resolve(true);
|
|
152
|
-
}, ms);
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
matches(matcherConfig: any) {
|
|
157
|
-
return this.sendContentMessage(
|
|
158
|
-
this.id,
|
|
159
|
-
{
|
|
160
|
-
type: "matches",
|
|
161
|
-
config: matcherConfig
|
|
162
|
-
},
|
|
163
|
-
{ frameId: 0 }
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
executeAction(config: any, param?: any): Promise<boolean> {
|
|
168
|
-
return this.sendContentMessage(
|
|
169
|
-
this.id,
|
|
170
|
-
{
|
|
171
|
-
type: "executeAction",
|
|
172
|
-
config,
|
|
173
|
-
param
|
|
174
|
-
},
|
|
175
|
-
{ frameId: 0 }
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
}
|
package/lib/web.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import Tab from './web/tab';
|
|
2
|
-
import handleContentMessage from './web/content';
|
|
3
|
-
import TabConsent from './tabwrapper';
|
|
4
|
-
import detectDialog from './detector';
|
|
5
|
-
import { rules, createAutoCMP } from './index';
|
|
6
|
-
import { ConsentOMaticCMP } from './consentomatic/index';
|
|
7
|
-
import prehideElements from './hider';
|
|
8
|
-
import { enableLogs } from './config';
|
|
9
|
-
export * from './index';
|
|
10
|
-
export { Tab, handleContentMessage, };
|
|
11
|
-
export default class AutoConsent {
|
|
12
|
-
constructor(browser, sendContentMessage) {
|
|
13
|
-
this.browser = browser;
|
|
14
|
-
this.sendContentMessage = sendContentMessage;
|
|
15
|
-
this.consentFrames = new Map();
|
|
16
|
-
this.tabCmps = new Map();
|
|
17
|
-
this.sendContentMessage = sendContentMessage;
|
|
18
|
-
this.rules = [...rules];
|
|
19
|
-
}
|
|
20
|
-
addCMP(config) {
|
|
21
|
-
this.rules.push(createAutoCMP(config));
|
|
22
|
-
}
|
|
23
|
-
disableCMPs(cmpNames) {
|
|
24
|
-
this.rules = this.rules.filter((cmp) => !cmpNames.includes(cmp.name));
|
|
25
|
-
}
|
|
26
|
-
addConsentomaticCMP(name, config) {
|
|
27
|
-
this.rules.push(new ConsentOMaticCMP(`com_${name}`, config));
|
|
28
|
-
}
|
|
29
|
-
createTab(tabId) {
|
|
30
|
-
return new Tab(tabId, this.consentFrames.get(tabId), this.sendContentMessage, this.browser);
|
|
31
|
-
}
|
|
32
|
-
async checkTab(tabId, prehide = true) {
|
|
33
|
-
enableLogs && console.log('checking tab', tabId, this.consentFrames, this.tabCmps);
|
|
34
|
-
const tab = this.createTab(tabId);
|
|
35
|
-
if (prehide) {
|
|
36
|
-
this.prehideElements(tab);
|
|
37
|
-
}
|
|
38
|
-
const consent = new TabConsent(tab, this.detectDialog(tab, 20));
|
|
39
|
-
this.tabCmps.set(tabId, consent);
|
|
40
|
-
// check tabs
|
|
41
|
-
consent.checked.then((rule) => {
|
|
42
|
-
if (this.consentFrames.has(tabId) && rule) {
|
|
43
|
-
const frame = this.consentFrames.get(tabId);
|
|
44
|
-
enableLogs && console.log(`Found ${rule.name} in a nested iframe ${frame.id} inside tab ${tabId}`);
|
|
45
|
-
if (frame.type === rule.name) {
|
|
46
|
-
consent.tab.frame = frame;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
enableLogs && console.log('finished checking tab', tabId, this.consentFrames, this.tabCmps);
|
|
50
|
-
// no CMP detected, undo hiding
|
|
51
|
-
if (!rule && prehide) {
|
|
52
|
-
enableLogs && console.log('no CMP detected, undo hiding');
|
|
53
|
-
tab.undoHideElements();
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
return this.tabCmps.get(tabId);
|
|
57
|
-
}
|
|
58
|
-
removeTab(tabId) {
|
|
59
|
-
this.tabCmps.delete(tabId);
|
|
60
|
-
this.consentFrames.delete(tabId);
|
|
61
|
-
}
|
|
62
|
-
onFrame({ tabId, url, frameId }) {
|
|
63
|
-
// ignore main frames
|
|
64
|
-
if (frameId === 0) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
try {
|
|
68
|
-
const frame = {
|
|
69
|
-
id: frameId,
|
|
70
|
-
url: url,
|
|
71
|
-
};
|
|
72
|
-
const tab = this.createTab(tabId);
|
|
73
|
-
const frameMatch = this.rules.findIndex(r => r.detectFrame(tab, frame));
|
|
74
|
-
if (frameMatch > -1) {
|
|
75
|
-
this.consentFrames.set(tabId, {
|
|
76
|
-
type: this.rules[frameMatch].name,
|
|
77
|
-
url,
|
|
78
|
-
id: frameId,
|
|
79
|
-
});
|
|
80
|
-
if (this.tabCmps.has(tabId)) {
|
|
81
|
-
this.tabCmps.get(tabId).tab.frame = this.consentFrames.get(tabId);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch (e) {
|
|
86
|
-
console.error(e);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
async detectDialog(tab, retries) {
|
|
90
|
-
return detectDialog(tab, retries, this.rules);
|
|
91
|
-
}
|
|
92
|
-
async prehideElements(tab) {
|
|
93
|
-
return prehideElements(tab, this.rules);
|
|
94
|
-
}
|
|
95
|
-
}
|
package/tests/runner.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { test, expect } from '@playwright/test';
|
|
4
|
-
import * as autoconsent from '../dist/autoconsent.puppet';
|
|
5
|
-
import * as extraRules from '../rules/rules.json';
|
|
6
|
-
|
|
7
|
-
const consentomatic = extraRules.consentomatic;
|
|
8
|
-
const rules = [
|
|
9
|
-
...autoconsent.rules,
|
|
10
|
-
...Object.keys(consentomatic).map(name => new autoconsent.ConsentOMaticCMP(`com_${name}`, consentomatic[name])),
|
|
11
|
-
...extraRules.autoconsent.map(spec => autoconsent.createAutoCMP(spec)),
|
|
12
|
-
];
|
|
13
|
-
const screenshotDir = `./screenshots`;
|
|
14
|
-
const testRegion = (process.env.REGION || 'NA').trim();
|
|
15
|
-
|
|
16
|
-
async function ensureScreenshotDir() {
|
|
17
|
-
try {
|
|
18
|
-
await fs.stat(screenshotDir);
|
|
19
|
-
} catch(e) {
|
|
20
|
-
await fs.mkdir(screenshotDir);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
type TestOptions = {
|
|
25
|
-
testOptOut: boolean;
|
|
26
|
-
testSelfTest: boolean;
|
|
27
|
-
skipRegions?: string[];
|
|
28
|
-
}
|
|
29
|
-
const defaultOptions: TestOptions = {
|
|
30
|
-
testOptOut: true,
|
|
31
|
-
testSelfTest: true,
|
|
32
|
-
skipRegions: [],
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function generateTest(url: string, expectedCmp: string, options: TestOptions = { testOptOut: true, testSelfTest: true }) {
|
|
36
|
-
test(`${url.split('://')[1]} .${testRegion}`, async ({ page }) => {
|
|
37
|
-
if (options.skipRegions && options.skipRegions.indexOf(testRegion) !== -1) {
|
|
38
|
-
test.skip();
|
|
39
|
-
}
|
|
40
|
-
await page.goto(url, { waitUntil: 'commit' });
|
|
41
|
-
|
|
42
|
-
const tab = autoconsent.attachToPage(page, url, rules, 20, true);
|
|
43
|
-
await tab.checked;
|
|
44
|
-
expect(tab.getCMPName()).toBe(expectedCmp);
|
|
45
|
-
expect(await tab.isPopupOpen(50, 100)).toBeTruthy();
|
|
46
|
-
if (options.testOptOut) {
|
|
47
|
-
expect(await tab.doOptOut()).toBeTruthy();
|
|
48
|
-
}
|
|
49
|
-
if (options.testSelfTest) {
|
|
50
|
-
expect(await tab.testOptOutWorked()).toBeTruthy();
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export default function generateCMPTests(cmp: string, sites: string[], options: Partial<TestOptions> = {}) {
|
|
56
|
-
test.describe(cmp, () => {
|
|
57
|
-
sites.forEach((url) => {
|
|
58
|
-
generateTest(url, cmp, Object.assign({}, defaultOptions, options));
|
|
59
|
-
});
|
|
60
|
-
})
|
|
61
|
-
}
|