1

I am getting pending steps for jbehave stories and please find the configuration details below: All the story steps are correct to my knowledge.I am not getting where i am going wrong in configuration. Could you please help me.

build.gradle:

    def buildNumber = System.getProperty('buildNumber') ?: '0'
def buildVersion = '1.0.0-' + buildNumber

version = buildVersion

apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: 'maven'

repositories {
    maven { url 'http://repo1.maven.org/maven2/' }
    maven { url 'https://mvnrepository.com/' }
    maven {url 'https://mvnrepository.com/artifact/org.jbehave'}
    mavenCentral()
}

dependencies {
    compile 'com.google.guava:guava:18.0'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8.1'
    compile group: 'org.codehaus.jackson', name: 'jackson-core-asl', version: '1.1.0'
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile 'org.codehaus.groovy:groovy-all:2.3.11'
    compile('org.springframework:spring-core:4.0.5.RELEASE') {
        exclude(module: 'commons-logging')
    }
    compile(group: 'org.jbehave.web', name: 'jbehave-web-selenium', version: '4.0-beta-1') {
        exclude(module: 'selenium-remote-control')
        exclude(module: 'selenium-java')
        exclude(module: 'jbehave-core')
    }
    compile 'javax.servlet:javax.servlet-api:3.0.1'
    compile 'org.springframework:spring-webmvc:4.0.5.RELEASE'
    compile 'org.springframework:spring-jdbc:4.0.5.RELEASE'
    compile 'org.springframework:spring-test:4.0.5.RELEASE'
    compile 'io.springfox:springfox-spring-web:2.2.2'
    compile 'io.springfox:springfox-swagger-ui:2.2.2'
    compile 'io.springfox:springfox-swagger2:2.2.2'
    compile 'com.googlecode.json-simple:json-simple:1.1.1'
    compile 'org.jbehave.site:jbehave-site-resources:3.1.1'
    compile 'org.jbehave:jbehave-spring:3.9.3'
    compile 'org.jbehave:jbehave-core:4.1.3'
    compile 'commons-dbcp:commons-dbcp:1.2.2'
    compile 'org.slf4j:slf4j-api:1.7.6'
    compile 'com.jcraft:jsch:0.1.53'
    compile 'org.json:json:20140107'
    compile 'log4j:log4j:1.2.11'
    compile 'org.assertj:assertj-core:2.3.0'
    compile group: 'commons-io', name: 'commons-io', version: '2.5'
    // https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-chrome-driver
    compile group: 'org.seleniumhq.selenium', name: 'selenium-chrome-driver', version: '2.33.0'
    compile group: 'org.seleniumhq.selenium', name: 'selenium-server', version: '3.7.1'
    // https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
    compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.7.1'

    compile group: 'org.picocontainer', name: 'picocontainer', version: '2.15'
    compile group: 'joda-time', name: 'joda-time', version: '2.8.1'
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'

    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version:'4.3.1'
    compile group: 'org.codehaus.plexus', name: 'plexus-utils', version:'3.0.22'
    compile group: 'commons-lang', name: 'commons-lang', version: '2.3'
//    testCompile 'org.jbehave:jbehave-core:3.9.3'
    compile 'org.jbehave.site:jbehave-site-resources:3.1.1:@zip'
    }

sourceSets.test.resources.srcDir 'src/test/java'

/** userDefined task to copy the srories from /src/main/stories into build/classes/test/stories*/
task copyStories(type: Copy) {
    from 'src/main/resources' into "${buildDir}/classes/test"
    from 'src/main/stories' into "${buildDir}/classes/test/stories"
}


sourceSets {
    test {
        java {
            srcDir "src/main/java"
        }
        resources {
            srcDir "src/main/resources"
        }
    }
}

/* This is to copy the system properties from gradle available to Junit test classes*/

test {
    systemProperty "metaFilters", System.getProperty("metaFilters", "")
    doFirst {
        copy {
            from(zipTree(jarPath("jbehave-core"))) {
                include "style/*"
            }
            into("build/reports/jbehave/view")

        }
        copy {
            from(zipTree(jarPath("jbehave-site-resources"))) {
                include "js/**/*"
                include "style/**/*"
                include "images/*"
            }
            into("build/reports/jbehave/view")
        }
    }
    systemProperties System.getProperties()
    dependsOn([clean,copyStories])
}

def jarPath(String jarName) {
    configurations.testCompile.find({ it.name.startsWith(jarName) }).absolutePath
}

Jbheave extending junitstories class as

public class JbehaveStories extends JUnitStories{
    private static final String _STORIES_SEPARATOR = ",";
    public static HtmlOutput qmoHtmlOutput;
    public static StoryData storyData;
    public static List<String> storyToExecute = null;
    static CrossReference crossReference = new CrossReference().withJsonOnly().withOutputAfterEachStory(true);
    Logger logger = Logger.getLogger(JbehaveStories.class);
    Logger log = Logger.getLogger(JbehaveStories.class);
    ContextView contextView = new LocalFrameContextView().sized(640, 120);
    SeleniumContext seleniumContext = new SeleniumContext();
    private org.jbehave.web.selenium.WebDriverProvider driverProvider = new org.jbehave.web.selenium.PropertyWebDriverProvider();
    private WebDriverSteps lifecycleSteps = new PerStoriesWebDriverSteps(driverProvider);
//    SeleniumStepMonitor stepMonitor = new SeleniumStepMonitor(contextView, seleniumContext,crossReference.getStepMonitor());
    Format[] formats = new Format[]{new SeleniumContextOutput(seleniumContext), CONSOLE, XML, HTML};
    StoryReporterBuilder reporterBuilder = new StoryReporterBuilder(storyData)
            .withCodeLocation(codeLocationFromClass(WebJbehaveStories.class)).withFailureTrace(true)
            .withFailureTraceCompression(true).withDefaultFormats().withFormats(formats)
            .withCrossReference(crossReference);
    private ApplicationContext applicationContext;

    public WebJbehaveStories() {
        super();
        try {
            System.setProperty("webdriver.chrome.driver", "src/main/resources/drivers/chromedriver.exe");
            storyData = new StoryData();
//            String path = BNSFWebJbehaveStories.class.getProtectionDomain().getCodeSource().getLocation().getPath() + "stories/log4j.properties";
//            PropertyConfigurator.configure(path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Configuration configuration() {
        new WebDriverScreenshotOnFailure(driverProvider, new StoryReporterBuilder());
        Class<? extends Embeddable> embeddableClass = this.getClass();
        ParameterConverters parameterConverters = new ParameterConverters();
        LoadFromClasspath resourceLoader = new LoadFromClasspath(embeddableClass);
        TableTransformers tableTranformers = new TableTransformers();
        ExamplesTableFactory examplesTableFactory = new ExamplesTableFactory(new LocalizedKeywords(), resourceLoader,
                parameterConverters, tableTranformers);
        parameterConverters.addConverters(new ParameterConverters.DateConverter(new SimpleDateFormat("yyyy-MM-dd")),
                new ParameterConverters.ExamplesTableConverter(examplesTableFactory));
        return new SeleniumConfiguration().useSeleniumContext(seleniumContext)
                .usePendingStepStrategy(new FailingUponPendingStep())
                .useStoryControls(new StoryControls().doResetStateBeforeScenario(true))
                .useStoryLoader(new LoadFromClasspath(WebJbehaveStories.class))
                .useStoryReporterBuilder(new StoryReporterBuilder())
                .useStoryParser(new RegexStoryParser(examplesTableFactory))
                .useStoryReporterBuilder(new StoryReporterBuilder(storyData)
                        .withCodeLocation(CodeLocations.codeLocationFromPath(getClassPath()))
                        .withCrossReference(crossReference)
                        .withFormats(Format.CONSOLE, Format.HTML, XML))
                .useParameterControls(new ParameterControls()
                        .useDelimiterNamedParameters(true))
                .useParameterConverters(parameterConverters)
                .useStepPatternParser(new RegexPrefixCapturingPatternParser()).doDryRun(true);
    }

    private List<String> getMetaFilters() {
        String metaFilterStr = System.getProperty("meta.filter");
        metaFilterStr = metaFilterStr == null ? "" : metaFilterStr;
        List<String> metaFilters = Arrays.asList(metaFilterStr.split(","));
        log.info("**** MetaFilters = " + metaFilters);
        return metaFilters;
    }

    private String getClassPath() {
        URL fileUrl = codeLocationFromClass(this.getClass());
        String classpath = getPathFromURL(fileUrl);
        System.out.println("getClassPath classpath = " + classpath);
        // class may come from a jar file
        if (classpath.endsWith(".jar!")) {
            int idx = classpath.lastIndexOf('.');
            classpath = classpath.substring(0, idx);
        }
        return classpath;
    }

    @Override
    public InjectableStepsFactory stepsFactory() {
        if (this.applicationContext == null) {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(WebJbehaveStories.class);
            this.applicationContext = applicationContext;
        }
        return new SpringStepsFactory(configuration(), this.applicationContext);
    }

    @Override
    public void run() throws Throwable {
        Embedder embedder = configuredEmbedder();
        embedder.embedderControls().useStoryTimeoutInSecs(450000);
        embedder.useMetaFilters(getMetaFilters());
        // These should be enabled so that even though the stories fail it wont go to catch method. Its useful when running multiple scenarios
        embedder.embedderControls().doIgnoreFailureInStories(true);
        embedder.embedderControls().doIgnoreFailureInView(false);
        embedder.embedderControls().doGenerateViewAfterStories(true);
        embedder.configuration().storyControls().doIgnoreMetaFiltersIfGivenStory(true);
        List<String> storyPaths = storyPaths();
        try {
            embedder.runStoriesAsPaths(storyPaths);
        } catch (Exception e) {
            e.printStackTrace();
            Loggers.CONSOLE_LOGGER.error("STORY FAILED DUE TO:");
            e.printStackTrace(System.err);
            Loggers.FILE_LOGGER.error("STORY FAILED DUE TO:");
            e.printStackTrace(System.err);
            Loggers.CONSOLE_LOGGER.info("Driver instance is closing");
            Loggers.FILE_LOGGER.info("Driver instance is closing");
            embedder.generateCrossReference();
            throw new Throwable(e.fillInStackTrace());
        } finally {
            try {
                Loggers.CONSOLE_LOGGER.info("Driver instance is closing");
                driver.quit();
                Loggers.FILE_LOGGER.info("Driver instance is closing");
            } catch (Exception e) {
                System.out.println("Issue in closing driver instance in run method: " + e.getMessage());// Wantedly not caught the exception
            }
            embedder.generateCrossReference();
        }
    }

    public String getStoryFromStoryPaths(String storyName, List<String> storyPaths) {
        for (String story : storyPaths) {
            System.out.println("story = " + story);
            int stroryLength = story.split("/").length;
            if (story.split("/")[stroryLength - 1].equalsIgnoreCase(storyName)) return story;
        }
        return "";
    }

    @Override
    protected List<String> storyPaths() {
        final List<String> globList = new ArrayList<String>();
        final String[] globs = storyFilter().split(_STORIES_SEPARATOR);
        for (final String story : globs) {
            globList.add("**/*" + story + (story.endsWith(".story") ? "" : ".story"));
        }
        log.info("******************************************************************************");
        log.info("**** globList = " + globList);
        log.info("******************************************************************************");
        String classpath = getClassPath();
        log.info("classpath=" + classpath);
        List<String> paths = new StoryFinder().findPaths(classpath, globList, null);
        log.info("**** story paths = " + paths.toString());
        return paths;
    }

    private String storyFilter() {
        String storyFilter = System.getProperty("story.filter");
        if (storyFilter == null) {
            storyFilter = "";
        }
        return storyFilter;
    }

    public String captureReportName() {
        String storyName = null;
        String fileNames[] = reporterBuilder.outputDirectory().list();
        for (int i = 0; i < fileNames.length; i++) {
            if (fileNames[i].contains("html") & !fileNames[i].contains("BeforeStories")) {
                String name[] = fileNames[i].split(".html");
                storyName = name[0];
            }
        }
        return storyName;
    }

}

The error i am getting is as follows:

(stories/HomePage.story)
Narrative:
As a user
I want to perform an action
So that I can achieve a business goal
Scenario: scenario description
Given I enter login details (PENDING)
@Given("I enter login details")
@Pending
public void givenIEnterLoginDetails() {
  // PENDING
}

Failed to run story stories/HomePage.story
org.jbehave.core.failures.PendingStepsFound: [Given I enter login details]

HomePage.story
Meta: 
Narrative: 
As a user 
I want to perform an action 
So that I can achieve a business goal 

Scenario: scenario description 

Given I enter login details 

public class HomePageSteps { 

  @Autowired HomePage homePage; 

  @When("I enter login details") 
  public void enter() { 
     try { 
       homePage.enterLoginDetails(); 
     } catch (Exception e) { 
        e.printStackTrace(System.err); 
     } 
  } 

  @Given("I enter login details") 
  public void enterx() { 
     try { 
         homePage.enterLoginDetails(); 
     } catch (Exception e) { 
         e.printStackTrace(System.err); 
     } 
  } 
} 
krokodilko
  • 35,300
  • 7
  • 55
  • 79
sri
  • 25
  • 7
  • Please show your story file and also a java class where you have defined the step annotated with `@Given("I enter login details")` – krokodilko Nov 29 '17 at 17:07
  • HomePage.storyMeta: Narrative: As a user I want to perform an action So that I can achieve a business goal Scenario: scenario description Given I enter login details – sri Nov 29 '17 at 17:09
  • public class HomePageSteps { @Autowired HomePage homePage; @When("I enter login details") public void enter() { try { homePage.enterLoginDetails(); } catch (Exception e) { e.printStackTrace(System.err); } } @Given("I enter login details") public void enterx() { try { homePage.enterLoginDetails(); } catch (Exception e) { e.printStackTrace(System.err); } } } – sri Nov 29 '17 at 17:10
  • Sorry that i am not understanding how to put the class exactly as java file code. – sri Nov 29 '17 at 17:14
  • 1
    Please open the story file in the editor and make sure there are no spaces or tabulations at the end of the step (after `Given I enter login details`). In the line directly under this step there can not be any spaces or tabulations too, please check it and delete if there are any. Then please run your test and check if it helped. If not, then please show a full log from JBehave. – krokodilko Nov 29 '17 at 18:28
  • I removed the spaces and tried and i am getting the same error again and again. – sri Nov 29 '17 at 20:07
  • stories/HomePage.story) Narrative: As a user I want to perform an action So that I can achieve a business goal Scenario: scenario description Given I enter login details (PENDING) @Given("I enter login details") @Pending public void givenIEnterLoginDetails() { // PENDING } Failed to run story stories/HomePage.story org.jbehave.core.failures.PendingStepsFound: [Given I enter login details] at org.jbehave.core.embedder.PerformableTree$PerformableSteps.generatePendingStepMethods(PerformableTree.java:1127) – sri Nov 29 '17 at 20:08
  • According to this line: `AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(WebJbehaveStories.class);` JBehave is looking for steps only in `WebJbehaveStories` **but not in `HomePageSteps` class**. Please append this class to the constructor, that is: `AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(WebJbehaveStories.class, HomePageSteps.class);` – krokodilko Nov 29 '17 at 20:23
  • I got a new error this time:Error creating bean with name 'homePageSteps': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.bnsfweb.pages.HomePage com.bnsfweb.steps.HomePageSteps.homePage; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.bnsfweb.pages.HomePage] found for dependency: expected at least 1 bean which qualifies as autowire – sri Nov 29 '17 at 20:54
  • The steps classes is not loaded. I am getting trouble in it. – sri Nov 29 '17 at 22:41
  • Add `HomePage` class to `AnnotationConfigApplicationContext(WebJbehaveStories.class, HomePageSteps.class);` as well, this should fix the last problem. – krokodilko Nov 30 '17 at 04:21
  • Hey i have fixed the problem by adding an config.xml where it scans for all the packages. – sri Nov 30 '17 at 14:57
  • If someone is still fighting with this, just make sure that your Step Classes are loaded by ApplicationContect of spring and that you use SpringStepsFactory. I used Spring annotation config in spring boot. – ancab Aug 20 '20 at 12:01

0 Answers0