How to integrate Selenium Webdriver with Cucumber - selenium-webdriver

I am looking to integrate Selenium Webdriver with Cucumber. Please let me know if anyone has already implemented the same.

You need the Cucumber-JVM. After that when you write feature files you need to define their steps definitions using Selenium (this could be your POM Based project or direct api call).
Below are links on how to go about implementing this
Links
http://cukes.info/install-cucumber-jvm.html
http://cukes.info/running.html
Snippets
Feature Sample
Feature: Page Verification
Scenario: Verify Page
Given User navigated to Page
And user SignUp
Then user should be redirected to Login
When User click "https://page.com/userLogin/"
Then User Should verify "Login"
And close browsers
Steps Definition
public class StepsDefinitions {
WebDriver driver = null;
#Given("^User navigated to \"([^\"]*)\"$")
public void gotoSite(String link) throws Throwable {
driver = new FirefoxDriver();
driver.navigate().to(link);
}
#When("^User click \"([^\"]*)\"$")
public void clickSignUp(String link) throws Throwable {
driver.findElement(By.linkText(link)).click();
}
#Then("^User Should verify \"([^\"]*)\"$")
public void User_Should_verify(String title) {
Assert.assertTrue( driver.getTitle().equals(title));
}
#And("^close browsers$")
public void close_browsers() throws Throwable {
driver.close();
}

I would recommend you to go through the detailed quick set-up instructions in the link.
Resource: Blog Thomas Sundberg

Related

How to test single registration page using selenium web driver and provide test report to development team?

I know basic selenium web driver and also written code using Page Object Model in TestNG frame work for one small application registration and login page.
Bu i don't know, how can provide test report to development team and what are the check points for automation testing please help me.
Example:
Assume my application have two pages like Registration and signin page
My code:
public class Sample {
Authentication_Locators authenticate;
WebDriver d = null;
#BeforeTest
public void beforeTest() throws Exception {
d = InitDriver.wbDriver("chrome", testData.getProperty("testUrl"));
authenticate = PageFactory.initElements(d,
Authentication_Locators.class);
}
#Test (priority = 0)
public void signIn() throws Exception {
Thread.sleep(1000);
authenticate.userName.sendKeys("user1");
authenticate.password.sendKeys("password1");
authenticate.signin.Click();
}
}
TesgNG creates HTML report of the execution which is located in the current working directory under results folder with name emailable_report. Also for more accurate reports you can also use Soft and hard asserts.
Hope this helps.

cucumber giving null pointer exception with multiple scenario in feature file

Test Steps
public class TestSmoke {
WebDriver driver;
#Given("^open firefox and start application$")jjj
public void open_firefox_and_start_application() throws Throwable {
driver=new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
driver.get("https://example.com");
}
**Scenario 1**
#When("^I click on Login$")
public void I_click_on_Login() throws Throwable {
driver.findElement(By.xpath("//a[contains(.,'Login')]")).click();
}
#When("^enter valid \"([^\"]*)\" and valid \"([^\"]*)\"$")
public void enter_valid_and_valid(String uname, String pass) throws Throwable {
driver.findElement(By.id("Username")).sendKeys(uname);
driver.findElement(By.id("Password")).sendKeys(pass);
}
#Then("^Click on login and User should be able to login successfully$")
public void Click_on_login_and_User_should_be_able_to_login_successfully() throws Throwable {
driver.findElement(By.id("loginUser")).click();
}
jkjbjkkjhjknjkbjkhjkbjbjbbjbnmbbnmb
**Scenario 2:**
#Given("^Click on shop for carts$")
public void Click_on_shop_for_carts() throws Throwable {
hhjbhbhgjbkjbhlhihjbhbb
driver.findElement(By.xpath("//span[text()='Shop for Parts']")).click();
}
#Given("^select plates$")
public void select_plates() throws Throwable {
driver.findElement(By.xpath("//a[contains(.,'Plates ')]")).click();
}
#When("^I click on drsired product$")
public void I_click_on_drsired_product() throws Throwable {
driver.findElement(By.xpath("//a[#data-itemnumber='PLT01096096046']")).click();
}
#When("^click on item increment$")
public void click_on_item_increment() throws Throwable {
WebElement ele=driver.findElement(By.xpath("//i[contains(#class,'fa fa-caret-up')]"));
for(int i=0;i<=3;i++)
{
ele.click();
}
}
#When("^Click on buy now$")
public void Click_on_buy_now() throws Throwable {
driver.findElement(By.xpath("//button[contains(.,'Buy Now')]")).click();
}
#Then("^Product should be added to the cart successfully$")
public void Product_should_be_added_to_the_cart_successfully() throws Throwable {
}
Feature File
Feature: Test test Smoke scenario
Scenario: Test login with valid credentials
Given open firefox and start application
When I click on Login
And enter valid "s#yopmail.com" and valid "passw0rd"
Then Click on login and User should be able to login successfully
Scenario: Test shop for cart
Given Click on shop for carts
And select plates
When I click on drsired product
And click on item increment
And Click on buy now
Then Product should be added to the cart successfully
Test runner
#RunWith(Cucumber.class)
#Cucumber.Options(features="features",glue={"steps"})
public class TestRunnr {
While i am running this cucumber script its throwing an NullPointer Exception :
java.lang.NullPointerException
at steps.testmoke.Click_on_shop_for_carts(testSmoke.java:47)
at ?.Given Click on shop for carts(MyApplication.feature:11)
First scenario is executing successfully but second scenario is not executing.I am login in a ecommerce website and try to click on shop for parts .
Each scenario creates a fresh instance of all the step definitions.
In your case you instantiate the driver in the Given step public void open_firefox_and_start_application() so the first scenario is successful.
Now for the second scenario a new instance of your class has a webdriver which is null and you are not calling the earlier step to instantiate it.
You can use a static webdriver, but you will run into issues with parallel tests. If you are planning for parallel tests look up ThreadLocal to make sure your webdriver is attached to the specific thread.
Another way could be to move the login tests to a separate file. For the other scenarios move the login steps into the Background cucumber tag. This way the webdriver will be instantiated for each scenario. But you will need to decide if you want to keep logged in across scenarios, delete cookies or a new browser for each scenario.

I am getting null pointer exception for webelement defined under #FindBy annotation in page factory model

I'm new in Selenium learning. I'm getting null pointer exception when I try to use web element - Milestone_Tile_Text.click; in my code but it works fine when I use
LoginTestScript.fd.findElement(By.linkText("Milestone")).click();
Please see below code I have used PageFactory.initElements as well but not sure how to solve this error.
public class MilestoneTileModel
{
GenerateTestData objtestdata = new GenerateTestData() ;
public MilestoneTileModel() //constructor
{
PageFactory.initElements(LoginTestScript.fd, this);
}
#FindBy(xpath="//a[text()='Milestone']")
WebElement Milestone_Tile_Text;
public void Milestone_Tile_Click()
{
Milestone_Tile_Text.click();
LoginTestScript.fd.findElement(By.linkText("Milestone")).click();
LoginTestScript.fd.findElement(By.xpath("//*#id='CPH_btnAddNewMilestoneTop']")).click();
}
}
Timing issues might occur more often when you use an init method.
The timing issue is when you init an element the driver immediately try to find the elements, on failure you will get no warning but the elements will refer null.
The above can occur for example because the page was not fully rendered or the driver see an older version of the page.
A fix can be to define the elements as a property and on the get of the property use the driver to get the element from the page
Please note that selenium does not promise the driver sees the latest version of the page so even this might break and on some situations a retry will work.
First problem what I see: You didn't set LoginTestScript
Following documentation at first you need to set PageObject variable:
GoogleSearchPage page = PageFactory.initElements(driver, GoogleSearchPage.class);
The best way to rich that point is separate Page Object Model and scenario scipt
You fist file POM should contain:
LoginTestPOM
public class LoginTestPOM {
#FindBy(xpath="//a[text()='Milestone']")
WebElement MilestoneTileText;
public void clickMilestoneTitleText(){
MilestoneTitleText.click();
}
}
TestScript
import LoginTestPOM
public class TestLogin {
public static void main(String[] args) {
// Create a new instance of a driver
WebDriver driver = new HtmlUnitDriver();
// Navigate to the right place
driver.get("http://www.loginPage.com/");
// Create a new instance of the login page class
// and initialise any WebElement fields in it.
LoginTestPOM page = PageFactory.initElements(driver, LoginTestPOM.class);
// And now do the page action.
page.clickMilestoneTitleText();
}
}
This is basis of Page Object Pattern.
NOTE: I'm writing that code only in browser so it could contain some mistakes.
LINK: https://github.com/SeleniumHQ/selenium/wiki/PageFactory
The "ugly" solution without page object pattern is:
UglyTestScript
public class UglyTestLogin {
public static void main(String[] args) {
// Create a new instance of a driver
WebDriver driver = new HtmlUnitDriver();
// Navigate to the right place
driver.get("http://www.loginPage.com/");
// DON'T create a new instance of the login page class
// and DON'T initialise any WebElement fields in it.
// And do the page action.
driver.findElement(By.xpath("//a[text()='Milestone']").click()
}
}

Alert doesn't close using Selenium WebDriver with Google Chrome.

I have the following Selenium script for opening alert on rediff.com:
public class TestC {
public static void main(String[] args) throws InterruptedException, Exception {
System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.rediff.com/");
driver.findElement(By.xpath("//*[#id='signin_info']/a[1]")).click();
driver.findElement(By.id("btn_login")).click();
Thread.sleep(5000);
Alert alert=driver.switchTo().alert();
alert.accept();
}
}
This very same script is working fine in Firefox and IE9, however using Google Chrome after opening the alert, rest of the code is not working. The main thing is that does not shows any exception, error or anything.
Please provide any solution as soon as possible.
Thanks a lot!
Note: If we need to change any setting of browser or any thing please let me know.
Selenium version:Selenium(2) Webdriver
OS:Windows 7
Browser:Chrome
Browser version:26.0.1410.64 m
I'm pretty sure your problem is a very common one, that's why i never advise using Thread.sleep(), since it does not guarantee the code will run only when the Alert shows up, also it may add up time to your tests even when the alert is shown.
The code below should wait only until some alert is display on the page, and i'd advise you using this one Firefox and IE9 aswell.
public class TestC {
public static void main(String[] args) throws InterruptedException, Exception {
System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe");
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 5);
driver.get("http://www.rediff.com/");
driver.findElement(By.xpath("//*[#id='signin_info']/a[1]")).click();
driver.findElement(By.id("btn_login")).click();
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
alert.accept();
}
}
Mostly all that is done here, is changing Thread.sleep(), for a condition that actually will only move forward on the code as soon a alert() is present in the page. As soon as someone does, it wil switch to it and accept.
You can find the Javadoc for the whole ExpectedConditions class here.
Unfortunately AlertIsPresent doesn't exist in C# API
http://selenium.googlecode.com/git/docs/api/dotnet/index.html
You can use something like this:
private static bool TryToAcceptAlert(this IWebDriver driver)
{
try
{
var alert = driver.SwitchTo().Alert();
alert.Accept();
return true;
}
catch (Exception)
{
return false;
}
}
public static void AcceptAlert(this IWebDriver driver, int timeOutInSeconds = ElementTimeout)
{
new WebDriverWait(driver, TimeSpan.FromSeconds(timeOutInSeconds)).Until(
delegate { return driver.TryToAcceptAlert(); }
);
}

How to handle login pop up window using Selenium WebDriver?

How to handle the login pop up window using Selenium Webdriver? I have attached the sample screen here. How can I enter/input Username and Password to this login pop up/alert window?
Thanks & Regards,
Use the approach where you send username and password in URL Request:
http://username:password#the-site.com
So just to make it more clear. The username is username password is password and the rest is usual URL of your test web
Works for me without needing any tweaks.
Sample Java code:
public static final String TEST_ENVIRONMENT = "the-site.com";
private WebDriver driver;
public void login(String uname, String pwd){
String URL = "http://" + uname + ":" + pwd + "#" + TEST_ENVIRONMENT;
driver.get(URL);
}
#Test
public void testLogin(){
driver = new FirefoxDriver();
login("Pavel", "UltraSecretPassword");
//Assert...
}
This should works with windows server 2012 and IE.
var alert = driver.SwitchTo().Alert();
alert.SetAuthenticationCredentials("username", "password");
alert.Accept();
This is very simple in WebDriver 3.0(As of now it is in Beta).
Alert alert = driver.switchTo().alert() ;
alert.authenticateUsing(new UserAndPassword(_user_name,_password));
driver.switchTo().defaultContent() ;
Hopefully this helps.
Now in 2020 Selenium 4 supports authenticating using Basic and Digest auth . Its using the CDP and currently only supports chromium-derived browsers
Example :
Java Example :
Webdriver driver = new ChromeDriver();
((HasAuthentication) driver).register(UsernameAndPassword.of("username", "pass"));
driver.get("http://sitewithauth");
Note : In Alpha-7 there is bug where it send username for both user/password. Need to wait for next release of selenium version as fix is available in trunk https://github.com/SeleniumHQ/selenium/commit/4917444886ba16a033a81a2a9676c9267c472894
Solution: Windows active directory authentication using Thread and Robot
I used Java Thread and Robot with Selenium webdriver to automate windows active directory authentication process of our website.
This logic worked fine in Firefox and Chrome but it didn't work in IE. For some reason IE kills the webdriver when authentication window pops up whereas Chrome and Firefox prevents the web driver from getting killed. I didn't try in other web browser such as Safari.
//...
//Note: this logic works in Chrome and Firefox. It did not work in IE and I did not try Safari.
//...
//import relevant packages here
public class TestDemo {
static WebDriver driver;
public static void main(String[] args) {
//setup web driver
System.setProperty("webdriver.chrome.driver", "path to your chromedriver.exe");
driver = new ChromeDriver();
//create new thread for interaction with windows authentication window
(new Thread(new LoginWindow())).start();
//open your url. this will prompt you for windows authentication
driver.get("your url");
//add test scripts below ...
driver.findElement(By.linkText("Home")).click();
//.....
//.....
}
//inner class for Login thread
public class LoginWindow implements Runnable {
#Override
public void run() {
try {
login();
} catch (Exception ex) {
System.out.println("Error in Login Thread: " + ex.getMessage());
}
}
public void login() throws Exception {
//wait - increase this wait period if required
Thread.sleep(5000);
//create robot for keyboard operations
Robot rb = new Robot();
//Enter user name by ctrl-v
StringSelection username = new StringSelection("username");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(username, null);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);
//tab to password entry field
rb.keyPress(KeyEvent.VK_TAB);
rb.keyRelease(KeyEvent.VK_TAB);
Thread.sleep(2000);
//Enter password by ctrl-v
StringSelection pwd = new StringSelection("password");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(pwd, null);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);
//press enter
rb.keyPress(KeyEvent.VK_ENTER);
rb.keyRelease(KeyEvent.VK_ENTER);
//wait
Thread.sleep(5000);
}
}
}
The easiest way to handle the Authentication Pop up is to enter the Credentials in Url Itself. For Example, I have Credentials like Username: admin and Password: admin:
WebDriver driver = new ChromeDriver();
driver.get("https://admin:admin#your website url");
This is a solution for Python based selenium, after going through the source code (here).
I found this 3 steps as useful.
obj = driver.switch_to.alert
obj.send_keys(keysToSend="username\ue004password")
obj.accept()
Here \ue004 is the value for TAB which you can find in Keys class in the source code.
I guess the same approach can be used in JAVA as well but not sure.
My usecase is:
Navigate to webapp.
Webapp detects I am not logged in, and redirects to an SSO site - different server!
SSO site (maybe on Jenkins) detects I am not logged into AD, and shows a login popup.
After you enter credentials, you are redirected back to webapp.
I am on later versions of Selenium 3, and the login popup is not detected with driver.switchTo().alert(); - results in NoAlertPresentException.
Just providing username:password in the URL is not propagated from step 1 to 2 above.
My workaround:
import org.apache.http.client.utils.URIBuilder;
driver.get(...webapp_location...);
wait.until(ExpectedConditions.urlContains(...sso_server...));
URIBuilder uri = null;
try {
uri = new URIBuilder(driver.getCurrentUrl());
} catch (URISyntaxException ex) {
ex.printStackTrace();
}
uri.setUserInfo(username, password);
driver.navigate().to(uri.toString());
You can use this Autoit script to handle the login popup:
WinWaitActive("Authentication Required","","10")
If WinExists("Authentication Required") Then
Send("username{TAB}")
Send("Password{Enter}")
EndIf'
I was getting windows security alert whenever my application was opening. to resolve this issue i used following procedure
import org.openqa.selenium.security.UserAndPassword;
UserAndPassword UP = new UserAndPassword("userName","Password");
driver.switchTo().alert().authenticateUsing(UP);
this resolved my issue of logging into application. I hope this might help who are all looking for authenticating windows security alert.
Simply switch to alert and use authenticateUsing to set usename and password and then comeback to parent window
Alert Windowalert = driver.switchTo().alert() ;
Windowalert.authenticateUsing(new UserAndPassword(_user_name,_password));
driver.switchTo().defaultContent() ;
1 way to handle this you can provide login details with url. e.g. if your url is "http://localhost:4040" and it's asking "Username" and "Password" on alert prompt message then you can pass baseurl as "http://username:password#localhost:4040".
Hope it works
In C# Selenium Web Driver I have managed to get it working with the following code:
var alert = TestDriver.SwitchTo().Alert();
alert.SendKeys(CurrentTestingConfiguration.Configuration.BasicAuthUser + Keys.Tab + CurrentTestingConfiguration.Configuration.BasicAuthPassword);
alert.Accept();
Although it seems similar, the following did not work with Firefox (Keys.Tab resets all the form and the password will be written within the user field):
alert.SendKeys(CurrentTestingConfiguration.Configuration.BasicAuthUser);
alert.SendKeys(Keys.Tab);
alert.SendKeys(CurrentTestingConfiguration.Configuration.BasicAuthPassword);
Also, I have tried the following solution which resulted in exception:
var alert = TestDriver.SwitchTo().Alert();
alert.SetAuthenticationCredentials(
CurrentTestingConfiguration.Configuration.BasicAuthUser,
CurrentTestingConfiguration.Configuration.BasicAuthPassword);
System.NotImplementedException: 'POST
/session/38146c7c-cd1a-42d8-9aa7-1ac6837e64f6/alert/credentials did
not match a known command'
Types of popups are defined in webdriver alerts: https://www.selenium.dev/documentation/webdriver/browser/alerts/
Here it is another type - authentication popup - eg generated by Weblogic and not seen by Selenium.
Being HTTPS the user/pass can't be put directly in the URL.
The solution is to create a browser extension: packed or unpacked.
Here is the code for unpacked and the packing procedure: https://qatestautomation.com/2019/11/11/handle-authentication-popup-in-chrome-with-selenium-webdriver-using-java/
In manifest.json instead of “https://ReplaceYourCompanyUrl“ put “<all_urls>”.
Unpacked can be used directly in Selenium:
#python:
co=webdriver.ChromeOptions()
co.add_argument("load-extension=ExtensionFolder")
<all_urls> is a match pattern
The flow for requests is in https://developer.chrome.com/docs/extensions/reference/webRequest/
We can also update browser setting to consider logged in user -
Internet Options-> Security -> Security Settings-> Select Automatic login with current user name and password.
The following Selenium-Webdriver Java code should work well to handle the alert/pop up up window:
driver.switchTo().alert();
//Selenium-WebDriver Java Code for entering Username & Password as below:
driver.findElement(By.id("userID")).sendKeys("userName");
driver.findElement(By.id("password")).sendKeys("myPassword");
driver.switchTo().alert().accept();
driver.switchTo().defaultContent();
I used IE, then create code like that and works after modification several code:
public class TestIEBrowser {
public static void main(String[] args) throws Exception {
//Set path of IEDriverServer.exe.
// Note : IEDriverServer.exe should be In D: drive.
System.setProperty("webdriver.ie.driver", "path /IEDriverServer.exe");
// Initialize InternetExplorerDriver Instance.
WebDriver driver = new InternetExplorerDriver();
// Load sample calc test URL.
driver.get("http://... /");
//Code to handle Basic Browser Authentication in Selenium.
Alert aa = driver.switchTo().alert();
Robot a = new Robot();
aa.sendKeys("host"+"\\"+"user");
a.keyPress(KeyEvent.VK_TAB);
a.keyRelease(KeyEvent.VK_TAB);
a.keyRelease(KeyEvent.VK_ADD);
setClipboardData("password");
a.keyPress(KeyEvent.VK_CONTROL);
a.keyPress(KeyEvent.VK_V);
a.keyRelease(KeyEvent.VK_V);
a.keyRelease(KeyEvent.VK_CONTROL);
//Thread.sleep(5000);
aa.accept();
}
private static void setClipboardData(String string) {
// TODO Auto-generated method stub
StringSelection stringSelection = new StringSelection(string); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
}

Resources