UNPKG

axe-core

Version:

Accessibility engine for automated Web UI testing

189 lines (164 loc) • 4.79 kB
/*global window */ /*eslint max-statements: ["error", 20], */ 'use strict'; var Promise = require('promise'); var WebDriver = require('selenium-webdriver'); module.exports = function (grunt) { /** * Keep injecting scripts until window.mochaResults is set */ function collectTestResults(driver) { // inject a script that waits half a second return driver.executeAsyncScript(function () { var callback = arguments[arguments.length - 1]; setTimeout(function () { // return the mocha results (or undefined if not finished) callback(window.mochaResults); }, 500); }).then(function (result) { // If there are no results, listen a little longer if (!result) { return collectTestResults(driver); // if there are, return them } else { return Promise.resolve(result); } }); } /** * Test each URL */ function runTestUrls(driver, isMobile, urls, errors) { var url = urls.shift(); errors = errors || []; // Give each page enough time driver.manage().timeouts().setScriptTimeout(!isMobile ? 60000 * 5 : (60000 * 10)); return driver.get(url) // Get results .then(function () { return collectTestResults(driver); }) // And process them .then(function (result) { grunt.log.writeln(url); // Remember the errors (result.reports || []).forEach(function (err) { grunt.log.error(err.message); err.url = url; errors.push(err); }); // Log the result of the page tests grunt.log[(result.failures ? 'error' : 'ok')]( 'passes: ' + result.passes + ', ' + 'failures: ' + result.failures + ', ' + 'duration: ' + (result.duration / 1000) + 's' ); grunt.log.writeln(); }).then(function () { // Start the next job, if any if (urls.length > 0) { return runTestUrls(driver, isMobile, urls, errors); } else { driver.quit(); return Promise.resolve(errors); } }); } /* * Build web driver depends whether REMOTE_SELENIUM_URL is set */ function buildWebDriver(browser) { var webdriver, capabilities; var mobileBrowser = browser.split('-mobile'); if (mobileBrowser.length > 1) { browser = mobileBrowser[0]; capabilities = { browserName: mobileBrowser[0], chromeOptions: { mobileEmulation: { deviceMetrics: { width: 320, height: 568, pixelRatio: 2 } } } }; } if (process.env.REMOTE_SELENIUM_URL) { webdriver = new WebDriver.Builder() .forBrowser(browser) .withCapabilities(capabilities) .usingServer(process.env.REMOTE_SELENIUM_URL) .build(); } else { webdriver = new WebDriver.Builder() .withCapabilities(capabilities) .forBrowser(browser) .build(); } return { driver: webdriver, isMobile: (mobileBrowser.length > 1) }; } /** * Run all tests in a browser using webdriver */ grunt.registerMultiTask('test-webdriver', 'Task for launching Webdriver with options and running tests against options URLs', function () { var driver; var isMobile = false; var done = this.async(); var options = this.options({ browser: 'firefox' }); // yes, really, and this isn't documented anywhere either. options.browser = (options.browser === 'edge') ? 'MicrosoftEdge' : options.browser; if ((process.platform === 'win32' && options.browser === 'safari') || (process.platform === 'darwin' && ['ie', 'MicrosoftEdge'].indexOf(options.browser) !== -1) || ((process.platform === 'linux' || process.env.REMOTE_SELENIUM_URL) && ['ie', 'MicrosoftEdge', 'safari'].indexOf(options.browser) !== -1) ) { grunt.log.writeln(); grunt.log.writeln('Skipped ' + options.browser + ' as it is not supported on this platform'); return done(); } // try to load the browser try { var webDriver = buildWebDriver(options.browser); driver = webDriver.driver; isMobile = webDriver.isMobile; // If load fails, warn user and move to the next task } catch (err) { grunt.log.writeln(); grunt.log.error(err.message); grunt.log.writeln('Aborted testing using ' + options.browser); return done(); } // Test all pages runTestUrls(driver, isMobile, options.urls) .then(function (testErrors) { // log each error and abort testErrors.forEach(function (err) { grunt.log.writeln(); grunt.log.error('URL: ' + err.url); grunt.log.error('Describe: ' + err.titles.join(' > ')); grunt.log.error('it ' + err.name); grunt.log.error(err.stack); grunt.log.writeln(); }); // Return the success to Grunt done(testErrors.length === 0); // catch any potential problems }).catch(function (err) { grunt.log.error(err); done(false); }); } ); };