Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 const REFRESH_INTERVAL = 200; | |
23 | |
24 let testDocument = null; | |
25 | |
26 exports.setUp = function(callback) | |
27 { | |
28 let iframe = document.createElement("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 = testDocument.defaultView.frameElement; |
25 while (styleElements.length) | 38 iframe.parentNode.removeChild(iframe); |
26 styleElements[0].parentNode.removeChild(styleElements[0]); | 39 testDocument = null; |
27 | |
28 let child; | |
29 while (child = document.body.firstChild) | |
30 child.parentNode.removeChild(child); | |
31 | 40 |
32 callback(); | 41 callback(); |
33 }; | 42 }; |
43 | |
44 function timeout(delay) | |
45 { | |
46 return new Promise((resolve, reject) => | |
47 { | |
48 window.setTimeout(resolve, delay); | |
49 }); | |
50 } | |
34 | 51 |
35 function unexpectedError(error) | 52 function unexpectedError(error) |
36 { | 53 { |
37 console.error(error); | 54 console.error(error); |
38 this.ok(false, "Unexpected error: " + error); | 55 this.ok(false, "Unexpected error: " + error); |
39 } | 56 } |
40 | 57 |
41 function expectHidden(test, element) | 58 function expectHidden(test, element) |
42 { | 59 { |
43 test.equal(window.getComputedStyle(element).display, "none", | 60 test.equal(window.getComputedStyle(element).display, "none", |
44 "The element's display property should be set to 'none'"); | 61 "The element's display property should be set to 'none'"); |
45 } | 62 } |
46 | 63 |
47 function expectVisible(test, element) | 64 function expectVisible(test, element) |
48 { | 65 { |
49 test.notEqual(window.getComputedStyle(element).display, "none", | 66 test.notEqual(window.getComputedStyle(element).display, "none", |
50 "The element's display property should not be set to 'none'"); | 67 "The element's display property should not be set to 'none'"); |
51 } | 68 } |
52 | 69 |
53 function findUniqueId() | 70 function findUniqueId() |
54 { | 71 { |
55 let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000); | 72 let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000); |
56 if (!document.getElementById(id)) | 73 if (!testDocument.getElementById(id)) |
57 return id; | 74 return id; |
58 return findUniqueId(); | 75 return findUniqueId(); |
59 } | 76 } |
60 | 77 |
61 function insertStyleRule(rule) | 78 function insertStyleRule(rule) |
62 { | 79 { |
63 let styleElement; | 80 let styleElement; |
64 let styleElements = document.head.getElementsByTagName("style"); | 81 let styleElements = testDocument.head.getElementsByTagName("style"); |
65 if (styleElements.length) | 82 if (styleElements.length) |
66 styleElement = styleElements[0]; | 83 styleElement = styleElements[0]; |
67 else | 84 else |
68 { | 85 { |
69 styleElement = document.createElement("style"); | 86 styleElement = testDocument.createElement("style"); |
70 document.head.appendChild(styleElement); | 87 testDocument.head.appendChild(styleElement); |
71 } | 88 } |
72 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length); | 89 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length); |
73 } | 90 } |
74 | 91 |
75 // Insert a <div> with a unique id and a CSS rule | 92 // Insert a <div> with a unique id and a CSS rule |
76 // for the the selector matching the id. | 93 // for the the selector matching the id. |
77 function createElementWithStyle(styleBlock, parent) | 94 function createElementWithStyle(styleBlock, parent) |
78 { | 95 { |
79 let element = document.createElement("div"); | 96 let element = testDocument.createElement("div"); |
80 element.id = findUniqueId(); | 97 element.id = findUniqueId(); |
81 if (!parent) | 98 if (!parent) |
82 document.body.appendChild(element); | 99 testDocument.body.appendChild(element); |
83 else | 100 else |
84 parent.appendChild(element); | 101 parent.appendChild(element); |
85 insertStyleRule("#" + element.id + " " + styleBlock); | 102 insertStyleRule("#" + element.id + " " + styleBlock); |
86 return element; | 103 return element; |
87 } | 104 } |
88 | 105 |
89 // Create a new ElemHideEmulation instance with @selectors. | 106 // Create a new ElemHideEmulation instance with @selectors. |
90 function applyElemHideEmulation(selectors) | 107 function applyElemHideEmulation(selectors) |
91 { | 108 { |
92 return Promise.resolve().then(() => | 109 return Promise.resolve().then(() => |
93 { | 110 { |
94 let elemHideEmulation = new ElemHideEmulation( | 111 let elemHideEmulation = new ElemHideEmulation( |
95 window, | 112 testDocument.defaultView, |
96 callback => | 113 callback => |
97 { | 114 { |
98 let patterns = []; | 115 let patterns = []; |
99 selectors.forEach(selector => | 116 selectors.forEach(selector => |
100 { | 117 { |
101 patterns.push({selector}); | 118 patterns.push({selector}); |
102 }); | 119 }); |
103 callback(patterns); | 120 callback(patterns); |
104 }, | 121 }, |
105 newSelectors => | 122 newSelectors => |
106 { | 123 { |
107 if (!newSelectors.length) | 124 if (!newSelectors.length) |
108 return; | 125 return; |
109 let selector = newSelectors.join(", "); | 126 let selector = newSelectors.join(", "); |
110 insertStyleRule(selector + "{display: none !important;}"); | 127 insertStyleRule(selector + "{display: none !important;}"); |
111 }, | 128 }, |
112 elems => | 129 elems => |
113 { | 130 { |
114 for (let elem of elems) | 131 for (let elem of elems) |
115 elem.style.display = "none"; | 132 elem.style.display = "none"; |
116 } | 133 } |
117 ); | 134 ); |
118 | 135 |
136 elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2; | |
119 elemHideEmulation.apply(); | 137 elemHideEmulation.apply(); |
120 return elemHideEmulation; | 138 return elemHideEmulation; |
121 }); | 139 }); |
122 } | 140 } |
123 | 141 |
124 exports.testVerbatimPropertySelector = function(test) | 142 exports.testVerbatimPropertySelector = function(test) |
125 { | 143 { |
126 let toHide = createElementWithStyle("{background-color: #000}"); | 144 let toHide = createElementWithStyle("{background-color: #000}"); |
127 applyElemHideEmulation( | 145 applyElemHideEmulation( |
128 [":-abp-properties(background-color: rgb(0, 0, 0))"] | 146 [":-abp-properties(background-color: rgb(0, 0, 0))"] |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 | 250 |
233 exports.testDynamicallyChangedProperty = function(test) | 251 exports.testDynamicallyChangedProperty = function(test) |
234 { | 252 { |
235 let toHide = createElementWithStyle("{}"); | 253 let toHide = createElementWithStyle("{}"); |
236 applyElemHideEmulation( | 254 applyElemHideEmulation( |
237 [":-abp-properties(background-color: rgb(0, 0, 0))"] | 255 [":-abp-properties(background-color: rgb(0, 0, 0))"] |
238 ).then(() => | 256 ).then(() => |
239 { | 257 { |
240 expectVisible(test, toHide); | 258 expectVisible(test, toHide); |
241 insertStyleRule("#" + toHide.id + " {background-color: #000}"); | 259 insertStyleRule("#" + toHide.id + " {background-color: #000}"); |
242 return new Promise((resolve, reject) => | 260 |
243 { | 261 return timeout(0); |
244 // Re-evaluation will only happen after a few seconds | 262 }).then(() => |
245 expectVisible(test, toHide); | 263 { |
246 window.setTimeout(() => | 264 // Re-evaluation will only happen after a delay |
247 { | 265 expectVisible(test, toHide); |
248 expectHidden(test, toHide); | 266 return timeout(REFRESH_INTERVAL); |
249 resolve(); | 267 }).then(() => |
250 }, 4000); | 268 { |
251 }); | 269 expectHidden(test, toHide); |
252 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 270 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
253 }; | 271 }; |
254 | 272 |
255 exports.testPseudoClassWithPropBeforeSelector = function(test) | 273 exports.testPseudoClassWithPropBeforeSelector = function(test) |
256 { | 274 { |
257 let parent = createElementWithStyle("{}"); | 275 let parent = createElementWithStyle("{}"); |
258 let child = createElementWithStyle("{background-color: #000}", parent); | 276 let child = createElementWithStyle("{background-color: #000}", parent); |
259 insertStyleRule(`#${child.id}::before {content: "publicite"}`); | 277 insertStyleRule(`#${child.id}::before {content: "publicite"}`); |
260 | 278 |
261 applyElemHideEmulation( | 279 applyElemHideEmulation( |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 { | 357 { |
340 expectVisible(test, parent); | 358 expectVisible(test, parent); |
341 expectVisible(test, middle); | 359 expectVisible(test, middle); |
342 expectVisible(test, sibling); | 360 expectVisible(test, sibling); |
343 expectHidden(test, toHide); | 361 expectHidden(test, toHide); |
344 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 362 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
345 }; | 363 }; |
346 | 364 |
347 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector , expectations) | 365 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector , expectations) |
348 { | 366 { |
349 document.body.innerHTML = `<div id="parent"> | 367 testDocument.body.innerHTML = `<div id="parent"> |
350 <div id="middle"> | 368 <div id="middle"> |
351 <div id="middle1"><div id="inside" class="inside"></div></div> | 369 <div id="middle1"><div id="inside" class="inside"></div></div> |
352 </div> | 370 </div> |
353 <div id="sibling"> | 371 <div id="sibling"> |
354 <div id="tohide">to hide</div> | 372 <div id="tohide">to hide</div> |
355 </div> | 373 </div> |
356 <div id="sibling2"> | 374 <div id="sibling2"> |
357 <div id="sibling21"><div id="sibling211" class="inside"></div></div> | 375 <div id="sibling21"><div id="sibling211" class="inside"></div></div> |
358 </div> | 376 </div> |
359 </div>`; | 377 </div>`; |
360 let elems = { | 378 let elems = { |
361 parent: document.getElementById("parent"), | 379 parent: testDocument.getElementById("parent"), |
362 middle: document.getElementById("middle"), | 380 middle: testDocument.getElementById("middle"), |
363 inside: document.getElementById("inside"), | 381 inside: testDocument.getElementById("inside"), |
364 sibling: document.getElementById("sibling"), | 382 sibling: testDocument.getElementById("sibling"), |
365 sibling2: document.getElementById("sibling2"), | 383 sibling2: testDocument.getElementById("sibling2"), |
366 toHide: document.getElementById("tohide") | 384 toHide: testDocument.getElementById("tohide") |
367 }; | 385 }; |
368 | 386 |
369 insertStyleRule(".inside {}"); | 387 insertStyleRule(".inside {}"); |
370 | 388 |
371 applyElemHideEmulation( | 389 applyElemHideEmulation( |
372 [selector] | 390 [selector] |
373 ).then(() => | 391 ).then(() => |
374 { | 392 { |
375 for (let elem in expectations) | 393 for (let elem in expectations) |
376 if (elems[elem]) | 394 if (elems[elem]) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
420 sibling: true, | 438 sibling: true, |
421 sibling2: true, | 439 sibling2: true, |
422 toHide: true | 440 toHide: true |
423 }; | 441 }; |
424 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( | 442 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( |
425 test, "div:-abp-has(> body div.inside) + div > div", expectations); | 443 test, "div:-abp-has(> body div.inside) + div > div", expectations); |
426 }; | 444 }; |
427 | 445 |
428 exports.testPseudoClassContains = function(test) | 446 exports.testPseudoClassContains = function(test) |
429 { | 447 { |
430 document.body.innerHTML = `<div id="parent"> | 448 testDocument.body.innerHTML = `<div id="parent"> |
431 <div id="middle"> | 449 <div id="middle"> |
432 <div id="middle1"><div id="inside" class="inside"></div></div> | 450 <div id="middle1"><div id="inside" class="inside"></div></div> |
433 </div> | 451 </div> |
434 <div id="sibling"> | 452 <div id="sibling"> |
435 <div id="tohide">to hide</div> | 453 <div id="tohide">to hide</div> |
436 </div> | 454 </div> |
437 <div id="sibling2"> | 455 <div id="sibling2"> |
438 <div id="sibling21"><div id="sibling211" class="inside"></div></div> | 456 <div id="sibling21"><div id="sibling211" class="inside"></div></div> |
439 </div> | 457 </div> |
440 </div>`; | 458 </div>`; |
441 let parent = document.getElementById("parent"); | 459 let parent = testDocument.getElementById("parent"); |
442 let middle = document.getElementById("middle"); | 460 let middle = testDocument.getElementById("middle"); |
443 let inside = document.getElementById("inside"); | 461 let inside = testDocument.getElementById("inside"); |
444 let sibling = document.getElementById("sibling"); | 462 let sibling = testDocument.getElementById("sibling"); |
445 let sibling2 = document.getElementById("sibling2"); | 463 let sibling2 = testDocument.getElementById("sibling2"); |
446 let toHide = document.getElementById("tohide"); | 464 let toHide = testDocument.getElementById("tohide"); |
447 | 465 |
448 applyElemHideEmulation( | 466 applyElemHideEmulation( |
449 ["#parent div:-abp-contains(to hide)"] | 467 ["#parent div:-abp-contains(to hide)"] |
450 ).then(() => | 468 ).then(() => |
451 { | 469 { |
452 expectVisible(test, parent); | 470 expectVisible(test, parent); |
453 expectVisible(test, middle); | 471 expectVisible(test, middle); |
454 expectVisible(test, inside); | 472 expectVisible(test, inside); |
455 expectHidden(test, sibling); | 473 expectHidden(test, sibling); |
456 expectVisible(test, sibling2); | 474 expectVisible(test, sibling2); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 let parent = createElementWithStyle("{}"); | 508 let parent = createElementWithStyle("{}"); |
491 let child = createElementWithStyle("{}", parent); | 509 let child = createElementWithStyle("{}", parent); |
492 applyElemHideEmulation( | 510 applyElemHideEmulation( |
493 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] | 511 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] |
494 ).then(() => | 512 ).then(() => |
495 { | 513 { |
496 expectVisible(test, child); | 514 expectVisible(test, child); |
497 expectVisible(test, parent); | 515 expectVisible(test, parent); |
498 | 516 |
499 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); | 517 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); |
500 | 518 return timeout(0); |
501 return new Promise((resolve, reject) => | 519 }).then(() => |
502 { | 520 { |
503 expectVisible(test, child); | 521 expectVisible(test, child); |
504 expectVisible(test, parent); | 522 expectVisible(test, parent); |
505 window.setTimeout(() => | 523 return timeout(REFRESH_INTERVAL); |
506 { | 524 }).then(() => |
507 //expectVisible(test, child); | 525 { |
hub
2017/08/23 01:11:31
This is where test are running into problems. This
| |
508 expectHidden(test, parent); | 526 expectVisible(test, child); |
509 resolve(); | 527 expectHidden(test, parent); |
510 }, 4000); | |
511 }); | |
512 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 528 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
513 }; | 529 }; |
514 | 530 |
515 exports.testDomUpdatesContent = function(test) | 531 exports.testDomUpdatesContent = function(test) |
516 { | 532 { |
517 let parent = createElementWithStyle("{}"); | 533 let parent = createElementWithStyle("{}"); |
518 let child = createElementWithStyle("{}", parent); | 534 let child = createElementWithStyle("{}", parent); |
519 applyElemHideEmulation( | 535 applyElemHideEmulation( |
520 ["div:-abp-contains(hide me)"] | 536 ["div > div:-abp-contains(hide me)"] |
521 ).then(() => | 537 ).then(() => |
522 { | 538 { |
523 expectVisible(test, parent); | 539 expectVisible(test, parent); |
524 expectVisible(test, child); | 540 expectVisible(test, child); |
525 | 541 |
526 child.innerText = "hide me"; | 542 child.textContent = "hide me"; |
527 return new Promise((resolve, reject) => | 543 return timeout(0); |
528 { | 544 }).then(() => |
529 expectVisible(test, parent); | 545 { |
530 expectVisible(test, child); | 546 expectVisible(test, parent); |
531 window.setTimeout(() => | 547 expectVisible(test, child); |
532 { | 548 return timeout(REFRESH_INTERVAL); |
533 expectVisible(test, parent); | 549 }).then(() => |
hub
2017/08/23 01:11:31
This one not commented out fail.
| |
534 expectHidden(test, child); | 550 { |
535 resolve(); | 551 expectVisible(test, parent); |
536 }, 4000); | 552 expectHidden(test, child); |
537 }); | |
538 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 553 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
539 }; | 554 }; |
540 | 555 |
541 exports.testDomUpdatesNewElement = function(test) | 556 exports.testDomUpdatesNewElement = function(test) |
542 { | 557 { |
543 let parent = createElementWithStyle("{}"); | 558 let parent = createElementWithStyle("{}"); |
544 let child = createElementWithStyle("{ background-color: #000}", parent); | 559 let child = createElementWithStyle("{ background-color: #000}", parent); |
560 let sibling; | |
561 let child2; | |
545 applyElemHideEmulation( | 562 applyElemHideEmulation( |
546 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] | 563 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] |
547 ).then(() => | 564 ).then(() => |
548 { | 565 { |
549 expectHidden(test, parent); | 566 expectHidden(test, parent); |
550 expectVisible(test, child); | 567 expectVisible(test, child); |
551 | 568 |
552 let sibling = createElementWithStyle("{}"); | 569 sibling = createElementWithStyle("{}"); |
570 return timeout(0); | |
571 }).then(() => | |
572 { | |
573 expectHidden(test, parent); | |
574 expectVisible(test, child); | |
553 expectVisible(test, sibling); | 575 expectVisible(test, sibling); |
554 | 576 |
555 return new Promise((resolve, reject) => | 577 return timeout(REFRESH_INTERVAL); |
556 { | 578 }).then(() => |
557 expectHidden(test, parent); | 579 { |
558 expectVisible(test, child); | 580 expectHidden(test, parent); |
559 expectVisible(test, sibling); | 581 expectVisible(test, child); |
560 window.setTimeout(() => | 582 expectVisible(test, sibling); |
561 { | 583 |
562 expectHidden(test, parent); | 584 child2 = createElementWithStyle("{ background-color: #000}", |
563 //expectVisible(test, child); | 585 sibling); |
564 //expectVisible(test, sibling); | 586 return timeout(0); |
565 | 587 }).then(() => |
566 let child2 = createElementWithStyle("{ background-color: #000}", | 588 { |
567 sibling); | 589 expectVisible(test, child2); |
568 expectVisible(test, child2); | 590 return timeout(REFRESH_INTERVAL); |
569 window.setTimeout(() => | 591 }).then(() => |
570 { | 592 { |
571 expectHidden(test, parent); | 593 expectHidden(test, parent); |
572 //expectVisible(test, child); | 594 expectVisible(test, child); |
573 expectHidden(test, sibling); | 595 expectHidden(test, sibling); |
574 //expectVisible(test, child2); | 596 expectVisible(test, child2); |
575 | 597 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
576 resolve(); | 598 }; |
577 }, 4000); | |
578 }, 4000); | |
579 }); | |
580 }).catch(unexpectedError.bind(test)).then(() => test.done()); | |
581 }; | |
LEFT | RIGHT |