From c3fa707adcd639291933898166a0c5d01f9e7d56 Mon Sep 17 00:00:00 2001 From: Ed Sanders Date: Fri, 24 Jun 2016 17:51:13 +0100 Subject: [PATCH] screenshots: Add multi-language support Change-Id: I1da41cffd946a76e5f09097decbc0a25562c9508 --- Gruntfile.js | 26 +- build/screenshots.js | 517 ++++++++++++++++--------------- build/tasks/screenshotLangs.json | 95 ++++++ 3 files changed, 379 insertions(+), 259 deletions(-) create mode 100644 build/tasks/screenshotLangs.json diff --git a/Gruntfile.js b/Gruntfile.js index 51af4a18cb..3932e8f788 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -56,10 +56,29 @@ module.exports = function ( grunt ) { } }, mochaTest: { - screenshots: { + 'screenshots-en': { options: { reporter: 'spec', - timeout: 20000 + timeout: 20000, + require: [ + function () { + /* jshint undef:false */ + langs = [ 'en' ]; + } + ] + }, + src: [ 'build/screenshots.js' ] + }, + 'screenshots-all': { + options: { + reporter: 'spec', + timeout: 20000, + require: [ + function () { + /* jshint undef:false */ + langs = require( './build/tasks/screenshotLangs.json' ).langs; + } + ] }, src: [ 'build/screenshots.js' ] } @@ -163,7 +182,8 @@ module.exports = function ( grunt ) { grunt.registerTask( 'fix', [ 'jscs:fix' ] ); grunt.registerTask( 'test', [ 'build', 'lint' ] ); grunt.registerTask( 'test-ci', [ 'git-status' ] ); - grunt.registerTask( 'screenshots', [ 'mochaTest:screenshots' ] ); + grunt.registerTask( 'screenshots', [ 'mochaTest:screenshots-en' ] ); + grunt.registerTask( 'screenshots-all', [ 'mochaTest:screenshots-all' ] ); grunt.registerTask( 'default', 'test' ); if ( process.env.JENKINS_HOME ) { diff --git a/build/screenshots.js b/build/screenshots.js index 986eaaedb3..207cc7af24 100644 --- a/build/screenshots.js +++ b/build/screenshots.js @@ -1,266 +1,271 @@ /* jshint node: true */ -/* global seleniumUtils */ - -var chrome = require( 'selenium-webdriver/chrome' ), +/* global seleniumUtils, langs */ +var i, l, + chrome = require( 'selenium-webdriver/chrome' ), test = require( 'selenium-webdriver/testing' ), fs = require( 'fs' ), - Jimp = require( 'jimp' ), - lang = 'en'; + Jimp = require( 'jimp' ); -test.describe( 'Screenshot', function () { - var driver; +function runTests( lang ) { + test.describe( 'Screenshots: ' + lang, function () { + var driver; - function runScreenshotTest( name, clientScript, padding ) { - var filename = './screenshots/' + name + '-' + lang + '.png'; - driver.get( 'http://en.wikipedia.beta.wmflabs.org/wiki/PageDoesNotExist?veaction=edit&uselang=' + lang ); - driver.wait( - driver.executeAsyncScript( + test.beforeEach( function () { + driver = new chrome.Driver(); + driver.manage().timeouts().setScriptTimeout( 20000 ); + driver.manage().window().setSize( 1200, 800 ); + } ); + + test.afterEach( function () { + driver.quit(); + } ); + + function runScreenshotTest( name, clientScript, padding ) { + var filename = './screenshots/' + name + '-' + lang + '.png'; + driver.get( 'http://en.wikipedia.beta.wmflabs.org/wiki/PageDoesNotExist?veaction=edit&uselang=' + lang ); + driver.wait( + driver.executeAsyncScript( + // This function is converted to a string and executed in the browser + function () { + var done = arguments[ arguments.length - 1 ]; + + window.seleniumUtils = { + getBoundingRect: function ( elements ) { + var i, l, rect, boundingRect; + for ( i = 0, l = elements.length; i < l; i++ ) { + rect = elements[ i ].getBoundingClientRect(); + if ( !boundingRect ) { + boundingRect = { + left: rect.left, + top: rect.top, + right: rect.right, + bottom: rect.bottom + }; + } else { + boundingRect.left = Math.min( boundingRect.left, rect.left ); + boundingRect.top = Math.min( boundingRect.top, rect.top ); + boundingRect.right = Math.max( boundingRect.right, rect.right ); + boundingRect.bottom = Math.max( boundingRect.bottom, rect.bottom ); + } + } + if ( boundingRect ) { + boundingRect.width = boundingRect.right - boundingRect.left; + boundingRect.height = boundingRect.bottom - boundingRect.top; + } + return boundingRect; + } + }; + + // Suppress welcome dialog + localStorage.setItem( 've-beta-welcome-dialog', 1 ); + // Suppress user education indicators + localStorage.setItem( 've-hideusered', 1 ); + mw.hook( 've.activationComplete' ).add( function () { + var target = ve.init.target, + surfaceView = target.getSurface().getView(); + // Hide edit notices + target.actionsToolbar.tools.notices.getPopup().toggle( false ); + // Modify the document to make the save button blue + // Wait for focus + surfaceView.once( 'focus', function () { + target.surface.getModel().getFragment().insertContent( ' ' ).collapseToStart().select(); + // Wait for save button fade + setTimeout( done, 100 ); + } ); + } ); + } + ).then( function () { + return driver.executeAsyncScript( clientScript ).then( function ( rect ) { + return driver.takeScreenshot().then( function ( base64Image ) { + var imageBuffer; + if ( rect ) { + imageBuffer = new Buffer( base64Image, 'base64' ); + return cropScreenshot( filename, imageBuffer, rect, padding ); + } else { + fs.writeFile( filename, base64Image, 'base64' ); + } + } ); + } ); + } ), + 20000 + ); + } + + function cropScreenshot( filename, imageBuffer, rect, padding ) { + if ( padding === undefined ) { + padding = 5; + } + + return Jimp.read( imageBuffer ).then( function ( jimpImage ) { + jimpImage + .crop( + rect.left - padding, + rect.top - padding, + rect.width + ( padding * 2 ), + rect.height + ( padding * 2 ) + ) + .write( filename ); + } ); + } + + test.it( 'Toolbar', function () { + runScreenshotTest( 'VisualEditor_toolbar', // This function is converted to a string and executed in the browser function () { var done = arguments[ arguments.length - 1 ]; - - window.seleniumUtils = { - getBoundingRect: function ( elements ) { - var i, l, rect, boundingRect; - for ( i = 0, l = elements.length; i < l; i++ ) { - rect = elements[ i ].getBoundingClientRect(); - if ( !boundingRect ) { - boundingRect = { - left: rect.left, - top: rect.top, - right: rect.right, - bottom: rect.bottom - }; - } else { - boundingRect.left = Math.min( boundingRect.left, rect.left ); - boundingRect.top = Math.min( boundingRect.top, rect.top ); - boundingRect.right = Math.max( boundingRect.right, rect.right ); - boundingRect.bottom = Math.max( boundingRect.bottom, rect.bottom ); - } - } - if ( boundingRect ) { - boundingRect.width = boundingRect.right - boundingRect.left; - boundingRect.height = boundingRect.bottom - boundingRect.top; - } - return boundingRect; - } - }; - - // Suppress welcome dialog - localStorage.setItem( 've-beta-welcome-dialog', 1 ); - // Suppress user education indicators - localStorage.setItem( 've-hideusered', 1 ); - mw.hook( 've.activationComplete' ).add( function () { - var target = ve.init.target, - surfaceView = target.getSurface().getView(); - // Hide edit notices - target.actionsToolbar.tools.notices.getPopup().toggle( false ); - // Modify the document to make the save button blue - // Wait for focus - surfaceView.once( 'focus', function () { - target.surface.getModel().getFragment().insertContent( ' ' ).collapseToStart().select(); - // Wait for save button fade - setTimeout( done, 100 ); - } ); - } ); - } - ).then( function () { - return driver.executeAsyncScript( clientScript ).then( function ( rect ) { - return driver.takeScreenshot().then( function ( base64Image ) { - var imageBuffer; - if ( rect ) { - imageBuffer = new Buffer( base64Image, 'base64' ); - return cropScreenshot( filename, imageBuffer, rect, padding ); - } else { - fs.writeFile( filename, base64Image, 'base64' ); - } - } ); - } ); - } ), - 20000 - ); - } - - function cropScreenshot( filename, imageBuffer, rect, padding ) { - if ( padding === undefined ) { - padding = 5; - } - - return Jimp.read( imageBuffer ).then( function ( jimpImage ) { - jimpImage - .crop( - rect.left - padding, - rect.top - padding, - rect.width + ( padding * 2 ), - rect.height + ( padding * 2 ) - ) - .write( filename ); + done( + seleniumUtils.getBoundingRect( [ + ve.init.target.toolbar.$element[ 0 ], + $( '#ca-nstab-main' )[ 0 ] + ] ) + ); + }, + 0 + ); } ); - } + test.it( 'Citoid inspector', function () { + runScreenshotTest( 'VisualEditor_Citoid_Inspector', + // This function is converted to a string and executed in the browser + function () { + var done = arguments[ arguments.length - 1 ]; + ve.init.target.toolbar.tools.citefromid.onSelect(); + setTimeout( function () { + var rect = ve.init.target.surface.context.inspectors.currentWindow.$element[ 0 ].getBoundingClientRect(); + done( { + top: rect.top - 20, + left: rect.left, + width: rect.width, + height: rect.height + 20 + } ); + }, 500 ); + } + ); + } ); + test.it( 'Headings tool list', function () { + runScreenshotTest( 'VisualEditor_Toolbar_Headings', + // This function is converted to a string and executed in the browser + function () { + var done = arguments[ arguments.length - 1 ], + toolGroup = ve.init.target.toolbar.tools.paragraph.toolGroup; + toolGroup.setActive( true ); + setTimeout( function () { + done( + seleniumUtils.getBoundingRect( [ + toolGroup.$element[ 0 ], + toolGroup.$group[ 0 ] + ] ) + ); + }, 500 ); + } + ); + } ); + test.it( 'Text style tool list', function () { + runScreenshotTest( 'VisualEditor_Toolbar_Formatting', + // This function is converted to a string and executed in the browser + function () { + var done = arguments[ arguments.length - 1 ], + toolGroup = ve.init.target.toolbar.tools.bold.toolGroup; + toolGroup.setActive( true ); + toolGroup.getExpandCollapseTool().onSelect(); + setTimeout( function () { + done( + seleniumUtils.getBoundingRect( [ + toolGroup.$element[ 0 ], + toolGroup.$group[ 0 ] + ] ) + ); + }, 500 ); + } + ); + } ); + test.it( 'Indentation tool list', function () { + runScreenshotTest( 'VisualEditor_Toolbar_List_and_indentation', + // This function is converted to a string and executed in the browser + function () { + var done = arguments[ arguments.length - 1 ], + toolGroup = ve.init.target.toolbar.tools.bullet.toolGroup; + toolGroup.setActive( true ); + setTimeout( function () { + done( + seleniumUtils.getBoundingRect( [ + toolGroup.$element[ 0 ], + toolGroup.$group[ 0 ] + ] ) + ); + }, 500 ); + } + ); + } ); + test.it( 'Page options list', function () { + runScreenshotTest( 'VisualEditor_More_Settings', + // This function is converted to a string and executed in the browser + function () { + var done = arguments[ arguments.length - 1 ], + toolGroup = ve.init.target.actionsToolbar.tools.advancedSettings.toolGroup; + toolGroup.setActive( true ); + setTimeout( function () { + done( + seleniumUtils.getBoundingRect( [ + toolGroup.$element[ 0 ], + toolGroup.$group[ 0 ], + // Include save button for context + ve.init.target.toolbarSaveButton.$element[ 0 ] + ] ) + ); + }, 500 ); + } + ); + } ); + test.it( 'Toolbar actions', function () { + runScreenshotTest( 'VisualEditor_toolbar_actions', + // This function is converted to a string and executed in the browser + function () { + var done = arguments[ arguments.length - 1 ]; + done( + seleniumUtils.getBoundingRect( [ + ve.init.target.toolbar.$actions[ 0 ] + ] ) + ); + }, + 0 + ); + } ); + test.it( 'Save dialog', function () { + runScreenshotTest( 'VisualEditor_save_dialog', + // This function is converted to a string and executed in the browser + function () { + var done = arguments[ arguments.length - 1 ]; + ve.init.target.toolbarSaveButton.emit( 'click' ); + setTimeout( function () { + done( + seleniumUtils.getBoundingRect( [ + ve.init.target.surface.dialogs.currentWindow.$frame[ 0 ] + ] ) + ); + }, 500 ); + } + ); + } ); + test.it( 'Special character inserter', function () { + runScreenshotTest( 'VisualEditor_Toolbar_SpecialCharacters', + // This function is converted to a string and executed in the browser + function () { + var done = arguments[ arguments.length - 1 ]; + ve.init.target.toolbar.tools.specialCharacter.onSelect(); + setTimeout( function () { + done( + seleniumUtils.getBoundingRect( [ + ve.init.target.toolbar.tools.specialCharacter.$element[ 0 ], + ve.init.target.surface.toolbarDialogs.$element[ 0 ] + ] + ) ); + }, 1000 ); + } + ); + } ); + } ); +} - test.beforeEach( function () { - driver = new chrome.Driver(); - driver.manage().timeouts().setScriptTimeout( 20000 ); - driver.manage().window().setSize( 1200, 800 ); - } ); - - test.afterEach( function () { - driver.quit(); - } ); - - test.it( 'Toolbar', function () { - runScreenshotTest( 'VisualEditor_toolbar', - // This function is converted to a string and executed in the browser - function () { - var done = arguments[ arguments.length - 1 ]; - done( - seleniumUtils.getBoundingRect( [ - ve.init.target.toolbar.$element[ 0 ], - $( '#ca-nstab-main' )[ 0 ] - ] ) - ); - }, - 0 - ); - } ); - test.it( 'Citoid inspector', function () { - runScreenshotTest( 'VisualEditor_Citoid_Inspector', - // This function is converted to a string and executed in the browser - function () { - var done = arguments[ arguments.length - 1 ]; - ve.init.target.toolbar.tools.citefromid.onSelect(); - setTimeout( function () { - var rect = ve.init.target.surface.context.inspectors.currentWindow.$element[ 0 ].getBoundingClientRect(); - done( { - top: rect.top - 20, - left: rect.left, - width: rect.width, - height: rect.height + 20 - } ); - }, 500 ); - } - ); - } ); - test.it( 'Headings tool list', function () { - runScreenshotTest( 'VisualEditor_Toolbar_Headings', - // This function is converted to a string and executed in the browser - function () { - var done = arguments[ arguments.length - 1 ], - toolGroup = ve.init.target.toolbar.tools.paragraph.toolGroup; - toolGroup.setActive( true ); - setTimeout( function () { - done( - seleniumUtils.getBoundingRect( [ - toolGroup.$element[ 0 ], - toolGroup.$group[ 0 ] - ] ) - ); - }, 500 ); - } - ); - } ); - test.it( 'Text style tool list', function () { - runScreenshotTest( 'VisualEditor_Toolbar_Formatting', - // This function is converted to a string and executed in the browser - function () { - var done = arguments[ arguments.length - 1 ], - toolGroup = ve.init.target.toolbar.tools.bold.toolGroup; - toolGroup.setActive( true ); - toolGroup.getExpandCollapseTool().onSelect(); - setTimeout( function () { - done( - seleniumUtils.getBoundingRect( [ - toolGroup.$element[ 0 ], - toolGroup.$group[ 0 ] - ] ) - ); - }, 500 ); - } - ); - } ); - test.it( 'Indentation tool list', function () { - runScreenshotTest( 'VisualEditor_Toolbar_List_and_indentation', - // This function is converted to a string and executed in the browser - function () { - var done = arguments[ arguments.length - 1 ], - toolGroup = ve.init.target.toolbar.tools.bullet.toolGroup; - toolGroup.setActive( true ); - setTimeout( function () { - done( - seleniumUtils.getBoundingRect( [ - toolGroup.$element[ 0 ], - toolGroup.$group[ 0 ] - ] ) - ); - }, 500 ); - } - ); - } ); - test.it( 'Page options list', function () { - runScreenshotTest( 'VisualEditor_More_Settings', - // This function is converted to a string and executed in the browser - function () { - var done = arguments[ arguments.length - 1 ], - toolGroup = ve.init.target.actionsToolbar.tools.advancedSettings.toolGroup; - toolGroup.setActive( true ); - setTimeout( function () { - done( - seleniumUtils.getBoundingRect( [ - toolGroup.$element[ 0 ], - toolGroup.$group[ 0 ], - // Include save button for context - ve.init.target.toolbarSaveButton.$element[ 0 ] - ] ) - ); - }, 500 ); - } - ); - } ); - test.it( 'Toolbar actions', function () { - runScreenshotTest( 'VisualEditor_toolbar_actions', - // This function is converted to a string and executed in the browser - function () { - var done = arguments[ arguments.length - 1 ]; - done( - seleniumUtils.getBoundingRect( [ - ve.init.target.toolbar.$actions[ 0 ] - ] ) - ); - }, - 0 - ); - } ); - test.it( 'Save dialog', function () { - runScreenshotTest( 'VisualEditor_save_dialog', - // This function is converted to a string and executed in the browser - function () { - var done = arguments[ arguments.length - 1 ]; - ve.init.target.toolbarSaveButton.emit( 'click' ); - setTimeout( function () { - done( - seleniumUtils.getBoundingRect( [ - ve.init.target.surface.dialogs.currentWindow.$frame[ 0 ] - ] ) - ); - }, 500 ); - } - ); - } ); - test.it( 'Special character inserter', function () { - runScreenshotTest( 'VisualEditor_Toolbar_SpecialCharacters', - // This function is converted to a string and executed in the browser - function () { - var done = arguments[ arguments.length - 1 ]; - ve.init.target.toolbar.tools.specialCharacter.onSelect(); - setTimeout( function () { - done( - seleniumUtils.getBoundingRect( [ - ve.init.target.toolbar.tools.specialCharacter.$element[ 0 ], - ve.init.target.surface.toolbarDialogs.$element[ 0 ] - ] - ) ); - }, 1000 ); - } - ); - } ); -} ); +for ( i = 0, l = langs.length; i < l; i++ ) { + runTests( langs[ i ] ); +} diff --git a/build/tasks/screenshotLangs.json b/build/tasks/screenshotLangs.json new file mode 100644 index 0000000000..3697a392fd --- /dev/null +++ b/build/tasks/screenshotLangs.json @@ -0,0 +1,95 @@ +{ + "langs": [ + "ar", + "as", + "ast", + "az", + "azb", + "bcl", + "be-tarask", + "bg", + "bn", + "bs", + "ca", + "cdo", + "ceb", + "cs", + "cy", + "da", + "de", + "diq", + "egl", + "el", + "eml", + "en", + "en-gb", + "eo", + "es", + "et", + "eu", + "fa", + "fi", + "fo", + "fr", + "fur", + "fy", + "gl", + "he", + "hi", + "hif", + "hr", + "hu", + "hy", + "id", + "ie", + "ilo", + "it", + "ja", + "jv", + "ka", + "km", + "kn", + "ko", + "lb", + "lt", + "lv", + "mai", + "mg", + "mk", + "ml", + "mr", + "ms", + "nap", + "nb", + "nl", + "om", + "or", + "pa", + "pcd", + "pl", + "ps", + "pt", + "pt-br", + "ro", + "ru", + "sah", + "sco", + "sd", + "sk", + "sl", + "sq", + "sr", + "su", + "sv", + "ta", + "th", + "tl", + "tr", + "tt", + "uk", + "vi", + "xh", + "yi", + "zh" + ] +}