Skip to content
Permalink
Browse files
feat(local-server): the new local-server module
affects: @serenity-js/core, @serenity-js/local-server, @serenity-js/rest,
@serenity-js-examples/calculator-app, @serenity-js-examples/cucumber-rest-api-level-testing,
@documentation/website

The local-server module enables the Actors to manage local node test servers.
  • Loading branch information
jan-molak committed Nov 16, 2018
1 parent 69f4e03 commit 29b2527c278dbd8eb701cff039c91f5e22a17df8
Showing with 5,546 additions and 2,950 deletions.
  1. +1 −0 documentation/website/package.json
  2. +9 −5 examples/calculator-app/index.js
  3. +0 −37 examples/calculator-app/spec/rest-api/controllers.spec.ts
  4. +1 −0 examples/calculator-app/src/index.ts
  5. +0 −4 examples/calculator-app/src/rest-api/controllers.ts
  6. +1 −1 examples/calculator-app/src/rest-api/index.ts
  7. +17 −2 examples/cucumber-rest-api-level-testing/features/step_definitions/api-level.steps.ts
  8. +5 −2 examples/cucumber-rest-api-level-testing/features/support/screenplay/Actors.ts
  9. +3 −1 examples/cucumber-rest-api-level-testing/features/support/screenplay/tasks/RequestCalculationOf.ts
  10. +1 −0 examples/cucumber-rest-api-level-testing/package.json
  11. +2,895 −2,895 package-lock.json
  12. +22 −0 packages/core/src/screenplay/Answer.ts
  13. +1 −0 packages/core/src/screenplay/index.ts
  14. +26 −0 packages/core/src/screenplay/interactions/Log.ts
  15. +1 −0 packages/core/src/screenplay/interactions/index.ts
  16. +1 −0 packages/local-server/.esdoc.js
  17. +9 −0 packages/local-server/.gitignore
  18. +14 −0 packages/local-server/.npmignore
  19. +201 −0 packages/local-server/LICENSE.md
  20. +1 −0 packages/local-server/NOTICE.md
  21. +11 −0 packages/local-server/README.md
  22. +1,809 −0 packages/local-server/package-lock.json
  23. +93 −0 packages/local-server/package.json
  24. +61 −0 packages/local-server/spec/reporting.spec.ts
  25. +37 −0 packages/local-server/spec/servers.spec.ts
  26. +8 −0 packages/local-server/spec/servers/barebones.ts
  27. +10 −0 packages/local-server/spec/servers/express.ts
  28. +11 −0 packages/local-server/spec/servers/hapi.ts
  29. +8 −0 packages/local-server/spec/servers/index.ts
  30. +7 −0 packages/local-server/spec/servers/koa.ts
  31. +13 −0 packages/local-server/spec/servers/restify.ts
  32. +1 −0 packages/local-server/src/index.ts
  33. +107 −0 packages/local-server/src/screenplay/abilities/ManageALocalServer.ts
  34. +1 −0 packages/local-server/src/screenplay/abilities/index.ts
  35. +3 −0 packages/local-server/src/screenplay/index.ts
  36. +24 −0 packages/local-server/src/screenplay/interactions/StartLocalServer.ts
  37. +24 −0 packages/local-server/src/screenplay/interactions/StopLocalServer.ts
  38. +2 −0 packages/local-server/src/screenplay/interactions/index.ts
  39. +40 −0 packages/local-server/src/screenplay/questions/LocalServer.ts
  40. +1 −0 packages/local-server/src/screenplay/questions/index.ts
  41. +10 −0 packages/local-server/tsconfig-lint.json
  42. +22 −0 packages/local-server/tsconfig.json
  43. +0 −3 packages/rest/register.js
  44. +2 −0 packages/rest/src/model/OptionsRequest.ts
  45. +11 −0 packages/rest/src/screenplay/abilities/CallAnApi.ts
  46. +20 −0 packages/rest/src/screenplay/interactions/ChangeApiUrl.ts
  47. +1 −0 packages/rest/src/screenplay/interactions/index.ts
@@ -39,6 +39,7 @@
"@serenity-js/assertions": "*",
"@serenity-js/core": "*",
"@serenity-js/cucumber": "*",
"@serenity-js/local-server": "*",
"@serenity-js/rest": "*",
"cheerio": "1.0.0-rc.2",
"clean-css": "4.2.1",
@@ -1,10 +1,14 @@
const
port = process.env.PORT || 3000,
runningInDevMode = `${ process.env.NODE_ENV }`.toLocaleLowerCase() === 'test';
http = require('http'),
logger = require('morgan')('combined'),
port = process.env.PORT || 3000,
runningInDevMode = `${ process.env.NODE_ENV }`.toLocaleLowerCase() === 'test',
{ requestHandler } = runningInDevMode ? inMemoryServer() : compiledServer(),
server = http.createServer(requestHandler.use(logger));

(runningInDevMode ? inMemoryServer() : compiledServer())
.use(require('morgan')('combined'))
.listen(port, () => console.log(`Calculator server started on port ${ port }`));
server.listen(port, () => {
console.log(`Calculator server started on port ${ port }`)
});

// ---

This file was deleted.

@@ -1,2 +1,3 @@
export * from './Calculator';
export * from './rest-api';
export * from './domain';
@@ -18,8 +18,6 @@ export function controllers(api: express.Application, calculator: Calculator) {
// curl -X POST -H "Content-Type: text/plain" --data "2+2" http://localhost:3000/api/calculations
api.post('/api/calculations', bodyParser.text(), (req: express.Request, res: express.Response) => {

// res.status(500).send();

const
calculation = Expression.fromString(req.body),
calculationId = CalculationId.create();
@@ -35,8 +33,6 @@ export function controllers(api: express.Application, calculator: Calculator) {

api.get('/api/calculations/:calculation_id', (req: express.Request, res: express.Response) => {

// res.status(500).send();

const
calculationId = new CalculationId(req.params.calculation_id),
query = new GetCalculationResult(calculationId);
@@ -3,4 +3,4 @@ import * as express from 'express';
import { Calculator } from '../Calculator';
import { controllers } from './controllers';

export = controllers(express(), new Calculator());
export const requestHandler = controllers(express(), new Calculator());
@@ -1,9 +1,18 @@
import { equals } from '@serenity-js/assertions';
import { WithStage } from '@serenity-js/cucumber';
import { LastResponse } from '@serenity-js/rest';
import { Then, When } from 'cucumber';
import { LocalServer, StartLocalServer, StopLocalServer } from '@serenity-js/local-server';
import { ChangeApiUrl, LastResponse } from '@serenity-js/rest';
import { After, Before, Then, When } from 'cucumber';
import { RequestCalculationOf, VerifyResultAt } from '../support/screenplay';

Before(function() {
return this.stage.theActorCalled('Apisitt').attemptsTo( // todo: change to Maggie
StartLocalServer.onRandomPort(),
ChangeApiUrl.to(LocalServer.url()),
// TakeNote.of(LocalServer.url()) // Question or Question<Promise>; Pass between actors
);
});

When(/^(.*) asks for the following calculation: (.*)$/, function(this: WithStage, actorName: string, expression: string) {
return this.stage.actor(actorName).attemptsTo(
RequestCalculationOf(expression),
@@ -15,3 +24,9 @@ Then(/(?:he|she|they) should get a result of ([\d-.]+)/, function(this: WithStag
VerifyResultAt(LastResponse.header('location'), equals({ result: Number(expectedResult) })),
);
});

After(function() {
return this.stage.theActorCalled('Apisitt').attemptsTo(
StopLocalServer.ifRunning(),
);
});
@@ -1,11 +1,14 @@
import { Actor, Cast } from '@serenity-js/core';
import { ManageALocalServer } from '@serenity-js/local-server';
import { CallAnApi } from '@serenity-js/rest';

import { requestHandler } from '@serenity-js-examples/calculator-app';

export class Actors implements Cast {
actor(name: string) {
return Actor.named(name).whoCan(
// todo add express restart ability
CallAnApi.at('http://localhost:3000'),
ManageALocalServer.using(requestHandler),
CallAnApi.at('http://localhost'),
);
}
}
@@ -4,7 +4,9 @@ import { LastResponse, PostRequest, Send } from '@serenity-js/rest';

export const RequestCalculationOf = (expression: string) =>
Task.where(`#actor requests calculation of ${ expression }`,
Send.a(PostRequest.to('/api/calculations').with(expression).using({ headers: { 'Content-Type': 'text/plain' }})),
Send.a(
PostRequest.to('/api/calculations').with(expression).using({ headers: { 'Content-Type': 'text/plain' }}),
),
Ensure.that(LastResponse.status(), equals(201)),
Ensure.that(LastResponse.header('location'), startsWith('/api/calculations/')),
);
@@ -40,6 +40,7 @@
"@serenity-js/assertions": "*",
"@serenity-js/core": "*",
"@serenity-js/cucumber": "*",
"@serenity-js/local-server": "*",
"@serenity-js/rest": "*",
"@types/cucumber": "4.0.4",
"@types/express": "4.16.0",

0 comments on commit 29b2527

Please sign in to comment.