How to execute a page object programme in eclipse? - java

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

Related

Bypass 'Accept All' cookies - Expected condition failed: waiting for element to be clickable

I'm new to automation, using JAVA with Selenium to do some basic tests on a website. I've stumbled upon a Cookies pop-up.
Seems like the element is not visible on the page when I'm trying to click it(waitForElementToBeVisible is not doing it either).
I've read all the related posts on SO and YT videos on how to bypass this, it doesn't seem to work for me.
package pageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
public class Login {
private static final String BASE_URL = "https://www.demo.guru99.com/V4/";
private static final By USER_ID = By.name("uid");
private static final By PASSWORD = By.name("password");
private static final By LOGIN_BTN = By.name("btnLogin");
private static final By ACCEPT_PRIVACY = By.xpath("//*[#id=\"save\"]/span[1]/div");;
private WebDriver driver;
public Login(WebDriver driver) {
this.driver = driver;
}
public void navigate() {
driver.get(BASE_URL);
}
public void setUsername(String username) {
driver.findElement(USER_ID).clear();
driver.findElement(USER_ID).sendKeys(username);
}
public void setPassword(String password) {
driver.findElement(PASSWORD).clear();
driver.findElement(PASSWORD).sendKeys(password);
}
public void clickLogin() {
driver.findElement(LOGIN_BTN).click();
}
public void clickAcceptPrivacy() {
driver.findElement(ACCEPT_PRIVACY).click();
}
// public String popupText() {
// String text = driver.findElement(ACCEPT_PRIVACY).getText();
// return text;
// }
//
// public void waitAcceptPrivacy() {
// new WebDriverWait(driver, Duration.ofSeconds(3)).until(ExpectedConditions.elementToBeClickable(ACCEPT_PRIVACY)).click();
// }
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import pageObjects.Login;
import java.util.concurrent.TimeUnit;
public class TestDrive {
private final WebDriver driver = new ChromeDriver();
private final Login login = new Login(driver);
#Before
public void setup() {
//use Chrome driver
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
}
#After
public void tearDown() {
driver.quit();
}
#Test
public void Test1() throws InterruptedException {
login.navigate();
Thread.sleep(1000);
login.clickAcceptPrivacy();
login.setUsername("mngr473114");
login.setPassword("ajybEvu");
Thread.sleep(2000);
login.clickLogin();
}
}
}
This is the error I'm getting:
org.openqa.selenium.NoSuchElementException: Unable to find element with locator By.xpath: //*[#id="save"]/span[1]/div
Tried different xpaths, css; tried ExpectedConditions.
I'm expecting to close the pop-up by clicking the Accept All button.
Thank you!
I didn't get any popups on this page. But probably this popup contained in 'iframe' block if so, you should switch to 'iframe' at first and only then do some action with element
//Store the web element
WebElement iframe = driver.findElement(By.cssSelector("iframe path"));
//Switch to the frame
driver.switchTo().frame(iframe);
//Now we can click the button
driver.findElement(ACCEPT_PRIVACY).click();
Check this out https://www.selenium.dev/documentation/webdriver/interactions/frames/
You could try is to use an explicit wait to wait for the element to be present before interacting with it. You can use the ExpectedConditions class to wait for the element to be visible and clickable before interacting with it.
public void clickAcceptPrivacy() {
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement acceptPrivacy = wait.until(ExpectedConditions.elementToBeClickable(ACCEPT_PRIVACY));
acceptPrivacy.click();
}

How to handle alert message within PageObjects

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

Can't find an element in the browser

