Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.

Commit 41c216a

Browse files
authored
feat(tests): Add Protractor configuration and tests
1 parent 5bd99a7 commit 41c216a

File tree

11 files changed

+5606
-19
lines changed

11 files changed

+5606
-19
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,4 @@ demo/demo.js
88
demo/demo.js.map
99
dist/
1010
docs/
11-
yarn.lock
1211
*.tgz

.travis.yml

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,28 @@ node_js:
33
- '6'
44
script:
55
- npm test
6+
- npm start &
7+
- npm run e2e
68
- npm run typedoc
79
cache:
810
directories:
911
- node_modules
1012
before_install:
11-
- test -z "$BUILD_DOCS" || openssl aes-256-cbc -K $encrypted_d98a3227cf72_key -iv $encrypted_d98a3227cf72_iv
12-
-in keypair.enc -out ~/.ssh/id_rsa -d
13+
- test -z "$BUILD_DOCS" || openssl aes-256-cbc -K $encrypted_d98a3227cf72_key -iv
14+
$encrypted_d98a3227cf72_iv -in keypair.enc -out ~/.ssh/id_rsa -d
1315
- test -z "$BUILD_DOCS" || chmod 600 ~/.ssh/id_rsa
16+
- export DISPLAY=:99.0
17+
- sh -e /etc/init.d/xvfb start
1418
after_success:
1519
- test -z "$BUILD_DOCS" || CURRENT_HASH=`git rev-parse HEAD`
16-
- test -z "$BUILD_DOCS" || RELEASE_VERSION=`git tag | xargs -I@ git log --format=format:"%ai @%n" -1 @ | sort | awk '{print $4}' | tail -n 1`
20+
- test -z "$BUILD_DOCS" || RELEASE_VERSION=`git tag | xargs -I@ git log --format=format:"%ai
21+
@%n" -1 @ | sort | awk '{print $4}' | tail -n 1`
1722
- test -z "$BUILD_DOCS" || RELEASE_HASH=`git rev-list $RELEASE_VERSION -n 1`
18-
- test -z "$BUILD_DOCS" || if [ "$CURRENT_HASH" = "$RELEASE_HASH" ]; then DEPLOY_DOCS=true; fi
23+
- test -z "$BUILD_DOCS" || if [ "$CURRENT_HASH" = "$RELEASE_HASH" ]; then DEPLOY_DOCS=true;
24+
fi
1925
- test -z "$DEPLOY_DOCS" || git config --global user.email "evangelists@stormpath.com"
20-
- test -z "$DEPLOY_DOCS" || git config --global user.name "stormpath-sdk-angular Auto Doc Build"
26+
- test -z "$DEPLOY_DOCS" || git config --global user.name "stormpath-sdk-angular Auto
27+
Doc Build"
2128
- test -z "$DEPLOY_DOCS" || git clone git@github.com:stormpath/stormpath.github.io.git
2229
- test -z "$DEPLOY_DOCS" || cd stormpath.github.io
2330
- test -z "$DEPLOY_DOCS" || git fetch origin source:source
@@ -31,4 +38,13 @@ after_success:
3138
matrix:
3239
include:
3340
- env: BUILD_DOCS=true
34-
node_js: 'node'
41+
node_js: node
42+
notifications:
43+
webhooks:
44+
on_success: change
45+
on_failure: always
46+
on_start: false
47+
env:
48+
global:
49+
- secure: Ql5jkxDVxmLRB+enk2SXT7ZuZQbAv0txQbMYv9iFOk/eezyA+joep3VAze7h8gDsC7eipUisuPNHa0wvJklpacTrNsUfK/HM/IPUwMNdyBEX+lk28L1oT199Aijj51KBH7OuIgnTHp6RP4SahonY9iBRyUhOlAcyan4aCYvMIr9sIvx9PJAPeO5/4olR9UnIIjPsLs8+xuh1nbnu/nb6BClA3wKriSe64K+vREl3x863BPTDzVDBCKbB5F5QTRuNSlJ7NT6JnbqqH6Dt5LQYwu/h4l3gFFMzROKzOcId62EfdMlpyH/akJqxqqKuCd9cQ3eo42wSIu3zD2eq3rhEj6g4WjKilMPxYIjEah3f+75qmby7U8qEJGsuyd1J0nWRXm0e+Uei9w9TVV+shjwH85QVz09w5ktOzZm595pV9v/2gx3dzbPZ/g/xHlhTcvFdxt587EDUEeejXKHFN2/kzQTqc04ZBJ5P2E0SbuoOGv6p030VsZFVuUlZaRcjempXOD7SuoRZ/6v7mpzvT/uHuQdJPzIEUejrLUnCbJ3k/VU9jXp0V88IAl+/vF/4h9e6zuo4eLcQ0Z9q4+hMRXZbiljSENty5tdgGzUfz3bwqWaL8AuFrDyA3wdlT1tqSIjbq1yvD9IzHRToq2jvjqlidbeDKwuh+GlF79+CTjlgV14=
50+
- secure: lLFXP0J7p1rwSAIYzTClDaS05Iv3w8uK1DysdqCFtS180QEP8KN5uWwJQ4+YPklrzPDrE7jN6JJgtDvch9+C4ea1Y/Tuvct3snslWyOCfrg0UKRKkNOv8n/QAgczjoTZkniCc/PElKCyYP1CRPv4jN4AyhOzgSVZ2dzm5+BnKsPf02U6dSn8SO37gOmJGinVPyXLzUpFgvShC5sz1zEahPhr87BM7yz2ImqgibXqPvHDlw0E0ZKYXoTB4w6jaVrl/R743rjJ7PNCvSs2AQT/MZoHBNHGJby3NdSmV4gOCxIhe/eu5AJ6Nu95GRy4q9ThxqlBILJseaQr8OII5ceQ5eaADgaZHqW0fVXZ3VSjdUgmxrZ8ZaVchrgZKDBbNG/tImcPAkjWP6YScUfyqPjaE21W/ckKuwq6mgtPR6mY2z1gQAie0q0mWlbWfGfXE0cvCo0z6Eyr7zsl5NS54ywdjtns8KaN+O2+SrgJbhHunxkKr3ZE/JWfmYyBie4Hb+7inmOcEFmDQJfQ5AaXiHONBnQAIq7RHE73jykpVNUog9nvD7jLSHpPj1+kHg0c18ADzApyP0BCtj42mEnfHlPpoRyrM7e4UxQtlt1WP7zOtWmF0HI9QJ6PcqG2qarC+HHwGs0dbtAU+itYvGcA4e2AD7N6rkbzHutP1ymixI+Krns=

