1 /* eslint-disable no-console */
2 const fs
= require( 'fs' );
3 const path
= require( 'path' );
4 const startChromedriver
= !process
.argv
.includes( '--skip-chromedriver' );
5 const logPath
= process
.env
.LOG_DIR
|| path
.join( __dirname
, '/log' );
9 // get current test title and clean it, to use it as file name
10 function fileName( title
) {
11 return encodeURIComponent( title
.replace( /\s+/g, '-' ) );
15 function filePath( test
, screenshotPath
, extension
) {
16 return path
.join( screenshotPath
, `${fileName( test.parent )}-${fileName( test.title )}.${extension}` );
20 * For more details documentation and available options,
21 * see <https://webdriver.io/docs/configurationfile.html>
22 * and <https://webdriver.io/docs/options.html>.
26 // Custom conf keys for MediaWiki
28 // Access via `browser.config.<key>`.
29 // Defaults are for MediaWiki-Vagrant
31 mwUser
: process
.env
.MEDIAWIKI_USER
|| 'Admin',
32 mwPwd
: process
.env
.MEDIAWIKI_PASSWORD
|| 'vagrant',
35 // Runner Configuration
38 // The standalone chromedriver (also used by WMF CI) uses "/wd/hub".
39 // The one provided by wdio uses "/".
40 path
: startChromedriver
? '/' : '/wd/hub',
45 // See http://webdriver.io/guide/services/sauce.html
46 // and https://github.com/bermi/sauce-connect-launcher#advanced-usage
47 user
: process
.env
.SAUCE_USERNAME
,
48 key
: process
.env
.SAUCE_ACCESS_KEY
,
55 './tests/selenium/wdio-mediawiki/specs/*.js',
56 './tests/selenium/specs/**/*.js'
61 // Define the different browser configurations to use ("capabilities") here.
65 // For Chrome/Chromium https://sites.google.com/a/chromium.org/chromedriver/capabilities
66 browserName
: 'chrome',
67 'goog:chromeOptions': {
68 // If DISPLAY is set, assume developer asked non-headless or CI with Xvfb.
69 // Otherwise, use --headless.
71 ...( process
.env
.DISPLAY
? [] : [ '--headless' ] ),
72 // Chrome sandbox does not work in Docker
73 ...( fs
.existsSync( '/.dockerenv' ) ? [ '--no-sandbox' ] : [] )
78 // ===================
79 // Test Configurations
80 // Define all options that are relevant for the WebdriverIO instance here
81 // ===================
82 // Level of logging verbosity: trace | debug | info | warn | error | silent
84 // Stop after this many failures, or 0 to run all tests before reporting failures.
86 // Base for browser.url() and wdio-mediawiki/Page#openTitle()
87 baseUrl
: ( process
.env
.MW_SERVER
|| 'http://127.0.0.1:8080' ) + (
88 process
.env
.MW_SCRIPT_PATH
|| '/w'
91 ...( startChromedriver
? [ 'chromedriver' ] : [] ),
92 ...( process
.env
.SAUCE_ACCESS_KEY
? [ 'sauce' ] : [] )
94 // See also: https://webdriver.io/docs/frameworks.html
96 // See also: https://webdriver.io/docs/dot-reporter.html
99 // See also: https://webdriver.io/docs/junit-reporter.html#configuration
104 // See also: http://mochajs.org/
114 * Executed before a Mocha test starts.
115 * @param {Object} test Mocha Test object
117 beforeTest: function ( test
) {
118 if ( process
.env
.DISPLAY
&& process
.env
.DISPLAY
.startsWith( ':' ) ) {
119 const videoPath
= filePath( test
, logPath
, 'mp4' );
120 const { spawn
} = require( 'child_process' );
121 ffmpeg
= spawn( 'ffmpeg', [
122 '-f', 'x11grab', // grab the X11 display
123 '-video_size', '1280x1024', // video size
124 '-i', process
.env
.DISPLAY
, // input file url
125 '-loglevel', 'error', // log only errors
126 '-y', // overwrite output files without asking
127 '-pix_fmt', 'yuv420p', // QuickTime Player support, "Use -pix_fmt yuv420p for compatibility with outdated media players"
128 videoPath
// output file
131 const logBuffer = function ( buffer
, prefix
) {
132 const lines
= buffer
.toString().trim().split( '\n' );
133 lines
.forEach( function ( line
) {
134 console
.log( prefix
+ line
);
138 ffmpeg
.stdout
.on( 'data', ( data
) => {
139 logBuffer( data
, 'ffmpeg stdout: ' );
142 ffmpeg
.stderr
.on( 'data', ( data
) => {
143 logBuffer( data
, 'ffmpeg stderr: ' );
146 ffmpeg
.on( 'close', ( code
, signal
) => {
147 console
.log( '\n\tVideo location:', videoPath
, '\n' );
148 if ( code
!== null ) {
149 console
.log( `\tffmpeg exited with code ${code} ${videoPath}` );
151 if ( signal
!== null ) {
152 console
.log( `\tffmpeg received signal ${signal} ${videoPath}` );
158 * Executed after a Mocha test ends.
159 * @param {Object} test Mocha Test object
161 afterTest: function ( test
) {
163 // stop video recording
164 ffmpeg
.kill( 'SIGINT' );
167 // if test passed, ignore, else take and save screenshot
172 const screenshotfile
= filePath( test
, logPath
, 'png' );
173 browser
.saveScreenshot( screenshotfile
);
174 console
.log( '\n\tScreenshot location:', screenshotfile
, '\n' );