Skip to content

Commit b8c62d9

Browse files
committed
A place to start
0 parents  commit b8c62d9

26 files changed

+513
-0
lines changed

.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# IntelliJ
2+
.idea
3+
*.iml
4+
5+
# Node
6+
node_modules
7+
target/
8+
*.log
9+
10+
# Build artifacts
11+
.nyc_output
12+
lib
13+
staging
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Feature: Journey Planner
2+
3+
As a commuter,
4+

I’d like to know the fastest route between two stations,
5+

So that I get to my destination as quickly as possible
6+
7+
Scenario: Connie looks for the next train
8+
9+
Given Jubilee line trains from Stratford leave Canary Wharf at 16:59, 17:01, 17:03, 17:09
10+
When Connie wants to travel from Canary Wharf to Waterloo Underground Station at 17:00, avoiding travelling by Bus, National Rail
11+
Then she should be told about the trains departing at 16:59, 17:01, 17:03
12+
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import {
2+
AvoidTravelling,
3+
Check,
4+
ChooseDestination,
5+
ChooseOrigin,
6+
ChooseTime,
7+
ConfirmSelection,
8+
SpecifyPreferences,
9+
} from '../../src/journey_planner';
10+
11+
import { Navigate, PlanAJourney } from '../../src';
12+
13+
import { following } from '../../src/text';
14+
15+
import { containTrainsDepartingAt } from '../../src/journey_planner/questions/journeys_found';
16+
17+
export = function journeyPlannerSteps() {
18+
19+
this.Given(/(.*) line trains from (.*) leave (.*) at (.*)$/, function(tubeLine, origin, station, departureTimes) {
20+
// return this.stage.theActorCalled('Adam the admin').attemptsTo(
21+
// ... Perform some data setup tasks
22+
// );
23+
});
24+
25+
this.When(/(.*) wants to travel from (.*) to (.*) at (.*), avoiding travelling by (.*)$/, function(name, origin, destination, departureTime, ignoredTravelOptions) {
26+
27+
return this.stage.theActorCalled(name).attemptsTo(
28+
29+
PlanAJourney.from(origin).
30+
to(destination).
31+
departingAt(departureTime).
32+
avoiding(ignoredTravelOptions),
33+
34+
// Note: The `PlanAJourney` task above is a composite of the below sub-tasks.
35+
// If you'd like, you could use them here instead:
36+
37+
// Navigate.to('https://tfl.gov.uk/'),
38+
//
39+
// ChooseOrigin.of(origin),
40+
// ChooseDestination.of(destination),
41+
// ChooseTime.ofDeparture(departureTime),
42+
// SpecifyPreferences.to(
43+
// AvoidTravelling.by(following(ignoredTravelOptions)),
44+
// ),
45+
// ConfirmSelection(),
46+
);
47+
});
48+
49+
this.Then(/s?he should be told about the trains departing at (.*)$/, function(departureTimes) {
50+
51+
return this.stage.theActorInTheSpotlight().attemptsTo(
52+
53+
Check.ifJourneysFound(containTrainsDepartingAt(following(departureTimes))),
54+
55+
// Note: the `Check` task above is a composite of the below sub-tasks:
56+
57+
// Wait.until(JourneyPlanner.Results, Is.visible()),
58+
// Scroll.to(JourneyPlanner.Results),
59+
// See.if(Journeys.found(), containTrainsDepartingAt(following(departureTimes))),
60+
);
61+
});
62+
};

features/support/world.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { serenity } from 'serenity-js';
2+
import { Actors } from '../../src/actors';
3+
4+
export = function() {
5+
6+
this.setDefaultTimeout(60 * 1000);
7+
8+
this.World = function() {
9+
this.stage = serenity.callToStageFor(new Actors());
10+
};
11+
};

