mirror of
https://github.com/openstf/stf
synced 2025-10-06 03:50:04 +02:00
Merge remote-tracking branch 'upstream/master' into market_name
This commit is contained in:
commit
96312dd453
23 changed files with 874 additions and 50 deletions
1
.nvmrc
Normal file
1
.nvmrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
8.16.1
|
1
.tool-versions
Normal file
1
.tool-versions
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nodejs 8.16.1
|
|
@ -15,13 +15,14 @@ addons:
|
||||||
- yasm
|
- yasm
|
||||||
env:
|
env:
|
||||||
matrix:
|
matrix:
|
||||||
- NODE_VERSION=6
|
- NODE_VERSION=8.16.1
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- os: osx
|
- os: osx
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
before_install:
|
before_install:
|
||||||
- rm -rf ~/.nvm && git clone --depth 1 https://github.com/creationix/nvm.git ~/.nvm
|
- rm -rf ~/.nvm && git clone --depth 1 https://github.com/creationix/nvm.git ~/.nvm
|
||||||
|
- rm .nvmrc
|
||||||
- source ~/.nvm/nvm.sh
|
- source ~/.nvm/nvm.sh
|
||||||
- nvm install $NODE_VERSION
|
- nvm install $NODE_VERSION
|
||||||
- node --version
|
- node --version
|
||||||
|
|
|
@ -23,9 +23,9 @@ Thank you to all our sponsors! (please ask your company to also support this ope
|
||||||
|
|
||||||
#### Gold Sponsor
|
#### Gold Sponsor
|
||||||
|
|
||||||
[<img src="doc/sponsors/headspin-wordmark-orange.png?raw=true" alt="HeadSpin" width="400">](https://headspin.io/)
|
[<img src="doc/sponsors/headspin-wordmark-orange.png?raw=true" alt="HeadSpin" width="400">](https://ui.headspin.io/register?referral=start-testing-hs)
|
||||||
|
|
||||||
> [HeadSpin](https://headspin.io/) provides secure and scalable STF for iOS integrated with Appium/XCTest/Selenium/Espresso, High speed interaction Audio/Video/Game testing and AI based Root cause analysis for Performance Management. It's free to start using HeadSpin in 150+ locations worldwide! [Try it out for free.](https://ui-dev.headspin.io/signup/23feaa95fec34c49a1da309380807795)
|
> [HeadSpin](https://headspin.io/) provides secure and scalable STF for iOS integrated with Appium/XCTest/Selenium/Espresso, High speed interaction Audio/Video/Game testing and AI based Root cause analysis for Performance Management. It's free to start using HeadSpin in 150+ locations worldwide! [Try it out for free.](https://ui.headspin.io/register?referral=start-testing-hs)
|
||||||
|
|
||||||
HeadSpin offers a generous monthly contribution towards STF development.
|
HeadSpin offers a generous monthly contribution towards STF development.
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ As the product has evolved from an internal tool running in our internal network
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* [Node.js](https://nodejs.org/) >= 6.9 (latest stable version preferred)
|
* [Node.js](https://nodejs.org/) 8.x **required** (some dependencies don't support newer versions)
|
||||||
* [ADB](http://developer.android.com/tools/help/adb.html) properly set up
|
* [ADB](http://developer.android.com/tools/help/adb.html) properly set up
|
||||||
* [RethinkDB](http://rethinkdb.com/) >= 2.2
|
* [RethinkDB](http://rethinkdb.com/) >= 2.2
|
||||||
* [GraphicsMagick](http://www.graphicsmagick.org/) (for resizing screenshots)
|
* [GraphicsMagick](http://www.graphicsmagick.org/) (for resizing screenshots)
|
||||||
|
|
43
TESTING.md
43
TESTING.md
|
@ -5,20 +5,49 @@
|
||||||
|
|
||||||
## E2E Frontend
|
## E2E Frontend
|
||||||
|
|
||||||
### On first run
|
## On first run
|
||||||
- `gulp webdriver-update`
|
- `gulp webdriver-update`
|
||||||
|
|
||||||
### Chrome Local STF
|
|
||||||
- Connect a device
|
|
||||||
- Run stf
|
|
||||||
- `gulp protractor`
|
|
||||||
|
|
||||||
### Multiple Browsers Local STF with a specific suite
|
|
||||||
|
## Protractor&Jasmine - Local STF tests
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
#### Preconditions
|
||||||
|
Test configuration point to Google Chrome browser. Test works on Google Chrome v.77.0.3865.75 together with chromedriver with ver. 77.0.3865.40.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- Connect a device or start android emulator
|
||||||
|
- Run RethinkDb
|
||||||
|
```
|
||||||
|
rethinkdb
|
||||||
|
```
|
||||||
|
- Run stf
|
||||||
|
```
|
||||||
|
./bin/stf local
|
||||||
|
```
|
||||||
|
Wait till STF will be fully functional and devices will be discovered
|
||||||
|
- Run tests
|
||||||
|
```
|
||||||
|
gulp protractor
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
#### Info
|
||||||
|
Test results can be found in:
|
||||||
|
test-results/reports-protractor/dashboardReport-protractor/index.html
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
===
|
||||||
|
## Multiple Browsers Local STF with a specific suite
|
||||||
- Connect a device
|
- Connect a device
|
||||||
- Run stf
|
- Run stf
|
||||||
- `gulp protractor --multi --suite devices`
|
- `gulp protractor --multi --suite devices`
|
||||||
|
|
||||||
### Chrome Remote STF
|
## Chrome Remote STF
|
||||||
- `export STF_URL='http://stf-url/#!/'`
|
- `export STF_URL='http://stf-url/#!/'`
|
||||||
- `export STF_USERNAME='user'`
|
- `export STF_USERNAME='user'`
|
||||||
- `export STF_PASSWORD='pass'`
|
- `export STF_PASSWORD='pass'`
|
||||||
|
|
|
@ -325,7 +325,7 @@ ExecStart=/usr/bin/docker run --rm \
|
||||||
-e "SECRET=YOUR_SESSION_SECRET_HERE" \
|
-e "SECRET=YOUR_SESSION_SECRET_HERE" \
|
||||||
-e "SAML_ID_PROVIDER_ENTRY_POINT_URL=YOUR_ID_PROVIDER_ENTRY_POINT" \
|
-e "SAML_ID_PROVIDER_ENTRY_POINT_URL=YOUR_ID_PROVIDER_ENTRY_POINT" \
|
||||||
-e "SAML_ID_PROVIDER_ISSUER=YOUR_ID_PROVIDER_ISSUER" \
|
-e "SAML_ID_PROVIDER_ISSUER=YOUR_ID_PROVIDER_ISSUER" \
|
||||||
-e "SAML_ID_PROVIDER_CERT_PATH=/etc/id_proider.cert" \
|
-e "SAML_ID_PROVIDER_CERT_PATH=/etc/id_provider.cert" \
|
||||||
-p %i:3000 \
|
-p %i:3000 \
|
||||||
openstf/stf:latest \
|
openstf/stf:latest \
|
||||||
stf auth-saml2 --port 3000 \
|
stf auth-saml2 --port 3000 \
|
||||||
|
|
|
@ -3,7 +3,7 @@ var util = require('util')
|
||||||
var _ = require('lodash')
|
var _ = require('lodash')
|
||||||
var Promise = require('bluebird')
|
var Promise = require('bluebird')
|
||||||
var uuid = require('uuid')
|
var uuid = require('uuid')
|
||||||
|
var adbkit = require('adbkit')
|
||||||
var dbapi = require('../../../db/api')
|
var dbapi = require('../../../db/api')
|
||||||
var logger = require('../../../util/logger')
|
var logger = require('../../../util/logger')
|
||||||
var datautil = require('../../../util/datautil')
|
var datautil = require('../../../util/datautil')
|
||||||
|
@ -23,6 +23,7 @@ module.exports = {
|
||||||
, remoteConnectUserDeviceBySerial: remoteConnectUserDeviceBySerial
|
, remoteConnectUserDeviceBySerial: remoteConnectUserDeviceBySerial
|
||||||
, remoteDisconnectUserDeviceBySerial: remoteDisconnectUserDeviceBySerial
|
, remoteDisconnectUserDeviceBySerial: remoteDisconnectUserDeviceBySerial
|
||||||
, getUserAccessTokens: getUserAccessTokens
|
, getUserAccessTokens: getUserAccessTokens
|
||||||
|
, addAdbPublicKey: addAdbPublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUser(req, res) {
|
function getUser(req, res) {
|
||||||
|
@ -400,3 +401,56 @@ function getUserAccessTokens(req, res) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addAdbPublicKey(req, res) {
|
||||||
|
var data = req.swagger.params.adb.value
|
||||||
|
adbkit.util.parsePublicKey(data.publickey)
|
||||||
|
.then(function(key) {
|
||||||
|
return dbapi.lookupUsersByAdbKey(key.fingerprint)
|
||||||
|
.then(function(cursor) {
|
||||||
|
return cursor.toArray()
|
||||||
|
})
|
||||||
|
.then(function(users) {
|
||||||
|
return {
|
||||||
|
key: {
|
||||||
|
title: data.title || key.comment
|
||||||
|
, fingerprint: key.fingerprint
|
||||||
|
}
|
||||||
|
, users: users
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
if (data.users.length) {
|
||||||
|
return res.json({
|
||||||
|
success: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return dbapi.insertUserAdbKey(req.user.email, data.key)
|
||||||
|
.then(function() {
|
||||||
|
return res.json({
|
||||||
|
success: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
req.options.push.send([
|
||||||
|
req.user.group
|
||||||
|
, wireutil.envelope(new wire.AdbKeysUpdatedMessage())
|
||||||
|
])
|
||||||
|
})
|
||||||
|
.catch(dbapi.DuplicateSecondaryIndexError, function() {
|
||||||
|
// No-op
|
||||||
|
return res.json({
|
||||||
|
success: true
|
||||||
|
})
|
||||||
|
}).catch(function(err) {
|
||||||
|
log.error('Failed to insert new adb key fingerprint: ', err.stack)
|
||||||
|
return res.status(500).json({
|
||||||
|
success: false
|
||||||
|
, message: 'Unable to insert new adb key fingerprint to database'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ var path = require('path')
|
||||||
var events = require('events')
|
var events = require('events')
|
||||||
|
|
||||||
var express = require('express')
|
var express = require('express')
|
||||||
var SwaggerExpress = require('swagger-express-mw')
|
var swaggerExpress = require('swagger-express-mw')
|
||||||
|
var swaggerUi = require('swagger-tools/middleware/swagger-ui')
|
||||||
var cookieSession = require('cookie-session')
|
var cookieSession = require('cookie-session')
|
||||||
var Promise = require('bluebird')
|
var Promise = require('bluebird')
|
||||||
var _ = require('lodash')
|
var _ = require('lodash')
|
||||||
|
@ -67,10 +68,11 @@ module.exports = function(options) {
|
||||||
, swaggerFile: path.resolve(__dirname, 'swagger', 'api_v1.yaml')
|
, swaggerFile: path.resolve(__dirname, 'swagger', 'api_v1.yaml')
|
||||||
}
|
}
|
||||||
|
|
||||||
SwaggerExpress.create(config, function(err, swaggerExpress) {
|
swaggerExpress.create(config, function(err, swaggerExpress) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
app.use(swaggerUi(swaggerExpress.runner.swagger))
|
||||||
swaggerExpress.register(app)
|
swaggerExpress.register(app)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -209,6 +209,41 @@ paths:
|
||||||
$ref: "#/definitions/ErrorResponse"
|
$ref: "#/definitions/ErrorResponse"
|
||||||
security:
|
security:
|
||||||
- accessTokenAuth: []
|
- accessTokenAuth: []
|
||||||
|
/user/adbPublicKeys:
|
||||||
|
x-swagger-router-controller: user
|
||||||
|
post:
|
||||||
|
summary: Adb public keys
|
||||||
|
description: Add adb public key for current user
|
||||||
|
operationId: addAdbPublicKey
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
parameters:
|
||||||
|
- name: adb
|
||||||
|
in: body
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- publickey
|
||||||
|
properties:
|
||||||
|
publickey:
|
||||||
|
type: string
|
||||||
|
description: adb public key (~/.android/id_rsa.pub)
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
description: By default will be extracted from public key
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Add adb key response
|
||||||
|
default:
|
||||||
|
description: Unexpected Error
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/ErrorResponse"
|
||||||
|
security:
|
||||||
|
- accessTokenAuth: []
|
||||||
/devices:
|
/devices:
|
||||||
x-swagger-router-controller: devices
|
x-swagger-router-controller: devices
|
||||||
get:
|
get:
|
||||||
|
|
|
@ -62,7 +62,7 @@ module.exports = syrup.serial()
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeResource(res) {
|
function removeResource(res) {
|
||||||
return adb.shell(options.serial, ['rm', res.dest])
|
return adb.shell(options.serial, ['rm', '-f', res.dest])
|
||||||
.timeout(10000)
|
.timeout(10000)
|
||||||
.then(function(out) {
|
.then(function(out) {
|
||||||
return streamutil.readAll(out)
|
return streamutil.readAll(out)
|
||||||
|
|
|
@ -36,7 +36,7 @@ module.exports = syrup.serial()
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeResource(res) {
|
function removeResource(res) {
|
||||||
return adb.shell(options.serial, ['rm', res.dest])
|
return adb.shell(options.serial, ['rm', '-f', res.dest])
|
||||||
.timeout(10000)
|
.timeout(10000)
|
||||||
.then(function(out) {
|
.then(function(out) {
|
||||||
return streamutil.readAll(out)
|
return streamutil.readAll(out)
|
||||||
|
|
|
@ -35,7 +35,7 @@ module.exports = syrup.serial()
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeResource(res) {
|
function removeResource(res) {
|
||||||
return adb.shell(options.serial, ['rm', res.dest])
|
return adb.shell(options.serial, ['rm', '-f', res.dest])
|
||||||
.timeout(10000)
|
.timeout(10000)
|
||||||
.then(function(out) {
|
.then(function(out) {
|
||||||
return streamutil.readAll(out)
|
return streamutil.readAll(out)
|
||||||
|
|
|
@ -36,6 +36,8 @@ module.exports.readAll = function(stream) {
|
||||||
stream.on('readable', readableListener)
|
stream.on('readable', readableListener)
|
||||||
stream.on('end', endListener)
|
stream.on('end', endListener)
|
||||||
|
|
||||||
|
readableListener()
|
||||||
|
|
||||||
return resolver.promise.finally(function() {
|
return resolver.promise.finally(function() {
|
||||||
stream.removeListener('error', errorListener)
|
stream.removeListener('error', errorListener)
|
||||||
stream.removeListener('readable', readableListener)
|
stream.removeListener('readable', readableListener)
|
||||||
|
|
16
package.json
16
package.json
|
@ -88,6 +88,7 @@
|
||||||
"stf-syrup": "^1.0.0",
|
"stf-syrup": "^1.0.0",
|
||||||
"stf-wiki": "^1.0.0",
|
"stf-wiki": "^1.0.0",
|
||||||
"swagger-express-mw": "^0.7.0",
|
"swagger-express-mw": "^0.7.0",
|
||||||
|
"swagger-tools": "^0.10.3",
|
||||||
"temp": "^0.8.1",
|
"temp": "^0.8.1",
|
||||||
"transliteration": "^1.1.6",
|
"transliteration": "^1.1.6",
|
||||||
"url-join": "1.1.0",
|
"url-join": "1.1.0",
|
||||||
|
@ -99,7 +100,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"async": "^2.0.1",
|
"async": "^2.0.1",
|
||||||
"bower": "^1.7.2",
|
"bower": "^1.8.8",
|
||||||
"chai": "^3.4.1",
|
"chai": "^3.4.1",
|
||||||
"css-loader": "^0.23.1",
|
"css-loader": "^0.23.1",
|
||||||
"del": "^2.0.1",
|
"del": "^2.0.1",
|
||||||
|
@ -108,6 +109,7 @@
|
||||||
"exports-loader": "^0.6.2",
|
"exports-loader": "^0.6.2",
|
||||||
"extract-text-webpack-plugin": "^1.0.1",
|
"extract-text-webpack-plugin": "^1.0.1",
|
||||||
"file-loader": "^0.9.0",
|
"file-loader": "^0.9.0",
|
||||||
|
"fs-extra": "^8.1.0",
|
||||||
"gulp": "^3.8.11",
|
"gulp": "^3.8.11",
|
||||||
"gulp-angular-gettext": "^2.1.0",
|
"gulp-angular-gettext": "^2.1.0",
|
||||||
"gulp-eslint": "^3.0.1",
|
"gulp-eslint": "^3.0.1",
|
||||||
|
@ -119,13 +121,13 @@
|
||||||
"html-loader": "^0.4.0",
|
"html-loader": "^0.4.0",
|
||||||
"imports-loader": "^0.6.5",
|
"imports-loader": "^0.6.5",
|
||||||
"jasmine-core": "^2.4.1",
|
"jasmine-core": "^2.4.1",
|
||||||
"jasmine-reporters": "^2.1.1",
|
"jasmine-reporters": "^2.3.2",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"karma": "^1.1.2",
|
"karma": "^1.7.1",
|
||||||
"karma-chrome-launcher": "^1.0.1",
|
"karma-chrome-launcher": "^2.2.0",
|
||||||
"karma-firefox-launcher": "^1.0.0",
|
"karma-firefox-launcher": "^1.0.0",
|
||||||
"karma-ie-launcher": "^1.0.0",
|
"karma-ie-launcher": "^1.0.0",
|
||||||
"karma-jasmine": "^1.0.2",
|
"karma-jasmine": "^2.0.1",
|
||||||
"karma-junit-reporter": "^1.1.0",
|
"karma-junit-reporter": "^1.1.0",
|
||||||
"karma-opera-launcher": "^1.0.0",
|
"karma-opera-launcher": "^1.0.0",
|
||||||
"karma-phantomjs-launcher": "^1.0.0",
|
"karma-phantomjs-launcher": "^1.0.0",
|
||||||
|
@ -137,8 +139,8 @@
|
||||||
"node-libs-browser": "^1.0.0",
|
"node-libs-browser": "^1.0.0",
|
||||||
"node-sass": "^3.4.2",
|
"node-sass": "^3.4.2",
|
||||||
"phantomjs-prebuilt": "^2.1.11",
|
"phantomjs-prebuilt": "^2.1.11",
|
||||||
"protractor": "^4.0.3",
|
"protractor": "^5.4.1",
|
||||||
"protractor-html-screenshot-reporter": "0.0.21",
|
"protractor-html-reporter-2": "1.0.4",
|
||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"sass-loader": "^4.0.0",
|
"sass-loader": "^4.0.0",
|
||||||
"script-loader": "^0.7.0",
|
"script-loader": "^0.7.0",
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
describe('Control Page', function() {
|
describe('Control Page', function() {
|
||||||
var DeviceListPage = require('../devices')
|
var DeviceListPage = require('../devices')
|
||||||
var deviceListPage = new DeviceListPage()
|
var deviceListPage = new DeviceListPage()
|
||||||
|
var localhost = browser.baseUrl
|
||||||
|
|
||||||
var ControlPage = function() {
|
var ControlPage = function() {
|
||||||
this.get = function() {
|
this.get = function() {
|
||||||
browser.get(protractor.getInstance().baseUrl + 'control')
|
browser.get(localhost + 'control')
|
||||||
}
|
}
|
||||||
this.kickDeviceButton = element.all(by.css('.kick-device')).first()
|
this.kickDeviceButton = element.all(by.css('.kick-device')).first()
|
||||||
this.kickDevice = function() {
|
this.kickDevice = function() {
|
||||||
|
@ -26,8 +27,8 @@ describe('Control Page', function() {
|
||||||
|
|
||||||
browser.sleep(500)
|
browser.sleep(500)
|
||||||
|
|
||||||
browser.getLocationAbsUrl().then(function(newUrl) {
|
browser.getCurrentUrl().then(function(newUrl) {
|
||||||
expect(newUrl).toMatch(protractor.getInstance().baseUrl + 'control')
|
expect(newUrl).toContain(localhost + 'control/')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -135,10 +136,10 @@ describe('Control Page', function() {
|
||||||
it('should stop controlling an usable device', function() {
|
it('should stop controlling an usable device', function() {
|
||||||
controlPage.kickDevice()
|
controlPage.kickDevice()
|
||||||
|
|
||||||
waitUrl(/devices/)
|
browser.wait(waitUrl(/devices/), 5000)
|
||||||
|
|
||||||
browser.getLocationAbsUrl().then(function(newUrl) {
|
browser.getCurrentUrl().then(function(newUrl) {
|
||||||
expect(newUrl).toBe(protractor.getInstance().baseUrl + 'devices')
|
expect(newUrl).toBe(localhost + 'devices')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ describe('Device Page', function() {
|
||||||
|
|
||||||
it('should go to Devices List page', function() {
|
it('should go to Devices List page', function() {
|
||||||
deviceListPage.get()
|
deviceListPage.get()
|
||||||
browser.getLocationAbsUrl().then(function(newUrl) {
|
browser.getCurrentUrl().then(function(newUrl) {
|
||||||
expect(newUrl).toBe(protractor.getInstance().baseUrl + 'devices')
|
expect(newUrl).toBe(browser.baseUrl + 'devices')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module.exports = function DeviceListPage() {
|
module.exports = function DeviceListPage() {
|
||||||
this.get = function() {
|
this.get = function() {
|
||||||
// TODO: Let's get rid off the login first
|
// TODO: Let's get rid off the login first
|
||||||
browser.get(protractor.getInstance().baseUrl + 'devices')
|
browser.get(browser.baseUrl + 'devices')
|
||||||
}
|
}
|
||||||
this.devices = element(by.model('tracker.devices'))
|
this.devices = element(by.model('tracker.devices'))
|
||||||
this.devicesByCss = element.all(by.css('ul.devices-icon-view > li'))
|
this.devicesByCss = element.all(by.css('ul.devices-icon-view > li'))
|
||||||
|
|
|
@ -15,7 +15,7 @@ module.exports = function BrowserLogs(opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
browser.getCapabilities().then(function(cap) {
|
browser.getCapabilities().then(function(cap) {
|
||||||
var browserName = ' ' + cap.caps_.browserName + ' log '
|
var browserName = ' ' + cap.browserName + ' log '
|
||||||
var browserStyled = chalk.bgBlue.white.bold(browserName) + ' '
|
var browserStyled = chalk.bgBlue.white.bold(browserName) + ' '
|
||||||
|
|
||||||
browser.manage().logs().get('browser').then(function(browserLogs) {
|
browser.manage().logs().get('browser').then(function(browserLogs) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module.exports = function LoginPage() {
|
module.exports = function LoginPage() {
|
||||||
this.login = protractor.getInstance().params.login
|
this.login = browser.params.login
|
||||||
|
|
||||||
this.get = function() {
|
this.get = function() {
|
||||||
return browser.get(this.login.url)
|
return browser.get(this.login.url)
|
||||||
|
@ -17,17 +17,24 @@ module.exports = function LoginPage() {
|
||||||
this.setName = function(username) {
|
this.setName = function(username) {
|
||||||
return this.username.sendKeys(username)
|
return this.username.sendKeys(username)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setEmail = function(email) {
|
this.setEmail = function(email) {
|
||||||
return this.email.sendKeys(email)
|
return this.email.sendKeys(email)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setPassword = function(password) {
|
this.setPassword = function(password) {
|
||||||
return this.password.sendKeys(password)
|
return this.password.sendKeys(password)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.submit = function() {
|
this.submit = function() {
|
||||||
return this.username.submit()
|
return this.username.submit()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.doLogin = function() {
|
this.doLogin = function() {
|
||||||
|
var EC = protractor.ExpectedConditions
|
||||||
|
var timeout = 15000
|
||||||
this.get()
|
this.get()
|
||||||
|
browser.wait(EC.presenceOf(element(by.css('[value="Log In"]'))), timeout)
|
||||||
this.setName(this.login.username)
|
this.setName(this.login.username)
|
||||||
if (this.login.method === 'ldap') {
|
if (this.login.method === 'ldap') {
|
||||||
this.setPassword(this.login.password)
|
this.setPassword(this.login.password)
|
||||||
|
@ -43,6 +50,7 @@ module.exports = function LoginPage() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cleanUp = function() {
|
this.cleanUp = function() {
|
||||||
this.username = null
|
this.username = null
|
||||||
this.password = null
|
this.password = null
|
||||||
|
|
|
@ -2,14 +2,20 @@ describe('Login Page', function() {
|
||||||
var LoginPage = require('./')
|
var LoginPage = require('./')
|
||||||
var loginPage = new LoginPage()
|
var loginPage = new LoginPage()
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
browser.executeScript('window.localStorage.clear();')
|
||||||
|
browser.executeScript('window.sessionStorage.clear();')
|
||||||
|
browser.driver.manage().deleteAllCookies()
|
||||||
|
})
|
||||||
|
|
||||||
it('should have an url to login', function() {
|
it('should have an url to login', function() {
|
||||||
expect(loginPage.login.url).toMatch('http')
|
expect(loginPage.login.url).toMatch('http')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should login with method: "' + loginPage.login.method + '"', function() {
|
it('should login with method: "' + loginPage.login.method + '"', function() {
|
||||||
loginPage.doLogin().then(function() {
|
loginPage.doLogin().then(function() {
|
||||||
browser.getLocationAbsUrl().then(function(newUrl) {
|
browser.getCurrentUrl().then(function(newUrl) {
|
||||||
expect(newUrl).toBe(protractor.getInstance().baseUrl + 'devices')
|
expect(newUrl).toBe(browser.baseUrl + 'devices')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
var config = require('./protractor.conf').config
|
var config = require('./protractor.conf').config
|
||||||
//var LoginPage = require('./e2e/login')
|
//var LoginPage = require('./e2e/login')
|
||||||
//var HtmlReporter = require('protractor-html-screenshot-reporter')
|
|
||||||
//var WaitUrl = require('./e2e/helpers/wait-url')
|
//var WaitUrl = require('./e2e/helpers/wait-url')
|
||||||
|
|
||||||
config.chromeOnly = false
|
config.chromeOnly = false
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
var LoginPage = require('./e2e/login')
|
var LoginPage = require('./e2e/login')
|
||||||
var BrowserLogs = require('./e2e/helpers/browser-logs')
|
var BrowserLogs = require('./e2e/helpers/browser-logs')
|
||||||
//var FailFast = require('./e2e/helpers/fail-fast')
|
//var FailFast = require('./e2e/helpers/fail-fast')
|
||||||
var HtmlReporter = require('protractor-html-screenshot-reporter')
|
var jasmineReporters = require('jasmine-reporters')
|
||||||
var WaitUrl = require('./e2e/helpers/wait-url')
|
var WaitUrl = require('./e2e/helpers/wait-url')
|
||||||
|
var HTMLReport = require('protractor-html-reporter-2')
|
||||||
|
|
||||||
|
var reportsDirectory = './test-results/reports-protractor'
|
||||||
|
var dashboardReportDirectory = reportsDirectory + '/dashboardReport'
|
||||||
|
|
||||||
module.exports.config = {
|
module.exports.config = {
|
||||||
baseUrl: process.env.STF_URL || 'http://localhost:7100/#!/',
|
baseUrl: process.env.STF_URL || 'http://localhost:7100/#!/',
|
||||||
|
@ -17,7 +21,7 @@ module.exports.config = {
|
||||||
params: {
|
params: {
|
||||||
login: {
|
login: {
|
||||||
url: process.env.STF_LOGINURL || process.env.STF_URL ||
|
url: process.env.STF_LOGINURL || process.env.STF_URL ||
|
||||||
'http://localhost:7120',
|
'http://localhost:7100',
|
||||||
username: process.env.STF_USERNAME || 'test_user',
|
username: process.env.STF_USERNAME || 'test_user',
|
||||||
email: process.env.STF_EMAIL || 'test_user@login.local',
|
email: process.env.STF_EMAIL || 'test_user@login.local',
|
||||||
password: process.env.STF_PASSWORD,
|
password: process.env.STF_PASSWORD,
|
||||||
|
@ -34,7 +38,7 @@ module.exports.config = {
|
||||||
capabilities: {
|
capabilities: {
|
||||||
browserName: 'chrome',
|
browserName: 'chrome',
|
||||||
chromeOptions: {
|
chromeOptions: {
|
||||||
args: ['--test-type'] // Prevent security warning bug in ChromeDriver
|
args: ['--test-type --no-sandbox'] // Prevent security warning bug in ChromeDriver
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
chromeOnly: true,
|
chromeOnly: true,
|
||||||
|
@ -45,16 +49,60 @@ module.exports.config = {
|
||||||
|
|
||||||
this.waitUrl = WaitUrl
|
this.waitUrl = WaitUrl
|
||||||
|
|
||||||
jasmine.getEnv().addReporter(new HtmlReporter({
|
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
|
||||||
baseDirectory: './res/test/test_out/screenshots'
|
consolidateAll: true,
|
||||||
|
savePath: reportsDirectory + '/xml',
|
||||||
|
filePrefix: 'xmlOutput'
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
var fs = require('fs-extra')
|
||||||
|
if (!fs.existsSync(dashboardReportDirectory)) {
|
||||||
|
fs.mkdirs(dashboardReportDirectory)
|
||||||
|
}
|
||||||
|
|
||||||
|
jasmine.getEnv().addReporter({
|
||||||
|
specDone: function(result) {
|
||||||
|
if (result.status === 'failed') {
|
||||||
|
browser.getCapabilities().then(function(caps) {
|
||||||
|
var browserName = caps.get('browserName')
|
||||||
|
|
||||||
|
browser.takeScreenshot().then(function(png) {
|
||||||
|
var stream = fs.createWriteStream(dashboardReportDirectory + '/' +
|
||||||
|
browserName + '-' + result.fullName + '.png')
|
||||||
|
stream.write(new Buffer(png, 'base64'))
|
||||||
|
stream.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
BrowserLogs({expectNoLogs: true})
|
BrowserLogs({expectNoLogs: true})
|
||||||
//FailFast()
|
//FailFast()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onComplete: function() {
|
onComplete: function() {
|
||||||
|
var browserName, browserVersion, platform, testConfig
|
||||||
|
var capsPromise = browser.getCapabilities()
|
||||||
|
|
||||||
|
capsPromise.then(function(caps) {
|
||||||
|
browserName = caps.get('browserName')
|
||||||
|
browserVersion = caps.get('version')
|
||||||
|
platform = caps.get('platform')
|
||||||
|
|
||||||
|
testConfig = {
|
||||||
|
reportTitle: 'Protractor Test Execution Report',
|
||||||
|
outputPath: dashboardReportDirectory,
|
||||||
|
outputFilename: 'index',
|
||||||
|
screenshotPath: './',
|
||||||
|
testBrowser: browserName,
|
||||||
|
browserVersion: browserVersion,
|
||||||
|
modifiedSuiteName: false,
|
||||||
|
screenshotsOnlyOnFailure: true,
|
||||||
|
testPlatform: platform
|
||||||
|
}
|
||||||
|
new HTMLReport().from(reportsDirectory + '/xml/xmlOutput.xml', testConfig)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue