Selenium PageObject throws Invocation Target Exception - java

I am trying to create a framework(Selenium+TestNg+java) for a Web app(The environment is MacOs+ChromeDriver and the driver server is in \usr\local\bin) but got stuck in basic structure. I have a class(Driversetup.java) that starts the browser, another one that contains WebElements and methods(ProfileUpdateObjects.java) and the third one containing test methods. Now, when I try to run this TestNG class having just a single method, I get following exception.
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at org.openqa.selenium.support.PageFactory.instantiatePage(PageFactory.java:138).
Below is the code (All the classes are in different packages).
public class ProfileUpdateTest {
#Test(enabled = true, priority = 1)
public void profileUpdate() throws MalformedURLException, InterruptedException, ParseException {
WebDriver driver = DriverSetup.startBrowser("chrome");
ProfileUpdateObjects pu = PageFactory.initElements(driver, ProfileUpdateObjects.class);
pu.navigateProfile();
}
}
The code for ProfileUpdateObject class
public class ProfileUpdateObjects {
WebDriver driver;
public ProfileUpdateObjects(WebDriver cdriver) {
this.driver = cdriver;
}
#FindBy(xpath = " //div[#class='ico-menu']")
private WebElement menu;
#FindBy(xpath = "//a[#title='My Dashboard']")
private WebElement myDashboard;
#FindBy(xpath = " //a[contains(text(),'View Profile')]")
public WebElement profile;
#FindBy(xpath = "//li[contains(text(),'Permanent Address')]")
private WebElement permanentAddress;
#FindBy(xpath = "//li[contains(text(),'Banking Information')]")
private WebElement bankingInformation;
WebDriverWait waitfor = new WebDriverWait(driver, 2000);
public void navigateProfile() throws InterruptedException {
menu.click();
profile.click();
waitfor.until(ExpectedConditions.visibilityOf(permanentAddress));
}
}
DriverSetup.java
public class DriverSetup {
public static WebDriver driver;
public static WebDriver startBrowser(String browserName, String url) {
if (browserName.equalsIgnoreCase("chrome")) {
driver = new ChromeDriver();
}
driver.manage().window().maximize();
driver.get(url);
return driver;
}
}
It is failing in pu.navigateProfile() call. Also, is it true that #FindBy takes more memory compared to driver.find() syntax and besides POM are there any other design principles for Automation framework because most of the resources over Web are one or the other implementation of POM.

Simple solution is to move new WebDriverWait. It should not be instantiated as instance variable.
Instead of:
WebDriverWait waitfor = new WebDriverWait(driver, 2000);
public void navigateProfile() throws InterruptedException {
menu.click();
profile.click();
waitfor.until(ExpectedConditions.visibilityOf(permanentAddress));
}
Use:
public void navigateProfile() {
menu.click();
profile.click();
new WebDriverWait(driver, 2000).until(ExpectedConditions.visibilityOf(permanentAddress));
}
This will solve your issue (Already tested it)

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

NullPointerException when running my test with page factory

I get an exception when I run my test. I am using selenium with page factory. When I run following code ,it will open up the website and fail with exception below. it doesn't perform the HomePage.ClickbtnCookieWarning() in my test case.
Can someone please help me to understand why my code isn't working?
FAILED CONFIGURATION: #BeforeTest SetUp 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.$Proxy5.click(Unknown Source) at
pageObjects.HomePage.ClickLoginLink(HomePage.java:57) at
myaccountsuite.TC1DefaultDeliveryAddDisplay.SetUp(TC1DefaultDeliveryAddDisplay.java:29)
Home Page page object
public class HomePage {
WebDriver driver;
public HomePage (WebDriver driver)
{
this.driver=driver;
}
#FindBy(id="ctl00_header_hdrCookieWarning_btnHideCookieWarning")
WebElement btnCookieWarning;
#FindBy(xpath=".//*#id='ctl00_masterContainerTop_Block_637_LoginView1_ulAnonymous']/li[2]/a")
WebElement LoginLink;
public void ClickbtnCookieWarning()
{
btnCookieWarning.click();
}
public void ClickLoginLink()
{
LoginLink.click();
}
}
Login Page Object
public class login {
WebDriver driver;
public login(WebDriver driver)
{
this.driver = driver;
}
#FindBy(id="ctl00_ContentPlaceHolderMain_container_container_Block_166_lgn1_UserName")
WebElement UserName;
#FindBy(id="ctl00_ContentPlaceHolderMain_container_container_Block_166_lgn1_Password")
WebElement Password;
#FindBy(id="ctl00_ContentPlaceHolderMain_container_container_Block_166_lgn1_LoginButton")
WebElement btn_LogIn;
#FindBy(id="ctl00_ContentPlaceHolderMain_container_container_Block_166_lgn1_txtAccount")
WebElement Account;
#FindBy(id="ctl00_ContentPlaceHolderMain_container_container_Block_166_lgn1_btnHomeBranch_3")
WebElement btn_Continue;
public void userLogin(String uname, String pass, String acc)
{
UserName.sendKeys(uname);
Password.sendKeys(pass);
btn_LogIn.click();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
Account.sendKeys(acc);
btn_LogIn.click();
btn_Continue.click();
}
}
My Test
public class TC1DefaultDeliveryAddDisplay {
public WebDriver driver;
#BeforeTest(alwaysRun = true)
public void SetUp() {
HomePage HomePage = PageFactory.initElements(driver, HomePage.class);
login loginpage = PageFactory.initElements(driver, login.class);
driver = new FirefoxDriver();
driver.get("http://URL/");
HomePage.ClickbtnCookieWarning();
HomePage.ClickLoginLink();
loginpage.userLogin("aa#yahoo.com", "125", "Test");
}
You're getting NullPointerException because you're using WebDriver instance before initialising.
You need to Initialize WebDriver before using this instance as :-
driver = new FirefoxDriver();
HomePage HomePage = PageFactory.initElements(driver, HomePage.class);
Login loginpage =PageFactory.initElements(driver, login.class);
If you want to use WebDriver as singleton which returns single instance for all your test methods you can follow this answer which is exactly you want.
The problem is in each class you are creating new instance of driver. You just need to create one driver instance in you base class where you do your browser setup. Please refer Page Object Model. Once the Driver instance is created you need to use the same in all your classes. Or else it will throw NullPointerException because driver will not have any reference.

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