Skip to content

Commit 501e705

Browse files
committed
[break] implemented configure abortedStepsShouldPass #755
1 parent 1ca3232 commit 501e705

File tree

6 files changed

+41
-18
lines changed

6 files changed

+41
-18
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1998,6 +1998,7 @@ You can adjust configuration settings for the HTTP client used by Karate using t
19981998
`retry` | JSON | defaults to `{ count: 3, interval: 3000 }` - see [`retry until`](#retry-until)
19991999
`outlineVariablesAuto` | boolean | defaults to `true`, whether each key-value pair in the `Scenario Outline` example-row is automatically injected into the context as a variable (and not just `__row`), see [`Scenario Outline` Enhancements](#scenario-outline-enhancements)
20002000
`lowerCaseResponseHeaders` | boolean | Converts every key and value in the [`responseHeaders`](#responseheaders) to lower-case which makes it easier to validate for e.g. using [`match header`](#match-header) (default `false`) [(example)](karate-demo/src/test/java/demo/headers/content-type.feature).
2001+
`abortedStepsShouldPass` | boolean | defaults to `false`, whether steps after a [`karate.abort()`](#karate-abort) should be marked as `PASSED` instead of `SKIPPED` - this can impact the behavior of 3rd-party reports, see [this issue](https://github.com/intuit/karate/issues/755) for details
20012002
`logModifier` | Java Object | See [Log Masking](#log-masking)
20022003
`httpClientClass` | string | See [`karate-mock-servlet`](karate-mock-servlet)
20032004
`httpClientInstance` | Java Object | See [`karate-mock-servlet`](karate-mock-servlet)
@@ -3150,7 +3151,7 @@ A JavaScript function or [Karate expression](#karate-expressions) at runtime has
31503151

31513152
Operation | Description
31523153
--------- | -----------
3153-
<a name="karate-abort"><code>karate.abort()</code></a> | you can prematurely exit a `Scenario` by combining this with [conditional logic](#conditional-logic) like so: `* if (condition) karate.abort()` - please use [sparingly](https://martinfowler.com/articles/nonDeterminism.html) !
3154+
<a name="karate-abort"><code>karate.abort()</code></a> | you can prematurely exit a `Scenario` by combining this with [conditional logic](#conditional-logic) like so: `* if (condition) karate.abort()` - please use [sparingly](https://martinfowler.com/articles/nonDeterminism.html) ! and also see [`configure abortedStepsShouldPass`](#configure)
31543155
<a name="karate-append"><code>karate.append(... items)</code></a> | useful to create lists out of items (which can be lists as well), see [JSON transforms](#json-transforms)
31553156
<a name="karate-appendto"><code>karate.appendTo(name, ... items)</code></a> | useful to append to a list-like variable (that has to exist) in scope, see [JSON transforms](#json-transforms)
31563157
<a name="karate-call"><code>karate.call(fileName, [arg])</code></a> | invoke a [`*.feature` file](#calling-other-feature-files) or a [JavaScript function](#calling-javascript-functions) the same way that [`call`](#call) works (with an optional solitary argument)

karate-core/src/main/java/com/intuit/karate/Config.java

+22-13
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
public class Config {
3939

4040
public static final int DEFAULT_RETRY_INTERVAL = 3000;
41-
public static final int DEFAULT_RETRY_COUNT = 3;
41+
public static final int DEFAULT_RETRY_COUNT = 3;
4242

4343
private boolean sslEnabled = false;
4444
private String sslAlgorithm = "TLS";
@@ -67,6 +67,7 @@ public class Config {
6767
private boolean logPrettyResponse;
6868
private boolean printEnabled = true;
6969
private boolean outlineVariablesAuto = true;
70+
private boolean abortedStepsShouldPass = false;
7071
private String clientClass;
7172
private HttpClient clientInstance;
7273
private Map<String, Object> userDefined;
@@ -87,7 +88,7 @@ public class Config {
8788
public Config() {
8889
// zero arg constructor
8990
}
90-
91+
9192
private static <T> T get(Map<String, Object> map, String key, T defaultValue) {
9293
Object o = map.get(key);
9394
return o == null ? defaultValue : (T) o;
@@ -158,18 +159,21 @@ public boolean configure(String key, ScriptValue value) { // TODO use enum
158159
if (value.isMapLike()) {
159160
Map<String, Object> map = value.getAsMap();
160161
retryInterval = get(map, "interval", retryInterval);
161-
retryCount = get(map, "count", retryCount);
162+
retryCount = get(map, "count", retryCount);
162163
}
163164
return false;
164165
case "outlineVariablesAuto":
165166
outlineVariablesAuto = value.isBooleanTrue();
166167
return false;
168+
case "abortedStepsShouldPass":
169+
abortedStepsShouldPass = value.isBooleanTrue();
170+
return false;
167171
// here on the http client has to be re-constructed ================
168172
case "httpClientClass":
169173
clientClass = value.getAsString();
170174
return true;
171175
case "logModifier":
172-
logModifier = value.getValue(HttpLogModifier.class);
176+
logModifier = value.getValue(HttpLogModifier.class);
173177
return true;
174178
case "httpClientInstance":
175179
clientInstance = value.getValue(HttpClient.class);
@@ -271,16 +275,17 @@ public Config(Config parent) {
271275
retryInterval = parent.retryInterval;
272276
retryCount = parent.retryCount;
273277
outlineVariablesAuto = parent.outlineVariablesAuto;
278+
abortedStepsShouldPass = parent.abortedStepsShouldPass;
274279
logModifier = parent.logModifier;
275280
}
276-
281+
277282
public void setCookies(ScriptValue cookies) {
278283
this.cookies = cookies;
279-
}
280-
284+
}
285+
281286
public void setClientClass(String clientClass) {
282287
this.clientClass = clientClass;
283-
}
288+
}
284289

285290
//==========================================================================
286291
//
@@ -354,8 +359,8 @@ public List<String> getNonProxyHosts() {
354359

355360
public String getLocalAddress() {
356361
return localAddress;
357-
}
358-
362+
}
363+
359364
public ScriptValue getHeaders() {
360365
return headers;
361366
}
@@ -458,18 +463,22 @@ public void setRetryCount(int retryCount) {
458463

459464
public boolean isOutlineVariablesAuto() {
460465
return outlineVariablesAuto;
461-
}
466+
}
467+
468+
public boolean isAbortedStepsShouldPass() {
469+
return abortedStepsShouldPass;
470+
}
462471

463472
public Target getDriverTarget() {
464473
return driverTarget;
465474
}
466475

467476
public void setDriverTarget(Target driverTarget) {
468477
this.driverTarget = driverTarget;
469-
}
478+
}
470479

471480
public HttpLogModifier getLogModifier() {
472481
return logModifier;
473-
}
482+
}
474483

475484
}

karate-core/src/main/java/com/intuit/karate/core/ScenarioExecutionUnit.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,13 @@ public StepResult execute(Step step) {
206206
}
207207
boolean hidden = step.isPrefixStar() && !step.isPrint() && !actions.context.getConfig().isShowAllSteps();
208208
if (stopped) {
209-
StepResult sr = new StepResult(step, aborted ? Result.passed(0) : Result.skipped(), null, null, null);
209+
Result result;
210+
if (aborted && actions.context.getConfig().isAbortedStepsShouldPass()) {
211+
result = Result.passed(0);
212+
} else {
213+
result = Result.skipped();
214+
}
215+
StepResult sr = new StepResult(step, result, null, null, null);
210216
sr.setHidden(hidden);
211217
return afterStep(sr);
212218
} else {

karate-core/src/test/java/com/intuit/karate/core/FeatureResultTest.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,16 @@ public void testFailureMultiScenarioFeature() throws Exception {
8282
public void testAbortMultiScenarioFeature() throws Exception {
8383
FeatureResult result = result("aborted.feature");
8484
assertEquals(0, result.getFailedCount());
85-
assertEquals(3, result.getScenarioCount());
85+
assertEquals(4, result.getScenarioCount());
8686
String contents = xml(result);
8787

8888
// skip-pass and skip-fail both should have all steps as skipped
8989
// TODO: generate the expected content string, below code puts a hard dependency
9090
// with KarateJunitFormatter$TestCase.addStepAndResultListing()
9191
assertTrue(contents.contains("* karate.abort() .......................................................... passed"));
92-
assertTrue(contents.contains("* assert a == 1 ........................................................... passed"));
93-
assertTrue(contents.contains("* assert a == 2 ........................................................... passed"));
92+
assertTrue(contents.contains("* assert a == 1 ........................................................... skipped"));
93+
assertTrue(contents.contains("* assert a == 2 ........................................................... skipped"));
94+
assertTrue(contents.contains("* assert a == 5 ........................................................... passed"));
9495

9596
// noskip should have both steps as passed
9697
assertTrue(contents.contains("Then assert a != 3 ........................................................ passed"));

karate-core/src/test/java/com/intuit/karate/core/aborted.feature

+5
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ Scenario: skip-fail
1414
Scenario: noskip
1515
Then assert a != 3
1616
And assert a != 4
17+
18+
Scenario: skip-pass-config
19+
* configure abortedStepsShouldPass = true
20+
* karate.abort()
21+
* assert a == 5

karate-demo/src/test/java/demo/abort/abort.feature

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Feature: abort should skip (but not fail) a test
33
Scenario: you can conditionally exit a test
44
but please use sparingly
55

6+
* configure abortedStepsShouldPass = true
67
* print 'before'
78
* if (true) karate.abort()
89
* print 'after'

0 commit comments

Comments
 (0)