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

Unified 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.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/browser/_bootstrap.js ('k') | test/browser/snippets.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/browser/elemHideEmulation.js
===================================================================
--- a/test/browser/elemHideEmulation.js
+++ b/test/browser/elemHideEmulation.js
@@ -10,1123 +10,1089 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
*/
+/* global assert */
+
"use strict";
const {ElemHideEmulation, setTestMode,
getTestInfo} = require("../../lib/content/elemHideEmulation");
const {timeout} = require("./_utils");
-const REFRESH_INTERVAL = 200;
-
-let testDocument = null;
-
-exports.setUp = function(callback)
-{
- setTestMode();
-
- 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 unexpectedError(test, error)
-{
- console.error(error);
- test.ok(false, "Unexpected error: " + error);
-}
-
-function expectHidden(test, element, id)
-{
- let withId = "";
- if (typeof id != "undefined")
- withId = ` with ID '${id}'`;
-
- test.equal(
- window.getComputedStyle(element).display, "none",
- `The element${withId}'s display property should be set to 'none'`);
-}
-
-function expectVisible(test, element, id)
-{
- let withId = "";
- if (typeof id != "undefined")
- withId = ` with ID '${id}'`;
-
- test.notEqual(
- window.getComputedStyle(element).display, "none",
- `The element${withId}'s display property should not be set to 'none'`);
-}
-
-function expectProcessed(test, element, id = null)
-{
- let withId = "";
- if (id)
- withId = ` with ID '${id}'`;
-
- test.ok(
- getTestInfo().lastProcessedElements.has(element),
- `The element${withId} should have been processed`);
-}
-
-function expectNotProcessed(test, element, id = null)
-{
- let withId = "";
- if (id)
- withId = ` with ID '${id}'`;
-
- test.ok(
- !getTestInfo().lastProcessedElements.has(element),
- `The element${withId} should not have been processed`);
-}
-
-function findUniqueId()
-{
- let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000);
- if (!testDocument.getElementById(id))
- return id;
- return findUniqueId();
-}
-
-function insertStyleRule(rule)
+describe("Element Hiding Emulation", () =>
{
- let styleElement;
- let styleElements = testDocument.head.getElementsByTagName("style");
- if (styleElements.length)
- styleElement = styleElements[0];
- else
- {
- styleElement = testDocument.createElement("style");
- testDocument.head.appendChild(styleElement);
- }
- styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length);
-}
+ const REFRESH_INTERVAL = 200;
-function createElement(parent, type = "div", id = findUniqueId(),
- innerText = null)
-{
- let element = testDocument.createElement(type);
- element.id = id;
- if (!parent)
- testDocument.body.appendChild(element);
- else
- parent.appendChild(element);
- if (innerText)
- element.innerText = innerText;
- return element;
-}
+ let testDocument = null;
-// Insert a <div> with a unique id and a CSS rule
-// for the the selector matching the id.
-function createElementWithStyle(styleBlock, parent)
-{
- let element = createElement(parent);
- insertStyleRule("#" + element.id + " " + styleBlock);
- return element;
-}
-
-// Create a new ElemHideEmulation instance with @selectors.
-async function applyElemHideEmulation(test, selectors)
-{
- await Promise.resolve();
-
- try
+ beforeEach(() =>
{
- let elemHideEmulation = new ElemHideEmulation(
- elems =>
- {
- for (let elem of elems)
- elem.style.display = "none";
- }
- );
+ setTestMode();
- elemHideEmulation.document = testDocument;
- elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2;
- elemHideEmulation.apply(selectors.map(
- selector => ({selector, text: selector})
- ));
-
- return elemHideEmulation;
- }
- catch (error)
- {
- unexpectedError(test, error);
- }
-}
+ let iframe = document.createElement("iframe");
+ document.body.appendChild(iframe);
+ testDocument = iframe.contentDocument;
+ });
-exports.testVerbatimPropertySelector = async function(test)
-{
- let toHide = createElementWithStyle("{background-color: #000}");
- let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
-
- if (await applyElemHideEmulation(test, selectors))
- expectHidden(test, toHide);
-
- test.done();
-};
+ afterEach(() =>
+ {
+ let iframe = testDocument.defaultView.frameElement;
+ iframe.parentNode.removeChild(iframe);
+ testDocument = null;
+ });
-exports.testVerbatimPropertySelectorWithPrefix = async function(test)
-{
- let parent = createElementWithStyle("{background-color: #000}");
- let toHide = createElementWithStyle("{background-color: #000}", parent);
-
- let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"];
-
- if (await applyElemHideEmulation(test, selectors))
+ function unexpectedError(error)
{
- expectVisible(test, parent);
- expectHidden(test, toHide);
+ console.error(error);
+ assert.ok(false, "Unexpected error: " + error);
}
- test.done();
-};
+ function expectHidden(element, id)
+ {
+ let withId = "";
+ if (typeof id != "undefined")
+ withId = ` with ID '${id}'`;
+
+ assert.equal(
+ window.getComputedStyle(element).display, "none",
+ `The element${withId}'s display property should be set to 'none'`);
+ }
+
+ function expectVisible(element, id)
+ {
+ let withId = "";
+ if (typeof id != "undefined")
+ withId = ` with ID '${id}'`;
-exports.testVerbatimPropertySelectorWithPrefixNoMatch = async function(test)
-{
- let parent = createElementWithStyle("{background-color: #000}");
- let toHide = createElementWithStyle("{background-color: #fff}", parent);
+ assert.notEqual(
+ window.getComputedStyle(element).display, "none",
+ `The element${withId}'s display property should not be set to 'none'`);
+ }
+
+ function expectProcessed(element, id = null)
+ {
+ let withId = "";
+ if (id)
+ withId = ` with ID '${id}'`;
- let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"];
+ assert.ok(
+ getTestInfo().lastProcessedElements.has(element),
+ `The element${withId} should have been processed`);
+ }
- if (await applyElemHideEmulation(test, selectors))
+ function expectNotProcessed(element, id = null)
{
- expectVisible(test, parent);
- expectVisible(test, toHide);
+ let withId = "";
+ if (id)
+ withId = ` with ID '${id}'`;
+
+ assert.ok(
+ !getTestInfo().lastProcessedElements.has(element),
+ `The element${withId} should not have been processed`);
}
- test.done();
-};
-
-exports.testVerbatimPropertySelectorWithSuffix = async function(test)
-{
- let parent = createElementWithStyle("{background-color: #000}");
- let toHide = createElementWithStyle("{background-color: #000}", parent);
-
- let selectors = [":-abp-properties(background-color: rgb(0, 0, 0)) > div"];
-
- if (await applyElemHideEmulation(test, selectors))
+ function findUniqueId()
{
- expectVisible(test, parent);
- expectHidden(test, toHide);
- }
-
- test.done();
-};
-
-exports.testVerbatimPropertyPseudoSelectorWithPrefixAndSuffix = async function(test)
-{
- let parent = createElementWithStyle("{background-color: #000}");
- let middle = createElementWithStyle("{background-color: #000}", parent);
- let toHide = createElementWithStyle("{background-color: #000}", middle);
-
- let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0)) > div"];
-
- if (await applyElemHideEmulation(test, selectors))
- {
- expectVisible(test, parent);
- expectVisible(test, middle);
- expectHidden(test, toHide);
+ let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000);
+ if (!testDocument.getElementById(id))
+ return id;
+ return findUniqueId();
}
- test.done();
-};
-
-// Add the style. Then add the element for that style.
-// This should retrigger the filtering and hide it.
-exports.testPropertyPseudoSelectorAddStyleAndElement = async function(test)
-{
- let styleElement;
- let toHide;
-
- let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
-
- if (await applyElemHideEmulation(test, selectors))
+ function insertStyleRule(rule)
{
- styleElement = testDocument.createElement("style");
- testDocument.head.appendChild(styleElement);
- styleElement.sheet.insertRule("#toHide {background-color: #000}");
- await timeout(REFRESH_INTERVAL);
-
- toHide = createElement();
- toHide.id = "toHide";
- expectVisible(test, toHide);
- await timeout(REFRESH_INTERVAL);
-
- expectHidden(test, toHide);
+ let styleElement;
+ let styleElements = testDocument.head.getElementsByTagName("style");
+ if (styleElements.length)
+ styleElement = styleElements[0];
+ else
+ {
+ styleElement = testDocument.createElement("style");
+ testDocument.head.appendChild(styleElement);
+ }
+ styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length);
}
- test.done();
-};
-
-exports.testPropertySelectorWithWildcard = async function(test)
-{
- let toHide = createElementWithStyle("{background-color: #000}");
- let selectors = [":-abp-properties(*color: rgb(0, 0, 0))"];
-
- if (await applyElemHideEmulation(test, selectors))
- expectHidden(test, toHide);
-
- test.done();
-};
-
-exports.testPropertySelectorWithRegularExpression = async function(test)
-{
- let toHide = createElementWithStyle("{background-color: #000}");
- let selectors = [":-abp-properties(/.*color: rgb\\(0, 0, 0\\)/)"];
-
- if (await applyElemHideEmulation(test, selectors))
- expectHidden(test, toHide);
-
- test.done();
-};
-
-exports.testDynamicallyChangedProperty = async function(test)
-{
- let toHide = createElementWithStyle("{}");
- let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
-
- if (await applyElemHideEmulation(test, selectors))
+ function createElement(parent, type = "div", id = findUniqueId(),
+ innerText = null)
{
- expectVisible(test, toHide);
- insertStyleRule("#" + toHide.id + " {background-color: #000}");
-
- await timeout(0);
-
- // Re-evaluation will only happen after a delay
- expectVisible(test, toHide);
- await timeout(REFRESH_INTERVAL);
-
- expectHidden(test, toHide);
+ let element = testDocument.createElement(type);
+ element.id = id;
+ if (!parent)
+ testDocument.body.appendChild(element);
+ else
+ parent.appendChild(element);
+ if (innerText)
+ element.innerText = innerText;
+ return element;
}
- test.done();
-};
-
-exports.testPseudoClassWithPropBeforeSelector = async function(test)
-{
- let parent = createElementWithStyle("{}");
- let child = createElementWithStyle("{background-color: #000}", parent);
-
- let selectors = ["div:-abp-properties(content: \"publicite\")"];
-
- insertStyleRule(`#${child.id}::before {content: "publicite"}`);
-
- if (await applyElemHideEmulation(test, selectors))
+ // Insert a <div> with a unique id and a CSS rule
+ // for the the selector matching the id.
+ function createElementWithStyle(styleBlock, parent)
{
- expectHidden(test, child);
- expectVisible(test, parent);
- }
-
- test.done();
-};
-
-exports.testPseudoClassHasSelector = async function(test)
-{
- let toHide = createElementWithStyle("{}");
-
- if (await applyElemHideEmulation(test, ["div:-abp-has(div)"]))
- expectVisible(test, toHide);
-
- test.done();
-};
-
-exports.testPseudoClassHasSelectorWithPrefix = async function(test)
-{
- let parent = createElementWithStyle("{}");
- let child = createElementWithStyle("{}", parent);
-
- if (await applyElemHideEmulation(test, ["div:-abp-has(div)"]))
- {
- expectHidden(test, parent);
- expectVisible(test, child);
+ let element = createElement(parent);
+ insertStyleRule("#" + element.id + " " + styleBlock);
+ return element;
}
- test.done();
-};
-
-exports.testPseudoClassHasSelectorWithSuffix = async function(test)
-{
- let parent = createElementWithStyle("{}");
- let middle = createElementWithStyle("{}", parent);
- let child = createElementWithStyle("{}", middle);
-
- if (await applyElemHideEmulation(test, ["div:-abp-has(div) > div"]))
+ // Create a new ElemHideEmulation instance with @selectors.
+ async function applyElemHideEmulation(selectors)
{
- expectVisible(test, parent);
- expectHidden(test, middle);
- expectHidden(test, child);
- }
-
- test.done();
-};
-
-exports.testPseudoClassHasSelectorWithSuffixSibling = async function(test)
-{
- let parent = createElementWithStyle("{}");
- let middle = createElementWithStyle("{}", parent);
- let toHide = createElementWithStyle("{}");
-
- if (await applyElemHideEmulation(test, ["div:-abp-has(div) + div"]))
- {
- expectVisible(test, parent);
- expectVisible(test, middle);
- expectHidden(test, toHide);
- }
-
- test.done();
-};
+ await Promise.resolve();
-exports.testPseudoClassHasSelectorWithSuffixSiblingChild = async function(test)
-{
- // <div>
- // <div></div>
- // <div>
- // <div>to hide</div>
- // </div>
- // </div>
- let parent = createElementWithStyle("{}");
- let middle = createElementWithStyle("{}", parent);
- let sibling = createElementWithStyle("{}");
- let toHide = createElementWithStyle("{}", sibling);
+ try
+ {
+ let elemHideEmulation = new ElemHideEmulation(
+ elems =>
+ {
+ for (let elem of elems)
+ elem.style.display = "none";
+ }
+ );
- if (await applyElemHideEmulation(test, ["div:-abp-has(div) + div > div"]))
- {
- expectVisible(test, parent);
- expectVisible(test, middle);
- expectVisible(test, sibling);
- expectHidden(test, toHide);
- }
-
- test.done();
-};
+ elemHideEmulation.document = testDocument;
+ elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2;
+ elemHideEmulation.apply(selectors.map(
+ selector => ({selector, text: selector})
+ ));
-function compareExpectations(test, elems, expectations)
-{
- for (let elem in expectations)
- {
- if (elems[elem])
+ return elemHideEmulation;
+ }
+ catch (error)
{
- if (expectations[elem])
- expectVisible(test, elems[elem], elem);
- else
- expectHidden(test, elems[elem], elem);
+ unexpectedError(error);
}
}
-}
-async function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector, expectations)
-{
- 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"><span>to hide</span></div>
- </div>
- <div id="sibling2">
- <div id="sibling21"><div id="sibling211" class="inside"></div></div>
- </div>
- </div>`;
- let elems = {
- 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 {}");
-
- if (await applyElemHideEmulation(test, [selector]))
- compareExpectations(test, elems, expectations);
-
- test.done();
-}
+ describe("Verbatim Property Selector", () =>
+ {
+ it("Regular", async() =>
+ {
+ let toHide = createElementWithStyle("{background-color: #000}");
+ let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
-exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test)
-{
- let expectations = {
- parent: true,
- middile: true,
- inside: true,
- sibling: true,
- sibling2: true,
- toHide: false
- };
- runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
- test, "div:-abp-has(:-abp-has(div.inside)) + div > div", expectations);
-};
+ if (await applyElemHideEmulation(selectors))
+ expectHidden(toHide);
+ });
-exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = function(test)
-{
- let expectations = {
- parent: true,
- middile: true,
- inside: true,
- sibling: true,
- sibling2: true,
- toHide: false
- };
- runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
- test, "div:-abp-has(:-abp-has(> div.inside)) + div > div", expectations);
-};
+ it("With Prefix", async() =>
+ {
+ let parent = createElementWithStyle("{background-color: #000}");
+ let toHide = createElementWithStyle("{background-color: #000}", parent);
-exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling3 = function(test)
-{
- let expectations = {
- parent: true,
- middile: true,
- inside: true,
- sibling: true,
- sibling2: true,
- toHide: false
- };
- runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
- test, "div:-abp-has(> div:-abp-has(div.inside)) + div > div", expectations);
-};
+ let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"];
-exports.testPseudoClassHasSelectorWithSuffixSiblingNoop = function(test)
-{
- let expectations = {
- parent: true,
- middile: true,
- inside: true,
- sibling: true,
- sibling2: true,
- toHide: true
- };
- runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
- test, "div:-abp-has(> body div.inside) + div > div", expectations);
-};
-
-exports.testPseudoClassHasSelectorWithSuffixSiblingContains = function(test)
-{
- let expectations = {
- parent: true,
- middile: true,
- inside: true,
- sibling: true,
- sibling2: true,
- toHide: true
- };
- runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
- test, "div:-abp-has(> span:-abp-contains(Advertisment))", expectations);
-};
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectVisible(parent);
+ expectHidden(toHide);
+ }
+ });
-async function runTestQualifier(test, selector)
-{
- testDocument.body.innerHTML = `
- <style>
- span::before {
- content: "any";
- }
- </style>
- <div id="toHide">
- <a>
- <p>
- <span></span>
- </p>
- </a>
- </div>`;
+ it("With Prefix No Match", async() =>
+ {
+ let parent = createElementWithStyle("{background-color: #000}");
+ let toHide = createElementWithStyle("{background-color: #fff}", parent);
- if (await applyElemHideEmulation(test, [selector]))
- expectHidden(test, testDocument.getElementById("toHide"));
-
- test.done();
-}
+ let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"];
-// See issue https://issues.adblockplus.org/ticket/7428
-exports.testPropertySelectorCombinatorQualifier = function(test)
-{
- runTestQualifier(
- test,
- "div:-abp-has(> a p > :-abp-properties(content: \"any\"))"
- );
-};
-
-// See issue https://issues.adblockplus.org/ticket/7359
-exports.testPropertySelectorCombinatorQualifierNested = function(test)
-{
- runTestQualifier(
- test,
- "div:-abp-has(> a p:-abp-has(> :-abp-properties(content: \"any\")))"
- );
-};
-
-// See issue https://issues.adblockplus.org/ticket/7400
-exports.testPropertySelectorIdenticalTypeQualifier = function(test)
-{
- runTestQualifier(
- test,
- "div:-abp-has(span:-abp-properties(content: \"any\"))"
- );
-};
-
-// See issue https://issues.adblockplus.org/ticket/7400
-exports.testPropertySelectorIdenticalTypeQualifierNested = function(test)
-{
- runTestQualifier(
- test,
- "div:-abp-has(p:-abp-has(span:-abp-properties(content: \"any\")))"
- );
-};
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectVisible(parent);
+ expectVisible(toHide);
+ }
+ });
-async function runTestPseudoClassContains(test, selector, expectations)
-{
- 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 \ud83d\ude42!</div>
- </div>
- <div id="sibling2">
- <div id="sibling21"><div id="sibling211" class="inside">Ad*</div></div>
- </div>
- </div>`;
- let elems = {
- parent: testDocument.getElementById("parent"),
- middle: testDocument.getElementById("middle"),
- inside: testDocument.getElementById("inside"),
- sibling: testDocument.getElementById("sibling"),
- sibling2: testDocument.getElementById("sibling2"),
- toHide: testDocument.getElementById("tohide")
- };
+ it("With Suffix", async() =>
+ {
+ let parent = createElementWithStyle("{background-color: #000}");
+ let toHide = createElementWithStyle("{background-color: #000}", parent);
- if (await applyElemHideEmulation(test, [selector]))
- compareExpectations(test, elems, expectations);
-
- test.done();
-}
+ let selectors = [":-abp-properties(background-color: rgb(0, 0, 0)) > div"];
-exports.testPseudoClassContainsText = function(test)
-{
- let expectations = {
- parent: true,
- middle: true,
- inside: true,
- sibling: false,
- sibling2: true,
- toHide: true
- };
- runTestPseudoClassContains(
- test, "#parent div:-abp-contains(to hide)", expectations);
-};
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectVisible(parent);
+ expectHidden(toHide);
+ }
+ });
-exports.testPseudoClassContainsRegexp = function(test)
-{
- let expectations = {
- parent: true,
- middle: true,
- inside: true,
- sibling: false,
- sibling2: true,
- toHide: true
- };
- runTestPseudoClassContains(
- test, "#parent div:-abp-contains(/to\\shide/)", expectations);
-};
-
-exports.testPseudoClassContainsRegexpIFlag = function(test)
-{
- let expectations = {
- parent: true,
- middle: true,
- inside: true,
- sibling: false,
- sibling2: true,
- toHide: true
- };
- runTestPseudoClassContains(
- test, "#parent div:-abp-contains(/to\\sHide/i)", expectations);
-};
-exports.testPseudoClassContainsRegexpUFlag = function(test)
-{
- let expectations = {
- parent: true,
- middle: true,
- inside: true,
- sibling: false,
- sibling2: true,
- toHide: true
- };
- runTestPseudoClassContains(
- test, "#parent div:-abp-contains(/to\\shide\\s.!/u)", expectations);
-};
+ it("With prefix and suffix", async() =>
+ {
+ let parent = createElementWithStyle("{background-color: #000}");
+ let middle = createElementWithStyle("{background-color: #000}", parent);
+ let toHide = createElementWithStyle("{background-color: #000}", middle);
-exports.testPseudoClassContainsWildcardNoMatch = function(test)
-{
- let expectations = {
- parent: true,
- middle: true,
- inside: true,
- sibling: true,
- sibling2: true,
- toHide: true
- };
- // this filter shouldn't match anything as "*" has no meaning.
- runTestPseudoClassContains(
- test, "#parent div:-abp-contains(to *hide)", expectations);
-};
-
-exports.testPseudoClassContainsWildcardMatch = function(test)
-{
- let expectations = {
- parent: true,
- middle: true,
- inside: true,
- sibling: true,
- sibling2: false,
- toHide: true
- };
- runTestPseudoClassContains(
- test, "#parent div:-abp-contains(Ad*)", expectations);
-};
-
-exports.testPseudoClassHasSelectorWithPropSelector = async function(test)
-{
- let parent = createElementWithStyle("{}");
- let child = createElementWithStyle("{background-color: #000}", parent);
+ let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0)) > div"];
- let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
-
- if (await applyElemHideEmulation(test, selectors))
- {
- expectVisible(test, child);
- expectHidden(test, parent);
- }
-
- test.done();
-};
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectVisible(parent);
+ expectVisible(middle);
+ expectHidden(toHide);
+ }
+ });
+ });
-exports.testPseudoClassHasSelectorWithPropSelector2 = async function(test)
-{
- let parent = createElementWithStyle("{}");
- let child = createElementWithStyle("{}", parent);
-
- let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
-
- insertStyleRule("body #" + parent.id + " > div { background-color: #000}");
-
- if (await applyElemHideEmulation(test, selectors))
+ // Add the style. Then add the element for that style.
+ // This should retrigger the filtering and hide it.
+ it("Property Pseudo Selector Add Style and elemment", async() =>
{
- expectVisible(test, child);
- expectHidden(test, parent);
- }
-
- test.done();
-};
-
-exports.testDomUpdatesStyle = async function(test)
-{
- let parent = createElementWithStyle("{}");
- let child = createElementWithStyle("{}", parent);
+ let styleElement;
+ let toHide;
- let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
-
- if (await applyElemHideEmulation(test, selectors))
- {
- expectVisible(test, child);
- expectVisible(test, parent);
-
- insertStyleRule("body #" + parent.id + " > div { background-color: #000}");
- await timeout(0);
-
- expectVisible(test, child);
- expectVisible(test, parent);
- await timeout(REFRESH_INTERVAL);
+ let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
- expectVisible(test, child);
- expectHidden(test, parent);
- }
-
- test.done();
-};
-
-exports.testDomUpdatesContent = async function(test)
-{
- let parent = createElementWithStyle("{}");
- let child = createElementWithStyle("{}", parent);
-
- if (await applyElemHideEmulation(test, ["div > div:-abp-contains(hide me)"]))
- {
- expectVisible(test, parent);
- expectVisible(test, child);
-
- child.textContent = "hide me";
- await timeout(0);
-
- expectVisible(test, parent);
- expectVisible(test, child);
- await timeout(REFRESH_INTERVAL);
-
- expectVisible(test, parent);
- expectHidden(test, child);
- }
-
- test.done();
-};
-
-exports.testDomUpdatesNewElement = async function(test)
-{
- let parent = createElementWithStyle("{}");
- let child = createElementWithStyle("{ background-color: #000}", parent);
- let sibling;
- let child2;
+ if (await applyElemHideEmulation(selectors))
+ {
+ styleElement = testDocument.createElement("style");
+ testDocument.head.appendChild(styleElement);
+ styleElement.sheet.insertRule("#toHide {background-color: #000}");
+ await timeout(REFRESH_INTERVAL);
- let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
-
- if (await applyElemHideEmulation(test, selectors))
- {
- expectHidden(test, parent);
- expectVisible(test, child);
-
- sibling = createElementWithStyle("{}");
- await timeout(0);
-
- expectHidden(test, parent);
- expectVisible(test, child);
- expectVisible(test, sibling);
-
- await timeout(REFRESH_INTERVAL);
-
- expectHidden(test, parent);
- expectVisible(test, child);
- expectVisible(test, sibling);
+ toHide = createElement();
+ toHide.id = "toHide";
+ expectVisible(toHide);
+ await timeout(REFRESH_INTERVAL);
- child2 = createElementWithStyle("{ background-color: #000}",
- sibling);
- await timeout(0);
-
- expectVisible(test, child2);
- await timeout(REFRESH_INTERVAL);
-
- expectHidden(test, parent);
- expectVisible(test, child);
- expectHidden(test, sibling);
- expectVisible(test, child2);
- }
-
- test.done();
-};
-
-exports.testPseudoClassPropertiesOnStyleSheetLoad = async function(test)
-{
- let parent = createElement();
- let child = createElement(parent);
+ expectHidden(toHide);
+ }
+ });
- let selectors = [
- "div:-abp-properties(background-color: rgb(0, 0, 0))",
- "div:-abp-contains(hide me)",
- "div:-abp-has(> div.hideMe)"
- ];
-
- if (await applyElemHideEmulation(test, selectors))
- {
- await timeout(REFRESH_INTERVAL);
-
- expectVisible(test, parent);
- expectVisible(test, child);
-
- // Load a style sheet that targets the parent element. This should run only
- // the "div:-abp-properties(background-color: rgb(0, 0, 0))" pattern.
- insertStyleRule("#" + parent.id + " {background-color: #000}");
-
- await timeout(REFRESH_INTERVAL);
-
- expectHidden(test, parent);
- expectVisible(test, child);
- }
-
- test.done();
-};
-
-exports.testPlainAttributeOnDomMutation = async function(test)
-{
- let parent = createElement();
- let child = createElement(parent);
-
- let selectors = [
- "div:-abp-properties(background-color: rgb(0, 0, 0))",
- "div[data-hide-me]",
- "div:-abp-contains(hide me)",
- "div:-abp-has(> div.hideMe)"
- ];
-
- if (await applyElemHideEmulation(test, selectors))
+ describe("Property Selector", () =>
{
- await timeout(REFRESH_INTERVAL);
-
- expectVisible(test, parent);
- expectVisible(test, child);
+ it("With Wildcard", async() =>
+ {
+ let toHide = createElementWithStyle("{background-color: #000}");
+ let selectors = [":-abp-properties(*color: rgb(0, 0, 0))"];
- // Set the "data-hide-me" attribute on the child element.
- //
- // Note: Since the "div[data-hide-me]" pattern has already been processed
- // and the selector added to the document's style sheet, this will in fact
- // not do anything at our end, but the browser will just match the selector
- // and hide the element.
- child.setAttribute("data-hide-me", "");
-
- await timeout(REFRESH_INTERVAL);
-
- expectVisible(test, parent);
- expectHidden(test, child);
- }
+ if (await applyElemHideEmulation(selectors))
+ expectHidden(toHide);
+ });
- test.done();
-};
-
-exports.testPseudoClassContainsOnDomMutation = async function(test)
-{
- let parent = createElement();
- let child = createElement(parent);
+ it("With regular expression", async() =>
+ {
+ let toHide = createElementWithStyle("{background-color: #000}");
+ let selectors = [":-abp-properties(/.*color: rgb\\(0, 0, 0\\)/)"];
- let selectors = [
- "div:-abp-properties(background-color: rgb(0, 0, 0))",
- "div[data-hide-me]",
- "div:-abp-contains(hide me)",
- "div:-abp-has(> div.hideMe)"
- ];
+ if (await applyElemHideEmulation(selectors))
+ expectHidden(toHide);
+ });
+ });
- child.innerText = "do nothing";
-
- if (await applyElemHideEmulation(test, selectors))
+ it("Dynamically Changed Property", async() =>
{
- await timeout(REFRESH_INTERVAL);
-
- expectVisible(test, parent);
- expectVisible(test, child);
+ let toHide = createElementWithStyle("{}");
+ let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"];
- // Set the child element's text to "hide me". This should run only the
- // "div:-abp-contains(hide me)" pattern.
- //
- // Note: We need to set Node.innerText here in order to trigger the
- // "characterData" DOM mutation on Chromium. If we set Node.textContent
- // instead, it triggers the "childList" DOM mutation instead.
- child.innerText = "hide me";
-
- await timeout(REFRESH_INTERVAL);
-
- expectHidden(test, parent);
- expectVisible(test, child);
- }
-
- test.done();
-};
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectVisible(toHide);
+ insertStyleRule("#" + toHide.id + " {background-color: #000}");
-exports.testPseudoClassHasOnDomMutation = async function(test)
-{
- let parent = createElement();
- let child = null;
-
- let selectors = [
- "div:-abp-properties(background-color: rgb(0, 0, 0))",
- "div[data-hide-me]",
- "div:-abp-contains(hide me)",
- "div:-abp-has(> div)"
- ];
+ await timeout(0);
- if (await applyElemHideEmulation(test, selectors))
- {
- await timeout(REFRESH_INTERVAL);
-
- expectVisible(test, parent);
-
- // Add the child element. This should run all the DOM-dependent patterns
- // ("div:-abp-contains(hide me)" and "div:-abp-has(> div)").
- child = createElement(parent);
-
- await timeout(REFRESH_INTERVAL);
+ // Re-evaluation will only happen after a delay
+ expectVisible(toHide);
+ await timeout(REFRESH_INTERVAL);
- expectHidden(test, parent);
- expectVisible(test, child);
- }
-
- test.done();
-};
+ expectHidden(toHide);
+ }
+ });
-exports.testPseudoClassHasWithClassOnDomMutation = async function(test)
-{
- let parent = createElement();
- let child = createElement(parent);
-
- let selectors = [
- "div:-abp-properties(background-color: rgb(0, 0, 0))",
- "div[data-hide-me]",
- "div:-abp-contains(hide me)",
- "div:-abp-has(> div.hideMe)"
- ];
-
- if (await applyElemHideEmulation(test, selectors))
+ describe("Pseudo Class", () =>
{
- await timeout(REFRESH_INTERVAL);
-
- expectVisible(test, parent);
- expectVisible(test, child);
-
- // Set the child element's class to "hideMe". This should run only the
- // "div:-abp-has(> div.hideMe)" pattern.
- child.className = "hideMe";
-
- await timeout(REFRESH_INTERVAL);
-
- expectHidden(test, parent);
- expectVisible(test, child);
- }
-
- test.done();
-};
-
-exports.testPseudoClassHasWithPseudoClassContainsOnDomMutation = async function(test)
-{
- let parent = createElement();
- let child = createElement(parent);
+ it("With prop before selector", async() =>
+ {
+ let parent = createElementWithStyle("{}");
+ let child = createElementWithStyle("{background-color: #000}", parent);
- let selectors = [
- "div:-abp-properties(background-color: rgb(0, 0, 0))",
- "div[data-hide-me]",
- "div:-abp-contains(hide me)",
- "div:-abp-has(> div:-abp-contains(hide me))"
- ];
+ let selectors = ["div:-abp-properties(content: \"publicite\")"];
- child.innerText = "do nothing";
-
- if (await applyElemHideEmulation(test, selectors))
- {
- await timeout(REFRESH_INTERVAL);
-
- expectVisible(test, parent);
- expectVisible(test, child);
+ insertStyleRule(`#${child.id}::before {content: "publicite"}`);
- // Set the child element's text to "hide me". This should run only the
- // "div:-abp-contains(hide me)" and
- // "div:-abp-has(> div:-abp-contains(hide me))" patterns.
- child.innerText = "hide me";
-
- await timeout(REFRESH_INTERVAL);
-
- // Note: Even though it runs both the :-abp-contains() patterns, it only
- // hides the parent element because of revision d7d51d29aa34.
- expectHidden(test, parent);
- expectVisible(test, child);
- }
-
- test.done();
-};
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectHidden(child);
+ expectVisible(parent);
+ }
+ });
-exports.testOnlyRelevantElementsProcessed = async function(test)
-{
- // <body>
- // <div id="n1">
- // <p id="n1_1"></p>
- // <p id="n1_2"></p>
- // <p id="n1_4">Hello</p>
- // </div>
- // <div id="n2">
- // <p id="n2_1"></p>
- // <p id="n2_2"></p>
- // <p id="n2_4">Hello</p>
- // </div>
- // <div id="n3">
- // <p id="n3_1"></p>
- // <p id="n3_2"></p>
- // <p id="n3_4">Hello</p>
- // </div>
- // <div id="n4">
- // <p id="n4_1"></p>
- // <p id="n4_2"></p>
- // <p id="n4_4">Hello</p>
- // </div>
- // </body>
- for (let i of [1, 2, 3, 4])
- {
- let n = createElement(null, "div", `n${i}`);
- for (let [j, text] of [[1], [2], [4, "Hello"]])
- createElement(n, "p", `n${i}_${j}`, text);
- }
-
- let selectors = [
- "p:-abp-contains(Hello)",
- "div:-abp-contains(Try me!)",
- "div:-abp-has(p:-abp-contains(This is good))"
- ];
-
- if (await applyElemHideEmulation(test, selectors))
- {
- await timeout(REFRESH_INTERVAL);
-
- // This is only a sanity check to make sure everything else is working
- // before we do the actual test.
- for (let i of [1, 2, 3, 4])
+ function compareExpectations(elems, expectations)
{
- for (let j of [1, 2, 4])
+ for (let elem in expectations)
{
- let id = `n${i}_${j}`;
- if (j == 4)
- expectHidden(test, testDocument.getElementById(id), id);
- else
- expectVisible(test, testDocument.getElementById(id), id);
+ if (elems[elem])
+ {
+ if (expectations[elem])
+ expectVisible(elems[elem], elem);
+ else
+ expectHidden(elems[elem], elem);
+ }
}
}
- // All <div> and <p> elements should be processed initially.
- for (let element of [...testDocument.getElementsByTagName("div"),
- ...testDocument.getElementsByTagName("p")])
+ describe("Has Selector", () =>
+ {
+ it("Simple", async() =>
+ {
+ let toHide = createElementWithStyle("{}");
+
+ if (await applyElemHideEmulation(["div:-abp-has(div)"]))
+ expectVisible(toHide);
+ });
+
+ it("With prefix", async() =>
+ {
+ let parent = createElementWithStyle("{}");
+ let child = createElementWithStyle("{}", parent);
+
+ if (await applyElemHideEmulation(["div:-abp-has(div)"]))
+ {
+ expectHidden(parent);
+ expectVisible(child);
+ }
+ });
+
+ it("With suffix", async() =>
+ {
+ let parent = createElementWithStyle("{}");
+ let middle = createElementWithStyle("{}", parent);
+ let child = createElementWithStyle("{}", middle);
+
+ if (await applyElemHideEmulation(["div:-abp-has(div) > div"]))
+ {
+ expectVisible(parent);
+ expectHidden(middle);
+ expectHidden(child);
+ }
+ });
+
+ it("With suffix sibling", async() =>
+ {
+ let parent = createElementWithStyle("{}");
+ let middle = createElementWithStyle("{}", parent);
+ let toHide = createElementWithStyle("{}");
+
+ if (await applyElemHideEmulation(["div:-abp-has(div) + div"]))
+ {
+ expectVisible(parent);
+ expectVisible(middle);
+ expectHidden(toHide);
+ }
+ });
+
+ it("With suffix sibling child", async() =>
+ {
+ // <div>
+ // <div></div>
+ // <div>
+ // <div>to hide</div>
+ // </div>
+ // </div>
+ let parent = createElementWithStyle("{}");
+ let middle = createElementWithStyle("{}", parent);
+ let sibling = createElementWithStyle("{}");
+ let toHide = createElementWithStyle("{}", sibling);
+
+ if (await applyElemHideEmulation(["div:-abp-has(div) + div > div"]))
+ {
+ expectVisible(parent);
+ expectVisible(middle);
+ expectVisible(sibling);
+ expectHidden(toHide);
+ }
+ });
+
+ async function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(selector, expectations)
+ {
+ 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"><span>to hide</span></div>
+ </div>
+ <div id="sibling2">
+ <div id="sibling21"><div id="sibling211" class="inside"></div></div>
+ </div>
+ </div>`;
+ let elems = {
+ 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 {}");
+ if (await applyElemHideEmulation([selector]))
+ compareExpectations(elems, expectations);
+ }
+
+ it("With has and with suffix sibling", () =>
+ {
+ let expectations = {
+ parent: true,
+ middile: true,
+ inside: true,
+ sibling: true,
+ sibling2: true,
+ toHide: false
+ };
+ runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
+ "div:-abp-has(:-abp-has(div.inside)) + div > div", expectations);
+ });
+
+ it("With has an with suffix sibling (2)", () =>
+ {
+ let expectations = {
+ parent: true,
+ middile: true,
+ inside: true,
+ sibling: true,
+ sibling2: true,
+ toHide: false
+ };
+ runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
+ "div:-abp-has(:-abp-has(> div.inside)) + div > div", expectations);
+ });
+
+ it("With has an with suffix sibling (3)", () =>
+ {
+ let expectations = {
+ parent: true,
+ middile: true,
+ inside: true,
+ sibling: true,
+ sibling2: true,
+ toHide: false
+ };
+ runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
+ "div:-abp-has(> div:-abp-has(div.inside)) + div > div", expectations);
+ });
+
+ it("With suffix sibling no-op", () =>
+ {
+ let expectations = {
+ parent: true,
+ middile: true,
+ inside: true,
+ sibling: true,
+ sibling2: true,
+ toHide: true
+ };
+ runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
+ "div:-abp-has(> body div.inside) + div > div", expectations);
+ });
+
+ it("With suffix sibling contains", () =>
+ {
+ let expectations = {
+ parent: true,
+ middile: true,
+ inside: true,
+ sibling: true,
+ sibling2: true,
+ toHide: true
+ };
+ runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
+ "div:-abp-has(> span:-abp-contains(Advertisment))", expectations);
+ });
+ });
+
+ describe("Property Selector Qualifiers", () =>
+ {
+ async function runTestQualifier(selector)
+ {
+ testDocument.body.innerHTML = `
+ <style>
+ span::before {
+ content: "any";
+ }
+ </style>
+ <div id="toHide">
+ <a>
+ <p>
+ <span></span>
+ </p>
+ </a>
+ </div>`;
+
+ if (await applyElemHideEmulation([selector]))
+ expectHidden(testDocument.getElementById("toHide"));
+ }
+
+ // See issue https://issues.adblockplus.org/ticket/7428
+ it("Combinator", () =>
+ {
+ runTestQualifier(
+ "div:-abp-has(> a p > :-abp-properties(content: \"any\"))"
+ );
+ });
+
+ // See issue https://issues.adblockplus.org/ticket/7359
+ it("Nested Combinator", () =>
+ {
+ runTestQualifier(
+ "div:-abp-has(> a p:-abp-has(> :-abp-properties(content: \"any\")))"
+ );
+ });
+
+ // See issue https://issues.adblockplus.org/ticket/7400
+ it("Identical", () =>
+ {
+ runTestQualifier(
+ "div:-abp-has(span:-abp-properties(content: \"any\"))"
+ );
+ });
+
+ // See issue https://issues.adblockplus.org/ticket/7400
+ it("Nested Identical", () =>
+ {
+ runTestQualifier(
+ "div:-abp-has(p:-abp-has(span:-abp-properties(content: \"any\")))"
+ );
+ });
+ });
+
+ describe("Contains selector", () =>
+ {
+ async function runTestPseudoClassContains(selector, expectations)
+ {
+ 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 \ud83d\ude42!</div>
+ </div>
+ <div id="sibling2">
+ <div id="sibling21">
+ <div id="sibling211" class="inside">Ad*</div>
+ </div>
+ </div>
+ </div>`;
+ let elems = {
+ parent: testDocument.getElementById("parent"),
+ middle: testDocument.getElementById("middle"),
+ inside: testDocument.getElementById("inside"),
+ sibling: testDocument.getElementById("sibling"),
+ sibling2: testDocument.getElementById("sibling2"),
+ toHide: testDocument.getElementById("tohide")
+ };
+
+ if (await applyElemHideEmulation([selector]))
+ compareExpectations(elems, expectations);
+ }
+
+ it("Text", () =>
+ {
+ let expectations = {
+ parent: true,
+ middle: true,
+ inside: true,
+ sibling: false,
+ sibling2: true,
+ toHide: true
+ };
+ runTestPseudoClassContains(
+ "#parent div:-abp-contains(to hide)", expectations);
+ });
+
+ it("Regexp", () =>
+ {
+ let expectations = {
+ parent: true,
+ middle: true,
+ inside: true,
+ sibling: false,
+ sibling2: true,
+ toHide: true
+ };
+ runTestPseudoClassContains(
+ "#parent div:-abp-contains(/to\\shide/)", expectations);
+ });
+
+ it("Regexp i flag", () =>
+ {
+ let expectations = {
+ parent: true,
+ middle: true,
+ inside: true,
+ sibling: false,
+ sibling2: true,
+ toHide: true
+ };
+ runTestPseudoClassContains(
+ "#parent div:-abp-contains(/to\\sHide/i)", expectations);
+ });
+
+ it("Regexp u flag", () =>
+ {
+ let expectations = {
+ parent: true,
+ middle: true,
+ inside: true,
+ sibling: false,
+ sibling2: true,
+ toHide: true
+ };
+ runTestPseudoClassContains(
+ "#parent div:-abp-contains(/to\\shide\\s.!/u)", expectations);
+ });
+
+ it("Wildcard no match", () =>
+ {
+ let expectations = {
+ parent: true,
+ middle: true,
+ inside: true,
+ sibling: true,
+ sibling2: true,
+ toHide: true
+ };
+ // this filter shouldn't match anything as "*" has no meaning.
+ runTestPseudoClassContains(
+ "#parent div:-abp-contains(to *hide)", expectations);
+ });
+
+ it("Wildcard match", () =>
+ {
+ let expectations = {
+ parent: true,
+ middle: true,
+ inside: true,
+ sibling: true,
+ sibling2: false,
+ toHide: true
+ };
+ runTestPseudoClassContains(
+ "#parent div:-abp-contains(Ad*)", expectations);
+ });
+ });
+
+ describe("Has Selector with prop selector", () =>
{
- expectProcessed(test, element, element.id);
+ it("Already present", async() =>
+ {
+ let parent = createElementWithStyle("{}");
+ let child = createElementWithStyle("{background-color: #000}", parent);
+
+ let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectVisible(child);
+ expectHidden(parent);
+ }
+ });
+
+ it("Dynamically added", async() =>
+ {
+ let parent = createElementWithStyle("{}");
+ let child = createElementWithStyle("{}", parent);
+
+ let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
+
+ insertStyleRule("body #" + parent.id + " > div { background-color: #000}");
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectVisible(child);
+ expectHidden(parent);
+ }
+ });
+ });
+ });
+
+ describe("DOM updates", () =>
+ {
+ it("Style", async() =>
+ {
+ let parent = createElementWithStyle("{}");
+ let child = createElementWithStyle("{}", parent);
+
+ let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectVisible(child);
+ expectVisible(parent);
+
+ insertStyleRule("body #" + parent.id + " > div { background-color: #000}");
+ await timeout(0);
+
+ expectVisible(child);
+ expectVisible(parent);
+ await timeout(REFRESH_INTERVAL);
+
+ expectVisible(child);
+ expectHidden(parent);
+ }
+ });
+
+ it("Content", async() =>
+ {
+ let parent = createElementWithStyle("{}");
+ let child = createElementWithStyle("{}", parent);
+
+ if (await applyElemHideEmulation(["div > div:-abp-contains(hide me)"]))
+ {
+ expectVisible(parent);
+ expectVisible(child);
+
+ child.textContent = "hide me";
+ await timeout(0);
+
+ expectVisible(parent);
+ expectVisible(child);
+ await timeout(REFRESH_INTERVAL);
+
+ expectVisible(parent);
+ expectHidden(child);
+ }
+ });
+
+ it("New element", async() =>
+ {
+ let parent = createElementWithStyle("{}");
+ let child = createElementWithStyle("{ background-color: #000}", parent);
+ let sibling;
+ let child2;
+
+ let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"];
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ expectHidden(parent);
+ expectVisible(child);
+
+ sibling = createElementWithStyle("{}");
+ await timeout(0);
+
+ expectHidden(parent);
+ expectVisible(child);
+ expectVisible(sibling);
+
+ await timeout(REFRESH_INTERVAL);
+
+ expectHidden(parent);
+ expectVisible(child);
+ expectVisible(sibling);
+
+ child2 = createElementWithStyle("{ background-color: #000}",
+ sibling);
+ await timeout(0);
+
+ expectVisible(child2);
+ await timeout(REFRESH_INTERVAL);
+
+ expectHidden(parent);
+ expectVisible(child);
+ expectHidden(sibling);
+ expectVisible(child2);
+ }
+ });
+ });
+
+ it("Pseudo class properties on stylesheet load", async() =>
+ {
+ let parent = createElement();
+ let child = createElement(parent);
+
+ let selectors = [
+ "div:-abp-properties(background-color: rgb(0, 0, 0))",
+ "div:-abp-contains(hide me)",
+ "div:-abp-has(> div.hideMe)"
+ ];
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ await timeout(REFRESH_INTERVAL);
+
+ expectVisible(parent);
+ expectVisible(child);
+
+ // Load a style sheet that targets the parent element. This should run only
+ // the "div:-abp-properties(background-color: rgb(0, 0, 0))" pattern.
+ insertStyleRule("#" + parent.id + " {background-color: #000}");
+
+ await timeout(REFRESH_INTERVAL);
+
+ expectHidden(parent);
+ expectVisible(child);
+ }
+ });
+
+ describe("On DOM mutation", () =>
+ {
+ it("Plain attributes", async() =>
+ {
+ let parent = createElement();
+ let child = createElement(parent);
+
+ let selectors = [
+ "div:-abp-properties(background-color: rgb(0, 0, 0))",
+ "div[data-hide-me]",
+ "div:-abp-contains(hide me)",
+ "div:-abp-has(> div.hideMe)"
+ ];
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ await timeout(REFRESH_INTERVAL);
+
+ expectVisible(parent);
+ expectVisible(child);
+
+ // Set the "data-hide-me" attribute on the child element.
+ //
+ // Note: Since the "div[data-hide-me]" pattern has already been processed
+ // and the selector added to the document's style sheet, this will in fact
+ // not do anything at our end, but the browser will just match the selector
+ // and hide the element.
+ child.setAttribute("data-hide-me", "");
+
+ await timeout(REFRESH_INTERVAL);
+
+ expectVisible(parent);
+ expectHidden(child);
+ }
+ });
+
+ it("Pseudo class contains", async() =>
+ {
+ let parent = createElement();
+ let child = createElement(parent);
+
+ let selectors = [
+ "div:-abp-properties(background-color: rgb(0, 0, 0))",
+ "div[data-hide-me]",
+ "div:-abp-contains(hide me)",
+ "div:-abp-has(> div.hideMe)"
+ ];
+
+ child.innerText = "do nothing";
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ await timeout(REFRESH_INTERVAL);
+
+ expectVisible(parent);
+ expectVisible(child);
+
+ // Set the child element's text to "hide me". This should run only the
+ // "div:-abp-contains(hide me)" pattern.
+ //
+ // Note: We need to set Node.innerText here in order to trigger the
+ // "characterData" DOM mutation on Chromium. If we set Node.textContent
+ // instead, it triggers the "childList" DOM mutation instead.
+ child.innerText = "hide me";
+
+ await timeout(REFRESH_INTERVAL);
+
+ expectHidden(parent);
+ expectVisible(child);
+ }
+ });
+
+ it("Pseudo class has", async() =>
+ {
+ let parent = createElement();
+ let child = null;
+
+ let selectors = [
+ "div:-abp-properties(background-color: rgb(0, 0, 0))",
+ "div[data-hide-me]",
+ "div:-abp-contains(hide me)",
+ "div:-abp-has(> div)"
+ ];
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ await timeout(REFRESH_INTERVAL);
+
+ expectVisible(parent);
+
+ // Add the child element. This should run all the DOM-dependent patterns
+ // ("div:-abp-contains(hide me)" and "div:-abp-has(> div)").
+ child = createElement(parent);
+
+ await timeout(REFRESH_INTERVAL);
+
+ expectHidden(parent);
+ expectVisible(child);
+ }
+ });
+
+ it("Pseudo class has", async() =>
+ {
+ let parent = createElement();
+ let child = createElement(parent);
+
+ let selectors = [
+ "div:-abp-properties(background-color: rgb(0, 0, 0))",
+ "div[data-hide-me]",
+ "div:-abp-contains(hide me)",
+ "div:-abp-has(> div.hideMe)"
+ ];
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ await timeout(REFRESH_INTERVAL);
+
+ expectVisible(parent);
+ expectVisible(child);
+
+ // Set the child element's class to "hideMe". This should run only the
+ // "div:-abp-has(> div.hideMe)" pattern.
+ child.className = "hideMe";
+
+ await timeout(REFRESH_INTERVAL);
+
+ expectHidden(parent);
+ expectVisible(child);
+ }
+ });
+
+ it("Pseudo class has with pseudo class contains", async() =>
+ {
+ let parent = createElement();
+ let child = createElement(parent);
+
+ let selectors = [
+ "div:-abp-properties(background-color: rgb(0, 0, 0))",
+ "div[data-hide-me]",
+ "div:-abp-contains(hide me)",
+ "div:-abp-has(> div:-abp-contains(hide me))"
+ ];
+
+ child.innerText = "do nothing";
+
+ if (await applyElemHideEmulation(selectors))
+ {
+ await timeout(REFRESH_INTERVAL);
+
+ expectVisible(parent);
+ expectVisible(child);
+
+ // Set the child element's text to "hide me". This should run only the
+ // "div:-abp-contains(hide me)" and
+ // "div:-abp-has(> div:-abp-contains(hide me))" patterns.
+ child.innerText = "hide me";
+
+ await timeout(REFRESH_INTERVAL);
+
+ // Note: Even though it runs both the :-abp-contains() patterns, it only
+ // hides the parent element because of revision d7d51d29aa34.
+ expectHidden(parent);
+ expectVisible(child);
+ }
+ });
+ });
+
+ it("Only relevant elements are processed", async() =>
+ {
+ // <body>
+ // <div id="n1">
+ // <p id="n1_1"></p>
+ // <p id="n1_2"></p>
+ // <p id="n1_4">Hello</p>
+ // </div>
+ // <div id="n2">
+ // <p id="n2_1"></p>
+ // <p id="n2_2"></p>
+ // <p id="n2_4">Hello</p>
+ // </div>
+ // <div id="n3">
+ // <p id="n3_1"></p>
+ // <p id="n3_2"></p>
+ // <p id="n3_4">Hello</p>
+ // </div>
+ // <div id="n4">
+ // <p id="n4_1"></p>
+ // <p id="n4_2"></p>
+ // <p id="n4_4">Hello</p>
+ // </div>
+ // </body>
+ for (let i of [1, 2, 3, 4])
+ {
+ let n = createElement(null, "div", `n${i}`);
+ for (let [j, text] of [[1], [2], [4, "Hello"]])
+ createElement(n, "p", `n${i}_${j}`, text);
}
- // Modify the text in <p id="n4_1">
- testDocument.getElementById("n4_1").innerText = "Try me!";
+ let selectors = [
+ "p:-abp-contains(Hello)",
+ "div:-abp-contains(Try me!)",
+ "div:-abp-has(p:-abp-contains(This is good))"
+ ];
- await timeout(REFRESH_INTERVAL);
+ if (await applyElemHideEmulation(selectors))
+ {
+ await timeout(REFRESH_INTERVAL);
- // When an element's text is modified, only the element or one of its
- // ancestors matching any selector is processed for :-abp-has() and
- // :-abp-contains()
- for (let element of [...testDocument.getElementsByTagName("div"),
- ...testDocument.getElementsByTagName("p")])
- {
- if (element.id == "n4" || element.id == "n4_1")
- expectProcessed(test, element, element.id);
- else
- expectNotProcessed(test, element, element.id);
- }
+ // This is only a sanity check to make sure everything else is working
+ // before we do the actual test.
+ for (let i of [1, 2, 3, 4])
+ {
+ for (let j of [1, 2, 4])
+ {
+ let id = `n${i}_${j}`;
+ if (j == 4)
+ expectHidden(testDocument.getElementById(id), id);
+ else
+ expectVisible(testDocument.getElementById(id), id);
+ }
+ }
+
+ // All <div> and <p> elements should be processed initially.
+ for (let element of [...testDocument.getElementsByTagName("div"),
+ ...testDocument.getElementsByTagName("p")])
+ {
+ expectProcessed(element, element.id);
+ }
- // Create a new <p id="n2_3"> element with no text.
- createElement(testDocument.getElementById("n2"), "p", "n2_3");
+ // Modify the text in <p id="n4_1">
+ testDocument.getElementById("n4_1").innerText = "Try me!";
+
+ await timeout(REFRESH_INTERVAL);
- await timeout(REFRESH_INTERVAL);
+ // When an element's text is modified, only the element or one of its
+ // ancestors matching any selector is processed for :-abp-has() and
+ // :-abp-contains()
+ for (let element of [...testDocument.getElementsByTagName("div"),
+ ...testDocument.getElementsByTagName("p")])
+ {
+ if (element.id == "n4" || element.id == "n4_1")
+ expectProcessed(element, element.id);
+ else
+ expectNotProcessed(element, element.id);
+ }
- // When a new element is added, only the element or one of its ancestors
- // matching any selector is processed for :-abp-has() and :-abp-contains()
- for (let element of [...testDocument.getElementsByTagName("div"),
- ...testDocument.getElementsByTagName("p")])
- {
- if (element.id == "n2" || element.id == "n2_3")
- expectProcessed(test, element, element.id);
- else
- expectNotProcessed(test, element, element.id);
+ // Create a new <p id="n2_3"> element with no text.
+ createElement(testDocument.getElementById("n2"), "p", "n2_3");
+
+ await timeout(REFRESH_INTERVAL);
+
+ // When a new element is added, only the element or one of its ancestors
+ // matching any selector is processed for :-abp-has() and :-abp-contains()
+ for (let element of [...testDocument.getElementsByTagName("div"),
+ ...testDocument.getElementsByTagName("p")])
+ {
+ if (element.id == "n2" || element.id == "n2_3")
+ expectProcessed(element, element.id);
+ else
+ expectNotProcessed(element, element.id);
+ }
}
- }
-
- test.done();
-};
+ });
+});
« 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