1.Creating a page in which declaring driver as RemoteDriver.
2.Calling a function where again I’m declaring a driver as RemoteDriver.
3.Running a test where I’m declaring driver as RemoteDriver.
4.Trying to access the AppiumDriver method in my test method.
I had the similar problem and solved it using the below code.
Public class DriverManager {
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
private static AppiumDriver driver;
private static DesiredCapabilities caps = new DesiredCapabilities();
public void initDriver(String browser){
if (browser.equalsIgnoreCase("chrome")){
caps.setCapability("");
....
....
webDriver.set(driver = new AppiumDriver(new URL("<<.../hub>>"), caps));
}
}
public AppiumDriver getDriver() throws Exception {
return driver;
}
}
Related
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);
}
}
Can you please tell me why the values jsonKeyboard and jsonMouse of null and because of this my actions do not work?
When I try to get my driver like that: driver = DriverFactory.getDriver();
private static WebDriver driver;
public static WebDriver getDriver() {
if (null == driver) {
LOG.info("The driver is null. Attempt to create new instance for webdriver.");
driver = new ChromeDriver();
}
return driver
But if I try to use some wrapper for my driver and get driver like that: driver = new AddLogsForWebDriver(DriverFactory.getDriver());
public class AddLogsForWebDriver implements WebDriver {
private static final CustomLogger LOG = LoggerFactory.getLogger();
private final WebDriver driver;
public AddLogsForWebDriver(WebDriver driver) {
this.driver = driver;
}
#Override
public void get(String url) {
driver.get(url);
LOG.info("The " + url + " was opened.");
}
#Override
public String getCurrentUrl() {
LOG.info("The current url was got.");
return driver.getCurrentUrl();
}
...
}
After that my Actions don't work
Any help would be helpful. Thank you
I have 3 classes - one for page locator, one for page action and the other one as script to execute the function. am getting nullpointer exception in main scripts where the function is called. Can anyone help me out, please!!!!.
The following are the code :
HomePageLocator.page
public class HomePageLocator{
WebDriver driver;
public HomePageLocator(WebDriver driver)
{
this.driver= driver;
}
#FindBy(xpath="//*[#id='header']/div[2]/div/div/nav/div[1]/a")
public WebElement signIn;
}
HomePageAction.page
public class HomePageAction{
public WebDriver driver;
public HomePageLocator homepageor;
public HomePageAction() {
this.homepage = new HomePageLocator(driver);
PageFactory.initElements(driver, this.homepage);
}
public void login() {
homepageor.signIn.click();
}
BaseTestCase.java
public class BaseTestCase {
public static Logger log = Logger.getLogger("devpinoyLogger");
public static void main(String[] args) throws Throwable {
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\\src\\test\\resources\\Executables\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://automationpractice.com/index.php");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
// Home page validation
HomePageAction homepageaction= new HomePageAction();
homepageaction.login();
}
Note : Am getting exception in line (homepageaction.login();)
the following is the exception logs :
Exception in thread "main" java.lang.NullPointerException
at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:69)
at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38)
at com.sun.proxy.$Proxy3.click(Unknown Source)
at com.way2.Pages.actions.HomePage.login(HomePageAction.java:31)
at com.way2.Testcases.BaseTestCase.main(BaseTestCase.java:35)
You are creating the driver in main class, but not passing it to homepageAction
public static void main(String[] args) throws Throwable {
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\\src\\test\\resources\\Executables\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
Try to pass driver as
HomePageAction homepageaction= new HomePageAction(driver);
this.driver =driver
I'm using Cucumber with Java and I'm trying to pass a value to local storage. I'm using also WebDriverManager and when I try to execute some script with JavaScripExecutor, another instance of a browser is opened.
I tried to implement the JavaScriptExecutor in the WebDriverManager but I got the same result as before.
public class WebDriverManager {
private WebDriver driver;
private static DriverType driverType;
private static EnvironmentType environmentType;
private static final String CHROME_DRIVER_PROPERTY = "webdriver.chrome.driver";
private JavascriptExecutor js;
public WebDriverManager() {
driverType = FileReaderManager.getInstance().getConfigReader().getBrowser();
environmentType = FileReaderManager.getInstance().getConfigReader().getEnvironment();
}
public WebDriver getDriver() throws MalformedURLException {
if(driver == null) driver = createDriver();
return driver;
}
public JavascriptExecutor getJavaScriptExecutor() {
js = (JavascriptExecutor) driver;
return js;
}
private WebDriver createDriver() throws MalformedURLException {
switch (environmentType) {
case LOCAL : driver = createLocalDriver();
break;
case REMOTE : driver = createRemoteDriver();
break;
}
return driver;
}
I want to be able to use this executor in the already existing browser instance.
I got some help from a team member and we figured it out already.
public WebDriverManager() throws MalformedURLException {
driverType = FileReaderManager.getInstance().getConfigReader().getBrowser();
environmentType = FileReaderManager.getInstance().getConfigReader().getEnvironment();
driver = createDriver();
}
By passing driver variable to constructor and by creating appropriate constructors in classes I managed to make JavaScriptExecutor use already existing instance of a WebDriver. Example:
JavascriptExecutor js;
public AcceptanceHelper(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, 15);
this.js = (JavascriptExecutor) driver;
}
I have a method called test, where I have defined a Webdriver object like this:
FirefoxProfile firefoxprofile = new FirefoxProfile();
firefoxprofile.setAssumeUntrustedCertificateIssuer(false);
WebDriver driver = new FirefoxDriver(firefoxprofile);
Selenium selenium = new WebDriverBackedSelenium(driver, "https://10.17.17.212:4343");
i can use selenium commands in this function, like
selenium.click() etc.
but I cannot use them in function that I call from this function.
e.g. i call a function called set() (private int set)
inside set
i resolved it by declaring WebDriver variable as static.
in my code it looks like:
public class BaseSeleniumTest extends SeleneseTestBase {
static WebDriver driver;
#BeforeClass
public static void firefoxSetUp() throws MalformedURLException {
driver = new FirefoxDriver();
}
#Before
public void homePageRefresh() throws IOException {
driver.get(propertyKeysLoader("login.base.url"));
}
#AfterClass
public static void closeFirefox(){
driver.quit();
}
....
//blablabla}
Make selenium object outside method and declare it as static so that you could use it globally.