I'm trying to use TestNG and Page Object for my Selenium test. But it fails with java.lang.NullPointerException error at a line where I'm creating new object of my Page Object Class.
public class TestTitle {
#Test
public void scenario1() {
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
WebDriver driver=new ChromeDriver();
FirstPage fp = new FirstPage(driver);
driver.get("https://www.google.com/");
fp.element.click();
}
}
public class FirstPage {
WebDriver driver;
public FirstPage (WebDriver driver) {
this.driver = driver;
}
public WebElement element = driver.findElement(By.id("hptl"));
}
FAILED: scenario1
java.lang.NullPointerException
at Pages.FirstPage.<init>(FirstPage.java:14)
at Test.TestTitle.scenario1(TestTitle.java:15)
FirstPage.java:14 is public WebElement element = driver.findElement(By.id("hptl"));
TestTitle.java:15 is FirstPage fp = new FirstPage(driver);
try this
public class FirstPage {
public WebDriver driver;
public WebElement element;
public FirstPage (WebDriver driver) {
this.driver = driver;
this.element = driver.findElement(By.id("hptl"));
}
}
Related
I would really like to understand why when approaching locating an element the exact same way as previously failing.
NoSuchElementException : Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//span[contains(text(),'Add')]"}
I have also tried to use something like the following but it also failed, so in order for me write a good automation code i need to get my knowledge straight with WebDriverWait, so i would appreciate somebody with knowledge to spend some time on this inquiry.
It does locates if i have xpath like this :
//body/div[#id='root']/div[1]/div[1]/div[1]/div[2]/div[1]/div[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]
public void clickOnAddVehicleButton() {
wait.until(ExpectedConditions.visibilityOf(addVehicleButton));
vehicles.addVehicleButton.click();
}
I am not new into Java but i am new into automation hence some areas of knowledge is missing, i ha
Base class:
public class BasePage {
protected final WebDriver driver;
protected final WebDriverWait wait;
public BasePage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver,5);
PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this);
}
}
The component where that button should be present :
public class Vehicles extends BasePage {
private static Vehicles vehicles;
private Vehicles(WebDriver driver) {
super(driver);
}
#FindBy(xpath = "//span[text(),'Add']")
public WebElement addVehicleButton;
public static Vehicles vehiclesInstance(WebDriver driver) {
return vehicles == null ? vehicles = new Vehicles(driver) : vehicles;
}
public void clickOnAddVehicleButton() {
vehicles.addVehicleButton.click();
}
Function in the service class:
public void addVehicle(String vehicleName, String numberPlate) {
myAccountService.myAccountPage()
.clickOnVehiclesTab();
vehicles.fillInVehicleName(vehicleName)
.fillInVehicleNumberPlate(numberPlate)
.clickOnAddVehicleButton();
}
WebDriverSettings for test :
public class WebDriverSettings {
protected WebDriver driver;
#Before
public void setUp() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
loginToDevEnvironment();
}
And finally my test class where i am calling the service method:
public class VehicleServiceTest extends WebDriverSettings {
private VehiclesService vehiclesService;
#Before
public void setUp(){
super.setUp();
CookieService.cookieServiceInstance(driver).acceptCookies();
HomePageService.homePageServiceInstance(driver).clickOnMyAccountTab();
LoginService.loginServiceInstance(driver).login(loginCorrectData());
HomePageService.homePageServiceInstance(driver).clickOnMyAccount();
vehiclesService = VehiclesService.vehiclesServiceInstance(driver);
}
#Test
public void shouldAddVehicle(){
vehiclesService.addVehicle("test-vehicle","test-test");
Assert.assertEquals(1,vehiclesService.getVehicles().listOfAddedVehicles().size());
}
I have 2 Java classes; Main.java and Methods.java. At Main.java, I initialize the chrome webdriver and I want to use the same webdriver for a method at Methods.java. Below are the codes.
Under Main.java
Methods getMethods = new Methods();
#BeforeTest
public void Setup()
{
System.setProperty("webdriver.chrome.driver", "C:\\...\\chromedriver.exe");
driver = new ChromeDriver();
driver.get(PropertiesConfig.getObject("websiteUrl"));
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#Test
public void TestCase1()
{
getMethods.method1();
}
#AfterTest
public void QuitTC() {
getMethods.QuitTC(); }
Under Methods.java
public void method1 (){
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
….. }
public void QuitTC() {
driver.quit();
}
My question is how do I called the initialize Webdriver from Main.java and used it at Methods.java?
Any help with be appreciated! Thanks!
You can do something like this in a utility class (say TestUtil.java)
private static WebDriver wd;
public static WebDriver getDriver() {
return wd;
}
and then you can use following line to get the webdriver in any of the classes mentioned and work on it
WebDriver driver = TestUtil.getDriver();
Declare a global variable for driver like this :
WebDriver driver = null;
#BeforeTest
public void Setup()
{
System.setProperty("webdriver.chrome.driver", "C:\\...\\chromedriver.exe");
driver = new ChromeDriver();
driver.get(PropertiesConfig.getObject("websiteUrl"));
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
Now, you can call method1 from method class like this :
public class Methods{
public Methods(WebDriver driver){
this.driver = driver;
}
public void method1 (){
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
….. }
}
Now once you create the instance of Methods class, constructor would be called and driver reference could be passed.
Try this
Class1 {
public WebDriver driver = null;
public String baseURL="...";
public void openURL() {
System.setProperty("webdriver.chrome.driver", "D:...\\chromedriver.exe");
driver = new ChromeDriver();
driver.get(baseURL);
}
Class2 extends Class1 {
driver.findElement(....);
}
I want to select and store a dropdown value in one element in a page(java class) and call it from different class.
EX : i am doing like this for all other fields
public class Home_page {
private static WebElement element = null;
public static WebElement txtbox_FirstName(WebDriver driver) {
element = driver.findElement(By.id("u_0_g"));
return element;
}
}
public class Action_createAccount {
private static WebDriver driver = null;
public static void main(String args[]) {
System.setProperty("webdriver.chrome.driver", "E://chromedriver.exe");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
driver.get("https://www.facebook.com/");
Home_page.txtbox_FirstName(driver).sendKeys("Anu");
}
}
and this is working perfectly. I am not able to write code for drop down to work in the same way. Please help
If you want to select birth day, the sample code is here. it may help you.
public class Home_page {
private static WebElement element = null;
public static WebElement txtbox_FirstName(WebDriver driver) {
element = driver.findElement(By.id("u_0_g"));
return element;
}
Public static WebElement dropdown_BirthDay_Day(WebDriver driver){
element = driver.findElement(By.id("day"));
return element;
}
Public static WebElement dropdown_BirthDay_Month(WebDriver driver){
element = driver.findElement(By.id("month"));
return element;
}Public static WebElement dropdown_BirthDay_Year(WebDriver driver){
element = driver.findElement(By.id("year"));
return element;
}
}
public class Action_createAccount {
private static WebDriver driver = null;
public static void main(String args[]) {
System.setProperty("webdriver.chrome.driver", "E://chromedriver.exe");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
driver.get("https://www.facebook.com/");
Home_page.txtbox_FirstName(driver).sendKeys("Anu");
new Select(Home_page.dropdown_BirthDay_Day(driver)).selectByVisibleText("16");
new Select(Home_page.dropdown_BirthDay_Month(driver)).selectByVisibleText("Nov");
new Select(Home_page.dropdown_BirthDay_Year(driver)).selectByVisibleText("1990");
}
}
Best practice to list my Driver instance as static, especially for dual test execution?
Driver factory (Used to setup the driver instance):
public class DriverFactory {
public static WebDriver driver;
protected BasePage basePage;
protected LoginPage loginPage;
public WebDriver getDriver() throws Exception {
try {
ReadConfigFile file = new ReadConfigFile();
String browserName = file.getBrowser();
switch (browserName) {
//firefox setup
case "firefox":
if (null == driver) {
System.setProperty("webdriver.gecko.driver", Constant.GECKO_DRIVER_DIRECTORY);
DesiredCapabilities capabilities=DesiredCapabilities.firefox();
capabilities.setCapability("marionette", true);
driver = new FirefoxDriver();
}
break;
}
}
}
}
Steps class: (Cucumber step class):
public class LoginSteps extends DriverFactory {
#Given("^User navigates to the \"([^\"]*)\" website$")
public void user_navigates_to_the_website(String url) throws Throwable {
BasePage basePage = new BasePage();
basePage.loadUrl(url);
}
}
Base Page(Base page for page objects):
public class BasePage extends DriverFactory {
protected WebDriverWait wait;
protected JavascriptExecutor jsExecutor;
public BasePage() throws IOException {
this.wait = new WebDriverWait(driver, 15);
jsExecutor = ((JavascriptExecutor) driver);
}
}
I have created 2 packages each contains a java class file. The Utility class in 1st package initiates the driver & closes the driver with methods- launchDriver() & closeDriver(). In the 2nd package-Example java class file contains call to these methods. The driver is successfully launched using launchDriver() but when the driver is passed to closeDriver method, the value becomes null...
Please provide a solution.The code is as shown,..
public class Utility {
public static WebDriver driver;
public static String driverpath="E:\\Drivers";
#Test
public static WebDriver launchDriver(final String browser,final String url){
if(browser=="firefox"){
WebDriver driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get(url);
}else if(browser=="chrome"){
System.setProperty("webdriver.chrome.driver", driverpath+"\\chromedriver.exe");
WebDriver driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get(url);
}else if(browser=="ie"){
System.setProperty("webdriver.ie.driver", driverpath+"\\IEDriverServer.exe");
WebDriver driver=new InternetExplorerDriver();
driver.manage().window().maximize();
driver.get(url);
}else{
WebDriver driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get(url);
}
return driver;
}
#Test
public static WebDriver closeDriver(WebDriver driver){
Utility.driver=driver;
driver.quit();
return driver;
}
}
class Example in tests package
public class Example{
#Test
public static void launchConfig(){
Utility.launchDriver("chrome", "https://www.google.com");
//Utility.launchDriver("firefox","www.google.com");
Utility.closeDriver(Utility.driver);
}
}
Create an abstract test class and have your test classes extend that. your abstract test class might look like this:
public abstract class Abstract test {
//delcare driver
public static WebDriver driver;
//Assign the correct driver
#BeforeSuite
public void webdriverSetUp() {
if(browser=="firefox"){
WebDriver driver=new FirefoxDriver();
} else if(browser=="chrome"){
WebDriver driver=new ChromeDriver();
} else if(browser=="ie"){
WebDriver driver=new InternetExplorerDriver();
} else{
WebDriver driver=new FirefoxDriver();
}
}
//call getDriver() in your tests
public static WebDriver getDriver() {
return driver;
}
}
Just dont forget your probably going to want to clear all cookies between test methods.