Inject WebDrivers in TestNG #before test with #guice - java

I am new with configure selenium. Looked for passing drivers find this solution https://stackoverflow.com/a/35101914/7104440 I wonder is possible to #inject many drivers from browsers in this way. Is possible to bind different drivers? I got error with this code:
encom.google.inject.CreationException: Unable to create injector, see the following errors:
1) Binding to null instances is not allowed. Use toProvider(Providers.of(null)) if this is your intended behaviour.
at assecobs.driver.DriverModule.configure(DriverModule.java:31)
2) A binding to org.openqa.selenium.WebDriver was already configured at assecobs.driver.DriverModule.configure(DriverModule.java:31).
at assecobs.driver.DriverModule.configure(DriverModule.java:31)
DriverModule.class
private DriverSetup driverSetup = new DriverSetup();
#BeforeSuite
#Override
public void configure(Binder binder) {
for (BrowserNames browserName : BrowserNames.values()) {
System.out.println(" bind " + browserName.toString());
WebDriver driver = driverSetup.initDriver(browserName.toString());
binder.bind(WebDriver.class).toInstance(driver);
}
}
}
DriverSetup.class
#SneakyThrows
public WebDriver initDriver(String browser) {
if (browser.equalsIgnoreCase("chrome")) {
capabilities = chromeCapabilities();
driver = initChromeDriver(capabilities);
} else if (browser.equalsIgnoreCase("firefox")) {
capabilities = firefoxCapabilities();
driver = initFirefoxDriver(capabilities);
} else if (browser.equalsIgnoreCase("opera")) {
capabilities = operaCapabilities();
driver = initOperaDriver(capabilities);
} else {
capabilities = firefoxCapabilities();
return driver = initFirefoxDriver(capabilities);
}
return driver;
}
ClientTest.class
#Guice(modules = {DriverModule.class})
public class ClientTest extends DriverSetup {
#Inject
WebDriver driver;

I have been using Guice + WebDriver for a while. You can inject webdriver as you have shown in the ClientTest.java.
Check here for the detailed steps. - http://www.testautomationguru.com/selenium-webdriver-dependency-injection-using-guice/

Related

how to make driver as thread safe to run methods of a class in parallel in selenium java

I have 3 test methods using driver from Base class. I tired to run these methods in parallel but getting failures. Reponse to my problem is appreciated. Thanks
Class having 3 test methods
public class TestCases extends BaseClass {
#Test
public void Test1() {
homePage.checkIfElementIsDisplayed(homePage.emailElement);
homePage.checkIfElementIsDisplayed(homePage.passwordElement);
homePage.checkIfElementIsDisplayed(homePage.signInElement);
homePage.emailElement.sendKeys("karteek#gmail.com");
homePage.passwordElement.sendKeys("******");
}
#Test
public void Test2() {
homePage.checkValuesInListGroup();
homePage.checkSecondListItem();
homePage.checkSecondListItemBadgeValue();
}
#Test
public void Test3() throws InterruptedException {
homePage.ScrolltotheElement(homePage.dropDownOption);
homePage.checkDefaultSelectedValue();
homePage.selectOption3();
}
}
Base Class
public class BaseClass {
public WebDriver driver;
public HomePage homePage;
public WebDriver setup() throws IOException {
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(
System.getProperty("user.dir") + "\\src\\main\\resource\\GlobalData.Properties");
prop.load(fis);
String browserName = System.getProperty("browser") != null ? System.getProperty("browser")
: prop.getProperty("browser");
if (browserName.contains("chrome")) {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
}
else if (browserName.contains("edge")) {
WebDriverManager.edgedriver().setup();
driver = new EdgeDriver();
} else if (browserName.contains("firefox")) {
WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
}
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().window().maximize();
return driver;
}
#BeforeMethod
public HomePage LaunchApplication() throws IOException {
driver = setup();
homePage = new HomePage(driver);
homePage.goTo();
return homePage;
}
#AfterMethod
public void tearDown() throws IOException {
driver.close();
}
I tried creating ThreadLocal Class for WebDriver as
ThreadLocal<WebDriver> threadSafeDriver=new ThreadLocal<WebDriver>();
and use this in setup() method of BaseClass by writing
threadSafeDriver.set(driver);
but this didnot really help
Most likely you are using the TestNG framework. One of the differences between JUnit and TestNG is that JUnit creates a new class instance for each test method by default but TestNG creates a single instance for all test methods in the class.
You can see the parallel option in TestNG suite (see docs) but there is no way to force TestNG to create a new instance for each test.
The simplest solution is to switch to JUnit framework. Then the code from the example should work.

java.lang.NullPointerException when using webdriver manager selenium java

While using selenium with java, WebdriverManager is not running and the below code is giving null pointer exception. I have returned the driver at end of class.
I have one ask whether should I keep the Webdriver driver as static or not.
import io.github.bonigarcia.wdm.WebDriverManager;
public class Browserselector {
public WebDriver driver;
public static Properties prop;
public WebDriver initializeDriver() throws IOException {
{
String browserName = "firefox";
System.out.println(browserName);
if (browserName.contains("Chrome")) {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
} else if (browserName.contains("IE")) {
WebDriverManager.iedriver().setup();
driver = new InternetExplorerDriver();
} else if (browserName.contains("FireFox")) {
WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
} else if (browserName.contains("EDGE")) {
WebDriverManager.edgedriver().setup();
driver = new EdgeDriver();
}
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("google.com");
return driver;
}
}
Thanks for your help in advance.
you are trying to start "firefox" - but the if condition checks for "Firefox", if you want to use it like that change the following condition
browserName.contains("FireFox")
into
browserName.equalsIgnoreCase("FireFox")
I recommend you to change the nested if with a "switch" it's more readable and easy to follow/understand
Also, don't use a URL without specifying the protocol
driver.get("https://www.google.com");

#beforetest testng its being ignored for some reason

I am running my Cucumber suite tests with TestNG (Selenium + Java) and getting java.lang.NullPointerException.
I realized the problem is that my #BeforeTest() is being ignored for some reason causing the NullPointer problem.
I am using the TestNG 7.0.0 (but tried to use latest Beta also).
#BeforeTest()
public void setUp() {
driver = Web.createChrome(); // it call a method that has the Chromedriver
}
Web.java
public class Web {
public static WebDriver createChrome() {
System.setProperty("webdriver.chrome.driver", webdriver_path);
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("http://the-internet.herokuapp.com/");
return driver;
}
}
Output
java.lang.NullPointerException
at br.dsanders.steps.steps.accessing_the_Tnternet_herokuapp_com_website(steps.java:62)
at ?.Given accessing the Tnternet.herokuapp.com website(testing.feature:9)
Try like below:
public class steps {
WebDriver driver = null;
public steps() {
this.driver=Web.createChrome();
}
#BeforeMethod()
public void setUp() {
driver.get("http://the-internet.herokuapp.com/");
}
}
Note ClassName here is steps if you have other class name then change the class name and constructor name.
Change the #BeforeTest to #BeforeMethod
Source:
What is the difference between BeforeTest and BeforeMethod in TestNG

Exception: null when setting up Selenium using ThreadLocal and ChromeDriver (Version 75)?

Current setup stored inside my DriverFactory:
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
return webDriver.get();
Currently the following method seems to be failing:
public void loadUrl(String url) {
try {
getDriver().get(url);
System.out.println("Successfully navigated to URL: " + url);
} catch (Exception e) {
System.out.println(e.getStackTrace());
Assert.fail("Unable to navigate to URL: " + url + ", Exception: " + e.getMessage());
}
}
Set driver method:
public final void setDriver(String browser) throws Exception {
String remoteHubUrl = "http://xxx.xxxx.xxx.xxx:4444/wd/hub/";
try {
switch (setBrowserType(browser)) {
case "grid":
DesiredCapabilities capabilities =new DesiredCapabilities();
capabilities.setBrowserName("chrome");
ChromeOptions op = new ChromeOptions();
op.merge(capabilities);
webDriver.set(new RemoteWebDriver(new URL(remoteHubUrl), op));
break;
}
}
Exception Message:
Exception: null
There seems to be no issues when using older versions of chromedriver, any ideas?
Base Step which is used to initialise the driver prior to executing the tests:
#Before
public void setupHook() {
setDriver("grid");
}
The main Issue I see with the above code is that you are trying to instantiate a RemoteWebDriver instance using a ChromeOptions object instead of a DesiredCapabilities object.
RemoteWebDriver requires a DesiredCapabilities (See Selenium code here) which ChromeOptions does not extend or implement. They do both extend AbstractCapabilities so you may just have been getting lucky in the past, but now they have diverged to an extent that they are no longer compatible.
*EDIT*
I would suggest you update your code to do this:
switch (setBrowserType(browser)) {
case "grid":
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("chrome");
webDriver.set(new RemoteWebDriver(new URL(remoteHubUrl),capabilities));
break;
}

WebDriver is not being instantiated in Cucumber tests

I'm trying to instantiate a single instance of WebDriver to use throughout some tests and, in doing so, I may have over complicated. I think I just need to instantiate a static webdriver and then re-use once for each feature file, assuming that's possible.
I'm not clear why the driver is not being instantiated. I am trying to Debug by running from feature file in the IDE (intelliJ). I'm expecting driver to instantiate when Super is called.
Step Defs:
public class FindAHolidayStepDefs extends DriverBase {
private HolidaysHomePage tcHomePage;
private SearchResultsPage searchPage;
#Before //this is the cucumber #Before
public void setup(){
holHomePage = new HolidaysHomePage(driver);
searchPage = new SearchResultsPage(driver);
}
#Given("^I am on the Holidays homepage$")
public void IAmOnTheHolidaysHomepage() {
assertEquals("the wrong page title was displayed !", "Cheap Travel\u00ae : Cheap Holidays & Last Minute Package Deals", holHomePage.getTitle());
} // more step defs below...
PageObject:
public class HolidaysHomePage extends SeleniumBase {
public HolidaysHomePage(WebDriver driver) {
super(driver); //Expecting driver to instantiate here
visit("");
driver.manage().window().maximize();
assertTrue("The Holidays header logo is not present",
isDisplayed(headerLogo));
}
//code...
DriverBase:
public class DriverBase implements Config {
protected WebDriver driver;
#Before //this is the Junit #Before
public void before() throws Throwable {
if (host.equals("localhost")) {
switch (browser) {
case "firefox":
driver = new FirefoxDriver();
break;
case "chrome":
System.setProperty("webdriver.chrome.driver",
System.getProperty("user.dir") + "\\drivers\\chromedriver.exe");
driver = new ChromeDriver();
break;
}
}
}
#After
public void after() {
driver.quit();
}
};
SeleniumBase (just a class with Selenium API methods abstracted out)
public class SeleniumBase implements Config {
public WebDriver driver;
public SeleniumBase(WebDriver driver) {
this.driver = driver;
}
public void visit(String url) {
if (url.contains("http")) {
driver.get(url);
} else {
driver.get(baseUrl + url);
}
}
Config:
public interface Config {
final String baseUrl = System.getProperty("baseUrl", "http://holidaystest.co.uk/");
final String browser = System.getProperty("browser", "chrome");
final String host = System.getProperty("host", "localhost");
}
Based on your code, here are my suggestions:
You do not need to have a DriverBase class as you already created a SeleniumBase class
Move the below driver initialization code to setup() method in FindAHolidayStepDefs
FindAHolidayStepDefs should extend SeleniumBase
if (host.equals("localhost")) {
switch (browser) {
case "firefox":
driver = new FirefoxDriver();
break;
case "chrome":
System.setProperty("webdriver.chrome.driver",
System.getProperty("user.dir") + "\\drivers\\chromedriver.exe");
driver = new ChromeDriver();
break;
}
}

Categories

Resources