Reputation: 633
I am trying to run my cucumber tests under different browser, so I have test.xml
(yes, currently just one browser)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="SelfCare" verbose="1" thread-count="1" parallel="tests" configfailurepolicy="continue">
<parameter name="environment" value="TEST" />
<test name="Chrome">
<parameter name="browser" value="chrome" />
<parameter name="width" value="1024" />
<parameter name="height" value="768" />
<classes>
<class name="TestNGRunner">
<methods>
<include name="scenario"/>
</methods>
</class>
</classes>
</test>
</suite>
And this TestNG runner class, I am able to access parameter browser
from this runner class, but I would need to pass this variable(s) to Cucumber where are create instance of browser based on passed variables. So far I use it without TestNG and I'm passing those variables through environment variables, however I assume this won't work if I run tests in parallel on different browsers.
import cucumber.api.CucumberOptions;
import cucumber.api.testng.CucumberFeatureWrapper;
import cucumber.api.testng.PickleEventWrapper;
import cucumber.api.testng.TestNGCucumberRunner;
import org.testng.annotations.*;
@CucumberOptions(
plugin = {"html:target/cucumber-html-report",
"json:target/cucumber.json",
"pretty:target/cucumber-pretty.txt",
"junit:target/cucumber-results.xml"},
strict = true,
extraGlue = {"src/test/resources/Hooks.java"},
features = {"src/test/resources/Header.feature"}
)
public class TestNGRunner {
private TestNGCucumberRunner testNGCucumberRunner;
private String browser;
@BeforeClass(alwaysRun = true)
public void setUpClass() throws Exception {
testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
}
@Parameters("browser")
@BeforeTest
public void beforeSuite(String browser) {
System.out.println("Browser for this test set is " + browser);
this.browser = browser;
}
@Test(groups = "Cucumber", description = "Runs Cucumber Feature", dataProvider = "scenarios")
public void scenario(PickleEventWrapper pickleEvent, CucumberFeatureWrapper cucumberFeature) throws Throwable {
testNGCucumberRunner.runScenario(pickleEvent.getPickleEvent());
}
@DataProvider
public Object[][] scenarios() {
return testNGCucumberRunner.provideScenarios();
}
@AfterClass(alwaysRun = true)
public void tearDownClass() throws Exception {
testNGCucumberRunner.finish();
}
}
Any ideas how to achieve that?
Upvotes: 1
Views: 6679
Reputation: 69
TestNG:
---------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Sauce Demo Cucumber Test Automation">
<parameter name="browser" value="Chrome" />
<test thread-count="2" name="test" parallel="classes">
<classes>
<class name="com.automation.cucumber.runner.ui.SauceDemoRunner" />
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Step definitions base class:
----------------------------
import org.openqa.selenium.WebDriver;
import org.testng.Reporter;
import org.testng.xml.XmlTest;
public class BaseStepDefinition {
WebDriver driver;
XmlTest xmlTest;
public BaseStepDefinition() {
try {
xmlTest = Reporter.getCurrentTestResult().getTestContext().getCurrentXmlTest();
System.out.println(xmlTest.getParameter("browser"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Step definitions class:
--------------------------------
import io.cucumber.java.After;
import io.cucumber.java.en.Given;
public class SauceDemoStepDefinition extends BaseStepDefinition {
@After
public void tearDown() throws Exception {
}
@Given("^User is on login page$")
public void user_is_on_login_page() throws Exception {
}
}
Upvotes: 0
Reputation: 1996
Step 1. Runner Class shall extends AbstractTestNGCucumberTests and implement @Parameters and @BeforeTest annotations.
package com.jacksparrow.automation.suite.runner;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import com.jacksparrow.automation.steps_definitions.functional.BaseSteps;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;
@CucumberOptions(features = "classpath:features/functional/",
glue = {"com.jacksparrow.automation.steps_definitions.functional" },
plugin = { "pretty","json:target/cucumber-json/cucumber.json",
"junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports"},
tags = { "@BAMS_Submitted_State_Guest_User" },
junit ={ "--step-notifications"},
strict = false,
dryRun = false,
monochrome = true)
public class RunCukeTest extends AbstractTestNGCucumberTests {
@Parameters({ "browser" })
@BeforeTest
public static void setUpScenario(String browser) {
BaseSteps.getInstance().getBrowserInstantiation(browser);
}
}
Note - I do have browser implementation method under BaseSteps Class. You can implement as per your need.
Step 2. Below is how we define parameter name and value in TestNG.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="1" name="Test" parallel="classes">
<parameter name="browser" value="chrome" />
<classes>
<class
name="com.jacksparrow.automation.suite.runner.RunCukeTest" />
</classes>
</test>
</suite>
Upvotes: 0
Reputation: 633
Apparently, I can access to parameters from anywher usgin Reporter.getCurrentTestResult().getTestContext().getCurrentXmlTest().getParameter("browser")
Upvotes: 8