I'm building an automation project using Selenium, Java, Cucumber..
I have 3 different classes at this time running the automation code
- Container Class: storing all the WebElements as single methods
- View Class: where all the logic hapens. exp: Performing clicks to the Webelement stored in the container class.
-Steps Class: Where I assert or verify the different pieces of a scenario
My problem is I'm not finding the webelements in the webside when I call the container methods from my view class...
I know the path are OK because if I build the entire scenario in the step class all WebElements are located without issues
I know the view class is excuting the container class because I set a prinln in the container method and is showing up every time the view class attempt to find the WebElement.
Container Class
package com.automation.automation.prototype.containers;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class loginContainer {
private WebDriver driver;
public loginContainer(WebDriver driver) {
this.driver = driver;
}
public WebElement loginEmail(){
//xpath that is not beign located
return driver.findElement(By.xpath("//*[#id='email']"));
}
}
View Class
package com.automation.automation.prototype.views;
import com.automation.automation.prototype.containers.loginContainer;
import org.openqa.selenium.WebDriver;
import com.automation.automation.prototype.containers.loginContainer;
public class loginView {
private static loginContainer login;
public loginView(WebDriver driver) {
login = new loginContainer(driver);
}
public boolean insertEmail( String email) throws InterruptedException{
boolean valid = false;
int flag = 0;
int attemps = 0;
do{
attemps++;
try{
login.loginEmail().click();
login.loginEmail().sendKeys(email);
System.out.println("Element Found!: "+attemps);
valid = true;
flag = 1;
}
catch(Exception e){
Thread.sleep(1000);
System.out.println("Element Searching: "+attemps);
}
}while (attemps <20 && flag ==0);
return valid;}
}
Step Class
package com.automation.automation.prototype;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import static org.junit.Assert.assertTrue;
import com.automation.automation.prototype.containers.URLs;
import com.automation.automation.prototype.containers.loginContainer;
import com.automation.automation.prototype.views.loginView;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class steps {
private WebDriver driver;
private static URLs URL;
private static loginView LoginView2;
//private static loginContainer LoginContainerstep;
public steps(){
URL = new URLs(driver);
//LoginContainerstep = new loginContainer(driver);
LoginView2 = new loginView(driver);
}
#Given(value = "^Launch$")
public void login() throws Throwable{
driver = new FirefoxDriver();
driver.get(URL.fbURL);
System.out.println(URL.fbURL);
}
#Then(value = "^insertCredentials (.*)$")
public void insertCredentials_and_and(String email) throws InterruptedException{
assertTrue("ELEMENT IS NOT SHOWING UP", LoginView2.insertEmail(email));
}
Try to minimize the code. Better to make a common class where you can put login, setup and teardown function, and use the main class (containing main logics and calling the function required from common). Secondly, try to take care for access modifiers. Thirdly, try to check the different types XPATH can be defined. Hope it will help.
Try to use this : instead of a retry
public WebElement findElementSafe(By selector, long timeOutInSeconds) {
try {
return findElement(selector, timeOutInSeconds);
} catch (TimeoutException e) {
return null;
}
}
public WebElement findElement(By selector, long timeOutInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.presenceOfElementLocated(selector));
return findElement(driver, selector);
}
public void waitForElementToAppear(By selector, long timeOutInSeconds) {
WebDriverWait wait = new WebDriverWait(getDriver(), timeOutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(selector));
}
public void waitForElementToDisappear(By selector, long timeOutInSeconds) {
WebDriverWait wait = new WebDriverWait(getDriver(), timeOutInSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(selector));
}

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

calling multiple methods within a method - selenium webdriver cross browser testing

I have a question with regards to calling multiple method using JUNIT. This is my test
package com.example.tests;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;
import org.testng.annotations.Test;
public class test {
private WebDriver _driver;
#Test
public void FFconfiguration() throws Exception {
System.out.println("Running FF");
_driver = new FirefoxDriver();
_driver.get("URL");
login();
setup();
_driver.quit();
}
public void login1()
{
}
public void setup()
{
}
}
My question is: Can I call both login() and setup() within the method FFConfiguration? If not what's the alternate solution...............
Yes, absolutely, you can do it. You can have tests like this:
#Test
public void testBuyingProcess(){
ShoppingUI shoppingPage = new ShoppingUI();
shoppingPage.login();
Assert.assertEquals(shoppingPage.getTitle(),"Welcome");
//....
}
And fill in the methods elsewhere even in different class. Few examples of methods used above:
public class ShoppingUI{
private WebDriver driver
public ShoppingUI(){
driver = new FirefoxDriver();
driver.get("http://my-test-site.com/buy-buy-buy.html");
}
public String getTitle(){
return driver.getTitle();
}
}

Categories