Skip to content

Commit

Permalink
fix(serenity-bdd): browser and platform context icons show up correct…
Browse files Browse the repository at this point in the history
…ly in scenario outline reports

- Corrected an issue where browser and platform icons might not show up in the Test Results reports.
| - Corrected an issue where browser and platform name might occur several times in the name of the
HTML report file | - Downgraded Serenity BDD reporter CLI to 2.1.10 until the issue with missing
icons is resolved

Closes #597
  • Loading branch information
jan-molak committed Jun 15, 2020
1 parent 7118b64 commit a685afc
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 23 deletions.
13 changes: 13 additions & 0 deletions examples/protractor-cucumber/features/outlines.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Feature: Outlines

Scenario Outline: Actor interacts with a website

When Umbra navigates to the test website number <id>
Then she should see the title of "Test Website number <id>"

Examples:
| id |
| 1 |
| 2 |
| 3 |
| 4 |
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Ensure, equals } from '@serenity-js/assertions';
import { actorCalled, actorInTheSpotlight, engage } from '@serenity-js/core';
import { actorCalled, actorInTheSpotlight, engage, Transform } from '@serenity-js/core';
import { LocalServer, StartLocalServer, StopLocalServer } from '@serenity-js/local-server';
import { Navigate, UseAngular, Website } from '@serenity-js/protractor';
import { After, Before, Then, When } from 'cucumber';
import { Actors } from '../support/screenplay';

Before(() => {
console.log('Cucumber :: sneario-level before')
engage(new Actors())
});

Expand All @@ -17,6 +16,13 @@ When(/^(.*) navigates to the test website$/, (actorName: string) =>
Navigate.to(LocalServer.url()),
));

When(/^(.*) navigates to the test website number (.*?)$/, (actorName: string, id: string) =>
actorCalled(actorName).attemptsTo(
StartLocalServer.onRandomPort(),
UseAngular.disableSynchronisation(),
Navigate.to(Transform.the(LocalServer.url(), url => `${ url }/${ id }`)),
));

