-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New: Setup selenium functional UI framework (#158)
* Set up express app to generate annotator tokens and test browsers * Update travis.yml w/ saucelabs config * Allowing concurrent testing w/ file ids in env variables * Chore: Only run tests on cron jobs * Chore: Only run enabled functional-tests * Chore: Run tests using all files in functional-tests/tests/ folder * Chore: Send travis alert emails to [email protected]
- Loading branch information
Showing
16 changed files
with
3,200 additions
and
1,243 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,3 +14,4 @@ src/i18n/json | |
test/dev.html | ||
lib | ||
*~~bak | ||
functional-tests/output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,57 @@ | ||
# @desktop @mobile @enabled | ||
language: node_js | ||
node_js: | ||
- "8" | ||
script: yarn run ci | ||
- '8' | ||
cache: yarn | ||
notifications: | ||
email: false | ||
|
||
# safelist | ||
branches: | ||
only: | ||
- master | ||
- /^greenkeeper/.*$/ | ||
email: | ||
recipients: | ||
- [email protected] | ||
aliases: | ||
- &sauce-labs | ||
if: type = cron | ||
before_script: | ||
- yarn run setup-travis & | ||
- sleep 5 | ||
addons: | ||
sauce_connect: true | ||
script: yarn run functional-tests-ci | ||
- &sauce-labs-mobile | ||
<<: *sauce-labs | ||
script: yarn run functional-tests-ci --grep @mobile --grep @enabled | ||
- &sauce-labs-desktop | ||
<<: *sauce-labs | ||
script: yarn run functional-tests-ci --grep @desktop --grep @enabled | ||
jobs: | ||
include: | ||
- script: yarn run ci | ||
# Mac Chrome | ||
- <<: *sauce-labs-desktop | ||
env: BROWSER_PLATFORM="macOS 10.13" BROWSER_NAME="chrome" FILE_ID="285567874839" FILE_VERSION_ID="300496591287" | ||
# Mac Safari | ||
- <<: *sauce-labs-desktop | ||
env: BROWSER_PLATFORM="macOS 10.13" BROWSER_NAME="safari" FILE_ID="285569765346" FILE_VERSION_ID="300498497346" | ||
script: yarn run functional-tests-ci | ||
# Mac Firefox | ||
- <<: *sauce-labs-desktop | ||
env: BROWSER_PLATFORM="macOS 10.13" BROWSER_NAME="firefox" FILE_ID="285568802145" FILE_VERSION_ID="300497533713" | ||
# Windows Edge | ||
- <<: *sauce-labs-desktop | ||
env: BROWSER_PLATFORM="Windows 10" BROWSER_NAME="MicrosoftEdge" FILE_ID="285567976309" FILE_VERSION_ID="300496707445" | ||
script: yarn run functional-tests-ci | ||
# Windows IE | ||
- <<: *sauce-labs-desktop | ||
env: BROWSER_PLATFORM="Windows 10" BROWSER_NAME="internet explorer" FILE_ID="285568624824" FILE_VERSION_ID="300497342136" | ||
script: yarn run functional-tests-ci | ||
# iPhone | ||
- <<: *sauce-labs-mobile | ||
env: BROWSER_PLATFORM="iOS" DEVICE_NAME="iPhone 6 Simulator" PLATFORM_VERSION="11.2" BROWSER_NAME="Safari" FILE_ID="285569765346" FILE_VERSION_ID="300498497346" | ||
# iPad | ||
- <<: *sauce-labs-mobile | ||
# Uses firefox file id | ||
env: BROWSER_PLATFORM="iOS" DEVICE_NAME="iPad Simulator" PLATFORM_VERSION="11.2" BROWSER_NAME="Safari" FILE_ID="285568802145" FILE_VERSION_ID="300497533713" | ||
# Android | ||
- <<: *sauce-labs-mobile | ||
# Uses chrome file id | ||
env: BROWSER_PLATFORM="Android" DEVICE_NAME="Android GoogleAPI Emulator" PLATFORM_VERSION="7.1" BROWSER_NAME="Chrome" FILE_ID="285567874839" FILE_VERSION_ID="300496591287" | ||
script: yarn run functional-tests-ci |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
require('babel-polyfill'); | ||
|
||
const isRelease = process.env.NODE_ENV === 'production'; | ||
const isDev = process.env.NODE_ENV === 'dev'; | ||
|
||
const path = require('path'); | ||
const commonConfig = require('./webpack.common.config'); | ||
const { UglifyJsPlugin } = require('webpack').optimize; | ||
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); | ||
const { BannerPlugin } = require('webpack'); | ||
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); | ||
const license = require('./license'); | ||
|
||
/* eslint-disable key-spacing, require-jsdoc */ | ||
const config = Object.assign(commonConfig(), { | ||
entry: { | ||
annotations: ['./src/BoxAnnotations.js'] | ||
}, | ||
output: { | ||
path: path.resolve('functional-tests/lib'), | ||
filename: '[Name].js' | ||
} | ||
}); | ||
|
||
config.devtool = 'inline-source-map'; | ||
|
||
module.exports = config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
const { | ||
SAUCE_USERNAME, | ||
SAUCE_ACCESS_KEY, | ||
TRAVIS_JOB_NUMBER, | ||
CI, | ||
BROWSER_NAME = 'chrome', | ||
BROWSER_VERSION = 'latest', | ||
BROWSER_PLATFORM, | ||
PLATFORM_VERSION, | ||
DEVICE_NAME, | ||
DEFAULT_WAIT_TIME = 9000 | ||
} = process.env; | ||
const MOBILE_PLATFORMS = ['iOS', 'Android']; | ||
|
||
// Local selenium config | ||
const commonConfigObj = { | ||
browser: BROWSER_NAME, | ||
url: 'http://localhost:8080', | ||
restart: true, | ||
waitForTimeout: DEFAULT_WAIT_TIME | ||
}; | ||
|
||
const helperObj = {}; | ||
const isLocalBuild = typeof SAUCE_USERNAME === 'undefined'; | ||
|
||
if (isLocalBuild) { | ||
helperObj.WebDriverIO = commonConfigObj; | ||
} else { | ||
// Common saucelab config | ||
const sauceObj = { | ||
host: 'ondemand.saucelabs.com', | ||
port: 80, | ||
user: SAUCE_USERNAME, | ||
key: SAUCE_ACCESS_KEY, | ||
desiredCapabilities: { | ||
name: CI ? 'Travis cron' : require('os').userInfo().username, // eslint-disable-line global-require | ||
build: TRAVIS_JOB_NUMBER, | ||
'tunnel-identifier': TRAVIS_JOB_NUMBER, | ||
browserName: BROWSER_NAME, | ||
platform: BROWSER_PLATFORM | ||
} | ||
}; | ||
|
||
const mixedInSauceObj = Object.assign({}, commonConfigObj, sauceObj); | ||
if (MOBILE_PLATFORMS.indexOf(BROWSER_PLATFORM) === -1) { | ||
// webdriver (desktop) | ||
Object.assign(sauceObj.desiredCapabilities, { | ||
version: BROWSER_VERSION | ||
}); | ||
helperObj.WebDriverIO = mixedInSauceObj; | ||
} else { | ||
// appium (mobile) | ||
Object.assign(sauceObj.desiredCapabilities, { | ||
platformVersion: PLATFORM_VERSION, | ||
deviceName: DEVICE_NAME, | ||
deviceOrientation: 'portrait', | ||
appiumVersion: '1.7.2', | ||
platformName: BROWSER_PLATFORM | ||
}); | ||
helperObj.Appium = mixedInSauceObj; | ||
} | ||
} | ||
|
||
exports.config = { | ||
tests: './functional-tests/tests/*.js', | ||
timeout: DEFAULT_WAIT_TIME, | ||
output: './functional-tests/output', | ||
helpers: helperObj, | ||
include: {}, | ||
bootstrap: './functional-tests/helpers/cleanup.js', | ||
teardown: './functional-tests/helpers/cleanup.js', | ||
mocha: {}, | ||
name: 'box-annotations', | ||
hooks: isLocalBuild ? [] : ['./functional-tests/helpers/eventHooks.js'] | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Running tests locally | ||
|
||
## SauceLabs | ||
1) Download the [saucelabs proxy](https://wiki.saucelabs.com/display/DOCS/Sauce+Connect+Proxy) | ||
2) Run ```yarn functional-tests``` to start a local server on localhost:8000 | ||
3) Run the proxy ```./bin/sc -u SAUCELABS_USER_NAME -k SAUCELABS_ACCESS_KEY -N -i test``` to allow saucelabs to access your localhost | ||
4) Run the tests | ||
```SAUCE_USERNAME=SAUCELABS_USER_NAME SAUCE_ACCESS_KEY=SAUCELABS_ACCESS_KEY TRAVIS_JOB_NUMBER=TUNNEL_ID FILE_ID="285568802145" FILE_VERSION_ID="300497533713" node ./node_modules/codeceptjs/bin/codecept.js run --verbose``` where SAUCE_USERNAME, SAUCELABS_ACCESS_KEY can be found in saucelabs website. TUNNEL_ID is a unique identifier such as your username. | ||
|
||
## Selenium (without SauceLabs) | ||
1) Install selenium-standalone `npm install selenium-standalone@latest -g` | ||
2) Install Selenium drivers `selenium-standalone install` | ||
3) Start Selenium `selenium-standalone start` | ||
4) In a separate terminal, build Preview `yarn run build` | ||
5) Run functional tests `FILE_ID="285568802145" FILE_VERSION_ID="300497533713" yarn run functional-tests` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* eslint-disable func-names */ | ||
/* eslint-disable prefer-arrow-callback */ | ||
/* eslint-disable require-jsdoc */ | ||
/* eslint-disable no-console */ | ||
const express = require('express'); | ||
const path = require('path'); | ||
const BoxSDK = require('box-node-sdk'); | ||
|
||
const { | ||
FILE_ID, | ||
ACCESS_TOKEN, | ||
CLIENT_ID | ||
} = process.env; | ||
|
||
const app = express(); | ||
const server = app.listen(8080, () => console.log('Example app listening on port 8080!')); | ||
|
||
// Set up SDK & client | ||
const sdk = new BoxSDK({ | ||
clientID: CLIENT_ID, | ||
clientSecret: 'NUH UH' | ||
}); | ||
const client = sdk.getBasicClient(ACCESS_TOKEN); | ||
|
||
app.use(express.static(path.join(__dirname, 'lib'))); | ||
app.set('view engine', 'pug'); | ||
app.set('views', path.join(__dirname, 'views')); | ||
|
||
// this function is called when you want the server to die gracefully | ||
// i.e. wait for existing connections | ||
function gracefulShutdown() { | ||
console.log('Received kill signal, shutting down gracefully.'); | ||
server.close(function() { | ||
console.log('Closed out remaining connections.'); | ||
process.exit(); | ||
}); | ||
|
||
// if after | ||
setTimeout(function() { | ||
console.error('Could not close connections in time, forcefully shutting down'); | ||
process.exit(); | ||
}, 10*1000); | ||
} | ||
|
||
function errorCallback(err) { | ||
console.log(err.response.body); | ||
gracefulShutdown(); | ||
} | ||
|
||
// viewed at http://localhost:8080 | ||
app.get('/', function(req, res) { | ||
const url = `https://api.box.com/2.0/files/${FILE_ID}`; | ||
const options = { | ||
actor: { | ||
id: '3504101558', | ||
name: 'Kanye West' | ||
} | ||
}; | ||
|
||
client.exchangeToken(['item_preview'], url, options) | ||
.then((tokenInfo) => { | ||
// tokenInfo.accessToken contains the new annotator token | ||
res.render('index', { token: tokenInfo.accessToken, file_id: FILE_ID }); | ||
}) | ||
.catch(errorCallback); | ||
}); | ||
|
||
// listen for TERM signal .e.g. kill | ||
process.on ('SIGTERM', gracefulShutdown); | ||
|
||
// listen for INT signal e.g. Ctrl-C | ||
process.on ('SIGINT', gracefulShutdown); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* eslint-disable func-names, prefer-arrow-callback, require-jsdoc, no-console */ | ||
const BoxSDK = require('box-node-sdk'); | ||
|
||
const { | ||
FILE_ID, | ||
FILE_VERSION_ID, | ||
ACCESS_TOKEN, | ||
CLIENT_ID | ||
} = process.env; | ||
|
||
const sdk = new BoxSDK({ | ||
clientID: CLIENT_ID, | ||
clientSecret: 'NUH UH' | ||
}); | ||
const client = sdk.getBasicClient(ACCESS_TOKEN); | ||
|
||
function deleteAnnotation(annotation) { | ||
const { id } = annotation; | ||
client.del(`/annotations/${id}`, {}, function(err) { | ||
if (err) { | ||
// handle error | ||
throw err; | ||
} | ||
console.log(`Annotation ID ${id} was deleted`); | ||
}); | ||
} | ||
|
||
module.exports = function() { | ||
client.get(`/files/${FILE_ID}/annotations?version=${FILE_VERSION_ID}`, {}, function(err, response) { | ||
if (err) { | ||
// handle error | ||
throw err; | ||
} | ||
|
||
const { entries } = response.body; | ||
if (!entries) { | ||
console.log('File does not have any existing annotations'); | ||
return; | ||
} | ||
|
||
console.log(`Deleting ${entries.length} annotations`); | ||
entries.forEach(deleteAnnotation); | ||
}); | ||
} |
Oops, something went wrong.