| Index: test/wrappers/pages.js |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/test/wrappers/pages.js |
| @@ -0,0 +1,157 @@ |
| +/* |
| + * This file is part of Adblock Plus <https://adblockplus.org/>, |
| + * Copyright (C) 2006-present eyeo GmbH |
| + * |
| + * Adblock Plus is free software: you can redistribute it and/or modify |
| + * it under the terms of the GNU General Public License version 3 as |
| + * published by the Free Software Foundation. |
| + * |
| + * Adblock Plus is distributed in the hope that it will be useful, |
| + * 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/>. |
| + */ |
| + |
| +"use strict"; |
| + |
| +const TEST_PAGES_URL = "https://testpages.adblockplus.org/"; |
| + |
| +const assert = require("assert"); |
| +const Jimp = require("jimp"); |
| +const {By} = require("selenium-webdriver"); |
| + |
| +function imageFromBase64(s) |
| +{ |
| + return Jimp.read(Buffer.from(s, "base64")); |
| +} |
| + |
| +function takeScreenshot(element) |
| +{ |
| + return element.takeScreenshot().then( |
| + imageFromBase64, |
| + |
| + // Chrome doesn't support taking screenshots of individual elements. So as |
| + // a workaround, we scroll to the position of the element, take a screenshot |
| + // of the viewport and crop it to the size and position of our element. |
| + // This is not guaranteed to work on other browsers (mostly because |
| + // the behavior of Driver.takeScreenshot() may vary across browsers). |
| + () => element.getLocation().then(loc => |
| + element.getDriver().executeScript(` |
| + window.scrollTo(${loc.x}, ${loc.y}); |
| + return [window.scrollX, window.scrollY]; |
| + `).then(result => |
| + { |
| + let x = loc.x - result[0]; |
| + let y = loc.y - result[1]; |
| + |
| + return Promise.all([ |
| + element.getDriver().takeScreenshot().then(imageFromBase64), |
| + element.getSize() |
| + ]).then(([img, size]) => |
| + img.crop(x, y, size.width, size.height) |
| + ); |
| + }) |
| + ) |
| + ).then(img => img.bitmap); |
| +} |
| + |
| +function getSections(driver) |
| +{ |
| + return driver.findElements(By.css("section")).then(elements => |
| + Promise.all(elements.map(e => |
| + Promise.all([ |
| + e.findElement(By.css("h2")).catch(() => null), |
| + e.findElement(By.className("testcase-container")).catch(() => null), |
| + e.findElements(By.css("pre")) |
| + ]) |
| + )) |
| + ).then(sections => sections.filter( |
| + ([title, demo, filters]) => title && demo && filters.length > 0 |
| + )); |
| +} |
| + |
| +it("test pages", function() |
| +{ |
| + return this.driver.navigate().to(TEST_PAGES_URL).then(() => |
| + this.driver.findElements(By.css(".site-pagelist a")) |
| + ).then(elements => |
| + Promise.all(elements.map(elem => elem.getAttribute("href"))) |
| + ).then(urls => |
| + { |
| + let p1 = Promise.resolve(); |
| + for (let url of urls) |
| + p1 = p1.then(() => |
| + this.driver.navigate().to(url) |
| + ).then(() => |
| + Promise.all([ |
| + getSections(this.driver), |
| + this.driver.findElement(By.css("h2")).getAttribute("textContent"), |
| + this.driver.executeScript("document.body.classList.add('expected');") |
| + ]) |
| + ).then(([sections, pageTitle]) => |
| + Promise.all(sections.map(([title, demo, filters]) => |
| + Promise.all([ |
| + title.getAttribute("textContent").then(testTitle => |
| + `${pageTitle.trim()} - ${testTitle.trim()}` |
| + ), |
| + takeScreenshot(demo), |
| + Promise.all(filters.map(elem => elem.getAttribute("textContent"))) |
| + ]) |
| + )) |
| + ).then(testCases => |
| + { |
| + let p2 = Promise.resolve(); |
| + for (let i = 0; i < testCases.length; i++) |
| + { |
| + let [title, expectedScreenshot, filters] = testCases[i]; |
| + let platform = this.test.parent.title; |
| + |
| + if (// https://issues.adblockplus.org/ticket/6917 |
| + title == "$subdocument - Test case" && platform == "gecko" || |
| + // Chromium doesn't support Flash |
| + /^\$object(-subrequest)? /.test(title) && platform == "chrome") |
| + continue; |
| + |
| + p2 = p2.then(() => |
| + this.driver.navigate().to(this.origin + "/options.html") |
| + ).then(() => |
| + this.driver.executeAsyncScript(` |
| + let filters = arguments[0]; |
| + let callback = arguments[arguments.length - 1]; |
| + browser.runtime.sendMessage({type: "subscriptions.get", |
| + downloadable: true, |
| + special: true}).then(subs => |
| + { |
| + for (let subscription of subs) |
| + browser.runtime.sendMessage({type: "subscriptions.remove", |
| + url: subscription.url}); |
| + return browser.runtime.sendMessage({type: "filters.importRaw", |
| + text: filters}); |
| + }).then(() => callback(), callback); |
| + `, filters.join("\n")) |
| + ).then(error => |
| + { |
| + if (error) |
| + throw error; |
| + return this.driver.navigate().to(url); |
| + }).then(() => |
| + getSections(this.driver) |
| + ).then(sections => |
| + takeScreenshot(sections[i][1]) |
| + ).then(screenshot => |
| + assert.ok( |
| + screenshot.width == expectedScreenshot.width && |
| + screenshot.height == expectedScreenshot.height && |
| + screenshot.data.compare(expectedScreenshot.data) == 0, |
| + title |
| + ) |
| + ); |
| + } |
| + return p2; |
| + }); |
| + return p1; |
| + }); |
| +}); |