demo/app.component.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@ import { Account } from '../src/shared/account';
99
<div class="container">
1010
<br/>
1111
<br/>
12+
<div class="row" *ngIf="(user$ | async) === false">
13+
<div class="col-xs-12 col-sm-offset-3 col-sm-6">
14+
<h1 class="text-center">Hello</h1>
15+
<br/>
16+
</div>
17+
</div>
1218
<div *ngIf="(user$ | async)" class="row text-center">
13-
<h2 class="">
14-
Welcome, ({{ ( user$ | async ).fullName }}).
15-
</h2>
19+
<h1>
20+
Welcome, {{ ( user$ | async ).fullName }}
21+
</h1>
1622
<hr/>
1723
1824
<ul class="nav nav-pills nav-stacked text-centered">
19-
<li role="presentation" (click)="logout()"><a href="#">Logout</a></li>
25+
<li role="presentation" (click)="logout()"><a id="logout" href="#">Logout</a></li>
2026
</ul>
2127
</div>
2228

demo/demo.module.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,34 @@ import { BrowserModule } from '@angular/platform-browser';
33
import { StormpathModule } from '../src/stormpath.module';
44
import { AppComponent } from './app.component';
55
import { FormsModule } from '@angular/forms';
6+
import { StormpathConfiguration } from '../src/stormpath/stormpath.config';
7+
8+
let config: StormpathConfiguration = new StormpathConfiguration();
9+
let params = {};
10+
11+
if (location.search) {
12+
let parts = location.search.substring(1).split('&');
13+
14+
for (let i = 0; i < parts.length; i++) {
15+
let nv = parts[i].split('=');
16+
if (!nv[0]) continue;
17+
params[nv[0]] = nv[1] || true;
18+
}
19+
}
20+
21+
if (params['api']) {
22+
config.endpointPrefix = params['api']; //'https://raible.apps.stormpath.io';
23+
console.log('Configured endpointPrefix to be: ' + params['api']);
24+
}
25+
626

