Selaa lähdekoodia

Merge pull request #410 from transloadit/feature/refactor-enetoent-tests

Refactor end-to-end tests
Artur Paikin 7 vuotta sitten
vanhempi
commit
5b70cb5dfc

+ 1 - 1
.travis.yml

@@ -21,7 +21,7 @@ script:
 - npm run web:install
 - npm run web:install
 - npm run build
 - npm run build
 - npm run test
 - npm run test
-- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then npm run test:acceptance:handleservers; fi
+- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then npm run test:acceptance; fi
 env:
 env:
   global:
   global:
   - CXX=g++-4.8
   - CXX=g++-4.8

+ 7 - 0
bin/endtoend-build

@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+echo "Preparing for end to end test: copying static HTML and CSS, building JS"
+rm -rf ./test/endtoend/dist && mkdir ./test/endtoend/dist
+cp ./dist/uppy.min.css ./test/endtoend/dist 
+cp ./test/endtoend/src/index.html ./test/endtoend/dist 
+browserify ./test/endtoend/src/main.js -o ./test/endtoend/dist/bundle.js -t babelify

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2302 - 1076
package-lock.json


+ 7 - 3
package.json

@@ -88,11 +88,14 @@
     "postcss": "5.1.0",
     "postcss": "5.1.0",
     "pre-commit": "1.1.3",
     "pre-commit": "1.1.3",
     "sass": "0.5.0",
     "sass": "0.5.0",
-    "selenium-webdriver": "2.53.3",
     "tape": "^4.8.0",
     "tape": "^4.8.0",
     "tinyify": "^1.0.0",
     "tinyify": "^1.0.0",
     "uppy-server": "0.0.7",
     "uppy-server": "0.0.7",
