Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: test/browser/elemHideEmulation.js

Issue 30025555: Issue 6820 - Move tests to mocha (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Created March 7, 2019, 1:14 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/browser/_bootstrap.js ('k') | test/browser/snippets.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH 3 * Copyright (C) 2006-present eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 /* global assert */
19
18 "use strict"; 20 "use strict";
19 21
20 const {ElemHideEmulation, setTestMode, 22 const {ElemHideEmulation, setTestMode,
21 getTestInfo} = require("../../lib/content/elemHideEmulation"); 23 getTestInfo} = require("../../lib/content/elemHideEmulation");
22 24
23 const REFRESH_INTERVAL = 200; 25 describe("Element Hiding Emulation", () =>
24
25 let testDocument = null;
26
27 exports.setUp = function(callback)
28 { 26 {
29 setTestMode(); 27 const REFRESH_INTERVAL = 200;
30 28
31 let iframe = document.createElement("iframe"); 29 let testDocument = null;
32 document.body.appendChild(iframe); 30
33 testDocument = iframe.contentDocument; 31 beforeEach(() =>
34 32 {
35 callback(); 33 setTestMode();
36 }; 34
37 35 let iframe = document.createElement("iframe");
38 exports.tearDown = function(callback) 36 document.body.appendChild(iframe);
39 { 37 testDocument = iframe.contentDocument;
40 let iframe = testDocument.defaultView.frameElement;
41 iframe.parentNode.removeChild(iframe);
42 testDocument = null;
43
44 callback();
45 };
46
47 function timeout(delay)
48 {
49 return new Promise((resolve, reject) =>
50 {
51 window.setTimeout(resolve, delay);
52 }); 38 });
53 } 39
54 40 afterEach(() =>
55 function unexpectedError(test, error) 41 {
56 { 42 let iframe = testDocument.defaultView.frameElement;
57 console.error(error); 43 iframe.parentNode.removeChild(iframe);
58 test.ok(false, "Unexpected error: " + error); 44 testDocument = null;
59 } 45 });
60 46
61 function expectHidden(test, element, id) 47 function timeout(delay)
62 { 48 {
63 let withId = ""; 49 return new Promise((resolve, reject) =>
64 if (typeof id != "undefined") 50 {
65 withId = ` with ID '${id}'`; 51 window.setTimeout(resolve, delay);
66 52 });
67 test.equal(
68 window.getComputedStyle(element).display, "none",
69 `The element${withId}'s display property should be set to 'none'`);
70 }
71
72 function expectVisible(test, element, id)
73 {
74 let withId = "";
75 if (typeof id != "undefined")
76 withId = ` with ID '${id}'`;
77
78 test.notEqual(
79 window.getComputedStyle(element).display, "none",
80 `The element${withId}'s display property should not be set to 'none'`);
81 }
82
83 function expectProcessed(test, element, id = null)
84 {
85 let withId = "";
86 if (id)
87 withId = ` with ID '${id}'`;
88
89 test.ok(
90 getTestInfo().lastProcessedElements.has(element),
91 `The element${withId} should have been processed`);
92 }
93
94 function expectNotProcessed(test, element, id = null)
95 {
96 let withId = "";
97 if (id)
98 withId = ` with ID '${id}'`;
99
100 test.ok(
101 !getTestInfo().lastProcessedElements.has(element),
102 `The element${withId} should not have been processed`);
103 }
104
105 function findUniqueId()
106 {
107 let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000);
108 if (!testDocument.getElementById(id))
109 return id;
110 return findUniqueId();
111 }
112
113 function insertStyleRule(rule)
114 {
115 let styleElement;
116 let styleElements = testDocument.head.getElementsByTagName("style");
117 if (styleElements.length)
118 styleElement = styleElements[0];
119 else
120 {
121 styleElement = testDocument.createElement("style");
122 testDocument.head.appendChild(styleElement);
123 } 53 }
124 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length); 54
125 } 55 function unexpectedError(error)
126 56 {
127 function createElement(parent, type = "div", id = findUniqueId(), 57 console.error(error);
128 innerText = null) 58 assert.ok(false, "Unexpected error: " + error);
129 {
130 let element = testDocument.createElement(type);
131 element.id = id;
132 if (!parent)
133 testDocument.body.appendChild(element);
134 else
135 parent.appendChild(element);
136 if (innerText)
137 element.innerText = innerText;
138 return element;
139 }
140
141 // Insert a <div> with a unique id and a CSS rule
142 // for the the selector matching the id.
143 function createElementWithStyle(styleBlock, parent)
144 {
145 let element = createElement(parent);
146 insertStyleRule("#" + element.id + " " + styleBlock);
147 return element;
148 }
149
150 // Create a new ElemHideEmulation instance with @selectors.
151 async function applyElemHideEmulation(test, selectors)
152 {
153 await Promise.resolve();
154
155 try
156 {
157 let elemHideEmulation = new ElemHideEmulation(
158 elems =>
159 {
160 for (let elem of elems)
161 elem.style.display = "none";
162 }
163 );
164
165 elemHideEmulation.document = testDocument;
166 elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2;
167 elemHideEmulation.apply(selectors.map(
168 selector => ({selector, text: selector})
169 ));
170
171 return elemHideEmulation;
172 } 59 }
173 catch (error) 60
174 { 61 function expectHidden(element, id)
175 unexpectedError(test, error); 62 {
63 let withId = "";
64 if (typeof id != "undefined")
65 withId = ` with ID '${id}'`;
66
67 assert.equal(
68 window.getComputedStyle(element).display, "none",
69 `The element${withId}'s display property should be set to 'none'`);
176 } 70 }
177 } 71
178 72 function expectVisible(element, id)
179 exports.testVerbatimPropertySelector = async function(test) 73 {
180 { 74 let withId = "";
181 let toHide = createElementWithStyle("{background-color: #000}"); 75 if (typeof id != "undefined")
182 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"]; 76 withId = ` with ID '${id}'`;
183 77
184 if (await applyElemHideEmulation(test, selectors)) 78 assert.notEqual(
185 expectHidden(test, toHide); 79 window.getComputedStyle(element).display, "none",
186 80 `The element${withId}'s display property should not be set to 'none'`);
187 test.done();
188 };
189
190 exports.testVerbatimPropertySelectorWithPrefix = async function(test)
191 {
192 let parent = createElementWithStyle("{background-color: #000}");
193 let toHide = createElementWithStyle("{background-color: #000}", parent);
194
195 let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"];
196
197 if (await applyElemHideEmulation(test, selectors))
198 {
199 expectVisible(test, parent);
200 expectHidden(test, toHide);
201 } 81 }
202 82
203 test.done(); 83 function expectProcessed(element, id = null)
204 }; 84 {
205 85 let withId = "";
206 exports.testVerbatimPropertySelectorWithPrefixNoMatch = async function(test) 86 if (id)
207 { 87 withId = ` with ID '${id}'`;
208 let parent = createElementWithStyle("{background-color: #000}"); 88
209 let toHide = createElementWithStyle("{background-color: #fff}", parent); 89 assert.ok(
210 90 getTestInfo().lastProcessedElements.has(element),
211 let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"]; 91 `The element${withId} should have been processed`);
212
213 if (await applyElemHideEmulation(test, selectors))
214 {
215 expectVisible(test, parent);
216 expectVisible(test, toHide);
217 } 92 }
218 93
219 test.done(); 94 function expectNotProcessed(element, id = null)
220 }; 95 {
221 96 let withId = "";
222 exports.testVerbatimPropertySelectorWithSuffix = async function(test) 97 if (id)
223 { 98 withId = ` with ID '${id}'`;
224 let parent = createElementWithStyle("{background-color: #000}"); 99
225 let toHide = createElementWithStyle("{background-color: #000}", parent); 100 assert.ok(
226 101 !getTestInfo().lastProcessedElements.has(element),
227 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0)) > div"]; 102 `The element${withId} should not have been processed`);
228
229 if (await applyElemHideEmulation(test, selectors))
230 {
231 expectVisible(test, parent);
232 expectHidden(test, toHide);
233 } 103 }
234 104
235 test.done(); 105 function findUniqueId()
236 }; 106 {
237 107 let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000);
238 exports.testVerbatimPropertyPseudoSelectorWithPrefixAndSuffix = async function(t est) 108 if (!testDocument.getElementById(id))
239 { 109 return id;
240 let parent = createElementWithStyle("{background-color: #000}"); 110 return findUniqueId();
241 let middle = createElementWithStyle("{background-color: #000}", parent);
242 let toHide = createElementWithStyle("{background-color: #000}", middle);
243
244 let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0)) > div "];
245
246 if (await applyElemHideEmulation(test, selectors))
247 {
248 expectVisible(test, parent);
249 expectVisible(test, middle);
250 expectHidden(test, toHide);
251 } 111 }
252 112
253 test.done(); 113 function insertStyleRule(rule)
254 }; 114 {
255 115 let styleElement;
256 // Add the style. Then add the element for that style. 116 let styleElements = testDocument.head.getElementsByTagName("style");
257 // This should retrigger the filtering and hide it. 117 if (styleElements.length)
258 exports.testPropertyPseudoSelectorAddStyleAndElement = async function(test) 118 styleElement = styleElements[0];
259 { 119 else
260 let styleElement; 120 {
261 let toHide; 121 styleElement = testDocument.createElement("style");
262 122 testDocument.head.appendChild(styleElement);
263 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"]; 123 }
264 124 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length);
265 if (await applyElemHideEmulation(test, selectors))
266 {
267 styleElement = testDocument.createElement("style");
268 testDocument.head.appendChild(styleElement);
269 styleElement.sheet.insertRule("#toHide {background-color: #000}");
270 await timeout(REFRESH_INTERVAL);
271
272 toHide = createElement();
273 toHide.id = "toHide";
274 expectVisible(test, toHide);
275 await timeout(REFRESH_INTERVAL);
276
277 expectHidden(test, toHide);
278 } 125 }
279 126
280 test.done(); 127 function createElement(parent, type = "div", id = findUniqueId(),
281 }; 128 innerText = null)
282 129 {
283 exports.testPropertySelectorWithWildcard = async function(test) 130 let element = testDocument.createElement(type);
284 { 131 element.id = id;
285 let toHide = createElementWithStyle("{background-color: #000}"); 132 if (!parent)
286 let selectors = [":-abp-properties(*color: rgb(0, 0, 0))"]; 133 testDocument.body.appendChild(element);
287 134 else
288 if (await applyElemHideEmulation(test, selectors)) 135 parent.appendChild(element);
289 expectHidden(test, toHide); 136 if (innerText)
290 137 element.innerText = innerText;
291 test.done(); 138 return element;
292 };
293
294 exports.testPropertySelectorWithRegularExpression = async function(test)
295 {
296 let toHide = createElementWithStyle("{background-color: #000}");
297 let selectors = [":-abp-properties(/.*color: rgb\\(0, 0, 0\\)/)"];
298
299 if (await applyElemHideEmulation(test, selectors))
300 expectHidden(test, toHide);
301
302 test.done();
303 };
304
305 exports.testDynamicallyChangedProperty = async function(test)
306 {
307 let toHide = createElementWithStyle("{}");
308 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
309
310 if (await applyElemHideEmulation(test, selectors))
311 {
312 expectVisible(test, toHide);
313 insertStyleRule("#" + toHide.id + " {background-color: #000}");
314
315 await timeout(0);
316
317 // Re-evaluation will only happen after a delay
318 expectVisible(test, toHide);
319 await timeout(REFRESH_INTERVAL);
320
321 expectHidden(test, toHide);
322 } 139 }
323 140
324 test.done(); 141 // Insert a <div> with a unique id and a CSS rule
325 }; 142 // for the the selector matching the id.
326 143 function createElementWithStyle(styleBlock, parent)
327 exports.testPseudoClassWithPropBeforeSelector = async function(test) 144 {
328 { 145 let element = createElement(parent);
329 let parent = createElementWithStyle("{}"); 146 insertStyleRule("#" + element.id + " " + styleBlock);
330 let child = createElementWithStyle("{background-color: #000}", parent); 147 return element;
331
332 let selectors = ["div:-abp-properties(content: \"publicite\")"];
333
334 insertStyleRule(`#${child.id}::before {content: "publicite"}`);
335
336 if (await applyElemHideEmulation(test, selectors))
337 {
338 expectHidden(test, child);
339 expectVisible(test, parent);
340 } 148 }
341 149
342 test.done(); 150 // Create a new ElemHideEmulation instance with @selectors.
343 }; 151 async function applyElemHideEmulation(selectors)
344 152 {
345 exports.testPseudoClassHasSelector = async function(test) 153 await Promise.resolve();
346 { 154
347 let toHide = createElementWithStyle("{}"); 155 try
348 156 {
349 if (await applyElemHideEmulation(test, ["div:-abp-has(div)"])) 157 let elemHideEmulation = new ElemHideEmulation(
350 expectVisible(test, toHide); 158 elems =>
351 159 {
352 test.done(); 160 for (let elem of elems)
353 }; 161 elem.style.display = "none";
354 162 }
355 exports.testPseudoClassHasSelectorWithPrefix = async function(test) 163 );
356 { 164
357 let parent = createElementWithStyle("{}"); 165 elemHideEmulation.document = testDocument;
358 let child = createElementWithStyle("{}", parent); 166 elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2;
359 167 elemHideEmulation.apply(selectors.map(
360 if (await applyElemHideEmulation(test, ["div:-abp-has(div)"])) 168 selector => ({selector, text: selector})
361 { 169 ));
362 expectHidden(test, parent); 170
363 expectVisible(test, child); 171 return elemHideEmulation;
364 } 172 }
365 173 catch (error)
366 test.done(); 174 {
367 }; 175 unexpectedError(error);
368
369 exports.testPseudoClassHasSelectorWithSuffix = async function(test)
370 {
371 let parent = createElementWithStyle("{}");
372 let middle = createElementWithStyle("{}", parent);
373 let child = createElementWithStyle("{}", middle);
374
375 if (await applyElemHideEmulation(test, ["div:-abp-has(div) > div"]))
376 {
377 expectVisible(test, parent);
378 expectHidden(test, middle);
379 expectHidden(test, child);
380 }
381
382 test.done();
383 };
384
385 exports.testPseudoClassHasSelectorWithSuffixSibling = async function(test)
386 {
387 let parent = createElementWithStyle("{}");
388 let middle = createElementWithStyle("{}", parent);
389 let toHide = createElementWithStyle("{}");
390
391 if (await applyElemHideEmulation(test, ["div:-abp-has(div) + div"]))
392 {
393 expectVisible(test, parent);
394 expectVisible(test, middle);
395 expectHidden(test, toHide);
396 }
397
398 test.done();
399 };
400
401 exports.testPseudoClassHasSelectorWithSuffixSiblingChild = async function(test)
402 {
403 // <div>
404 // <div></div>
405 // <div>
406 // <div>to hide</div>
407 // </div>
408 // </div>
409 let parent = createElementWithStyle("{}");
410 let middle = createElementWithStyle("{}", parent);
411 let sibling = createElementWithStyle("{}");
412 let toHide = createElementWithStyle("{}", sibling);
413
414 if (await applyElemHideEmulation(test, ["div:-abp-has(div) + div > div"]))
415 {
416 expectVisible(test, parent);
417 expectVisible(test, middle);
418 expectVisible(test, sibling);
419 expectHidden(test, toHide);
420 }
421
422 test.done();
423 };
424
425 function compareExpectations(test, elems, expectations)
426 {
427 for (let elem in expectations)
428 {
429 if (elems[elem])
430 {
431 if (expectations[elem])
432 expectVisible(test, elems[elem], elem);
433 else
434 expectHidden(test, elems[elem], elem);
435 } 176 }
436 } 177 }
437 } 178
438 179 describe("Verbatim Property Selector", () =>
439 async function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, se lector, expectations) 180 {
440 { 181 it("Regular", async() =>
441 testDocument.body.innerHTML = `<div id="parent"> 182 {
442 <div id="middle"> 183 let toHide = createElementWithStyle("{background-color: #000}");
443 <div id="middle1"><div id="inside" class="inside"></div></div> 184 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
444 </div> 185
445 <div id="sibling"> 186 if (await applyElemHideEmulation(selectors))
446 <div id="tohide"><span>to hide</span></div> 187 expectHidden(toHide);
447 </div> 188 });
448 <div id="sibling2"> 189
449 <div id="sibling21"><div id="sibling211" class="inside"></div></div> 190 it("With Prefix", async() =>
450 </div> 191 {
451 </div>`; 192 let parent = createElementWithStyle("{background-color: #000}");
452 let elems = { 193 let toHide = createElementWithStyle("{background-color: #000}", parent);
453 parent: testDocument.getElementById("parent"), 194
454 middle: testDocument.getElementById("middle"), 195 let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"] ;
455 inside: testDocument.getElementById("inside"), 196
456 sibling: testDocument.getElementById("sibling"), 197 if (await applyElemHideEmulation(selectors))
457 sibling2: testDocument.getElementById("sibling2"), 198 {
458 toHide: testDocument.getElementById("tohide") 199 expectVisible(parent);
459 }; 200 expectHidden(toHide);
460 201 }
461 insertStyleRule(".inside {}"); 202 });
462 203
463 if (await applyElemHideEmulation(test, [selector])) 204 it("With Prefix No Match", async() =>
464 compareExpectations(test, elems, expectations); 205 {
465 206 let parent = createElementWithStyle("{background-color: #000}");
466 test.done(); 207 let toHide = createElementWithStyle("{background-color: #fff}", parent);
467 } 208
468 209 let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"] ;
469 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test) 210
470 { 211 if (await applyElemHideEmulation(selectors))
471 let expectations = { 212 {
472 parent: true, 213 expectVisible(parent);
473 middile: true, 214 expectVisible(toHide);
474 inside: true, 215 }
475 sibling: true, 216 });
476 sibling2: true, 217
477 toHide: false 218 it("With Suffix", async() =>
478 }; 219 {
479 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( 220 let parent = createElementWithStyle("{background-color: #000}");
480 test, "div:-abp-has(:-abp-has(div.inside)) + div > div", expectations); 221 let toHide = createElementWithStyle("{background-color: #000}", parent);
481 }; 222
482 223 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0)) > div"] ;
483 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = function(test) 224
484 { 225 if (await applyElemHideEmulation(selectors))
485 let expectations = { 226 {
486 parent: true, 227 expectVisible(parent);
487 middile: true, 228 expectHidden(toHide);
488 inside: true, 229 }
489 sibling: true, 230 });
490 sibling2: true, 231
491 toHide: false 232
492 }; 233 it("With prefix and suffix", async() =>
493 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( 234 {
494 test, "div:-abp-has(:-abp-has(> div.inside)) + div > div", expectations); 235 let parent = createElementWithStyle("{background-color: #000}");
495 }; 236 let middle = createElementWithStyle("{background-color: #000}", parent);
496 237 let toHide = createElementWithStyle("{background-color: #000}", middle);
497 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling3 = function(test) 238
498 { 239 let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0)) > div"];
499 let expectations = { 240
500 parent: true, 241 if (await applyElemHideEmulation(selectors))
501 middile: true, 242 {
502 inside: true, 243 expectVisible(parent);
503 sibling: true, 244 expectVisible(middle);
504 sibling2: true, 245 expectHidden(toHide);
505 toHide: false 246 }
506 }; 247 });
507 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( 248 });
508 test, "div:-abp-has(> div:-abp-has(div.inside)) + div > div", expectations); 249
509 }; 250 // Add the style. Then add the element for that style.
510 251 // This should retrigger the filtering and hide it.
511 exports.testPseudoClassHasSelectorWithSuffixSiblingNoop = function(test) 252 it("Property Pseudo Selector Add Style and elemment", async() =>
512 { 253 {
513 let expectations = { 254 let styleElement;
514 parent: true, 255 let toHide;
515 middile: true, 256
516 inside: true, 257 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
517 sibling: true, 258
518 sibling2: true, 259 if (await applyElemHideEmulation(selectors))
519 toHide: true 260 {
520 }; 261 styleElement = testDocument.createElement("style");
521 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( 262 testDocument.head.appendChild(styleElement);
522 test, "div:-abp-has(> body div.inside) + div > div", expectations); 263 styleElement.sheet.insertRule("#toHide {background-color: #000}");
523 }; 264 await timeout(REFRESH_INTERVAL);
524 265
525 exports.testPseudoClassHasSelectorWithSuffixSiblingContains = function(test) 266 toHide = createElement();
526 { 267 toHide.id = "toHide";
527 let expectations = { 268 expectVisible(toHide);
528 parent: true, 269 await timeout(REFRESH_INTERVAL);
529 middile: true, 270
530 inside: true, 271 expectHidden(toHide);
531 sibling: true, 272 }
532 sibling2: true, 273 });
533 toHide: true 274
534 }; 275 describe("Property Selector", () =>
535 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( 276 {
536 test, "div:-abp-has(> span:-abp-contains(Advertisment))", expectations); 277 it("With Wildcard", async() =>
537 }; 278 {
538 279 let toHide = createElementWithStyle("{background-color: #000}");
539 async function runTestPseudoClassContains(test, selector, expectations) 280 let selectors = [":-abp-properties(*color: rgb(0, 0, 0))"];
540 { 281
541 testDocument.body.innerHTML = `<div id="parent"> 282 if (await applyElemHideEmulation(selectors))
542 <div id="middle"> 283 expectHidden(toHide);
543 <div id="middle1"><div id="inside" class="inside"></div></div> 284 });
544 </div> 285
545 <div id="sibling"> 286 it("With regular expression", async() =>
546 <div id="tohide">to hide \ud83d\ude42!</div> 287 {
547 </div> 288 let toHide = createElementWithStyle("{background-color: #000}");
548 <div id="sibling2"> 289 let selectors = [":-abp-properties(/.*color: rgb\\(0, 0, 0\\)/)"];
549 <div id="sibling21"><div id="sibling211" class="inside">Ad*</div></div> 290
550 </div> 291 if (await applyElemHideEmulation(selectors))
551 </div>`; 292 expectHidden(toHide);
552 let elems = { 293 });
553 parent: testDocument.getElementById("parent"), 294 });
554 middle: testDocument.getElementById("middle"), 295
555 inside: testDocument.getElementById("inside"), 296 it("Dynamically Changed Property", async() =>
556 sibling: testDocument.getElementById("sibling"), 297 {
557 sibling2: testDocument.getElementById("sibling2"), 298 let toHide = createElementWithStyle("{}");
558 toHide: testDocument.getElementById("tohide") 299 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
559 }; 300
560 301 if (await applyElemHideEmulation(selectors))
561 if (await applyElemHideEmulation(test, [selector])) 302 {
562 compareExpectations(test, elems, expectations); 303 expectVisible(toHide);
563 304 insertStyleRule("#" + toHide.id + " {background-color: #000}");
564 test.done(); 305
565 } 306 await timeout(0);
566 307
567 exports.testPseudoClassContainsText = function(test) 308 // Re-evaluation will only happen after a delay
568 { 309 expectVisible(toHide);
569 let expectations = { 310 await timeout(REFRESH_INTERVAL);
570 parent: true, 311
571 middle: true, 312 expectHidden(toHide);
572 inside: true, 313 }
573 sibling: false, 314 });
574 sibling2: true, 315
575 toHide: true 316 describe("Pseudo Class", () =>
576 }; 317 {
577 runTestPseudoClassContains( 318 it("With prop before selector", async() =>
578 test, "#parent div:-abp-contains(to hide)", expectations); 319 {
579 }; 320 let parent = createElementWithStyle("{}");
580 321 let child = createElementWithStyle("{background-color: #000}", parent);
581 exports.testPseudoClassContainsRegexp = function(test) 322
582 { 323 let selectors = ["div:-abp-properties(content: \"publicite\")"];
583 let expectations = { 324
584 parent: true, 325 insertStyleRule(`#${child.id}::before {content: "publicite"}`);
585 middle: true, 326
586 inside: true, 327 if (await applyElemHideEmulation(selectors))
587 sibling: false, 328 {
588 sibling2: true, 329 expectHidden(child);
589 toHide: true 330 expectVisible(parent);
590 }; 331 }
591 runTestPseudoClassContains( 332 });
592 test, "#parent div:-abp-contains(/to\\shide/)", expectations); 333
593 }; 334 function compareExpectations(elems, expectations)
594 335 {
595 exports.testPseudoClassContainsRegexpIFlag = function(test) 336 for (let elem in expectations)
596 { 337 {
597 let expectations = { 338 if (elems[elem])
598 parent: true, 339 {
599 middle: true, 340 if (expectations[elem])
600 inside: true, 341 expectVisible(elems[elem], elem);
601 sibling: false, 342 else
602 sibling2: true, 343 expectHidden(elems[elem], elem);
603 toHide: true 344 }
604 }; 345 }
605 runTestPseudoClassContains( 346 }
606 test, "#parent div:-abp-contains(/to\\sHide/i)", expectations); 347
607 }; 348 describe("Has Selector", () =>
608 349 {
609 exports.testPseudoClassContainsRegexpUFlag = function(test) 350 it("Simple", async() =>
610 { 351 {
611 let expectations = { 352 let toHide = createElementWithStyle("{}");
612 parent: true, 353
613 middle: true, 354 if (await applyElemHideEmulation(["div:-abp-has(div)"]))
614 inside: true, 355 expectVisible(toHide);
615 sibling: false, 356 });
616 sibling2: true, 357
617 toHide: true 358 it("With prefix", async() =>
618 }; 359 {
619 runTestPseudoClassContains( 360 let parent = createElementWithStyle("{}");
620 test, "#parent div:-abp-contains(/to\\shide\\s.!/u)", expectations); 361 let child = createElementWithStyle("{}", parent);
621 }; 362
622 363 if (await applyElemHideEmulation(["div:-abp-has(div)"]))
623 exports.testPseudoClassContainsWildcardNoMatch = function(test) 364 {
624 { 365 expectHidden(parent);
625 let expectations = { 366 expectVisible(child);
626 parent: true, 367 }
627 middle: true, 368 });
628 inside: true, 369
629 sibling: true, 370 it("With suffix", async() =>
630 sibling2: true, 371 {
631 toHide: true 372 let parent = createElementWithStyle("{}");
632 }; 373 let middle = createElementWithStyle("{}", parent);
633 // this filter shouldn't match anything as "*" has no meaning. 374 let child = createElementWithStyle("{}", middle);
634 runTestPseudoClassContains( 375
635 test, "#parent div:-abp-contains(to *hide)", expectations); 376 if (await applyElemHideEmulation(["div:-abp-has(div) > div"]))
636 }; 377 {
637 378 expectVisible(parent);
638 exports.testPseudoClassContainsWildcardMatch = function(test) 379 expectHidden(middle);
639 { 380 expectHidden(child);
640 let expectations = { 381 }
641 parent: true, 382 });
642 middle: true, 383
643 inside: true, 384 it("With suffix sibling", async() =>
644 sibling: true, 385 {
645 sibling2: false, 386 let parent = createElementWithStyle("{}");
646 toHide: true 387 let middle = createElementWithStyle("{}", parent);
647 }; 388 let toHide = createElementWithStyle("{}");
648 runTestPseudoClassContains( 389
649 test, "#parent div:-abp-contains(Ad*)", expectations); 390 if (await applyElemHideEmulation(["div:-abp-has(div) + div"]))
650 }; 391 {
651 392 expectVisible(parent);
652 exports.testPseudoClassHasSelectorWithPropSelector = async function(test) 393 expectVisible(middle);
653 { 394 expectHidden(toHide);
654 let parent = createElementWithStyle("{}"); 395 }
655 let child = createElementWithStyle("{background-color: #000}", parent); 396 });
656 397
657 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0) ))"]; 398 it("With suffix sibling child", async() =>
658 399 {
659 if (await applyElemHideEmulation(test, selectors)) 400 // <div>
660 { 401 // <div></div>
661 expectVisible(test, child); 402 // <div>
662 expectHidden(test, parent); 403 // <div>to hide</div>
663 } 404 // </div>
664 405 // </div>
665 test.done(); 406 let parent = createElementWithStyle("{}");
666 }; 407 let middle = createElementWithStyle("{}", parent);
667 408 let sibling = createElementWithStyle("{}");
668 exports.testPseudoClassHasSelectorWithPropSelector2 = async function(test) 409 let toHide = createElementWithStyle("{}", sibling);
669 { 410
670 let parent = createElementWithStyle("{}"); 411 if (await applyElemHideEmulation(["div:-abp-has(div) + div > div"]))
671 let child = createElementWithStyle("{}", parent); 412 {
672 413 expectVisible(parent);
673 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0) ))"]; 414 expectVisible(middle);
674 415 expectVisible(sibling);
675 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); 416 expectHidden(toHide);
676 417 }
677 if (await applyElemHideEmulation(test, selectors)) 418 });
678 { 419
679 expectVisible(test, child); 420 async function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(se lector, expectations)
680 expectHidden(test, parent); 421 {
681 } 422 testDocument.body.innerHTML = `<div id="parent">
682 423 <div id="middle">
683 test.done(); 424 <div id="middle1"><div id="inside" class="inside"></div></div>
684 }; 425 </div>
685 426 <div id="sibling">
686 exports.testDomUpdatesStyle = async function(test) 427 <div id="tohide"><span>to hide</span></div>
687 { 428 </div>
688 let parent = createElementWithStyle("{}"); 429 <div id="sibling2">
689 let child = createElementWithStyle("{}", parent); 430 <div id="sibling21"><div id="sibling211" class="inside"></div></div>
690 431 </div>
691 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0) ))"]; 432 </div>`;
692 433 let elems = {
693 if (await applyElemHideEmulation(test, selectors)) 434 parent: testDocument.getElementById("parent"),
694 { 435 middle: testDocument.getElementById("middle"),
695 expectVisible(test, child); 436 inside: testDocument.getElementById("inside"),
696 expectVisible(test, parent); 437 sibling: testDocument.getElementById("sibling"),
697 438 sibling2: testDocument.getElementById("sibling2"),
698 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); 439 toHide: testDocument.getElementById("tohide")
699 await timeout(0); 440 };
700 441
701 expectVisible(test, child); 442 insertStyleRule(".inside {}");
702 expectVisible(test, parent); 443 if (await applyElemHideEmulation([selector]))
703 await timeout(REFRESH_INTERVAL); 444 compareExpectations(elems, expectations);
704 445 }
705 expectVisible(test, child); 446
706 expectHidden(test, parent); 447 it("With has and with suffix sibling", () =>
707 } 448 {
708 449 let expectations = {
709 test.done(); 450 parent: true,
710 }; 451 middile: true,
711 452 inside: true,
712 exports.testDomUpdatesContent = async function(test) 453 sibling: true,
713 { 454 sibling2: true,
714 let parent = createElementWithStyle("{}"); 455 toHide: false
715 let child = createElementWithStyle("{}", parent); 456 };
716 457 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
717 if (await applyElemHideEmulation(test, ["div > div:-abp-contains(hide me)"])) 458 "div:-abp-has(:-abp-has(div.inside)) + div > div", expectations);
718 { 459 });
719 expectVisible(test, parent); 460
720 expectVisible(test, child); 461 it("With has an with suffix sibling (2)", () =>
721 462 {
722 child.textContent = "hide me"; 463 let expectations = {
723 await timeout(0); 464 parent: true,
724 465 middile: true,
725 expectVisible(test, parent); 466 inside: true,
726 expectVisible(test, child); 467 sibling: true,
727 await timeout(REFRESH_INTERVAL); 468 sibling2: true,
728 469 toHide: false
729 expectVisible(test, parent); 470 };
730 expectHidden(test, child); 471 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
731 } 472 "div:-abp-has(:-abp-has(> div.inside)) + div > div", expectations);
732 473 });
733 test.done(); 474
734 }; 475 it("With has an with suffix sibling (3)", () =>
735 476 {
736 exports.testDomUpdatesNewElement = async function(test) 477 let expectations = {
737 { 478 parent: true,
738 let parent = createElementWithStyle("{}"); 479 middile: true,
739 let child = createElementWithStyle("{ background-color: #000}", parent); 480 inside: true,
740 let sibling; 481 sibling: true,
741 let child2; 482 sibling2: true,
742 483 toHide: false
743 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0) ))"]; 484 };
744 485 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
745 if (await applyElemHideEmulation(test, selectors)) 486 "div:-abp-has(> div:-abp-has(div.inside)) + div > div", expectations);
746 { 487 });
747 expectHidden(test, parent); 488
748 expectVisible(test, child); 489 it("With suffix sibling no-op", () =>
749 490 {
750 sibling = createElementWithStyle("{}"); 491 let expectations = {
751 await timeout(0); 492 parent: true,
752 493 middile: true,
753 expectHidden(test, parent); 494 inside: true,
754 expectVisible(test, child); 495 sibling: true,
755 expectVisible(test, sibling); 496 sibling2: true,
756 497 toHide: true
757 await timeout(REFRESH_INTERVAL); 498 };
758 499 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
759 expectHidden(test, parent); 500 "div:-abp-has(> body div.inside) + div > div", expectations);
760 expectVisible(test, child); 501 });
761 expectVisible(test, sibling); 502
762 503 it("With suffix sibling contains", () =>
763 child2 = createElementWithStyle("{ background-color: #000}", 504 {
764 sibling); 505 let expectations = {
765 await timeout(0); 506 parent: true,
766 507 middile: true,
767 expectVisible(test, child2); 508 inside: true,
768 await timeout(REFRESH_INTERVAL); 509 sibling: true,
769 510 sibling2: true,
770 expectHidden(test, parent); 511 toHide: true
771 expectVisible(test, child); 512 };
772 expectHidden(test, sibling); 513 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
773 expectVisible(test, child2); 514 "div:-abp-has(> span:-abp-contains(Advertisment))", expectations);
774 } 515 });
775 516 });
776 test.done(); 517
777 }; 518 describe("Contains selector", () =>
778 519 {
779 exports.testPseudoClassPropertiesOnStyleSheetLoad = async function(test) 520 async function runTestPseudoClassContains(selector, expectations)
780 { 521 {
781 let parent = createElement(); 522 testDocument.body.innerHTML = `<div id="parent">
782 let child = createElement(parent); 523 <div id="middle">
783 524 <div id="middle1"><div id="inside" class="inside"></div></div>
784 let selectors = [ 525 </div>
785 "div:-abp-properties(background-color: rgb(0, 0, 0))", 526 <div id="sibling">
786 "div:-abp-contains(hide me)", 527 <div id="tohide">to hide \ud83d\ude42!</div>
787 "div:-abp-has(> div.hideMe)" 528 </div>
788 ]; 529 <div id="sibling2">
789 530 <div id="sibling21">
790 if (await applyElemHideEmulation(test, selectors)) 531 <div id="sibling211" class="inside">Ad*</div>
791 { 532 </div>
792 await timeout(REFRESH_INTERVAL); 533 </div>
793 534 </div>`;
794 expectVisible(test, parent); 535 let elems = {
795 expectVisible(test, child); 536 parent: testDocument.getElementById("parent"),
796 537 middle: testDocument.getElementById("middle"),
797 // Load a style sheet that targets the parent element. This should run only 538 inside: testDocument.getElementById("inside"),
798 // the "div:-abp-properties(background-color: rgb(0, 0, 0))" pattern. 539 sibling: testDocument.getElementById("sibling"),
799 insertStyleRule("#" + parent.id + " {background-color: #000}"); 540 sibling2: testDocument.getElementById("sibling2"),
800 541 toHide: testDocument.getElementById("tohide")
801 await timeout(REFRESH_INTERVAL); 542 };
802 543
803 expectHidden(test, parent); 544 if (await applyElemHideEmulation([selector]))
804 expectVisible(test, child); 545 compareExpectations(elems, expectations);
805 } 546 }
806 547
807 test.done(); 548 it("Text", () =>
808 }; 549 {
809 550 let expectations = {
810 exports.testPlainAttributeOnDomMutation = async function(test) 551 parent: true,
811 { 552 middle: true,
812 let parent = createElement(); 553 inside: true,
813 let child = createElement(parent); 554 sibling: false,
814 555 sibling2: true,
815 let selectors = [ 556 toHide: true
816 "div:-abp-properties(background-color: rgb(0, 0, 0))", 557 };
817 "div[data-hide-me]", 558 runTestPseudoClassContains(
818 "div:-abp-contains(hide me)", 559 "#parent div:-abp-contains(to hide)", expectations);
819 "div:-abp-has(> div.hideMe)" 560 });
820 ]; 561
821 562 it("Regexp", () =>
822 if (await applyElemHideEmulation(test, selectors)) 563 {
823 { 564 let expectations = {
824 await timeout(REFRESH_INTERVAL); 565 parent: true,
825 566 middle: true,
826 expectVisible(test, parent); 567 inside: true,
827 expectVisible(test, child); 568 sibling: false,
828 569 sibling2: true,
829 // Set the "data-hide-me" attribute on the child element. 570 toHide: true
830 // 571 };
831 // Note: Since the "div[data-hide-me]" pattern has already been processed 572 runTestPseudoClassContains(
832 // and the selector added to the document's style sheet, this will in fact 573 "#parent div:-abp-contains(/to\\shide/)", expectations);
833 // not do anything at our end, but the browser will just match the selector 574 });
834 // and hide the element. 575
835 child.setAttribute("data-hide-me", ""); 576 it("Regexp i flag", () =>
836 577 {
837 await timeout(REFRESH_INTERVAL); 578 let expectations = {
838 579 parent: true,
839 expectVisible(test, parent); 580 middle: true,
840 expectHidden(test, child); 581 inside: true,
841 } 582 sibling: false,
842 583 sibling2: true,
843 test.done(); 584 toHide: true
844 }; 585 };
845 586 runTestPseudoClassContains(
846 exports.testPseudoClassContainsOnDomMutation = async function(test) 587 "#parent div:-abp-contains(/to\\sHide/i)", expectations);
847 { 588 });
848 let parent = createElement(); 589
849 let child = createElement(parent); 590 it("Regexp u flag", () =>
850 591 {
851 let selectors = [ 592 let expectations = {
852 "div:-abp-properties(background-color: rgb(0, 0, 0))", 593 parent: true,
853 "div[data-hide-me]", 594 middle: true,
854 "div:-abp-contains(hide me)", 595 inside: true,
855 "div:-abp-has(> div.hideMe)" 596 sibling: false,
856 ]; 597 sibling2: true,
857 598 toHide: true
858 child.innerText = "do nothing"; 599 };
859 600 runTestPseudoClassContains(
860 if (await applyElemHideEmulation(test, selectors)) 601 "#parent div:-abp-contains(/to\\shide\\s.!/u)", expectations);
861 { 602 });
862 await timeout(REFRESH_INTERVAL); 603
863 604 it("Wildcard no match", () =>
864 expectVisible(test, parent); 605 {
865 expectVisible(test, child); 606 let expectations = {
866 607 parent: true,
867 // Set the child element's text to "hide me". This should run only the 608 middle: true,
868 // "div:-abp-contains(hide me)" pattern. 609 inside: true,
869 // 610 sibling: true,
870 // Note: We need to set Node.innerText here in order to trigger the 611 sibling2: true,
871 // "characterData" DOM mutation on Chromium. If we set Node.textContent 612 toHide: true
872 // instead, it triggers the "childList" DOM mutation instead. 613 };
873 child.innerText = "hide me"; 614 // this filter shouldn't match anything as "*" has no meaning.
874 615 runTestPseudoClassContains(
875 await timeout(REFRESH_INTERVAL); 616 "#parent div:-abp-contains(to *hide)", expectations);
876 617 });
877 expectHidden(test, parent); 618
878 expectVisible(test, child); 619 it("Wildcard match", () =>
879 } 620 {
880 621 let expectations = {
881 test.done(); 622 parent: true,
882 }; 623 middle: true,
883 624 inside: true,
884 exports.testPseudoClassHasOnDomMutation = async function(test) 625 sibling: true,
885 { 626 sibling2: false,
886 let parent = createElement(); 627 toHide: true
887 let child = null; 628 };
888 629 runTestPseudoClassContains(
889 let selectors = [ 630 "#parent div:-abp-contains(Ad*)", expectations);
890 "div:-abp-properties(background-color: rgb(0, 0, 0))", 631 });
891 "div[data-hide-me]", 632 });
892 "div:-abp-contains(hide me)", 633
893 "div:-abp-has(> div)" 634 describe("Has Selector with prop selector", () =>
894 ]; 635 {
895 636 it("Already present", async() =>
896 if (await applyElemHideEmulation(test, selectors)) 637 {
897 { 638 let parent = createElementWithStyle("{}");
898 await timeout(REFRESH_INTERVAL); 639 let child = createElementWithStyle("{background-color: #000}", parent);
899 640
900 expectVisible(test, parent); 641 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
901 642
902 // Add the child element. This should run all the DOM-dependent patterns 643 if (await applyElemHideEmulation(selectors))
903 // ("div:-abp-contains(hide me)" and "div:-abp-has(> div)"). 644 {
904 child = createElement(parent); 645 expectVisible(child);
905 646 expectHidden(parent);
906 await timeout(REFRESH_INTERVAL); 647 }
907 648 });
908 expectHidden(test, parent); 649
909 expectVisible(test, child); 650 it("Dynamically added", async() =>
910 } 651 {
911 652 let parent = createElementWithStyle("{}");
912 test.done(); 653 let child = createElementWithStyle("{}", parent);
913 }; 654
914 655 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
915 exports.testPseudoClassHasWithClassOnDomMutation = async function(test) 656
916 { 657 insertStyleRule("body #" + parent.id + " > div { background-color: #000} ");
917 let parent = createElement(); 658
918 let child = createElement(parent); 659 if (await applyElemHideEmulation(selectors))
919 660 {
920 let selectors = [ 661 expectVisible(child);
921 "div:-abp-properties(background-color: rgb(0, 0, 0))", 662 expectHidden(parent);
922 "div[data-hide-me]", 663 }
923 "div:-abp-contains(hide me)", 664 });
924 "div:-abp-has(> div.hideMe)" 665 });
925 ]; 666 });
926 667
927 if (await applyElemHideEmulation(test, selectors)) 668 describe("DOM updates", () =>
928 { 669 {
929 await timeout(REFRESH_INTERVAL); 670 it("Style", async() =>
930 671 {
931 expectVisible(test, parent); 672 let parent = createElementWithStyle("{}");
932 expectVisible(test, child); 673 let child = createElementWithStyle("{}", parent);
933 674
934 // Set the child element's class to "hideMe". This should run only the 675 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0 , 0)))"];
935 // "div:-abp-has(> div.hideMe)" pattern. 676
936 child.className = "hideMe"; 677 if (await applyElemHideEmulation(selectors))
937 678 {
938 await timeout(REFRESH_INTERVAL); 679 expectVisible(child);
939 680 expectVisible(parent);
940 expectHidden(test, parent); 681
941 expectVisible(test, child); 682 insertStyleRule("body #" + parent.id + " > div { background-color: #000} ");
942 } 683 await timeout(0);
943 684
944 test.done(); 685 expectVisible(child);
945 }; 686 expectVisible(parent);
946 687 await timeout(REFRESH_INTERVAL);
947 exports.testPseudoClassHasWithPseudoClassContainsOnDomMutation = async function( test) 688
948 { 689 expectVisible(child);
949 let parent = createElement(); 690 expectHidden(parent);
950 let child = createElement(parent); 691 }
951 692 });
952 let selectors = [ 693
953 "div:-abp-properties(background-color: rgb(0, 0, 0))", 694 it("Content", async() =>
954 "div[data-hide-me]", 695 {
955 "div:-abp-contains(hide me)", 696 let parent = createElementWithStyle("{}");
956 "div:-abp-has(> div:-abp-contains(hide me))" 697 let child = createElementWithStyle("{}", parent);
957 ]; 698
958 699 if (await applyElemHideEmulation(["div > div:-abp-contains(hide me)"]))
959 child.innerText = "do nothing"; 700 {
960 701 expectVisible(parent);
961 if (await applyElemHideEmulation(test, selectors)) 702 expectVisible(child);
962 { 703
963 await timeout(REFRESH_INTERVAL); 704 child.textContent = "hide me";
964 705 await timeout(0);
965 expectVisible(test, parent); 706
966 expectVisible(test, child); 707 expectVisible(parent);
967 708 expectVisible(child);
968 // Set the child element's text to "hide me". This should run only the 709 await timeout(REFRESH_INTERVAL);
969 // "div:-abp-contains(hide me)" and 710
970 // "div:-abp-has(> div:-abp-contains(hide me))" patterns. 711 expectVisible(parent);
971 child.innerText = "hide me"; 712 expectHidden(child);
972 713 }
973 await timeout(REFRESH_INTERVAL); 714 });
974 715
975 // Note: Even though it runs both the :-abp-contains() patterns, it only 716 it("New element", async() =>
976 // hides the parent element because of revision d7d51d29aa34. 717 {
977 expectHidden(test, parent); 718 let parent = createElementWithStyle("{}");
978 expectVisible(test, child); 719 let child = createElementWithStyle("{ background-color: #000}", parent);
979 } 720 let sibling;
980 721 let child2;
981 test.done(); 722
982 }; 723 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0 , 0)))"];
983 724
984 exports.testOnlyRelevantElementsProcessed = async function(test) 725 if (await applyElemHideEmulation(selectors))
985 { 726 {
986 // <body> 727 expectHidden(parent);
987 // <div id="n1"> 728 expectVisible(child);
988 // <p id="n1_1"></p> 729
989 // <p id="n1_2"></p> 730 sibling = createElementWithStyle("{}");
990 // <p id="n1_4">Hello</p> 731 await timeout(0);
991 // </div> 732
992 // <div id="n2"> 733 expectHidden(parent);
993 // <p id="n2_1"></p> 734 expectVisible(child);
994 // <p id="n2_2"></p> 735 expectVisible(sibling);
995 // <p id="n2_4">Hello</p> 736
996 // </div> 737 await timeout(REFRESH_INTERVAL);
997 // <div id="n3"> 738
998 // <p id="n3_1"></p> 739 expectHidden(parent);
999 // <p id="n3_2"></p> 740 expectVisible(child);
1000 // <p id="n3_4">Hello</p> 741 expectVisible(sibling);
1001 // </div> 742
1002 // <div id="n4"> 743 child2 = createElementWithStyle("{ background-color: #000}",
1003 // <p id="n4_1"></p> 744 sibling);
1004 // <p id="n4_2"></p> 745 await timeout(0);
1005 // <p id="n4_4">Hello</p> 746
1006 // </div> 747 expectVisible(child2);
1007 // </body> 748 await timeout(REFRESH_INTERVAL);
1008 for (let i of [1, 2, 3, 4]) 749
1009 { 750 expectHidden(parent);
1010 let n = createElement(null, "div", `n${i}`); 751 expectVisible(child);
1011 for (let [j, text] of [[1], [2], [4, "Hello"]]) 752 expectHidden(sibling);
1012 createElement(n, "p", `n${i}_${j}`, text); 753 expectVisible(child2);
1013 } 754 }
1014 755 });
1015 let selectors = [ 756 });
1016 "p:-abp-contains(Hello)", 757
1017 "div:-abp-contains(Try me!)", 758 it("Pseudo class properties on stylesheet load", async() =>
1018 "div:-abp-has(p:-abp-contains(This is good))" 759 {
1019 ]; 760 let parent = createElement();
1020 761 let child = createElement(parent);
1021 if (await applyElemHideEmulation(test, selectors)) 762
1022 { 763 let selectors = [
1023 await timeout(REFRESH_INTERVAL); 764 "div:-abp-properties(background-color: rgb(0, 0, 0))",
1024 765 "div:-abp-contains(hide me)",
1025 // This is only a sanity check to make sure everything else is working 766 "div:-abp-has(> div.hideMe)"
1026 // before we do the actual test. 767 ];
768
769 if (await applyElemHideEmulation(selectors))
770 {
771 await timeout(REFRESH_INTERVAL);
772
773 expectVisible(parent);
774 expectVisible(child);
775
776 // Load a style sheet that targets the parent element. This should run onl y
777 // the "div:-abp-properties(background-color: rgb(0, 0, 0))" pattern.
778 insertStyleRule("#" + parent.id + " {background-color: #000}");
779
780 await timeout(REFRESH_INTERVAL);
781
782 expectHidden(parent);
783 expectVisible(child);
784 }
785 });
786
787 describe("On DOM mutation", () =>
788 {
789 it("Plain attributes", async() =>
790 {
791 let parent = createElement();
792 let child = createElement(parent);
793
794 let selectors = [
795 "div:-abp-properties(background-color: rgb(0, 0, 0))",
796 "div[data-hide-me]",
797 "div:-abp-contains(hide me)",
798 "div:-abp-has(> div.hideMe)"
799 ];
800
801 if (await applyElemHideEmulation(selectors))
802 {
803 await timeout(REFRESH_INTERVAL);
804
805 expectVisible(parent);
806 expectVisible(child);
807
808 // Set the "data-hide-me" attribute on the child element.
809 //
810 // Note: Since the "div[data-hide-me]" pattern has already been processe d
811 // and the selector added to the document's style sheet, this will in fa ct
812 // not do anything at our end, but the browser will just match the selec tor
813 // and hide the element.
814 child.setAttribute("data-hide-me", "");
815
816 await timeout(REFRESH_INTERVAL);
817
818 expectVisible(parent);
819 expectHidden(child);
820 }
821 });
822
823 it("Pseudo class contains", async() =>
824 {
825 let parent = createElement();
826 let child = createElement(parent);
827
828 let selectors = [
829 "div:-abp-properties(background-color: rgb(0, 0, 0))",
830 "div[data-hide-me]",
831 "div:-abp-contains(hide me)",
832 "div:-abp-has(> div.hideMe)"
833 ];
834
835 child.innerText = "do nothing";
836
837 if (await applyElemHideEmulation(selectors))
838 {
839 await timeout(REFRESH_INTERVAL);
840
841 expectVisible(parent);
842 expectVisible(child);
843
844 // Set the child element's text to "hide me". This should run only the
845 // "div:-abp-contains(hide me)" pattern.
846 //
847 // Note: We need to set Node.innerText here in order to trigger the
848 // "characterData" DOM mutation on Chromium. If we set Node.textContent
849 // instead, it triggers the "childList" DOM mutation instead.
850 child.innerText = "hide me";
851
852 await timeout(REFRESH_INTERVAL);
853
854 expectHidden(parent);
855 expectVisible(child);
856 }
857 });
858
859 it("Pseudo class has", async() =>
860 {
861 let parent = createElement();
862 let child = null;
863
864 let selectors = [
865 "div:-abp-properties(background-color: rgb(0, 0, 0))",
866 "div[data-hide-me]",
867 "div:-abp-contains(hide me)",
868 "div:-abp-has(> div)"
869 ];
870
871 if (await applyElemHideEmulation(selectors))
872 {
873 await timeout(REFRESH_INTERVAL);
874
875 expectVisible(parent);
876
877 // Add the child element. This should run all the DOM-dependent patterns
878 // ("div:-abp-contains(hide me)" and "div:-abp-has(> div)").
879 child = createElement(parent);
880
881 await timeout(REFRESH_INTERVAL);
882
883 expectHidden(parent);
884 expectVisible(child);
885 }
886 });
887
888 it("Pseudo class has", async() =>
889 {
890 let parent = createElement();
891 let child = createElement(parent);
892
893 let selectors = [
894 "div:-abp-properties(background-color: rgb(0, 0, 0))",
895 "div[data-hide-me]",
896 "div:-abp-contains(hide me)",
897 "div:-abp-has(> div.hideMe)"
898 ];
899
900 if (await applyElemHideEmulation(selectors))
901 {
902 await timeout(REFRESH_INTERVAL);
903
904 expectVisible(parent);
905 expectVisible(child);
906
907 // Set the child element's class to "hideMe". This should run only the
908 // "div:-abp-has(> div.hideMe)" pattern.
909 child.className = "hideMe";
910
911 await timeout(REFRESH_INTERVAL);
912
913 expectHidden(parent);
914 expectVisible(child);
915 }
916 });
917
918 it("Pseudo class has with pseudo class contains", async() =>
919 {
920 let parent = createElement();
921 let child = createElement(parent);
922
923 let selectors = [
924 "div:-abp-properties(background-color: rgb(0, 0, 0))",
925 "div[data-hide-me]",
926 "div:-abp-contains(hide me)",
927 "div:-abp-has(> div:-abp-contains(hide me))"
928 ];
929
930 child.innerText = "do nothing";
931
932 if (await applyElemHideEmulation(selectors))
933 {
934 await timeout(REFRESH_INTERVAL);
935
936 expectVisible(parent);
937 expectVisible(child);
938
939 // Set the child element's text to "hide me". This should run only the
940 // "div:-abp-contains(hide me)" and
941 // "div:-abp-has(> div:-abp-contains(hide me))" patterns.
942 child.innerText = "hide me";
943
944 await timeout(REFRESH_INTERVAL);
945
946 // Note: Even though it runs both the :-abp-contains() patterns, it only
947 // hides the parent element because of revision d7d51d29aa34.
948 expectHidden(parent);
949 expectVisible(child);
950 }
951 });
952 });
953
954 it("Only relevant elements are processed", async() =>
955 {
956 // <body>
957 // <div id="n1">
958 // <p id="n1_1"></p>
959 // <p id="n1_2"></p>
960 // <p id="n1_4">Hello</p>
961 // </div>
962 // <div id="n2">
963 // <p id="n2_1"></p>
964 // <p id="n2_2"></p>
965 // <p id="n2_4">Hello</p>
966 // </div>
967 // <div id="n3">
968 // <p id="n3_1"></p>
969 // <p id="n3_2"></p>
970 // <p id="n3_4">Hello</p>
971 // </div>
972 // <div id="n4">
973 // <p id="n4_1"></p>
974 // <p id="n4_2"></p>
975 // <p id="n4_4">Hello</p>
976 // </div>
977 // </body>
1027 for (let i of [1, 2, 3, 4]) 978 for (let i of [1, 2, 3, 4])
1028 { 979 {
1029 for (let j of [1, 2, 4]) 980 let n = createElement(null, "div", `n${i}`);
1030 { 981 for (let [j, text] of [[1], [2], [4, "Hello"]])
1031 let id = `n${i}_${j}`; 982 createElement(n, "p", `n${i}_${j}`, text);
1032 if (j == 4) 983 }
1033 expectHidden(test, testDocument.getElementById(id), id); 984
985 let selectors = [
986 "p:-abp-contains(Hello)",
987 "div:-abp-contains(Try me!)",
988 "div:-abp-has(p:-abp-contains(This is good))"
989 ];
990
991 if (await applyElemHideEmulation(selectors))
992 {
993 await timeout(REFRESH_INTERVAL);
994
995 // This is only a sanity check to make sure everything else is working
996 // before we do the actual test.
997 for (let i of [1, 2, 3, 4])
998 {
999 for (let j of [1, 2, 4])
1000 {
1001 let id = `n${i}_${j}`;
1002 if (j == 4)
1003 expectHidden(testDocument.getElementById(id), id);
1004 else
1005 expectVisible(testDocument.getElementById(id), id);
1006 }
1007 }
1008
1009 // All <div> and <p> elements should be processed initially.
1010 for (let element of [...testDocument.getElementsByTagName("div"),
1011 ...testDocument.getElementsByTagName("p")])
1012 {
1013 expectProcessed(element, element.id);
1014 }
1015
1016 // Modify the text in <p id="n4_1">
1017 testDocument.getElementById("n4_1").innerText = "Try me!";
1018
1019 await timeout(REFRESH_INTERVAL);
1020
1021 // When an element's text is modified, only the element or one of its
1022 // ancestors matching any selector is processed for :-abp-has() and
1023 // :-abp-contains()
1024 for (let element of [...testDocument.getElementsByTagName("div"),
1025 ...testDocument.getElementsByTagName("p")])
1026 {
1027 if (element.id == "n4" || element.id == "n4_1")
1028 expectProcessed(element, element.id);
1034 else 1029 else
1035 expectVisible(test, testDocument.getElementById(id), id); 1030 expectNotProcessed(element, element.id);
1031 }
1032
1033 // Create a new <p id="n2_3"> element with no text.
1034 createElement(testDocument.getElementById("n2"), "p", "n2_3");
1035
1036 await timeout(REFRESH_INTERVAL);
1037
1038 // When a new element is added, only the element or one of its ancestors
1039 // matching any selector is processed for :-abp-has() and :-abp-contains()
1040 for (let element of [...testDocument.getElementsByTagName("div"),
1041 ...testDocument.getElementsByTagName("p")])
1042 {
1043 if (element.id == "n2" || element.id == "n2_3")
1044 expectProcessed(element, element.id);
1045 else
1046 expectNotProcessed(element, element.id);
1036 } 1047 }
1037 } 1048 }
1038 1049 });
1039 // All <div> and <p> elements should be processed initially. 1050 });
1040 for (let element of [...testDocument.getElementsByTagName("div"),
1041 ...testDocument.getElementsByTagName("p")])
1042 {
1043 expectProcessed(test, element, element.id);
1044 }
1045
1046 // Modify the text in <p id="n4_1">
1047 testDocument.getElementById("n4_1").innerText = "Try me!";
1048
1049 await timeout(REFRESH_INTERVAL);
1050
1051 // When an element's text is modified, only the element or one of its
1052 // ancestors matching any selector is processed for :-abp-has() and
1053 // :-abp-contains()
1054 for (let element of [...testDocument.getElementsByTagName("div"),
1055 ...testDocument.getElementsByTagName("p")])
1056 {
1057 if (element.id == "n4" || element.id == "n4_1")
1058 expectProcessed(test, element, element.id);
1059 else
1060 expectNotProcessed(test, element, element.id);
1061 }
1062
1063 // Create a new <p id="n2_3"> element with no text.
1064 createElement(testDocument.getElementById("n2"), "p", "n2_3");
1065
1066 await timeout(REFRESH_INTERVAL);
1067
1068 // When a new element is added, only the element or one of its ancestors
1069 // matching any selector is processed for :-abp-has() and :-abp-contains()
1070 for (let element of [...testDocument.getElementsByTagName("div"),
1071 ...testDocument.getElementsByTagName("p")])
1072 {
1073 if (element.id == "n2" || element.id == "n2_3")
1074 expectProcessed(test, element, element.id);
1075 else
1076 expectNotProcessed(test, element, element.id);
1077 }
1078 }
1079
1080 test.done();
1081 };
OLDNEW
« no previous file with comments | « test/browser/_bootstrap.js ('k') | test/browser/snippets.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld