@duckduckgo/autoconsent 1.0.2
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 +12 -0
- package/Dockerfile +9 -0
- package/Jenkinsfile +50 -0
- package/LICENSE +373 -0
- package/cosmetics/rules.json +110 -0
- package/dist/autoconsent.cjs.js +1316 -0
- package/dist/autoconsent.esm.js +1308 -0
- package/dist/autoconsent.puppet.js +980 -0
- package/lib/cmps/all.js +17 -0
- package/lib/cmps/all.ts +21 -0
- package/lib/cmps/base.js +170 -0
- package/lib/cmps/base.ts +199 -0
- package/lib/cmps/consentmanager.js +31 -0
- package/lib/cmps/consentmanager.ts +39 -0
- package/lib/cmps/cookiebot.js +73 -0
- package/lib/cmps/cookiebot.ts +81 -0
- package/lib/cmps/evidon.js +26 -0
- package/lib/cmps/evidon.ts +32 -0
- package/lib/cmps/sourcepoint.js +82 -0
- package/lib/cmps/sourcepoint.ts +95 -0
- package/lib/cmps/trustarc.js +106 -0
- package/lib/cmps/trustarc.ts +147 -0
- package/lib/consentomatic/index.js +52 -0
- package/lib/consentomatic/index.ts +86 -0
- package/lib/detector.js +29 -0
- package/lib/detector.ts +30 -0
- package/lib/hider.js +13 -0
- package/lib/hider.ts +16 -0
- package/lib/index.js +4 -0
- package/lib/index.ts +6 -0
- package/lib/messages.d.ts +58 -0
- package/lib/node.js +30 -0
- package/lib/node.ts +38 -0
- package/lib/puppet/tab.js +114 -0
- package/lib/puppet/tab.ts +136 -0
- package/lib/rules.d.ts +80 -0
- package/lib/tabwrapper.js +61 -0
- package/lib/tabwrapper.ts +68 -0
- package/lib/types.d.ts +61 -0
- package/lib/web/consentomatic/index.js +188 -0
- package/lib/web/consentomatic/index.ts +249 -0
- package/lib/web/consentomatic/tools.js +177 -0
- package/lib/web/consentomatic/tools.ts +198 -0
- package/lib/web/content.js +91 -0
- package/lib/web/content.ts +83 -0
- package/lib/web/tab.js +106 -0
- package/lib/web/tab.ts +171 -0
- package/lib/web.js +90 -0
- package/lib/web.ts +109 -0
- package/package.json +41 -0
- package/playwright.config.ts +31 -0
- package/readme.md +151 -0
- package/rollup.config.js +54 -0
- package/rules/autoconsent/asus.json +7 -0
- package/rules/autoconsent/cc-banner.json +9 -0
- package/rules/autoconsent/cookie-law-info.json +14 -0
- package/rules/autoconsent/cookie-notice.json +9 -0
- package/rules/autoconsent/cookieconsent.json +9 -0
- package/rules/autoconsent/drupal.json +7 -0
- package/rules/autoconsent/eu-cookie-compliance.json +14 -0
- package/rules/autoconsent/fundingchoices.json +12 -0
- package/rules/autoconsent/hubspot.json +7 -0
- package/rules/autoconsent/klaro.json +10 -0
- package/rules/autoconsent/notice-cookie.json +9 -0
- package/rules/autoconsent/onetrust.json +24 -0
- package/rules/autoconsent/osano.json +11 -0
- package/rules/autoconsent/quantcast.json +14 -0
- package/rules/autoconsent/tealium.json +19 -0
- package/rules/autoconsent/testcmp.json +12 -0
- package/rules/build.js +63 -0
- package/rules/rules.json +3030 -0
- package/tests/asus.spec.ts +5 -0
- package/tests/ccbanner.spec.ts +11 -0
- package/tests/consentmanager.spec.ts +10 -0
- package/tests/cookiebot.spec.ts +9 -0
- package/tests/cookieconsent.spec.ts +8 -0
- package/tests/cookielawinfo.spec.ts +9 -0
- package/tests/cookienotice.spec.ts +6 -0
- package/tests/didomi.spec.ts +9 -0
- package/tests/eu-cookie-compliance-banner.spec.ts +7 -0
- package/tests/evidon.spec.ts +6 -0
- package/tests/fundingchoices.spec.ts +10 -0
- package/tests/hubspot.spec.ts +6 -0
- package/tests/klaro.spec.ts +5 -0
- package/tests/notice-cookie.spec.ts +7 -0
- package/tests/oil.spec.ts +10 -0
- package/tests/onetrust.spec.ts +15 -0
- package/tests/optanon.spec.ts +10 -0
- package/tests/osano.spec.ts +5 -0
- package/tests/quantcast.spec.ts +16 -0
- package/tests/runner.ts +61 -0
- package/tests/sourcepoint.spec.ts +17 -0
- package/tests/springer.spec.ts +11 -0
- package/tests/tealium.spec.ts +6 -0
- package/tests/testcmp.spec.ts +5 -0
- package/tests/trustarc.spec.ts +13 -0
- package/tests/wordpressgdpr.spec.ts +9 -0
- package/tsconfig.json +14 -0
- package/update_version.js +8 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This code is in most parts copied from https://github.com/cavi-au/Consent-O-Matic/blob/master/Extension/Tools.js
|
|
3
|
+
* which is licened under the MIT.
|
|
4
|
+
*/
|
|
5
|
+
export default class Tools {
|
|
6
|
+
static base: HTMLElement = null;
|
|
7
|
+
|
|
8
|
+
static setBase(base: HTMLElement) {
|
|
9
|
+
Tools.base = base;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static findElement(options: any, parent: any = null, multiple = false): HTMLElement[] | HTMLElement {
|
|
13
|
+
let possibleTargets = null;
|
|
14
|
+
|
|
15
|
+
if (parent != null) {
|
|
16
|
+
possibleTargets = Array.from(parent.querySelectorAll(options.selector));
|
|
17
|
+
} else {
|
|
18
|
+
if (Tools.base != null) {
|
|
19
|
+
possibleTargets = Array.from(
|
|
20
|
+
Tools.base.querySelectorAll(options.selector)
|
|
21
|
+
);
|
|
22
|
+
} else {
|
|
23
|
+
possibleTargets = Array.from(
|
|
24
|
+
document.querySelectorAll(options.selector)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (options.textFilter != null) {
|
|
30
|
+
possibleTargets = possibleTargets.filter(possibleTarget => {
|
|
31
|
+
let textContent = possibleTarget.textContent.toLowerCase();
|
|
32
|
+
|
|
33
|
+
if (Array.isArray(options.textFilter)) {
|
|
34
|
+
let foundText = false;
|
|
35
|
+
|
|
36
|
+
for (let text of options.textFilter) {
|
|
37
|
+
if (textContent.indexOf(text.toLowerCase()) !== -1) {
|
|
38
|
+
foundText = true;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return foundText;
|
|
44
|
+
} else if (options.textFilter != null) {
|
|
45
|
+
return textContent.indexOf(options.textFilter.toLowerCase()) !== -1;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (options.styleFilters != null) {
|
|
51
|
+
possibleTargets = possibleTargets.filter(possibleTarget => {
|
|
52
|
+
let styles = window.getComputedStyle(possibleTarget);
|
|
53
|
+
|
|
54
|
+
let keep = true;
|
|
55
|
+
|
|
56
|
+
for (let styleFilter of options.styleFilters) {
|
|
57
|
+
let option = styles[styleFilter.option];
|
|
58
|
+
|
|
59
|
+
if (styleFilter.negated) {
|
|
60
|
+
keep = keep && option !== styleFilter.value;
|
|
61
|
+
} else {
|
|
62
|
+
keep = keep && option === styleFilter.value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return keep;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (options.displayFilter != null) {
|
|
71
|
+
possibleTargets = possibleTargets.filter(possibleTarget => {
|
|
72
|
+
if (options.displayFilter) {
|
|
73
|
+
//We should be displayed
|
|
74
|
+
return possibleTarget.offsetHeight !== 0;
|
|
75
|
+
} else {
|
|
76
|
+
//We should not be displayed
|
|
77
|
+
return possibleTarget.offsetHeight === 0;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (options.iframeFilter != null) {
|
|
83
|
+
possibleTargets = possibleTargets.filter(possibleTarget => {
|
|
84
|
+
if (options.iframeFilter) {
|
|
85
|
+
//We should be inside an iframe
|
|
86
|
+
return window.location !== window.parent.location;
|
|
87
|
+
} else {
|
|
88
|
+
//We should not be inside an iframe
|
|
89
|
+
return window.location === window.parent.location;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (options.childFilter != null) {
|
|
95
|
+
possibleTargets = possibleTargets.filter(possibleTarget => {
|
|
96
|
+
let oldBase = Tools.base;
|
|
97
|
+
Tools.setBase(possibleTarget);
|
|
98
|
+
let childResults = Tools.find(options.childFilter);
|
|
99
|
+
Tools.setBase(oldBase);
|
|
100
|
+
return childResults.target != null;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (multiple) {
|
|
105
|
+
return possibleTargets;
|
|
106
|
+
} else {
|
|
107
|
+
if (possibleTargets.length > 1) {
|
|
108
|
+
console.warn(
|
|
109
|
+
"Multiple possible targets: ",
|
|
110
|
+
possibleTargets,
|
|
111
|
+
options,
|
|
112
|
+
parent
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return possibleTargets[0];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
static find(options: any, multiple = false) {
|
|
121
|
+
let results: any[] = [];
|
|
122
|
+
if (options.parent != null) {
|
|
123
|
+
let parent = Tools.findElement(options.parent, null, multiple);
|
|
124
|
+
if (parent != null) {
|
|
125
|
+
if (parent instanceof Array) {
|
|
126
|
+
parent.forEach(p => {
|
|
127
|
+
let targets = Tools.findElement(options.target, p, multiple);
|
|
128
|
+
if (targets instanceof Array) {
|
|
129
|
+
targets.forEach(target => {
|
|
130
|
+
results.push({
|
|
131
|
+
parent: p,
|
|
132
|
+
target: target
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
} else {
|
|
136
|
+
results.push({
|
|
137
|
+
parent: p,
|
|
138
|
+
target: targets
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
return results;
|
|
144
|
+
} else {
|
|
145
|
+
let targets = Tools.findElement(options.target, parent, multiple);
|
|
146
|
+
if (targets instanceof Array) {
|
|
147
|
+
targets.forEach(target => {
|
|
148
|
+
results.push({
|
|
149
|
+
parent: parent,
|
|
150
|
+
target: target
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
} else {
|
|
154
|
+
results.push({
|
|
155
|
+
parent: parent,
|
|
156
|
+
target: targets
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
let targets = Tools.findElement(options.target, null, multiple);
|
|
163
|
+
if (targets instanceof Array) {
|
|
164
|
+
targets.forEach(target => {
|
|
165
|
+
results.push({
|
|
166
|
+
parent: null,
|
|
167
|
+
target: target
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
} else {
|
|
171
|
+
results.push({
|
|
172
|
+
parent: null,
|
|
173
|
+
target: targets
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (results.length === 0) {
|
|
179
|
+
results.push({
|
|
180
|
+
parent: null,
|
|
181
|
+
target: null
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (multiple) {
|
|
186
|
+
return results;
|
|
187
|
+
} else {
|
|
188
|
+
if (results.length !== 1) {
|
|
189
|
+
console.warn(
|
|
190
|
+
"Multiple results found, even though multiple false",
|
|
191
|
+
results
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return results[0];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { matches, executeAction } from "./consentomatic/index";
|
|
2
|
+
let actionQueue = Promise.resolve(null);
|
|
3
|
+
const styleOverrideElementId = "autoconsent-css-rules";
|
|
4
|
+
const styleSelector = `style#${styleOverrideElementId}`;
|
|
5
|
+
export default function handleMessage(message, debug = false) {
|
|
6
|
+
if (message.type === "click") {
|
|
7
|
+
const elem = document.querySelectorAll(message.selector);
|
|
8
|
+
debug && console.log("[click]", message.selector, elem);
|
|
9
|
+
if (elem.length > 0) {
|
|
10
|
+
if (message.all === true) {
|
|
11
|
+
elem.forEach(e => e.click());
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
elem[0].click();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return elem.length > 0;
|
|
18
|
+
}
|
|
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
|
+
}
|
|
24
|
+
else if (message.type === "elemVisible") {
|
|
25
|
+
const elem = document.querySelectorAll(message.selector);
|
|
26
|
+
const results = new Array(elem.length);
|
|
27
|
+
elem.forEach((e, i) => {
|
|
28
|
+
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none" || e.style?.display !== "none";
|
|
29
|
+
});
|
|
30
|
+
if (results.length === 0) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
else if (message.check === "any") {
|
|
34
|
+
return results.some(r => r);
|
|
35
|
+
}
|
|
36
|
+
else if (message.check === "none") {
|
|
37
|
+
return results.every(r => !r);
|
|
38
|
+
}
|
|
39
|
+
// all
|
|
40
|
+
return results.every(r => r);
|
|
41
|
+
}
|
|
42
|
+
else if (message.type === "getAttribute") {
|
|
43
|
+
const elem = document.querySelector(message.selector);
|
|
44
|
+
if (!elem) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return elem.getAttribute(message.attribute);
|
|
48
|
+
}
|
|
49
|
+
else if (message.type === "eval") {
|
|
50
|
+
// TODO: chrome support
|
|
51
|
+
const result = window.eval(message.script); // eslint-disable-line no-eval
|
|
52
|
+
debug && console.log("[eval]", message.script, result);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
else if (message.type === "hide") {
|
|
56
|
+
const parent = document.head ||
|
|
57
|
+
document.getElementsByTagName("head")[0] ||
|
|
58
|
+
document.documentElement;
|
|
59
|
+
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
|
|
60
|
+
const existingElement = document.querySelector(styleSelector);
|
|
61
|
+
debug && console.log("[hide]", message.selectors, !!existingElement);
|
|
62
|
+
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
63
|
+
existingElement.innerText += rule;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const css = document.createElement("style");
|
|
67
|
+
css.type = "text/css";
|
|
68
|
+
css.id = styleOverrideElementId;
|
|
69
|
+
css.appendChild(document.createTextNode(rule));
|
|
70
|
+
parent.appendChild(css);
|
|
71
|
+
}
|
|
72
|
+
return message.selectors.length > 0;
|
|
73
|
+
}
|
|
74
|
+
else if (message.type === "undohide") {
|
|
75
|
+
const existingElement = document.querySelector(styleSelector);
|
|
76
|
+
debug && console.log("[unhide]", !!existingElement);
|
|
77
|
+
if (existingElement) {
|
|
78
|
+
existingElement.remove();
|
|
79
|
+
}
|
|
80
|
+
return !!existingElement;
|
|
81
|
+
}
|
|
82
|
+
else if (message.type === "matches") {
|
|
83
|
+
const matched = matches(message.config);
|
|
84
|
+
return matched;
|
|
85
|
+
}
|
|
86
|
+
else if (message.type === "executeAction") {
|
|
87
|
+
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { matches, executeAction } from "./consentomatic/index";
|
|
2
|
+
import { ContentScriptMessage } from "../messages";
|
|
3
|
+
|
|
4
|
+
let actionQueue = Promise.resolve(null);
|
|
5
|
+
const styleOverrideElementId = "autoconsent-css-rules";
|
|
6
|
+
const styleSelector = `style#${styleOverrideElementId}`;
|
|
7
|
+
|
|
8
|
+
export default function handleMessage(message: ContentScriptMessage, debug = false) {
|
|
9
|
+
if (message.type === "click") {
|
|
10
|
+
const elem = document.querySelectorAll<HTMLElement>(message.selector);
|
|
11
|
+
debug && console.log("[click]", message.selector, elem);
|
|
12
|
+
if (elem.length > 0) {
|
|
13
|
+
if (message.all === true) {
|
|
14
|
+
elem.forEach(e => e.click());
|
|
15
|
+
} else {
|
|
16
|
+
elem[0].click();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return elem.length > 0;
|
|
20
|
+
} else if (message.type === "elemExists") {
|
|
21
|
+
const exists = document.querySelector(message.selector) !== null;
|
|
22
|
+
debug && console.log("[exists?]", message.selector, exists);
|
|
23
|
+
return exists;
|
|
24
|
+
} else if (message.type === "elemVisible") {
|
|
25
|
+
const elem = document.querySelectorAll<HTMLElement>(message.selector);
|
|
26
|
+
const results = new Array(elem.length);
|
|
27
|
+
elem.forEach((e, i) => {
|
|
28
|
+
results[i] = e.offsetParent !== null || window.getComputedStyle(e).display !== "none" || e.style?.display !== "none";
|
|
29
|
+
});
|
|
30
|
+
if (results.length === 0) {
|
|
31
|
+
return false;
|
|
32
|
+
} else if (message.check === "any") {
|
|
33
|
+
return results.some(r => r);
|
|
34
|
+
} else if (message.check === "none") {
|
|
35
|
+
return results.every(r => !r);
|
|
36
|
+
}
|
|
37
|
+
// all
|
|
38
|
+
return results.every(r => r);
|
|
39
|
+
} else if (message.type === "getAttribute") {
|
|
40
|
+
const elem = document.querySelector(message.selector);
|
|
41
|
+
if (!elem) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return elem.getAttribute(message.attribute);
|
|
45
|
+
} else if (message.type === "eval") {
|
|
46
|
+
// TODO: chrome support
|
|
47
|
+
const result = window.eval(message.script); // eslint-disable-line no-eval
|
|
48
|
+
debug && console.log("[eval]", message.script, result);
|
|
49
|
+
return result;
|
|
50
|
+
} else if (message.type === "hide") {
|
|
51
|
+
const parent =
|
|
52
|
+
document.head ||
|
|
53
|
+
document.getElementsByTagName("head")[0] ||
|
|
54
|
+
document.documentElement;
|
|
55
|
+
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
|
|
56
|
+
const existingElement = document.querySelector(styleSelector);
|
|
57
|
+
debug && console.log("[hide]", message.selectors, !!existingElement);
|
|
58
|
+
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
59
|
+
existingElement.innerText += rule;
|
|
60
|
+
} else {
|
|
61
|
+
const css = document.createElement("style");
|
|
62
|
+
css.type = "text/css";
|
|
63
|
+
css.id = styleOverrideElementId;
|
|
64
|
+
css.appendChild(document.createTextNode(rule));
|
|
65
|
+
parent.appendChild(css);
|
|
66
|
+
}
|
|
67
|
+
return message.selectors.length > 0;
|
|
68
|
+
} else if (message.type === "undohide") {
|
|
69
|
+
const existingElement = document.querySelector(styleSelector);
|
|
70
|
+
debug && console.log("[unhide]", !!existingElement);
|
|
71
|
+
if (existingElement) {
|
|
72
|
+
existingElement.remove();
|
|
73
|
+
}
|
|
74
|
+
return !!existingElement
|
|
75
|
+
} else if (message.type === "matches") {
|
|
76
|
+
const matched = matches(message.config);
|
|
77
|
+
return matched;
|
|
78
|
+
} else if (message.type === "executeAction") {
|
|
79
|
+
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
package/lib/web/tab.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { waitFor } from "../cmps/base";
|
|
2
|
+
export default class TabActions {
|
|
3
|
+
constructor(tabId, frame, sendContentMessage, browser) {
|
|
4
|
+
this.frame = frame;
|
|
5
|
+
this.sendContentMessage = sendContentMessage;
|
|
6
|
+
this.browser = browser;
|
|
7
|
+
this.id = tabId;
|
|
8
|
+
}
|
|
9
|
+
async elementExists(selector, frameId = 0) {
|
|
10
|
+
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
|
|
11
|
+
return this.sendContentMessage(this.id, {
|
|
12
|
+
type: "elemExists",
|
|
13
|
+
selector
|
|
14
|
+
}, {
|
|
15
|
+
frameId
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async clickElement(selector, frameId = 0) {
|
|
19
|
+
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
|
+
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) {
|
|
72
|
+
return this.sendContentMessage(this.id, {
|
|
73
|
+
type: "hide",
|
|
74
|
+
selectors
|
|
75
|
+
}, { frameId });
|
|
76
|
+
}
|
|
77
|
+
async undoHideElements(frameId = 0) {
|
|
78
|
+
return this.sendContentMessage(this.id, {
|
|
79
|
+
type: "undohide",
|
|
80
|
+
}, { frameId });
|
|
81
|
+
}
|
|
82
|
+
async getBrowserTab() {
|
|
83
|
+
return this.browser.tabs.get(this.id);
|
|
84
|
+
}
|
|
85
|
+
async goto(url) {
|
|
86
|
+
return this.browser.tabs.update(this.id, { url });
|
|
87
|
+
}
|
|
88
|
+
wait(ms) {
|
|
89
|
+
return new Promise(resolve => {
|
|
90
|
+
setTimeout(() => resolve(true), ms);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
matches(matcherConfig) {
|
|
94
|
+
return this.sendContentMessage(this.id, {
|
|
95
|
+
type: "matches",
|
|
96
|
+
config: matcherConfig
|
|
97
|
+
}, { frameId: 0 });
|
|
98
|
+
}
|
|
99
|
+
executeAction(config, param) {
|
|
100
|
+
return this.sendContentMessage(this.id, {
|
|
101
|
+
type: "executeAction",
|
|
102
|
+
config,
|
|
103
|
+
param
|
|
104
|
+
}, { frameId: 0 });
|
|
105
|
+
}
|
|
106
|
+
}
|
package/lib/web/tab.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { waitFor } from "../cmps/base";
|
|
2
|
+
import { TabActor, MessageSender, Browser } from "../types";
|
|
3
|
+
|
|
4
|
+
export default class TabActions implements TabActor {
|
|
5
|
+
id: number;
|
|
6
|
+
|
|
7
|
+
constructor(
|
|
8
|
+
tabId: number,
|
|
9
|
+
public frame: any,
|
|
10
|
+
private sendContentMessage: MessageSender,
|
|
11
|
+
private browser: Browser
|
|
12
|
+
) {
|
|
13
|
+
this.id = tabId;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async elementExists(selector: string, frameId = 0) {
|
|
17
|
+
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
|
|
18
|
+
return this.sendContentMessage(
|
|
19
|
+
this.id,
|
|
20
|
+
{
|
|
21
|
+
type: "elemExists",
|
|
22
|
+
selector
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
frameId
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async clickElement(selector: string, frameId = 0) {
|
|
31
|
+
console.log(`click element ${selector} in tab ${this.id}`);
|
|
32
|
+
return this.sendContentMessage(
|
|
33
|
+
this.id,
|
|
34
|
+
{
|
|
35
|
+
type: "click",
|
|
36
|
+
selector
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
frameId
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async clickElements(selector: string, frameId = 0) {
|
|
45
|
+
console.log(`click elements ${selector} in tab ${this.id}`);
|
|
46
|
+
return this.sendContentMessage(
|
|
47
|
+
this.id,
|
|
48
|
+
{
|
|
49
|
+
type: "click",
|
|
50
|
+
all: true,
|
|
51
|
+
selector
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
frameId
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async elementsAreVisible(selector: string, check?: 'all' | 'any' | 'none', frameId = 0) {
|
|
60
|
+
return this.sendContentMessage(
|
|
61
|
+
this.id,
|
|
62
|
+
{
|
|
63
|
+
type: "elemVisible",
|
|
64
|
+
selector,
|
|
65
|
+
check
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
frameId
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async getAttribute(selector: string, attribute: string, frameId = 0) {
|
|
74
|
+
return this.sendContentMessage(
|
|
75
|
+
this.id,
|
|
76
|
+
{
|
|
77
|
+
type: "getAttribute",
|
|
78
|
+
selector,
|
|
79
|
+
attribute
|
|
80
|
+
},
|
|
81
|
+
{ frameId }
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async eval(script: string, frameId = 0) {
|
|
86
|
+
// console.log(`run ${script} in tab ${this.id}`);
|
|
87
|
+
return await this.sendContentMessage(
|
|
88
|
+
this.id,
|
|
89
|
+
{
|
|
90
|
+
type: "eval",
|
|
91
|
+
script
|
|
92
|
+
},
|
|
93
|
+
{ frameId }
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async waitForElement(selector: string, timeout: number, frameId = 0) {
|
|
98
|
+
const interval = 200;
|
|
99
|
+
const times = Math.ceil(timeout / interval);
|
|
100
|
+
return waitFor(
|
|
101
|
+
() => this.elementExists(selector, frameId),
|
|
102
|
+
times,
|
|
103
|
+
interval
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async waitForThenClick(selector: string, timeout: number, frameId = 0) {
|
|
108
|
+
if (await this.waitForElement(selector, timeout, frameId)) {
|
|
109
|
+
return await this.clickElement(selector, frameId);
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async hideElements(selectors: string[], frameId = 0) {
|
|
115
|
+
return this.sendContentMessage(
|
|
116
|
+
this.id,
|
|
117
|
+
{
|
|
118
|
+
type: "hide",
|
|
119
|
+
selectors
|
|
120
|
+
},
|
|
121
|
+
{ frameId }
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async undoHideElements(frameId = 0): Promise<boolean> {
|
|
126
|
+
return this.sendContentMessage(
|
|
127
|
+
this.id,
|
|
128
|
+
{
|
|
129
|
+
type: "undohide",
|
|
130
|
+
},
|
|
131
|
+
{ frameId }
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async getBrowserTab() {
|
|
136
|
+
return this.browser.tabs.get(this.id);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async goto(url: string) {
|
|
140
|
+
return this.browser.tabs.update(this.id, { url });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
wait(ms: number): Promise<true> {
|
|
144
|
+
return new Promise(resolve => {
|
|
145
|
+
setTimeout(() => resolve(true), ms);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
matches(matcherConfig: any) {
|
|
150
|
+
return this.sendContentMessage(
|
|
151
|
+
this.id,
|
|
152
|
+
{
|
|
153
|
+
type: "matches",
|
|
154
|
+
config: matcherConfig
|
|
155
|
+
},
|
|
156
|
+
{ frameId: 0 }
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
executeAction(config: any, param?: any): Promise<boolean> {
|
|
161
|
+
return this.sendContentMessage(
|
|
162
|
+
this.id,
|
|
163
|
+
{
|
|
164
|
+
type: "executeAction",
|
|
165
|
+
config,
|
|
166
|
+
param
|
|
167
|
+
},
|
|
168
|
+
{ frameId: 0 }
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|