-    "watchify": "3.7.0"
+    "watchify": "3.7.0",
+    "webdriverio": "^4.9.5",
+    "wdio-mocha-framework": "^0.5.11",
+    "wdio-sauce-service": "^0.4.4",
+    "wdio-static-server-service": "^1.0.1"
   },
   },
   "dependencies": {
   "dependencies": {
     "cuid": "^1.3.8",
     "cuid": "^1.3.8",
@@ -132,7 +135,8 @@
     "start:server": "cd ./node_modules/uppy-server && npm run start",
     "start:server": "cd ./node_modules/uppy-server && npm run start",
     "start": "npm-run-all --parallel watch start:server web:preview",
     "start": "npm-run-all --parallel watch start:server web:preview",
     "test:acceptance:handleservers": "bin/bootandkill-servers node test/acceptance/index.js",
     "test:acceptance:handleservers": "bin/bootandkill-servers node test/acceptance/index.js",
-    "test:acceptance": "node test/acceptance/index.js",
+    "test:acceptance": "./bin/endtoend-build && wdio test/endtoend/wdio.remote.conf.js",
+    "test:acceptance:local": "./bin/endtoend-build && wdio test/endtoend/wdio.local.conf.js",
     "test:unit": "jest --testPathPattern=src --coverage",
     "test:unit": "jest --testPathPattern=src --coverage",
     "test": "npm run lint && npm run test:unit",
     "test": "npm run lint && npm run test:unit",
     "test:watch": "jest --watch --testPathPattern=src",
     "test:watch": "jest --watch --testPathPattern=src",

+ 2 - 3
src/core/Core.js

@@ -115,10 +115,9 @@ class Uppy {
     // for debugging and testing
     // for debugging and testing
     // this.updateNum = 0
     // this.updateNum = 0
     if (this.opts.debug) {
     if (this.opts.debug) {
-      global.UppyState = this.state
       global.uppyLog = ''
       global.uppyLog = ''
-      // global.UppyAddFile = this.addFile.bind(this)
-      global._uppy = this
+      global[this.opts.id] = this
+      // global._uppy = this
     }
     }
   }
   }
 
 

BIN
test/endtoend/fixtures/image.jpg


+ 67 - 0
test/endtoend/specs/uppy.test.js

@@ -0,0 +1,67 @@
+/* global browser, expect, capabilities  */
+var path = require('path')
+
+var testURL = 'http://localhost:4567'
+
+function uppySelectFakeFile (uppyID) {
+  var blob = new Blob(
+    ['data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTIwIDEyMCI+CiAgPGNpcmNsZSBjeD0iNjAiIGN5PSI2MCIgcj0iNTAiLz4KPC9zdmc+Cg=='],
+    { type: 'image/svg+xml' }
+  )
+  window[uppyID].addFile({
+    source: 'test',
+    name: 'test-file',
+    type: blob.type,
+    data: blob
+  })
+}
+
+function browserSupportsChooseFile (capabilities) {
+  // Webdriver for Safari and Edge doesn’t support .chooseFile
+  return capabilities.browserName !== 'safari' &&
+         capabilities.browserName !== 'MicrosoftEdge' &&
+         capabilities.platformName !== 'Android'
+}
+
+browser.url(testURL)
+
+describe('File upload with DragDrop + Tus, DragDrop + XHRUpload, i18n translated string', () => {
+  it('should upload a file with Tus and set progressbar to 100%', () => {
+    if (browserSupportsChooseFile(capabilities)) {
+      browser.chooseFile('#uppyDragDrop .uppy-DragDrop-input', path.join(__dirname, '../fixtures/image.jpg'))
+    } else {
+      browser.execute(uppySelectFakeFile, 'uppyDragDrop')
+    }
+    browser.pause(3000)
+    var html = browser.getHTML('#uppyDragDrop-progress .UppyProgressBar-percentage', false)
+    expect(parseInt(html)).to.be.equal(100)
+  })
+
+  it('should upload a file with XHRUpload and set progressbar to 100%', () => {
+    if (browserSupportsChooseFile(capabilities)) {
+      browser.chooseFile('#uppyi18n .uppy-DragDrop-input', path.join(__dirname, '../fixtures/image.jpg'))
+    } else {
+      browser.execute(uppySelectFakeFile, 'uppyi18n')
+    }
+    browser.pause(3000)
+    var html = browser.getHTML('#uppyi18n-progress .UppyProgressBar-percentage', false)
+    expect(parseInt(html)).to.be.equal(100)
+  })
+
+  it('should translate text strings into Russian', () => {
+    var text = browser.getText('#uppyi18n .uppy-DragDrop-label')
+    expect(text.trim()).to.be.equal('Перенесите файлы сюда или выберите')
+  })
+})
+
+  // it('another test', function () {
+  //   return browser
+  //     .url(uppyTestURL)
+  //     .chooseFile('#uppyDragDrop .uppy-DragDrop-input', path.join(__dirname, 'image.jpg'))
+  //     .pause(3000)
+  //     .getHTML('#uppyDragDrop-progress .UppyProgressBar-percentage', false).then(val => {
+  //       console.log(val)
+  //       expect(parseInt(val)).toBe(100)
+  //     })
+  // })
+// })

+ 43 - 0
test/endtoend/src/index.html

@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>Uppy test page</title>
+  </head>
+  <body>
+    <style>
+      main {
+        max-width: 700px;
+        margin: auto;
+      }
+
+      #uppyDragDrop-progress,
+      #uppyi18n-progress {
+        position: relative;
+      }
+
+    </style>
+    <main>
+      <h2>Uppy DragDrop + Tus</h2>
+      <div>
+        <div id="uppyDragDrop"></div>
+        <div id="uppyDragDrop-progress"></div>
+      </div>
+
+      <h2>Uppy DragDrop i18n + XHRUpload</h2>
+      <div>
+        <div id="uppyi18n"></div>
+        <div id="uppyi18n-progress"></div>
+      </div>
+
+      <h2>Uppy Dashboard + Tus</h2>
+      <div>
+        <div id="uppyDashboard"></div>
+      </div>
+    </main>
+
+    <link href="uppy.min.css" rel="stylesheet">
+    <script src="bundle.js"></script>
+  </body>
+</html>

+ 48 - 0
test/endtoend/src/main.js

@@ -0,0 +1,48 @@
+const Uppy = require('../../../src/core')
+const DragDrop = require('../../../src/plugins/DragDrop')
+const Dashboard = require('../../../src/plugins/Dashboard')
+const Tus = require('../../../src/plugins/Tus')
+const XHRUpload = require('../../../src/plugins/XHRUpload')
+const ProgressBar = require('../../../src/plugins/ProgressBar')
+
+// Initialise Uppy with Drag & Drop
+const uppyDragDrop = Uppy({
+  id: 'uppyDragDrop',
+  debug: true
+})
+  .use(DragDrop, {
+    target: '#uppyDragDrop'
+  })
+  .use(ProgressBar, { target: '#uppyDragDrop-progress' })
+  .use(Tus, { endpoint: 'http://master.tus.io/files/' })
+  .run()
+
+const uppyi18n = Uppy({
+  id: 'uppyi18n',
+  debug: true
+})
+  .use(DragDrop, {
+    target: '#uppyi18n',
+    locale: {
+      strings: {
+        dropHereOr: 'Перенесите файлы сюда или',
+        browse: 'выберите'
+      }
+    }
+  })
+  .use(ProgressBar, { target: '#uppyi18n-progress' })
+  .use(XHRUpload, { endpoint: 'http://api2.transloadit.com' })
+  .run()
+
+const uppyDashboard = Uppy({
+  id: 'uppyDashboard',
+  debug: true
+})
+  .use(Dashboard, {
+    target: '#uppyDashboard',
+    inline: true
+  })
+  .use(Tus, { endpoint: 'http://master.tus.io/files/' })
+  .run()
+
+console.log(uppyDragDrop, uppyi18n, uppyDashboard)

+ 245 - 0
test/endtoend/wdio.local.conf.js

@@ -0,0 +1,245 @@
+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: [
+    'test/endtoend/specs/**/*.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: 5,
+    //
+    // 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: [
+        { browserName: 'firefox' }
+        // { browserName: 'MicrosoftEdge', version: '14.14393', platform: 'Windows 10' },
+        // { browserName: 'safari', version: '11.0', platform: 'macOS 10.12' }
+  ],
+    //
+    // ===================
+    // 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: 'silent',
+    //
+    // Enables colors for log output.
+  coloredLogs: true,
+    //
+    // If you only want to run your tests until a specific amount of tests have failed use
+    // bail (default is 0 - don't bail, run all tests).
+  bail: 0,
+    //
+    // Saves a screenshot to a given path if a command fails.
+    // screenshotPath: './endtoend/screenshots',
+    //
+    // 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://localhost',
+    //
+    // 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: ['static-server'],
+
+  staticServerFolders: [
+      { mount: '/', path: './test/endtoend/dist' }
+  ],
+
+    //
+    // 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: 'dot',
+    timeout: 30000
+  },
+    //
+    // =====
+    // 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.
+     * @param {Object} config wdio configuration object
+     * @param {Array.<Object>} capabilities list of capabilities details
+     */
+    // onPrepare: function (config, capabilities) {
+    // },
+    /**
+     * Gets executed just before initialising the webdriver session and test framework. It allows you
+     * to manipulate configurations depending on the capability or spec.
+     * @param {Object} config wdio configuration object
+     * @param {Array.<Object>} capabilities list of capabilities details
+     * @param {Array.<String>} specs List of spec file paths that are to be run
+     */
+    // beforeSession: function (config, capabilities, specs) {
+    // },
+    /**
+     * Gets executed before test execution begins. At this point you can access to all global
+     * variables like `browser`. It is the perfect place to define custom commands.
+     * @param {Array.<Object>} capabilities list of capabilities details
+     * @param {Array.<String>} specs List of spec file paths that are to be run
+     */
+  before: function (capabilities, specs) {
+    var chai = require('chai')
+    global.expect = chai.expect
+    global.capabilities = capabilities
+    chai.Should()
+  }
+    //
+    /**
+     * Hook that gets executed before the suite starts
+     * @param {Object} suite suite details
+     */
+    // 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.
+     * @param {Object} test test details
+     */
+    // beforeTest: function (test) {
+    // },
+    /**
+     * Runs before a WebdriverIO command gets executed.
+     * @param {String} commandName hook command name
+     * @param {Array} args arguments that command would receive
+     */
+    // beforeCommand: function (commandName, args) {
+    // },
+    /**
+     * Runs after a WebdriverIO command gets executed
+     * @param {String} commandName hook command name
+     * @param {Array} args arguments that command would receive
+     * @param {Number} result 0 - command success, 1 - command error
+     * @param {Object} error error object if any
+     */
+    // afterCommand: function (commandName, args, result, error) {
+    // },
+    /**
+     * Function to be executed after a test (in Mocha/Jasmine) or a step (in Cucumber) starts.
+     * @param {Object} test test details
+     */
+    // afterTest: function (test) {
+    // },
+    /**
+     * Hook that gets executed after the suite has ended
+     * @param {Object} suite suite details
+     */
+    // afterSuite: function (suite) {
+    // },
+    /**
+     * Gets executed after all tests are done. You still have access to all global variables from
+     * the test.
+     * @param {Number} result 0 - test pass, 1 - test fail
+     * @param {Array.<Object>} capabilities list of capabilities details
+     * @param {Array.<String>} specs List of spec file paths that ran
+     */
+    // after: function (result, capabilities, specs) {
+    // },
+    /**
+     * Gets executed right after terminating the webdriver session.
+     * @param {Object} config wdio configuration object
+     * @param {Array.<Object>} capabilities list of capabilities details
+     * @param {Array.<String>} specs List of spec file paths that ran
+     */
+    // afterSession: function (config, 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.
+     * @param {Object} exitCode 0 - success, 1 - fail
+     */
+    // onComplete: function(exitCode) {
+    // }
+}

