Permalink
Browse files

feat(interactions): Multi-value Select interaction and question

  • Loading branch information...
jan-molak committed Dec 15, 2016
1 parent 87c2d80 commit 81fdb4532fb6806479e3f0030d328250b435febd
View
@@ -1,5 +1,6 @@
.idea
*.iml
.nyc_output
node_modules
typings
View
@@ -8,6 +8,7 @@ typings
!typings.json
npm-debug.log
.npmignore
.nyc_output
# Build process
staging
@@ -17,6 +18,7 @@ mocha.opts
# Pre-transpiled sources and specs
behaviour
cookbook
examples
spec
src
@@ -17,7 +17,9 @@ exports.config = {
},
baseUrl: 'file://' + __dirname + '/',
restartBrowserBetweenTests: false,
onPrepare: function () {
// By default, Protractor uses data:text/html,<html></html> as resetUrl, but
View
No changes.
@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html>
<head>
<script src="/lib/angular.min.js"></script>
<title>Basic Forms</title>
<style>
fieldset {
margin-bottom: 10px;
}
label {
display: block;
padding:10px;
margin:10px;
border:1px solid grey;
border-radius: 5px;
}
pre {
border: 1px dashed lightgrey;
padding:10px;
}
</style>
</head>
<body ng-app="demo">
<form>
<fieldset name="text-input" ng-controller="text-input">
<legend>Working with text</legend>
<label for="text">
Username:
<input type="text" ng-model="text.username" id="text" />
<pre>{{ text.username }}</pre>
</label>
<label for="textarea">
Bio:
<textarea id="textarea" ng-model="text.bio"></textarea>
<pre>{{ text.bio }}</pre>
</label>
</fieldset>
<fieldset name="checkboxes" ng-controller="checkboxes">
<legend>Working with checkboxes</legend>
<label for="checkbox">
<input type="checkbox" ng-model="checkboxes.weekly_newsletter" id="checkbox" />
Select to receive the weekly newsletter
<pre>{{ checkboxes.weekly_newsletter }}</pre>
</label>
</fieldset>
<fieldset name="options" ng-controller="options">
<legend>Working with options</legend>
<label for="single-option">
Country
<select ng-options="country as country.name for country in countries track by country.id"
ng-model="selected_country" id="single-option"></select>
<pre>{{ selected_country.name }}</pre>
</label>
<label for="multiple-options">
Country
<select ng-options="country as country.name for country in countries track by country.id"
ng-model="selected_countries" multiple id="multiple-options"></select>
<pre>{{ list_countries() }}</pre>
</label>
</fieldset>
</form>
<script>
angular.module('demo', [])
.controller('text-input', ['$scope', function ($scope) {
$scope.checkboxes = {
weekly_newsletter: false
};
}])
.controller('checkboxes', ['$scope', function ($scope) {
$scope.checkboxes = {
weekly_newsletter: false
};
}])
.controller('options', ['$scope', function ($scope) {
$scope.countries = [{
id: 'GB',
name: 'United Kingdom'
}, {
id: 'PL',
name: 'Poland'
}, {
id: 'DE',
name: 'Germany'
}, {
id: 'FR',
name: 'France'
}];
$scope.selected_country = $scope.countries[0];
$scope.selected_countries = [ $scope.countries[0] ];
$scope.list_countries = function() {
return $scope.selected_countries.map(country => country.name).join(', ');
}
}]);
</script>
</body>
</html>
View
@@ -0,0 +1,6 @@
import chai = require('chai');
chai.use(require('chai-as-promised')); // tslint:disable-line:no-var-requires
chai.use(require('chai-smoothie')); // tslint:disable-line:no-var-requires
export = chai.expect;
@@ -0,0 +1,20 @@
'use strict';
require('ts-node/register');
var path = require('path'),
protractor = require.resolve('protractor'),
node_modules = protractor.substring(0, protractor.lastIndexOf('node_modules') + 12);
exports.config = {
seleniumServerJar: path.resolve(node_modules, 'protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-2.53.1.jar'),
framework: 'mocha',
specs: [ 'recipes/**/*.recipe.ts' ],
capabilities: {
'browserName': 'chrome',
'phantomjs.binary.path': path.resolve(node_modules, 'phantomjs-prebuilt/lib/phantom/bin/phantomjs'),
},
restartBrowserBetweenTests: false
};
@@ -0,0 +1,95 @@
import synced = require('selenium-webdriver/testing');
import expect = require('../expect');
import { Actor, BrowseTheWeb, Target } from '../../src/screenplay-protractor';
import { Click, Enter, Open, Select, SelectedValue, SelectedValues, Text, Value } from '../../src/serenity-protractor';
import { AppServer } from '../server';
import { by, protractor } from 'protractor';
class Username {
static Field = Target.the('username field').located(by.css('[name="text-input"] label[for="text"] input'));
static Result = Target.the('username value').located(by.css('[name="text-input"] label[for="text"] pre'));
}
class Bio {
static Field = Target.the('bio field').located(by.css('[name="text-input"] label[for="textarea"] textarea'));
static Result = Target.the('bio value').located(by.css('[name="text-input"] label[for="textarea"] pre'));
}
class Newsletter {
static Checkbox = Target.the('newsletter checkbox').located(by.css('[name="checkboxes"] label[for="checkbox"] input'));
static Result = Target.the('newsletter result').located(by.css('[name="checkboxes"] label[for="checkbox"] pre'));
}
class SingleCountry {
static Selector = Target.the('country selector').located(by.css('[name="options"] label[for="single-option"] select'));
static Result = Target.the('country result').located(by.css('[name="options"] label[for="single-option"] pre'));
}
class MultiCountry {
static Selector = Target.the('country selector').located(by.css('[name="options"] label[for="multiple-options"] select'));
static Result = Target.the('country result').located(by.css('[name="options"] label[for="multiple-options"] pre'));
}
synced.describe ('When demonstrating the usage of an HTML form, a test scenario', () => {
let app = new AppServer();
let james = Actor.named('James').whoCan(BrowseTheWeb.using(protractor.browser));
synced.before(app.start());
synced.before(() => james.attemptsTo(
Open.browserOn(app.demonstrating('basic_forms'))
));
synced.after(app.stop());
synced.it ('can interact with a single-line text input', () =>
james.attemptsTo(
Enter.theValue('James').into(Username.Field)
).then(() => Promise.all([
expect(james.toSee(Value.of(Username.Field))).eventually.equal('James'),
expect(james.toSee(Text.of(Username.Result))).eventually.equal('James'),
]))
);
synced.it ('can interact with a text area', () =>
james.attemptsTo(
Enter.theValue('Lorem ipsum\ndolor\nsit amet').into(Bio.Field)
).then(() => Promise.all([
expect(james.toSee(Value.of(Bio.Field))).eventually.equal('Lorem ipsum\ndolor\nsit amet'),
expect(james.toSee(Text.of(Bio.Result))).eventually.equal('Lorem ipsum\ndolor\nsit amet'),
]))
);
synced.it ('can interact with a checkbox', () =>
james.attemptsTo(
Click.on(Newsletter.Checkbox)
).then(() => Promise.all([
expect(james.toSee(Value.of(Newsletter.Checkbox))).eventually.equal('on'),
expect(james.toSee(Text.of(Newsletter.Result))).eventually.equal('true'),
]))
);
synced.it ('can interact with a select box', () =>
james.attemptsTo(
Select.theValue('France').from(SingleCountry.Selector)
).then(() => Promise.all([
expect(james.toSee(SelectedValue.of(SingleCountry.Selector))).eventually.equal('France'),
expect(james.toSee(Text.of(SingleCountry.Result))).eventually.equal('France')
]))
);
synced.it ('can interact with multi-choice select box', () =>
james.attemptsTo(
Select.values('Poland', 'France').from(MultiCountry.Selector)
).then(() => Promise.all([
expect(james.toSee(SelectedValues.of(MultiCountry.Selector))).eventually.deep.equal(['Poland', 'France']),
expect(james.toSee(Text.of(MultiCountry.Result))).eventually.equal('Poland, France'),
]))
);
});
View
@@ -0,0 +1,2 @@
require('ts-node/register');
require('./server/index.ts').start(8080);
View
@@ -0,0 +1,40 @@
import express = require('express');
import { Server } from 'http';
export class AppServer {
private instance?: Server;
constructor() {}
start(port: number = 0) {
return () => new Promise<AppServer>((resolve, reject) => {
let app = express();
app.use('/lib', express.static(__dirname + '/lib'));
app.use(express.static(__dirname + '/../apps'));
let server = app.listen(port, () => {
this.instance = server;
resolve(this);
});
});
}
demonstrating = (app: string) => `http://localhost:${ this.instance.address().port }/${ app }.html`;
stop(): () => void {
return () => this.instance.close();
}
}
export function start(port: number = 8080) {
let app = express();
app.use('/lib', express.static(__dirname + '/lib'));
app.use(express.static(__dirname + '/../apps'));
return app.listen(port);
}
@@ -27,7 +27,7 @@
"chai-smoothie": "^0.1.2",
"cucumber": "1.2.2",
"npm-failsafe": "^0.1.0",
"protractor": "4.0.11",
"protractor": "4.0.13",
"protractor-cucumber-framework": "0.6.0",
"rimraf": "2.5.4",
"serenity-cli": "^0.1.4",
View
@@ -6,6 +6,7 @@ module.exports = {
coverage: {
all: 'staging/reports/coverage',
spec: 'staging/reports/coverage/spec',
cookbook: 'staging/reports/coverage/cookbook/coverage-final.json',
behaviour: {
all: 'staging/reports/coverage/behaviour',
cucumber: 'staging/reports/coverage/behaviour/cucumber',
View
@@ -76,7 +76,8 @@ gulp.task('aggregate', () => {
return merge([
remapCoverageToTypescript(dirs.staging.reports.coverage.spec),
remapCoverageToTypescript(dirs.staging.reports.coverage.behaviour.protractor),
remapCoverageToTypescript(dirs.staging.reports.coverage.behaviour.cucumber)
remapCoverageToTypescript(dirs.staging.reports.coverage.behaviour.cucumber),
gulp.src(dirs.staging.reports.coverage.cookbook)
])
// .pipe(gulp.dest(dirs.staging.reports.coverage.all));
Oops, something went wrong.

0 comments on commit 81fdb45

Please sign in to comment.