Index: test/browser/elemHideEmulation.js |
=================================================================== |
--- a/test/browser/elemHideEmulation.js |
+++ b/test/browser/elemHideEmulation.js |
@@ -14,29 +14,46 @@ |
* You should have received a copy of the GNU General Public License |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
*/ |
"use strict"; |
const {ElemHideEmulation} = require("../../lib/content/elemHideEmulation"); |
-exports.tearDown = function(callback) |
+const REFRESH_INTERVAL = 200; |
+ |
+let testDocument = null; |
+ |
+exports.setUp = function(callback) |
{ |
- let styleElements = document.head.getElementsByTagName("style"); |
- while (styleElements.length) |
- styleElements[0].parentNode.removeChild(styleElements[0]); |
- |
- let child; |
- while (child = document.body.firstChild) |
- child.parentNode.removeChild(child); |
+ let iframe = document.createElement("iframe"); |
+ document.body.appendChild(iframe); |
+ testDocument = iframe.contentDocument; |
callback(); |
}; |
+exports.tearDown = function(callback) |
+{ |
+ let iframe = testDocument.defaultView.frameElement; |
+ iframe.parentNode.removeChild(iframe); |
+ testDocument = null; |
+ |
+ callback(); |
+}; |
+ |
+function timeout(delay) |
+{ |
+ return new Promise((resolve, reject) => |
+ { |
+ window.setTimeout(resolve, delay); |
+ }); |
+} |
+ |
function unexpectedError(error) |
{ |
console.error(error); |
this.ok(false, "Unexpected error: " + error); |
} |
function expectHidden(test, element) |
{ |
@@ -48,56 +65,56 @@ |
{ |
test.notEqual(window.getComputedStyle(element).display, "none", |
"The element's display property should not be set to 'none'"); |
} |
function findUniqueId() |
{ |
let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000); |
- if (!document.getElementById(id)) |
+ if (!testDocument.getElementById(id)) |
return id; |
return findUniqueId(); |
} |
function insertStyleRule(rule) |
{ |
let styleElement; |
- let styleElements = document.head.getElementsByTagName("style"); |
+ let styleElements = testDocument.head.getElementsByTagName("style"); |
if (styleElements.length) |
styleElement = styleElements[0]; |
else |
{ |
- styleElement = document.createElement("style"); |
- document.head.appendChild(styleElement); |
+ styleElement = testDocument.createElement("style"); |
+ testDocument.head.appendChild(styleElement); |
} |
styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length); |
} |
// Insert a <div> with a unique id and a CSS rule |
// for the the selector matching the id. |
function createElementWithStyle(styleBlock, parent) |
{ |
- let element = document.createElement("div"); |
+ let element = testDocument.createElement("div"); |
element.id = findUniqueId(); |
if (!parent) |
- document.body.appendChild(element); |
+ testDocument.body.appendChild(element); |
else |
parent.appendChild(element); |
insertStyleRule("#" + element.id + " " + styleBlock); |
return element; |
} |
// Create a new ElemHideEmulation instance with @selectors. |
function applyElemHideEmulation(selectors) |
{ |
return Promise.resolve().then(() => |
{ |
let elemHideEmulation = new ElemHideEmulation( |
- window, |
+ testDocument.defaultView, |
callback => |
{ |
let patterns = []; |
selectors.forEach(selector => |
{ |
patterns.push({selector}); |
}); |
callback(patterns); |
@@ -111,16 +128,17 @@ |
}, |
elems => |
{ |
for (let elem of elems) |
elem.style.display = "none"; |
} |
); |
+ elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2; |
elemHideEmulation.apply(); |
return elemHideEmulation; |
}); |
} |
exports.testVerbatimPropertySelector = function(test) |
{ |
let toHide = createElementWithStyle("{background-color: #000}"); |
@@ -234,26 +252,26 @@ |
{ |
let toHide = createElementWithStyle("{}"); |
applyElemHideEmulation( |
[":-abp-properties(background-color: rgb(0, 0, 0))"] |
).then(() => |
{ |
expectVisible(test, toHide); |
insertStyleRule("#" + toHide.id + " {background-color: #000}"); |
- return new Promise((resolve, reject) => |
- { |
- // Re-evaluation will only happen after a few seconds |
- expectVisible(test, toHide); |
- window.setTimeout(() => |
- { |
- expectHidden(test, toHide); |
- resolve(); |
- }, 4000); |
- }); |
+ |
+ return timeout(0); |
+ }).then(() => |
+ { |
+ // Re-evaluation will only happen after a delay |
+ expectVisible(test, toHide); |
+ return timeout(REFRESH_INTERVAL); |
+ }).then(() => |
+ { |
+ expectHidden(test, toHide); |
}).catch(unexpectedError.bind(test)).then(() => test.done()); |
}; |
exports.testPseudoClassWithPropBeforeSelector = function(test) |
{ |
let parent = createElementWithStyle("{}"); |
let child = createElementWithStyle("{background-color: #000}", parent); |
insertStyleRule(`#${child.id}::before {content: "publicite"}`); |
@@ -341,34 +359,34 @@ |
expectVisible(test, middle); |
expectVisible(test, sibling); |
expectHidden(test, toHide); |
}).catch(unexpectedError.bind(test)).then(() => test.done()); |
}; |
function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector, expectations) |
{ |
- document.body.innerHTML = `<div id="parent"> |
+ testDocument.body.innerHTML = `<div id="parent"> |
<div id="middle"> |
<div id="middle1"><div id="inside" class="inside"></div></div> |
</div> |
<div id="sibling"> |
<div id="tohide">to hide</div> |
</div> |
<div id="sibling2"> |
<div id="sibling21"><div id="sibling211" class="inside"></div></div> |
</div> |
</div>`; |
let elems = { |
- parent: document.getElementById("parent"), |
- middle: document.getElementById("middle"), |
- inside: document.getElementById("inside"), |
- sibling: document.getElementById("sibling"), |
- sibling2: document.getElementById("sibling2"), |
- toHide: document.getElementById("tohide") |
+ parent: testDocument.getElementById("parent"), |
+ middle: testDocument.getElementById("middle"), |
+ inside: testDocument.getElementById("inside"), |
+ sibling: testDocument.getElementById("sibling"), |
+ sibling2: testDocument.getElementById("sibling2"), |
+ toHide: testDocument.getElementById("tohide") |
}; |
insertStyleRule(".inside {}"); |
applyElemHideEmulation( |
[selector] |
).then(() => |
{ |
@@ -422,33 +440,33 @@ |
toHide: true |
}; |
runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( |
test, "div:-abp-has(> body div.inside) + div > div", expectations); |
}; |
exports.testPseudoClassContains = function(test) |
{ |
- document.body.innerHTML = `<div id="parent"> |
+ testDocument.body.innerHTML = `<div id="parent"> |
<div id="middle"> |
<div id="middle1"><div id="inside" class="inside"></div></div> |
</div> |
<div id="sibling"> |
<div id="tohide">to hide</div> |
</div> |
<div id="sibling2"> |
<div id="sibling21"><div id="sibling211" class="inside"></div></div> |
</div> |
</div>`; |
- let parent = document.getElementById("parent"); |
- let middle = document.getElementById("middle"); |
- let inside = document.getElementById("inside"); |
- let sibling = document.getElementById("sibling"); |
- let sibling2 = document.getElementById("sibling2"); |
- let toHide = document.getElementById("tohide"); |
+ let parent = testDocument.getElementById("parent"); |
+ let middle = testDocument.getElementById("middle"); |
+ let inside = testDocument.getElementById("inside"); |
+ let sibling = testDocument.getElementById("sibling"); |
+ let sibling2 = testDocument.getElementById("sibling2"); |
+ let toHide = testDocument.getElementById("tohide"); |
applyElemHideEmulation( |
["#parent div:-abp-contains(to hide)"] |
).then(() => |
{ |
expectVisible(test, parent); |
expectVisible(test, middle); |
expectVisible(test, inside); |
@@ -479,8 +497,102 @@ |
applyElemHideEmulation( |
["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] |
).then(() => |
{ |
expectVisible(test, child); |
expectHidden(test, parent); |
}).catch(unexpectedError.bind(test)).then(() => test.done()); |
}; |
+ |
+exports.testDomUpdatesStyle = function(test) |
+{ |
+ let parent = createElementWithStyle("{}"); |
+ let child = createElementWithStyle("{}", parent); |
+ applyElemHideEmulation( |
+ ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] |
+ ).then(() => |
+ { |
+ expectVisible(test, child); |
+ expectVisible(test, parent); |
+ |
+ insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); |
+ return timeout(0); |
+ }).then(() => |
+ { |
+ expectVisible(test, child); |
+ expectVisible(test, parent); |
+ return timeout(REFRESH_INTERVAL); |
+ }).then(() => |
+ { |
+ expectVisible(test, child); |
+ expectHidden(test, parent); |
+ }).catch(unexpectedError.bind(test)).then(() => test.done()); |
+}; |
+ |
+exports.testDomUpdatesContent = function(test) |
+{ |
+ let parent = createElementWithStyle("{}"); |
+ let child = createElementWithStyle("{}", parent); |
+ applyElemHideEmulation( |
+ ["div > div:-abp-contains(hide me)"] |
+ ).then(() => |
+ { |
+ expectVisible(test, parent); |
+ expectVisible(test, child); |
+ |
+ child.textContent = "hide me"; |
+ return timeout(0); |
+ }).then(() => |
+ { |
+ expectVisible(test, parent); |
+ expectVisible(test, child); |
+ return timeout(REFRESH_INTERVAL); |
+ }).then(() => |
+ { |
+ expectVisible(test, parent); |
+ expectHidden(test, child); |
+ }).catch(unexpectedError.bind(test)).then(() => test.done()); |
+}; |
+ |
+exports.testDomUpdatesNewElement = function(test) |
+{ |
+ let parent = createElementWithStyle("{}"); |
+ let child = createElementWithStyle("{ background-color: #000}", parent); |
+ let sibling; |
+ let child2; |
+ applyElemHideEmulation( |
+ ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] |
+ ).then(() => |
+ { |
+ expectHidden(test, parent); |
+ expectVisible(test, child); |
+ |
+ sibling = createElementWithStyle("{}"); |
+ return timeout(0); |
+ }).then(() => |
+ { |
+ expectHidden(test, parent); |
+ expectVisible(test, child); |
+ expectVisible(test, sibling); |
+ |
+ return timeout(REFRESH_INTERVAL); |
+ }).then(() => |
+ { |
+ expectHidden(test, parent); |
+ expectVisible(test, child); |
+ expectVisible(test, sibling); |
+ |
+ child2 = createElementWithStyle("{ background-color: #000}", |
+ sibling); |
+ return timeout(0); |
+ }).then(() => |
+ { |
+ expectVisible(test, child2); |
+ return timeout(REFRESH_INTERVAL); |
+ }).then(() => |
+ { |
+ expectHidden(test, parent); |
+ expectVisible(test, child); |
+ expectHidden(test, sibling); |
+ expectVisible(test, child2); |
+ }).catch(unexpectedError.bind(test)).then(() => test.done()); |
+}; |