Can't run my test JUnit step definition - testing

I want to run test JUnit i work in 2 different projets :
In the first one i have
The feature :
Feature: Google Search
Scenario: Validate google search text field
Given open a browser
When navigate to google page
Then validate search text field
The Step definition Class :
#Given("^open a browser$")
public void open_a_browser() throws Throwable {
System.setProperty("webdriver.chrome.driver", "D:\\Drive\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
}
#When("^navigate to google page$")
public void navigate_to_google_page() throws Throwable {
driver.get("http://www.google.com");
}
#Then("^validate search text field$")
public void validate_search_text_field() throws Throwable {
driver.findElement(By.name("q")).sendKeys("selenium "); }
And the Runner class :
#RunWith(Cucumber.class)
#CucumberOptions(features={"src\\test\\resources\\com\\tutoriel\\testing\\features\\Googlesearch.feature",
glue={"com\\tutoriel\\testing\\stepdefinitions"})
public class RunTestRunner {
}
And it works for me very good
but when i tr to add those 3steps (feature, stepdef and the runner ) in an big another project it doesn't work
i don't undersand the issue !!
this is the error
You can implement missing steps with the snippets below:
but i have already defined them in the class steps definition
Anyone can help me please

Related

How to manage the step definition code that needs to be reused again & again