727
@NgModule({
828
declarations: [AppComponent],
929
imports: [BrowserModule, FormsModule, StormpathModule],
1030
bootstrap: [AppComponent],
11-
providers: []
31+
providers: [{
32+
provide: StormpathConfiguration, useValue: config
33+
}]
1234
})
1335
export class DemoModule {
1436
}

e2e/login.spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { browser, element, by, $ } from 'protractor';
2+
3+
describe('login', () => {
4+
5+
const username = element(by.id('loginField'));
6+
const password = element(by.id('passwordField'));
7+
const logout = element(by.id('logout'));
8+
const title = element.all(by.css('h1')).first();
9+
10+
beforeAll(() => {
11+
browser.get('');
12+
});
13+
14+
it('should fail to login with bad password', () => {
15+
expect(element.all(by.css('h1')).first().getText()).toMatch(/Hello/);
16+
17+
username.sendKeys('admin');
18+
password.sendKeys('foo');
19+
element(by.css('button[type=submit]')).click();
20+
21+
let error = $('.alert-danger').getText();
22+
expect(error).toMatch(/Invalid username or password./);
23+
});
24+
25+
it('should login successfully with valid account', () => {
26+
expect(title.getText()).toMatch(/Hello/);
27+
28+
username.clear();
29+
username.sendKeys('matt.raible+user@stormpath.com');
30+
password.clear();
31+
password.sendKeys('Stormpath1');
32+
element(by.css('button[type=submit]')).click();
33+
34+
expect(title.getText()).toMatch(/Welcome, Hip User/);
35+
36+
logout.click();
37+
38+
expect(title.getText()).toMatch(/Hello/);
39+
});
40+
});

e2e/register.spec.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { browser, element, by, $ } from 'protractor';
2+
3+
describe('register', () => {
4+
5+
const registerLink = element(by.id('register'));
6+
const firstName = element(by.id('givenName'));
7+
const lastName = element(by.id('surname'));
8+
const email = element(by.id('email'));
9+
const password = element(by.id('password'));
10+
const logout = element(by.id('logout'));
11+
const title = element.all(by.css('h1')).first();
12+
13+
beforeEach(() => {
14+
browser.get('');
15+
registerLink.click();
16+
expect(firstName.isDisplayed());
17+
});
18+
19+
afterAll(() => {
20+
// delete user via the REST API
21+
});
22+
23+
it('should fail with short password', () => {
24+
firstName.sendKeys('Test');
25+
lastName.sendKeys('User');
26+
email.sendKeys('matt.raible+user' + getRandomInt(0, 1000) + '@stormpath.com');
27+
password.sendKeys('short');
28+
element(by.css('button[type=submit]')).click();
29+
30+
let error = $('.alert-danger').getText();
31+
expect(error).toMatch(/Account password minimum length not satisfied./);
32+
});
33+
34+
it('should register successfully', () => {
35+
firstName.sendKeys('Test');
36+
lastName.sendKeys('User');
37+
email.sendKeys('matt.raible+user' + getRandomInt(0, 1000) + '@stormpath.com');
38+
password.sendKeys('Stormpath123');
39+
element(by.css('button[type=submit]')).click();
40+
41+
let success = $('.alert-success').getText();
42+
expect(success).toMatch(/Your account has been created, you may now log in./);
43+
expect(title.getText()).toMatch(/Welcome, Test User/);
44+
45+
logout.click();
46+
47+
expect(title.getText()).toMatch(/Hello/);
48+
});
49+
});
50+
51+
function getRandomInt(min, max) {
52+
min = Math.ceil(min);
53+
max = Math.floor(max);
54+
return Math.floor(Math.random() * (max - min)) + min;
55+
}

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"build:clean": "rm -rf dist",
1616
"test": "karma start",
1717
"test:watch": "karma start --watch",
18+
"postinstall": "webdriver-manager update",
19+
"e2e": "protractor",
1820
"commit": "git-cz",
1921
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
2022
"typedoc": "mkdir -p dist/docs && typedoc --options typedoc.json src/*.ts",
@@ -70,6 +72,7 @@
7072
"ghooks": "~1.3.2",
7173
"imports-loader": "^0.7.0",
7274
"jasmine-core": "~2.5.0",
75+
"jasmine-reporters": "^2.2.0",
7376
"karma": "~1.3.0",
7477
"karma-coverage": "~1.1.0",
7578
"karma-jasmine": "^1.1.0",
@@ -78,13 +81,16 @@
7881
"karma-sourcemap-loader": "~0.3.7",
7982
"karma-webpack": "~1.8.0",
8083
"phantomjs-prebuilt": "~2.1.7",
84+
"protractor": "4.0.14",
85+
"protractor-jasmine2-screenshot-reporter": "0.3.2",
8186
"raw-loader": "^0.5.1",
8287
"rxjs": "5.0.1",
8388
"sinon": "~1.17.4",
8489
"sinon-chai": "~2.8.0",
8590
"sourcemap-istanbul-instrumenter-loader": "~0.2.0",
8691
"standard-version": "^4.0.0",
8792
"ts-loader": "^1.3.2s",
93+
"ts-node": "^1.7.2",
8894
"tslint": "^4.0.2",
8995
"tslint-loader": "^3.3.0",
9096
"typescript": "^2.1.4",

