Merge "Selenium: record video of every test"
This commit is contained in:
commit
1658759d42
2 changed files with 79 additions and 8 deletions
|
|
@ -20,8 +20,26 @@ If using MediaWiki-Vagrant:
|
|||
|
||||
npm run selenium
|
||||
|
||||
By default, Chrome will run in headless mode. If you want to see Chrome, set DISPLAY
|
||||
environment variable to any value:
|
||||
There are three supported modes of running the tests:
|
||||
|
||||
- Headless. It's the default. You will not see the browser while tests are
|
||||
running because it's running in a headless mode. This mode should run fine
|
||||
on all supported platforms.
|
||||
- Headless recording. Set DISPLAY environment variable to a value that starts
|
||||
with colon (`:`) and video of each test will be recorded. Browser will run
|
||||
headless. Recording videos works only on Linux.
|
||||
- Visible. If you want to see the browser, set DISPLAY environment variable to
|
||||
any value that does not start with colon. This mode will not work in a
|
||||
headless environment like MediaWiki-Vagrant.
|
||||
|
||||
Example recording session:
|
||||
|
||||
sudo apt-get install chromedriver ffmpeg xvfb
|
||||
export DISPLAY=:94
|
||||
Xvfb "$DISPLAY" -screen 0 1280x1024x24 &
|
||||
npm run selenium
|
||||
|
||||
Example visible session:
|
||||
|
||||
DISPLAY=1 npm run selenium
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,20 @@
|
|||
const fs = require( 'fs' ),
|
||||
path = require( 'path' ),
|
||||
saveScreenshot = require( 'wdio-mediawiki' ).saveScreenshot,
|
||||
logPath = process.env.LOG_DIR || __dirname + '/log';
|
||||
logPath = process.env.LOG_DIR || path.join( __dirname, '/log' );
|
||||
|
||||
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
|
||||
function relPath( foo ) {
|
||||
return path.resolve( __dirname, '../..', foo );
|
||||
}
|
||||
|
|
@ -135,16 +147,57 @@ exports.config = {
|
|||
// =====
|
||||
// See also: http://webdriver.io/guide/testrunner/configurationfile.html
|
||||
|
||||
/**
|
||||
* 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}` );
|
||||
} );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Save a screenshot when test fails.
|
||||
*
|
||||
* @param {Object} test Mocha Test object
|
||||
*/
|
||||
afterTest: function ( test ) {
|
||||
var filePath;
|
||||
if ( !test.passed ) {
|
||||
filePath = saveScreenshot( test.title );
|
||||
console.log( '\n\tScreenshot: ' + filePath + '\n' );
|
||||
if ( ffmpeg ) {
|
||||
// stop video recording
|
||||
ffmpeg.kill( 'SIGINT' );
|
||||
}
|
||||
|
||||
// if test passed, ignore, else take and save screenshot
|
||||
if ( test.passed ) {
|
||||
return;
|
||||
}
|
||||
// save screenshot
|
||||
let screenshotPath = filePath( test, this.screenshotPath, 'png' );
|
||||
browser.saveScreenshot( screenshotPath );
|
||||
console.log( '\n\tScreenshot location:', screenshotPath, '\n' );
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue