2018-04-07 13:56:56 +00:00
|
|
|
const fs = require( 'fs' ),
|
2018-04-14 00:24:35 +00:00
|
|
|
path = require( 'path' ),
|
2018-03-30 16:42:04 +00:00
|
|
|
logPath = process.env.LOG_DIR || path.join( __dirname, '/log' );
|
2016-12-19 16:39:29 +00:00
|
|
|
|
2018-03-30 16:42:04 +00:00
|
|
|
let ffmpeg;
|
|
|
|
|
|
|
|
|
|
// get current test title and clean it, to use it as file name
|
|
|
|
|
function fileName( title ) {
|
|
|
|
|
return encodeURIComponent( title.replace( /\s+/g, '-' ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// build file path
|
|
|
|
|
function filePath( test, screenshotPath, extension ) {
|
|
|
|
|
return path.join( screenshotPath, `${fileName( test.parent )}-${fileName( test.title )}.${extension}` );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// relative path
|
2016-12-19 16:39:29 +00:00
|
|
|
function relPath( foo ) {
|
|
|
|
|
return path.resolve( __dirname, '../..', foo );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exports.config = {
|
|
|
|
|
// ======
|
2018-04-14 00:24:35 +00:00
|
|
|
// Custom WDIO config specific to MediaWiki
|
2016-12-19 16:39:29 +00:00
|
|
|
// ======
|
2018-04-14 00:24:35 +00:00
|
|
|
// Use in a test as `browser.options.<key>`.
|
|
|
|
|
// Defaults are for convenience with MediaWiki-Vagrant
|
2018-05-02 17:48:24 +00:00
|
|
|
|
|
|
|
|
// Wiki admin
|
2018-04-14 00:24:35 +00:00
|
|
|
username: process.env.MEDIAWIKI_USER || 'Admin',
|
|
|
|
|
password: process.env.MEDIAWIKI_PASSWORD || 'vagrant',
|
|
|
|
|
|
2018-05-02 17:48:24 +00:00
|
|
|
// Base for browser.url() and Page#openTitle()
|
|
|
|
|
baseUrl: ( process.env.MW_SERVER || 'http://127.0.0.1:8080' ) + (
|
|
|
|
|
process.env.MW_SCRIPT_PATH || '/w'
|
|
|
|
|
),
|
|
|
|
|
|
2017-03-31 11:47:17 +00:00
|
|
|
// ======
|
|
|
|
|
// Sauce Labs
|
|
|
|
|
// ======
|
2018-05-02 17:48:24 +00:00
|
|
|
// See http://webdriver.io/guide/services/sauce.html
|
|
|
|
|
// and https://docs.saucelabs.com/reference/platforms-configurator
|
2017-03-31 11:47:17 +00:00
|
|
|
services: [ 'sauce' ],
|
|
|
|
|
user: process.env.SAUCE_USERNAME,
|
|
|
|
|
key: process.env.SAUCE_ACCESS_KEY,
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2018-05-02 17:48:24 +00:00
|
|
|
// Default timeout in milliseconds for Selenium Grid requests
|
|
|
|
|
connectionRetryTimeout: 90 * 1000,
|
|
|
|
|
|
|
|
|
|
// Default request retries count
|
|
|
|
|
connectionRetryCount: 3,
|
|
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
// ==================
|
2018-05-02 17:48:24 +00:00
|
|
|
// Test Files
|
2016-12-19 16:39:29 +00:00
|
|
|
// ==================
|
|
|
|
|
specs: [
|
2018-05-02 17:48:24 +00:00
|
|
|
relPath( './tests/selenium/wdio-mediawiki/specs/*.js' ),
|
2016-12-19 16:39:29 +00:00
|
|
|
relPath( './tests/selenium/specs/**/*.js' ),
|
|
|
|
|
relPath( './extensions/*/tests/selenium/specs/**/*.js' ),
|
2017-08-25 14:51:05 +00:00
|
|
|
relPath( './extensions/VisualEditor/modules/ve-mw/tests/selenium/specs/**/*.js' ),
|
2018-06-19 15:04:09 +00:00
|
|
|
relPath( './extensions/Wikibase/repo/tests/selenium/specs/**/*.js' ),
|
2017-12-21 16:28:58 +00:00
|
|
|
relPath( './skins/*/tests/selenium/specs/**/*.js' )
|
2016-12-19 16:39:29 +00:00
|
|
|
],
|
2018-05-02 17:48:24 +00:00
|
|
|
// Patterns to exclude
|
2016-12-19 16:39:29 +00:00
|
|
|
exclude: [
|
2018-05-02 03:42:05 +00:00
|
|
|
relPath( './extensions/CirrusSearch/tests/selenium/specs/**/*.js' )
|
2016-12-19 16:39:29 +00:00
|
|
|
],
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
// ============
|
|
|
|
|
// Capabilities
|
|
|
|
|
// ============
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2018-05-02 17:48:24 +00:00
|
|
|
// How many instances of the same capability (browser) may be started at the same time.
|
2016-12-19 16:39:29 +00:00
|
|
|
maxInstances: 1,
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
capabilities: [ {
|
2018-05-02 17:48:24 +00:00
|
|
|
// For Chrome/Chromium https://sites.google.com/a/chromium.org/chromedriver/capabilities
|
2016-12-19 16:39:29 +00:00
|
|
|
browserName: 'chrome',
|
2018-05-02 17:48:24 +00:00
|
|
|
maxInstances: 1,
|
2016-12-19 16:39:29 +00:00
|
|
|
chromeOptions: {
|
2018-05-02 17:48:24 +00:00
|
|
|
// If DISPLAY is set, assume developer asked non-headless or CI with Xvfb.
|
2018-04-14 00:24:35 +00:00
|
|
|
// Otherwise, use --headless (added in Chrome 59)
|
|
|
|
|
// https://chromium.googlesource.com/chromium/src/+/59.0.3030.0/headless/README.md
|
2018-05-02 17:48:24 +00:00
|
|
|
args: [
|
|
|
|
|
...( process.env.DISPLAY ? [] : [ '--headless' ] ),
|
2018-04-14 00:24:35 +00:00
|
|
|
// Chrome sandbox does not work in Docker
|
2018-05-02 17:48:24 +00:00
|
|
|
...( fs.existsSync( '/.dockerenv' ) ? [ '--no-sandbox' ] : [] )
|
|
|
|
|
]
|
2016-12-19 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
} ],
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
// ===================
|
|
|
|
|
// Test Configurations
|
|
|
|
|
// ===================
|
2018-05-02 17:48:24 +00:00
|
|
|
|
|
|
|
|
// Enabling synchronous mode (via the wdio-sync package), means specs don't have to
|
|
|
|
|
// use Promise#then() or await for browser commands, such as like `brower.element()`.
|
|
|
|
|
// Instead, it will automatically pause JavaScript execution until th command finishes.
|
2016-12-19 16:39:29 +00:00
|
|
|
//
|
2018-05-02 17:48:24 +00:00
|
|
|
// For non-browser commands (such as MWBot and other promises), this means you
|
|
|
|
|
// have to use `browser.call()` to make sure WDIO waits for it before the next
|
|
|
|
|
// browser command.
|
2016-12-19 16:39:29 +00:00
|
|
|
sync: true,
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
// Level of logging verbosity: silent | verbose | command | data | result | error
|
|
|
|
|
logLevel: 'error',
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
// Enables colors for log output.
|
|
|
|
|
coloredLogs: true,
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2018-03-29 14:12:35 +00:00
|
|
|
// Warns when a deprecated command is used
|
|
|
|
|
deprecationWarnings: true,
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2018-05-02 17:48:24 +00:00
|
|
|
// Stop the tests once a certain number of failed tests have been recorded.
|
|
|
|
|
// Default is 0 - don't bail, run all tests.
|
2018-03-29 14:12:35 +00:00
|
|
|
bail: 0,
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2018-05-02 17:48:24 +00:00
|
|
|
// Setting this enables automatic screenshots for when a browser command fails
|
|
|
|
|
// It is also used by afterTest for capturig failed assertions.
|
2018-04-07 13:56:56 +00:00
|
|
|
screenshotPath: logPath,
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2018-05-02 17:48:24 +00:00
|
|
|
// Default timeout for each waitFor* command.
|
|
|
|
|
waitforTimeout: 10 * 1000,
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
// Framework you want to run your specs with.
|
2018-05-02 17:48:24 +00:00
|
|
|
// See also: http://webdriver.io/guide/testrunner/frameworks.html
|
2016-12-19 16:39:29 +00:00
|
|
|
framework: 'mocha',
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
// Test reporter for stdout.
|
2018-05-02 17:48:24 +00:00
|
|
|
// See also: http://webdriver.io/guide/testrunner/reporters.html
|
2018-04-07 13:56:56 +00:00
|
|
|
reporters: [ 'spec', 'junit' ],
|
|
|
|
|
reporterOptions: {
|
|
|
|
|
junit: {
|
|
|
|
|
outputDir: logPath
|
|
|
|
|
}
|
|
|
|
|
},
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
// Options to be passed to Mocha.
|
|
|
|
|
// See the full list at http://mochajs.org/
|
|
|
|
|
mochaOpts: {
|
|
|
|
|
ui: 'bdd',
|
2018-05-02 17:48:24 +00:00
|
|
|
timeout: 60 * 1000
|
2016-12-19 16:39:29 +00:00
|
|
|
},
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2016-12-19 16:39:29 +00:00
|
|
|
// =====
|
|
|
|
|
// Hooks
|
|
|
|
|
// =====
|
2018-05-02 17:48:24 +00:00
|
|
|
// See also: http://webdriver.io/guide/testrunner/configurationfile.html
|
2018-04-14 00:24:35 +00:00
|
|
|
|
2018-03-30 16:42:04 +00:00
|
|
|
/**
|
|
|
|
|
* Function to be executed before a test (in Mocha/Jasmine) or a step (in Cucumber) starts.
|
|
|
|
|
* @param {Object} test test details
|
|
|
|
|
*/
|
|
|
|
|
beforeTest: function ( test ) {
|
|
|
|
|
if ( process.env.DISPLAY && process.env.DISPLAY.startsWith( ':' ) ) {
|
|
|
|
|
let videoPath = filePath( test, this.screenshotPath, 'mp4' );
|
|
|
|
|
const { spawn } = require( 'child_process' );
|
|
|
|
|
ffmpeg = spawn( 'ffmpeg', [
|
|
|
|
|
'-f', 'x11grab', // grab the X11 display
|
|
|
|
|
'-video_size', '1280x1024', // video size
|
|
|
|
|
'-i', process.env.DISPLAY, // input file url
|
|
|
|
|
'-loglevel', 'error', // log only errors
|
|
|
|
|
'-y', // overwrite output files without asking
|
|
|
|
|
'-pix_fmt', 'yuv420p', // QuickTime Player support, "Use -pix_fmt yuv420p for compatibility with outdated media players"
|
|
|
|
|
videoPath // output file
|
|
|
|
|
] );
|
|
|
|
|
|
|
|
|
|
ffmpeg.stdout.on( 'data', ( data ) => {
|
|
|
|
|
console.log( `ffmpeg stdout: ${data}` );
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
ffmpeg.stderr.on( 'data', ( data ) => {
|
|
|
|
|
console.log( `ffmpeg stderr: ${data}` );
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
ffmpeg.on( 'close', ( code ) => {
|
|
|
|
|
console.log( '\n\tVideo location:', videoPath, '\n' );
|
|
|
|
|
console.log( `ffmpeg exited with code ${code}` );
|
|
|
|
|
} );
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2018-03-29 14:12:35 +00:00
|
|
|
/**
|
2018-05-02 17:48:24 +00:00
|
|
|
* Save a screenshot when test fails.
|
|
|
|
|
*
|
|
|
|
|
* @param {Object} test Mocha Test object
|
2018-04-14 00:24:35 +00:00
|
|
|
*/
|
2017-07-06 08:54:21 +00:00
|
|
|
afterTest: function ( test ) {
|
2018-03-30 16:42:04 +00:00
|
|
|
if ( ffmpeg ) {
|
|
|
|
|
// stop video recording
|
|
|
|
|
ffmpeg.kill( 'SIGINT' );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if test passed, ignore, else take and save screenshot
|
|
|
|
|
if ( test.passed ) {
|
|
|
|
|
return;
|
selenium: Create local ./log directory if needed
Without this, the tests sometimes fail like this:
> Error: ENOENT: no such file or directory, open './log/should-be-creatable.png'
> at screenshot() - saveScreenshot.js:52:17
> at saveScreenshot("./log/should-be-creatable.png")
This seems to race with the junit plugin, which uses mkdirp to
create it if missing, but the screenshot handling is separate
from that. WebdriverIO's own screenshot handling also does this
so it makes sense for ours to do that, too.
I considered trying to re-use WebdriverIO's save mechanism,
directly but it's not publicly exposed and only used for the
crash scenario, so for now we'll have to keep our own.
Also:
* Add to gitignore.
* Update default to use __dirname instead of './' because the
latter will somtimes be mediawiki/ and sometimes be selenium/
depending on whether you run all tests or some tests.
* Remove trailing slash from default logPath, and instead add the
slash in filePath.
Reason:
- The LOG_DIR used by Jenkins doesn't end in a slash either
(currently not failing because we no longer use that job,
and let quibble run the tests instead, which doesn't set
the LOG_DIR).
- The WDIO docs and example also use screenshotPath without
trailing slash.
- Without this, setting LOG_DIR=/tmp/something results in
filenames like /tmp/somethingexample.png.
Bug: T193088
Change-Id: I6550f9315bae89f96a791f7ae8cc2fbec5ee8dd5
2018-05-02 22:47:16 +00:00
|
|
|
}
|
2018-03-30 16:42:04 +00:00
|
|
|
// save screenshot
|
|
|
|
|
let screenshotPath = filePath( test, this.screenshotPath, 'png' );
|
|
|
|
|
browser.saveScreenshot( screenshotPath );
|
|
|
|
|
console.log( '\n\tScreenshot location:', screenshotPath, '\n' );
|
2017-12-21 16:28:58 +00:00
|
|
|
}
|
2016-12-19 16:39:29 +00:00
|
|
|
};
|