FluentLenium / FluentLenium

FluentLenium is a web & mobile automation framework which extends Selenium to write reliable and resilient UI functional tests. This framework is React ready. Written and maintained by people who are automating browser-based tests on a daily basis.
https://fluentlenium.io
Other
877 stars 214 forks source link

Cucumber with Spring issue #786

Open Sonali77 opened 5 years ago

Sonali77 commented 5 years ago

Hi,

Initially we used fluentlenium 3.7.1,cucumber 3.0.2 , Spring 4 (Jdk 1.8) and our cucumber tests(using spring 4) seemed to work fine. Now we upgraded to fluentlenium 3.8.1,cucumber 4.2.6(Keeping back Spring 4 and JDk 1.8) and or cucumber tests (using spring 4) is having the below error-

Expected only one instance, but found too many: [cucumber.runtime.java.spring.SpringFactory@29372, cucumber.runtime.java.fluentlenium.FluentObjectFactory@3b3b2f] More than one Cucumber ObjectFactory was found in the classpath

You probably may have included, for instance, cucumber-spring AND cucumber-guice as part of your dependencies. When this happens, Cucumber falls back to instantiating the DefaultJavaObjectFactory implementation which doesn't provide IoC. In order to enjoy IoC features, please remove the unnecessary dependencies from your classpath.

I tried excluding cucumber-guice in my POM.xml but still i am getting this error. Not sure if some other API also have this as a transitive dependency.

Please let me know, the possible solution for the same.

Regards, Sonali

koryl commented 5 years ago

@Sonali77, thank you for report. Actually, the case is different, because the fluentlenium-cucumber does not use Spring or Guice dependencies at all. I have implemented special ObjectFactory for FL and this is the reason why Cucumber says there are few Object Factories. The FluentObjectFactory was created to handle creating instances and injecting FluentLenium context into step definitions classes. You can check the mentioned class here: https://github.com/FluentLenium/FluentLenium/blob/develop/fluentlenium-cucumber/src/main/java/cucumber/runtime/java/fluentlenium/FluentObjectFactory.java I would like to know, how did you start FluentLenium context for your tests? Did you add Before and After hooks for all you step definition classes?

Sonali77 commented 5 years ago

Basically i am getting this for my Spring related tests. I have defined one step def as below- @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring/api/application-context.xml") public class SpringSystemTestSteps { @Before public void SetupCucumberSpringContext() { //dummy method so cucumber will recognize this class as glue //and use its context configuration }

}

The other step definitions doesn't have the - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring/api/application-context.xml") defined anymore. Its just the tests. I am getting this error.

I also have other stepdefinitions where Before and After hooks defined for all step defs. This error is even present there.

Please let me know, if i need to do something different now.

Sonali77 commented 5 years ago
public class StepDefinition1 extends FluentCucumberTest { 

 @Before("@UISetUp")
    public void beforeScenario(Scenario scenario) {
        this.scenario = scenario;
        super.before(scenario);
    }

    @After("@UISetUp")
    public void teardown(Scenario scenario) {
        if (scenario.isFailed()) {
            try {
                scenario.embed(((TakesScreenshot) getDriver()).getScreenshotAs(OutputType.BYTES), "image/png");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        super.after(scenario);
        super.setWebDriver(null);

    }
}

We have added before and after hooks in all of our step definitions which run UI tests(which uses Fluentlenium).

Additionally, we also have spring related tests, where we initialize spring context with only one step definition class-

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/api/application-context.xml")
public class SpringSystemTestSteps {
    @Before
    public void SetupCucumberSpringContext() {
        //dummy method so cucumber will recognize this class as glue
        //and use its context configuration
    }
}

We use Spring's context for both API testing (doesn't extend FluentCucumberTest) and UI testing (does extend FluentCucumberTest).

koryl commented 5 years ago

Thank you for this input - I will try to find workaround for this matter and back to you with the anwser.

koryl commented 5 years ago

@Sonali77, try to use fluentlenium-core dependency instead of fluentlenium-cucumber. Please chceck example here: https://github.com/koryl/fluentlenium-cucumber-config-example/tree/spring To work correctly, add two new classes:

Your BaseTest should inherit after you.package.FluentCucumberTest. Everything will work as earlier but you have to add before and after hook for each step definition class (as you already did). Let me know if it works for you.

Sonali77 commented 5 years ago

I will test your suggestion and let you know the update.

Just to let you know, we use Spring, Cucumber, Fluentlenium in our project. Also we would like to use Single step definition class with a before and after hook in our project, instead of adding to each step definition class. I work with Rich, who opened the below issue - https://github.com/FluentLenium/FluentLenium/issues/738

We would like to have one step def to have before and after hook, instead of all. Before and After hook in all step definition classes will instance all step definiton files for every scenario regardless if they are used or not within the test.

Sonali77 commented 5 years ago

I tested your suggestion. It works but its the same as fluentlenium 3.7.1 and is not solving the issue if multiple step definition and also need to have my own FluentCucumberTest. So it does not make sense to make an upgrade to fluentlenium 3.8.1.