Zfilipin has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/328191 )
Change subject: WIP Research webdriver.io ...................................................................... WIP Research webdriver.io Bug: T151442 Change-Id: Ibe7a004a120e82af637ab3e31b725de743134c99 --- M Gruntfile.js M package.json A tests/selenium/page.js A tests/selenium/user.js A wdio.conf.js 5 files changed, 252 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/91/328191/1 diff --git a/Gruntfile.js b/Gruntfile.js index 55b7932..906fdde 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -13,6 +13,7 @@ grunt.loadNpmTasks( 'grunt-jsonlint' ); grunt.loadNpmTasks( 'grunt-karma' ); grunt.loadNpmTasks( 'grunt-stylelint' ); + grunt.loadNpmTasks( 'grunt-webdriver' ); karmaProxy[ wgScriptPath ] = wgServer + wgScriptPath; @@ -98,7 +99,15 @@ return require( 'path' ).join( dest, src.replace( 'resources/', '' ) ); } } + }, + + // Configure WebdriverIO task + webdriver: { + test: { + configFile: './wdio.conf.js' + } } + } ); grunt.registerTask( 'assert-mw-env', function () { @@ -116,6 +125,7 @@ grunt.registerTask( 'lint', [ 'eslint', 'banana', 'stylelint' ] ); grunt.registerTask( 'qunit', [ 'assert-mw-env', 'karma:main' ] ); + grunt.registerTask( 'wdio', 'webdriver' ); grunt.registerTask( 'test', [ 'lint' ] ); grunt.registerTask( 'default', 'test' ); diff --git a/package.json b/package.json index 99e752c..284ab1d 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "scripts": { "test": "grunt test", "doc": "jsduck", - "postdoc": "grunt copy:jsduck" + "postdoc": "grunt copy:jsduck", + "selenium": "chromedriver --url-base=/wd/hub --port=4444 & grunt wdio; pkill chromedriver" }, "devDependencies": { "eslint-config-wikimedia": "0.3.0", @@ -15,11 +16,15 @@ "grunt-jsonlint": "1.1.0", "grunt-karma": "2.0.0", "grunt-stylelint": "0.6.0", + "grunt-webdriver": "^2.0.3", "karma": "1.1.0", "karma-chrome-launcher": "1.0.1", "karma-firefox-launcher": "1.0.0", "karma-qunit": "1.0.0", "qunitjs": "1.22.0", - "stylelint-config-wikimedia": "0.3.0" + "stylelint-config-wikimedia": "0.3.0", + "wdio-dot-reporter": "0.0.6", + "wdio-mocha-framework": "^0.5.8", + "webdriverio": "^4.5.1" } } diff --git a/tests/selenium/page.js b/tests/selenium/page.js new file mode 100644 index 0000000..f35ac27 --- /dev/null +++ b/tests/selenium/page.js @@ -0,0 +1,21 @@ +/* global browser */ +var assert = require( 'assert' ); + +describe( 'Page', function () { + + it( 'should be created', function () { + browser.url( '/Does_not_exist' ); + assert( browser.isVisible( 'li#ca-edit a' ) ); + } ); + + it( 'should be edited', function () { + browser.url( '/Main_Page' ); + assert( browser.isVisible( 'li#ca-edit a' ) ); + } ); + + it( 'should have history', function () { + browser.url( '/Main_Page' ); + assert( browser.isVisible( 'li#ca-history a' ) ); + } ); + +} ); diff --git a/tests/selenium/user.js b/tests/selenium/user.js new file mode 100644 index 0000000..2455961 --- /dev/null +++ b/tests/selenium/user.js @@ -0,0 +1,26 @@ +/* global browser */ +var assert = require( 'assert' ); + +describe( 'User', function () { + + it( 'should be able to create account', function () { + browser.url( '/Special:CreateAccount' ); + assert( browser.isVisible( '#wpCreateaccount' ) ); + } ); + + it( 'should be able to log in', function () { + browser.url( '/Special:UserLogin' ); + assert( browser.isVisible( '#wpLoginAttempt' ) ); + } ); + + it( 'should be able to change preferences', function () { + browser.url( '/Special:UserLogin' ); + browser.setValue( '#wpName1', 'Admin' ); + browser.setValue( '#wpPassword1', 'vagrant' ); + browser.click( '#wpLoginAttempt' ); + + browser.url( '/Special:Preferences' ); + assert( browser.isVisible( '#prefcontrol' ) ); + } ); + +} ); diff --git a/wdio.conf.js b/wdio.conf.js new file mode 100644 index 0000000..a8222f8 --- /dev/null +++ b/wdio.conf.js @@ -0,0 +1,188 @@ +/* eslint no-undef: "error"*/ +/* eslint-env node*/ +exports.config = { + + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. Notice that, if you are calling `wdio` from an + // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working + // directory is where your package.json resides, so `wdio` will be called from there. + // + specs: [ + './tests/selenium/**/*.js' + ], + // Patterns to exclude. + exclude: [ + // 'path/to/excluded/files' + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilities at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude options in + // order to group specific specs to a specific capability. + // + // First, you can define how many instances should be started at the same time. Let's + // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have + // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec + // files and you set maxInstances to 10, all spec files will get tested at the same time + // and 30 processes will get spawned. The property handles how many capabilities + // from the same test should run tests. + // + maxInstances: 10, + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + capabilities: [ { + // maxInstances can get overwritten per capability. So if you have an in-house Selenium + // grid with only 5 firefox instances available you can make sure that not more than + // 5 instances get started at a time. + maxInstances: 5, + // + browserName: 'chrome' + } ], + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + // By default WebdriverIO commands are executed in a synchronous way using + // the wdio-sync package. If you still want to run your tests in an async way + // e.g. using promises you can set the sync option to false. + sync: true, + // + // Level of logging verbosity: silent | verbose | command | data | result | error + logLevel: 'error', + // + // Enables colors for log output. + coloredLogs: true, + // + // Saves a screenshot to a given path if a command fails. + screenshotPath: './errorShots/', + // + // Set a base URL in order to shorten url command calls. If your url parameter starts + // with "/", then the base url gets prepended. + baseUrl: 'http://127.0.0.1:8080/wiki', + // + // Default timeout for all waitFor* commands. + waitforTimeout: 10000, + // + // Default timeout in milliseconds for request + // if Selenium Grid doesn't send response + connectionRetryTimeout: 90000, + // + // Default request retries count + connectionRetryCount: 3, + // + // Initialize the browser instance with a WebdriverIO plugin. The object should have the + // plugin name as key and the desired plugin options as properties. Make sure you have + // the plugin installed before running any tests. The following plugins are currently + // available: + // WebdriverCSS: https://github.com/webdriverio/webdrivercss + // WebdriverRTC: https://github.com/webdriverio/webdriverrtc + // Browserevent: https://github.com/webdriverio/browserevent + // plugins: { + // webdrivercss: { + // screenshotRoot: 'my-shots', + // failedComparisonsRoot: 'diffs', + // misMatchTolerance: 0.05, + // screenWidth: [320,480,640,1024] + // }, + // webdriverrtc: {}, + // browserevent: {} + // }, + // + // Test runner services + // Services take over a specific job you don't want to take care of. They enhance + // your test setup with almost no effort. Unlike plugins, they don't add new + // commands. Instead, they hook themselves up into the test process. + // services: [],// + // Framework you want to run your specs with. + // The following are supported: Mocha, Jasmine, and Cucumber + // see also: http://webdriver.io/guide/testrunner/frameworks.html + // + // Make sure you have the wdio adapter package for the specific framework installed + // before running any tests. + framework: 'mocha', + // + // Test reporter for stdout. + // The only one supported by default is 'dot' + // see also: http://webdriver.io/guide/testrunner/reporters.html + reporters: [ 'dot' ], + + // + // Options to be passed to Mocha. + // See the full list at http://mochajs.org/ + mochaOpts: { + ui: 'bdd' + } + // + // ===== + // Hooks + // ===== + // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance + // it and to build services around it. You can either apply a single function or an array of + // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got + // resolved to continue. + // + // Gets executed once before all workers get launched. + // onPrepare: function (config, capabilities) { + // }, + // + // Gets executed before test execution begins. At this point you can access all global + // variables, such as `browser`. It is the perfect place to define custom commands. + // before: function (capabilities, specs) { + // }, + // + // Hook that gets executed before the suite starts + // beforeSuite: function (suite) { + // }, + // + // Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling + // beforeEach in Mocha) + // beforeHook: function () { + // }, + // + // Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling + // afterEach in Mocha) + // afterHook: function () { + // }, + // + // Function to be executed before a test (in Mocha/Jasmine) or a step (in Cucumber) starts. + // beforeTest: function (test) { + // }, + // + // Runs before a WebdriverIO command gets executed. + // beforeCommand: function (commandName, args) { + // }, + // + // Runs after a WebdriverIO command gets executed + // afterCommand: function (commandName, args, result, error) { + // }, + // + // Function to be executed after a test (in Mocha/Jasmine) or a step (in Cucumber) starts. + // afterTest: function (test) { + // }, + // + // Hook that gets executed after the suite has ended + // afterSuite: function (suite) { + // }, + // + // Gets executed after all tests are done. You still have access to all global variables from + // the test. + // after: function (result, capabilities, specs) { + // }, + // + // Gets executed after all workers got shut down and the process is about to exit. It is not + // possible to defer the end of the process using a promise. + // onComplete: function(exitCode) { + // } +}; -- To view, visit https://gerrit.wikimedia.org/r/328191 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibe7a004a120e82af637ab3e31b725de743134c99 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Zfilipin <zfili...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits