package Pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class HomePage {
WebDriver driver;
public HomePage() {
System.setProperty ("webdriver.chrome.driver", "D:\\Desktop\\Selenium\\chromedriver.exe");
this.driver = new ChromeDriver ();
PageFactory.initElements (driver, this);
}
#FindBy(xpath = "//*[#id='MenuContent']/a[2]")
WebElement signInButton;
public void signInButtonClick() {
signInButton.click();
}
}
and this is the main method:
import Pages.HomePage;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
System.setProperty ("webdriver.chrome.driver", "D:\\Desktop\\Selenium\\chromedriver.exe");
WebDriver driver = new ChromeDriver ();
driver.manage ().timeouts ().implicitlyWait (10, TimeUnit.SECONDS);
driver.manage ().window ().maximize ();
driver.get ("https://petstore.octoperf.com/actions/Catalog.action");
HomePage homePage = new HomePage ();
homePage.signInButtonClick ();
}
}
i am trying to get a locator (CSS or XPATH or really anything by this point) for a specific link and i cant manage no matter what I try.
this is the link in question:
Sign In
I have tried to find locators for a[text()='Sign In']
after I run the main method the process does not execute and this are the errors:
*** Element info: {Using=xpath, value=//*[#id='MenuContent']/a[2]}
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:323)
at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:428)
at org.openqa.selenium.By$ByXPath.findElement(By.java:353)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:315)
at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:69)
at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38)
at jdk.proxy2/jdk.proxy2.$Proxy4.click(Unknown Source)
at Pages.HomePage.signInButtonClick(HomePage.java:23)
at Main.main(Main.java:17)
There are few things incorrect here.
Driver is getting initialized 2 times which should not be correct.
Path to geckodriver seems incorrect as well.
I am adding the correct code below but have used chromedriver instead of geckodriver. It is working with the below code.
package sample;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class HomePage {
WebDriver driver;
public HomePage() {
System.setProperty ("webdriver.chrome.driver", "/Users/riteshpc/Documents/eclipse-workspace/Drivers/chromedriver");
this.driver = new ChromeDriver();
PageFactory.initElements (driver, this);
}
#FindBy(xpath = "//a[text()='Sign In']")
WebElement signInButton;
public void signInButtonClick() {
signInButton.click();
}
}
package sample;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
public class Main {
public static void main(String[] args) {
HomePage homePage = new HomePage();
WebDriver driver = homePage.driver;
driver.manage().timeouts().implicitlyWait (10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("https://petstore.octoperf.com/actions/Catalog.action");
homePage.signInButtonClick();
}
}
To copy your driver location, you can simply go to the driver's folder location in your eclipse and right click the driver and from properties you can copy path.
I have added the screenshot below.
There are a few things that need to be corrected.
You are creating 2 drivers, one in main and one in HomePage. You should create driver from your main and pass that instance into HomePage through the constructor.
Your first XPath, as you posted it, is not valid. a[text()='Sign In'] should be //a[text()='Sign In'].
The creator of Selenium has stated that PageFactory and implicit waits are a bad practice and should not be used. Instead use the Page Object Model and WebDriverWait.
I rewritten your code and tested it and it successfully clicks the Sign In link.
Main.java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import Pages.HomePage;
public class Main {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\Desktop\\Selenium\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://petstore.octoperf.com/actions/Catalog.action");
HomePage homePage = new HomePage(driver);
homePage.signInButtonClick();
}
}
HomePage.java
package Pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class HomePage {
WebDriver driver;
private By signInButton = By.xpath("//a[text()='Sign In']");
public HomePage(WebDriver driver) {
this.driver = driver;
}
public void signInButtonClick() {
driver.findElement(signInButton).click();
}
}
Related
I've run into the following error."Cannot instantiate class co.edureka.tests.FBLoginTest". Below I've posted the entire error console. I'm trying to use POM (Page Obeject Model) for Selenium. I'm believe the issue has to do with me creating too many drivers... I've been digging through online resources, but haven't found anything that resolves my issue.
FBLoginPage.java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
public class FBLoginPage {
WebDriver driver;
public FBLoginPage(WebDriver driver) {
this.driver=driver;
}
#FindBy(how=How.XPATH, using="/html/body/div[1]/div[1]/div[1]/div/div/div/div[2]/div/div[1]/form/div[1]/div[1]/input")
public WebElement emailTextBox;
#FindBy(how=How.XPATH, using="//input[#type='password'][#name='pass']") WebElement passwordTextBox;
#FindBy(how=How.XPATH, using="//input[#type='submit'][#value='Log In']") WebElement signinButton;
// Defining all the user actions (Methods) that can be performed in the Facebook home page
// This method is to set Email in the email text box
public void setEmail(String strEmail) {
emailTextBox.sendKeys(strEmail);
}
public void setPassword(String strPassword) {
passwordTextBox.sendKeys(strPassword);
}
// This method is to click on Login Button
public void clickOnLoginButton() {
signinButton.click();
}
}
FBHomePage.java
package co.edureka.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
public class FBHomePage {
WebDriver driver;
public FBHomePage(WebDriver driver) {
this.driver=driver;
}
#FindBy(how=How.XPATH, using="//div[text()='Account Settings']") WebElement profileDropdown;
#FindBy(how=How.LINK_TEXT, using="Log Out") WebElement logoutLink;
// Defining all the user actions (Methods) that can be performed in the Facebook home page
public void clickOnProfileDropdown() {
profileDropdown.click();
}
public void clickOnLogoutLink() {
logoutLink.click();
}
}
TestBase.java
package co.edureka.tests;
import java.io.IOException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
public class TestBase {
public static WebDriver driver;
#BeforeSuite
public void initialize() throws IOException{
System.setProperty("webdriver.chrome.driver", "C:\\Program Files (x86)\\Drivers\\chromedriver.exe");
driver = new ChromeDriver();
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.facebook.com");
}
#AfterSuite
public void TeardownTest()
{
TestBase.driver.quit();
}
}
FBLoginTest.java
package co.edureka.tests;
import java.time.Duration;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;
import co.edureka.pages.FBHomePage;
import co.edureka.pages.FBLoginPage;
public class FBLoginTest extends TestBase {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
#Test
public void init() throws Exception{
//driver.get("https://www.facebook.com");
FBLoginPage loginpage = PageFactory.initElements(driver, FBLoginPage.class);
wait.until(ExpectedConditions.titleContains("Facebook"));
loginpage.setEmail("432547#gmail.com");
loginpage.setPassword("ashish.bakshi#selenium");
loginpage.clickOnLoginButton();
FBHomePage homepage = PageFactory.initElements(driver, FBHomePage.class);
homepage.clickOnProfileDropdown();
homepage.clickOnLogoutLink();
}
}
Error Console Results
[RemoteTestNG] detected TestNG version 7.4.0
org.testng.TestNGException:
Cannot instantiate class co.edureka.tests.FBLoginTest
at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:30)
at org.testng.internal.InstanceCreator.instantiateUsingDefaultConstructor(InstanceCreator.java:193)
at org.testng.internal.InstanceCreator.createInstanceUsingObjectFactory(InstanceCreator.java:113)
at org.testng.internal.InstanceCreator.createInstance(InstanceCreator.java:79)
at org.testng.internal.objects.SimpleObjectDispenser.dispense(SimpleObjectDispenser.java:25)
at org.testng.internal.objects.GuiceBasedObjectDispenser.dispense(GuiceBasedObjectDispenser.java:30)
at org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:112)
at org.testng.internal.ClassImpl.getInstances(ClassImpl.java:165)
at org.testng.TestClass.getInstances(TestClass.java:122)
at org.testng.TestClass.initTestClassesAndInstances(TestClass.java:102)
at org.testng.TestClass.init(TestClass.java:94)
at org.testng.TestClass.<init>(TestClass.java:59)
at org.testng.TestRunner.initMethods(TestRunner.java:463)
at org.testng.TestRunner.init(TestRunner.java:339)
at org.testng.TestRunner.init(TestRunner.java:292)
at org.testng.TestRunner.<init>(TestRunner.java:223)
at org.testng.remote.support.RemoteTestNG6_12$1.newTestRunner(RemoteTestNG6_12.java:33)
at org.testng.remote.support.RemoteTestNG6_12$DelegatingTestRunnerFactory.newTestRunner(RemoteTestNG6_12.java:66)
at org.testng.ITestRunnerFactory.newTestRunner(ITestRunnerFactory.java:55)
at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:659)
at org.testng.SuiteRunner.init(SuiteRunner.java:173)
at org.testng.SuiteRunner.<init>(SuiteRunner.java:107)
at org.testng.TestNG.createSuiteRunner(TestNG.java:1300)
at org.testng.TestNG.createSuiteRunners(TestNG.java:1276)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1125)
at org.testng.TestNG.runSuites(TestNG.java:1063)
at org.testng.TestNG.run(TestNG.java:1031)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:79)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:483)
at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:23)
... 29 more
Caused by: java.lang.IllegalArgumentException: Input must be set
at org.openqa.selenium.internal.Require.nonNull(Require.java:59)
at org.openqa.selenium.support.ui.FluentWait.<init>(FluentWait.java:97)
at org.openqa.selenium.support.ui.WebDriverWait.<init>(WebDriverWait.java:77)
at org.openqa.selenium.support.ui.WebDriverWait.<init>(WebDriverWait.java:46)
at co.edureka.tests.FBLoginTest.<init>(FBLoginTest.java:15)
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67)
... 32 more
If anyone has any suggestions I would appreciate it.
To solve this issue you should move the WebDriverWait initialization to the init or any other method in FBLoginTest.java like below.
package co.edureka.tests;
import java.time.Duration;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;
import co.edureka.pages.FBHomePage;
import co.edureka.pages.FBLoginPage;
public class FBLoginTest extends TestBase {
WebDriverWait wait;
#BeforeMethod
public void init() {
wait = new WebDriverWait(driver, Duration.ofSeconds(30));
}
#Test
public void testLogin() throws Exception {
driver.get("https://www.facebook.com");
FBLoginPage loginpage = PageFactory.initElements(driver, FBLoginPage.class);
wait.until(ExpectedConditions.titleContains("Facebook"));
loginpage.setEmail("432547#gmail.com");
loginpage.setPassword("ashish.bakshi#selenium");
loginpage.clickOnLoginButton();
FBHomePage homepage = PageFactory.initElements(driver, FBHomePage.class);
homepage.clickOnProfileDropdown();
homepage.clickOnLogoutLink();
}
}
I am a newbie in Java and Selenium.
Below are my java classes for POM, Driver Utilites and Test Case.
When I run the Test Case as TestNG test, I have :
FAILED: verifyLogin
java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.WebElement.sendKeys(java.lang.CharSequence[])" because "this.userName" is null.
Please help me out. Let me know if further info is needed.
Thanks in advance.
<----------------------------------------POM-------------------------------------------------->
package com.inetBankingV1.pageObjects;
import org.openqa.selenium.WebDriver;
import com.inetBankingV1.utilities.callBrowserDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
public class LoginPage {
WebDriver driver;
#FindBy(how=How.LINK_TEXT, using="Log in")
WebElement logUser;
#FindBy(how=How.NAME, using="username")
WebElement userName;
#FindBy(how=How.NAME, using="password")
WebElement passWord;
//constructor
public LoginPage(WebDriver driver)
{
this.driver=driver;
}
public void loginCheck(String uname,String passwd)
{
userName.sendKeys(uname);
passWord.sendKeys(passwd);
logUser.click();
}
}
<----------------------------------------Driver------------------------------------------------>
package com.inetBankingV1.utilities;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
public class callBrowserDriver {
public WebDriver startApplication(String browser, String baseURL, WebDriver driver)
{
if(browser.equalsIgnoreCase("firefox"))
{
System.setProperty("webdriver.gecko.driver", "./Drivers/geckodriver.exe");
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setCapability("marionette", true);
driver = new FirefoxDriver(firefoxOptions);
}
if(browser.equalsIgnoreCase("chrome"))
{
System.setProperty("webdriver.chrome.driver", "./Drivers/chromedriver.exe");
driver=new ChromeDriver();
}
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.navigate().to(baseURL);
return driver;
}
}
<--------------------------------------Test Case----------------------------------------------->
package com.inetBankingV1.testCases;
import com.inetBankingV1.utilities.callBrowserDriver;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
import com.inetBankingV1.pageObjects.LoginPage;
public class TC2_VerifyLogin {
WebDriver driver;
callBrowserDriver browserDriver=new callBrowserDriver();
#Test
public void verifyLogin()
{
driver=browserDriver.startApplication("chrome","https://demosite.com/",this.driver);
LoginPage login=new LoginPage(driver);
login.loginCheck("admin","Password");
}
}
See if this works:-
#FindBy(how=How.ID, using="inline-search-submit")
WebElement logUser;
#FindBy(how=How.NAME, using="user")
WebElement userName;
#FindBy(how=How.NAME, using="pass")
WebElement passWord;
The issue is resolved after initialising the webelements of the POM class using initElements:
LoginPage login=PageFactory.initElements(driver, LoginPage.class);
Use below line in your constructor
PageFactory.initElements( driver, this);
----------------------------------------------
public LoginPage(WebDriver driver)
{
this.driver=driver;
PageFactory.initElements( driver, this);
}
This should solve your problem.
There are total of three classes. One class for Browser initialization(BrowserConfig.java), one for storing the elements of the page(LoginPageElements.java) and one class for executing the test case(Login_positive_case.java).
BrowserConfig.java
package com.midcities.utility;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import com.paulhammant.ngwebdriver.NgWebDriver;
public class BrowserConfig {
public static WebDriver startApplication(WebDriver driver, String browsername, String AppUrl) {
if(browsername.equalsIgnoreCase("chrome")) {
System.setProperty("webdriver.chrome.driver", "./Drivers/chromedriver.exe");
driver = new ChromeDriver();
} else if(browsername.equalsIgnoreCase("firefox")){
System.setProperty("webdriver.gecko.driver", "./Drivers/geckodriver.exe");
driver = new FirefoxDriver();
} else {
System.out.println("Browser not supported");
}
NgWebDriver ngWebDriver = new NgWebDriver((JavascriptExecutor) driver);
ngWebDriver.waitForAngularRequestsToFinish();
driver.manage().window().maximize();
driver.get(AppUrl);
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
return driver;
}
public static void quitBrowser(WebDriver driver) {
driver.quit();
}
}
LoginPageElements.java
package com.midcities.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import com.paulhammant.ngwebdriver.ByAngular;
public class LoginPageElements {
WebDriver driver;
public LoginPageElements(WebDriver driver){
this.driver = driver;
}
public void Login(String uname, String pass) {
driver.findElement(By.id("mat-input-0")).sendKeys(uname);
driver.findElement(By.id("mat-input-1")).sendKeys(pass);
driver.findElement(ByAngular.buttonText("SIGN IN")).click();
}
}
Login_positive_case.java
package com.midcities.testcases;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
import com.midcities.pages.LoginPageElements;
import com.midcities.utility.BrowserConfig;
public class Login_Positive_Case {
WebDriver driver;
#Test
public void loginIntoTheApplication() {
BrowserConfig.startApplication(driver, "chrome", "http://test.com/");
LoginPageElements loginFunc = new LoginPageElements(driver);
loginFunc.Login("test#gmail.com", "test");
}
}
Console log
FAILED: loginIntoTheApplication
java.lang.NullPointerException
at com.midcities.pages.LoginPageElements.Login(LoginPageElements.java:20)
at com.midcities.testcases.Login_Positive_Case.loginIntoTheApplication(Login_Positive_Case.java:20)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
BrowserConfig.startApplication initialize new WebDriver in the method scope, you need to use the returned value
driver = BrowserConfig.startApplication(driver, "chrome", "http://test.com/");
I am working on a Selenium testing framework tutorial of John Sonmez and ran into problem trying to perform the very first test. The test part consists of two methods: 1. LoginPage.GoTo(); which opens wordpress login page and 2. LoginPage.LoginAs("admin").Login(); which inserts username and clicks continue.
What happens when I run the test is wordpress loginpage opens and after 2 seconds blank Chrome browser opens and JUnit displays NoSuchElementException. The author of tutorial solved this problem adding some WebDriverWait and switchTo.ActiveElement.getAttribute() to LoginPage.GoTo(); method. However he is coding in C# and offers no solution for Java I'm coding in. I tried to apply WebDriverWait also but the problem is still there. Can anyone please suggest me how to solve this problem using WebDriverWait in Java.
LoginTest
import static org.junit.Assert.*;
import org.junit.Assert;
import org.junit.Test;
import wordpressAutomation.Driver;
import wordpressAutomation.LoginPage;
public class LoginTest extends Driver {
#Test
public void admin_user_can_login() {
LoginPage l = new LoginPage();
l.GoTo();
LoginPage.LoginAs("scenicrail").Login();
//Assert.assertTrue(DashboardPage.IsAt, "Failed to login");
}
}
LoginPage
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class LoginPage extends Driver {
#Test
public void GoTo() {
openBrowser().get("https://wordpress.com/log-in");
}
public static LoginCommand LoginAs(String username) {
return new LoginCommand(username);
}
}
public class LoginCommand extends Driver {
private String username;
private String password;
public LoginCommand(String username) {
this.username = username;
}
public LoginCommand WithPassword(String password) {
this.password = password;
return this;
}
public void Login() {
WebElement login = openBrowser().findElement(By.xpath("//*[#id='usernameOrEmail']"));
login.sendKeys(username);
openBrowser().findElement(By.xpath("//button[#type = 'submit']")).click();
}
}
public class Driver {
public WebDriver openBrowser() {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\KatarinaOleg\\Desktop\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
//driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
return driver;
}
}
After opening the page, where you get the NoSuchElementException you can add in something like this.
FluentWait<WebDriver> webDriverWait = new WebDriverWait(driver, 25).pollingEvery(5, TimeUnit.SECONDS);
webDriverWait.until(ExpectedConditions.visibilityOf(webElement));
Just add in whatever element you want to use as your check to make sure the page has loaded
you have called the Openbrowser multiple times in Login Method from LoginCommand Class.So, It will be unnecessarily create different driver instance. So, your code needs to be modified as below along with explicit wait (Driver Class also needs to be changed as below)
Login Method from LoginCommand Class:
public void Login() {
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id='usernameOrEmail']")));
WebElement login = driver.findElement(By.xpath("//*[#id='usernameOrEmail']"));
login.sendKeys(username);
driver.findElement(By.xpath("//button[#type = 'submit']")).click();
}
Driver Class:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class Driver {
WebDriver driver;
public WebDriver openBrowser() {
System.setProperty("webdriver.chrome.driver", "drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
//driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
return driver;
}
}
Edit: (dmin_user_can_login() method in LoginTest class)
#Test
public void admin_user_can_login() {
LoginPage l = new LoginPage();
l.GoTo();
l.LoginAs("scenicrail").Login();
//Assert.assertTrue(DashboardPage.IsAt, "Failed to login");
}
LoginPage Class:
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class LoginPage extends Driver {
#Test
public void GoTo() {
openBrowser().get("https://wordpress.com/log-in");
}
public LoginCommand LoginAs(String username) {
return new LoginCommand(username);
}
}
Using an example from Selenium Wedriver Practical Guide (to login in and create a test post on Wordpress), I encounter the above mentioned error.
Here is the PageObject that I am using:
package com.PageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
/**
* Created by JTester on 3/9/2016.
*/
public class AdminLoginPage {
WebDriver driver;
#FindBy(how=How.ID, id="user_login")
WebElement email;
#FindBy(how=How.ID, id="user_pass")
WebElement pwd;
#FindBy(how=How.ID, id="wp-submit")
WebElement submit;
public AdminLoginPage(WebDriver driver){
this.driver = driver;
driver.get("http://mysite.wordpress.com/wp-admin/");
}
public void login(){
email.sendKeys("myEmailAddress#yahoo.com");
pwd.sendKeys("myPasswd");
submit.click();
}
}
And here is the test class:
package com.features.trial;
import com.PageObjects.AdminLoginPage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
/**
* Created by JTester on 3/9/2016.
*/
public class TestAddNewPost {
public static void main(String... args) {
WebDriver driver = new FirefoxDriver();
//login to wordpress admin
AdminLoginPage admLoginPage = new AdminLoginPage(driver);
admLoginPage.login();
//go to AllPosts page
driver.get("http://mysite.wordpress.com/wp-admin/edit.php");
//add a new post
WebElement addNewPost = driver.findElement(By.linkText("Add New"));
addNewPost.click();
//add new post's content
driver.switchTo().frame("content_ifr");
WebElement postBody = driver.findElement(By.id("tinymce"));
postBody.sendKeys("This is my description.");
driver.switchTo().defaultContent();
WebElement title = driver.findElement(By.id("title"));
title.sendKeys("This is my first post");
//publish my post
WebElement publish = driver.findElement(By.id("publish"));
publish.click();
}
}
Since I am new to Selenium and Page Objects, could anyone explain why it is throwing the following error:
Exception in thread "main" java.lang.NullPointerException
at com.PageObjects.AdminLoginPage.login(AdminLoginPage.java:29)
at com.features.trial.TestAddNewPost.main(TestAddNewPost.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Process finished with exit code 1
Many thanks..
ps: After looking at a lot of code examples on the web, I think I need to use PageFactory to instantiate my elements but not sure if this is true, and if it is, how do I go about it using my example code.
Debugger Screenshot :
AdminLoginPage should have been initialized using PageFactory.
import org.openqa.selenium.support.PageFactory;
public AdminLoginPage(WebDriver driver){
PageFactory.initElements(driver, this); //add this
this.driver = driver;
driver.get("http://mysite.wordpress.com/wp-admin/");
}
Add the following code:
AdminLoginPage loginPage = PageFactory.initElements(driver,AdminLoginPage.class);
loginPage.login();
to the TestAddNewPost class, instead of using the existing code:
AdminLoginPage admLoginPage = new AdminLoginPage(driver);
admLoginPage.login();