Then(/(?:he|she|they) should see the title of "(.*)"/, (expectedTitle: string) =>
actorInTheSpotlight().attemptsTo(
Ensure.that(Website.title(), equals(expectedTitle)),
Expand Down
12 changes: 12 additions & 0 deletions examples/protractor-cucumber/features/support/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import express = require('express');

export const app = express()
.get('/:id', (req: express.Request, res: express.Response) => {

res.send(`<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test Website number ${ req.params.id }</title>
</head>
<body />
</html>
`);
})
.get('/', (req: express.Request, res: express.Response) => {

res.send(`<!DOCTYPE html>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@ import 'mocha';

import { expect } from '@integration/testing-tools';
import { StageManager } from '@serenity-js/core';
import { SceneFinished, SceneParametersDetected, SceneSequenceDetected, SceneStarts, SceneTemplateDetected, TestRunFinishes } from '@serenity-js/core/lib/events';
import { SceneFinished, SceneParametersDetected, SceneSequenceDetected, SceneStarts, SceneTagged, SceneTemplateDetected, TestRunFinishes } from '@serenity-js/core/lib/events';
import { FileSystemLocation, Path } from '@serenity-js/core/lib/io';
import { Category, Description, ExecutionFailedWithError, ExecutionSuccessful, Name, ScenarioDetails, ScenarioParameters } from '@serenity-js/core/lib/model';
import {
BrowserTag,
Category,
Description,
ExecutionFailedWithError,
ExecutionSuccessful,
Name,
PlatformTag,
ScenarioDetails,
ScenarioParameters,
} from '@serenity-js/core/lib/model';
import * as sinon from 'sinon';

import { SerenityBDDReporter } from '../../../../../src/stage';
Expand Down Expand Up @@ -179,4 +189,83 @@ describe('SerenityBDDReporter', () => {
expect(report.testSteps[1].description)
.to.equal(`${name.value} #2 - Developer: wakaleo, Twitter_Handle: @wakaleo`);
});

/**
* @test {SerenityBDDReporter}
* @test {SceneSequenceDetected}
* @test {SceneTemplateDetected}
* @test {SceneParametersDetected}
* @test {ScenarioParameters}
* @test {SceneStarts}
* @test {SceneFinished}
* @test {ExecutionFailedWithError}
* @test {ExecutionSuccessful}
* @test {TestRunFinishes}
*/
it('ensures that context and tags are not duplicated despite having multiple scenarios in a sequence', () => {
given(reporter).isNotifiedOfFollowingEvents(
new SceneSequenceDetected(sequence),
new SceneTemplateDetected(template),
new SceneParametersDetected(
scenario1,
new ScenarioParameters(
new Name('Serenity/JS contributors'),
new Description(`Some of the people who have contributed their time and talent to the Serenity/JS project`),
{ Developer: 'jan-molak', Twitter_Handle: '@JanMolak' },
),
),
new SceneStarts(scenario1),
new SceneTagged(
scenario1,
new BrowserTag('chrome', '83.0.4103.106'),
),
new SceneTagged(
scenario1,
new PlatformTag('Mac OS X'),
),
new SceneFinished(scenario1, new ExecutionFailedWithError(new Error('Something happened'))),

new SceneSequenceDetected(sequence),
new SceneTemplateDetected(template),
new SceneParametersDetected(
scenario2,
new ScenarioParameters(
new Name('Serenity/JS contributors'),
new Description(`Some of the people who have contributed their time and talent to the Serenity/JS project`),
{ Developer: 'wakaleo', Twitter_Handle: '@wakaleo' },
),
),
new SceneStarts(scenario2),
new SceneTagged(
scenario2,
new BrowserTag('chrome', '83.0.4103.106'),
),
new SceneTagged(
scenario2,
new PlatformTag('Mac OS X'),
),
new SceneFinished(scenario2, new ExecutionSuccessful()),
new TestRunFinishes(),
);

const report: SerenityBDDReport = stageManager.notifyOf.firstCall.lastArg.artifact.map(_ => _);

expect(report.id).to.equal('reporting-results;reports-scenario-outlines;chrome-83-0-4103-106;mac-os-x');

expect(report.context).to.equal('chrome,Mac OS X');

expect(report.tags).to.deep.equal([{
browserName: 'chrome',
browserVersion: '83.0.4103.106',
displayName: 'chrome 83.0.4103.106',
name: 'chrome 83.0.4103.106',
type: 'browser',
}, {
displayName: 'Mac OS X',
name: 'Mac OS X',
platformName: 'Mac OS X',
platformVersion: '',
type: 'platform',
}]);
});
});
2 changes: 1 addition & 1 deletion packages/serenity-bdd/src/cli/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @public
*/
export const defaults = {
artifact: 'net.serenity-bdd:serenity-cli:jar:all:2.1.11',
artifact: 'net.serenity-bdd:serenity-cli:jar:all:2.1.10',
repository: 'https://jcenter.bintray.com/',
cacheDir: 'node_modules/@serenity-js/cache',
sourceDir: 'target/site/serenity',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface ScenarioParametersResultLocation {
export class SceneReport {
private static outcomeMapper = new OutcomeMapper();

private id: SceneReportId;
private readonly report: Partial<SerenityBDDReport> & { children?: Array<Partial<TestStep>> };
private readonly activities = new ActivityStack();
private readonly parameters: ScenarioParametersResultLocation[] = [];
Expand All @@ -52,10 +53,11 @@ export class SceneReport {

const isFeatureFile = () => this.scenarioDetails.location.path.value.endsWith('.feature');

this.id = new SceneReportId(this.scenarioDetails.category.value).append(this.scenarioDetails.name.value);

this.report = {
name: this.scenarioDetails.name.value,
title: this.scenarioDetails.name.value,
id: new SceneReportId(this.scenarioDetails.category.value).append(this.scenarioDetails.name.value).value,
manual: false,
testSteps: [],
get children() {
Expand All @@ -64,7 +66,7 @@ export class SceneReport {
return this.testSteps;
},
userStory: {
id: new SceneReportId(this.scenarioDetails.category.value).value,
id: new SceneReportId(this.scenarioDetails.category.value).value(),
storyName: this.scenarioDetails.category.value,
path: isFeatureFile() ? this.scenarioDetails.location.path.value : '',
type: 'feature',
Expand Down Expand Up @@ -101,7 +103,14 @@ export class SceneReport {
};
}

const concatenated = (...names: string[]): string => names.filter(name => !! name).join('/');
const concatenated = (...names: string[]): string =>
names.filter(name => !! name).join('/');

const unique = (items: string[]) =>
[...new Set(items)];

const appendUniqueTo = (commaSeparatedListOrEmpty: string, item: string): string =>
unique((commaSeparatedListOrEmpty || '').split(',').filter(_ => !! _).concat(item)).join(',');

const serenityBDDTag = serenityBDDTagFrom(tag);

Expand All @@ -128,15 +137,21 @@ export class SceneReport {
report.additionalIssues = (report.additionalIssues || []).concat(tag.name);
})
.when(BrowserTag, (browserTag: BrowserTag) => {
report.context = [report.context, browserTag.browserName].filter(part => !! part).join(',');
report.driver = browserTag.browserName;
report.id = new SceneReportId(browserTag.name, report.id).value;
report.context = appendUniqueTo(report.context, browserTag.browserName);
report.driver = browserTag.browserName;

this.id.append(browserTag.name);
})
.when(PlatformTag, (platformTag: PlatformTag) => {
report.context = [report.context, platformTag.name].filter(part => !! part).join(',');
report.id = new SceneReportId(platformTag.name, report.id).value;
report.context = appendUniqueTo(report.context, platformTag.name);

this.id.append(platformTag.name);
})
.when(ContextTag, _ => {
report.context = tag.name;

this.id.append(tag.name);
})
.when(ContextTag, _ => (report.context = tag.name))
.else(_ => void 0);

if (! report.tags.find(current => equal(current, serenityBDDTag))) {
Expand Down Expand Up @@ -325,6 +340,8 @@ export class SceneReport {

delete report.children; // remove the fake reference

report.id = this.id.value();

this.parameters.forEach(entry => {

const parameters = entry.parameters.values;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@ import { ensure, isDefined, isGreaterThan, property, TinyType } from 'tiny-types

export class SceneReportId extends TinyType {

public readonly value: string;
public readonly values: string[] = [];

constructor(segment: string, base?: string) {
constructor(segment: string) {
super();
ensure('ID segment', segment, isDefined(), property('length', isGreaterThan(0)));

this.value = [
base,
this.dashify(segment),
].filter(_ => !! _).join(';');
this.values = [this.verified(segment)];
}

append(segment: string): SceneReportId {
return new SceneReportId(segment, this.value);
this.values.push(this.verified(segment));

return this;
}

public value(): string {
return [...new Set(this.values)].map(value => this.dashify(value)).join(';');
}

private verified(segment: string) {
return ensure('SceneReportId segment', segment, isDefined(), property('length', isGreaterThan(0)));
}

private dashify(text: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ export class SceneReports {
return new SceneReportId(scenarioDetails.category.value)
.append(scenarioDetails.name.value)
.append(scenarioDetails.location.path.value) // todo: should this include the line?
.value;
.value();
}
}

0 comments on commit a685afc

Please sign in to comment.