package.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "tutorial-journey-planner",
3+
"version": "1.0.0",
4+
"description": "Serenity.js with Protractor and Cucumber",
5+
"main": "index.js",
6+
"scripts": {
7+
"clean": "rimraf target",
8+
"lint": "tslint --config ./tslint.json --project ./tsconfig.json --format stylish",
9+
"pretest": "serenity update",
10+
"pree2e": "npm run lint && npm run webdriver:update -- --standalone --versions.standalone=2.53.1 --versions.chrome=2.29",
11+
"e2e": "protractor ./protractor.conf.js --cucumberOpts.name 'Connie looks for the next train'",
12+
"report": "serenity run",
13+
"test": "failsafe e2e report",
14+
"webdriver:update": "webdriver-manager update"
15+
},
16+
"repository": {
17+
"type": "git",
18+
"url": "git+https://github.com/serenity-js/tutorial-journey-planner.git"
19+
},
20+
"author": "Jan Molak <jan.molak@smartcodeltd.co.uk>",
21+
"license": "Apache-2.0",
22+
"dependencies": {},
23+
"devDependencies": {
24+
"@types/chai": "3.5.2",
25+
"@types/chai-as-promised": "0.0.30",
26+
"@types/node": "7.0.18",
27+
"chai": "3.5.0",
28+
"chai-as-promised": "6.0.0",
29+
"chai-smoothie": "0.x",
30+
"cucumber": "1.3.2",
31+
"npm-failsafe": "0.x",
32+
"protractor": "5.1.1",
33+
"rimraf": "2.6.1",
34+
"serenity-cli": "^0.1.4",
35+
"serenity-js": "^1.x",
36+
"ts-node": "3.0.2",
37+
"tslint": "5.1.0",
38+
"tslint-microsoft-contrib": "5.0.0",
39+
"typescript": "2.2.2"
40+
},
41+
"engines": {
42+
"node": ">= 6.9.x"
43+
}
44+
}

protractor.conf.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
exports.config = {
2+
3+
baseUrl: 'https://tfl.gov.uk',
4+
5+
allScriptsTimeout: 110000,
6+
7+
framework: 'custom',
8+
frameworkPath: require.resolve('serenity-js'),
9+
10+
specs: [ 'features/**/*.feature' ],
11+
cucumberOpts: {
12+
require: [ 'features/**/*.ts' ],
13+
format: 'pretty',
14+
compiler: 'ts:ts-node/register'
15+
},
16+
17+
capabilities: {
18+
browserName: 'chrome',
19+
chromeOptions: {
20+
args: [
21+
// 'incognito',
22+
// 'disable-extensions',
23+
// 'show-fps-counter=true'
24+
]
25+
}
26+
}
27+
};

readme.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Journey Planner
2+
3+
4+
5+
This project demonstrates how a Serenity/JS test scenario can interact with
6+
a non-Angular app - the [TFL's Journey Planner](https://tfl.gov.uk/)
7+
and acts as a supporting material for my Devoxx UK 2017 talk ["Test-driving modern web apps at scale"](https://cfp.devoxx.co.uk/2017/talk/UTM-3900/Test-driving_modern_web_apps._At_scale._)
8+
9+
To run the example:
10+
```
11+
npm install
12+
npm test
13+
```
14+
15+
Once the test execution is complete, you'll find the test report at:
16+
17+
```
18+
target/site/serenity/index.html
19+
```
20+
21+
To remove the test report and start fresh run:
22+
23+
```
24+
npm run clean
25+
```
26+
27+
Please make sure that you're using the latest [long-term support](https://nodejs.org/en/download/) of Node.js
28+
29+
----
30+
31+
Have fun!
32+
33+
[Jan Molak](https://janmolak.com)

src/actors.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { protractor } from 'protractor';
2+
import { Actor, BrowseTheWeb, Cast } from 'serenity-js/lib/screenplay-protractor';
3+
4+
// note: it's important to use `protractor.browser` not simply `browser`
5+
// a bug in Protractor makes the latter to fail upon a browser restart
6+
// see: https://github.com/angular/protractor/issues/2001
7+
8+
export class Actors implements Cast {
9+
actor(name: string): Actor {
10+
return Actor.named(name).whoCan(BrowseTheWeb.using(protractor.browser));
11+
}
12+
}

src/expect.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import chai = require('chai');
2+
import chaiAsPromised = require('chai-as-promised');
3+
4+
chai.use(chaiAsPromised);
5+
6+
export const expect = chai.expect;

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './actors';
2+
export * from './navigate';
3+
export * from './plan_a_journey';

0 commit comments

Comments
 (0)