How to handle alert message within PageObjects - java

Code trials:
package Pages;
import org.openqa.selenium.Alert;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.Select;
public class pageBase {
public static WebDriver driver;
public pageBase(WebDriver driver) {
PageFactory.initElements(driver, this);
}
public static void AcceptAlert() {
Alert alert = driver.switchTo().alert();
alert.accept();
}
}
Test page:
public void SignUp(String user_name,String password) throws InterruptedException {
Set_UserName(user_name);
Set_Password(password);
click_SignupBtn();
Thread.sleep(3000);
AcceptAlert();
}
Error:
java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.WebDriver.switchTo()" because "Pages.pageBase.driver" is null

In the pageBase pageobject as you are casting the WebDriver instance you need to remove the keywords:
public
static
Effectively, instead of:
public static WebDriver driver;
your line of code will be:
WebDriver driver;
References
You can find a couple of relevant detailed discussions in:
How to wait for invisibility of an element through PageFactory using Selenium and Java

Related

Selenium FindBy Amazon Search Giving Error. (java.lang.NullPointerException)

There is the Search Class where I made a method to do amazon search, and the Main Class calls the Method searchFor()
But I keep getting the error
Exception in thread "main" java.lang.NullPointerException
package Project1;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class Search {
#FindBy(id = "twotabsearchtextbox")
WebElement search_box;
public void searchFor(String content) {
search_box.sendKeys(content);
search_box.submit();
}
}
And this is the Main Class
package Project1;
public class Main {
public static void main(String[] args) {
Search s1 = new Search();
s1.searchFor("gaming laptop");
}
}
Please refer below solution:
Main class
public class Main {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:\\New folder\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("Your url ");
Search s1 = new Search(driver);
s1.searchFor("gaming laptop");
}
}
Search class
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class Search {
#FindBy(id = "twotabsearchtextbox")
WebElement search_box;
WebDriver driver;
public Search(WebDriver driver){
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void searchFor(String content) {
search_box.sendKeys(content);
search_box.submit();
}
}

How to get the name of the WebElement variable name in another class

I am trying to pass the webElement name to another class for Webdriver operations.I am using the pagefactory model.
I want to print the name of the webelement variable as well in another class.
The below is the code I have.
Class A:
Class A{
#FindBy(how = How.XPATH, using = "//div[text()='Example_23']")
public WebElement exampleTab;
}
Class B:
class B{
public static void Click(WebElement objName) throws Exception
{
objName.click();
System.out.println("Clicked on"+ objName);
}
}
Desired Output:
Clicked on exampleTab
Actual Output:
Clicked on com.sun.proxy.$Proxy14
You can do that using below code :
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.How;
import org.openqa.selenium.support.PageFactory;
class A {
public WebDriver driver;
#FindBy(how = How.XPATH, using = "//div[text()='Example_23']")
public WebElement exampleTab;
public void initElements(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
}
public class B {
public static void main(String r[]) {
A a = new A();
System.setProperty("webdriver.chrome.driver",
"D:\\ECLIPSE-WORKSPACE\\playground\\src\\main\\resources\\chromedriver-2.35.exe");
WebDriver driver = new ChromeDriver();
a.initElements(driver); // instantiating class A elements
driver.navigate().to("url");
driver.manage().window().maximize();
Click(a.exampleTab);
}
public static void Click(WebElement objName) throws Exception {
objName.click();
System.out.println("Clicked on" + objName);
}
}

Not able to call the properties of two separate classes from TestNG Class ->java.lang.NullPointerException

I have 2 classes
1.BROWSER--- This class has methods for loading browser so that i can call in my every test case
2.LOCATORS --This class contains methods for storing all webelements
3.NEW TEST-This is my test case, in which i have called "browser" and "locators" class...
Below is my Browser class
BROWSER CLASS
package TestProject.TestProject;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class Browser {
WebDriver driver;
public Browser (WebDriver driver) {
this.driver = driver;
}
public WebDriver GetBrowser()
{
System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");
driver = new ChromeDriver();
String baseurl = "https:\\live.guru99.com\\index.php\\";
driver.get(baseurl);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
return driver;
}
}
Below is my Locator class
package TestProject.TestProject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class Locators {
WebDriver driver;
//Locators
By mobile = By.xpath("//a[contains(.,'Mobile')]");
public Locators (WebDriver driver){
this.driver = driver;
}
public void mobile()
{
driver.findElement(mobile).click();
}
}
MY TEST CASE
package TestProject.TestProject;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeTest;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
public class NewTest {
WebDriver driver;
#BeforeTest
public void beforeTest() {
Browser load = new Browser(driver);
driver =load.GetBrowser();
}
#Test
public void VerifyMobile() {
Locators mobilemenu = new Locators(driver);
mobilemenu.mobile();
}
#AfterTest
public void afterTest() {
}
}
You get NullPointerException because you are using non-initialized WebDriver
Below code gives you trouble. You are passing null driver to Browser class and... Then you probably do something with it but you did not return any initialized WebDriver
public class NewTest {
WebDriver driver;
#BeforeTest
public void beforeTest() {
Browser load = new Browser(driver);
load.GetBrowser();
}
Try this:
public WebDriver GetBrowser() {
System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");
driver = new ChromeDriver();
String baseurl = "https:\\live.guru99.com\\index.php\\";
driver.get(baseurl);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
return driver;
}
You will return initialized WebDriver to your test like this:
driver = load.GetBrowser();
This is bound to give a NullPointerException as the WebDriver object in #BeforeTest method is not yet initialized and is thus Null.
Browser load = new Browser(driver);
Here, the driver object is not yet initialized.
Advice:
Instead of calling the GetBrowser() method, initialize the WebDriver object in the Browser class constructor, and inherit the Browser class, and use the WebDriver object as and when required.

Why is webdriver opening so many drivers?

When I start a test, 3-4 drivers will spawn, but only one of them will actually run the test. I do not want more than one driver spinning up. I'm using intellij, and a maven project. I'm using cucumber-jvm on top of selenium. I feel like I'm missing something simple, but I'm not able to pin point the problem area.
Versions:
Selenium 2.42.2
Cucumber-junit 1.1.5
Chromedriver 2.42.2
Test runner code:
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#Cucumber.Options(
features = "automation/src/main/resources/applicationLogin.feature",
format = {"pretty", "html:target/cucumber", "json:target/cucmber.json"})
public class ApplicationLoginTest {
}
Gherkin script:
Feature: Application login
As a user
I want to login to the application
So I can see the dashboard
Scenario: Login to the application
Given I am on the page "product URL"
And I enter "username" into the username field
And I enter the "password" into the password field
And I click the "submit" button
And I accept the "User Agreement"
Then I should be on the "dashboard" page
Stepdefs:
package stepdefs;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import objectmaps.LoginMap;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import static com.thoughtworks.selenium.SeleneseTestBase.assertTrue;
public class ApplicationLoginStepDefs {
protected WebDriver driver;
protected LoginMap loginMap;
#Given("^I am on the page \"([^\"]*)\"$")
public void I_am_on_the_page(String page) throws Throwable {
driver = new ChromeDriver();
driver.manage().window().maximize();
loginMap = PageFactory.initElements(driver, LoginMap.class);
driver.get(page);
}
#And("^I enter \"([^\"]*)\" into the username field$")
public void I_enter_into_the_username_field(String arg1) throws Throwable {
loginMap.getUsernameField().sendKeys("automation");
}
#And("^I enter the \"([^\"]*)\" into the password field$")
public void I_enter_the_into_the_password_field(String arg1) throws Throwable {
loginMap.getPasswordField().sendKeys("a");
}
#And("^I click the \"([^\"]*)\" button$")
public void I_click_the_button(String arg1) throws Throwable {
loginMap.getLoginButton().submit();
}
#And("^I accept the \"([^\"]*)\"$")
public void I_accept_the(String arg1) throws Throwable {
Thread.sleep(2000);
loginMap.getBetaUserTermsAgree().click();
}
#Then("^I should be on the \"([^\"]*)\" page$")
public void I_should_be_on_the_page(String text) throws Throwable {
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("ng-binding")));
assertTrue(driver.getCurrentUrl().contains(text));
driver.quit();
}
}
Page object abstraction layer:
package objectmaps;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class LoginMap {
protected String hawkeyeLoginPage = "product URL";
#FindBy(id = "hk-login-username")
private WebElement usernameField;
#FindBy(id = "hk-login-password")
private WebElement passwordField;
#FindBy(xpath = "//button[contains(text(),'Agree')]")
private WebElement betaUserTermsAgree;
#FindBy(xpath = "//button[contains(text(),'Cancel')]")
private WebElement betaUserTermsCancel;
public WebElement getUsernameField() {
return usernameField;
}
public WebElement getPasswordField() {
return passwordField;
}
public WebElement getBetaUserTermsAgree() {
return betaUserTermsAgree;
}
public WebElement getBetaUserTermsCancel() {
return betaUserTermsCancel;
}
public WebElement getLoginButton() {
WebElement element = getUsernameField();
return element;
}
public void loginToHawkeye() throws Exception{
usernameField.sendKeys("automation");
passwordField.sendKeys("a");
getLoginButton().submit();
Thread.sleep(2000);
}
public void acceptUserAgreement() throws Exception{
Thread.sleep(2000);
getBetaUserTermsAgree().click();
}
public String getHawkeyeLoginPage() {
return hawkeyeLoginPage;
}
}
#Before
public void setUp() {
driver = new ChromeDriver();
driver.manage().window().maximize();
loginMap = PageFactory.initElements(driver, LoginMap.class);
}
#Before will run before each test method, so a new driver will be created each time.
You may want to try out #BeforeClass
I figured it out, and it maybe what you were saying Arran but I found my issue to be with classes and not necessarily methods. I have several step definition classes (many methods within each class), and when you execute one cucumber-jvm test, it appears that cucumber-jvm will load all of those step definition classes, and if there are before and after annotations within said classes, they will execute. And in my case, I had it set up to where the before would spin up a WebDriver instance. I moved the functionality from the before methods and into the various steps within my step definition classes

How to execute a page object programme in eclipse?

I am basically trying to run a sample page object framework in java in Selenium .I have tried to run some sample classes given by some of the sites and forums. But for some reason, it doesnt seem to work. I dont know if I am missing out anything. Please help. Thank You
I have tried these examples -
https://weblogs.java.net/blog/johnsmart/archive/2010/08/09/selenium-2web-driver-land-where-page-objects-are-king
http://www.wakaleo.com/blog/selenium-2-webdriver-quick-tips-page-object-navigation-strategies
package google;
import org.junit.After;
import org.junit.Before;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.Test;
public class WhenAUserSearchesOnGoogle {
private GoogleSearchPage page;
#Before
public void openTheBrowser() {
page = PageFactory.initElements(new ChromeDriver(), GoogleSearchPage.class);
page.open("http://google.co.nz/");
}
#After
public void closeTheBrowser() {
page.close();
}
#Test
public void whenTheUserSearchesForCatsTheResultPageTitleShouldContainCats() {
page.searchFor("cats");
//assertThat(page.getTitle(), containsString("cats") );
}
}
Above is the page factory class that I am using.
Following is the Page object.
package google;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
//import org.openqa.selenium.firefox.FirefoxDriver;
public class GoogleSearchPage {
protected WebDriver driver;
private WebElement q;
private WebElement btnG;
public GoogleSearchPage(WebDriver driver) {
this.driver = driver;
}
public void open(String url) {
driver.get(url);
}
public void close() {
driver.quit();
}
public String getTitle() {
return driver.getTitle();
}
public void searchFor(String searchTerm) {
q.sendKeys(searchTerm);
btnG.click();
}
public void typeSearchTerm(String searchTerm) {
q.sendKeys(searchTerm);
}
public void clickOnSearch() {
btnG.click();
}
}
The stack trace says
FAILED: whenTheUserSearchesForCatsTheResultPageTitleShouldContainCats
Your WebElement's aren't being bound by any selectors, ergo the PageFactory is failing. (it doesn't know how to find these)
Add the #FindBy annotation before each web element. e.g
#FindBy(css = "[name='q']") public WebElement q;
#Findby(css = "[name='btnG]") public WebElement btnG;
You'll get red underlines underneath #Findby. Just do a Ctrl+Shift+O to import it in.
Install the TestNG test framework to generate the report automatically

Categories