selenium: Replace ES5 one-var assignments with const/let per line
[lhc/web/wiklou.git] / tests / selenium / wdio.conf.js
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' );
6
7 let ffmpeg;
8
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, '-' ) );
12 }
13
14 // build file path
15 function filePath( test, screenshotPath, extension ) {
16 return path.join( screenshotPath, `${fileName( test.parent )}-${fileName( test.title )}.${extension}` );
17 }
18
19 /**
20 * For more details documentation and available options,
21 * see <https://webdriver.io/docs/configurationfile.html>
22 * and <https://webdriver.io/docs/options.html>.
23 */
24 exports.config = {
25 // ======
26 // Custom conf keys for MediaWiki
27 //
28 // Access via `browser.config.<key>`.
29 // Defaults are for MediaWiki-Vagrant
30 // ======
31 mwUser: process.env.MEDIAWIKI_USER || 'Admin',
32 mwPwd: process.env.MEDIAWIKI_PASSWORD || 'vagrant',
33
34 // ==================
35 // Runner Configuration
36 // ==================
37 runner: 'local',
38 // The standalone chromedriver (also used by WMF CI) uses "/wd/hub".
39 // The one provided by wdio uses "/".
40 path: startChromedriver ? '/' : '/wd/hub',
41
42 // ======
43 // Sauce Labs
44 // ======
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,
49 sauceConnect: true,
50
51 // ==================
52 // Test Files
53 // ==================
54 specs: [
55 './tests/selenium/wdio-mediawiki/specs/*.js',
56 './tests/selenium/specs/**/*.js'
57 ],
58
59 // ============
60 // Capabilities
61 // Define the different browser configurations to use ("capabilities") here.
62 // ============
63 maxInstances: 1,
64 capabilities: [ {
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.
70 args: [
71 ...( process.env.DISPLAY ? [] : [ '--headless' ] ),
72 // Chrome sandbox does not work in Docker
73 ...( fs.existsSync( '/.dockerenv' ) ? [ '--no-sandbox' ] : [] )
74 ]
75 }
76 } ],
77
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
83 logLevel: 'error',
84 // Stop after this many failures, or 0 to run all tests before reporting failures.
85 bail: 0,
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'
89 ),
90 services: [
91 ...( startChromedriver ? [ 'chromedriver' ] : [] ),
92 ...( process.env.SAUCE_ACCESS_KEY ? [ 'sauce' ] : [] )
93 ],
94 // See also: https://webdriver.io/docs/frameworks.html
95 framework: 'mocha',
96 // See also: https://webdriver.io/docs/dot-reporter.html
97 reporters: [
98 'dot',
99 // See also: https://webdriver.io/docs/junit-reporter.html#configuration
100 [ 'junit', {
101 outputDir: logPath
102 } ]
103 ],
104 // See also: http://mochajs.org/
105 mochaOpts: {
106 ui: 'bdd',
107 timeout: 60 * 1000
108 },
109
110 // =====
111 // Hooks
112 // =====
113 /**
114 * Executed before a Mocha test starts.
115 * @param {Object} test Mocha Test object
116 */
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
129 ] );
130
131 const logBuffer = function ( buffer, prefix ) {
132 const lines = buffer.toString().trim().split( '\n' );
133 lines.forEach( function ( line ) {
134 console.log( prefix + line );
135 } );
136 };
137
138 ffmpeg.stdout.on( 'data', ( data ) => {
139 logBuffer( data, 'ffmpeg stdout: ' );
140 } );
141
142 ffmpeg.stderr.on( 'data', ( data ) => {
143 logBuffer( data, 'ffmpeg stderr: ' );
144 } );
145
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}` );
150 }
151 if ( signal !== null ) {
152 console.log( `\tffmpeg received signal ${signal} ${videoPath}` );
153 }
154 } );
155 }
156 },
157 /**
158 * Executed after a Mocha test ends.
159 * @param {Object} test Mocha Test object
160 */
161 afterTest: function ( test ) {
162 if ( ffmpeg ) {
163 // stop video recording
164 ffmpeg.kill( 'SIGINT' );
165 }
166
167 // if test passed, ignore, else take and save screenshot
168 if ( test.passed ) {
169 return;
170 }
171 // save screenshot
172 const screenshotfile = filePath( test, logPath, 'png' );
173 browser.saveScreenshot( screenshotfile );
174 console.log( '\n\tScreenshot location:', screenshotfile, '\n' );
175 }
176 };