Is there some way to get these cucumber report values inside code in some variables?
For example:
int scenariosRun = cucumber.getScenarios(); // 8
int scenariosPassed = cucumber.getScenariosPassed(); // 8
Yes, you can get current scenario details in the after/before hook as given below,
#Before
public void before(Scenario scenario) {
System.out.println("------------------------------");
System.out.println("Starting - " + scenario.getName());
System.out.println("------------------------------");
}
#After
public void before(Scenario scenario) {
System.out.println("------------------------------");
System.out.println(scenario.getName() + " Status - " + scenario.getStatus());
System.out.println("------------------------------");
}
Related
I'm new to reactive programming. I was playing around with fallback methods in case of an error scenario. For this, I referred to this doc https://projectreactor.io/docs/core/release/reference/index.html#_fallback_method and created a sample code.
public static void main(String[] args) {
Flux.just("key1", "key2")
.flatMap(k -> callExternalService(k)
.doOnError(e -> System.out.println("Error scenario"))
.onErrorResume(e -> getFromCache(k)))
.subscribe(value -> System.out.println("value = " + value),
error -> System.out.println("error = " + error));
}
private static Mono<String> callExternalService(String input) {
if(input.equals("key2")) throw new RuntimeException("Mocking the exception");
return Mono.just(input + " - " + LocalDateTime.now());
}
private static Mono<String> getFromCache(String input) {
return Mono.just(input + " ^^ " + LocalDateTime.now());
}
Based on whatever I referred so far, doOnError should print the message in case of the ERROR scenario and onErrorResume should fall back to the other method. But I didn't see the expected outcome->
value = key1 - 2022-05-18T15:58:36.364949
error = java.lang.RuntimeException: Mocking the exception
Please correct me if I'm missing anything.
I have a Selenium test suite that is running Selenium integration tests against a number of web applications, some that are written in Angular 2+, and some that are written in AngularJS.
We use a custom ExpectedCondition with WebDriverWait that we use to make test cases wait until AngularJS apps have finished loading, in order to avoid waiting an arbitrary amount of time:
private static ExpectedCondition<Boolean> angularIsFinished() {
return new ExpectedCondition<Boolean>() {
public Boolean apply(final WebDriver driver) {
Object result = null;
while(result == null || result.toString().equals("undefined")) {
result = ((JavascriptExecutor)driver).executeScript("return typeof angular;");
try {
Thread.sleep(200L);
} catch (final InterruptedException ex) {
logger.error("Error while trying to sleep", ex);
}
}
final String script = " var el = document.querySelector(\"body\");\n" +
" var callback = arguments[arguments.length - 1];\n" +
" angular.element(el).injector().get('$browser').notifyWhenNoOutstandingRequests(callback);";
((JavascriptExecutor)driver).executeAsyncScript(script);
return true;
}
public String toString() {
return "Wait for AngularJS";
}
};
}
However, return typeof angular; will always return undefined for an Angular 2+ app. Is there a similar way to AngularJS's notifyWhenNoOutstandingRequests that you can use to determine when an Angular 2+ app has finished loading?
This question mentions using NgZone as a possible solution, but how would you get a handle on that via a script executed via JavascriptExecutor?
You can check it by calling e.g. document.querySelector('app-root')? or arbitrary component selector...
Or what about calling document.readyState? It should have result 'complete' after fully loaded wep page and it doesn't matter if web page is based on angular.
Thanks to #Ardesco's answer, I was able to do something similar to what Protractor does, using the window.getAllAngularTestabilities function. Here is the script that I run to determine if the Angular 2+ page loads:
var testability = window.getAllAngularTestabilities()[0];
var callback = arguments[arguments.length - 1];
testability.whenStable(callback);
And here is what the complete ExpectedCondition looks like that works for both AngularJS and Angular 2+:
private static ExpectedCondition<Boolean> angularIsFinished() {
return new ExpectedCondition<Boolean>() {
public Boolean apply(final WebDriver driver) {
Object result = null;
boolean isAngular2Plus = false;
while(result == null || result.toString().equals("undefined")) {
result = ((JavascriptExecutor)driver).executeScript("return typeof angular;");
if (result == null || result.toString().equals("undefined")) {
result = ((JavascriptExecutor)driver).executeScript("return typeof window.getAngularTestability;");
if (result != null && !result.toString().equals("undefined")) {
isAngular2Plus = true;
}
}
try {
Thread.sleep(200L);
} catch (final InterruptedException ex) {
logger.error("Error while trying to sleep", ex);
}
}
final String script;
if (isAngular2Plus) {
script =" var testability = window.getAllAngularTestabilities()[0];\n" +
" var callback = arguments[arguments.length - 1];\n" +
" testability.whenStable(callback);";
} else {
script =" var el = document.querySelector(\"body\");\n" +
" var callback = arguments[arguments.length - 1];\n" +
" angular.element(el).injector().get('$browser').notifyWhenNoOutstandingRequests(callback);";
}
((JavascriptExecutor) driver).executeAsyncScript(script);
return true;
}
public String toString() {
return "Wait for AngularJS";
}
};
}
Looking at the Protractor code I have come up with two possible solutions:
First of all we have an option where we find a list of testability's, then add a callback to all of them, and then wait for one of them to flag the site as testable (This does mean that your script will continue after any one testability has become testable, it will not wait for all of them to become testable).
private static ExpectedCondition angular2IsTestable() {
return (ExpectedCondition<Boolean>) driver -> {
JavascriptExecutor jsexec = ((JavascriptExecutor) driver);
Object result = jsexec.executeAsyncScript("window.seleniumCallback = arguments[arguments.length -1];\n" +
"if (window.getAllAngularTestabilities()) {\n" +
" window.getAllAngularTestabilities().forEach(function (testability) {\n" +
" testability.whenStable(window.seleniumCallback(true))\n" +
" }\n" +
" );\n" +
"} else {\n" +
" window.seleniumCallback(false)\n" +
"}"
);
return Boolean.parseBoolean(result.toString());
};
}
The second option is to specifically check an angular root elements testability state:
private static ExpectedCondition angular2ElementIsTestable(final WebElement element) {
return (ExpectedCondition<Boolean>) driver -> {
JavascriptExecutor jsexec = ((JavascriptExecutor) driver);
Object result = jsexec.executeAsyncScript(
"window.seleniumCallback = arguments[arguments.length -1];\n" +
"var element = arguments[0];\n" +
"if (window.getAngularTestability && window.getAngularTestability(element)) {\n" +
" window.getAngularTestability(element).whenStable(window.seleniumCallback(true));\n" +
"} else {\n" +
" window.seleniumCallback(false)\n" +
"}"
, element);
return Boolean.parseBoolean(result.toString());
};
}
The second option is more targeted and therefore more reliable if you want to test a specific area of the site.
A third option would be to write something a bit more complicated that tracks the state of all testability's and then only fires a true callback when all of them have become true. I don't have an implementation for this yet.
public void logTimeTaken(String label, long estimatedTime, int size, boolean isDebug)
{
String out = label + " took " +
TimeUnit.MILLISECONDS.convert(estimatedTime, TimeUnit.NANOSECONDS)
+ " milliseconds for " + size + " events!";
if (isDebug) {
logger.debug(out);
} else {
logger.info(out);
}
}
I'm unable to write mockit here any one know help me in this..
test code here..
#Mock
EventUtility event;
#Test
public void getLogTimeTaken_checkBooleanTrue() {
doNothing().when(event).logTimeTaken("Corner Stone", 1000, 100, true);
eventUtil.logTimeTaken("Corner Stone", 1000, 100, true);
verify(event).logTimeTaken("Corner Stone", 1000, 100, true);
}
I test this code but i'm getting exception ,I don't know it is correct way or not and below is the exception
Exception ::Wanted but not invoked: event.logTimeTaken( "Corner
Stone",1000,100,true);
-> at com.wf.cornerstone.datacontrols.util.EventUtilityTest.getLogTimeTaken_checkBooleanTrue(EventUtilityTest.java:244)
Actually, there were zero interactions with this mock.
at com.wf.cornerstone.datacontrols.util.EventUtilityTest.getLogTimeTaken_checkBooleanTrue(EventUtilityTest.java:244)
can you help me this ..
I need to test this code with Mockito (JUnit):
public class Calculation {
public void logTimeTaken(String label, long estimatedTime, int size, boolean isDebug) {
String out = label + " took " + TimeUnit.MILLISECONDS.convert(estimatedTime, TimeUnit.NANOSECONDS) + " milliseconds for " + size + " events!";
if (isDebug) {
System.out.println(out);
} else {
System.out.println(out);
}
}
}
I search so many examples google but still not getting any idea.
You can configure System with an instance of PrintStream which you can then assert against after invoking Calculation.logTimeTaken.
Here's an example:
#Test
public void canLogTimeTaken() {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
PrintStream out = new PrintStream(bout);
System.setOut(out);
Calculation sut = new Calculation();
sut.logTimeTaken("label", 20 , 2, false);
assertEquals("if isDebug is false label took 0 milliseconds for 2 events!\n", bout.toString());
}
Note: there is no need for Mockito here, this is just vanilla JUnit, no mocking.
But, it might be a better design to refactor logTimeTaken into two distinct aspects:
Deriving the log message
Logging that message
For example:
public String createTimeTakenMessage(String label, long estimatedTime, int size, boolean isDebug) {
return label + " took " + TimeUnit.MILLISECONDS.convert(estimatedTime, TimeUnit.NANOSECONDS) + " milliseconds for " + size + " events!";
}
public void logTimeTaken(String message) {
System.out.println(message);
}
Then testing createTimeTakenMessage is trivial and you might even choose not to test logTimeTaken at all since all it does is invoke a System method. Or, perhaps you would hide the 'log action' behind an interface with an implementation using System.out now and perhaps, later, other implementations using a formal logging framework such as Logback.
I'm trying to allow jargo to ignore any amount of "junk-be-here" strings. How can I do that? This is the code I've come up with:
#Test
public void testUsage() throws Exception
{
Argument<Integer> nrOfPotatoes = Arguments.integerArgument("-n").build();
ParsedArguments parsedArguments = CommandLineParser.withArguments(nrOfPotatoes).parse("-n", "123", "junk-be-here");
int potatoesToPlant = parsedArguments.get(nrOfPotatoes);
System.out.println("Hold on, planting " + potatoesToPlant + " potatoes");
}
But I get:
se.softhouse.jargo.ArgumentExceptions$UnexpectedArgumentException: Unexpected argument: junk-be-here, previous argument: 123
at se.softhouse.jargo.ArgumentExceptions.forUnexpectedArgument(ArgumentExceptions.java:299)
at se.softhouse.jargo.CommandLineParserInstance.getDefinitionForCurrentArgument(CommandLineParserInstance.java:329)
at se.softhouse.jargo.CommandLineParserInstance.parseArguments(CommandLineParserInstance.java:262)
at se.softhouse.jargo.CommandLineParserInstance.parse(CommandLineParserInstance.java:234)
at se.softhouse.jargo.CommandLineParserInstance.parse(CommandLineParserInstance.java:228)
at se.softhouse.jargo.CommandLineParser.parse(CommandLineParser.java:224)
at
.....
You can use an indexed argument (by specifying no names to the argument), and set variableArity (any amount of arguments is allowed).
#Test
public void testUsage() throws Exception
{
Argument<List<String>> junk = Arguments.stringArgument().variableArity().build();
Argument<Integer> nrOfPotatoes = Arguments.integerArgument("-n").build();
ParsedArguments parsedArguments = CommandLineParser.withArguments(junk, nrOfPotatoes).parse("-n", "123", "junk-be-here");
int potatoesToPlant = parsedArguments.get(nrOfPotatoes);
System.out.println("Hold on, planting " + potatoesToPlant + " potatoes");
System.out.println("Junk:" + parsedArguments.get(junk));
}
This prints:
Hold on, planting 123 potatoes
Junk:[junk-be-here]