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

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

Issue 29494577: Issue 5438 - Observer DOM changes to reapply filters. (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Test harness changes: test pass. Created Aug. 23, 2017, 2:42 a.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 | « lib/content/elemHideEmulation.js ('k') | no next file » | 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 "use strict"; 18 "use strict";
19 19
20 const {ElemHideEmulation} = require("../../lib/content/elemHideEmulation"); 20 const {ElemHideEmulation} = require("../../lib/content/elemHideEmulation");
21 21
22 let testDocument = null;
23
24 exports.setUp = function(callback)
25 {
26 testDocument = null;
Wladimir Palant 2017/08/23 13:23:31 This assignment seems pointless.
hub 2017/08/23 16:38:00 Done.
27 let iframe = document.createElement("iframe");
28 iframe.id = "test-iframe";
29 document.body.appendChild(iframe);
30 testDocument = iframe.contentDocument;
31
32 callback();
33 };
34
22 exports.tearDown = function(callback) 35 exports.tearDown = function(callback)
23 { 36 {
24 let styleElements = document.head.getElementsByTagName("style"); 37 let iframe = document.getElementById("test-iframe");
Wladimir Palant 2017/08/23 13:23:32 Use `testDocument.defaultView.frameElement` here?
hub 2017/08/23 16:38:00 Done.
25 while (styleElements.length) 38 iframe.parentNode.removeChild(iframe);
Wladimir Palant 2017/08/23 13:23:31 Please null out testDocument as well, so that tryi
hub 2017/08/23 16:38:00 Done.
26 styleElements[0].parentNode.removeChild(styleElements[0]);
27
28 let child;
29 while (child = document.body.firstChild)
30 child.parentNode.removeChild(child);
31 39
32 callback(); 40 callback();
33 }; 41 };
34 42
35 function unexpectedError(error) 43 function unexpectedError(error)
36 { 44 {
37 console.error(error); 45 console.error(error);
38 this.ok(false, "Unexpected error: " + error); 46 this.ok(false, "Unexpected error: " + error);
39 } 47 }
40 48
41 function expectHidden(test, element) 49 function expectHidden(test, element)
42 { 50 {
43 test.equal(window.getComputedStyle(element).display, "none", 51 test.equal(window.getComputedStyle(element).display, "none",
44 "The element's display property should be set to 'none'"); 52 "The element's display property should be set to 'none'");
45 } 53 }
46 54
47 function expectVisible(test, element) 55 function expectVisible(test, element)
48 { 56 {
49 test.notEqual(window.getComputedStyle(element).display, "none", 57 test.notEqual(window.getComputedStyle(element).display, "none",
50 "The element's display property should not be set to 'none'"); 58 "The element's display property should not be set to 'none'");
51 } 59 }
52 60
53 function findUniqueId() 61 function findUniqueId()
54 { 62 {
55 let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000); 63 let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000);
56 if (!document.getElementById(id)) 64 if (!testDocument.getElementById(id))
57 return id; 65 return id;
58 return findUniqueId(); 66 return findUniqueId();
59 } 67 }
60 68
61 function insertStyleRule(rule) 69 function insertStyleRule(rule)
62 { 70 {
63 let styleElement; 71 let styleElement;
64 let styleElements = document.head.getElementsByTagName("style"); 72 let styleElements = testDocument.head.getElementsByTagName("style");
65 if (styleElements.length) 73 if (styleElements.length)
66 styleElement = styleElements[0]; 74 styleElement = styleElements[0];
67 else 75 else
68 { 76 {
69 styleElement = document.createElement("style"); 77 styleElement = testDocument.createElement("style");
70 document.head.appendChild(styleElement); 78 testDocument.head.appendChild(styleElement);
71 } 79 }
72 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length); 80 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length);
73 } 81 }
74 82
75 // Insert a <div> with a unique id and a CSS rule 83 // Insert a <div> with a unique id and a CSS rule
76 // for the the selector matching the id. 84 // for the the selector matching the id.
77 function createElementWithStyle(styleBlock, parent) 85 function createElementWithStyle(styleBlock, parent)
78 { 86 {
79 let element = document.createElement("div"); 87 let element = testDocument.createElement("div");
80 element.id = findUniqueId(); 88 element.id = findUniqueId();
81 if (!parent) 89 if (!parent)
82 document.body.appendChild(element); 90 testDocument.body.appendChild(element);
83 else 91 else
84 parent.appendChild(element); 92 parent.appendChild(element);
85 insertStyleRule("#" + element.id + " " + styleBlock); 93 insertStyleRule("#" + element.id + " " + styleBlock);
86 return element; 94 return element;
87 } 95 }
88 96
89 // Create a new ElemHideEmulation instance with @selectors. 97 // Create a new ElemHideEmulation instance with @selectors.
90 function applyElemHideEmulation(selectors) 98 function applyElemHideEmulation(selectors)
91 { 99 {
92 return Promise.resolve().then(() => 100 return Promise.resolve().then(() =>
93 { 101 {
94 let elemHideEmulation = new ElemHideEmulation( 102 let elemHideEmulation = new ElemHideEmulation(
95 window, 103 testDocument.defaultView,
96 callback => 104 callback =>
97 { 105 {
98 let patterns = []; 106 let patterns = [];
99 selectors.forEach(selector => 107 selectors.forEach(selector =>
100 { 108 {
101 patterns.push({selector}); 109 patterns.push({selector});
102 }); 110 });
103 callback(patterns); 111 callback(patterns);
104 }, 112 },
105 newSelectors => 113 newSelectors =>
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 { 347 {
340 expectVisible(test, parent); 348 expectVisible(test, parent);
341 expectVisible(test, middle); 349 expectVisible(test, middle);
342 expectVisible(test, sibling); 350 expectVisible(test, sibling);
343 expectHidden(test, toHide); 351 expectHidden(test, toHide);
344 }).catch(unexpectedError.bind(test)).then(() => test.done()); 352 }).catch(unexpectedError.bind(test)).then(() => test.done());
345 }; 353 };
346 354
347 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector , expectations) 355 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector , expectations)
348 { 356 {
349 document.body.innerHTML = `<div id="parent"> 357 testDocument.body.innerHTML = `<div id="parent">
350 <div id="middle"> 358 <div id="middle">
351 <div id="middle1"><div id="inside" class="inside"></div></div> 359 <div id="middle1"><div id="inside" class="inside"></div></div>
352 </div> 360 </div>
353 <div id="sibling"> 361 <div id="sibling">
354 <div id="tohide">to hide</div> 362 <div id="tohide">to hide</div>
355 </div> 363 </div>
356 <div id="sibling2"> 364 <div id="sibling2">
357 <div id="sibling21"><div id="sibling211" class="inside"></div></div> 365 <div id="sibling21"><div id="sibling211" class="inside"></div></div>
358 </div> 366 </div>
359 </div>`; 367 </div>`;
360 let elems = { 368 let elems = {
361 parent: document.getElementById("parent"), 369 parent: testDocument.getElementById("parent"),
362 middle: document.getElementById("middle"), 370 middle: testDocument.getElementById("middle"),
363 inside: document.getElementById("inside"), 371 inside: testDocument.getElementById("inside"),
364 sibling: document.getElementById("sibling"), 372 sibling: testDocument.getElementById("sibling"),
365 sibling2: document.getElementById("sibling2"), 373 sibling2: testDocument.getElementById("sibling2"),
366 toHide: document.getElementById("tohide") 374 toHide: testDocument.getElementById("tohide")
367 }; 375 };
368 376
369 insertStyleRule(".inside {}"); 377 insertStyleRule(".inside {}");
370 378
371 applyElemHideEmulation( 379 applyElemHideEmulation(
372 [selector] 380 [selector]
373 ).then(() => 381 ).then(() =>
374 { 382 {
375 for (let elem in expectations) 383 for (let elem in expectations)
376 if (elems[elem]) 384 if (elems[elem])
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 sibling: true, 428 sibling: true,
421 sibling2: true, 429 sibling2: true,
422 toHide: true 430 toHide: true
423 }; 431 };
424 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( 432 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
425 test, "div:-abp-has(> body div.inside) + div > div", expectations); 433 test, "div:-abp-has(> body div.inside) + div > div", expectations);
426 }; 434 };
427 435
428 exports.testPseudoClassContains = function(test) 436 exports.testPseudoClassContains = function(test)
429 { 437 {
430 document.body.innerHTML = `<div id="parent"> 438 testDocument.body.innerHTML = `<div id="parent">
431 <div id="middle"> 439 <div id="middle">
432 <div id="middle1"><div id="inside" class="inside"></div></div> 440 <div id="middle1"><div id="inside" class="inside"></div></div>
433 </div> 441 </div>
434 <div id="sibling"> 442 <div id="sibling">
435 <div id="tohide">to hide</div> 443 <div id="tohide">to hide</div>
436 </div> 444 </div>
437 <div id="sibling2"> 445 <div id="sibling2">
438 <div id="sibling21"><div id="sibling211" class="inside"></div></div> 446 <div id="sibling21"><div id="sibling211" class="inside"></div></div>
439 </div> 447 </div>
440 </div>`; 448 </div>`;
441 let parent = document.getElementById("parent"); 449 let parent = testDocument.getElementById("parent");
442 let middle = document.getElementById("middle"); 450 let middle = testDocument.getElementById("middle");
443 let inside = document.getElementById("inside"); 451 let inside = testDocument.getElementById("inside");
444 let sibling = document.getElementById("sibling"); 452 let sibling = testDocument.getElementById("sibling");
445 let sibling2 = document.getElementById("sibling2"); 453 let sibling2 = testDocument.getElementById("sibling2");
446 let toHide = document.getElementById("tohide"); 454 let toHide = testDocument.getElementById("tohide");
447 455
448 applyElemHideEmulation( 456 applyElemHideEmulation(
449 ["#parent div:-abp-contains(to hide)"] 457 ["#parent div:-abp-contains(to hide)"]
450 ).then(() => 458 ).then(() =>
451 { 459 {
452 expectVisible(test, parent); 460 expectVisible(test, parent);
453 expectVisible(test, middle); 461 expectVisible(test, middle);
454 expectVisible(test, inside); 462 expectVisible(test, inside);
455 expectHidden(test, sibling); 463 expectHidden(test, sibling);
456 expectVisible(test, sibling2); 464 expectVisible(test, sibling2);
(...skipping 20 matching lines...) Expand all
477 let child = createElementWithStyle("{}", parent); 485 let child = createElementWithStyle("{}", parent);
478 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); 486 insertStyleRule("body #" + parent.id + " > div { background-color: #000}");
479 applyElemHideEmulation( 487 applyElemHideEmulation(
480 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] 488 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"]
481 ).then(() => 489 ).then(() =>
482 { 490 {
483 expectVisible(test, child); 491 expectVisible(test, child);
484 expectHidden(test, parent); 492 expectHidden(test, parent);
485 }).catch(unexpectedError.bind(test)).then(() => test.done()); 493 }).catch(unexpectedError.bind(test)).then(() => test.done());
486 }; 494 };
495
496 exports.testDomUpdatesStyle = function(test)
497 {
498 let parent = createElementWithStyle("{}");
499 let child = createElementWithStyle("{}", parent);
500 applyElemHideEmulation(
501 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"]
502 ).then(() =>
503 {
504 expectVisible(test, child);
505 expectVisible(test, parent);
506
507 insertStyleRule("body #" + parent.id + " > div { background-color: #000}");
508
509 return new Promise((resolve, reject) =>
510 {
511 expectVisible(test, child);
512 expectVisible(test, parent);
513 window.setTimeout(() =>
514 {
515 expectVisible(test, child);
516 expectHidden(test, parent);
517 resolve();
518 }, 4000);
519 });
Wladimir Palant 2017/08/23 13:23:32 Please use a helper to promisify timeouts: func
hub 2017/08/23 16:38:00 Done.
520 }).catch(unexpectedError.bind(test)).then(() => test.done());
521 };
522
523 exports.testDomUpdatesContent = function(test)
524 {
525 let parent = createElementWithStyle("{}");
526 let child = createElementWithStyle("{}", parent);
527 applyElemHideEmulation(
528 ["div > div:-abp-contains(hide me)"]
529 ).then(() =>
530 {
531 expectVisible(test, parent);
532 expectVisible(test, child);
533
534 child.innerText = "hide me";
Wladimir Palant 2017/08/23 13:23:32 Please use child.textContent, innerText is non-sta
hub 2017/08/23 16:38:00 Done.
535 return new Promise((resolve, reject) =>
536 {
537 expectVisible(test, parent);
538 expectVisible(test, child);
539 window.setTimeout(() =>
540 {
541 expectVisible(test, parent);
542 expectHidden(test, child);
543 resolve();
544 }, 4000);
545 });
546 }).catch(unexpectedError.bind(test)).then(() => test.done());
547 };
548
549 exports.testDomUpdatesNewElement = function(test)
550 {
551 let parent = createElementWithStyle("{}");
552 let child = createElementWithStyle("{ background-color: #000}", parent);
553 applyElemHideEmulation(
554 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"]
555 ).then(() =>
556 {
557 expectHidden(test, parent);
558 expectVisible(test, child);
559
560 let sibling = createElementWithStyle("{}");
561 expectVisible(test, sibling);
562
563 return new Promise((resolve, reject) =>
564 {
565 expectHidden(test, parent);
566 expectVisible(test, child);
567 expectVisible(test, sibling);
568 window.setTimeout(() =>
569 {
570 expectHidden(test, parent);
571 expectVisible(test, child);
572 expectVisible(test, sibling);
573
574 let child2 = createElementWithStyle("{ background-color: #000}",
575 sibling);
576 expectVisible(test, child2);
577 window.setTimeout(() =>
578 {
579 expectHidden(test, parent);
580 expectVisible(test, child);
581 expectHidden(test, sibling);
582 expectVisible(test, child2);
583
584 resolve();
585 }, 4000);
586 }, 4000);
Wladimir Palant 2017/08/23 13:23:32 The huge delays here are an issue. We need to chan
hub 2017/08/23 16:38:00 IMHO the best approach would be to have it configu
587 });
588 }).catch(unexpectedError.bind(test)).then(() => test.done());
589 };
OLDNEW
« no previous file with comments | « lib/content/elemHideEmulation.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld