I am getting "java.lang.NullPointerException" when I am trying to execute my test case based on POM.
The class BrowserFactory lets me choose a browser, the class Flipkart_Login based on POM stores all the element of that particular page and has a method for Valid_Login()
and finally Test_Flipkart_Login class - calls the Valid_Login() method for executon but when I try to execute this class, I get java.lang.NullPointerException.
Kindly advise!
FAILED: Flipkart_Login_Test
java.lang.NullPointerException
at DataProviders.ConfigDataProvider.getURL(ConfigDataProvider.java:31)
at TestCases.Test_Flipkart_Login.Flipkart_Login_Test(Test_Flipkart_Login.java:19)
public class ConfigDataProvider
{
static Properties pro;
public ConfigDataProvider()
{
File src = new File("C:\\Data\\Bimlesh\\Flipkart_HybridFramework\\Flipkart.Hybrid.FrameworkComplete\\Configuration\\Config.Properties");
try
{
FileInputStream fis = new FileInputStream(src);
pro = new Properties();
pro.load(fis);
} catch (Exception e)
{
System.out.println("The Config exception is :"+e.getMessage());
}
}
public static String getURL()
{
String URL = pro.getProperty("URL");
return URL;
}
public static String ChromePath()
{
String Chrome = pro.getProperty("Chromepath");
return Chrome;
}
public static String IEPath()
{
String IE = pro.getProperty("IEpath");
return IE;
}
}
public class BrowserFactory
{
static WebDriver driver;
public static WebDriver getBrowser(String BrowserName)
{
if(BrowserName.equalsIgnoreCase("Firefox"))
{
driver = new FirefoxDriver();
}
else if(BrowserName.equalsIgnoreCase("Chrome"))
{
System.setProperty("webdriver.chrome.driver", ConfigDataProvider.ChromePath());
driver = new ChromeDriver();
}
else if(BrowserName.equalsIgnoreCase("IE"))
{
System.setProperty("webdriver.ie.driver", ConfigDataProvider.IEPath());
driver = new InternetExplorerDriver();
}
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
return driver;
}
public void ShutDown(WebDriver driver)
{
driver.quit();
}
}
public class Flipkart_Login
{
WebDriver driver;
public Flipkart_Login(WebDriver driver)
{
this.driver=driver;
}
#FindBy(xpath="//a[text()='Log In']") WebElement Login_Click;
#FindBy(xpath="//input[#class='_2zrpKA' and #type='text']") WebElement Enter_Email;
#FindBy(xpath="//input[#class='_2zrpKA _3v41xv' and #type='password']") WebElement Enter_Pass;
#FindBy(xpath="//button[#type='submit' and #class='_3zLR9i _1LctnI _36SmAs']") WebElement Login_Button;
public void Valid_Login()
{
Login_Click.click();
Enter_Email.sendKeys("xxx#gmail.com");
Enter_Pass.sendKeys("xxx");
Login_Button.click();
}
}
public class Test_Flipkart_Login
{
WebDriver driver;
#Test
public void Flipkart_Login_Test()
{
driver = BrowserFactory.getBrowser("Firefox");
driver.get(ConfigDataProvider.getURL());
Flipkart_Login page1 = PageFactory.initElements(driver, Flipkart_Login.class);
page1.Valid_Login();
}
}
You have initialized Properties pro in the constructor of the COnfigDataProider but you are using a static call to getURL method from your test class. Thus pro will be null and not initialized. Remove static call and use the constructor or make pro to static and initialize in static block.
Related
I am running a test case using pagefactory method and have created an appium driver. I'm trying to initialising a page using pagefactory class like this:
The test class:
public class VerifyValidLogin {
#Test
public void CheckValidUser() throws MalformedURLException {
AppiumDriver driver = DeviceFactory.CreateDriver();
login login_page = PageFactory.initElements(driver, login.class);
}
}
DeviceFactory class:
public class DeviceFactory {
public static AppiumDriver<MobileElement> driver;
public static AppiumDriver CreateDriver() throws MalformedURLException {
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability( capabilityName: 'deviceName', value: 'Something');
...
URL url = new URL("http://127.0.0.1:4723/wd/hub");
driver = new AppiumDriver<MobileElement>(url,cap);
System.out.print("Application started");
return driver;
}
}
Login class has element locators:
public class login {
AppiumDriver driver;
public login(AppiumDriver ldriver)
{
this.driver=ldriver;
}
#FindBy(how = How.XPATH,using ="xpath");
MobileElement SignInButton;
}
But i'm not sure where i am doing wrong.
The error is
java.lang.RuntimeException: java.lang.InstantiationException: com.Demo.pages.login
at org.openqa.selenium.support.PageFactory.instantiatePage(PageFactory.java:134)
at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:64)
at com.Demo.Testcases.VerifyValidLogin.CheckValidUser(VerifyValidLogin.java:18)
...
I am new to the automation testing so i'm not able to properly understand the error. Let me know if you need more details.
Initialise elements in constructor
public login(AppiumDriver ldriver)
{
this.driver=ldriver;
PageFactory.initElements(ldriver,this);
}
Please let me know how to read properties file in device farm, since following code is not working. I have looked into various solutions but still device farm is not able to recognize properties file, although this code works fine locally
public abstract class AndroidCapabilities {
// protected static AppiumDriver<MobileElement> driver;
public static ExtentHtmlReporter reporter;
public static ExtentReports extent;
public static ExtentTest logger1;
// #Parameters("browser")
// #BeforeSuite
// public void setUp() throws MalformedURLException {
public static AndroidDriver<MobileElement> driver;
public abstract String getName();
#BeforeTest
public abstract void setUpPage();
#BeforeSuite
public void setUpAppium() throws MalformedURLException {
DesiredCapabilities capabilities = new DesiredCapabilities();
// capabilities.setCapability("device", "Android");
// capabilities.setCapability("platformName", "Android");
// capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome");
final String URL_STRING = "http://127.0.0.1:4723/wd/hub";
URL url = new URL(URL_STRING);
// Use a empty DesiredCapabilities object
driver = new AndroidDriver<MobileElement>(url, capabilities);
// Use a higher value if your mobile elements take time to show up
driver.manage().timeouts().implicitlyWait(35, TimeUnit.SECONDS);
}
public static Properties properties;
static {
properties = new Properties();
FileInputStream fis;
InputStream input;
try {
// fis = new FileInputStream(System.getProperty("user.dir") +
// "//src//test//resources//Properties//Android_OR.properties");
fis = (FileInputStream) Thread.currentThread().getContextClassLoader()
.getResourceAsStream("//Properties//Android_OR.properties");
System.out.println(properties.getProperty("url"));
properties.load(fis);
} catch (IOException e) {
e.printStackTrace();
}
}
#BeforeTest
public void createReport() {
reporter = new ExtentHtmlReporter("./extent.html");
extent = new ExtentReports();
extent.attachReporter(reporter);
}
#AfterTest
public void flush() throws IOException {
extent.flush();
// reporter.setAppendExisting(true);
}
#AfterSuite
public void closeApplication() {
driver.quit();
Reporter.log("===Session End===", true);
}
}
Faced the same issue. Instead of using System.getProperty, try this:
// pass fileName as "Android_OR.properties"
public Properties loadProperty(String fileName) {
Properties prop = new Properties();
try (InputStream input = Base.class.getClassLoader().getResourceAsStream(filePath)) {
if (input == null) {
System.out.println("Sorry, unable to find config.properties");
return prop;
}
// load a properties file from class path, inside static method
prop.load(input);
} catch (IOException ex) {
ex.printStackTrace();
}
return prop;
}
I did a basic project to training about Page Objects using selenium WebDriver with java and Junit. So, I make a page object class and Junit class too. I Make a call of method and pass the parameters to method but, the eclipse show a message that say: java.lang.NullPointerException
public class LogarBkoMaisPage {
static WebDriver driver;
By campoNome = By.id("matricula_I");
By campoSenha = By.id("senha_I");
By btnLogin = By.id("bt_entrar");
public LogarBkoMaisPage(WebDriver driver) {
this.driver = driver;
}
public void logar(String usuario, String senha) {
driver.findElement(campoNome).sendKeys(usuario);
driver.findElement(campoSenha).sendKeys(senha);
driver.findElement(btnLogin).click();
}
}
public class LogarBkoMaisTest {
static WebDriver driver;
#Before
public void setUp() throws Exception {
SelecionarNavegador nav = new SelecionarNavegador();
nav.iniciarNavegador("ie","http://10.5.9.45/BkoMais_Selenium/");
}
#Test
public void logarAplicacao() {
try {
LogarBkoMaisPage login = new LogarBkoMaisPage(driver);
login.logar("844502","Bcc201707");
}catch(Exception e) {
System.out.println("Mensagem de erro: " +e);
}
}
#After
public void tearDown() throws Exception {
}
}
public class SelecionarNavegador {
static WebDriver driver;
public static WebDriver iniciarNavegador(String nomeNavegador, String url) {
if(nomeNavegador.equalsIgnoreCase("firefox")) {
System.setProperty("webdriver.gecko.driver", "E:\\workspace_BCC_QA_BKOMAIS\\"
+ "FireFoxGeckodriver64\\geckodriver.exe");
driver = new FirefoxDriver();
}
else if(nomeNavegador.equalsIgnoreCase("chrome")){
System.setProperty("webdriver.chrome.driver", "E:\\workspace_BCC_QA_BKOMAIS"
+ "\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
}else if(nomeNavegador.equalsIgnoreCase("IE")) {
System.setProperty("webdriver.ie.driver", "E:\\workspace_BCC_QA_BKOMAIS"
+ "\\IE Plugin\\IEDriverServer.exe");
driver = new InternetExplorerDriver();
}
driver.manage().window().maximize();
driver.get(url);
return driver;
}
}
Exception:
You are getting a null pointer exception because iniciarNavegador method inside SelecionarNavegador class is the one which initializes the driver and it returns the driver which has to be assigned to a vairable. You need to do this in your setUp()method
#Before
public void setUp() throws Exception {
SelecionarNavegador nav = new SelecionarNavegador();
driver=nav.iniciarNavegador("ie","http://10.5.9.45/BkoMais_Selenium/");
}
While automating cross browser test, I used the driver in both main and sub method. It is showing syntax error in the line "System.setProperty("webdriver.chrome.driver","D:\chromedriver_win32"
Thanks
import org.openqa.selenium.chrome.ChromeDriver;
public class MyClass {
System.setProperty("webdriver.chrome.driver","D:\\chromedriver_win32\\chromedriver.exe");
static WebDriver driver = new ChromeDriver();
public static void main(String[] args) throws IO Exception {
driver.findElement(By.id("aaa")).clear();
-do-
String B = new MyClass().gettext("eeee");
}
driver.quit();
}
public String getIframe(String id) {
driver.findElement(By.id("ddd")).clear();
-do-
return A;
}
}
I resolved it by modifying the code as below:
import org.openqa.selenium.chrome.ChromeDriver;
public class MyClass {
static Webdriver driver;
public static void main(String[] args) throws IO Exception {
System.setProperty("webdriver.chrome.driver","D:\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
driver.findElement(By.id("aaa")).clear();
-do-
String B = new MyClass().gettext("eeee");
}
driver.quit();
}
public String getIframe(String id) {
driver.findElement(By.id("ddd")).clear();
-do-
return A;
}
}
So Simple!!!
I'm looking for solution how to get page object relative to another object in Page Object Model for selenium webdriver
Code of my test:
class StartPage {
WebDriver driver;
public HomePage(driver) {
this.driver = driver;
}
#FindBy(xpath="//div[#class='widget']//a[text()='link text']")
WebElement linkInWidget;
public void clickLink() {
linkInWidget.click();
return PageFactory.initElements(driver, NextPage.class);
}
}
Next page
class NextPage {
WebDriver driver;
public HomePage(driver) {
this.driver = driver;
}
#FindBy(xpath="//div[#class='widget']//input[#type='button']")
WebElement buttonInWidget;
#FindBy(id = "Index")
WebElement index;
public void clickButton() {
buttonInWidget.click();
return PageFactory.initElements(driver, NextPage.class);
}
public String getText() {
return index.getText();
}
}
Configuration class
public class ConfigureTest{
protected WebDriver driver;
protected String baseUrl;
protected StartPage startPage;
protected NextPage nextPage ;
#BeforeSuite
public void setUp() {
baseUrl = "http://webapp.com/";
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#AfterSuite
public void tearDown() throws Exception {
driver.quit();
}
}
And class of my test
public class SomeTest extends ConfigureTest {
#Test
public void testLinkAndButton() throws Exception {
startPage = PageFactory.initElements(driver, SomePage.class);
driver.get(baseUrl);
nextPage = startPage.clickLink();
nextPage.clickButton();
String data = nextPage.getText();
}
}
In both classes FirstPage and NextPage i find elements by xpath which has same first part //div[#class='widget'] it mean that all elements like buttons and links are under this widget and i have same xpath for widgets in my all pages
Problem: if only xpath of my widget will be changed i must make changes in all page objects of my test
Question: Is in any way how to improve my test for more flexibility with usage like:
page().get(Widget.class, "Widget name").get(Button.class, "Button name").click
Update: I resolve part of this problem in such way:
I create classes of my UI elements with get methods which can return objects of any class:
Class of Widget object
public class widget{
WebDriver driver;
public widget (WebDriver driver) {
this.driver = driver;
}
// Find a single element
#FindBy(xpath="//div[#class='tsf-p']")
WebElement linkInWidget;
public void click() {
linkInWidget.click();
}
public <T> T get(Class<T> expectedPage, String uiclass){
return PageFactory.initElements(driver, expectedPage);
}
}
Class of Button object
public class Button {
WebDriver driver;
public Button (WebDriver driver) {
this.driver = driver;
}
#FindBy(name="btnG")
WebElement button;
public void click() {
button.click();
}
public <T> T get(Class<T> expectedPage){
return PageFactory.initElements(driver, expectedPage);
}
}
Class of HomePage
public class HomePage {
WebDriver driver;
public HomePage(WebDriver driver) {
this.driver = driver;
}
#FindBy(xpath="//div[#class='widget']//a[text()='']")
WebElement linkInWidget;
public void click() {
linkInWidget.click();
}
public <T> T get(Class<T> expectedPage, String name){
return PageFactory.initElements(driver, expectedPage);
}
}
My test
public class searchTest {
WebDriver driver;
#BeforeTest
public void setup() {
driver = new FirefoxDriver();
driver.get("https://www.google.com.ua/");
}
#Test
public void testUI() {
HomePage homePage = PageFactory.initElements(driver, HomePage.class);
widget widget = PageFactory.initElements(driver, widget.class);
homePage.get(widget.class).get(Input.class).setValue("yahoo");
homePage.get(widget.class).get(Button.class).click();
}
}
And a result is that we can compose any object by using our classes
homePage.get(widget.class).get(Input.class).setValue("yahoo");
But how to get element by it name or number for example:
homePage.get(widget.class, "Name").get(Input.class, 1).setValue("yahoo");
I have a public repository here where I have implemented PageObject and PageFactory concept with TestNG. You are probably looking for a better way to inherit BaseClasse. The common methods should be placed in BaseClass and available to all PageObjects through inheritance. I have everything placed in GitHub and it's too broad to implement here.