I'm trying to run my tests in Chrome. I've been using Firefox until now, and with FF it all worked fine. But now I need to switch to Chrome and I came across with a problem of launching the ChromeDriver.
I guess I either have problems with my framework architecture or missing understanding of TestNG. I'm using stack TestNG + WebDriver + PageObject + Java
Classes structure looks like this: classes structure
ConciseAPI - is an abstract class, means its object is created once its child class tries to access helper methods from ConciseAPI. In concise API we get driver instance using in this way:
public abstract WebDriver getWebDriver();
As you can see, method itself isn't described. BaseTest extends ConciseAPI, and BaseTest is a class where WebDriver instance is created and exists. All child classes inherit WebDriver instance and access it through the following method:
@Override
public WebDriver getWebDriver() {
return driver;
}
BasePage.class extends ConciseAPI and accesses driver instance using the completely the same @Override method mentioned above.
It stores webdriver instance in private object. And, of course, it has PageFactory method that is inherited by all child Page classes:
private WebDriver driver;
public BasePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
Now, to the BaseTest.class, where the webdriver instance is created. That's what it looks like when I'm using FirefoxDriver to run tests. Everything works 100% correct:
public class BaseTest extends ConciseAPI {
// ConciseAPI is a public abstract class with basic helper methods, waits and assertions
public static FirefoxDriver driver = new FirefoxDriver();
@BeforeSuite
public void setUp() {
openPage("http://url");
// makes sure page is ready for interactions
elementIsPresent(someElement);
}
//used to make it possible to get WebDriver instance in different classes
@Override
public WebDriver getWebDriver() {
return driver;
}
@AfterSuite
public void tearDown() {
driver.quit();
}
And this is how my BaseTest class looks like when I'm trying to launch ChromeDriver.
public class BaseTest extends ConciseAPI {
private static String driverPath = "path/to/chromedriver";
public static ChromeDriver driver;
@BeforeSuite
public void setUpEnvironment() {
System.setProperty("webdriver.chrome.driver", driverPath);
driver = new ChromeDriver();
openPage("http://url");
// makes sure page is ready for interactions
elementIsPresent(someElement);
}
//if needed, in TestClasses I use getWebdriver.someMethod() instead of driver.someMethod()
@Override
public WebDriver getWebDriver() {
return driver;
}
@AfterSuite
public void tearDown() {
driver.quit();
}
WebDriver instance seems to be created (browser appears on screen), and it is accessed by openPage() method that opens url and maximizes browser window. When test proceeds to a method that has WebElement as an argument (that should be defined in a BasePage.class), I get NullPointerException.
Here's a stack trace:
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) <1 internal call>
at packagename.base.ConciseAPI.elementIsPresent(ConciseAPI.java:58)
// in this class a method is invoked that is accessed from the class below \/\/\/
at packagename.test1.RegularAccLoginTest.logInTest(RegularAccLoginTest.java:19) <16 internal calls>
// error in this class refers to a method accessed from ConciseAPI
// Method has WebElement as an argument
// WebElement is supposed to be found by @FindBy in a BasePage.class, but somehow it doesn't.
// ^^^ structure description at the beginning of the post shows BasePage.class code.
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) <3 Internal calls>
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:74)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:121) <5 internal calls>
What am I doing wrong within my BaseTest.class when I'm trying to launch tests using ChromeDriver? I wouldn't say the problem is in BasePage.class (even though it looks like it is) since it all works correctly with Firefox. But any opinions are greatly appreciated.
UPD: I tried to replace the WebElement that can't be found at BasePage.class with getWebDriver().findElement(By.xpath("xpath_string") and it worked. So there's something about BasePage.class. If I understand it right, for some reason it can't communicate with BaseTest.class.