My feature file contains a feature that needs to be reused by each and every step definition file again & again. How to manage the code
My feature is :-
"User is on home Page".
The above feature / scenario contains a code that needs to be reused again & again. In my code base , for every feature file i have written separate step definition.
My first step definition file :-
#Given ("^user is on HomePage$")
public void user_homePage()
{
configFileReader =new ConfigFileReader();
System.setProperty("webdriver.chrome.driver","D:\\chromedriver.exe");
driver=new ChromeDriver();
driver.get("https://parabank.parasoft.com/parabank/index.htm");
driver.manage().window().maximize();
}
Now the same feature needs to be used in another step definition file. i.e
here below
Before user clicks on 'Register' link , it should verify that user is on homePage. The description of 'User is on home page' is defined in first step definition file .
Now how to manage the code here :-
My Second Step definition file here below:-
import StepFiles.ParaBank_TC_01_Step; [ I have even imported first step definition file , so that feature "User is on home page" could be executed. ]
public class ParaBank_TC_02_Step {
public WebDriver driver;
ConfigFileReader configFileReader;
#When ("^user clicks on register link$")
public void click_register() throws InterruptedException
{
Thread.sleep(3000);
WebElement register_link= driver.findElement(By.xpath("//a[contains(text(),'Register')]"));
register_link.click();
}
Actual Result :-
1. When i write all the step definition for 2 features files in one file , then it executes perfectly fine , because feature 'User is on home page' is defined in one same file.
As i write separate step definition for feature 2 in another java file. It shows me "Null pointer exception" error because on feature "User is on home page" > driver is initialised in 1 step def file . It isn't executing for second step definition file.
Please help me out in understanding the root cause of this issue & provide the best possible solution.
In order to share state between steps, you can use dependency injection (DI). Cucumber offers support for several DI frameworks. We recommend you use either the one your application already uses / you are familiar with (in my case, that is Spring). Otherwise, we recommend PicoContainer as the most lightweight option.
You can find a little more information about using DI in the Cucumber docs and the related code on GitHub.
For more information on using PicoContainer, see this blogpost.
To use Spring, please have a look at my blogpost.
To use Guice, have a look at this blogpost.
Sidenote:
Feature-coupled step definitions (defining the step definitions for each feature in a separate file, in a way so that they cannot be reused across features), is considered an anti-pattern, as "This may lead to an explosion of step definitions, code duplication, and high maintenance costs."
(from the Cucumber docs).
The solution is to decouple your step definitions:
"
* Organise your steps by domain concept.
Use domain-related names (rather than feature- or scenario-related names) for your step & step definition files."
(from the Cucumber docs).
In order to do so, you will need to use DI.
If you are interested to implement PicoContainer, please follow below steps for good understanding :
Step 1. OrderSelectionStepDef & OrderDetailsStepDef would look like below (please change name as per your implementation)
/**
* Step Definition implementation class for Cucumber Steps defined in Feature file
*/
public class HomePageSteps extends BaseSteps {
TestContext testContext;
public HomePageSteps(TestContext context) {
testContext = context;
}
#When("^User is on Brand Home Page (.+)$")
public void user_is_on_Brand_Home_Page(String siteName) throws InterruptedException {
homePage = new HomePage().launchBrandSite(siteName);
testContext.scenarioContext.setContext(Context.HOMEPAGE, homePage);
}
#Then("^Clicking on Sign In link shall take user to Sign In Page$")
public void clicking_on_Sign_In_link_shall_take_user_to_Sign_In_Page() {
homePage = (HomePage) testContext.scenarioContext.getContext(Context.HOMEPAGE);
signInPage = homePage.ecommSignInPageNavigation();
testContext.scenarioContext.setContext(Context.SIGNINPAGE, signInPage);
}
For your reference
public class BaseSteps {
protected HomePage homePage;
protected PLPPage plpPage;
protected PDPPage pdpPage;
protected ShoppingBagPage shoppingBagPage;
protected ShippingPage shippingPage;
More implementation goes here.....
}
Step 2. Please add below 2 Classes under your framework -
First, Java file name - ScenarioContext.java
public class ScenarioContext {
private Map<String, Object> scenarioContext;
public ScenarioContext(){
scenarioContext = new HashMap<String, Object>();
}
public void setContext(Context key, Object value) {
scenarioContext.put(key.toString(), value);
}
public Object getContext(Context key){
return scenarioContext.get(key.toString());
}
public Boolean isContains(Context key){
return scenarioContext.containsKey(key.toString());
}
}
Second, Java file name - TestContext.java
public class TestContext {
public ScenarioContext scenarioContext;
public TestContext(){
scenarioContext = new ScenarioContext();
}
public ScenarioContext getScenarioContext() {
return scenarioContext;
}
}
Step 3. POM Dependency - picocontainer shall be as per your cucumber version
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>${cucumber.version}</version>
</dependency>

How to make an executable jar file using IntelliJ from a Selenium/Junit java file?

I am trying to generate a jar file of my test to use it in JMeter, I am trying this solution How to make an executable jar file using IntelliJ from a Selenium/TestNG java file? but the problem in on step 4.
4- Select your main class using the browse button.
When I search for class I can't select mine .java code, how I can do the step 4 possible?
My code
public class Jmeter {
WebDriver driver = null;
#Test
public void testLoad() {
// Robot robot = new Robot();
ChromeOptions options = new ChromeOptions();
options.addArguments(Arrays.asList("disable-infobars", "ignore-certificate-errors", "start-maximized","use-fake-ui-for-media-stream"));//
System.setProperty("webdriver.chrome.driver", "/usr/bin/chromedriver.exe");
WebDriver driver = new ChromeDriver(options);
driver.get("myurl");
my commands
}
}
Does someone know how to solve this?
Solution
I created a class with the main method to call my test.
package Jmeter;
public class JmeterMain {
public static void main(String[] args) {
Jmeter test = new Jmeter();
test.testLoad();
}
}

Cucumber- // Write code here that turns the phrase above into concrete actions

I Tried to execute the same test with different data but I am getting the following error when I tried to run the test
You can implement missing steps with the snippets below:
#When("^Enter the ADMIN and password(\\d+)$")
public void enter_the_ADMIN_and_password(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
Below is my Feature file
Scenario Outline: Login
Given Open chrome and login
When Enter the <Username> and <Password>
Then Click on Login
Examples:
|Username |Password |
|ADMIN |password123|
Below is the #when annotation part in Steps file
#When("^Enter the \"(.*)\" and \"(.*)\"$")
public void enter_the_Username_and_Password(String username,String Password) throws Throwable
{
System.out.println("This step enter the Username and Password on the login page."+username +Password);
loginObj.Login(driver);
}
It may be occurring due to cucumbers packages is misconfigured. Check the GLUE options
#RunWith(Cucumber.class)
#CucumberOptions(
features = { "src/test/resources/features/CucumberTests.feature" },
tags = { "#integration_test"},
glue = { "br.com.cucumber.integration.stepDefinition" },
format = { "pretty", "html:target/reports/cucumber/html", "json:target/cucumber.json", "usage:target/usage.jsonx", "junit:target/junit.xml" })
#ContextConfiguration(classes= AppConfiguration.class)
public class CumcumberTest extends BaseTestCase {
}
I think what you are describing as an "error" is in fact cucumber telling you that is not able to find the matching definition for the step "When Enter the Username and Password" and has auto-generated the example definition below based on the scenario outline data:
#When("^Enter the ADMIN and password(\\d+)$")
public void enter_the_ADMIN_and_password(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
The problem is that your step definition is using quotes on the parameters but your actual step has no quotes, hence cucumber is not able to match them. You either need to change your step in the feature file to include quotes:
When Enter the "<Username>" and "<Password>"
Or you need to change the step definition to not include quotes:
#When("^Enter the (.*) and (.*)$")
public void enter_the_Username_and_Password(String username,String Password) throws Throwable
{
System.out.println("This step enter the Username and Password on the login page."+username +Password);
loginObj.Login(driver);
}
I got the same error. For me the problem was that I created step definition in the package for back end tests instead of front end ones. If the step definition classes have same or similar names, it is possible to make a mistake. This would happen during chosing the wrong package while creating step definition from the feature file in Intellij.
I was getting this issue and discovered the reason was I accidentally gave the name of the class and not the package for the glue code:
The wrong argument value for my gluecode was my class as: gluecode="StepDefinition", when it should have been my package: gluecode="stepDefs"
My TestRunner.java looks as follows:
package testRunner;
import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
#RunWith(Cucumber.class)
#CucumberOptions(
features = "src/test/java/features",
glue = "stepDefs")
public class TestRunner {
}
I got the same error. In my case I was forgetting the .step. part in my file name.
So I've solved by modifying my file name from:
mystepfile.ts
to:
mystepfile.step.ts

Selenium WebDriver based framework using POM with java

I am trying to write code to validate a webpage (Test Form with 3 required fields firstname, lastname, phone and 2 buttons submit and clear form) using POM with Selenium WebDriver with Java.
This is the code which I have written so far. I want to confirm whether I am going in the right way.
public class TestForm {
WebDriver driver;
By firstName=By.id("fname");
By lastName=By.id("lname");
By phoneno=By.id("phone");
By submit=By.id("submit");
By clearForm=By.xpath("//tagname[#type='button']");
public TestForm(WebDriver driver)
{
this.driver=driver;
}
public void typeFirstName(String fname)
{
driver.findElement(firstName).sendKeys(fname);
}
public void typeLastName(String lname)
{
driver.findElement(lastName).sendKeys(lname);
}
public void typePhone(String phone)
{
driver.findElement(phoneno).sendKeys(phone);
}
public void clickSubmit()
{
driver.findElement(submit).click();
}
public void clickClearForm()
{
driver.findElement(clearForm).click();
}
}
public class VerifyTestForm {
#Test
public void verifyValidTestForm()
{
WebDriver driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get("url of the application");
TestForm form=new TestForm(driver);
form.typeFirstName("John");
form.typeLastName("Adams");
form.typePhone("1234567890");
form.clickSubmit();
form.clickClearForm();
driver.quit();
}
}
Most code look good, except following items:
1) By clearForm=By.xpath("//tagname[#type='button']");
tagname should be a correct tag, like button or 'input'
2) After click Submit, the page still stay the form page, If so call clickClearForm should work.
form.clickSubmit();
form.clickClearForm();
3) There is no any check point/validation in your code, all are operateion on page.
// Assume an new page will open after click Submit button
// You need to check the new page opened by check page title if it'll change
// or check an element belongs to the new page is displayed
Assert(driver.getTitle()).toEqual('xxx')
Assert(driver.findElement(xxx).isDisplay()).toBe(true)
// above code may not exact correct, dependent on you choose Junit, TestNG
// or third-party Assert library.
// After click `Clear/Reset` button, you should check all fields reset to default value
Assert(form.readFirstName()).toEqual("")
4) For test class name VerifyTestForm, it's better start or end with Test, like Testxxx or xxxTest
As your code is correct but it is not the way to implementing Page object Model.
You have to use concept of DataProvider to implement framework.
Make a excel sheet and extract the data by using DataProvider.
Make a new class file from where you can read your excel data.
Make a function which return 2d data of the file.
So By using this, The way to implement the framework.
Page object Model generally says that we should have to make the separate page of each module which we are using and return the reference of the last page.

How to generate test report using selenium web driver

I want to know is any other option available to generate test report except TestNG framework in selenium webdriver
You can try ExtentReports: http://extentreports.com. An example:
public class Main {
public static void main(String[] args) {
// start reporters
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter("extent.html");
// create ExtentReports and attach reporter(s)
ExtentReports extent = new ExtentReports();
extent.attachReporter(htmlReporter);
// creates a toggle for the given test, adds all log events under it
ExtentTest test = extent.createTest("MyFirstTest", "Sample description");
// log(Status, details)
test.log(Status.INFO, "This step shows usage of log(status, details)");
// info(details)
test.info("This step shows usage of info(details)");
// log with snapshot
test.fail("details", MediaEntityBuilder.createScreenCaptureFromPath("screenshot.png").build());
// test with snapshot
test.addScreenCaptureFromPath("screenshot.png");
// calling flush writes everything to the log file
extent.flush();
}
}
try Allure reporting framework
https://github.com/allure-framework
Hope this helps