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