Left: | ||
Right: |
OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 }; | |
OLD | NEW |