Cucumber Junit Testing Code - selenium

I tried to work with webdriver to see if the cucumber will open browser with junit. It is recognizing everything except for opening the web browser or even doing what I asked to do. Here is the code snippet:
public class JobSearch {
WebDriver driver;
#Test
public void JobSearchSteps()
{
driver = new FirefoxDriver();
driver.navigate().to("http://www.careerbuilder.com");
}
#Given("^I am on the page Find Jobs$")
public void I_am_on_the_page_Find_Jobs()throws Throwable{
System.out.println("******************************");
System.out.println("#Given -- I am on the page Find Jobs");
}
#When("^I enter \"([a-zA-Z]{1,})\" in the Keywords textbox$")
public void I_enter_QA_in_the_Keywords_textbox(String Job){
driver.findElement(By.id("s_rawwords")).sendKeys(Job);
System.out.println("The search is "+Job);
}
#And("^I enter\"([a-zA-Z]{1,})\" in the Location textbox$")
public void I_enter_my_location_in_the_Location_textbox(String Loc)throws Throwable{
System.out.println("The location is "+ Loc);
driver.findElement(By.id("s_freeloc")).sendKeys(Loc);
}
#And ("^I Select\"([a-zA-Z]{1,})\" from the Careers Category List$")
public void I_Select_from_the_Careers_Category_List(String Option)throws Throwable{
WebElement ListBox =driver.findElement(By.id("s_jobtypes"));
List options = ListBox.findElements(By.tagName(Option));
}
#And ("^I click the button Find Jobs$")
public void I_click_the_button_Find_Jobs()throws Throwable{
driver.findElement(By.id("qsbButton")).click();
}
#Then("^the page Jobs should be shown$")
public void the_page_Jos_should_be_shown()throws Throwable{
}
}

You cannot combine Junit annotations with Cucumber annotations. I suggest you to remove #Test annotation. You should rather write a step to launch the site and implement it. For example put this at the top of your scenario,
Given I navigate to "http://www.careerbuilder.com"
This will translate to a step like,
#Given("^I navigate to \"([^\"]*)\"$")
public void I_navigate_to_site(String url) throws Throwable {
driver = new FirefoxDriver();
driver.navigate().to(url);
}

Related

Selenium : Does not identify second element from tabbar

I am using TestNG with java to execute my scripts.
I have a fixed tab bar with 5 elements fixed for all time once the user logged in to the application.
I am able to execute the script by clicking on the first element from the list, but for the second time when I try to click on another element from the tab bar it is failing continuously. I tried adding explicit waits, but is not helping me either.
Here is a snippet of my code:
afterLogin.java
public class afterLogin {
WebDriver driver;
WebDriverWait wait;
#FindBy(xpath="//*[#id=\"root\"]/div/div[2]/div/div[1]/div[1]/div[3]")
WebElement button1;
#FindBy(xpath = "//*[#id=\"root\"]/div/div[2]/div/div[1]/div[1]/div[2]")
WebElement button2;
public afterLogin(WebDriver driver){
this.driver = driver;
wait = new WebDriverWait(driver,Duration.ofSeconds(300));
}
public void clickButton1() {
wait.until(ExpectedConditions.visibilityOf(button1);
button1.click();
}
public void clickButton2(){
wait.until(ExpectedConditions.visibilityOf(button2));
button2.click();
}
}
testCase1.java
#Test
public void init() throws Exception {
afterLogin obj = PageFactory.initElements(driver, afterLogin.class);
obj.clickButton1();
}
testCase2.java
#Test
public void init() throws Exception {
afterLogin obj = PageFactory.initElements(driver, afterLogin.class);
obj.clickButton2(); /////THIS IS FAILING
}
I was able to solve this by using Thread.sleep(1000). I will try to update my code to use Implicit waits, but this solves the purpose for now.

Standard approach for multi browser test execution in Selenium Jupiter

I went through Selenium Jupiter manual and still cannot get the idea of how I can set multiple
browsers in Selenium Jupiter to run every test in every browser.
Should use Test Template for that purpose?
Again I did not see an example of how can I do it in Selenium Jupiter?
p.s. An example with RemoteDrivers on Selenium Grid.
Here is my attempt to do it:
public class BaseTestWithRemoteDrivers {
#RegisterExtension
static SeleniumExtension extension = new SeleniumExtension();
#BeforeAll
public static void setupAll() {
extension.getConfig().setSeleniumServerUrl("http://localhost:4444/wd/hub");
Browser chrome = BrowserBuilder.chrome().build();
Browser firefox = BrowserBuilder.firefox().build();
extension.addBrowsers(chrome, firefox);
}
#Test
public void testWithBrowser(WebDriver driver) {
driver.get("https://www.google.com");
}
#AfterAll
public static void tearDownAll(WebDriver driver) {
driver.quit();
}
Unfortunately, only the Chrome browser will open.
Upd: I also found that there is a message saying:
Browser list for context id is not found. Not sure how to set up Browsers List if it is needed.
So far I did not find multi browsers support except by explicitly putting the browsers type into mvn command like below:
mvn verify -Dtest=BaseTest
-Dsel.jup.selenium.server.url=http://localhost:4444/wd/hub
-Dsel.jup.default.browser=chrome
-Dsel.jup.default.version=80.0.3987.106
#ExtendWith(SeleniumExtension.class)
public class BaseTest {
#Test
public void testNumber1(RemoteWebDriver driver) throws {
driver.get("https://www.google.com/");
}
#AfterAll()
public static void tearDown(RemoteWebDriver driver) {
driver.quit();
}
}
Update:
I figured out the way I can do it with Test Template too.
Below is the working example:
public class MultiBrowserTestTemplate {
#RegisterExtension
static SeleniumExtension extension = new SeleniumExtension();
#BeforeAll
static void setup() {
String browsersList = System.getProperty("prop.browsers.list");
List<String> browsers = Arrays.asList(browsersList.split(","));
if (browsers.contains("chrome")) {
extension.addBrowsers(BrowserBuilder.chrome().version("80.0.3987.106").build());
}
if (browsers.contains("firefox")) {
extension.addBrowsers(BrowserBuilder.firefox().version("73.0").build());
}
}
}
public class MultiBrowserDemoTest extends MultiBrowserTestTemplate {
#TestTemplate
public void testInMultipleBrowsers(WebDriver driver) {
driver.get("https://www.google.com/");
WebElement search = driver.findElement(By.name("q"));
search.sendKeys("JUnit5 extensions");
search.submit();
}
And the maven command goes like this:
mvn verify -DMultiBrowserDemoTest
-Dsel.jup.selenium.server.url=http://localhost:4444/wd/hub
-Dprop.browsers.list=chrome,firefox

Running selenium, cucumber and Page Factory. Second step definition fail to run

I wrote a cucumber framework that has two feature files and two stepdefinitions which are glued to the feature files. When i run the test together, it ran for the first stepDefinition and fail to enter the second stepDefinition. I have initialize my pages and yet couldn't get it to work.
Error and Codes below
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 Pages.HomePage.CreateANewOrderPage.createOrderLink(CreateANewOrderPage.java:35)
at StepDefinitions.CreateOrderStep.user_click_on_create_a_new_order(CreateOrderStep.java:24)
at ✽.When user click on create a new order(CreateOrder.feature:5)
public class CreateANewOrderPage {
WebDriver driver;
public CreateANewOrdePage(WebDriver driver){
this.driver=driver;
PageFactory.initElements(driver, this);
}
#FindBy (linkText= "Create a new order")
public WebElement createOrderLink;
public void createOrderLink(){
createOrderLink.click();
}
public class SigninPage {
WebDriver driver;
public SigninPage(WebDriver driver) {
this.driver=driver;
PageFactory.initElements(driver, this);
}
#FindBy(xpath="//*[#id=\"userName\"]")
public WebElement usernameField;
#FindBy(name="password")
public WebElement passwordField;
#FindBy(id="buttonSubmitLogin")
public WebElement submitBtn;
public void loginDetails(String uname, String psw) {
usernameField.sendKeys(uname);
passwordField.sendKeys(psw);}
public void clickLogin(){
submitBtn.click();
}
}
public class SigninStep {
WebDriver driver;
SigninPage logIn = new SigninPage(driver);
#Given("^user navigates to mySite$")
public void userNavigatesToMysite() throws Throwable {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\mypc\\Documents\\Automation\\drivers\\chromedriver.exe");
driver=new ChromeDriver();
driver.get("www.com");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#And("^user enter \"([^\"]*)\" and \"([^\"]*)\"$")
public void userEnterValidCredentials(String validuname, String validpsw) throws Throwable {
SigninPage logIn = new SigninPage(driver);
logIn.loginDetails("jdjdjdj","jjdjdj");
}
#When("^user click on Sign in$")
public void userClickSignIn() throws Throwable {
SigninPage logIn = new SigninPage(driver);
logIn.clickLogin();
}
}
public class CreateOrderStep {
WebDriver driver;
CreateANewOrderPage ordercreate;
#When("^user click on create a new order$")
public void user_click_on_create_a_new_order() throws Throwable {
ordercreate= PageFactory.initElements(driver,CreateANewOrderPage.class);
ordercreate.createOrderLink();
}
#RunWith(Cucumber.class)
#CucumberOptions (features = "src\\test\\java\\Features\\",
glue ={"StepDefinitions"},
tags={"#Signin, #CreateOrder"}
//format = {"pretty", "html:target/Destination.."}
// format={"json:target/Destination/cucumber.json"
)
public class SigninRunner {
}

Null Pointer exception using Page object model with Cucumber

I have used Page Object Model design pattern along with Cucumber. So for this I have created two pages named as abstractPage and loginPage but on running the script i get null pointer exception even when i have already initialize the webelements using pagefactory , please have a look at below code:
abstractPage:
public class abstractPage {
protected WebDriver driver;
public static loginPage lpOBJ;
public void openBrowsernURLhit() {
driver=new FirefoxDriver();
driver.get("http://www.facebook.com");
PageFactory.initElements(driver, loginPage.class);
}
}
loginPage:
public class loginPage extends abstractPage {
#FindBy(name = "email")
public WebElement username;
#FindBy(name = "pass")
public WebElement password;
#FindBy(id = "u_0_2")
public WebElement loginButon;
public void loginIntoApp() {
String url=driver.getCurrentUrl();
System.out.println("the url is::::::::::::::::"+url);
username.sendKeys("testuser");
password.sendKeys("123");
}
public void clicklogn() {
loginButon.click();
}
}
And then I have a class stepDefination from where I am calling the above methods of login class. Browser is opened fine and url is hit but when it goes inside loginintoapp() method it throws exception on first line itself.
public class SmokeTest {
#Given("^Open Firefox and start application$")
public void Open_Firefox_and_start_application() throws Throwable {
abstractPage obj = new abstractPage();
obj.openBrowsernURLhit();
}
#When("^I enter valid \"([^\"]*)\" and \"([^\"]*)\"$")
public void I_enter_valid_username_and_password(String arg1, String arg2) throws Throwable {
loginPage lpobj = new loginPage();
lpobj.loginIntoApp();
}
#Then("^user should be able to login successfully$")
public void user_should_be_able_to_login_successfully() throws Throwable {
loginPage lpobj = new loginPage();
lpobj.clicklogn();
}
}
I also have a TestRunner class where i have glued my stepDefination:
#RunWith(Cucumber.class)
#CucumberOptions(
features= "features",
glue= {"stepDefination"},
plugin= {"html:target/cucumber-html-report"}
)
public class TestRunner {
}
But on running the above script I always get NullPointerException in first line ofloginIntoApp() method.I have already used Pagefactory to initialize webelements but i guess "driver" variable is not getting initialized in Login class though i have inherited asbtract class where i m instantiating the driver due to which it is throwing null pointer.Please see what I am i doing wrong here.Error is as follows:
1 Scenarios ([31m1 failed[0m)
3 Steps ([31m1 failed[0m, [36m1 skipped[0m, [32m1 passed[0m)
0m18.149s
java.lang.NullPointerException
at pages.loginPage.loginIntoApp(loginPage.java:22)
at stepDefination.SmokeTest.I_enter_valid_username_and_password(SmokeTest.java:33)
at ?.When I enter valid "t1#gmail.com" and "pass"(MyApp.feature:5)
Thanks
please add the following constructor. It may solve the issue.
public loginPage(){
PageFactory.initElements(driver, loginPage.class);
}
you can put outside as well like,
public void loginIntoApp() {
String url=abstractPage.driver.getCurrentUrl();
System.out.println("the url is::::::::::::::::"+url);
loginPage lp=PageFactory.initElements(abstractPage.driver, loginPage.class);
lp.username.sendKeys("testuser");
lp.password.sendKeys("123");
}
other way is,
public class SmokeTest extends abstractPage {
#Given("^Open Firefox and start application$")
public void Open_Firefox_and_start_application() throws Throwable {
openBrowsernURLhit();
}
#When("^I enter valid \"([^\"]*)\" and \"([^\"]*)\"$")
public void I_enter_valid_username_and_password(String arg1, String arg2) throws Throwable {
loginPage lpobj = PageFactory.initElements(driver, loginPage.class);
lpobj.loginIntoApp();
}
#Then("^user should be able to login successfully$")
public void user_should_be_able_to_login_successfully() throws Throwable {
loginPage lpobj = PageFactory.initElements(driver, loginPage.class);
lpobj.clicklogn();
}
}
the simplest way to solve the problem is to make your driver object static.
protected static WebDriver driver;
as you are using page factory, you also need to initiazlize the page object, otherwise all the the WebElement will be null
public loginPage(){
PageFactory.initElements(driver, this);
}
or this, which I don't think is a good practice and people should avoid this.
public void loginIntoApp() {
String url=driver.getCurrentUrl();
System.out.println("the url is::::::::::::::::"+url);
PageFactory.initElements(driver, this);
username.sendKeys("testuser");
password.sendKeys("123");
}

Parallel execution using POM with PageFactory

I started encountering problems when I use static objects reference for WebDriver and run the tests in parallel.
public static WebDriver driver;
Hence I decided to use non-static object reference for the WebDriver.
private WebDriver driver;
Now when I use POM with Page Factory, my understanding is that everytime I create a Test I will have to be creating a new Object in the test class as shown below.
/* Constructor in the Page Object class */
private WebDriver driver;
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
2 testcases as shown below in the same class.
private LoginPage loginPage;
#Test
public void testCase1() {
loginPage = new LoginPage(getDriver());
loginPage.sendkeys("sometext");
}
#Test
public void testCase2() {
loginPage = new LoginPage(getDriver());
loginPage.sendkeys("sometext");
}
My question here is a
Am I right in creating page object for every test cases?
Is there any way I can optimize this? Because One doubt I got is that non-static object reference may be getting overridden and causing problems in one of the methods if I run them in parallel.
Sorry if my query is naive. Any help would be appreciated.
You do not need to initialize it again. Also, initialize the pages in #BeforeTest rather than in test cases.
Here i would like to give you example of Page object model. Hope you can relate this.
My Main test:
#Before
public void SelectBrowser(){
driver = WebUtils.SelectBrowser(driver,"Chrome");
}
#Test
public void LoginToGmail() throws InterruptedException{
//WebDriver driver = new FirefoxDriver();
//MAximize the Screen
driver.manage().window().maximize();
//Go to Gmail Login Page
SignInPage SignInPage = new SignInPage();
WebUtils.GoToSignInPageForPropertyFile(driver, "URL");
//Click on Next
SignInPage.ClickToLogin(driver, By.cssSelector("input[id='next']"));
Now Supporting class:
GoToSignInPageForPropertyFile method will be in WebUtils
Whatever i write in Webutils will be used by each page object class.
For e.g.
public class WebUtils {
public static pageobject.SignInPage GoToSignInPageForPropertyFile(WebDriver driver, String URL) {
ReadFileData File = new ReadFileData();
Properties Values = File.ReadFile();
driver.get(Values.getProperty("URL"));
return PageFactory.initElements(driver, pageobject.SignInPage.class);
}
}
Now the method ClickToLogin is defined under SignInPage class as:
public class SignInPage {
public EmailViewPage ClickToLogin(WebDriver driver, By by) {
WebUtils.Click(driver, by);
return PageFactory.initElements(driver, EmailViewPage.class);
}
}
Which will further be in Webutils
public class WebUtils {
public static void Click(WebDriver driver, By by) {
WebElement Element = driver.findElement(by);
Element.click();
}
}