Null Pointer Exception while Using PageFactory Design Pattern

Hi,
I am trying to use PageFactoty Design Pattern but getting Null Pointer Exception.
Please suggest any improvement required.

public DriverCapabilities() throws IOException{

	URL url;
	try {

		DesiredCapabilities caps = new DesiredCapabilities();
		caps.setCapability("newCommandTimeout", "90");
		caps.setCapability("browserName", "");

		
			caps.setCapability("appActivity",Config.appActivity );
			caps.setCapability("appPackage", Config.appPackage);
			caps.setCapability("appWaitActivity",Config.appWaitActivity);
			caps.setCapability("platformName", "Android");
			caps.setCapability("platformVersion", "5.0");
			caps.setCapability("deviceName", "Android Emulator");
		}

		
		caps.setCapability("app", Config.path);

		caps.setCapability("appium-version", "1.3.7.2");
		url = new URL("http://127.0.0.1:4723/wd/hub");

		

		innerDriver = Config.os.equalsIgnoreCase("ANDROID")? new AndroidDriver(url, caps): new IOSDriver(url, caps);
		DriverWait.implicitWait();
		PageFactory.initElements(new AppiumFieldDecorator(innerDriver, 5, TimeUnit.SECONDS), this);
	}

Sample Screen Class:
public class DemoScreen{
@AndroidFindBy(id = “eula_accept”)
private static RemoteWebElement eula;

public static void submit() throws IOException{

	 init.getInstance(); //To initialize the driver
	 getEula().click();
}
public static WebElement getEula() {
	return eula;
}

}
Sample Test code

public class Demo1{
@Test(groups={“smokeTest”})
public void test1() throws IOException {
DemoScreen.submit();
}

I’m getting below error:

java.lang.NullPointerException
at automation.screens.DemoScreen.submit(DemoScreen.java:36)
at automation.scripts.Demo1.test1(Demo1.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)

I have already tried with RemoteWebElement, WebElement and MobileElement for PageFactory.initElements

Try AjaxElementLocatorFactory factory = new AjaxElementLocatorFactory(this.driver,30);

driver = android driver

Thanks for the prompt reply.
I tried your workaround but got the same error

  1. create abstract Page:

public abstract class Page {
public Page(WebDriver driver) {
this.driver = driver;
}
}

  1. update your Page:

public class DemoScreen extends Page{

@AndroidFindBy(id = “eula_accept”)
private WebElement eula;

public DemoScreen(WebDriver driver) {
super(driver);
PageFactory.initElements(new AppiumFieldDecorator(driver,Integer.parseInt(10,TimeUnit.SECONDS), this);
}

public void submit() {
getEula().click();
}
public WebElement getEula() {
return eula;
}
}

  1. do your test like:

public class Demo1{
@Test(groups={“smokeTest”})
public void test1() throws IOException {
DemoScreen demoscreen;
demoscreen = new DemoScreen(driver);
demoScreen.submit();
}
}

  1. add Before test e.g. here to start driver:

@BeforeMethod(alwaysRun=true)
public void beforeMethod() throws Exception {
// fill here your capatibilities
driver = new AndroidDriver(new URL(“http://0.0.0.0:4725/wd/hub”), capabilities);
}

In Page abstract class we need not have to declare WebDriver instance? inside constructor u asked to call this.driver = driver

yes. add “protected WebDriver driver;”. just fogotten to add

1 Like

Hey Thanks… It worked.
But why it is necessary to add abstract class and instantiate driver object there?
Also, AppiumDriver functions are not exposed by using WebDriver. Like swipe(),scroll,TouchActions.
Instead all WebDriver functions are exposed. I tried passing AppiumDriver instead of WebDriver, code works well but still WebDriver specific in-built functions are accessible not AppiumDriver

  1. Abstract just enhance functionality. you may add many code here instead of each page.
  2. to use specific driver do: ((IOSDriver) driver). or ((AndroidDriver) driver.

Yes… still appium specific methods are not getting exposed

write code and what you are expecting

https://github.com/priyankshah217/AppiumTestAutomation, Please find above project with PageFactory implementation with Appium.

Thanks… It did helped

Getting same exception even after creating abstract class

I am using
java-client - 5.0.4
Appium - 1.7.2

Abstract class -

public abstract class object {
public static final String appPkgName = “com.test.test”;
public AndroidDriver<?> driver;

public object(AndroidDriver<?> driver) {
	this.driver = driver;
}
public void loadPage(){
	PageFactory.initElements(new AppiumFieldDecorator(driver), this);		
}

}

public class LoginPage extends object{
	private static final Logger log = Logger.getLogger(LoginPage.class.getName());
	
	@AndroidFindBy(xpath="//android.widget.Button[@text='test']")
	WebElement BtnID;
	@AndroidFindBy(id = appPkgName + ":id/login_username")
	WebElement inputUserName;
	@AndroidFindBy(id= appPkgName + "id/logikn_password")
	WebElement inputPassword;
	@AndroidFindBy(xpath="//android.widget.Button[@text='Sign In']")
	WebElement BtnSignIn;

	public LoginPage(AndroidDriver driver ){
		super(driver);
		loadPage();
	}
	
	public void login(String email,String pass) throws InterruptedException {
		System.out.println(BtnID.getText());
		BtnJioID.click();
		Thread.sleep(1000);
		System.out.println(BtnID.getSize());
		BtnID.click();
		inputUserName.sendKeys(email);
		inputPassword.sendKeys(pass);
		driver.navigate().back();
		BtnSignIn.click();
	}
}

Test

public class Login extends TestBase{
	private static final Logger log = Logger.getLogger(Login.class);
	public static AndroidDriver driver;
	static LoginPage login;
	
	public static void main(String[] args) throws IOException, InterruptedException {
		init();
		loadCapFromProperties();
		log.info("Application launch succesfully");
		login = new LoginPage(driver);
		login.login(USER_NAME, PASSWORD);
		log.info("Login succesfully");
	}

Following exception occur while serching for the element

log4j:WARN Failed to set property [append] to value "true;". 
2018-02-18 10:31:24 INFO  TestBase:57 - using DEVICE_NAME{LS5510}
2018-02-18 10:31:24 INFO  TestBase:61 - using PLATFORM_NAME{Android}
2018-02-18 10:31:24 INFO  TestBase:64 - using APP_PACKAGE{com.test.test}
2018-02-18 10:31:24 INFO  TestBase:66 - using APP_ACTIVITY{com.access_company.twine.android.dmc.HomeActivity}
Feb 18, 2018 10:31:45 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
2018-02-18 10:31:45 INFO  Login:19 - Application launch succesfully
log4j:WARN Failed to set property [append] to value "true;". 
Exception in thread "main" org.openqa.selenium.WebDriverException: java.lang.NullPointerException
Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T15:28:36.4Z'
System info: host: 'WINCTRL-6JIFFF1', ip: '192.168.1.8', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_144'
Driver info: driver.version: unknown
	at io.appium.java_client.pagefactory.AppiumElementLocator$WaitingFunction.apply(AppiumElementLocator.java:170)
	at io.appium.java_client.pagefactory.AppiumElementLocator$WaitingFunction.apply(AppiumElementLocator.java:1)
	at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:208)
	at io.appium.java_client.pagefactory.AppiumElementLocator.waitFor(AppiumElementLocator.java:76)
	at io.appium.java_client.pagefactory.AppiumElementLocator.findElement(AppiumElementLocator.java:95)
	at io.appium.java_client.pagefactory.interceptors.InterceptorOfASingleElement.intercept(InterceptorOfASingleElement.java:61)
	at org.openqa.selenium.remote.RemoteWebElement$$EnhancerByCGLIB$$d27c0df4.getText(<generated>)
	at pages.LoginPage.login(LoginPage.java:28)
	at testCases.Login.main(Login.java:21)

Caused by: java.lang.NullPointerException
at io.appium.java_client.pagefactory.AppiumElementLocator.lambda$0(AppiumElementLocator.java:96)
at io.appium.java_client.pagefactory.AppiumElementLocator$WaitingFunction.apply(AppiumElementLocator.java:150)
… 8 more