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

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

Issue 29383960: Issue 3143 - Filter elements with :-abp-has() (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Added validate of element id, and fixed an infinite recursion in parsing. Created May 15, 2017, 6:10 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2017 eyeo GmbH 3 * Copyright (C) 2006-2017 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 /* globals ElemHideEmulation */ 20 /* globals ElemHideEmulation, splitSelector,
21 parseSelector,
22 PlainSelector, HasSelector, PropsSelector */
21 23
22 let myUrl = document.currentScript.src; 24 let myUrl = document.currentScript.src;
23 25
24 exports.tearDown = function(callback) 26 exports.tearDown = function(callback)
25 { 27 {
26 let styleElements = document.head.getElementsByTagName("style"); 28 let styleElements = document.head.getElementsByTagName("style");
27 while (styleElements.length) 29 while (styleElements.length)
28 styleElements[0].parentNode.removeChild(styleElements[0]); 30 styleElements[0].parentNode.removeChild(styleElements[0]);
31
32 let child;
33 while (child = document.body.firstChild)
34 document.body.removeChild(child);
35
29 callback(); 36 callback();
30 }; 37 };
31 38
32 function unexpectedError(error) 39 function unexpectedError(error)
33 { 40 {
34 console.error(error); 41 console.error(error);
35 this.ok(false, "Unexpected error: " + error); 42 this.ok(false, "Unexpected error: " + error);
36 } 43 }
37 44
38 function expectHidden(test, element) 45 function expectHidden(test, element)
(...skipping 23 matching lines...) Expand all
62 if (styleElements.length) 69 if (styleElements.length)
63 styleElement = styleElements[0]; 70 styleElement = styleElements[0];
64 else 71 else
65 { 72 {
66 styleElement = document.createElement("style"); 73 styleElement = document.createElement("style");
67 document.head.appendChild(styleElement); 74 document.head.appendChild(styleElement);
68 } 75 }
69 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length); 76 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length);
70 } 77 }
71 78
72 function createElementWithStyle(styleBlock) 79 // insert a <div> with a unique id and and empty CSS rule
80 // for the the selector matching the id.
81 function createElementWithStyle(styleBlock, parent)
73 { 82 {
74 let element = document.createElement("div"); 83 let element = document.createElement("div");
75 element.id = findUniqueId(); 84 element.id = findUniqueId();
76 document.body.appendChild(element); 85 if (!parent)
86 document.body.appendChild(element);
87 else
88 parent.appendChild(element);
77 insertStyleRule("#" + element.id + " " + styleBlock); 89 insertStyleRule("#" + element.id + " " + styleBlock);
78 return element; 90 return element;
79 } 91 }
80 92
81 function applyElemHideEmulation(selectors) 93 // Will ensure the class ElemHideEmulation is loaded
94 // and then will call the callback.
95 // NOTE: if it never loads, this will probably hang in an infinite
96 // loop
97 function loadElemHideEmulation()
82 { 98 {
83 if (typeof ElemHideEmulation == "undefined") 99 if (typeof ElemHideEmulation == "undefined")
84 { 100 {
85 return loadScript(myUrl + "/../../../lib/common.js").then(() => 101 return loadScript(myUrl + "/../../../lib/common.js").then(() =>
86 { 102 {
87 return loadScript(myUrl + "/../../../chrome/content/elemHideEmulation.js") ; 103 return loadScript(myUrl + "/../../../chrome/content/elemHideEmulation.js") ;
88 }).then(() => 104 }).then(() =>
89 { 105 {
90 return applyElemHideEmulation(selectors); 106 return loadElemHideEmulation();
91 }); 107 });
92 } 108 }
93 109
94 let elemHideEmulation = new ElemHideEmulation( 110 return Promise.resolve();
95 window, 111 }
96 callback => 112
97 { 113 // instantiate a ElemHideEmulation with @selectors.
98 let patterns = []; 114 function applyElemHideEmulation(selectors)
99 selectors.forEach(selector => 115 {
116 return loadElemHideEmulation().then(() =>
117 {
118 let elemHideEmulation = new ElemHideEmulation(
119 window,
120 callback =>
100 { 121 {
101 patterns.push({selector}); 122 let patterns = [];
102 }); 123 selectors.forEach(selector =>
103 callback(patterns); 124 {
104 }, newSelectors => 125 patterns.push({selector});
105 { 126 });
106 if (!newSelectors.length) 127 callback(patterns);
107 return; 128 },
108 let selector = newSelectors.join(", "); 129 newSelectors =>
109 insertStyleRule(selector + "{display: none !important;}"); 130 {
110 } 131 if (!newSelectors.length)
111 ); 132 return;
112 133 let selector = newSelectors.join(", ");
113 elemHideEmulation.apply(); 134 insertStyleRule(selector + "{display: none !important;}");
114 return Promise.resolve(); 135 },
115 } 136 elements =>
137 {
138 if (!elements.length)
139 return;
140 for (let element of elements)
141 element.style.display = "none";
142 }
143 );
144
145 elemHideEmulation.apply();
146 return Promise.resolve();
147 });
148 }
149
150 exports.testValidId = function(test)
151 {
152 loadElemHideEmulation().then(() =>
153 {
154 test.ok(!idValid(null));
155 test.ok(!idValid(undefined));
156 test.ok(!idValid(""));
157 test.ok(idValid("abcdef-u_"));
158 test.ok(idValid("-abdsc"));
159 test.ok(!idValid("--abdsc"));
160 test.ok(!idValid("0abcsd"));
161 test.ok(!idValid("-0abcsd"));
162 }).catch(unexpectedError.bind(test)).then(() => test.done());
163 }
164
165 exports.testParseSelector = function(test)
166 {
167 loadElemHideEmulation().then(() =>
168 {
169 let selectors = parseSelector("");
170 test.equal(selectors.length, 0);
171
172 let selector = "div > :-abp-properties('background-color: rgb(0, 0, 0)')";
173 selectors = parseSelector(selector);
174 test.equal(selectors.length, 2);
175 test.ok(selectors[0] instanceof PlainSelector);
176 test.ok(selectors[1] instanceof PropsSelector);
177
178 selector = "div > :-abp-has(> div.inside) > div";
179 selectors = parseSelector(selector);
180 test.equal(selectors.length, 3);
181 test.ok(selectors[0] instanceof PlainSelector);
182 test.ok(selectors[1] instanceof HasSelector);
183 test.ok(selectors[2] instanceof PlainSelector);
184
185 selector = "div > div:-abp-has(> div.inside) > div";
186 selectors = parseSelector(selector);
187
188 test.equal(selectors.length, 3);
189 test.ok(selectors[0] instanceof PlainSelector);
190 test.ok(selectors[1] instanceof HasSelector);
191 test.ok(selectors[2] instanceof PlainSelector);
192
193 selector = "div > :-abp-has(> div.inside) > :-abp-properties('background-col or: rgb(0, 0, 0)')";
194 selectors = parseSelector(selector);
195
196 test.equal(selectors.length, 4);
197 test.ok(selectors[0] instanceof PlainSelector);
198 test.ok(selectors[1] instanceof HasSelector);
199 test.ok(selectors[2] instanceof PlainSelector);
200 test.ok(selectors[3] instanceof PropsSelector);
201
202 selector = "div > :-abp-has(> div.inside > :-abp-properties('background-colo r: rgb(0, 0, 0)')";
203 selectors = parseSelector(selector);
204 test.equal(selectors, null);
205
206 // -abp-has-unsupported() is unknown. Ensure we fail parsing.
207 selector = 'div[arial-label="Story"]:-abp-has(> div > div > span > span:-abp -unsupported("Suggested Post"))';
208 selectors = parseSelector(selector);
209 test.equal(selectors, null);
210 }).catch(unexpectedError.bind(test)).then(() => test.done());
211 };
212
213 function buildDom(doc)
214 {
215 doc.body.innerHTML = `<div id="parent">
216 <div id="middle">
217 <div id="middle1"><div id="inside" class="inside"></div></div>
218 </div>
219 <div id="sibling">
220 <div id="tohide">to hide</div>
221 </div>
222 <div id="sibling2">
223 <div id="sibling21"><div id="sibling211" class="inside"></div></div>
224 </div>
225 </div>`;
226 let parent = document.getElementById("parent");
227 let middle = document.getElementById("middle");
228 let inside = document.getElementById("inside");
229 let sibling = document.getElementById("sibling");
230 let sibling2 = document.getElementById("sibling2");
231 let toHide = document.getElementById("tohide");
232 return {parent, middle, inside, sibling, sibling2, toHide};
233 }
234
235 exports.testPlainSelector = function(test)
236 {
237 let nodes = buildDom(document);
238
239 loadElemHideEmulation().then(() =>
240 {
241 let selector = new PlainSelector("div > div");
242
243 let iter = selector.getSelectors("foo > ");
244 let value = iter.next();
245 test.equal(value.value[0], "foo > div > div");
246 test.ok(iter.next().done);
247
248 iter = selector.getElements("", document, [document.sheet]);
249 value = iter.next();
250 test.ok(!value.done);
251 test.equal(value.value, nodes.middle);
252 value = iter.next();
253 test.ok(!value.done);
254 test.equal(value.value.id, "middle1");
255 value = iter.next();
256 test.ok(!value.done);
257 test.equal(value.value, nodes.inside);
258 }).catch(unexpectedError.bind(test)).then(() => test.done());
259 };
260
261 exports.testHasSelector = function(test)
262 {
263 buildDom(document);
264
265 loadElemHideEmulation().then(() =>
266 {
267 let selector = new HasSelector("> div.inside");
268
269 let iter = selector.getSelectors("", document, document.sheet);
270 let value = iter.next();
271 test.ok(!value.done);
272 test.equal(value.value[0], "#middle1");
273
274 iter = selector.getElements("", document, document.sheet);
275 value = iter.next();
276 test.ok(!value.done);
277 test.equal(value.value.id, "middle1");
278 value = iter.next();
279 test.ok(!value.done);
280 test.equal(value.value.id, "sibling21");
281 value = iter.next();
282 test.ok(value.done);
283 }).catch(unexpectedError.bind(test)).then(() => test.done());
284 };
285
286 exports.testSplitStyleRule = function(test)
287 {
288 loadElemHideEmulation().then(() =>
289 {
290 let selectors = splitSelector("div:-abp-has(div) > [-abp-properties='backgro und-color: rgb(0, 0, 0)'] > span");
291 test.ok(selectors);
292 test.equal(selectors.length, 1, "There is only one selector");
293
294 selectors = splitSelector("div:-abp-has(div), [-abp-properties='background-c olor: rgb(0, 0, 0)']");
295 test.ok(selectors);
296 test.equal(selectors.length, 2, "There are two selectors");
297 }).catch(unexpectedError.bind(test)).then(() => test.done());
298 };
116 299
117 exports.testVerbatimPropertySelector = function(test) 300 exports.testVerbatimPropertySelector = function(test)
118 { 301 {
119 let toHide = createElementWithStyle("{background-color: #000}"); 302 let toHide = createElementWithStyle("{background-color: #000}");
120 applyElemHideEmulation( 303 applyElemHideEmulation(
121 ["[-abp-properties='background-color: rgb(0, 0, 0)']"] 304 [":-abp-properties('background-color: rgb(0, 0, 0)')"]
122 ).then(() => 305 ).then(() =>
123 { 306 {
307 expectHidden(test, toHide);
308 }).catch(unexpectedError.bind(test)).then(() => test.done());
309 };
310
311 exports.testVerbatimPropertySelectorWithPrefix = function(test)
312 {
313 let parent = createElementWithStyle("{background-color: #000}");
314 let toHide = createElementWithStyle("{background-color: #000}", parent);
315 applyElemHideEmulation(
316 ["div > :-abp-properties('background-color: rgb(0, 0, 0)')"]
317 ).then(() =>
318 {
319 expectVisible(test, parent);
320 expectHidden(test, toHide);
321 }).catch(unexpectedError.bind(test)).then(() => test.done());
322 };
323
324 exports.testVerbatimPropertySelectorWithPrefixNoMatch = function(test)
325 {
326 let parent = createElementWithStyle("{background-color: #000}");
327 let toHide = createElementWithStyle("{background-color: #fff}", parent);
328 applyElemHideEmulation(
329 ["div > :-abp-properties('background-color: rgb(0, 0, 0)')"]
330 ).then(() =>
331 {
332 expectVisible(test, parent);
333 expectVisible(test, toHide);
334 }).catch(unexpectedError.bind(test)).then(() => test.done());
335 };
336
337 exports.testVerbatimPropertySelectorWithSuffix = function(test)
338 {
339 let parent = createElementWithStyle("{background-color: #000}");
340 let toHide = createElementWithStyle("{background-color: #000}", parent);
341 applyElemHideEmulation(
342 [":-abp-properties('background-color: rgb(0, 0, 0)') > div"]
343 ).then(() =>
344 {
345 expectVisible(test, parent);
346 expectHidden(test, toHide);
347 }).catch(unexpectedError.bind(test)).then(() => test.done());
348 };
349
350 exports.testVerbatimPropertyPseudoSelectorWithPrefixAndSuffix = function(test)
351 {
352 let parent = createElementWithStyle("{background-color: #000}");
353 let middle = createElementWithStyle("{background-color: #000}", parent);
354 let toHide = createElementWithStyle("{background-color: #000}", middle);
355 applyElemHideEmulation(
356 ["div > :-abp-properties('background-color: rgb(0, 0, 0)') > div"]
357 ).then(() =>
358 {
359 expectVisible(test, parent);
360 expectVisible(test, middle);
124 expectHidden(test, toHide); 361 expectHidden(test, toHide);
125 }).catch(unexpectedError.bind(test)).then(() => test.done()); 362 }).catch(unexpectedError.bind(test)).then(() => test.done());
126 }; 363 };
127 364
128 exports.testPropertySelectorWithWildcard = function(test) 365 exports.testPropertySelectorWithWildcard = function(test)
129 { 366 {
130 let toHide = createElementWithStyle("{background-color: #000}"); 367 let toHide = createElementWithStyle("{background-color: #000}");
131 applyElemHideEmulation( 368 applyElemHideEmulation(
132 ["[-abp-properties='*color: rgb(0, 0, 0)']"] 369 [":-abp-properties('*color: rgb(0, 0, 0)')"]
133 ).then(() => 370 ).then(() =>
134 { 371 {
135 expectHidden(test, toHide); 372 expectHidden(test, toHide);
136 }).catch(unexpectedError.bind(test)).then(() => test.done()); 373 }).catch(unexpectedError.bind(test)).then(() => test.done());
137 }; 374 };
138 375
139 exports.testPropertySelectorWithRegularExpression = function(test) 376 exports.testPropertySelectorWithRegularExpression = function(test)
140 { 377 {
141 let toHide = createElementWithStyle("{background-color: #000}"); 378 let toHide = createElementWithStyle("{background-color: #000}");
142 applyElemHideEmulation( 379 applyElemHideEmulation(
143 ["[-abp-properties='/.*color: rgb\\(0, 0, 0\\)/']"] 380 [":-abp-properties('/.*color: rgb\\(0, 0, 0\\)/')"]
144 ).then(() => 381 ).then(() =>
145 { 382 {
146 expectHidden(test, toHide); 383 expectHidden(test, toHide);
147 }).catch(unexpectedError.bind(test)).then(() => test.done()); 384 }).catch(unexpectedError.bind(test)).then(() => test.done());
148 }; 385 };
149 386
150 exports.testPropertySelectorWithEscapedBrace = function(test) 387 exports.testPropertySelectorWithEscapedBrace = function(test)
151 { 388 {
152 let toHide = createElementWithStyle("{background-color: #000}"); 389 let toHide = createElementWithStyle("{background-color: #000}");
153 applyElemHideEmulation( 390 applyElemHideEmulation(
154 ["[-abp-properties='/background.\\x7B 0,6\\x7D : rgb\\(0, 0, 0\\)/']"] 391 [":-abp-properties('/background.\\x7B 0,6\\x7D : rgb\\(0, 0, 0\\)/')"]
155 ).then(() => 392 ).then(() =>
156 { 393 {
157 expectHidden(test, toHide); 394 expectHidden(test, toHide);
158 }).catch(unexpectedError.bind(test)).then(() => test.done()); 395 }).catch(unexpectedError.bind(test)).then(() => test.done());
159 }; 396 };
160 397
161 exports.testPropertySelectorWithImproperlyEscapedBrace = function(test) 398 exports.testPropertySelectorWithImproperlyEscapedBrace = function(test)
162 { 399 {
163 let toHide = createElementWithStyle("{background-color: #000}"); 400 let toHide = createElementWithStyle("{background-color: #000}");
164 applyElemHideEmulation( 401 applyElemHideEmulation(
165 ["[-abp-properties='/background.\\x7B0,6\\x7D: rgb\\(0, 0, 0\\)/']"] 402 [":-abp-properties('/background.\\x7B0,6\\x7D: rgb\\(0, 0, 0\\)/')"]
166 ).then(() => 403 ).then(() =>
167 { 404 {
168 expectVisible(test, toHide); 405 expectVisible(test, toHide);
169 }).catch(unexpectedError.bind(test)).then(() => test.done()); 406 }).catch(unexpectedError.bind(test)).then(() => test.done());
170 }; 407 };
171 408
172 exports.testDynamicallyChangedProperty = function(test) 409 exports.testDynamicallyChangedProperty = function(test)
173 { 410 {
174 let toHide = createElementWithStyle("{}"); 411 let toHide = createElementWithStyle("{}");
175 applyElemHideEmulation( 412 applyElemHideEmulation(
176 ["[-abp-properties='background-color: rgb(0, 0, 0)']"] 413 [":-abp-properties('background-color: rgb(0, 0, 0)')"]
177 ).then(() => 414 ).then(() =>
178 { 415 {
179 expectVisible(test, toHide); 416 expectVisible(test, toHide);
180 insertStyleRule("#" + toHide.id + " {background-color: #000}"); 417 insertStyleRule("#" + toHide.id + " {background-color: #000}");
181 return new Promise((resolve, reject) => 418 return new Promise((resolve, reject) =>
182 { 419 {
183 window.setTimeout(() => 420 window.setTimeout(() =>
184 { 421 {
185 expectHidden(test, toHide); 422 expectHidden(test, toHide);
186 resolve(); 423 resolve();
187 }, 0); 424 }, 0);
188 }); 425 });
189 }).catch(unexpectedError.bind(test)).then(() => test.done()); 426 }).catch(unexpectedError.bind(test)).then(() => test.done());
190 }; 427 };
428
429 exports.testPseudoClassHasSelector = function(test)
430 {
431 let toHide = createElementWithStyle("{}");
432 applyElemHideEmulation(
433 ["div:-abp-has(div)"]
434 ).then(() =>
435 {
436 expectVisible(test, toHide);
437 }).catch(unexpectedError.bind(test)).then(() => test.done());
438 };
439
440 exports.testPseudoClassHasSelectorWithPrefix = function(test)
441 {
442 let parent = createElementWithStyle("{}");
443 let child = createElementWithStyle("{}", parent);
444 applyElemHideEmulation(
445 ["div:-abp-has(div)"]
446 ).then(() =>
447 {
448 expectHidden(test, parent);
449 expectVisible(test, child);
450 }).catch(unexpectedError.bind(test)).then(() => test.done());
451 };
452
453 exports.testPseudoClassHasSelectorWithSuffix = function(test)
454 {
455 let parent = createElementWithStyle("{}");
456 let middle = createElementWithStyle("{}", parent);
457 let child = createElementWithStyle("{}", middle);
458 applyElemHideEmulation(
459 ["div:-abp-has(div) > div"]
460 ).then(() =>
461 {
462 expectVisible(test, parent);
463 expectHidden(test, middle);
464 expectHidden(test, child);
465 }).catch(unexpectedError.bind(test)).then(() => test.done());
466 };
467
468 exports.testPseudoClassHasSelectorWithSuffixSibling = function(test)
469 {
470 let parent = createElementWithStyle("{}");
471 let middle = createElementWithStyle("{}", parent);
472 let toHide = createElementWithStyle("{}");
473 applyElemHideEmulation(
474 ["div:-abp-has(div) + div"]
475 ).then(() =>
476 {
477 expectVisible(test, parent);
478 expectVisible(test, middle);
479 expectHidden(test, toHide);
480 }).catch(unexpectedError.bind(test)).then(() => test.done());
481 };
482
483 exports.testPseudoClassHasSelectorWithSuffixSiblingChild = function(test)
484 {
485 // <div>
486 // <div></div>
487 // <div>
488 // <div>to hide</div>
489 // </div>
490 // </div>
491 let parent = createElementWithStyle("{}");
492 let middle = createElementWithStyle("{}", parent);
493 let sibling = createElementWithStyle("{}");
494 let toHide = createElementWithStyle("{}", sibling);
495 applyElemHideEmulation(
496 ["div:-abp-has(div) + div > div"]
497 ).then(() =>
498 {
499 expectVisible(test, parent);
500 expectVisible(test, middle);
501 expectVisible(test, sibling);
502 expectHidden(test, toHide);
503 }).catch(unexpectedError.bind(test)).then(() => test.done());
504 };
505
506 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector )
507 {
508 document.body.innerHTML = `<div id="parent">
509 <div id="middle">
510 <div id="middle1"><div id="inside" class="inside"></div></div>
511 </div>
512 <div id="sibling">
513 <div id="tohide">to hide</div>
514 </div>
515 <div id="sibling2">
516 <div id="sibling21"><div id="sibling211" class="inside"></div></div>
517 </div>
518 </div>`;
519 let parent = document.getElementById("parent");
520 let middle = document.getElementById("middle");
521 let inside = document.getElementById("inside");
522 let sibling = document.getElementById("sibling");
523 let sibling2 = document.getElementById("sibling2");
524 let toHide = document.getElementById("tohide");
525
526 insertStyleRule(".inside {}");
527
528 applyElemHideEmulation(
529 [selector]
530 ).then(() =>
531 {
532 expectVisible(test, parent);
533 expectVisible(test, middle);
534 expectVisible(test, inside);
535 expectVisible(test, sibling);
536 expectVisible(test, sibling2);
537 expectHidden(test, toHide);
538 }).catch(unexpectedError.bind(test)).then(() => test.done());
539 }
540
541 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test)
542 {
543 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div:-abp-has(: -abp-has(div.inside)) + div > div");
544 };
545
546 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = function(test)
547 {
548 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div:-abp-has(: -abp-has(> div.inside)) + div > div");
549 };
550
551 exports.testPseudoClassHasSelectorWithPropSelector = function(test)
552 {
553 let parent = createElementWithStyle("{}");
554 let child = createElementWithStyle("{background-color: #000}", parent);
555 applyElemHideEmulation(
556 ["div:-abp-has(:-abp-properties(\"background-color: rgb(0, 0, 0)\"))"]
557 ).then(() =>
558 {
559 expectVisible(test, child);
560 expectHidden(test, parent);
561 }).catch(unexpectedError.bind(test)).then(() => test.done());
562 };
OLDNEW
« lib/filterClasses.js ('K') | « lib/filterClasses.js ('k') | test/filterClasses.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld