prashant-ramcharan / courgette-jvm

Multiprocess | Parallel Cucumber-JVM | Parallelize your Java Cucumber tests on a feature level or on a scenario level.
MIT License
130 stars 38 forks source link

Hook debug #358

Closed alikatircio closed 1 year ago

alikatircio commented 1 year ago

Hi,

With courgette, I can't debug to hook class. I'm trying to testNG the browser parameter to step definition. Created static String value for browser name 'browser' in 'DriverManager'

public static String browser;

After that,


@Parameters({ "browser" })
    @BeforeTest
    public void beforeRun(String browser) {
        DriverManager.browser = browser;
        System.out.println(DriverManager.browser);
        System.out.println("Starting Courgette parallel run: " + CourgetteRunInfo.sessionId());

    }

like this, I try to set the value. But when I try to run the chrome driver in the Hook class 'browser' value is null. To understand added breakpoint but is not working for debugging. Test run without stop.

Hook class;

    @Before
    public void InitializeTest(Scenario scenario) throws Throwable {

        System.out.println(DriverManager.browser);
        DriverManager.initializeDriver("");

    }

Maybe my solution is wrong but can you help me?

and directly in the step definition driver is null.

public Step() {

        this.driver = DriverManager.getDriver();
        this.actions = new Actions(driver);-
    }
prashant-ramcharan commented 1 year ago

Hello,

To answer the first question, you will not be able to debug Cucumber tests when running in parallel using Courgette. Courgette runs your tests in a separate Java process and therefore cannot be accessed by your debugger. This is reason why your debugger does not stop at your breakpoints.

Are you setting the static property DriverManager.browser from the Courgette runner?

If so, this wont work because DriverManager.browser will not be accessible from another Java process (i.e. Courgette test runs)

Static variables that are set outside the scope of a test will no be available to Courgette. If you were to set the static property DriverManager.browser from within a Cucumber test then it will be available.

If you need to pass a browser to your test at runtime, you can pass a System property -Dbrowser=chrome to the Courgette runner and access this property from your Cucumber hook.

 @Before
    public void InitializeTest(Scenario scenario) throws Throwable {
        DriverManager.initializeDriver(System.getProperty("browser"));
    }
alikatircio commented 1 year ago

Hi,

Thank you for the answer I found a solution close to your suggestion. I created a hook class and passed to browser parameter to DriverManager and now it is working but I can not work same time chrome and firefox for the same scenario. One of the browsers is working other is just opening. I think I'm doing something wrong. And I have error message why? [Courgette Runner] There was an unexpected error processing the individual Cucumber report files and Courgette was unable to create any reports for this test run.


public class Hook {

    @Before("@Chrome")
    public void setUpChrome(Scenario scenario) throws Throwable {

        DriverManager.setBrowserType("Chrome");
        DriverManager.initializeLocalDriver();
    }

    @Before("@Firefox")
    public void setUpFirefox(Scenario scenario) throws Throwable {

        DriverManager.setBrowserType("Firefox");
        DriverManager.initializeLocalDriver();
    }

@CourgetteOptions(
        plugin = {
                CourgettePlugin.EXTENT_REPORTS
        },

        threads = 10,
        runLevel = CourgetteRunLevel.SCENARIO,
        rerunFailedScenarios = false,
        rerunAttempts = 1,
        testOutput = CourgetteTestOutput.CONSOLE,
        reportTitle = "Ex",
        reportTargetDir = "target",
        cucumberOptions = @CucumberOptions(
                features = "src/test/resources/features",
                glue = "stepdefinitions",
                tags = "@demo1",
                publish = true,
                plugin = {
                        "pretty",
                        "json:build/cucumber-report/cucumber.json",
                        "html:build/cucumber-report/cucumber.html"}
        ))
public class Runner extends TestNGCourgette {

        @BeforeTest
        public static void beforeRun() {
                System.out.println("Starting Courgette parallel run: " + CourgetteRunInfo.sessionId());
        }

        @AfterTest
        public static void afterRun() {
                if (CourgetteRunInfo.testStatistics().hasFailures()) {
                        // do something extra here
                }
        }
}

DriverManager


public static ThreadLocal<WebDriver> driver = new ThreadLocal<>();

    private static String browserType;

    public static void setBrowserType(String browser){

        browserType = browser;
    }

    public static WebDriver getDriver() {

        return driver.get();
    }

    public static void initializeLocalDriver() throws Throwable {

        BrowserType browser = BrowserType.valueOf(browserType);
        try {

            switch (browser) {
                case Firefox:

                    WebDriverManager.firefoxdriver().setup();
                    driver.set(new FirefoxDriver());
                    break;

                default:

                    WebDriverManager.chromedriver().setup();
                    LoggingPreferences logPrefs = new LoggingPreferences();
                    logPrefs.enable( LogType.PERFORMANCE, Level.ALL );
                    ChromeOptions chromeOptions = new ChromeOptions();
//              chromeOptions.addArguments("--headless");
//              chromeOptions.addArguments("--window-size=1440,900");
                    chromeOptions.addArguments("--no-sandbox");
                    chromeOptions.addArguments("--disable-dev-shm-usage");
                    chromeOptions.setCapability("goog:loggingPrefs", logPrefs);
                    chromeOptions.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
                    driver.set(new ChromeDriver(chromeOptions));
                    break;
            }
        }catch (Throwable e){

            e.printStackTrace();
        }
    }
prashant-ramcharan commented 1 year ago

Hello,

I cannot comment as to why your tests are not working for one browser and not the other but you can refer to the example project here for multi browser testing.

https://github.com/prashant-ramcharan/courgette-jvm-selenium

With regards to the [Courgette Runner] There was an unexpected error processing the individual Cucumber report files and Courgette was unable to create any reports for this test run message:

Are you excluding any Jackson dependencies in your project?

alikatircio commented 1 year ago

Hii,

Thank you for your quick response for multi browsers in maven I have to add a line for each browser?

<configuration>
                    <includes>
                        <include>**/suites/ScenarioSuite.class</include>
                    </includes>
                </configuration>

and for the error message I do not exclude Jackson dependencies am I have to?

prashant-ramcharan commented 1 year ago

Hello,

No, you cannot run a single test against 2 browser at the same time. You can only run a single test against 1 browser at a time.

To test a single test against 2 browsers at the same time, you will need to run the test twice (at the same time)

https://github.com/prashant-ramcharan/courgette-jvm-selenium/blob/master/courgette-selenium-testng.sh

You can create a shell script like the one above but with your maven commands

 mvn test -Dbrowser=chrome
 mvn test -Dbrowser=firefox

I do not exclude Jackson dependencies am I have to

No, you should not exclude this, I was wanted to know if you did.

alikatircio commented 1 year ago

Hello,

Thank you I understood. With TestNG XML, it is possible maybe you can add a feature to run with it. And for the error message it's still coming, does it have a solution?

prashant-ramcharan commented 1 year ago

Hello,

Could you please clarify what you mean by adding a feature using TestNG xml to run?

Note: Courgette will only run Cucumber tests and not standard JUnit or TestNG tests.

About the error message, it could be the way your project is setup. This error usually occurs when Courgette attempts to find Cucumber messages / reports that got generated in the parallel run but later is unable too process it because it could be corrupt or missing. (write permission on the OS etc)

Please take a look at the Courgette example projects for reference and try running them to see if you get any errors.

alikatircio commented 1 year ago

Hello,

TestNG XML, as you know if you are using the TestNG framework you can also trigger your scenario with like this XML file. And with XML, I can manage my scenario. At the same time, 4 browsers can run each browser with 2 scenarios total of 8 threads. I just thought maybe this run method can add to courgette-jvm. It's just an idea

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite" data-provider-thread-count="8"
       thread-count="4" parallel="tests">
    <listeners>
        <listener
                class-name="com.oneapi.ta.oneapihub.listeners.TestNGListener"/>
        <listener
                class-name="com.oneapi.ta.oneapihub.listeners.TestFilterListener"/>
    </listeners>

 <test name="Firefox">
        <parameter name="browser" value="firefox"/>
        <classes>
            <class
                    name="com.runner.Runner"/>
        </classes>
    </test>

    <test name="Edge">
        <parameter name="browser" value="edge"/>
        <classes>
            <class
                    name="com.runner.Runner"/>
        </classes>
    </test>

    <test name="Chrome">
        <parameter name="browser" value="chrome"/>
        <classes>
            <class
                    name="com.runner.Runner"/>
        </classes>
    </test>

    <test name="Safari">
         <parameter name="browser" value="safari"/>
         <classes>
             <class
                     name="com.runner.Runner"/>
         </classes>
     </test>

</suite>

I fixed to create a report but now when I try to generate an extent report it has an error

Courgette published your Cucumber Report to:
https://reports.cucumber.io/reports/5d138816-1a1b-4b1d-9842-338292ca30cc
─────────────────────────────────────────────────────────────────────────

Kas 07, 2022 2:13:32 ÖS freemarker.log._JULLoggerFactory$JULLogger error
SEVERE: Error executing FreeMarker template
FreeMarker template error:
Template inclusion failed (for parameter value "partials/exceptıon.ftl"):
Template not found for name "spark/partials/exceptıon.ftl".
The name was interpreted by this TemplateLoader: ClassTemplateLoader(resourceLoaderClass=com.aventstack.extentreports.ExtentReports, basePackagePath="templates/" /* relatively to resourceLoaderClass pkg */).

----
FTL stack trace ("~" means nesting-related):
    - Failed at: #include "partials/${view.toString()}...  [in template "spark/spark.spa.ftl" at line 27, column 36]
----

Java stack trace (for programmers):
----
freemarker.core._MiscTemplateException: [... Exception message was already printed; see it above ...]
    at freemarker.core.Include.accept(Include.java:164)
    at freemarker.core.Environment.visit(Environment.java:370)
    at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:321)
    at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271)
    at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:244)
    at freemarker.core.Environment.visitIteratorBlock(Environment.java:644)
    at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:108)
    at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94)
    at freemarker.core.Environment.visit(Environment.java:334)
    at freemarker.core.Environment.visit(Environment.java:340)
    at freemarker.core.Environment.process(Environment.java:313)
    at freemarker.template.Template.process(Template.java:383)
    at com.aventstack.extentreports.templating.FreemarkerTemplate.processTemplate(FreemarkerTemplate.java:52)
    at com.aventstack.extentreports.templating.FreemarkerTemplate.getSource(FreemarkerTemplate.java:39)
    at com.aventstack.extentreports.templating.FreemarkerTemplate.writeTemplate(FreemarkerTemplate.java:45)
    at com.aventstack.extentreports.reporter.AbstractFileReporter.processTemplate(AbstractFileReporter.java:74)
    at com.aventstack.extentreports.reporter.ExtentSparkReporter.flush(ExtentSparkReporter.java:149)
    at com.aventstack.extentreports.reporter.ExtentSparkReporter.access$100(ExtentSparkReporter.java:27)
    at com.aventstack.extentreports.reporter.ExtentSparkReporter$1.onNext(ExtentSparkReporter.java:121)
    at com.aventstack.extentreports.reporter.ExtentSparkReporter$1.onNext(ExtentSparkReporter.java:113)
    at io.reactivex.rxjava3.subjects.PublishSubject$PublishDisposable.onNext(PublishSubject.java:310)
    at io.reactivex.rxjava3.subjects.PublishSubject.onNext(PublishSubject.java:226)
    at com.aventstack.extentreports.ReactiveSubject.onFlush(ReactiveSubject.java:83)
    at com.aventstack.extentreports.AbstractProcessor.onFlush(AbstractProcessor.java:85)
    at com.aventstack.extentreports.ExtentReports.flush(ExtentReports.java:284)
    at courgette.integration.extentreports.ExtentReportsBuilder.buildReport(ExtentReportsBuilder.java:59)
    at courgette.runtime.CourgetteRunner.createCourgettePluginReports(CourgetteRunner.java:212)
    at courgette.api.testng.TestNGCourgette.parallelRun(TestNGCourgette.java:57)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:134)
    at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:597)
    at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
    at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
    at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:816)
    at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    at org.testng.TestRunner.privateRun(TestRunner.java:766)
    at org.testng.TestRunner.run(TestRunner.java:587)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:384)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337)
    at org.testng.SuiteRunner.run(SuiteRunner.java:286)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1187)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1109)
    at org.testng.TestNG.runSuites(TestNG.java:1039)
    at org.testng.TestNG.run(TestNG.java:1007)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Caused by: freemarker.template.TemplateNotFoundException: Template not found for name "spark/partials/exceptıon.ftl".
The name was interpreted by this TemplateLoader: ClassTemplateLoader(resourceLoaderClass=com.aventstack.extentreports.ExtentReports, basePackagePath="templates/" /* relatively to resourceLoaderClass pkg */).
    at freemarker.template.Configuration.getTemplate(Configuration.java:2869)
    at freemarker.core.Environment.getTemplateForInclusion(Environment.java:2883)
    at freemarker.core.Include.accept(Include.java:162)
    ... 54 more

Kas 07, 2022 2:13:32 ÖS com.aventstack.extentreports.reporter.ExtentSparkReporter flush
SEVERE: An exception occurred
FreeMarker template error:
Template inclusion failed (for parameter value "partials/exceptıon.ftl"):
Template not found for name "spark/partials/exceptıon.ftl".
The name was interpreted by this TemplateLoader: ClassTemplateLoader(resourceLoaderClass=com.aventstack.extentreports.ExtentReports, basePackagePath="templates/" /* relatively to resourceLoaderClass pkg */).

----
FTL stack trace ("~" means nesting-related):
    - Failed at: #include "partials/${view.toString()}...  [in template "spark/spark.spa.ftl" at line 27, column 36]
----

Java stack trace (for programmers):
----
freemarker.core._MiscTemplateException: [... Exception message was already printed; see it above ...]
    at freemarker.core.Include.accept(Include.java:164)
    at freemarker.core.Environment.visit(Environment.java:370)
    at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:321)
    at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271)
    at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:244)
    at freemarker.core.Environment.visitIteratorBlock(Environment.java:644)
    at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:108)
    at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94)
    at freemarker.core.Environment.visit(Environment.java:334)
    at freemarker.core.Environment.visit(Environment.java:340)
    at freemarker.core.Environment.process(Environment.java:313)
    at freemarker.template.Template.process(Template.java:383)
    at com.aventstack.extentreports.templating.FreemarkerTemplate.processTemplate(FreemarkerTemplate.java:52)
    at com.aventstack.extentreports.templating.FreemarkerTemplate.getSource(FreemarkerTemplate.java:39)
    at com.aventstack.extentreports.templating.FreemarkerTemplate.writeTemplate(FreemarkerTemplate.java:45)
    at com.aventstack.extentreports.reporter.AbstractFileReporter.processTemplate(AbstractFileReporter.java:74)
    at com.aventstack.extentreports.reporter.ExtentSparkReporter.flush(ExtentSparkReporter.java:149)
    at com.aventstack.extentreports.reporter.ExtentSparkReporter.access$100(ExtentSparkReporter.java:27)
    at com.aventstack.extentreports.reporter.ExtentSparkReporter$1.onNext(ExtentSparkReporter.java:121)
    at com.aventstack.extentreports.reporter.ExtentSparkReporter$1.onNext(ExtentSparkReporter.java:113)
    at io.reactivex.rxjava3.subjects.PublishSubject$PublishDisposable.onNext(PublishSubject.java:310)
    at io.reactivex.rxjava3.subjects.PublishSubject.onNext(PublishSubject.java:226)
    at com.aventstack.extentreports.ReactiveSubject.onFlush(ReactiveSubject.java:83)
    at com.aventstack.extentreports.AbstractProcessor.onFlush(AbstractProcessor.java:85)
    at com.aventstack.extentreports.ExtentReports.flush(ExtentReports.java:284)
    at courgette.integration.extentreports.ExtentReportsBuilder.buildReport(ExtentReportsBuilder.java:59)
    at courgette.runtime.CourgetteRunner.createCourgettePluginReports(CourgetteRunner.java:212)
    at courgette.api.testng.TestNGCourgette.parallelRun(TestNGCourgette.java:57)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:134)
    at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:597)
    at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
    at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
    at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:816)
    at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    at org.testng.TestRunner.privateRun(TestRunner.java:766)
    at org.testng.TestRunner.run(TestRunner.java:587)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:384)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337)
    at org.testng.SuiteRunner.run(SuiteRunner.java:286)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1187)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1109)
    at org.testng.TestNG.runSuites(TestNG.java:1039)
    at org.testng.TestNG.run(TestNG.java:1007)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Caused by: freemarker.template.TemplateNotFoundException: Template not found for name "spark/partials/exceptıon.ftl".
The name was interpreted by this TemplateLoader: ClassTemplateLoader(resourceLoaderClass=com.aventstack.extentreports.ExtentReports, basePackagePath="templates/" /* relatively to resourceLoaderClass pkg */).
    at freemarker.template.Configuration.getTemplate(Configuration.java:2869)
    at freemarker.core.Environment.getTemplateForInclusion(Environment.java:2883)
    at freemarker.core.Include.accept(Include.java:162)
    ... 54 more
prashant-ramcharan commented 1 year ago

From your console logs, Courgette successfully published your Cucumber report which suggest the tests ran without issues.

This looks like your project and dependencies are out of sync somewhere.

Could you try re-importing your project and dependancies?