Skip to content
This repository was archived by the owner on Jun 17, 2025. It is now read-only.

Commit e8bff30

Browse files
authored
Merge pull request #64 from reportportal/develop
Release
2 parents 6da3ceb + e18c50d commit e8bff30

33 files changed

+1458
-106
lines changed

CHANGELOG.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
# Changelog
22

3-
[Unreleased]
3+
## [Unreleased]
4+
### Fixed
5+
- A bug whe ambiguous item cases a Null Pointer Exception
6+
- Incorrect item type settings
7+
### Added
8+
- Nested steps support
49

510
## [5.0.0-BETA-12]
11+
### Added
12+
- multi-thread execution support
13+
- Test Case ID support
14+
### Fixed
15+
- codeRef reporting was added for every item in an item tree
16+
17+
## [3.0.0]
18+
### New Features
19+
- Migrate to 3x client generation
20+
- Asynchronous reporting
21+
22+
## [2.6.1]
23+
### Changed
24+
- access modifier to 'protected' for rootSuiteId in ScenarioReporter to allow inherit this reporter without unnecessary code duplication.
25+
26+
## [2.6.0]
27+
### Released: 20 November 2016
28+
### New Features
29+
- Initial release to Public Maven Repositories

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Cucumber Agent for ReportPortal
22
[ ![Download](https://api.bintray.com/packages/epam/reportportal/agent-java-cucumber/images/download.svg) ](https://bintray.com/epam/reportportal/agent-java-cucumber/_latestVersion)
33

4+
![CI Build](https://github.com/reportportal/agent-java-cucumber/workflows/CI%20Build/badge.svg)
45
[![Join Slack chat!](https://reportportal-slack-auto.herokuapp.com/badge.svg)](https://reportportal-slack-auto.herokuapp.com)
56
[![stackoverflow](https://img.shields.io/badge/reportportal-stackoverflow-orange.svg?style=flat)](http://stackoverflow.com/questions/tagged/reportportal)
67
[![UserVoice](https://img.shields.io/badge/uservoice-vote%20ideas-orange.svg?style=flat)](https://rpp.uservoice.com/forums/247117-report-portal)

build.gradle

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,13 @@ publishing {
4848
}
4949

5050
dependencies {
51-
api 'com.epam.reportportal:client-java:5.0.6'
51+
api 'com.epam.reportportal:client-java:5.0.7'
5252
api 'com.epam.reportportal:commons-model:5.0.0'
5353
api 'com.google.code.findbugs:jsr305:3.0.2'
5454

5555
implementation 'info.cukes:gherkin:2.12.2'
5656

57+
testImplementation 'org.aspectj:aspectjweaver:1.9.2'
5758
testImplementation 'info.cukes:cucumber-java:1.2.6'
5859
testImplementation 'info.cukes:cucumber-testng:1.2.6'
5960
testImplementation 'org.hamcrest:hamcrest-core:2.2'
@@ -73,7 +74,17 @@ dependencies {
7374
}
7475

7576
test {
77+
outputs.upToDateWhen { return false }
7678
useJUnitPlatform()
79+
maxParallelForks(5) // it's forks - separate JVMs, should not interfere each other
80+
doFirst {
81+
def weaver = configurations.testRuntimeClasspath.find { it.name.contains("aspectjweaver") }
82+
jvmArgs += "-javaagent:$weaver"
83+
}
84+
testLogging {
85+
events "failed"
86+
exceptionFormat "full"
87+
}
7788
}
7889

7990
wrapper {

src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ public abstract class AbstractReporter implements Formatter, Reporter {
5151
protected static final String COLON_INFIX = ": ";
5252
private static final String SKIPPED_ISSUE_KEY = "skippedIssue";
5353

54-
protected String stepPrefix;
55-
56-
protected Queue<String> outlineIterations;
57-
private Boolean inBackground;
58-
5954
protected final ThreadLocal<String> currentFeatureUri = new ThreadLocal<>();
6055
protected final ThreadLocal<RunningContext.FeatureContext> currentFeatureContext = new ThreadLocal<>();
6156
protected final ThreadLocal<RunningContext.ScenarioContext> currentScenarioContext = new ThreadLocal<>();
@@ -98,12 +93,6 @@ public Launch get() {
9893
}
9994
});
10095

101-
protected AbstractReporter() {
102-
outlineIterations = new ArrayDeque<>();
103-
stepPrefix = "";
104-
inBackground = false;
105-
}
106-
10796
/**
10897
* Extension point to customize ReportPortal instance
10998
*
@@ -152,6 +141,15 @@ protected void afterFeature() {
152141
}
153142
}
154143

144+
protected RunningContext.ScenarioContext getCurrentScenarioContext() {
145+
RunningContext.ScenarioContext context = currentScenarioContext.get();
146+
if (context == null) {
147+
context = new RunningContext.ScenarioContext();
148+
currentScenarioContext.set(context);
149+
}
150+
return context;
151+
}
152+
155153
/**
156154
* Start Cucumber Feature (if not started) and Scenario
157155
*
@@ -179,27 +177,30 @@ protected void beforeScenario(Scenario scenario, String outlineIteration) {
179177
Maybe<String> id = Utils.startNonLeafNode(
180178
launch.get(),
181179
currentFeature.getId(),
182-
Utils.buildStatementName(scenario, null, AbstractReporter.COLON_INFIX, outlineIteration),
180+
Utils.buildStatementName(scenario, null, outlineIteration),
183181
currentFeatureUri.get(),
184182
codeRef,
185183
scenario.getTags(),
186184
getScenarioTestItemType()
187185
);
188-
currentScenarioContext.set(new RunningContext.ScenarioContext(id));
186+
RunningContext.ScenarioContext context = getCurrentScenarioContext();
187+
context.setId(id);
189188
}
190189

191190
/**
192191
* Finish Cucumber scenario
193192
*/
194193
protected void afterScenario() {
195-
RunningContext.ScenarioContext context = currentScenarioContext.get();
194+
RunningContext.ScenarioContext context = getCurrentScenarioContext();
196195
Utils.finishTestItem(launch.get(), context.getId(), context.getStatus());
196+
currentScenarioContext.set(null);
197197
}
198198

199199
/**
200200
* Start Cucumber step
201201
*
202-
* @param step Step object
202+
* @param step Step object
203+
* @param match Match object
203204
*/
204205
protected abstract void beforeStep(Step step, Match match);
205206

@@ -250,10 +251,8 @@ protected void reportResult(Result result, String message) {
250251
if (message != null) {
251252
Utils.sendLog(message, level, null);
252253
}
253-
RunningContext.ScenarioContext currentScenario = currentScenarioContext.get();
254-
if (currentScenario != null) {
255-
currentScenario.updateStatus(Utils.mapStatus(result.getStatus()));
256-
}
254+
RunningContext.ScenarioContext currentScenario = getCurrentScenarioContext();
255+
currentScenario.updateStatus(Utils.mapStatus(result.getStatus()));
257256
}
258257

259258
/**
@@ -281,7 +280,8 @@ public void before(Match match, Result result) {
281280
@Override
282281
public void result(Result result) {
283282
afterStep(result);
284-
if (!inBackground && currentScenarioContext.get().noMoreSteps()) {
283+
RunningContext.ScenarioContext context = getCurrentScenarioContext();
284+
if (!context.isInBackground() && context.noMoreSteps()) {
285285
beforeHooks(false);
286286
}
287287
}
@@ -293,7 +293,7 @@ public void after(Match match, Result result) {
293293

294294
@Override
295295
public void match(Match match) {
296-
beforeStep(currentScenarioContext.get().getNextStep(), match);
296+
beforeStep(getCurrentScenarioContext().getNextStep(), match);
297297
}
298298

299299
@Override
@@ -334,40 +334,46 @@ public void scenarioOutline(ScenarioOutline scenarioOutline) {
334334
@Override
335335
public void examples(Examples examples) {
336336
// examples always have headers; therefore up to num - 1
337-
IntStream.range(1, examples.getRows().size()).forEach(it -> outlineIterations.add(String.format("[%d]", it)));
337+
RunningContext.ScenarioContext context = getCurrentScenarioContext();
338+
Queue<String> iterations = context.getOutlineIterations();
339+
IntStream.range(1, examples.getRows().size()).forEach(it -> iterations.add(String.format("[%d]", it)));
338340
}
339341

340342
@Override
341343
public void startOfScenarioLifeCycle(Scenario scenario) {
342-
inBackground = false;
343-
beforeScenario(scenario, outlineIterations.poll());
344+
RunningContext.ScenarioContext context = getCurrentScenarioContext();
345+
String iteration = context.getOutlineIterations().poll();
346+
context.setInBackground(false);
347+
beforeScenario(scenario, iteration);
344348
beforeHooks(true);
345349
}
346350

347351
@Override
348352
public void background(Background background) {
349353
afterHooks(true);
350-
inBackground = true;
351-
stepPrefix = background.getKeyword().toUpperCase() + AbstractReporter.COLON_INFIX;
354+
RunningContext.ScenarioContext context = getCurrentScenarioContext();
355+
context.setInBackground(true);
356+
context.setStepPrefix(background.getKeyword().toUpperCase() + AbstractReporter.COLON_INFIX);
352357
}
353358

354359
@Override
355360
public void scenario(Scenario scenario) {
356-
if (!inBackground) { // if there was no background
361+
RunningContext.ScenarioContext context = getCurrentScenarioContext();
362+
if (!context.isInBackground()) { // if there was no background
357363
afterHooks(true);
358364
} else {
359-
inBackground = false;
365+
context.setInBackground(false);
360366
}
361-
stepPrefix = "";
367+
context.setStepPrefix("");
362368
}
363369

364370
@Override
365371
public void step(Step step) {
366-
RunningContext.ScenarioContext currentScenario = currentScenarioContext.get();
367-
if (currentScenario != null) {
368-
currentScenario.addStep(step);
372+
RunningContext.ScenarioContext context = currentScenarioContext.get();
373+
if (context != null) {
374+
// Skip scenario outlines steps without initialized parameters
375+
context.addStep(step);
369376
}
370-
// otherwise it's a step collection in an outline, useless.
371377
}
372378

373379
@Override

src/main/java/com/epam/reportportal/cucumber/RunningContext.java

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import gherkin.formatter.model.Step;
66
import io.reactivex.Maybe;
77

8+
import javax.annotation.Nonnull;
89
import java.util.ArrayDeque;
910
import java.util.Queue;
1011

@@ -33,20 +34,55 @@ public StartTestItemRQ getItemRq() {
3334

3435
public static class ScenarioContext {
3536

37+
private boolean inBackground;
38+
private String stepPrefix;
3639
private Maybe<String> currentStepId;
3740
private Maybe<String> hookStepId;
3841
private ItemStatus hookStatus;
3942

40-
private final Maybe<String> id;
4143
private final Queue<Step> steps;
44+
private final Queue<String> outlineIterations;
45+
46+
private Maybe<String> id;
4247
private ItemStatus status;
4348

44-
public ScenarioContext(Maybe<String> newId) {
45-
id = newId;
49+
public ScenarioContext() {
50+
stepPrefix = "";
4651
steps = new ArrayDeque<>();
52+
outlineIterations = new ArrayDeque<>();
4753
status = ItemStatus.PASSED;
4854
}
4955

56+
public ScenarioContext(Maybe<String> newId) {
57+
this();
58+
id = newId;
59+
}
60+
61+
@Nonnull
62+
public Queue<String> getOutlineIterations() {
63+
return outlineIterations;
64+
}
65+
66+
public void setId(Maybe<String> id) {
67+
this.id = id;
68+
}
69+
70+
public boolean isInBackground() {
71+
return inBackground;
72+
}
73+
74+
public void setInBackground(boolean inBackground) {
75+
this.inBackground = inBackground;
76+
}
77+
78+
public String getStepPrefix() {
79+
return stepPrefix;
80+
}
81+
82+
public void setStepPrefix(String prefix) {
83+
stepPrefix = prefix;
84+
}
85+
5086
public Maybe<String> getCurrentStepId() {
5187
return currentStepId;
5288
}

0 commit comments

Comments
 (0)