Chromedriver does not work unless I manually click borowser elements - selenium

I am new in selenium and trying to run a basic test both firefox and chrome in parallel. Everthing works for firefox but chrome is not working. Actually chrome browser opens up but does nothing unless I click email input and then click anywhere expect email input. When I do that my test starts on chrome and everything works fine. I am really sure that I should'nt click manually to start the test :)
Here is my page object;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import page.objects.AbstractPageObject;
public class LoginPage extends AbstractPageObject {
#FindBy(xpath = "//input[#type='email']")
private WebElement email;
#FindBy(xpath = "//input[#type='password']")
private WebElement password;
#FindBy(xpath = "//button[#type='submit']")
private WebElement continueButton;
public void verifyAllElementsAreDisplaying() {
email.isDisplayed();
password.isDisplayed();
continueButton.isDisplayed();
}
public void fillEmail (String userEmail) {
email.clear();
email.sendKeys(userEmail);
}
public void fillPassword (String userPassword) {
password.clear();
password.sendKeys(userPassword);
}
public void login () {
this.continueButton.click();
}
}
And here is my test;
import org.testng.annotations.Test;
import page.objects.Login.LoginPage;
public class VerifyLogin extends BaseTest {
#Test(description = "Verfifies Login Page Functionality")
public void verifyLogin() throws InterruptedException {
LoginPage loginPage = new LoginPage();
loginPage.verifyAllElementsAreDisplaying();
loginPage.fillEmail("email");
loginPage.fillPassword("***");
Thread.sleep(2000);
}
}
In BaseTest class I have #BeforeSuit and #AfterSuite annotations to manage driver.

Related

In Page Object Model do i have to create webdriver all the time?

I'm using the Page Object Model I just started i created 2 packages one is com.automation.pages another one is com.automation.testcases.
In both packages I created a class for the login page it works fine I'm sharing the code below.
package com.automation.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class LoginPage {
WebDriver driver;
public LoginPage(WebDriver ldriver)
{
this.driver=ldriver;
}
#FindBy (xpath="//input[#name='email'] ") WebElement email;
#FindBy (xpath="//input[#name='password']") WebElement password;
#FindBy (xpath="//body/div[2]/div[2]/div[2]/form[1]/div[3]/div[2]/button[1]") WebElement loginbutton;
public void logintoLabaiik(String email1, String password1 )
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
email.sendKeys(email1);
password.sendKeys(password1);
loginbutton.click();
}
}
The problem I'm facing when I working on the new page is when I created a driver and when using ldriver it throws me an error also when I replace the "l" still it throws me the error. kindly solve my problem.
package com.automation.pages;
import org.openqa.selenium.WebDriver;
public class TaxSetup {
WebDriver driver;
public TaxSetup(WebDriver driver)
{
this.driver.ldriver;
}
}
It looks you have an issue in TaxSetup constructor.
This should work.
public TaxSetup(WebDriver driver){
this.driver=driver;
}
Take a look at how to create 2 Page Object classes and use them in tests:
LoginPage
public class LoginPage {
final WebDriver driver;
public LoginPage(WebDriver driver){
this.driver=driver;
}
// page implementation
}
TaxSetup
public class TaxSetup {
final WebDriver driver;
public TaxSetup(WebDriver driver){
this.driver=driver;
}
// page implementation
}
How to use in test
public class SomeTest {
WebDriver driver;
LoginPage loginPage;
TaxSetup taxSetupPage;
#BeforeClass
public void initDriverAndPages() {
driver = ... // e.g. new ChromeDriver()
loginPage = PageFactory.initElements(driver, LoginPage.class);
taxSetupPage = PageFactory.initElements(driver, TaxSetup.class);
}
#Test
public void someTest() {
// implement test using loginPage, taxSetupPage as you like
}
#AfterClass
public void quitDriver() {
driver.quit();
}
}
Please correct the below line in your TaxSetUp constructor.
this.driver.ldriver;
This is suppose to be
this.driver = driver;
And yes, you have to pass the WebDriver instance for all the page classes that you create as part of your application otherwise they will assign default value to the driver which is null.

I am receiving java.lang.NullPointerException at stepDefinition

I am using POM pattern in cucumber and in StepDefinition package I created one 'Hooks.java' to launch the browser and 'CustomersModuleSteps.java' to add new customer when I am executing the runner file I am receiving the below error. someone please look into it and advise.
Error:```
************ open URL ************
************ Enter Username & password ************
************ clicking on login button ************
************ Validating page Title ************
************ clicking on CustomersMenu **********
Given user clicks on customers menu # com.nopCommerse.StepDefinition.CustomersModuleSteps.user_clicks_on_customers_menu() in file:/Users/rajasekhar/eclipse-workspace/nopCommerse/target/test-classes/
java.lang.NullPointerException
at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:69)
at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38)
at com.sun.proxy.$Proxy19.click(Unknown Source)
at com.nopCommerse.Base.ElementExtension.ClickOnIt(ElementExtension.java:55)
at com.nopCommerse.pageObjects.CustomersModuleObjects.clickCustomersMenu(CustomersModuleObjects.java:31)
at com.nopCommerse.StepDefinition.CustomersModuleSteps.user_clicks_on_customers_menu(CustomersModuleSteps.java:32)
at ✽.user clicks on customers menu(com.Features/CustomersModule.feature:4)
When user clicks on customers menu item # com.nopCommerse.StepDefinition.CustomersModuleSteps.user_clicks_on_customers_menu_item() in file:/Users/rajasekhar/eclipse-workspace/nopCommerse/target/test-classes/
************ clicking on logout link ************
************ closing the Browser ************
Failed scenarios:
com.Features/CustomersModule.feature:3 # Add a new customer
1 Scenarios (1 failed)
2 Steps (1 failed, 1 skipped)
0m24.213s
My Base class
public class TestBase extends ElementExtension {
public WebDriver driver;
public Logger logger;
public Properties configProp;
public CustomersModuleObjects custmod;
public LoginPageObjects lp ;
}
My CustomersModuleSteps.java
package com.nopCommerse.StepDefinition;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import com.nopCommerse.Base.TestBase;
import com.nopCommerse.pageObjects.CustomersModuleObjects;
import io.cucumber.java.Before;
import io.cucumber.java.en.*;
public class CustomersModuleSteps extends TestBase {
#Before
public void setup() {
//object creation for logger
logger = Logger.getLogger("EmployeeRestApi"); //added logger
PropertyConfigurator.configure("Log4j.properties"); //added logger
logger.setLevel(Level.DEBUG);
}
#Given("user clicks on customers menu")
public void user_clicks_on_customers_menu() {
logger.info("************ clicking on CustomersMenu **********");
custmod = new CustomersModuleObjects(driver);
custmod.clickCustomersMenu();
}
#When("user clicks on customers menu item")
public void user_clicks_on_customers_menu_item() {
logger.info("************ clicking on customer Menu item **********");
custmod.clickCustomerMenuItem();
}
}
And this is my page factory class
package com.nopCommerse.pageObjects;
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;
import com.nopCommerse.Base.TestBase;
public class CustomersModuleObjects extends TestBase {
WebDriver driver;
//constructor of CustomersModule class
public CustomersModuleObjects(WebDriver ldriver) {
driver = ldriver;
PageFactory.initElements(ldriver,this);
}
//Identify webElements
#FindBy(how = How.XPATH,using = "//a[#href='#']//span[contains(text(),'Customers')]")
WebElement CustomersMenu;
#FindBy(how = How.XPATH,using ="//a[#href='/Admin/Customer/List']//span[contains(text(),'Customers')]")
WebElement customerMenuItem;
//action methods for elements identified
public void clickCustomersMenu() {
ClickOnIt(CustomersMenu);
}
public void clickCustomerMenuItem() {
ClickOnIt(customerMenuItem);
}
}
This could be for two reasons in my experience:
You are not initializing the WebDriver correctly, so that you could debug and check that driver is not null at this point CustomersModuleSteps.java:32
The XPath for the element is not the correct one, so that you could install an extension for google chrome (I use xpath helper) and check that you are locating correctly the element in the Page.
In addition to you could improve the structure, extending a little bit the POM Patterns and get the code cleaner splitting the Page Actions and Page Objects as you can see in the following example:
Web Page Element definition
public class LoginPageElements {
protected WebDriver driver;
public LoginPageElements(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
//Mapping web elements
#FindBy(id = "userName")
protected WebElement TxtUserName;
#FindBy(id = "Password")
protected WebElement TxtPassword;
#FindBy(id = "Login")
protected WebElement BtnLogin;
}
Web Page Actions definition
public class LoginActions extends LoginPageElements {
WebDriverWait wait;
public LoginActions (WebDriver driver, WebDriverWait wait) {
super(driver);
this.wait = wait;
}
public void Login() {
fillUserName();
fillPassword();
ClickLogin();
}
private void fillUserName() {
wait.until(ExpectedConditions.visibilityOf(TxtUserName));
TxtUserName.sendKeys("User");
}
private void fillPassword() {
wait.until(ExpectedConditions.visibilityOf(TxtPassword));
TxtPassword.sendKeys("Pass");
}
private void ClickLogin() {
wait.until(ExpectedConditions.visibilityOf(BtnLogin));
wait.until(ExpectedConditions.elementToBeClickable(BtnLogin));
BtnLogin.submit();
}
Test Class
public class LoginExample {
WebDriver driver;
WebDriverWait wait;
LoginActions loginActions;
#BeforeClass
public void setDriver() {
System.setProperty("webdriver.chrome.driver", ClassLoader.getSystemResource("chromedriver.exe").getPath());
driver = new ChromeDriver();
wait = new WebDriverWait(driver, 10);
loginActions = new LoginActions(driver, wait);
driver.manage().window().maximize();
}
#Test()
public void testLogin() {
driver.get("http://www.YourLoginPage.com/");
loginActions.Login();
}
#AfterClass
public void close() {
driver.quit();
}
}
Hope this could help you and so that you will be able to find where the problem is easier

POM not working on multiple test of TestNG

Below are my classes of POM:
Home
package com.sec.page;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class Home {
private WebDriver driver;
#FindBy(linkText = "Frequency Calculator")
WebElement frqcalc_page;
#FindBy(linkText = "Radial O-ring Selector")
WebElement radslct_page;
public Home(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
public Freq_Calc clickFreqCalcPage() {
frqcalc_page.click();
return PageFactory.initElements(driver,Freq_Calc.class);
}
public Radial_Selector clickRadialSelectorPage() {
radslct_page.click();
return PageFactory.initElements(driver,Radial_Selector.class);
}
}
Freq_Calc
package com.sec.page;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class Freq_Calc {
private WebDriver driver;
#FindBy(linkText = "Bearing Frequencies Calculator")
WebElement BrgFreqCalc;
#FindBy(linkText = "Gearbox Calculator")
WebElement GearCalc;
#FindBy(linkText = "Overview")
WebElement overview_page;
public Freq_Calc(WebDriver driver){
this.driver=driver;
}
public Freq_Calc_BrgFreqCalc clickBrgFreqCalc(){
BrgFreqCalc.click();
return PageFactory.initElements(driver, Freq_Calc_BrgFreqCalc.class);
}
}
Radial_Selector
package com.sec.page;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.Select;
public class Radial_Selector {
private WebDriver driver;
#FindBy(name = "boreDiameter")
WebElement boreDiameter;
#FindBy(name = "boreTolerance")
WebElement boreTolerance;
#FindBy(css = "input[value='Calculate']")
WebElement calculate;
public Radial_Selector(WebDriver driver){
this.driver=driver;
}
public Radial_Selector enterboreDiameter(String value) {
boreDiameter.sendKeys(value);
return PageFactory.initElements(driver, Radial_Selector.class);
}
public Radial_Selector enterboreTolerance(String value) {
boreTolerance.sendKeys(value);
return PageFactory.initElements(driver, Radial_Selector.class);
}
public Radial_Selector clickcalculate() {
calculate.click();
return PageFactory.initElements(driver, Radial_Selector.class);
}
}
TestBase
package com.sec.util;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import com.sec.page.Freq_Calc;
import com.sec.page.Home;
import com.sec.page.Radial_Selector;
public class TestBaseSEC {
protected WebDriver driver=null;
protected String baseUrl;
protected Home homePage;
protected Radial_Selector radialselector;
protected Freq_Calc freqcalc;
#BeforeTest
public void setUp() {
baseUrl = "http://10.177.2.60:8080/engcalc/";
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#AfterTest
public void tearDown() throws Exception {
driver.quit();
}
}
Testcase:
package com.sec.scripts;
import org.openqa.selenium.By;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.Test;
import com.sec.page.Home;
import com.sec.util.TestBaseSEC;
public class TestCaseSEC extends TestBaseSEC{
#Test
public void Test_RadialSelector_Page() throws Exception {
homePage = PageFactory.initElements(driver, Home.class);
driver.get(baseUrl);
radialselector = homePage.clickRadialSelectorPage();
radialselector.enterboreDiameter("10");
radialselector.enterboreTolerance("12");
radialselector.clickcalculate();
driver.findElement(By.xpath("//*[#id='top-navigation']/ul/li[1]/a/span")).click();
}
#Test
public void Test_Freq_Calc_BrgFreqCalc_Page() throws Exception {
homePage = PageFactory.initElements(driver, Home.class);
freqcalc = homePage.clickFreqCalcPage();
}
}
My isssue is:
Whenn I run Testcase, The first #Test works fine. but when it goes to second #Test, where "freqcalc =homePage.clickFreqCalcPage()"is used, it tells there is no locator for Frequency Calculator, but that exist.
Also if I use "freqcalc =homePage.clickFreqCalcPage()" as last line in first #Test then it works.
So I want to understand why it does not work for second #Test.
You have to take care of a lot of things in your code as follows :
Loading the page elements even before accessing the url makes no sense. Hence first load the URL then initialize the WebElements on the Page Object.
When you initialize a Page Object get back the object in return.
driver.get(baseUrl);
Home homePage = PageFactory.initElements(driver, Home.class);
Use the returned Page Object to access it's methods.
homePage.clickRadialSelectorPage();
Avoid chaining of Page Objects i.e. initialization of another Page Object through return statement, rather initialize the required Page Object in your Test class.
//avoid
return PageFactory.initElements(driver,Radial_Selector.class);
//within Test Class
Radial_Selector radialselector = PageFactory.initElements(driver,Radial_Selector.class);
radialselector.enterboreDiameter("10");
As you are having seperate Page Objects for different pages try to define the locators e.g. xpath for the associated WebElement in the respective Page Objects only.
//avoid
driver.findElement(By.xpath("//*[#id='top-navigation']/ul/li[1]/a/span"));
As you are having seperate Page Objects for different pages try to define the Page Object Methods e.g. click() for the WebElement's in the respective Page Factory only.
//avoid
driver.findElement(By.xpath("//*[#id='top-navigation']/ul/li[1]/a/span")).click();
First #Test works fine because, though you try to initialize Home.class nothing really happens. When driver.get(baseUrl); gets executed the elements gets initialized and your #Test gets passed. But that's not the case with Second #Test. Hence Fails
The problem here is that, the URL is not launched in the second test when the page got initialized because it is missed in the second test.
Solution 1:
Please add the line driver.get(baseUrl) in your second test as given below.
#Test
public void Test_Freq_Calc_BrgFreqCalc_Page() throws Exception {
driver.get(baseUrl);
homePage = PageFactory.initElements(driver, Home.class);
freqcalc = homePage.clickFreqCalcPage();
}
Solution 2: Move the launch URL step to before Test method. Then remove it in first test as given below.
#BeforeTest
public void setUp() {
baseUrl = "http://10.177.2.60:8080/engcalc/";
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get(baseUrl);
}
then remove it in the first test as given below.
#Test
public void Test_RadialSelector_Page() throws Exception {
homePage = PageFactory.initElements(driver, Home.class);
// driver.get(baseUrl);
radialselector = homePage.clickRadialSelectorPage();
radialselector.enterboreDiameter("10");
radialselector.enterboreTolerance("12");
radialselector.clickcalculate();
driver.findElement(By.xpath("//*[#id='top-navigation']/ul/li[1]/a/span")).click();
}

Page object model in selenium

Can anyone please resolve the issue in the below post.
Selenium Framework Page Object Model and Page Navigation
I am not able to resolve the null pointer exception issue when a page returns an object of other page. Can anyone please tell what is the exact way of doing it. As explained in the above link, it's not clear how the error is resolved.
I will try illustrating PageFactory example using 3 different classes types.
Base Class- Has configuration setting like driver declaration
POM Class- Contains the POM objects for a single page
Test Class-Class containing test steps
BaseClass Example
public class BaseClass {
public WebDriver driver=null;
public BaseClass() throws MalformedURLException {
driver=new firefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get(baseURL);
}
POM Class example
//Class1
public class WebshopHomePage {
WebDriver driver;
public WebshopHomePage(WebDriver driver){
this.driver=driver;
}
#FindBy(how=How.LINK_TEXT,using="Log in")//Identifying page elements
WebElement loginLink;
public void clickLoginLink(){
loginLink.click();
}
}
//Class2
public class SignInSignUpPage {
WebDriver driver;
public SignInSignUpPage(WebDriver driver){
this.driver=driver;
}
#FindBy(how=How.ID,using="Email")
WebElement emailID;
}
TestClass Example
public class WebShopSignInTest extends BaseClass {
#Test
public void testSteps() {
System.out.println("I'm in teststeps!!");
WebshopHomePage wshpObj=PageFactory.initElements(driver,WebshopHomePage.class);//Assigning POM class1 objects to driver
wshpObj.clickLoginLink();
SignInSignUpPage signInSignUpPageObj=PageFactory.initElements(driver, SignInSignUpPage.class);//Assigning POM class2 objects to driver
signInSignUpPageObj.enterCredsSubmit(userID, passw0rd);
}
package org.pom;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class GoogleHomePageObjects
{
public GoogleHomePageObjects(WebDriver driver)
{
PageFactory.initElements(driver, this);
}
#FindBy(name="q")
public WebElement txtSearch;
#FindBy(name="btnG")
public WebElement btnSearch;
#FindBy(linkText="Selenium - Web Browser Automation")
public WebElement lnkSelenium;
public void searchGoogle(String SearchText)
{
txtSearch.sendKeys(SearchText);
btnSearch.click();
}
public SeleniumPageObjects clickSelenium()
{
lnkSelenium.click();
return new SeleniumPageObjects(driver); //Here is the issue and i am getting error
}
}
//test class 2
package org.pom;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class SeleniumPageObjects{
public SeleniumPageObjects(WebDriver driver)
{
PageFactory.initElements(driver, this);
}
#FindBy(linkText="Download")
public WebElement lnkDownload;
#FindBy(xpath=".//*[#id='header']/h1/a")
public WebElement lnkHome;
public void clickDownloads()
{
lnkDownload.click();//Here it throws null pointer excception
}
public void clickHome()
{
lnkHome.click();
}
}
Below is my main class:
package org.pom;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class GoogleSearchTest
{
public static void main(String[] args) throws InterruptedException
{
System.setProperty("webdriver.gecko.driver","D:\\Desktop\\Selenium\\Jars\\geckodriver-v0.11.1-win64\\geckodriver.exe");
WebDriver driver=new FirefoxDriver();
driver.get("http://www.google.com");
GoogleHomePageObjects page=new GoogleHomePageObjects(driver);
page.searchGoogle("Selenium");
Thread.sleep(4000);
SeleniumPageObjects selPage=page.clickSelenium();
Thread.sleep(4000);
selPage.clickDownloads();
Thread.sleep(4000);
selPage.clickHome();
}
}
In the below example, We have created a Login class , Home class, and a Test class ...
It is not necessary to create one class for one page may be you can group the functionality or modules based on your convenience...
Summary:-
Created Login Class with all the required objects...and the loginas method should return the homepage class.....
public class LoginPage {
private final WebDriver driver;
public LoginPage(WebDriver driver) {
this.driver = driver;
// Check that we're on the right page.
if (!"Login".equals(driver.getTitle())) {
// Alternatively, we could navigate to the login page, perhaps logging out first
throw new IllegalStateException("This is not the login page");
}
}
// The login page contains several HTML elements that will be represented as WebElements.
// The locators for these elements should only be defined once.
By usernameLocator = By.id("username");
By passwordLocator = By.id("passwd");
By loginButtonLocator = By.id("login");
public LoginPage typeUsername(String username) {
driver.findElement(usernameLocator).sendKeys(username);
// Return the current page object as this action doesn't navigate to a page represented by another PageObject
return this;
}
public LoginPage typePassword(String password) {
driver.findElement(passwordLocator).sendKeys(password);
// Return the current page object as this action doesn't navigate to a page represented by another PageObject
return this;
}
public HomePage submitLogin() {
// This is the only place that submits the login form and expects the destination to be the home page.
// A seperate method should be created for the instance of clicking login whilst expecting a login failure.
driver.findElement(loginButtonLocator).submit();
// Return a new page object representing the destination. Should the login page ever
// go somewhere else (for example, a legal disclaimer) then changing the method signature
// for this method will mean that all tests that rely on this behaviour won't compile.
return new HomePage(driver);
}
// Conceptually, the login page offers the user the service of being able to "log into"
// the application using a user name and password.
public HomePage loginAs(String username, String password) {
// The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
typeUsername(username);
typePassword(password);
return submitLogin();
}
}
2. Created Homepage class , I have added only a sample verification method here , may be you can add methods as per your application needs...
class HomePage {
private final WebDriver driver;
public HomePage(WebDriver driver) {
this.driver = driver;
// Check that we're on the right page.
if (!"HOME".equals(driver.getTitle())) {
// Alternatively, we could navigate to the login page, perhaps
// logging out first
throw new IllegalStateException("This is not the home page");
}
}
// below method is just a sample method
public HomePage verifyRecords() {
/// your homepage validation
return null;
}
}
Now we are going to see how to put the above class together and make it work as per your requirement...
class Test {
public static void main(String[] args) {
LoginPage login = new LoginPage(new FirefoxDriver());
// login and verify records in home page
login.loginAs("myname", "pass##").verifyRecords();
}
}
In this line login.loginAs("", "").verifyRecords(); we are calling a method from login class and the method that is being called would return HomePage class....
You can create any no of pom classes and return it like the above......Like create some thing like dashboard and return it from homepage class
How returning page works :-
login.loginAs("myname", "pass##").verifyRecords();
In the above code once this login.loginAs("myname", "pass##") snippet executes , it will complete the login action and returns this method submitLogin(); which in turns returns new HomePage......
Here once execution of login.loginAs("myname", "pass##") is done it will become new Homepageobject..... Javacompiler is smart enough to manipulate that and provides the Homepageobject's methods once you put a dot after login.loginAs("myname", "pass##").

Testing different Scenarios in “Selenium Cucumber with Java” without opening new Web browser

I have a feature file where i have 2 scenarios
Feature: Login to Online Store
Scenario: Login successful with valid credentials
Given User is on Home Page
When User navigates to Login Page
And User provides username and password
Then Message displays Login successfully
Scenario: User logout successfully
When User logouts from application
Then Message displays Logout successfully
Every time I run the RunFeatures.java file, after the first Scenario, driver to open new Browser to execute next Scenario. Can we use the same browser to execute the 2nd scenario?
Below is my code:
RunFeatures.java
package cucumbertest;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
#RunWith(Cucumber.class)
#CucumberOptions(features="src/test/java/features/"
,glue={"steps"}
,dryRun=false
,monochrome=false)
public class RunFeatures
{
}
ClientSteps.java:
package steps;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import cucumber.api.java.en.*;
import pages.HomePage;
import pages.LoginPage;
public class ClientSteps
{
WebDriver driver=new FirefoxDriver();
#Given("^User is on Home Page$")
public void user_is_on_Home_Page() throws Throwable {
new HomePage(driver).user_is_on_Home_Page();
}
#When("^User navigates to Login Page$")
public void user_navigates_to_Login_Page() throws Throwable {
new HomePage(driver).user_navigates_to_Login_Page();
}
#When("^User provides username and password$")
public void user_provides_username_and_password() throws Throwable {
new LoginPage(driver).user_provides_username_and_password();
}
#Then("^Message displays Login successfully$")
public void message_displays_Login_successfully() throws Throwable {
new LoginPage(driver).message_displays_Login_successfully();
}
#When("^User logouts from application$")
public void user_logouts_from_application() throws Throwable {
new LoginPage(driver).user_Logout_from_the_Application();
}
#Then("^Message displays Logout successfully$")
public void message_displays_Logout_successfully() throws Throwable {
new LoginPage(driver).message_displayed_Logout_successfully();
}
}
Homepage.java file
package pages;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.When;
public class HomePage
{
WebDriver driver;
public HomePage(WebDriver driver)
{
this.driver=driver;
}
public void user_is_on_Home_Page() throws Throwable {
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("http://www.store.demoqa.com");
}
public void user_navigates_to_Login_Page() throws Throwable {
driver.findElement(By.xpath(".//*[#id='account']/a")).click();
}
}
LoginPage.java
package pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class LoginPage
{
WebDriver driver;
public LoginPage(WebDriver driver)
{
this.driver=driver;
}
public void user_provides_username_and_password() throws Throwable {
// This is to get the first data of the set (First Row + First Column)
driver.findElement(By.id("log")).sendKeys("tri.nguyen");
// This is to get the first data of the set (First Row + Second Column)
driver.findElement(By.id("pwd")).sendKeys("Test#123");
driver.findElement(By.id("login")).click();
}
public void message_displays_Login_successfully() throws Throwable {
System.out.println("Login Successfully");
}
public void user_Logout_from_the_Application() throws Throwable {
driver.findElement (By.xpath(".//*[#id='account_logout']/a")).click();
}
public void message_displayed_Logout_successfully() throws Throwable {
System.out.println("Logout Successfully");
driver.quit();
}
}
As a good practice, test cases should be atomic. Automation Test case shouldn't be dependent on another test case for browser instance, data etc.
You rather should close all browser windows after every test case and open browser again as a new instance for a next test case.
Use #Before and #After in your stefdef file to achieve this.
as I am not able to add as a comment due to word restrictions, writing it here as a answer again! This is in continuation to my previous post. You can try this. Replace #Given by following
WebDriver driver;
#Before
public void setUp(){
driver=new FirefoxDriver();
}
#After
public void cleanUp(){
driver.quit();
}
#Given("^User is on Home Page$")
public void user_is_on_Home_Page() throws Throwable {
new HomePage(driver).user_is_on_Home_Page();
}
make sure you import following files only and not junit*
import cucumber.api.java.After;
import cucumber.api.java.Before;
I tried to modify my codes following your instruction but its getting NullPointer exception:
WebDriver driver;
#Before
public void setUp(){
WebDriver driver=new FirefoxDriver();
}
#After
public void cleanUp(){
driver.quit();
}
#Given("^User is on Home Page$")
public void user_is_on_Home_Page() throws Throwable {
new HomePage(driver).user_is_on_Home_Page();
}
Exception:
java.lang.NullPointerException
at pages.HomePage.user_is_on_Home_Page(HomePage.java:24)
at steps.ClientSteps.user_is_on_Home_Page(ClientSteps.java:30)
at ✽.Given User is on Home Page(Login.feature:4)
java.lang.NullPointerException
at steps.ClientSteps.cleanUp(ClientSteps.java:25)
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)
I'm again not able to add it as a comment :(.
You have declared and instantiated driver variable inside setup method which makes it local to setup method only. Declare driver at class level.
WebDriver driver;
#Before
public void setUp(){
driver=new FirefoxDriver();
}
This should work. Let me know in case you face any issues, we may get on hangout to resolve it.