protractor.conf.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
var HtmlScreenshotReporter = require("protractor-jasmine2-screenshot-reporter");
2+
var JasmineReporters = require('jasmine-reporters');
3+
4+
exports.config = {
5+
allScriptsTimeout: 20000,
6+
7+
specs: [
8+
'./e2e/*.spec.ts'
9+
],
10+
11+
capabilities: {
12+
'browserName': 'firefox',
13+
'phantomjs.binary.path': require('phantomjs-prebuilt').path,
14+
'phantomjs.ghostdriver.cli.args': ['--loglevel=DEBUG']
15+
},
16+
17+
directConnect: true,
18+
19+
baseUrl: 'http://localhost:8000/', // ?api=https://raible.apps.stormpath.io
20+
21+
framework: 'jasmine2',
22+
23+
jasmineNodeOpts: {
24+
showColors: true,
25+
defaultTimeoutInterval: 30000
26+
},
27+
28+
beforeLaunch: function() {
29+
require('ts-node').register({
30+
project: ''
31+
});
32+
},
33+
34+
onPrepare: function() {
35+
browser.driver.manage().window().setSize(1280, 1024);
36+
jasmine.getEnv().addReporter(new JasmineReporters.JUnitXmlReporter({
37+
savePath: 'dist/reports/e2e',
38+
consolidateAll: false
39+
}));
40+
jasmine.getEnv().addReporter(new HtmlScreenshotReporter({
41+
dest: "dist/reports/e2e/screenshots"
42+
}));
43+
},
44+
45+
useAllAngular2AppRoots: true
46+
};

src/authport/authport.component.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,15 @@ import { Account } from '../shared/account';
1111
<br/>
1212
<br/>
1313
<div class="row" *ngIf="(user$ | async) === false">
14-
<div class="col-xs-12 col-sm-offset-3 col-sm-6">
15-
<h1 class="text-center">Hello</h1>
16-
<br/>
17-
</div>
1814
<div class="col-xs-12 col-sm-offset-3 col-sm-6">
1915
<div class="panel panel-default">
2016
<div class="panel-heading">
2117
<h4>
2218
<ul class="nav nav-pills">
23-
<li role="presentation" [ngClass]="{active:loginService.login || loginService.forgot}" (click)="showLogin()">
19+
<li role="presentation" [ngClass]="{active:loginService.login || loginService.forgot}" id="login" (click)="showLogin()">
2420
<a>Sign In</a>
2521
</li>
26-
<li role="presentation" [ngClass]="{active:loginService.register}" (click)="showRegister()" class="pull-right">
22+
<li role="presentation" [ngClass]="{active:loginService.register}" (click)="showRegister()" id="register" class="pull-right">
2723
<a>Register</a>
2824
</li>
2925
</ul>

src/login/login.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { FormsModule } from '@angular/forms';
3131
</div>
3232
3333
<div *ngIf="error" class="alert alert-danger">{{error}}</div>
34-
<button (click)="login()" class="btn btn-primary pull-right">Login</button>
34+
<button (click)="login()" id="loginBtn" type="submit" class="btn btn-primary pull-right">Login</button>
3535
</form>
3636
</template>
3737
<template

0 commit comments

Comments
 (0)