+ 252 - 0
test/endtoend/wdio.remote.conf.js

@@ -0,0 +1,252 @@
+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: [
+    'test/endtoend/specs/**/*.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: 5,
+    //
+    // 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: [
+        { browserName: 'firefox', version: '38.0', platform: 'Linux', 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, build: process.env.TRAVIS_BUILD_NUMBER },
+        { browserName: 'internet explorer', version: '10.0', platform: 'Windows 7', 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, build: process.env.TRAVIS_BUILD_NUMBER },
+        { browserName: 'chrome', version: '50.0', platform: 'Windows 7', 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, build: process.env.TRAVIS_BUILD_NUMBER },
+        { browserName: 'MicrosoftEdge', version: '14.14393', platform: 'Windows 10', 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, build: process.env.TRAVIS_BUILD_NUMBER },
+        { browserName: 'safari', version: '11.0', platform: 'macOS 10.12', 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, build: process.env.TRAVIS_BUILD_NUMBER },
+        { browserName: 'safari', version: '11.0', platformName: 'iOS', platformVersion: '10.0', deviceOrientation: 'portrait', deviceName: 'iPhone 6 Simulator', appiumVersion: '1.7.1', 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, build: process.env.TRAVIS_BUILD_NUMBER },
+        { browserName: 'chrome', platformName: 'Android', platformVersion: '6.0', deviceOrientation: 'portrait', deviceName: 'Android Emulator', appiumVersion: '1.7.1', 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, build: process.env.TRAVIS_BUILD_NUMBER }
+  ],
+    //
+    // ===================
+    // 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: 'silent',
+    //
+    // Enables colors for log output.
+  coloredLogs: true,
+    //
+    // If you only want to run your tests until a specific amount of tests have failed use
+    // bail (default is 0 - don't bail, run all tests).
+  bail: 3,
+    //
+    // Saves a screenshot to a given path if a command fails.
+    // screenshotPath: './endtoend/screenshots',
+    //
+    // 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://localhost',
+    //
+    // 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: ['static-server', 'sauce'],
+  user: process.env.SAUCE_USERNAME,
+  key: process.env.SAUCE_ACCESS_KEY,
+  // sauceConnect: true,
+
+  staticServerFolders: [
+      { mount: '/', path: './test/endtoend/dist' }
+  ],
+
+    //
+    // 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: 'dot',
+    timeout: 30000
+  },
+    //
+    // =====
+    // 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.
+     * @param {Object} config wdio configuration object
+     * @param {Array.<Object>} capabilities list of capabilities details
+     */
+    // onPrepare: function (config, capabilities) {
+    // },
+    /**
+     * Gets executed just before initialising the webdriver session and test framework. It allows you
+     * to manipulate configurations depending on the capability or spec.
+     * @param {Object} config wdio configuration object
+     * @param {Array.<Object>} capabilities list of capabilities details
+     * @param {Array.<String>} specs List of spec file paths that are to be run
+     */
+    // beforeSession: function (config, capabilities, specs) {
+    // },
+    /**
+     * Gets executed before test execution begins. At this point you can access to all global
+     * variables like `browser`. It is the perfect place to define custom commands.
+     * @param {Array.<Object>} capabilities list of capabilities details
+     * @param {Array.<String>} specs List of spec file paths that are to be run
+     */
+  before: function (capabilities, specs) {
+    var chai = require('chai')
+    global.expect = chai.expect
+    global.capabilities = capabilities
+    chai.Should()
+  }
+    //
+    /**
+     * Hook that gets executed before the suite starts
+     * @param {Object} suite suite details
+     */
+    // 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.
+     * @param {Object} test test details
+     */
+    // beforeTest: function (test) {
+    // },
+    /**
+     * Runs before a WebdriverIO command gets executed.
+     * @param {String} commandName hook command name
+     * @param {Array} args arguments that command would receive
+     */
+    // beforeCommand: function (commandName, args) {
+    // },
+    /**
+     * Runs after a WebdriverIO command gets executed
+     * @param {String} commandName hook command name
+     * @param {Array} args arguments that command would receive
+     * @param {Number} result 0 - command success, 1 - command error
+     * @param {Object} error error object if any
+     */
+    // afterCommand: function (commandName, args, result, error) {
+    // },
+    /**
+     * Function to be executed after a test (in Mocha/Jasmine) or a step (in Cucumber) starts.
+     * @param {Object} test test details
+     */
+    // afterTest: function (test) {
+    // },
+    /**
+     * Hook that gets executed after the suite has ended
+     * @param {Object} suite suite details
+     */
+    // afterSuite: function (suite) {
+    // },
+    /**
+     * Gets executed after all tests are done. You still have access to all global variables from
+     * the test.
+     * @param {Number} result 0 - test pass, 1 - test fail
+     * @param {Array.<Object>} capabilities list of capabilities details
+     * @param {Array.<String>} specs List of spec file paths that ran
+     */
+    // after: function (result, capabilities, specs) {
+    // },
+    /**
+     * Gets executed right after terminating the webdriver session.
+     * @param {Object} config wdio configuration object
+     * @param {Array.<Object>} capabilities list of capabilities details
+     * @param {Array.<String>} specs List of spec file paths that ran
+     */
+    // afterSession: function (config, 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.
+     * @param {Object} exitCode 0 - success, 1 - fail
+     */
+    // onComplete: function(exitCode) {
+    // }
+}

+ 14 - 0
website/src/guide/contributing.md

@@ -53,6 +53,20 @@ atom src/core/Core.js \
 
 
 And open <http://0.0.0.0:4000/examples/multipart/index.html> in your webbrowser.
 And open <http://0.0.0.0:4000/examples/multipart/index.html> in your webbrowser.
 
 
+## Tests
+
+Unit tests can be run with:
+
+```npm run test:unit```
+
+For acceptance (or end to end) tests, we use [Webdriverio](http://webdriver.io). For it to run locally, you need to install selenium standalone server, just follow [the guide](http://webdriver.io/guide.html) to do so.
+
+After you’ve installed and launched the selenium standalone server, run:
+
+```
+npm run test:acceptance:local
+```
+
 ## CSS Guidelines
 ## CSS Guidelines
 
 
 The CSS standards followed in this project closely resemble those from [Medium's CSS Guidelines](https://gist.github.com/fat/a47b882eb5f84293c4ed). If it's not mentioned here, follow their guidelines.
 The CSS standards followed in this project closely resemble those from [Medium's CSS Guidelines](https://gist.github.com/fat/a47b882eb5f84293c4ed). If it's not mentioned here, follow their guidelines.

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä