Selenium - Can't access page object model properties - selenium

I'm using the Boni Garcia 'webdrivermanager'.
https://github.com/bonigarcia/webdrivermanager/blob/master/README.md
My issue:
I'm not able to 'get' my initialized driver properties from 'BaseSwag' to 'home.page' in order to launch Chrome and go to the desired URL. Here is my set up as follows. What can I do to fix this?
src/main/java/swaglogin/BaseSwag
package swaggerLogin;
import io.github.bonigarcia.wdm.WebDriverManager;
import io.github.bonigarcia.wdm.managers.ChromeDriverManager;
import io.github.bonigarcia.wdm.managers.FirefoxDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class BaseSwag {
public WebDriver driver;
public Properties prop;
public WebDriverManager initializeDriver() throws IOException {
// Create global property file
prop = new Properties();
FileInputStream fis = new FileInputStream(
"//Users/rad/WebTest/src/main/resources/data.properties");
prop.load(fis);
String browserName = prop.getProperty("browser");
System.out.println(browserName);
if (browserName.equals("chrome")) {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
} else if (browserName.equals("firefox")) {
WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
}
return driver;
}
}
resources/data.properties
url = http://qaclickacademy.com/
apiKey = 1234563333random
browser = chrome
test/java/home.page
package home.page;
import java.io.IOException;
import org.testng.annotations.BeforeTest;
import swaggerLogin.BaseSwag;
public class SwaggerLoginDev extends BaseSwag {
#BeforeTest
public void initialize() throws IOException {
driver = initializeDriver();
driver.get(prop.getProperty("url"));
}
}
Stack Trace
Error:(32, 12) java: cannot find symbol
symbol: method driver()
location: class resources.Base

Your driver variable should be an instance of WebDriver, not WebDriverManager.
You can consider WebDriverManager as utility class, that only manage (download, setup, etc...) your drivers for different browsers. Once you call .setup() method for the desired type of browser, you can create an instance of it:
public class BaseSwag {
public WebDriver driver;
public Properties prop;
public WebDriver initializeDriver() throws IOException {
// Create global property file
prop = new Properties();
FileInputStream fis = new FileInputStream(
"//Users/rad/WebTest/src/main/resources/data.properties");
prop.load(fis);
String browserName = prop.getProperty("browser");
System.out.println(browserName);
if (browserName.equals("chrome")) {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
} else if (browserName.equals("firefox")) {
WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
}
return driver;
}
}
Now, you should be able to call .get(...) method on your driver.

Related

How to run tests in parallel by classes with TestNG and Selenium with POM Pattern

I am using webdrivermanager with driver call.
But it retains the pom pattern and is difficult to construct in parallel using the threadlocal class.
My module is structured as below.
Some of my code.
Driver class
public class Driver {
public WebDriver setDriver(WebDriver driver, String browser, String lang) throws Exception {
if (browser.contains("Chrome")) {
ChromeOptions options = new ChromeOptions();
WebDriverManager.chromedriver().clearResolutionCache().clearDriverCache().setup();
}
options.addArguments(lang);
driver = new ChromeDriver(options);
Capabilities cap = ((RemoteWebDriver) driver).getCapabilities();
} else {
WebDriverManager.iedriver().clearResolutionCache().clearDriverCache().setup();
}
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
return driver;
}
}
Next Pageclass
public class LoginPage{
private WebDriver driver;
#CacheLookup
#FindBy(id = "j_domain")
public static WebElement domainField;
#CacheLookup
#FindBy(id = "j_username")
public static WebElement usernameField;
#CacheLookup
#FindBy(id = "j_password")
public static WebElement passwordField;
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver,this);
}
}
Next Base testclass :
public class BaseTest {
public WebDriver driver;
public LoginPage loginPage;
#Parameters({"browser"})
#BeforeClass
public void Setup(ITestContext context, String browsertype) throws Exception {
pageFactory.driver.Driver driversetting = new pageFactory.driver.Driver();
driver = driversetting.setDriver(driver, browsertype, "lang=ko_KR");
context.setAttribute("webDriver", driver);
loginPage = new LoginPage(driver);
}
}
Next testclass
public class Remotepc_Center extends BaseTest {
#Test(priority = 1, enabled = true)
public void a1(Method method) throws Exception {
}
}
Using threadlocal I want sessions to be configured independently and tests running in parallel.
You would need to follow the below sugggestions/recommendations in order for you to be able to work with Page Object Model and thread local variables, please do the following:
Make use of a library such as autospawn to handle the webdriver instances backed by thread local variables.
Make sure that you create Page Objects only within your test methods because that's the only place wherein your thread local variables would have a webdriver that can be accessed by the test method as well. Querying the thread local variable for retrieving the webdriver instance from within a configuration method such as #BeforeClass (in the testng world) is going to give you a different thread.
In TestNG context, only a #BeforeMethod, #Test and a #AfterMethod are guaranteed to run in the same thread.
For additional details on how to work with a thread local variable, you can perhaps refer to my blog
For the sake of completeness, including relevant code snippets for the thread local creation.
Define a factory that can create webdriver instances as below
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
class LocalDriverFactory {
static WebDriver createInstance(String browserName) {
WebDriver driver = null;
if (browserName.toLowerCase().contains("firefox")) {
driver = new FirefoxDriver();
return driver;
}
if (browserName.toLowerCase().contains("internet")) {
driver = new InternetExplorerDriver();
return driver;
}
if (browserName.toLowerCase().contains("chrome")) {
driver = new ChromeDriver();
return driver;
}
return driver;
}
}
Define a driver manager class that looks like below:
import org.openqa.selenium.WebDriver;
public class LocalDriverManager {
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
public static WebDriver getDriver() {
return webDriver.get();
}
static void setWebDriver(WebDriver driver) {
webDriver.set(driver);
}
}
Define a TestNG listener that looks like below
import org.openqa.selenium.WebDriver;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;
public class WebDriverListener implements IInvokedMethodListener {
#Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
String browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName");
WebDriver driver = LocalDriverFactory.createInstance(browserName);
LocalDriverManager.setWebDriver(driver);
}
}
#Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
WebDriver driver = LocalDriverManager.getDriver();
if (driver != null) {
driver.quit();
}
}
}
}
A typical test case would now look like below:
import org.testng.annotations.Test;
public class ThreadLocalDemo {
#Test
public void testMethod1() {
invokeBrowser("http://www.ndtv.com");
}
#Test
public void testMethod2() {
invokeBrowser("http://www.facebook.com");
}
private void invokeBrowser(String url) {
System.out.println("Thread " + Thread.currentThread().getId());
System.out.println("HashcodeebDriver instance = " +
LocalDriverManager.getDriver().hashCode());
LocalDriverManager.getDriver().get(url);
}
}

Getting InvalidArgumentException

package trails2110;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class Demo01 {
WebDriver driver;
#Before
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "D:\\Eclipse\\Drivers\\chromedriver.exe");
System.out.println("1");
driver= new ChromeDriver();
System.out.println("2");
}
#After
public void tearDown() throws Exception {
driver.close();
}
#Test
public void test() {
String url= "www.hotstar.com";
System.out.println("3");
driver.get(url);
System.out.println("4");
String Title=driver.getTitle();
System.out.println(Title);
}
}
In Console till 3 its getting printed.
I have latest version of chrome and latest version of chrome driver for it.
i tried with multiple drivers didnt work.
am i missing something?
I am able to route to the url with the following code
System.setProperty("webdriver.chrome.driver", "D:\\Eclipse\\Drivers\\chromedriver.exe");
WebDriver driver= new ChromeDriver();
String url = "https://www.google.com";
String script = "window.location = \'"+url+"\'";
((JavascriptExecutor) driver).executeScript(script);
any reasons its not happening with get() method and happening with JavascriptExecutor ?
You should declare the URL with its protocol. So
String url= "www.hotstar.com";
url = "https://" + url

Where the property key name for the chromedriver has been determined and where it is getting utilized in Selenium?

We usually set the system property for the chromedriver exe using the below code
System.setProperty("webdriver.chrome.driver",path of the chromedriver.exe)
How the property key name is determined as "webdriver.chrome.driver"?
Where the property is utilized in Webdriver wire protocol(Any particular class file for reference)?
Hi i have write utils class for that
You can open browser/navigate url/close browser and etc
package utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
public class TestApp {
private WebDriver driver;
private static TestApp myObj;
// public static WebDriver driver;
utils.PropertyFileReader property = new PropertyFileReader();
public static TestApp getInstance() {
if (myObj == null) {
myObj = new TestApp();
return myObj;
} else {
return myObj;
}
}
//get the selenium driver
public WebDriver getDriver()
{
return driver;
}
//when selenium opens the browsers it will automatically set the web driver
private void setDriver(WebDriver driver) {
this.driver = driver;
}
public static void setMyObj(TestApp myObj) {
TestApp.myObj = myObj;
}
public void openBrowser() {
//String chromeDriverPath = property.getProperty("config", "chrome.driver.path");
//String chromeDriverPath = property.getProperty("config", getChromeDriverFilePath());
System.setProperty("webdriver.chrome.driver", getChromeDriverFilePath());
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-notifications");
options.addArguments("disable-infobars");
driver = new ChromeDriver(options);
driver.manage().window().maximize();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void navigateToURL() {
String url =property.getProperty("config","url");
driver.get(url);
}
public void closeBrowser()
{
driver.quit();
}
public WebElement waitForElement(By locator, int timeout)
{
WebElement element = new WebDriverWait(TestApp.getInstance().getDriver(), timeout).until
(ExpectedConditions.presenceOfElementLocated(locator));
return element;
}
private String getChromeDriverFilePath()
{
// checking resources file for chrome driver in side main resources
URL res = getClass().getClassLoader().getResource("chromedriver.exe");
File file = null;
try {
file = Paths.get(res.toURI()).toFile();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return file.getAbsolutePath();
}
}
enter code here

Getting NullPointerException when trying to access Selenium Webdriver instance in below scenario.

I am trying to create a framework where I can run my test cases(test tags in xml file) in parallel in different browsers. I have tried using all combinations of testNG annotations but after reading a blog came to know that this can only be achieved by using testNg listners. I am using ThreadLocal to keep my driver thread-safe. I am getting null pointer exception when trying to access Webdriver in my test cases class in line LocalDriverManager.getDriver().get(url);
This is LocalBrowserFactory.Class
package BrowserFactory;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import DataProvider.ConfigDataProvider;
public class LocalDriverFactory {
public static WebDriver createInstance(String browserName) {
WebDriver driver = null;
ConfigDataProvider config=new ConfigDataProvider();
if (browserName.toLowerCase().contains("firefox")) {
System.setProperty("webdriver.gecko.driver", config.getgeckoPath());
driver = new FirefoxDriver();
}
if (browserName.toLowerCase().contains("internet")) {
driver = new InternetExplorerDriver();
}
if (browserName.toLowerCase().contains("chrome")) {
System.setProperty("webdriver.chrome.driver", config.getchromePath());
driver = new ChromeDriver();
}
driver.manage().window().maximize();
return driver;
}
}
This is my LocalDriverManager.class
package BrowserFactory;
import org.openqa.selenium.WebDriver;
public class LocalDriverManager {
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
public static WebDriver getDriver() {
return webDriver.get();
}
public static void setWebDriver(WebDriver driver) {
webDriver.set(driver);
}
}
This is my ConfigPropertyReader.class
package DataProvider;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
public class ConfigDataProvider {
static Properties p;
public ConfigDataProvider()
{
File f =new File("C:/Eclipse/parallelframework/configuration/config.properties");
try {
FileInputStream fis = new FileInputStream(f);
p=new Properties();
p.load(fis);
}
catch (Exception e)
{
System.out.println("Custom Exception- cannot load properties file"+e.getMessage());
}
}
public String getvalue(String key)
{
return p.getProperty(key);
}
public String getUrl()
{
return p.getProperty("url");
}
public String getchromePath()
{
return p.getProperty("chromepath");
}
public String getgeckoPath()
{
return p.getProperty("firefoxpath");
}
public String getIEPath()
{
return System.getProperty("User.dir")+p.getProperty("IEPath");
}
}
This is WebDriverListner.class
package Listners;
import org.openqa.selenium.WebDriver;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;
import BrowserFactory.LocalDriverFactory;
import BrowserFactory.LocalDriverManager;
public class WebDriverListner implements IInvokedMethodListener {
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
String browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName");
System.out.println(browserName);
WebDriver driver = LocalDriverFactory.createInstance(browserName);
LocalDriverManager.setWebDriver(driver);
System.out.println("Driver Set");
}
}
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
WebDriver driver = LocalDriverManager.getDriver();
if (driver != null) {
driver.quit();
}
}
}
}
This is my sample testcase.class
package tests;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
import BrowserFactory.LocalDriverManager;
public class sampleTest {
#Test
public void testMethod1() {
invokeBrowser("http://www.ndtv.com");
}
#Test
public void testMethod2() {
invokeBrowser("http://www.facebook.com");
}
private void invokeBrowser(String url) {
LocalDriverManager.getDriver().get(url);
}
}
Your Listener code is messed up. You basically have the beforeInvocation and afterInvocation in the wrong order.
Here's how it should have looked like
import org.openqa.selenium.WebDriver;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;
public class WebDriverListener implements IInvokedMethodListener {
#Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
String browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName");
WebDriver driver = LocalDriverFactory.createInstance(browserName);
LocalDriverManager.setWebDriver(driver);
}
}
#Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
WebDriver driver = LocalDriverManager.getDriver();
if (driver != null) {
driver.quit();
}
}
}
}
You basically would setup the webdriver into the thread local variable (push the webdriver instance into the thread local variable's context) from within the beforeInvocation and then within your afterInvocation method, you would pop it out and clean up the webdriver instance (by calling quit() ). In your case, your code is doing the opposite.
For more details you can refer to my blog post here.

Facing NullPointerException in Selenium

I have created three files: one is index file, other is configuration file and last the last one is the property file. While executing the code I'm getting NULLPointerException.
I am not able to solve this issue. Please help me to rectify this code.
index.java:
package main;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;
import config.Configuration;
public class Index
{
WebDriver driver;
#Test(priority = 1)
public void handling_multiple_windows() throws Exception
{
Configuration obj = new Configuration();
System.setProperty("webdriver.chrome.driver", obj.path());
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get(obj.handling_window_url());
}
}
Configuration.java:
package config;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import org.openqa.selenium.WebDriver;
public class Configuration
{
Properties pro;
WebDriver driver;
public Configuration() throws Exception
{
File f = new File("./Config/config.property");
FileInputStream fis = new FileInputStream(f);
Properties pro = new Properties();
pro.load(fis);
}
public String path()
{
String url = pro.getProperty("ChromeDriverPath");
return url;
}
public String handling_window_url()
{
return pro.getProperty("URL");
}
}
config.property:
ChromeDriverPath = G:\\Selenium Webdriver\\chromedriver\\chromedriver.exe
URL = https://www.naukri.com
The reason you get a NullPointerException is because in the Configuration.java Class you have declared Properties pro; globally but again within the Configuration() constructor you have again initiated another instance of Properties as Properties pro = new Properties();. Hence the NullPointerException.
Change the line:
Properties pro = new Properties();
to:
pro = new Properties();
Your code will work fine.
Remove Properties from Properties pro = new Properties(); from this code and make it:
pro = new Properties();
You already declare it above, so need to declare it again