Execute Cucumber Step Defination with multiple files with Page Object Model - selenium

I am trying to execute a Cucumber Feature file which Step Definition in two different files. All methods in first Step Defination is executed and when executing second one, It launches a new browser instance, instead of continuing with existing one.
Cucumber Feature file
Scenario: Given I open Firefox and Navigate to Guru
When I enter UserName and Password and login to guru
And I click on New Customer
Then New Customer Page is displayed
And I click on HomePage
Then HomePage is displayed
First Step Definition
package stepDefination;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import Pages.HomePage;
import Pages.NewCustomerPage;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class GuruStepDef {
WebDriver Driver;
NewCustomerPage customerPage;
HomePage homePage = new HomePage(Driver);
#When("^I enter UserName and Password and login to guru$")
public void I_enter_and_and_login_to_guru() {
homePage=homePage.setup();
homePage.navigateToWebApp();
}
#Then("^HomePage is displayed$")
public void Homepage_is_displayed() {
//assert
}
#Then("^I click on New Customer$")
public void I_click_on_New_Customer() {
customerPage= homePage.NavigateToCustomerPage();
}
#Then("^New Customer Page is displayed$")
public void New_Customer_Page_is_displayed() {
//assert
}
}
Second Step Definition
package stepDefination;
import org.openqa.selenium.WebDriver;
import Pages.HomePage;
import Pages.NewCustomerPage;
import cucumber.api.java.en.Then;
public class SmokeTest {
WebDriver Driver;
NewCustomerPage customerPage;
HomePage homePage = new HomePage(Driver);
#Then("^I click on HomePage$")
public void I_click_on_HomePage() {
homePage=customerPage.Manager();
}
}

In both classes, you have:
HomePage homePage = new HomePage(Driver);
You are creating two instances of HomePage. If you want to utilize the same object, you'll need to share it between the two classes. For example, you could create HomePage in one of the classes and use a getter in the other, or you could use a Singleton pattern in the object itself to ensure only one instance is created at a time.

Related

Getting as "Cannot invoke "org.openqa.selenium.WebDriver.findElement(org.openqa.selenium.By)" because "this.driver" is null."

I am trying to run a page object methods by cucumber. I am getting error out with driver null NPE errpr. Could you please help. I created Page Object Model file. A feature file describing scenario outline. And then in Test, I am trying to call the method by creating a object of Page Model java class
POM class:
package pages;
import javax.imageio.IIOException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class Pom {
static WebDriver driver;
By username=By.xpath("//*[#id='user-name']");
By password=By.xpath("//*[#id='password']");
By loginbutton=By.xpath("//*[#id='login-button']");
By logout=By.xpath("//*[contains(text(),'Logout')]");
By open_menu=By.xpath("//*[contains(text(),'Open Menu')]");
public Pom(WebDriver driver)
{
this.driver=driver;
//if (!driver.getTitle().equals("Swag Labs")) {
//throw new IIOException("This is not the login page. The current url is " +driver.getCurrentUrl());
}
//}
public void enter_username(String username1)
{
driver.findElement(username).sendKeys(username1);
}
public void enter_password(String password1)
{
driver.findElement(password).sendKeys(password1);
}
public void click_login()
{
driver.findElement(loginbutton).click();
}
public void check_logout()
{
driver.findElement(logout).isDisplayed();
}
public void click_open_menu()
{
driver.findElement(open_menu).click();
}
}
StepDefination:
package StepDefinations;
import java.time.Duration;
import javax.imageio.IIOException;
import org.junit.BeforeClass;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.cucumber.java.en.*;
import io.github.bonigarcia.wdm.WebDriverManager;
import pages.Pom;
public class PomTest {
public WebDriver driver;
Pom pom=new Pom(driver);
#Given("User launches the browser")
public void user_launches_the_browser() {
// Write code here that turns the phrase above into concrete actions
WebDriverManager.chromedriver().setup();
driver=new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(6));
driver.manage().window().maximize();
}
#Given("user navigate to the Login landing Page")
public void user_navigate_to_the_login_landing_page() throws InterruptedException {
// Write code here that turns the phrase above into concrete actions
driver.navigate().to("https://www.saucedemo.com/");
Thread.sleep(3000);
}
#When("^User enters the credentials as (.+) and (.+) $")
public void user_enters_the_credentials_as_and(String username, String password) throws Throwable {
// Write code here that turns the phrase above into concrete actions
// pom=new Pom(driver);
pom.enter_username(username);
Thread.sleep(3000);
pom.enter_password(password);
Thread.sleep(3000);
}
#And("User clicks on the login button after entering credentials")
public void user_clicks_on_the_login_button_after_entering_credentials() {
pom.click_login();
}
#Then("User lands on the user account home page and checks the logout button")
public void user_lands_on_the_user_account_home_page_and_checks_the_logout_button() {
// Write code here that turns the phrase above into concrete actions
pom.click_open_menu();
pom.check_logout();
}
#Then("the user closes the browser")
public void the_user_closes_the_browser() {
// Write code here that turns the phrase above into concrete actions
driver.close();
}
}
Faeture File:
Feature: Login functionality Test
Scenario Outline: Verify the login of the user on the particvular website
Given User launches the browser
And user navigate to the Login landing Page
When User enters the credentials as <username> and <password>
And User clicks on the login button after entering credentials
Then User lands on the user account home page and checks the logout button
And the user closes the browser
Examples:
|username|password|
|standard_user|secret_sauce|
|locked_out_user|secret_sauce|
|problem_user|secret_sauce|
|performance_glitch_user|secret_sauce|
I am expecting this code to run in a data driven way.
#user3857859 , in your step definition file, move the initialization of pom object to inside #Given("User launches the browser"), after you initialize the driver. so after changes your #Given should look like below:
public WebDriver driver;
Pom pom;
#Given("User launches the browser")
public void user_launches_the_browser() {
// Write code here that turns the phrase above into concrete actions
WebDriverManager.chromedriver().setup();
driver=new ChromeDriver();
pom=new Pom(driver);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(6));
driver.manage().window().maximize();
}
this way, you not sending the driver without initializing to your Pom constructor.

Can we bind pagefactory with assertions in selenium web driver?

I have written the following code
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.testng.Assert;
public class CreateGroup_Page {
public class CreateGroup{
public CreateGroup(WebDriver driver){
PageFactory.initElements(driver, this);
}
#FindBy(linkText = "CREATE A GROUP")
public WebElement menu_createGroup;
HOW CAN I ADD Assert.assertTrue WITH THE ABOVE PAGE OBJECT FACTORY.
//public WebElement menu_createGroup(WebDriver driver){
//WebElement element = driver.findElement(By.linkText("CREATE A GROUP"));
//Assert.assertTrue(menu_createGroup.isDisplayed());
//return element;
//}
//}
In the above case when I try with to call assertions with pagefactory objects, I cannot do so. However if I define seperate class and when I call it works fine as above. Please help me in how to call assertions with pagefactory.
In page factory the element is a variable which you have done correctly. Use an assert in method which I do not see in your code.
See this link for ex: https://code.google.com/p/selenium/wiki/PageFactory

What is Hybrid Driven and Keyword Driven in selenium?

Please give an example for Hybrid Driven and Keyword Driven using selenium. Thanks in advance!
Never heard about Hybrid driven testing, you might be referring to testing hybrid applications.
A hybrid application (hybrid app) is one that combines elements of
both native and Web applications. Native applications are developed
for a specific platform and installed on a computing device. Web
applications are generalized for multiple platforms and not installed
locally but made available over the Internet through a browser. Hybrid
apps are often mentioned in the context of mobile computing.
About Keyword driven testing, each keyword corresponds to an individual testing action like a mouse click, selection of a menu item, keystrokes, opening or closing a window or other actions. A keyword-driven test is a sequence of operations, in a keyword format, that simulate user actions on the tested application.
Posted below is a simple class for Hybrid (Modular and Data Driven) framework -
SearchData.java
Has the code for data to be used in the test.
package com.data;
public class SearchData {
private String url;
private String searchWord;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getSearchWord() {
return searchWord;
}
public void setSearchWord(String searchWord) {
this.searchWord = searchWord;
}
}
SearchPage.java
Contains modules of code.
package com.page;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import com.data.SearchData;
public class SearchPage {
WebDriver driver;
public SearchPage(WebDriver driver) {
this.driver = driver;
}
public void launchGoogle(SearchData searchData) {
driver.get(searchData.getUrl());
}
public void search(SearchData searchData) {
driver.findElement(By.name("q")).sendKeys(searchData.getSearchWord());
driver.findElement(By.name("btnG")).click();
}
}
GoogleTest.java
Contains the actual Junit Test.
package com.test;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import com.data.SearchData;
import com.page.SearchPage;
public class GoogleTest {
protected WebDriver driver;
#Before
public void setUp() {
driver = new FirefoxDriver();
}
#After
public void tearDown() {
driver.close();
driver.quit();
}
#Test
public void searchTest() throws InterruptedException {
// set the data
SearchData searchData = new SearchData();
searchData.setUrl("https://www.google.com");
searchData.setSearchWord("Selenium");
// call the methods
SearchPage searchPage = new SearchPage(driver);
searchPage.launchGoogle(searchData);
searchPage.search(searchData);
Thread.sleep(10000);
}
}
The above code is pretty basic and can be enhanced to a great extend.
As for Keyword driven framework use SELENIUM IDE / ROBOT FRAMEWORK.

Page Factory with properties

i m confused :( as automation framework if i use page object/factory than i should use object repository I mean Properties file in selenium webdriver.
OR
i can use one at a time either page factory or properties file approach.
i m using this code:
package Pages;
import java.util.Properties;
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;
public class LoginPage {
final WebDriver driver;
static Properties prop = new Properties();
#FindBy(how = How.ID, using = "form-login-username")
private WebElement usernameEditbox;
#FindBy(how = How.NAME, using = "password")
private WebElement passwordEditbox;
#FindBy(how = How.NAME, using = "Log In")
private WebElement loginButton;
public LoginPage(WebDriver driver) {
this.driver = driver;
}
public void enterUsername(String login) {
usernameEditbox.clear();
usernameEditbox.sendKeys(login);
}
/*public void enterUsername(String login) {
signInUsername.clear();
usernameEditbox.sendKeys(login);
}*/
public void enterPassword(String password) {
passwordEditbox.clear();
passwordEditbox.sendKeys(password);
}
public void clickSigninButton() {
loginButton.click();
}
public LandingPage login(String login, String password) {
enterUsername(login);
enterPassword(password);
clickSigninButton();
return PageFactory.initElements(driver, LandingPage.class);
}
}
Instead on defining #FindBy(how = How.ID, using = "form-login-username")
private WebElement usernameEditbox; in same file how i can call it from OR.properties ???
Here's a suggestion I made to somebody else using Page Object Pattern.
Properties files would be no different than just separating your elements to an elements class file and initializing them in the way I describe in the linked post.
Edit: Example of an elements class:
#FindBy(css = "button[id='Save']")
public static WebElement buttonSave;
#FindBy(css = "button[id='Cancel']")
public static WebElement buttonCancel;
And so on. The elements class is just meant to hold on to your elements. You then use those elements via the PageFactory.init example shown in the link above. It would be preferred to have a separate elements class for each "page." I hope that's clear enough :)
If you follow the page object pattern, then in theory each selector will only exist once. Therefore, it is acceptable to in affect hard code them in the page object class rather than create some kind of repository or external resource.
Take a look at Test Automation Framework (TAF) which have enhanced Page Object Factory implementation. It will allow you to use a properties file for your locators for your Page Factory classes.
You can mention a default locator file for your factory and can also override it at runtime (if required) by providing a external file.
http://menonvarun.github.io/taf/
http://menonvarun.github.io/taf/pages/locator_in_taf.html

Check links with getAllLinks

I´m testing application with selenium ide and rc. I need verify the links.
Usually I export file from Selenium ide to junit 4, and run file in eclipse. File is as next
package com.example.tests;
import com.thoughtworks.selenium.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.regex.Pattern;
public class login_csupport extends SeleneseTestCase {
#Before
public void setUp() throws Exception {
selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://daisy-w2003.hi.inet/CustomerSupport");
selenium.start();
}
#Test
public void testLogin_csupport() throws Exception {
selenium.open("http://daisy-w2003.hi.inet/CustomerSupport/?ReturnUrl=%2fCustomerSupport%2fAccount");
assertEquals("Calling Cards Customer Support - Inicio", selenium.getTitle());
selenium.type("UserName", "admin");
selenium.type("Password", "admin");
selenium.click("//div[#id='content']/div/form/div[3]/a/span[2]");
selenium.waitForPageToLoad("30000");
assertEquals("Calling Cards Customer Support - Gestión", selenium.getTitle());
}
#After
public void tearDown() throws Exception {
selenium.stop();
}
}
Using getAllLinks I´d like check the links of the page. Please, anyone can to help me??
Thanks
assertAllLinks(pattern) generated from getAllLinks()
Returns:
the IDs of all links on the page
Returns the IDs of all links on the page.
If a given link has no ID, it will appear as "" in this array.