From 619cbb5f281209bedc1861d0d998b0cf1f279ac0 Mon Sep 17 00:00:00 2001 From: l-1sqared <30831153+l-1squared@users.noreply.github.com> Date: Tue, 23 Nov 2021 07:17:57 +0100 Subject: [PATCH 1/5] format classes relevant to the issue Signed-off-by: l-1sqared <30831153+l-1squared@users.noreply.github.com> --- .../jgiven/impl/ScenarioModelBuilder.java | 51 +-- .../jgiven/report/text/PlainTextReporter.java | 44 +- .../report/text/PlainTextReporterTest.java | 393 +++++++++--------- .../jgiven/impl/ScenarioExecutorTest.java | 100 ++--- .../jgiven/report/html5/Html5AppTest.java | 269 ++++++------ .../jgiven/report/html5/ThenHtml5App.java | 103 ++--- .../jgiven/report/model/GivenReportModel.java | 267 ++++++------ .../report/model/GivenReportModels.java | 109 ++--- 8 files changed, 683 insertions(+), 653 deletions(-) diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java b/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java index a046d4d3e7..fede67184a 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java @@ -44,11 +44,8 @@ import java.util.List; import java.util.Set; import java.util.Stack; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class ScenarioModelBuilder implements ScenarioListener { - private static final Logger log = LoggerFactory.getLogger(ScenarioModelBuilder.class); private static final Set STACK_TRACE_FILTER = ImmutableSet .of("sun.reflect", "com.tngtech.jgiven.impl.intercept", "com.tngtech.jgiven.impl.intercept", @@ -98,7 +95,26 @@ public void scenarioStarted(String description) { this.tagCreator = new TagCreator(configuration); } - public void addStepMethod(Method paramMethod, List arguments, InvocationMode mode, + @Override + public void scenarioStarted(Class testClass, Method method, List namedArguments) { + readConfiguration(testClass); + readAnnotations(testClass, method); + scenarioModel.setClassName(testClass.getName()); + setParameterNames(getNames(namedArguments)); + + // must come at last + setMethodName(method.getName()); + + ParameterFormattingUtil parameterFormattingUtil = new ParameterFormattingUtil(configuration); + List> formatter = + parameterFormattingUtil.getFormatter(method.getParameterTypes(), getNames(namedArguments), + method.getParameterAnnotations()); + + setArguments(parameterFormattingUtil.toStringList(formatter, getValues(namedArguments))); + setCaseDescription(testClass, method, namedArguments); + } + + private void addStepMethod(Method paramMethod, List arguments, InvocationMode mode, boolean hasNestedSteps) { StepModel stepModel = createStepModel(paramMethod, arguments, mode); @@ -330,26 +346,7 @@ public void scenarioFailed(Throwable e) { setException(e); } - @Override - public void scenarioStarted(Class testClass, Method method, List namedArguments) { - readConfiguration(testClass); - readAnnotations(testClass, method); - scenarioModel.setClassName(testClass.getName()); - setParameterNames(getNames(namedArguments)); - - // must come at last - setMethodName(method.getName()); - - ParameterFormattingUtil parameterFormattingUtil = new ParameterFormattingUtil(configuration); - List> formatter = - parameterFormattingUtil.getFormatter(method.getParameterTypes(), getNames(namedArguments), - method.getParameterAnnotations()); - - setArguments(parameterFormattingUtil.toStringList(formatter, getValues(namedArguments))); - setCaseDescription(testClass, method, namedArguments); - } - - private void setCaseDescription(Class testClass, Method method, List namedArguments) { + private void setCaseDescription(Class testClass, Method method, List namedArguments) { CaseAs annotation = null; if (method.isAnnotationPresent(CaseAs.class)) { @@ -421,8 +418,6 @@ private void readAnnotations(Class testClass, Method method) { } } - - @Override public void scenarioFinished() { AssertionUtil.assertTrue(scenarioStartedNanos > 0, "Scenario has no start time"); @@ -473,13 +468,13 @@ public void tagAdded(Class annotationClass, String... valu } - public void addTags(Annotation... annotations) { + private void addTags(Annotation... annotations) { for (Annotation annotation : annotations) { addTags(tagCreator.toTags(annotation)); } } - public void addTags(List tags) { + private void addTags(List tags) { if (tags.isEmpty()) { return; } diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/report/text/PlainTextReporter.java b/jgiven-core/src/main/java/com/tngtech/jgiven/report/text/PlainTextReporter.java index 46a1f758e2..abc62a9bc2 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/report/text/PlainTextReporter.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/report/text/PlainTextReporter.java @@ -17,55 +17,55 @@ public class PlainTextReporter extends PlainTextWriter { private static final ConfigValue COLOR_CONFIG = Config.config().textColorEnabled(); - public static String toString( ScenarioModel scenarioModel ) throws UnsupportedEncodingException { + public static String toString(ScenarioModel scenarioModel) throws UnsupportedEncodingException { ReportModel model = new ReportModel(); - model.addScenarioModel( scenarioModel ); - return toString( model ); + model.addScenarioModel(scenarioModel); + return toString(model); } - public static String toString( ReportModel model ) throws UnsupportedEncodingException { + public static String toString(ReportModel model) throws UnsupportedEncodingException { StringWriter stringWriter = new StringWriter(); - PrintWriter printWriter = new PrintWriter( stringWriter ); - PlainTextReporter textWriter = new PlainTextReporter( printWriter, ConfigValue.FALSE ); + PrintWriter printWriter = new PrintWriter(stringWriter); + PlainTextReporter textWriter = new PlainTextReporter(printWriter, ConfigValue.FALSE); try { - textWriter.write( model ); + textWriter.write(model); return stringWriter.toString(); } finally { - ResourceUtil.close( printWriter ); + ResourceUtil.close(printWriter); } } public PlainTextReporter() { - this( COLOR_CONFIG ); + this(COLOR_CONFIG); } - public PlainTextReporter( ConfigValue colorConfig ) { - this( PrintWriterUtil.getPrintWriter( System.out, colorConfig ), colorConfig ); + public PlainTextReporter(ConfigValue colorConfig) { + this(PrintWriterUtil.getPrintWriter(System.out, colorConfig), colorConfig); } - public PlainTextReporter( PrintWriter printWriter, ConfigValue colorConfig ) { - super( printWriter, colorConfig != ConfigValue.FALSE ); + public PlainTextReporter(PrintWriter printWriter, ConfigValue colorConfig) { + super(printWriter, colorConfig != ConfigValue.FALSE); } - public PlainTextReporter write( ReportModel model ) { - model.accept( this ); + public PlainTextReporter write(ReportModel model) { + model.accept(this); return this; } @Override - public void visit( ReportModel multiScenarioModel ) { + public void visit(ReportModel multiScenarioModel) { writer.println(); - String title = bold( "Test Class: " ); + String title = bold("Test Class: "); title += multiScenarioModel.getClassName(); - writer.println( title ); + writer.println(title); } @Override - public void visit( ScenarioModel scenarioModel ) { - if( scenarioModel.isCasesAsTable() ) { - scenarioModel.accept( new DataTablePlainTextScenarioWriter( writer, withColor ) ); + public void visit(ScenarioModel scenarioModel) { + if (scenarioModel.isCasesAsTable()) { + scenarioModel.accept(new DataTablePlainTextScenarioWriter(writer, withColor)); } else { - scenarioModel.accept( new PlainTextScenarioWriter( writer, withColor ) ); + scenarioModel.accept(new PlainTextScenarioWriter(writer, withColor)); } } diff --git a/jgiven-core/src/test/java/com/tngtech/jgiven/report/text/PlainTextReporterTest.java b/jgiven-core/src/test/java/com/tngtech/jgiven/report/text/PlainTextReporterTest.java index c71eb51f24..91da1b9a11 100644 --- a/jgiven-core/src/test/java/com/tngtech/jgiven/report/text/PlainTextReporterTest.java +++ b/jgiven-core/src/test/java/com/tngtech/jgiven/report/text/PlainTextReporterTest.java @@ -30,7 +30,7 @@ * as this would require a dependency to jgiven-junit, which we have to avoid * here. */ -@RunWith( DataProviderRunner.class ) +@RunWith(DataProviderRunner.class) public class PlainTextReporterTest extends ScenarioTestBaseForTesting { @Rule @@ -39,31 +39,31 @@ public class PlainTextReporterTest extends ScenarioTestBaseForTesting { @Test public void methods_called_during_stage_construction_are_ignored_in_the_report() { given().some_stage_with_method_called_during_construction(); - then().the_method_does_not_appear_in_the_report( getScenario().getScenarioCaseModel() ); + then().the_method_does_not_appear_in_the_report(getScenario().getScenarioCaseModel()); + } + + @DataProvider + public static Object[][] primitiveArrays() { + return new Object[][] { + {"byte", new byte[] {1, 2, 3}}, + {"char", new char[] {'a', 'b', 'c'}}, + {"short", new short[] {1, 2, 3}}, + {"int", new int[] {1, 2, 3}}, + {"long", new long[] {1, 2, 3}}, + {"double", new double[] {1, 2, 3}}, + {"float", new float[] {1, 2, 3}}, + {"boolean", new boolean[] {true, false}}, + }; } - public static class TestSteps { + @Test + @UseDataProvider("primitiveArrays") + @Issue("#1") + @FeatureStepParameters + public void step_methods_can_have_primitive_arrays_as_parameters(String type, Object array) { + given().a_step_method_with_a_primitive_$_array_$_as_parameter(type, array); + when().the_scenario_is_executed(); + then().no_exception_is_thrown(); + } + + @SuppressWarnings("UnusedReturnValue") + static class TestSteps extends Stage { String test = buildString(); public String buildString() { return "testString"; } - public void the_method_does_not_appear_in_the_report( @Hidden ScenarioCaseModel scenarioCaseModel ) { + TestSteps the_method_does_not_appear_in_the_report(@Hidden ScenarioCaseModel scenarioCaseModel) { StepModel stepModel = scenarioCaseModel.getFirstStep(); - assertThat( stepModel.getWords().get( 1 ).getValue() ) - .isNotEqualTo( "buildString" ) - .isEqualTo( "some stage with method called during construction" ); + assertThat(stepModel.getWords().get(1).getValue()) + .isNotEqualTo("buildString") + .isEqualTo("some stage with method called during construction"); + return this; } - public void some_stage_with_method_called_during_construction() {} - - public void a_step_method_with_a_primitive_$_array_$_as_parameter( String type, Object array ) {} - - public void the_scenario_is_executed() {} - - public void no_exception_is_thrown() { - assertThat( true ).as( "no exception is thrown" ).isTrue(); + TestSteps some_stage_with_method_called_during_construction() { + return this; } - public void a_step_failed() { - assertThat( false ).isTrue(); + TestSteps a_step_method_with_a_primitive_$_array_$_as_parameter(String type, Object array) { + return this; } - public void a_NotImplementedYet_annotated_step() {} - - public void the_next_step_is_skipped() {} - - } + TestSteps the_scenario_is_executed() { + return this; + } - @DataProvider - public static Object[][] primitiveArrays() { - return new Object[][] { - { "byte", new byte[] { 1, 2, 3 } }, - { "char", new char[] { 'a', 'b', 'c' } }, - { "short", new short[] { 1, 2, 3 } }, - { "int", new int[] { 1, 2, 3 } }, - { "long", new long[] { 1, 2, 3 } }, - { "double", new double[] { 1, 2, 3 } }, - { "float", new float[] { 1, 2, 3 } }, - { "boolean", new boolean[] { true, false } }, - }; - } + TestSteps no_exception_is_thrown() { + assertThat(true).as("no exception is thrown").isTrue(); + return this; + } - @Test - @UseDataProvider( "primitiveArrays" ) - @Issue( "#1" ) - @FeatureStepParameters - public void step_methods_can_have_primitive_arrays_as_parameters( String type, Object array ) { - given().a_step_method_with_a_primitive_$_array_$_as_parameter( type, array ); - when().the_scenario_is_executed(); - then().no_exception_is_thrown(); + @SuppressWarnings("ConstantConditions") + TestSteps a_step_failed() { + assertThat(false).isTrue(); + return this; + } } } diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/Html5AppTest.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/Html5AppTest.java index 6409460b4b..3b716e538b 100644 --- a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/Html5AppTest.java +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/Html5AppTest.java @@ -1,22 +1,5 @@ package com.tngtech.jgiven.report.html5; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import io.github.bonigarcia.wdm.WebDriverManager; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.openqa.selenium.Dimension; -import org.openqa.selenium.OutputType; -import org.openqa.selenium.TakesScreenshot; -import org.openqa.selenium.WebDriver; - import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; @@ -35,14 +18,29 @@ import com.tngtech.jgiven.tags.FeatureTags; import com.tngtech.jgiven.tags.FeatureTagsWithCustomStyle; import com.tngtech.jgiven.tags.Issue; +import io.github.bonigarcia.wdm.WebDriverManager; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.TakesScreenshot; +import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; @BrowserTest @FeatureHtml5Report -@As( "HTML App" ) -@Description( "Tests against the generated HTML5 App using WebDriver" ) -@RunWith( DataProviderRunner.class ) +@As("HTML App") +@Description("Tests against the generated HTML5 App using WebDriver") +@RunWith(DataProviderRunner.class) public class Html5AppTest extends JGivenScenarioTest, WhenHtml5App, ThenHtml5App> { @ScenarioStage @@ -65,7 +63,7 @@ public static void setupWebDriver() { webDriver = new ChromeDriver(options); - webDriver.manage().window().setSize( new Dimension( 1280, 768 ) ); + webDriver.manage().window().setSize(new Dimension(1280, 768)); } @AfterClass @@ -83,14 +81,14 @@ public void the_welcome_page_of_the_HTML5_report_can_be_opened() throws Exceptio when().the_index_page_is_opened(); - then().the_page_title_is( "Welcome" ); + then().the_page_title_is("Welcome"); } @Test public void the_statistics_on_the_welcome_page_of_the_HTML5_report_is_correct() throws Exception { given().a_report_model() - .and().the_report_has_$_scenarios( 3 ) - .and().step_$_of_case_$_has_status( 1, 1, StepStatus.FAILED ); + .and().the_report_has_$_scenarios(3) + .and().step_$_of_case_$_has_status(1, 1, StepStatus.FAILED); jsonReports .and().the_report_exist_as_JSON_file(); @@ -99,22 +97,22 @@ public void the_statistics_on_the_welcome_page_of_the_HTML5_report_is_correct() when().the_index_page_is_opened(); - then().the_page_statistics_line_contains_text( "3 Total" ) - .and().the_page_statistics_line_contains_text( "2 Successful" ) - .and().the_page_statistics_line_contains_text( "1 Failed" ) - .and().the_page_statistics_line_contains_text( "0 Pending" ); + then().the_page_statistics_line_contains_text("3 Total") + .and().the_page_statistics_line_contains_text("2 Successful") + .and().the_page_statistics_line_contains_text("1 Failed") + .and().the_page_statistics_line_contains_text("0 Pending"); } @Test @FeatureTags - @Issue( "#47" ) - @DataProvider( { + @Issue("#47") + @DataProvider({ "true, testtag-#42", - "false, #42" } ) - public void clicking_on_tag_labels_opens_the_tag_page( boolean prependType, String tagName ) throws Exception { + "false, #42"}) + public void clicking_on_tag_labels_opens_the_tag_page(boolean prependType, String tagName) throws Exception { given().a_report_model() - .and().scenario_$_has_tag_$_with_value_$( 1, "testtag", "#42" ) - .and().the_tag_has_prependType_set_to( prependType ); + .and().scenario_$_has_tag_$_with_value_$(1, "testtag", "#42") + .and().the_tag_has_prependType_set_to(prependType); jsonReports .and().the_report_exist_as_JSON_file(); @@ -122,9 +120,9 @@ public void clicking_on_tag_labels_opens_the_tag_page( boolean prependType, Stri .and().the_HTML_Report_Generator_is_executed(); when().the_All_Scenarios_page_is_opened() - .and().the_tag_with_name_$_is_clicked( tagName ); + .and().the_tag_with_name_$_is_clicked(tagName); - then().the_page_title_is( tagName ); + then().the_page_title_is(tagName); } @Test @@ -132,8 +130,8 @@ public void clicking_on_tag_labels_opens_the_tag_page( boolean prependType, Stri public void tags_with_custom_styles_are_shown_correctly() throws Exception { String style = "background-color: black;"; given().a_report_model() - .and().the_first_scenario_has_tag( "TagWithCustomStyle" ) - .and().the_tag_has_style( style ); + .and().the_first_scenario_has_tag("TagWithCustomStyle") + .and().the_tag_has_style(style); jsonReports .and().the_report_exist_as_JSON_file(); whenReport @@ -141,28 +139,28 @@ public void tags_with_custom_styles_are_shown_correctly() throws Exception { when().the_All_Scenarios_page_is_opened(); - then().the_page_contains_tag( "TagWithCustomStyle" ) - .and().the_tag_has_style( style ); + then().the_page_contains_tag("TagWithCustomStyle") + .and().the_tag_has_style(style); } @Test - @Issue( "#191" ) + @Issue("#191") @FeatureAttachments public void attachments_of_all_cases_appear_in_the_HTML5_report_when_having_a_data_table() throws Exception { given().a_report_model() .and().the_scenario_has_one_parameter() - .and().the_scenario_has_$_default_cases( 2 ) - .and().step_$_of_case_$_has_a_text_attachment( 1, 1 ) - .and().step_$_of_case_$_has_a_text_attachment( 1, 2 ); + .and().the_scenario_has_$_default_cases(2) + .and().step_$_of_case_$_has_a_text_attachment(1, 1) + .and().step_$_of_case_$_has_a_text_attachment(1, 2); jsonReports .and().the_report_exist_as_JSON_file(); whenReport .and().the_HTML_Report_Generator_is_executed(); - when().the_page_of_scenario_$_is_opened( 1 ); + when().the_page_of_scenario_$_is_opened(1); - then().$_attachment_icons_exist( 2 ); + then().$_attachment_icons_exist(2); } @Test @@ -170,16 +168,16 @@ public void attachments_of_all_cases_appear_in_the_HTML5_report_when_having_a_da public void attachments_appear_in_the_HTML5_report() throws Exception { String content = "Some Example Attachment\nwith some example content"; given().a_report_model() - .and().step_$_of_scenario_$_has_a_text_attachment_with_content( 1, 1, content ); + .and().step_$_of_scenario_$_has_a_text_attachment_with_content(1, 1, content); jsonReports .and().the_report_exist_as_JSON_file(); whenReport .and().the_HTML_Report_Generator_is_executed(); - when().the_page_of_scenario_$_is_opened( 1 ); + when().the_page_of_scenario_$_is_opened(1); then().an_attachment_icon_exists() - .and().the_content_of_the_attachment_referenced_by_the_icon_is( content ); + .and().the_content_of_the_attachment_referenced_by_the_icon_is(content); } @Test @@ -188,19 +186,19 @@ public void steps_can_have_multiple_attachments() throws Exception { String content1 = "Some Example Attachment\nwith some example content"; String content2 = "Another Example Attachment\nwith some example content"; given().a_report_model() - .and().step_$_of_scenario_$_has_a_text_attachment_with_content( 1, 1, content1 ) - .and().step_$_of_scenario_$_has_another_text_attachment_with_content( 1, 1, content2 ); + .and().step_$_of_scenario_$_has_a_text_attachment_with_content(1, 1, content1) + .and().step_$_of_scenario_$_has_another_text_attachment_with_content(1, 1, content2); jsonReports .and().the_report_exist_as_JSON_file(); whenReport .and().the_HTML_Report_Generator_is_executed(); - when().the_page_of_scenario_$_is_opened( 1 ); + when().the_page_of_scenario_$_is_opened(1); - then().$_attachment_icons_exist( 2 ) - .and().the_content_of_the_attachment_referenced_by_icon_$_is( 1, content1 ) - .and().the_content_of_the_attachment_referenced_by_icon_$_is( 2, content2 ); + then().$_attachment_icons_exist(2) + .and().the_content_of_the_attachment_referenced_by_icon_$_is(1, content1) + .and().the_content_of_the_attachment_referenced_by_icon_$_is(2, content2); } @Test @@ -210,149 +208,154 @@ public void the_configured_title_appears_in_the_generated_HTML_report() throws E .and().the_report_exist_as_JSON_file(); whenReport - .and().the_HTML_Report_Generator_is_executed_with_title( "Test Title" ); + .and().the_HTML_Report_Generator_is_executed_with_title("Test Title"); when().the_index_page_is_opened(); - then().the_report_title_is( "Test Title" ); + then().the_report_title_is("Test Title"); } - @Issue( "#146" ) + @Issue("#146") @Test - @DataProvider( { + @DataProvider({ "JGiven Documentation, http://jgiven.org/docs", - "Back, javascript:window.history.back()" } ) - public void navigation_links_of_the_HTML_report_can_be_customized_using_a_custom_JS_file( String title, String href ) throws Exception { + "Back, javascript:window.history.back()"}) + public void navigation_links_of_the_HTML_report_can_be_customized_using_a_custom_JS_file(String title, String href) + throws Exception { given().a_report_model(); jsonReports .and().the_report_exist_as_JSON_file() .given().a_custom_JS_file_with_content( - "jgivenReport.addNavigationLink( { \n" - + " href: '" + href + "', \n" - + " text: '" + title + "', \n" - + " target: '_blank' \n" - + "});" ); + "jgivenReport.addNavigationLink( { \n" + + " href: '" + href + "', \n" + + " text: '" + title + "', \n" + + " target: '_blank' \n" + + "});"); whenReport.when().the_HTML_Report_Generator_is_executed(); when().and().the_index_page_is_opened(); - then().the_navigation_menu_has_a_link_with_text( title.toUpperCase() ) - .and().href( href ) - .and().target( "_blank" ); + then().the_navigation_menu_has_a_link_with_text(title.toUpperCase()) + .and().href(href) + .and().target("_blank"); } @Test - @Issue( "#226" ) + @Issue("#226") public void newlines_are_detected_in_formatted_values_and_shown_as_multiline_text() throws IOException { String content = "Some \n text \n with \n newlines"; given().a_report_model() - .and().step_$_of_case_$_has_a_formatted_value_$_as_parameter( 1, 1, content ); + .and().step_$_of_case_$_has_a_formatted_value_$_as_parameter(1, 1, content); jsonReports .and().the_report_exist_as_JSON_file(); whenReport.when().the_HTML_Report_Generator_is_executed(); - when().the_page_of_scenario_$_is_opened( 1 ); - then().an_element_with_a_$_class_exists( "multiline" ) - .and().has_content( content ); + when().the_page_of_scenario_$_is_opened(1); + then().an_element_with_a_$_class_exists("multiline") + .and().has_content(content); } @DataProvider public static Object[][] parserTestData() { return new Object[][] { - { "Placeholder with index", "$1", Arrays.asList( "a", "b" ), Arrays.asList( 1, 2 ), "1" }, - { "Placeholder without index", "$", Arrays.asList( "a", "b" ), Arrays.asList( 1, 2 ), "1" }, - { "Escaped placeholder", "$$", Arrays.asList( "a", "b" ), Arrays.asList( 1, 2 ), "$" }, - { "Multiple placeholders with switch order", "$2 + $1", Arrays.asList( "a", "b" ), Arrays.asList( 1, 2 ), "2 + 1" }, - { "Placeholders with additional text", "a = $1 and b = $2", Arrays.asList( "a", "b" ), Arrays.asList( 1, 2 ), - "a = 1 and b = 2" }, - { "Placeholders references by argument names in order", "int = $int and str = $str and bool = $bool", - Arrays.asList( "int", "str", "bool" ), Arrays.asList( 1, "some string", true ), - "int = 1 and str = some string and bool = true" }, - { "Placeholders references by argument names in mixed order", "str = $str and int = $int and bool = $bool", - Arrays.asList( "int", "str", "bool" ), Arrays.asList( 1, "some string", true ), - "str = some string and int = 1 and bool = true" }, - { "Placeholders references by argument names and enumeration", "str = $str and int = $1 and bool = $bool", - Arrays.asList( "int", "str", "bool" ), Arrays.asList( 1, "some string", true ), - "str = some string and int = 1 and bool = true" }, - { "Placeholders references by argument names and enumerations ", "bool = $3 and str = $2 and int = $int", - Arrays.asList( "int", "str", "bool" ), Arrays.asList( 1, "some string", true ), - "bool = true and str = some string and int = 1" }, - { "Placeholder without index mixed with names", "bool = $bool and int = $ and str = $", - Arrays.asList( "int", "str", "bool" ), Arrays.asList( 1, "some string", true ), - "bool = true and int = 1 and str = some string" }, - { "Placeholder without index mixed with names and index", "bool = $bool and str = $2 and int = $ and str = $ and bool = $3", - Arrays.asList( "int", "str", "bool" ), Arrays.asList( 1, "some string", true ), - "bool = true and str = some string and int = 1 and str = some string and bool = true" }, - { "Placeholder with unknown argument names get erased", "bool = $bool and not known = $unknown and unknown = $10", - Arrays.asList( "int", "str", "bool" ), Arrays.asList( 1, "some string", true ), - "bool = true and not known = 1 and unknown = some string" }, - { "Non-Java-Identifier char does trigger a space after a placeholder", "$]", - Collections.singletonList( "int" ), Collections.singletonList( 1 ), "1 ]" }, + {"Placeholder with index", "$1", Arrays.asList("a", "b"), Arrays.asList(1, 2), "1"}, + {"Placeholder without index", "$", Arrays.asList("a", "b"), Arrays.asList(1, 2), "1"}, + {"Escaped placeholder", "$$", Arrays.asList("a", "b"), Arrays.asList(1, 2), "$"}, + {"Multiple placeholders with switch order", "$2 + $1", Arrays.asList("a", "b"), Arrays.asList(1, 2), + "2 + 1"}, + {"Placeholders with additional text", "a = $1 and b = $2", Arrays.asList("a", "b"), Arrays.asList(1, 2), + "a = 1 and b = 2"}, + {"Placeholders references by argument names in order", "int = $int and str = $str and bool = $bool", + Arrays.asList("int", "str", "bool"), Arrays.asList(1, "some string", true), + "int = 1 and str = some string and bool = true"}, + {"Placeholders references by argument names in mixed order", "str = $str and int = $int and bool = $bool", + Arrays.asList("int", "str", "bool"), Arrays.asList(1, "some string", true), + "str = some string and int = 1 and bool = true"}, + {"Placeholders references by argument names and enumeration", "str = $str and int = $1 and bool = $bool", + Arrays.asList("int", "str", "bool"), Arrays.asList(1, "some string", true), + "str = some string and int = 1 and bool = true"}, + {"Placeholders references by argument names and enumerations ", "bool = $3 and str = $2 and int = $int", + Arrays.asList("int", "str", "bool"), Arrays.asList(1, "some string", true), + "bool = true and str = some string and int = 1"}, + {"Placeholder without index mixed with names", "bool = $bool and int = $ and str = $", + Arrays.asList("int", "str", "bool"), Arrays.asList(1, "some string", true), + "bool = true and int = 1 and str = some string"}, + {"Placeholder without index mixed with names and index", + "bool = $bool and str = $2 and int = $ and str = $ and bool = $3", + Arrays.asList("int", "str", "bool"), Arrays.asList(1, "some string", true), + "bool = true and str = some string and int = 1 and str = some string and bool = true"}, + {"Placeholder with unknown argument names get erased", + "bool = $bool and not known = $unknown and unknown = $10", + Arrays.asList("int", "str", "bool"), Arrays.asList(1, "some string", true), + "bool = true and not known = 1 and unknown = some string"}, + {"Non-Java-Identifier char does trigger a space after a placeholder", "$]", + Collections.singletonList("int"), Collections.singletonList(1), "1 ]"}, }; } @Test - @Issue( "#236" ) - @UseDataProvider( "parserTestData" ) - @CaseAs( value = "$1" ) - public void extended_description_should_handle_every_case_correctly( String description, String value, List parameterNames, - List parameterValues, - String expectedValue ) throws IOException { + @Issue("#236") + @UseDataProvider("parserTestData") + @CaseAs(value = "$1") + public void extended_description_should_handle_every_case_correctly(String description, String value, + List parameterNames, + List parameterValues, + String expectedValue) throws IOException { Map argumentMap = new LinkedHashMap<>(); - for( int i = 0; i < parameterNames.size(); ++i ) { - String argName = parameterNames.get( i ); - String argValue = String.valueOf( parameterValues.get( i ) ); - argumentMap.put( argName, argValue ); + for (int i = 0; i < parameterNames.size(); ++i) { + String argName = parameterNames.get(i); + String argValue = String.valueOf(parameterValues.get(i)); + argumentMap.put(argName, argValue); } given().a_report_model() - .and().step_$_of_scenario_$_has_extended_description_with_arguments( 1, 1, value, argumentMap ); + .and().step_$_of_scenario_$_has_extended_description_with_arguments(1, 1, value, argumentMap); jsonReports .and().the_report_exist_as_JSON_file(); whenReport.when().the_HTML_Report_Generator_is_executed(); - when().the_page_of_scenario_$_is_opened( 1 ) + when().the_page_of_scenario_$_is_opened(1) .and().show_tooltip_of_extended_description(); - then().an_element_with_a_$_class_exists( "has-tip" ) - .and().attribute_$_has_value_$( "tooltip-html-unsafe", expectedValue ); + then().an_element_with_a_$_class_exists("has-tip") + .and().attribute_$_has_value_$("tooltip-html-unsafe", expectedValue); } @Test - @Issue( "#274" ) + @Issue("#274") public void a_thumbnail_is_shown_for_image_attachments() throws IOException { - String screenshot = ( (TakesScreenshot) webDriver ).getScreenshotAs( OutputType.BASE64 ); + String screenshot = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.BASE64); given().a_report_model() - .and().step_$_of_scenario_$_has_an_image_attachment_$( 1, 1, screenshot ); + .and().step_$_of_scenario_$_has_an_image_attachment_$(1, 1, screenshot); jsonReports .and().the_report_exist_as_JSON_file(); whenReport.when().the_HTML_Report_Generator_is_executed(); - when().the_page_of_scenario_$_is_opened( 1 ); - then().an_element_with_a_$_class_exists( "jgiven-html-thumbnail" ) + when().the_page_of_scenario_$_is_opened(1); + then().an_element_with_a_$_class_exists("jgiven-html-thumbnail") .and().the_image_is_loaded(); } @Test - @Issue( "#274" ) - @DataProvider( { + @Issue("#274") + @DataProvider({ "true", - "false" } ) - public void showing_thumbnails_can_be_configured( boolean thumbOption ) throws IOException { - String screenshot = ( (TakesScreenshot) webDriver ).getScreenshotAs( OutputType.BASE64 ); + "false"}) + public void showing_thumbnails_can_be_configured(boolean thumbOption) throws IOException { + String screenshot = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.BASE64); given().a_report_model() - .and().step_$_of_scenario_$_has_an_image_attachment_$( 1, 1, screenshot ); + .and().step_$_of_scenario_$_has_an_image_attachment_$(1, 1, screenshot); jsonReports .and().the_report_exist_as_JSON_file(); - whenReport.when().showing_thumbnails_is_set_to( thumbOption ) + whenReport.when().showing_thumbnails_is_set_to(thumbOption) .and().the_HTML_Report_Generator_is_executed(); - when().the_page_of_scenario_$_is_opened( 1 ); - if( thumbOption ) { - then().an_element_with_a_$_class_exists( "jgiven-html-thumbnail" ) + when().the_page_of_scenario_$_is_opened(1); + if (thumbOption) { + then().an_element_with_a_$_class_exists("jgiven-html-thumbnail") .and().the_image_is_loaded(); } else { - then().$_attachment_icons_exist( 1 ); + then().$_attachment_icons_exist(1); } } } diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/ThenHtml5App.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/ThenHtml5App.java index 171ee22d8d..aa3920a2b3 100644 --- a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/ThenHtml5App.java +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/ThenHtml5App.java @@ -1,19 +1,18 @@ package com.tngtech.jgiven.report.html5; -import com.tngtech.jgiven.annotation.BeforeStage; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.PageFactory; -import org.testng.reporters.Files; +import static org.assertj.core.api.Assertions.assertThat; +import com.tngtech.jgiven.annotation.BeforeStage; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.PageFactory; +import org.testng.reporters.Files; public class ThenHtml5App> extends Html5AppStage { @@ -21,104 +20,106 @@ public class ThenHtml5App> extends Html5AppStage attachmentIcons; @BeforeStage public void setup() { - PageFactory.initElements( webDriver, this ); + PageFactory.initElements(webDriver, this); } - public SELF the_page_title_is( String title ) { - assertThat( pageTitle.getText() ).isEqualTo( title ); + public SELF the_page_title_is(String title) { + assertThat(pageTitle.getText()).isEqualTo(title); return self(); } - public SELF the_page_statistics_line_contains_text( String text ) throws IOException { - assertThat( statistics.getText() ).contains( text ); + public SELF the_page_statistics_line_contains_text(String text) { + assertThat(statistics.getText()).contains(text); return self(); } - public SELF $_attachment_icons_exist( int nrIcons ) { - assertThat( attachmentIcons ).hasSize( nrIcons ); + public SELF $_attachment_icons_exist(int nrIcons) { + assertThat(attachmentIcons).hasSize(nrIcons); return self(); } public SELF an_attachment_icon_exists() { - assertThat( attachmentIcons ).isNotEmpty(); + assertThat(attachmentIcons).isNotEmpty(); return self(); } - public SELF the_content_of_the_attachment_referenced_by_the_icon_is( String content ) throws IOException, URISyntaxException { - return the_content_of_the_attachment_referenced_by_icon_$_is( 1, content ); + public SELF the_content_of_the_attachment_referenced_by_the_icon_is(String content) + throws IOException, URISyntaxException { + return the_content_of_the_attachment_referenced_by_icon_$_is(1, content); } - public SELF the_content_of_the_attachment_referenced_by_icon_$_is( int iconNr, String content ) throws IOException, URISyntaxException { - String href = attachmentIcons.get( iconNr - 1 ).findElement( By.xpath( "../.." ) ).getAttribute( "href" ); - String foundContent = Files.readFile( new File( new URL( href ).toURI() ) ).trim(); - assertThat( content ).isEqualTo( foundContent ); + public SELF the_content_of_the_attachment_referenced_by_icon_$_is(int iconNr, String content) + throws IOException, URISyntaxException { + String href = attachmentIcons.get(iconNr - 1).findElement(By.xpath("../..")).getAttribute("href"); + String foundContent = Files.readFile(new File(new URL(href).toURI())).trim(); + assertThat(content).isEqualTo(foundContent); return self(); } - public SELF the_page_contains_tag( String tagName ) { - foundTag = findTagWithName( tagName ); - assertThat( foundTag ).isNotNull(); + public SELF the_page_contains_tag(String tagName) { + foundTag = findTagWithName(tagName); + assertThat(foundTag).isNotNull(); return self(); } - public SELF the_tag_has_style( String style ) { - WebElement span = foundTag.findElement( By.xpath( "span" ) ); - assertThat( span.getAttribute( "style" ) ).contains( style ); + public SELF the_tag_has_style(String style) { + WebElement span = foundTag.findElement(By.xpath("span")); + assertThat(span.getAttribute("style")).contains(style); return self(); } - public SELF the_report_title_is( String title ) { - assertThat( webDriver.findElement( By.id( "title" ) ).getText() ).isEqualTo( title ); + public SELF the_report_title_is(String title) { + assertThat(webDriver.findElement(By.id("title")).getText()).isEqualTo(title); return self(); } - public SELF the_navigation_menu_has_a_link_with_text( String text ) { - foundLink = webDriver.findElement( By.linkText( text ) ); - assertThat( foundLink.getText() ).isEqualTo( text ); + public SELF the_navigation_menu_has_a_link_with_text(String text) { + foundLink = webDriver.findElement(By.linkText(text)); + assertThat(foundLink.getText()).isEqualTo(text); return self(); } - public SELF href( String href ) { - assertThat( foundLink ).isNotNull(); - assertThat( foundLink.getAttribute( "href" ) ).isEqualTo( href ); + public SELF href(String href) { + assertThat(foundLink).isNotNull(); + assertThat(foundLink.getAttribute("href")).isEqualTo(href); return self(); } - public SELF target( String target ) { - assertThat( foundLink ).isNotNull(); - assertThat( foundLink.getAttribute( "target" ) ).isEqualTo( target ); + public SELF target(String target) { + assertThat(foundLink).isNotNull(); + assertThat(foundLink.getAttribute("target")).isEqualTo(target); return self(); } - public SELF an_element_with_a_$_class_exists( String multiline ) { - foundElement = webDriver.findElement( By.className( multiline ) ); - assertThat( foundElement ).isNotNull(); + public SELF an_element_with_a_$_class_exists(String multiline) { + foundElement = webDriver.findElement(By.className(multiline)); + assertThat(foundElement).isNotNull(); return self(); } - public SELF has_content( String content ) { - assertThat( foundElement.getText() ).isEqualTo( content ); + public SELF has_content(String content) { + assertThat(foundElement.getText()).isEqualTo(content); return self(); } - public SELF attribute_$_has_value_$( String attribute, String content){ - assertThat( foundElement.getAttribute( attribute ) ).isEqualTo( content ); + public SELF attribute_$_has_value_$(String attribute, String content) { + assertThat(foundElement.getAttribute(attribute)).isEqualTo(content); return self(); } - public SELF the_image_is_loaded(){ - assertThat( foundElement.getAttribute( "naturalHeight") ).isNotEqualTo( "0" ); + public SELF the_image_is_loaded() { + assertThat(foundElement.getAttribute("naturalHeight")).isNotEqualTo("0"); return self(); } } diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModel.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModel.java index 5640d41b6e..59136d6055 100644 --- a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModel.java +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModel.java @@ -27,7 +27,7 @@ public class GivenReportModel> extends Stage attachments; - @ExtendedDescription( "A report model where the analysers have not been executed on" ) + @ExtendedDescription("A report model where the analysers have not been executed on") public SELF an_unanalyzed_report_model_with_one_scenario() { analyze = false; return a_report_model_with_one_scenario(); @@ -39,55 +39,55 @@ public SELF a_report_model_with_one_scenario() { public SELF a_report_model() { reportModel = new ReportModel(); - reportModel.setClassName( "Test Class" ); + reportModel.setClassName("Test Class"); - createScenarioModel( "something should happen", "something_should_happen" ); + createScenarioModel("something should happen", "something_should_happen"); return self(); } - private void createScenarioModel( String description, String testMethodName ) { + private void createScenarioModel(String description, String testMethodName) { ScenarioModel scenarioModel = new ScenarioModel(); - scenarioModel.setClassName( reportModel.getClassName() ); - scenarioModel.setDescription( description ); - scenarioModel.setTestMethodName( testMethodName ); + scenarioModel.setClassName(reportModel.getClassName()); + scenarioModel.setDescription(description); + scenarioModel.setTestMethodName(testMethodName); - addDefaultCase( scenarioModel ); + addDefaultCase(scenarioModel); - reportModel.getScenarios().add( scenarioModel ); + reportModel.getScenarios().add(scenarioModel); } - private void addDefaultCase( ScenarioModel scenarioModel ) { + private void addDefaultCase(ScenarioModel scenarioModel) { ScenarioCaseModel scenarioCaseModel = new ScenarioCaseModel(); - scenarioModel.addCase( scenarioCaseModel ); + scenarioModel.addCase(scenarioCaseModel); int i = 0; - for( String param : scenarioModel.getExplicitParameters() ) { - scenarioCaseModel.addExplicitArguments( "arg" + scenarioCaseModel.getCaseNr() + i++ ); + for (String param : scenarioModel.getExplicitParameters()) { + scenarioCaseModel.addExplicitArguments("arg" + scenarioCaseModel.getCaseNr() + i++); } scenarioCaseModel - .addStep( new StepModel( "something_happens", Arrays.asList( Word.introWord( "given" ), new Word( "something" ) ) ) ); + .addStep(new StepModel("something_happens", Arrays.asList(Word.introWord("given"), new Word("something")))); i = 0; - for( String arg : scenarioCaseModel.getExplicitArguments() ) { + for (String arg : scenarioCaseModel.getExplicitArguments()) { String argumentName = "stepArg" + i++; - scenarioCaseModel.addStep( new StepModel( "something_happens", asList( Word.introWord( "when" ), - Word.argWord( argumentName, arg, (String) null ) ) ) ); + scenarioCaseModel.addStep(new StepModel("something_happens", asList(Word.introWord("when"), + Word.argWord(argumentName, arg, (String) null)))); } } - public SELF a_report_model_with_name( String name ) { + public SELF a_report_model_with_name(String name) { a_report_model(); - reportModel.setClassName( name ); - for( ScenarioModel model : reportModel.getScenarios() ) { - model.setClassName( name ); + reportModel.setClassName(name); + for (ScenarioModel model : reportModel.getScenarios()) { + model.setClassName(name); } return self(); } - public SELF the_report_has_$_scenarios( int n ) { + public SELF the_report_has_$_scenarios(int n) { reportModel.getScenarios().clear(); - for( int i = 0; i < n; i++ ) { - createScenarioModel( "something should happen " + i, "something_should_happen_" + i ); + for (int i = 0; i < n; i++) { + createScenarioModel("something should happen " + i, "something_should_happen_" + i); } return self(); } @@ -96,220 +96,223 @@ public ReportModel getReportModel() { return reportModel; } - public SELF parameters( String... params ) { - return the_scenario_has_parameters( params ); + public SELF parameters(String... params) { + return the_scenario_has_parameters(params); } - public SELF the_scenario_has_parameters( String... params ) { - reportModel.getLastScenarioModel().addParameterNames( params ); + public SELF the_scenario_has_parameters(String... params) { + reportModel.getLastScenarioModel().addParameterNames(params); return self(); } - public SELF the_scenario_has_a_duration_of_$_nano_seconds( long durationInNanos ) { - reportModel.getLastScenarioModel().setDurationInNanos( durationInNanos ); + public SELF the_scenario_has_a_duration_of_$_nano_seconds(long durationInNanos) { + reportModel.getLastScenarioModel().setDurationInNanos(durationInNanos); return self(); } - public SELF the_scenario_has_$_cases( int ncases ) { + public SELF the_scenario_has_$_cases(int ncases) { ScenarioModel scenarioModel = reportModel.getLastScenarioModel(); scenarioModel.clearCases(); - for( int i = 0; i < ncases; i++ ) { - scenarioModel.addCase( new ScenarioCaseModel() ); + for (int i = 0; i < ncases; i++) { + scenarioModel.addCase(new ScenarioCaseModel()); } return self(); } - public SELF the_scenario_has_$_default_cases( int ncases ) { + public SELF the_scenario_has_$_default_cases(int ncases) { reportModel.getLastScenarioModel().clearCases(); - for( int i = 0; i < ncases; i++ ) { - addDefaultCase( reportModel.getLastScenarioModel() ); + for (int i = 0; i < ncases; i++) { + addDefaultCase(reportModel.getLastScenarioModel()); } return self(); } - public SELF case_$_of_scenario_$_has_failed( int caseNr, int scenarioNr ) { - getCase( scenarioNr, caseNr ).setStatus( ExecutionStatus.FAILED ); + public SELF case_$_of_scenario_$_has_failed(int caseNr, int scenarioNr) { + getCase(scenarioNr, caseNr).setStatus(ExecutionStatus.FAILED); return self(); } - public SELF case_$_fails_with_error_message( int ncase, String errorMessage ) { - getCase( ncase ).setErrorMessage( errorMessage ); - getCase( ncase ).setStatus( ExecutionStatus.FAILED ); + public SELF case_$_fails_with_error_message(int ncase, String errorMessage) { + getCase(ncase).setErrorMessage(errorMessage); + getCase(ncase).setStatus(ExecutionStatus.FAILED); return self(); } - public SELF case_$_has_arguments( int ncase, String... args ) { - getCase( ncase ).setExplicitArguments( Arrays.asList( args ) ); + public SELF case_$_has_arguments(int ncase, String... args) { + getCase(ncase).setExplicitArguments(Arrays.asList(args)); return self(); } - public SELF case_$_has_description( int ncase, String description ) { - getCase( ncase ).setDescription( description ); + public SELF case_$_has_description(int ncase, String description) { + getCase(ncase).setDescription(description); return self(); } - public SELF all_cases_have_a_step_$_with_argument( String name, String arg ) { + public SELF all_cases_have_a_step_$_with_argument(String name, String arg) { int i = 1; - for( ScenarioCaseModel caseModel : reportModel.getLastScenarioModel().getScenarioCases() ) { - case_$_has_a_step_$_with_argument( i++, name, arg ); + for (ScenarioCaseModel caseModel : reportModel.getLastScenarioModel().getScenarioCases()) { + case_$_has_a_step_$_with_argument(i++, name, arg); } return self(); } - public SELF case_$_has_step_$( int ncase, String name ) { - getCase( ncase ).addStep( new StepModel( name, Arrays.asList( Word.introWord( "when" ), new Word( name ) ) ) ); + public SELF case_$_has_step_$(int ncase, String name) { + getCase(ncase).addStep(new StepModel(name, Arrays.asList(Word.introWord("when"), new Word(name)))); return self(); } - public SELF case_$_has_a_step_$_with_argument( int i, String name, String arg ) { - return case_$_has_a_when_step_$_with_argument( i, name, arg ); + public SELF case_$_has_a_step_$_with_argument(int i, String name, String arg) { + return case_$_has_a_when_step_$_with_argument(i, name, arg); } - private ScenarioCaseModel getCase( int scenarioNr, int caseNr ) { - return reportModel.getScenarios().get( scenarioNr - 1 ).getCase( caseNr - 1 ); + private ScenarioCaseModel getCase(int scenarioNr, int caseNr) { + return reportModel.getScenarios().get(scenarioNr - 1).getCase(caseNr - 1); } - private ScenarioCaseModel getCase( int ncase ) { - return reportModel.getLastScenarioModel().getScenarioCases().get( ncase - 1 ); + private ScenarioCaseModel getCase(int ncase) { + return reportModel.getLastScenarioModel().getScenarioCases().get(ncase - 1); } - public SELF step_$_is_named( int i, String name ) { - getCase( 1 ).getStep( i - 1 ).getWords().get( 1 ).setValue( name ); + public SELF step_$_is_named(int i, String name) { + getCase(1).getStep(i - 1).getWords().get(1).setValue(name); return self(); } - public SELF step_$_of_case_$_has_status( int stepNr, int caseNr, StepStatus status ) { - getCase( caseNr ).getStep( stepNr - 1 ).setStatus( status ); + public SELF step_$_of_case_$_has_status(int stepNr, int caseNr, StepStatus status) { + getCase(caseNr).getStep(stepNr - 1).setStatus(status); return self(); } - public SELF step_$_has_status( int stepNr, StepStatus status ) { - return step_$_of_case_$_has_status( stepNr, 1, status ); + public SELF step_$_has_status(int stepNr, StepStatus status) { + return step_$_of_case_$_has_status(stepNr, 1, status); } - public SELF step_$_has_a_duration_of_$_nano_seconds( int i, long durationInNanos ) { - getCase( 1 ).getStep( i - 1 ).setDurationInNanos( durationInNanos ); + public SELF step_$_has_a_duration_of_$_nano_seconds(int i, long durationInNanos) { + getCase(1).getStep(i - 1).setDurationInNanos(durationInNanos); return self(); } - public SELF case_$_has_a_when_step_$_with_argument( int ncase, String name, String arg ) { - return case_$_has_a_when_step_$_with_argument_$_and_argument_name_$( ncase, name, arg, "argName" ); + public SELF case_$_has_a_when_step_$_with_argument(int ncase, String name, String arg) { + return case_$_has_a_when_step_$_with_argument_$_and_argument_name_$(ncase, name, arg, "argName"); } - public SELF case_$_has_a_when_step_$_with_argument_$_and_argument_name_$( int ncase, @Quoted String name, @Quoted String arg, - @Quoted String argName ) { - lastArgWord = Word.argWord( argName, arg, arg ); - getCase( ncase ) + public SELF case_$_has_a_when_step_$_with_argument_$_and_argument_name_$(int ncase, @Quoted String name, + @Quoted String arg, + @Quoted String argName) { + lastArgWord = Word.argWord(argName, arg, arg); + getCase(ncase) .addStep( - new StepModel( name, - Arrays.asList( Word.introWord( "when" ), new Word( name ), lastArgWord ) ) ); + new StepModel(name, + Arrays.asList(Word.introWord("when"), new Word(name), lastArgWord))); return self(); } - public SELF formatted_value( @Quoted String formattedValue ) { - lastArgWord.getArgumentInfo().setFormattedValue( formattedValue ); + public SELF formatted_value(@Quoted String formattedValue) { + lastArgWord.getArgumentInfo().setFormattedValue(formattedValue); return self(); } - public SELF the_first_scenario_has_tag( @Quoted String name ) { - return scenario_$_has_tag_$_with_value_$( 1, name, null ); + public SELF the_first_scenario_has_tag(@Quoted String name) { + return scenario_$_has_tag_$_with_value_$(1, name, null); } - public SELF scenario_$_has_tag_$_with_value_$( int i, String name, String value ) { - latestTag = new Tag( name, value ).setPrependType( true ); - latestTag.setType( name ); - reportModel.getScenarios().get( i - 1 ).addTag( latestTag ); - reportModel.addTag( latestTag ); + public SELF scenario_$_has_tag_$_with_value_$(int i, String name, String value) { + latestTag = new Tag(name, value).setPrependType(true); + latestTag.setType(name); + reportModel.getScenarios().get(i - 1).addTag(latestTag); + reportModel.addTag(latestTag); return self(); } - public void the_tag_has_prependTpe_set_to( boolean prependType ) { - latestTag.setPrependType( prependType ); + public void the_tag_has_prependTpe_set_to(boolean prependType) { + latestTag.setPrependType(prependType); } - public SELF the_tag_has_style( String style ) { - latestTag.setStyle( style ); + public SELF the_tag_has_style(String style) { + latestTag.setStyle(style); return self(); } @AfterStage public void analyzeReport() { - if( analyze ) { - new CaseArgumentAnalyser().analyze( reportModel ); + if (analyze) { + new CaseArgumentAnalyser().analyze(reportModel); } } - public void transpose_set_to( boolean b ) {} + public void transpose_set_to(boolean b) { + } - public SELF header_type_set_to( Table.HeaderType headerType ) { - latestWord.getArgumentInfo().getDataTable().setHeaderType( headerType ); + public SELF header_type_set_to(Table.HeaderType headerType) { + latestWord.getArgumentInfo().getDataTable().setHeaderType(headerType); return self(); } - public SELF step_$_of_scenario_$_has_an_attachment_with_content( int stepNr, int scenarioNr, String content ) { - StepModel step = getStep( stepNr, scenarioNr ); - step.addAttachment( Attachment.fromText( content, MediaType.PLAIN_TEXT_UTF_8 ) ); + public SELF step_$_of_scenario_$_has_an_attachment_with_content(int stepNr, int scenarioNr, String content) { + StepModel step = getStep(stepNr, scenarioNr); + step.addAttachment(Attachment.fromText(content, MediaType.PLAIN_TEXT_UTF_8)); return self(); } - public SELF step_$_of_case_$_has_an_attachment_with_content_and_media_type( int stepNr, int caseNr, String content ) { - return step_$_of_case_$_has_an_attachment_with_content_and_media_type( stepNr, caseNr, content, MediaType.PLAIN_TEXT_UTF_8 ); + public SELF step_$_of_case_$_has_an_attachment_with_content_and_media_type(int stepNr, int caseNr, String content) { + return step_$_of_case_$_has_an_attachment_with_content_and_media_type(stepNr, caseNr, content, + MediaType.PLAIN_TEXT_UTF_8); } - public SELF step_$_of_case_$_has_an_attachment_with_content_and_media_type( int stepNr, int caseNr, String content, - MediaType mediaType ) { - StepModel step = getStep( stepNr, 1, caseNr ); - step.addAttachment( Attachment.fromText( content, mediaType ) ); + public SELF step_$_of_case_$_has_an_attachment_with_content_and_media_type(int stepNr, int caseNr, String content, + MediaType mediaType) { + StepModel step = getStep(stepNr, 1, caseNr); + step.addAttachment(Attachment.fromText(content, mediaType)); return self(); } - public SELF step_$_of_scenario_$_has_another_attachment_with_content( int stepNr, int scenarioNr, String content ) { - return step_$_of_scenario_$_has_an_attachment_with_content( stepNr, scenarioNr, content ); + public SELF step_$_of_scenario_$_has_another_attachment_with_content(int stepNr, int scenarioNr, String content) { + return step_$_of_scenario_$_has_an_attachment_with_content(stepNr, scenarioNr, content); } - private StepModel getStep( int stepNr, int scenarioNr ) { - return getStep( stepNr, scenarioNr, 1 ); + private StepModel getStep(int stepNr, int scenarioNr) { + return getStep(stepNr, scenarioNr, 1); } - private StepModel getStep( int stepNr, int scenarioNr, int caseNr ) { - return reportModel.getScenarios().get( scenarioNr - 1 ).getScenarioCases().get( caseNr - 1 ).getStep( stepNr - 1 ); + private StepModel getStep(int stepNr, int scenarioNr, int caseNr) { + return reportModel.getScenarios().get(scenarioNr - 1).getScenarioCases().get(caseNr - 1).getStep(stepNr - 1); } - public SELF a_step_has_a_data_table_with_following_values( @Table List> dataTable ) { - return step_$_of_scenario_$_has_a_data_table_as_parameter( dataTable ); + public SELF a_step_has_a_data_table_with_following_values(@Table List> dataTable) { + return step_$_of_scenario_$_has_a_data_table_as_parameter(dataTable); } - public SELF step_$_of_scenario_$_has_a_data_table_as_parameter( @Table List> dataTable ) { - StepModel step = getStep( 1, 1 ); - Word word = Word.argWord( "a", "b", new DataTable( Table.HeaderType.HORIZONTAL, dataTable ) ); - step.addWords( word ); + public SELF step_$_of_scenario_$_has_a_data_table_as_parameter(@Table List> dataTable) { + StepModel step = getStep(1, 1); + Word word = Word.argWord("a", "b", new DataTable(Table.HeaderType.HORIZONTAL, dataTable)); + step.addWords(word); latestWord = word; return self(); } - public SELF case_$_has_no_steps( int caseNr ) { - reportModel.getLastScenarioModel().getCase( caseNr - 1 ).setSteps( Collections.emptyList() ); + public SELF case_$_has_no_steps(int caseNr) { + reportModel.getLastScenarioModel().getCase(caseNr - 1).setSteps(Collections.emptyList()); return self(); } - public SELF scenario_$_has_no_steps( int i ) { + public SELF scenario_$_has_no_steps(int i) { ScenarioModel scenarioModel = reportModel.getLastScenarioModel(); - for( ScenarioCaseModel caseModel : scenarioModel.getScenarioCases() ) { - caseModel.setSteps( Collections.emptyList() ); + for (ScenarioCaseModel caseModel : scenarioModel.getScenarioCases()) { + caseModel.setSteps(Collections.emptyList()); } return self(); } - public SELF step_$_of_case_$_has_a_formatted_value_$_as_parameter( int stepNr, int caseNr, String formattedValue ) { - StepModel step = getStep( stepNr, 1, caseNr ); - Word word = Word.argWord( "a", "dummy value", formattedValue ); - step.addWords( word ); + public SELF step_$_of_case_$_has_a_formatted_value_$_as_parameter(int stepNr, int caseNr, String formattedValue) { + StepModel step = getStep(stepNr, 1, caseNr); + Word word = Word.argWord("a", "dummy value", formattedValue); + step.addWords(word); latestWord = word; return self(); } - public SELF the_attachment_is_added_to_step_$_of_case_$( int stepNr, int caseNr ) { - getStep( stepNr, 1, caseNr ).addAttachment( attachments.get( attachments.size() - 1 ) ); + public SELF the_attachment_is_added_to_step_$_of_case_$(int stepNr, int caseNr) { + getStep(stepNr, 1, caseNr).addAttachment(attachments.get(attachments.size() - 1)); return self(); } @@ -320,19 +323,21 @@ public SELF a_step_has_a_data_table_with_following_values( @Table List argumentMap){ - StepModel stepModel = getStep( stepNr, scenarioNr ); - stepModel.setExtendedDescription( description ); - for (Map.Entry entry : argumentMap.entrySet()){ - Word word = Word.argWord( entry.getKey(), entry.getValue(), entry.getValue() ); - stepModel.addWords( word ); + public SELF step_$_of_scenario_$_has_extended_description_with_arguments(int stepNr, int scenarioNr, + String description, + Map argumentMap) { + StepModel stepModel = getStep(stepNr, scenarioNr); + stepModel.setExtendedDescription(description); + for (Map.Entry entry : argumentMap.entrySet()) { + Word word = Word.argWord(entry.getKey(), entry.getValue(), entry.getValue()); + stepModel.addWords(word); } return self(); } - public SELF step_$_of_scenario_$_has_an_image_attachment(int stepNr, int scenarioNr, String base64img){ - StepModel stepModel = getStep( stepNr, scenarioNr ); - stepModel.addAttachment( Attachment.fromBase64( base64img, MediaType.PNG ).withTitle( "Screenshot" ) ); + public SELF step_$_of_scenario_$_has_an_image_attachment(int stepNr, int scenarioNr, String base64img) { + StepModel stepModel = getStep(stepNr, scenarioNr); + stepModel.addAttachment(Attachment.fromBase64(base64img, MediaType.PNG).withTitle("Screenshot")); return self(); } } diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModels.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModels.java index 82653aaf1f..82d3184a6d 100644 --- a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModels.java +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModels.java @@ -2,14 +2,18 @@ import com.google.common.collect.Lists; import com.tngtech.jgiven.Stage; -import com.tngtech.jgiven.annotation.*; +import com.tngtech.jgiven.annotation.BeforeStage; +import com.tngtech.jgiven.annotation.ExpectedScenarioState; +import com.tngtech.jgiven.annotation.Format; +import com.tngtech.jgiven.annotation.ProvidedScenarioState; +import com.tngtech.jgiven.annotation.ScenarioStage; import com.tngtech.jgiven.attachment.Attachment; import com.tngtech.jgiven.attachment.MediaType; import com.tngtech.jgiven.format.PrintfFormatter; - import java.util.List; import java.util.Map; +@SuppressWarnings("UnusedReturnValue") public class GivenReportModels> extends Stage { @ExpectedScenarioState protected ReportModel reportModel; @@ -25,117 +29,121 @@ public class GivenReportModels> extends Stage< @BeforeStage public void useReportModel() { - if( reportModel != null ) { - reportModels.add( reportModel ); + if (reportModel != null) { + reportModels.add(reportModel); } } - public SELF $_report_models( int n ) { - for( int i = 0; i < n; i++ ) { - a_report_model_with_name( "Test" + i ); + public SELF $_report_models(int n) { + for (int i = 0; i < n; i++) { + a_report_model_with_name("Test" + i); } return self(); } public SELF a_report_model() { - return a_report_model_with_name( "Test" ); + return a_report_model_with_name("Test"); } - public SELF a_report_model_with_name( String name ) { - ReportModel reportModel = givenReportModel.a_report_model_with_name( name ).getReportModel(); - reportModels.add( reportModel ); + public SELF a_report_model_with_name(String name) { + ReportModel reportModel = givenReportModel.a_report_model_with_name(name).getReportModel(); + reportModels.add(reportModel); return self(); } - public SELF the_report_has_$_scenarios( int n ) { - givenReportModel.the_report_has_$_scenarios( n ); + public SELF the_report_has_$_scenarios(int n) { + givenReportModel.the_report_has_$_scenarios(n); return self(); } - public SELF the_first_scenario_has_tag( String name ) { - givenReportModel.the_first_scenario_has_tag( name ); + public SELF the_first_scenario_has_tag(String name) { + givenReportModel.the_first_scenario_has_tag(name); return self(); } - public SELF the_tag_has_style( String style ) { - givenReportModel.the_tag_has_style( style ); + public SELF the_tag_has_style(String style) { + givenReportModel.the_tag_has_style(style); return self(); } - public SELF scenario_$_has_tag_$_with_value_$( int i, String name, String value ) { - givenReportModel.scenario_$_has_tag_$_with_value_$( i, name, value ); + public SELF scenario_$_has_tag_$_with_value_$(int i, String name, String value) { + givenReportModel.scenario_$_has_tag_$_with_value_$(i, name, value); return self(); } - public SELF the_tag_has_prependType_set_to( boolean prependType ) { - givenReportModel.the_tag_has_prependTpe_set_to( prependType ); + public SELF the_tag_has_prependType_set_to(boolean prependType) { + givenReportModel.the_tag_has_prependTpe_set_to(prependType); return self(); } - public SELF case_$_of_scenario_$_has_failed( int caseNr, int scenarioNr ) { - givenReportModel.case_$_of_scenario_$_has_failed( caseNr, scenarioNr ); + public SELF case_$_of_scenario_$_has_failed(int caseNr, int scenarioNr) { + givenReportModel.case_$_of_scenario_$_has_failed(caseNr, scenarioNr); return self(); } public SELF the_scenario_has_one_parameter() { - givenReportModel.the_scenario_has_parameters( "foo" ); + givenReportModel.the_scenario_has_parameters("foo"); return self(); } - public SELF the_scenario_has_parameters( String... params ) { - givenReportModel.the_scenario_has_parameters( params ); + public SELF the_scenario_has_parameters(String... params) { + givenReportModel.the_scenario_has_parameters(params); return self(); } - public SELF the_scenario_has_$_default_cases( int ncases ) { - givenReportModel.the_scenario_has_$_default_cases( ncases ); + public SELF the_scenario_has_$_default_cases(int ncases) { + givenReportModel.the_scenario_has_$_default_cases(ncases); return self(); } - public SELF step_$_of_case_$_has_status( int stepNr, int caseNr, StepStatus status ) { - givenReportModel.step_$_of_case_$_has_status( stepNr, caseNr, status ); + public SELF step_$_of_case_$_has_status(int stepNr, int caseNr, StepStatus status) { + givenReportModel.step_$_of_case_$_has_status(stepNr, caseNr, status); return self(); } - public SELF step_$_of_case_$_has_a_text_attachment( int stepNr, int caseNr ) { - givenReportModel.step_$_of_case_$_has_an_attachment_with_content_and_media_type( stepNr, caseNr, "Test Text" ); + + public SELF step_$_of_case_$_has_a_text_attachment(int stepNr, int caseNr) { + givenReportModel.step_$_of_case_$_has_an_attachment_with_content_and_media_type(stepNr, caseNr, "Test Text"); return self(); } - public SELF step_$_of_case_$_has_a_text_attachment_with_content_$_and_mediaType( int stepNr, int caseNr, String content, - MediaType mediaType ) { - givenReportModel.step_$_of_case_$_has_an_attachment_with_content_and_media_type( stepNr, caseNr, content, mediaType ); + public SELF step_$_of_case_$_has_a_text_attachment_with_content_$_and_mediaType(int stepNr, int caseNr, + String content, + MediaType mediaType) { + givenReportModel + .step_$_of_case_$_has_an_attachment_with_content_and_media_type(stepNr, caseNr, content, mediaType); return self(); } - public SELF step_$_of_case_$_has_a_text_attachment_with_content( int stepNr, int caseNr, String content ) { - givenReportModel.step_$_of_case_$_has_an_attachment_with_content_and_media_type( stepNr, caseNr, content ); + public SELF step_$_of_case_$_has_a_text_attachment_with_content(int stepNr, int caseNr, String content) { + givenReportModel.step_$_of_case_$_has_an_attachment_with_content_and_media_type(stepNr, caseNr, content); return self(); } - public SELF step_$_of_scenario_$_has_a_text_attachment_with_content( int stepNr, int scenarioNr, String content ) { - givenReportModel.step_$_of_scenario_$_has_an_attachment_with_content( stepNr, scenarioNr, content ); + public SELF step_$_of_scenario_$_has_a_text_attachment_with_content(int stepNr, int scenarioNr, String content) { + givenReportModel.step_$_of_scenario_$_has_an_attachment_with_content(stepNr, scenarioNr, content); return self(); } - public SELF step_$_of_scenario_$_has_another_text_attachment_with_content( int stepNr, int scenarioNr, String content ) { - givenReportModel.step_$_of_scenario_$_has_another_attachment_with_content( stepNr, scenarioNr, content ); + public SELF step_$_of_scenario_$_has_another_text_attachment_with_content(int stepNr, int scenarioNr, + String content) { + givenReportModel.step_$_of_scenario_$_has_another_attachment_with_content(stepNr, scenarioNr, content); return self(); } - public SELF scenario_$_has_no_steps( int i ) { - givenReportModel.scenario_$_has_no_steps( i ); + public SELF scenario_$_has_no_steps(int i) { + givenReportModel.scenario_$_has_no_steps(i); return self(); } - public SELF step_$_of_case_$_has_a_formatted_value_$_as_parameter( int stepNr, int caseNr, String formattedValue ) { - givenReportModel.step_$_of_case_$_has_a_formatted_value_$_as_parameter( stepNr, caseNr, formattedValue ); + public SELF step_$_of_case_$_has_a_formatted_value_$_as_parameter(int stepNr, int caseNr, String formattedValue) { + givenReportModel.step_$_of_case_$_has_a_formatted_value_$_as_parameter(stepNr, caseNr, formattedValue); return self(); } - public SELF the_attachment_is_added_to_step_$_of_case_$( int stepNr, int caseNr ) { - givenReportModel.the_attachment_is_added_to_step_$_of_case_$( stepNr, caseNr ); + public SELF the_attachment_is_added_to_step_$_of_case_$(int stepNr, int caseNr) { + givenReportModel.the_attachment_is_added_to_step_$_of_case_$(stepNr, caseNr); return self(); } @@ -144,8 +152,11 @@ public SELF the_scenario_has_parameters( String... params ) { return self(); } - public SELF step_$_of_scenario_$_has_extended_description_with_arguments(int stepNr, int scenarioNr, String description, Map argumentMap){ - givenReportModel.step_$_of_scenario_$_has_extended_description_with_arguments(stepNr, scenarioNr, description, argumentMap); + public SELF step_$_of_scenario_$_has_extended_description_with_arguments(int stepNr, int scenarioNr, + String description, + Map argumentMap) { + givenReportModel + .step_$_of_scenario_$_has_extended_description_with_arguments(stepNr, scenarioNr, description, argumentMap); return self(); } From e1d4d61a83cff6fb3c6766d9cc2efe64b389dfeb Mon Sep 17 00:00:00 2001 From: l-1sqared <30831153+l-1squared@users.noreply.github.com> Date: Tue, 23 Nov 2021 08:24:12 +0100 Subject: [PATCH 2/5] Issue-755: Test Reporting is correct if timings are appropriate Signed-off-by: l-1sqared <30831153+l-1squared@users.noreply.github.com> --- .../jgiven/report/html5/Html5AppTest.java | 12 ++++++++++++ .../jgiven/report/html5/ThenHtml5App.java | 10 ++++++++++ .../jgiven/report/model/GivenReportModel.java | 18 ++++++++++++++---- .../jgiven/report/model/GivenReportModels.java | 14 +++++++++++++- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/Html5AppTest.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/Html5AppTest.java index 3b716e538b..03a9cb02cd 100644 --- a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/Html5AppTest.java +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/Html5AppTest.java @@ -358,4 +358,16 @@ public void showing_thumbnails_can_be_configured(boolean thumbOption) throws IOE then().$_attachment_icons_exist(1); } } + + @Test + @Issue("#755") + public void timings_greater_than_10_millis_are_displayed() throws IOException{ + given().a_report_model().and().step_$_of_scenario_took_$_nanos(0, 11_000_000); + + jsonReports.the_report_exist_as_JSON_file(); + whenReport.when().the_HTML_Report_Generator_is_executed(); + when().the_page_of_scenario_$_is_opened(1); + then().the_$_th_element_with_a_$_class_exists(2,"duration").has_content("(11ms)"); + + } } diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/ThenHtml5App.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/ThenHtml5App.java index aa3920a2b3..bf279f0107 100644 --- a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/ThenHtml5App.java +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/ThenHtml5App.java @@ -108,6 +108,16 @@ public SELF target(String target) { return self(); } + /** + * @param index the ordinal number of this element, starting at 1. + */ + public SELF the_$_th_element_with_a_$_class_exists(int index, String multiline) { + List elements = webDriver.findElements(By.className(multiline)); + assertThat(elements).hasSizeGreaterThanOrEqualTo(index); + foundElement = elements.get(index - 1); + return self(); + } + public SELF has_content(String content) { assertThat(foundElement.getText()).isEqualTo(content); return self(); diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModel.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModel.java index 59136d6055..3e81f8955b 100644 --- a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModel.java +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModel.java @@ -1,18 +1,22 @@ package com.tngtech.jgiven.report.model; +import static java.util.Arrays.asList; + import com.tngtech.jgiven.Stage; -import com.tngtech.jgiven.annotation.*; +import com.tngtech.jgiven.annotation.AfterStage; +import com.tngtech.jgiven.annotation.ExpectedScenarioState; +import com.tngtech.jgiven.annotation.ExtendedDescription; +import com.tngtech.jgiven.annotation.ProvidedScenarioState; +import com.tngtech.jgiven.annotation.Quoted; +import com.tngtech.jgiven.annotation.Table; import com.tngtech.jgiven.attachment.Attachment; import com.tngtech.jgiven.attachment.MediaType; import com.tngtech.jgiven.report.analysis.CaseArgumentAnalyser; - import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import static java.util.Arrays.asList; - public class GivenReportModel> extends Stage { @ProvidedScenarioState @@ -110,6 +114,12 @@ public SELF the_scenario_has_parameters(String... params) { return self(); } + public SELF the_step_$_has_a_duration_of_$_nano_seconds(int step, long durationInNanos) { + reportModel.getLastScenarioModel().getCase(0).getStep(step).setDurationInNanos(durationInNanos); + return self(); + } + + public SELF the_scenario_has_$_cases(int ncases) { ScenarioModel scenarioModel = reportModel.getLastScenarioModel(); scenarioModel.clearCases(); diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModels.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModels.java index 82d3184a6d..f9ff27db69 100644 --- a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModels.java +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/model/GivenReportModels.java @@ -160,7 +160,19 @@ public SELF the_scenario_has_parameters(String... params) { return self(); } - public SELF step_$_of_scenario_$_has_an_image_attachment_$(int stepNr, int scenarioNr, @Format( value = PrintfFormatter.class, args = { "base64 data: %.10s..." } ) String base64image){ + public SELF scenario_took_$_nanos(long durationInNanos) { + givenReportModel.the_scenario_has_a_duration_of_$_nano_seconds(durationInNanos); + return self(); + } + + public SELF step_$_of_scenario_took_$_nanos(int step, long durationInNanos){ + givenReportModel.the_step_$_has_a_duration_of_$_nano_seconds(step, durationInNanos); + return self(); + } + + public SELF step_$_of_scenario_$_has_an_image_attachment_$(int stepNr, int scenarioNr, + @Format(value = PrintfFormatter.class, args = { + "base64 data: %.10s..."}) String base64image) { givenReportModel.step_$_of_scenario_$_has_an_image_attachment(stepNr, scenarioNr, base64image); return self(); } From e4ddf9eb9012981d2ef9b2960724ff10c8c180be Mon Sep 17 00:00:00 2001 From: l-1sqared <30831153+l-1squared@users.noreply.github.com> Date: Thu, 25 Nov 2021 07:46:40 +0100 Subject: [PATCH 3/5] Issue-755: Set up tescases for Filler Word timings Signed-off-by: l-1sqared <30831153+l-1squared@users.noreply.github.com> Issue-755: set up testcases Signed-off-by: l-1sqared <30831153+l-1squared@users.noreply.github.com> --- .../jgiven/tests/StepTimingRecordingTest.java | 53 ++++++++++++++ .../com/tngtech/jgiven/impl/TimingsTest.java | 71 +++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 jgiven-tests/src/main/java/com/tngtech/jgiven/tests/StepTimingRecordingTest.java create mode 100644 jgiven-tests/src/test/java/com/tngtech/jgiven/impl/TimingsTest.java diff --git a/jgiven-tests/src/main/java/com/tngtech/jgiven/tests/StepTimingRecordingTest.java b/jgiven-tests/src/main/java/com/tngtech/jgiven/tests/StepTimingRecordingTest.java new file mode 100644 index 0000000000..0537a588ce --- /dev/null +++ b/jgiven-tests/src/main/java/com/tngtech/jgiven/tests/StepTimingRecordingTest.java @@ -0,0 +1,53 @@ +package com.tngtech.jgiven.tests; + +import com.tngtech.jgiven.Stage; +import com.tngtech.jgiven.annotation.FillerWord; +import com.tngtech.jgiven.junit.SimpleScenarioTest; +import org.junit.Test; + +public class StepTimingRecordingTest extends SimpleScenarioTest { + + @Test + public void last_step_is_preceeded_by_step() throws InterruptedException { + given().a_step_method_whose_execution_time_wont_be_displayed() + .a_step_method_whose_execution_time_will_be_displayed(); + } + + @Test + public void last_step_is_preceeded_by_intro_word() throws InterruptedException { + given().a_step_method_whose_execution_time_wont_be_displayed() + .and().a_step_method_whose_execution_time_will_be_displayed(); + } + + @Test + public void last_step_is_succeeded_by_intro_word() throws InterruptedException { + given().a_step_method_whose_execution_time_will_be_displayed().and(); + } + + @Test + public void last_step_is_succeeded_by_filler_word() throws InterruptedException { + given().a_step_method_whose_execution_time_will_be_displayed().before(); + } + + @Test + public void last_step_is_preceeded_by_filler_word() throws InterruptedException { + given().before().a_step_method_whose_execution_time_will_be_displayed(); + } + + static class TestSteps extends Stage { + + @FillerWord + TestSteps before() { + return this; + } + + TestSteps a_step_method_whose_execution_time_wont_be_displayed() { + return this; + } + + TestSteps a_step_method_whose_execution_time_will_be_displayed() throws InterruptedException { + Thread.sleep(15); + return this; + } + } +} diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/impl/TimingsTest.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/impl/TimingsTest.java new file mode 100644 index 0000000000..8748de7f8d --- /dev/null +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/impl/TimingsTest.java @@ -0,0 +1,71 @@ +package com.tngtech.jgiven.impl; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.jgiven.Stage; +import com.tngtech.jgiven.junit.SimpleScenarioTest; +import com.tngtech.jgiven.report.model.ReportModel; +import com.tngtech.jgiven.report.model.StepModel; +import com.tngtech.jgiven.tags.Issue; +import com.tngtech.jgiven.testframework.TestExecutionResult; +import com.tngtech.jgiven.testframework.TestExecutor; +import com.tngtech.jgiven.testframework.TestFramework; +import com.tngtech.jgiven.tests.StepTimingRecordingTest; +import com.tngtech.jgiven.tests.TestScenarioRepository; +import java.lang.reflect.Method; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; + +@Issue("#755") +@RunWith(DataProviderRunner.class) +public class TimingsTest extends SimpleScenarioTest { + + @Test + @DataProvider({ + "last_step_is_preceeded_by_step", + "last_step_is_preceeded_by_intro_word", + "last_step_is_preceeded_by_filler_word", + "last_step_is_succeeded_by_intro_word", + "last_step_is_succeeded_by_filler_word", + }) + public void recorded_timing_is_correct_for(String methodName) { + given().the_JGiven_timings_test_class_with_method(methodName); + when().the_test_is_executed(); + then().the_recorded_timing_is_greater_than_ten_millis(); + } + + @SuppressWarnings("UnusedReturnValue") + static class SimpleTestStage extends Stage { + TestScenarioRepository.TestScenario testScenario; + private ReportModel testReport; + + SimpleTestStage the_JGiven_timings_test_class_with_method(String requestedMethod) { + testScenario = new TestScenarioRepository.TestScenario(StepTimingRecordingTest.class, requestedMethod); + assertThat(StepTimingRecordingTest.class.getMethods()) + .as("Requested method exists in class") + .extracting(Method::getName) + .contains(requestedMethod); + return this; + } + + SimpleTestStage the_test_is_executed() { + TestExecutor testExecutor = TestExecutor.getExecutor(TestFramework.JUnit); + TestExecutionResult testExecutionResult = testExecutor.execute(testScenario.testClass, + testScenario.testMethod); + + testReport = testExecutionResult.getReportModel(); + return this; + } + + SimpleTestStage the_recorded_timing_is_greater_than_ten_millis() { + long tenMillisecondsInNanos = 10_000_000; + List executedSteps = testReport.getLastScenarioModel().getCase(0).getSteps(); + long actualDurationInNanos = executedSteps.get(executedSteps.size() - 1).getDurationInNanos(); + assertThat(actualDurationInNanos).isGreaterThan(tenMillisecondsInNanos); + return this; + } + } +} From 77801511685e731dee1527c0778ccbf64e951b74 Mon Sep 17 00:00:00 2001 From: l-1sqared <30831153+l-1squared@users.noreply.github.com> Date: Wed, 1 Dec 2021 07:49:49 +0100 Subject: [PATCH 4/5] Issue-755: implement awful solution The source of the incorrect timings is that the StepInterceptor and the ScenarioModelBuilder have different concepts about what a step is. Consequently, in the eyes of the scenario builder, the stepMethodFinished is called way more often than it should be. This is the source of incorrect timings in the presence of nested steps, intro and filler words. The current solution tries to track the and accomodate for the difference in understandings when it comes to timings. The limitation on timing is part of what makes this implementation so awful. Signed-off-by: l-1sqared <30831153+l-1squared@users.noreply.github.com> --- .../jgiven/impl/ScenarioModelBuilder.java | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java b/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java index fede67184a..37ea37dc48 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java @@ -76,6 +76,8 @@ public void setReportModel(ReportModel reportModel) { this.reportModel = reportModel; } + private Stack discrepancyOnLayer = new Stack<>(); + @Override public void scenarioStarted(String description) { scenarioStartedNanos = System.nanoTime(); @@ -93,6 +95,7 @@ public void scenarioStarted(String description) { scenarioModel.addCase(scenarioCaseModel); scenarioModel.setDescription(readableDescription); this.tagCreator = new TagCreator(configuration); + discrepancyOnLayer.push(0); } @Override @@ -115,7 +118,7 @@ public void scenarioStarted(Class testClass, Method method, List arguments, InvocationMode mode, - boolean hasNestedSteps) { + boolean hasNestedSteps) { StepModel stepModel = createStepModel(paramMethod, arguments, mode); if (parentSteps.empty()) { @@ -126,6 +129,7 @@ private void addStepMethod(Method paramMethod, List arguments, In if (hasNestedSteps) { parentSteps.push(stepModel); + discrepancyOnLayer.push(0); } currentStep = stepModel; } @@ -213,16 +217,31 @@ private ScenarioCaseModel getCurrentScenarioCase() { return scenarioCaseModel; } + private void incrementDiscrepancy() { + int discrepancyOnCurrentLayer = discrepancyOnLayer.pop(); + discrepancyOnCurrentLayer++; + discrepancyOnLayer.push(discrepancyOnCurrentLayer); + } + + private void decrementDiscrepancy() { + int discrepancyOnCurrentLayer = discrepancyOnLayer.pop(); + discrepancyOnCurrentLayer--; + discrepancyOnLayer.push(discrepancyOnCurrentLayer); + } + @Override public void stepMethodInvoked(Method method, List arguments, InvocationMode mode, boolean hasNestedSteps) { if (method.isAnnotationPresent(IntroWord.class)) { introWordAdded(getDescription(method)); + incrementDiscrepancy(); } else if (method.isAnnotationPresent(FillerWord.class)) { FillerWord fillerWord = method.getAnnotation(FillerWord.class); addToSentence(getDescription(method), fillerWord.joinToPreviousWord(), fillerWord.joinToNextWord()); + incrementDiscrepancy(); } else if (method.isAnnotationPresent(StepComment.class)) { addStepComment(arguments); + incrementDiscrepancy(); } else { addTags(method.getAnnotations()); addTags(method.getDeclaringClass().getAnnotations()); @@ -272,7 +291,7 @@ public void setStatus(ExecutionStatus status) { scenarioCaseModel.setStatus(status); } - public void setException(Throwable throwable) { + private void setException(Throwable throwable) { scenarioCaseModel.setErrorMessage(throwable.getClass().getName() + ": " + throwable.getMessage()); scenarioCaseModel.setStackTrace(getStackTrace(throwable, FILTER_STACK_TRACE)); } @@ -309,18 +328,25 @@ public void stepMethodFinished(long durationInNanos, boolean hasNestedSteps) { } if (currentStep != null) { - currentStep.setDurationInNanos(durationInNanos); + if (discrepancyOnLayer.empty() || discrepancyOnLayer.peek() == 0) { + currentStep.setDurationInNanos(durationInNanos); + } if (hasNestedSteps) { if (currentStep.getStatus() != StepStatus.FAILED) { currentStep.setStatus(getStatusFromNestedSteps(currentStep.getNestedSteps())); } parentSteps.pop(); + discrepancyOnLayer.pop(); } } if (!hasNestedSteps && !parentSteps.isEmpty()) { currentStep = parentSteps.peek(); } + + if (discrepancyOnLayer.peek() > 0) { + decrementDiscrepancy(); + } } private StepStatus getStatusFromNestedSteps(List nestedSteps) { @@ -346,7 +372,7 @@ public void scenarioFailed(Throwable e) { setException(e); } - private void setCaseDescription(Class testClass, Method method, List namedArguments) { + private void setCaseDescription(Class testClass, Method method, List namedArguments) { CaseAs annotation = null; if (method.isAnnotationPresent(CaseAs.class)) { From 2b71c0a7b42e3a819b2a52d039bcff3b8c9b8bac Mon Sep 17 00:00:00 2001 From: Christian Oertel Date: Fri, 10 Dec 2021 10:47:19 +0100 Subject: [PATCH 5/5] Refactoring Signed-off-by: Christian Oertel --- .../jgiven/impl/ScenarioModelBuilder.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java b/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java index 37ea37dc48..fcd4e302d3 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/impl/ScenarioModelBuilder.java @@ -58,11 +58,6 @@ public class ScenarioModelBuilder implements ScenarioListener { private StepModel currentStep; private final Stack parentSteps = new Stack<>(); - /** - * In case the current step is a step with nested steps, this list contains these steps. - */ - private List nestedSteps; - private final SentenceBuilder sentenceBuilder = new SentenceBuilder(); private long scenarioStartedNanos; @@ -224,9 +219,11 @@ private void incrementDiscrepancy() { } private void decrementDiscrepancy() { - int discrepancyOnCurrentLayer = discrepancyOnLayer.pop(); - discrepancyOnCurrentLayer--; - discrepancyOnLayer.push(discrepancyOnCurrentLayer); + if (discrepancyOnLayer.peek() > 0) { + int discrepancyOnCurrentLayer = discrepancyOnLayer.pop(); + discrepancyOnCurrentLayer--; + discrepancyOnLayer.push(discrepancyOnCurrentLayer); + } } @Override @@ -344,9 +341,8 @@ public void stepMethodFinished(long durationInNanos, boolean hasNestedSteps) { currentStep = parentSteps.peek(); } - if (discrepancyOnLayer.peek() > 0) { - decrementDiscrepancy(); - } + decrementDiscrepancy(); + } private StepStatus getStatusFromNestedSteps(List nestedSteps) {