how to open links one by one from excel using selenium java? - selenium

I have an excel with 5 different links in first five rows and first column in the excel. Now I need to open all this five links one after the other. This is the code I have tried
#DataProvider(name="URLS")
// #Test
public Object[][] readFromExcel() throws IOException {
XSSFWorkbook workbook = new XSSFWorkbook("pagelinks.xlsx");
XSSFSheet sheet = workbook.getSheet("URL");
int lastRowNum = sheet.getLastRowNum();
int columns = sheet.getRow(0).getPhysicalNumberOfCells();
Object [][]urls=new Object[lastRowNum][columns];
for(int i=1;i<=lastRowNum;i++){
XSSFRow row = sheet.getRow(i);
for(int j=0;j<columns;j++){
XSSFCell cell = row.getCell(j);
urls[i-1][j]=cell.getStringCellValue();
}
// String url = sheet.getRow(i).getCell(0).getStringCellValue();
//System.out.println(url);
}
return urls;
}
public WebDriver initializedriver() {
System.setProperty("webdriver.chrome.driver","C:\\Natesh\\Automation\\chromedriver_win32\\chromedriver.exe");
WebDriver driver=new ChromeDriver();
return driver;
}
#Test(dataProvider = "URLS")
public void logInMethod(String url) throws Exception{
driver.get(url);
}
with this code the first link is fetched from the excel and it is opening in the browser but it stops there it is not reading the second link. Can anyone please help me with this?

If you have an entity that contains multiple URLs (i.e. a spreadsheet), you need a regular Java process to fetch the data (loop thru the rows or columns), and then make calls for the web driver to open each URL either as tabs or as separate windows. The easiest way to do this is something like this:
WebDriver driver = initializedriver();
// more code here?
for(int i=1;i<=lastRowNum;i++){
XSSFRow row = sheet.getRow(i);
for(int j=0;j<columns;j++){
XSSFCell cell = row.getCell(j);
urls[i-1][j]=cell.getStringCellValue();
}
String url = sheet.getRow(i).getCell(0).getStringCellValue();
driver.get(url); // assuming the loop you created works correctly
}

Related

Not able to identify element on the screen- how to use tab

Screenshot of the element I want to click:
I automating my website(new to automation). once i login i get to another page where selenium web driver is not able to find any of the elements(I tried all possibilities even sso related).
Only solution i could find was using tabs and enter.
So when i enter that page i need to click 9 time "TAB" key from the keyboard and then enter so that my login is verified. since i don't have any element using which i can perform the tab and enter actions. is there a way where once i get to that page the web driver starts pressing "TAB" key 9 times and then "Enter" on 10 time.
Please help I have been working on this over a week now and not getting
anywhere.
optimist_creeper-main class:
package Modules;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.Test;
import Modules.HomePage;
public class MainClass {
String appUrl = "als-stg-1.mtvn.ad.viacom.com/webqa/";
#Test public void MainTest() {
System.setProperty("webdriver.gecko.driver", "C:\\Shayni Coding\\Automation\\Gecko\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get(appUrl);
HomePage home = new HomePage();
home.HomePageTest(driver);
}
}
Home Page class:
public class HomePage {
#BeforeClass public void beforeClass() {
System.out.println("before class");
}
public void HomePageTest(WebDriver driver) {
driver.manage().window().maximize();
WebElement email = driver.findElement(By.id("cred_userid_inputtext"));
email.sendKeys("shayni#outlook.com");
WebElement pass = driiver.findElement(By.id("cred_password_inputtext"));
pass.sendKeys(Keys.ENTER);
pass.click();
String expectedTitle = "VMS Web";
String actualTitle = driver.getTitle();
Assert.assertEquals(expectedTitle,actualTitle);
}
}
Thanks.
Just get a random object like the body tag and use that to send your key presses.
e.g.
WebElement dummyElement = driver.findElement(By.xpath("/html/body"));
for (int i = 0; i < 9; ++i) {
dummyElement.sendKeys(keys.TAB);
}
dummyElement.sendKeys(keys.ENTER);
The above code finds the body take and sets it as an element. It then presses the tab key 9 times and then presses the enter key. Which is what you asked for. Hope that helps.

find xpath for a repeated angularJs Item

how is possible to find the xpath for an angularJs element? for instance i discovered that all links in my page have the same xpath due to the repeated items in angularJs -->
.//*[#id='div_1_1_1_2']/div/div[1]/div[2]/div[2]/div/div[2]/div[1]/div/div[2]/a
but i have 10 of element , they are differente for text, so i tried with `"
so i tried with contains but it never find it
.//[#id='div_1_1_1_2']/div/div[1]/div[2]/div[2]/div/div[2]/div[1]/div/div[2]/a[contains(#aria-label='Creazione Prodotto')]"`
i use selenium, junit4 , firefox webDriver
this is my code
public class PB01_TTT {
private WebDriver driver;
private String baseUrl;
private boolean acceptNextAlert = true;
private StringBuffer verificationErrors = new StringBuffer();
WebElement element;
#Before()
public void setUp() throws Exception {
FirefoxProfile fxProfile = new FirefoxProfile();
fxProfile.setPreference("browser.download.folderList", 2);
fxProfile.setPreference("browser.download.manager.showWhenStarting", false);
fxProfile.setPreference("browser.helperApps.alwaysAsk.force", false);
fxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk",
"application/pdf, application/x-pdf, application/octet-stream");
fxProfile.setPreference("pdfjs.disabled", true);
driver = new FirefoxDriver(fxProfile);
baseUrl = "https://w8aon2bpm.replynet.prv:9443";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#Test
public void testPBO1TTT() throws Exception {
driver.get(baseUrl + "/ProcessPortal/login.jsp");
// driver.get(baseUrl + "/ProcessPortal/dashboards/SYSRP/RESPONSIVE_WORK");
driver.findElement(By.id("username")).clear();
driver.findElement(By.id("username")).sendKeys("user");
driver.findElement(By.id("password")).clear();
driver.findElement(By.id("password")).sendKeys("password");
String columnToDisplay=driver.findElements(By.xpath(".//*[#id='div_1_1_1_2']/div/div[1]/div[2]/div[2]/div/div[2]/div[1]/div/div[2]/a[contains(#aria-label='Creazione Prodotto')]"));
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
element = (WebElement) driver.findElements(By.xpath(columnToDisplayXpath));
Assert.assertNotNull(element);
it always return me a notFoundElement, any suggestions ?
Thank you
If you have 10 links, then there is a high chance they are different in a way even if the path is the same, in this case you need to construct an path based on the thing that is different.
For example: use href, text or other any part that differs
//a[contains(#href, 'part_of_href')]
//a[contains(text(), 'part_of_text')]
//a[#title='title']
//a[contains(#aria-label='Creazione Prodotto')]
If you need any help in getting the selector please add the html section of the links, you can change the url if needed.
Tip: avoid using absolute xpaths and attributes that do not suggest anything and they can change like: .//*[#id='div_1_1_1_2']/div/div[1]/div[2]/div[2]/div/div[2]/div[1]/div/div[2]/a[contains(#aria-label='Creazione Prodotto')]"
This will give you a lot of work in the future.

How to read excel file in cucumber project?

I am creating testing automation framework using java but i am not able to read excel file in cucumber.
is there any way to use #DataProvider functionality og testNG?
I do not want to use datatable of feature file.
If you use CucumberJVM, I don't think you can make use of TestNG Data Providers without major hacks. Or at least this is not a "cucumber way" of doing things. Data Table is a Cucumber equivalent of TestNG Data Provider:
https://cucumber.io/docs/reference#data-tables
This is how you parametrise tests in Cucumber. I'm not saying the solution you are looking for can't be implemented, I'm saying you are most likely looking for a wrong thing. CucumberJVM makes use of DataProviders internally, to handle features this way:
https://github.com/cucumber/cucumber-jvm/blob/master/testng/src/main/java/cucumber/api/testng/AbstractTestNGCucumberTests.java
In case it helps others:
here is described how to link a Cucumber Scenario Outline to read data from an Excel file
https://startingwithseleniumwebdriver.blogspot.com/2017/04/getting-data-from-external-file-using.html
and here is described how to load data from an Excel file in a Cucumber feature file before executing Scenario steps
https://startingwithseleniumwebdriver.blogspot.com/2017/04/loading-data-from-external-file-to.html
I my case this was very useful, as for each Scenario step I had to load Excel data (data from multiple rows having same group ID) in order to perform further validations. Like this the Cucumber feature file was a bit cleaner while the Excel had all the details under the hood.
ExcelBDD Java edition can resolve this problem gracefully. code example
static Stream<Map<String, String>> provideExampleList() throws IOException {
String filePath = TestWizard.getExcelBDDStartPath("excelbdd-test")
+ "excelbdd-test\\src\\test\\resources\\excel.xlsx";
return Behavior.getExampleStream(filePath,"Expected1","Scenario1");
}
#ParameterizedTest(name = "Test{index}:{0}")
#MethodSource("provideExampleList")
void testgetExampleWithExpected(Map<String, String> parameterMap) {
assertNotNull(parameterMap.get("Header"));
System.out.println(String.format("=======Header: %s=======", parameterMap.get("Header")));
for (Map.Entry<String, String> param : parameterMap.entrySet()) {
System.out.println(String.format("%s --- %s", param.getKey(), param.getValue()));
}
}
more detail at ExcelBDD Guideline By Java Example
Here is the example how to read TestData from excel
public class Framework {
static String TestDataPath = System.getProperty("user.dir")
+ "\\ExcelFiles\\TestData.xlsx";
public static HashMap<String, HashMap<String, String>> hm1 = new HashMap<>();
static String s3;
public static void ReadTestData() throws IOException {
FileInputStream file = new FileInputStream(TestDataPath);
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheet("Sheet1");
Row HeaderRow = sheet.getRow(0);
for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {
Row currentRow = sheet.getRow(i);
HashMap<String, String> currentHash = new HashMap<String, String>();
for (int j = 0; j < currentRow.getPhysicalNumberOfCells(); j++) {
Cell currentCell1 = currentRow.getCell(0);
switch (currentCell1.getCellType()) {
case Cell.CELL_TYPE_STRING:
s3 = currentCell1.getStringCellValue();
System.out.println(s3);
break;
case Cell.CELL_TYPE_NUMERIC:
s3 = String.valueOf(currentCell1.getNumericCellValue());
System.out.println(s3);
break;
}
Cell currentCell = currentRow.getCell(j);
switch (currentCell.getCellType()) {
case Cell.CELL_TYPE_STRING:
currentHash.put(HeaderRow.getCell(j).getStringCellValue(),
currentCell.getStringCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
currentHash.put(HeaderRow.getCell(j).getStringCellValue(),
String.valueOf(currentCell.getNumericCellValue()));
break;
}
}
hm1.put(s3, currentHash);
}
Here is the Model cucumber file and testData.
Scenario Outline: Successful Login with Valid Credentials
Given User is on Home Page
When User Navigate to LogIn Page
And User enters mandatory details of "<TextCase>"
Then Message displayed Login Successfully
Examples:
|TextCase|
|Case1 |
|Case2 |
[Test data img Link][1]
[1]: https://i.stack.imgur.com/IjOap.png
Here is the Model Stepdefination File
#When("^User enters mandatory details of \"([^\"]*)\"$")
public void user_enters_mandatory_details_of(String arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
driver.FindElement("UserName").sendKeys(Framework.hm1.get(arg1).get("UserName"));
Framework.FindElement("Password").sendKeys(Framework.hm1.get(arg1).get("Password"));
}
Follow above three steps in cucumber you will able to read test data.

how to read the data from excel sheet using two #Test in same class in testng selenium webdriver

In this below example program, is it possible to use two # test in one class,and then i have to fetch the data from excel sheet for both # test in same excel sheet.is it possible?.two methods can be used in same class? one excel can contains both data's of two# test?.please give me some ideas or example to be used two # test in same class fetching data from excel sheet. I am waiting for reply.please help me...thanks in advance.
public class Test1 {
#BeforeTest
#Test(groups = { "" }, dataProvider = "getTestData", description = "")
public void abc(String a, String b) {
}
#Test(groups = { "" }, dataProvider = "", description = "")
public void abcd(String c, String d) {
}
#AfterMethod
#DataProvider
public Object[][] getTestData() {
check = true;
return TestUtil.getData(Sprint1xls, this.getClass().getSimpleName());
}
}
Yes the above is possible. I still don't get it where is the problem statement. Did you try above? is it failing? if yes then what is the error?
1) Yes, You can have 2 #Test methods in one class using same data provider.
2) If in the same sheet if you are using same data for this tests then there is no problem at all. if there is different data for different test then in your data provider toggle between test data using method name.
Let me know if you need further help.

Getting error while running selenium code

I am getting below error while running selenium code while everything is right in code. Please help
Exception in thread "main" com.thoughtworks.selenium.SeleniumException: ERROR: Element .//*[#id='content']/p[2] not found
at com.thoughtworks.selenium.HttpCommandProcessor.throwAssertionFailureExceptionOrError(HttpCommandProcessor.java:109)
at com.thoughtworks.selenium.HttpCommandProcessor.doCommand(HttpCommandProcessor.java:103)
at com.thoughtworks.selenium.HttpCommandProcessor.getString(HttpCommandProcessor.java:272)
at com.thoughtworks.selenium.DefaultSelenium.getText(DefaultSelenium.java:471)
at selrcdemo.RCDemo.main(RCDemo.java:35)
package selrcdemo;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
public class RCDemo {
public static void main(String[] args) throws InterruptedException
{
Selenium selenium = new DefaultSelenium("localhost", 4444 , "firefox", "http://www.calculator.net");
selenium.start(); // Start
selenium.open("/"); // Open the URL
selenium.windowMaximize();
// Click on Link Math Calculator
selenium.click("xpath=.//*[#id='menu']/div[3]/a");
Thread.sleep(2500); // Wait for page load
// Click on Link Percent Calculator
selenium.click("xpath=.//*[#id='menu']/div[4]/div[3]/a");
Thread.sleep(4000); // Wait for page load
// Focus on text Box
selenium.focus("name=cpar1");
// enter a value in Text box 1
selenium.type("css=input[name=\"cpar1\"]", "10");
// enter a value in Text box 2
selenium.focus("name=cpar2");
selenium.type("css=input[name=\"cpar2\"]", "50");
// Click Calculate button
selenium.click("xpath=.//*[#id='content']/table/tbody/tr/td[2]/input");
Thread.sleep(4000);
// verify if the result is 5
String result = selenium.getText(".//*[#id='content']/p[2]");
if (result == "5")
{
System.out.println("Pass");
}else
{
System.out.println("Fail");
}
}
}
If you open this site, you'll find that the output is not getting stored in the third text box, rather it is getting displayed above, just under where "Result" is written.
You'll have to make some changes in the code(the xpath for click button and that for the third text box, i.e. from where the value is getting picked). The following codes works perfectly:
package seleniumrcdemo;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
#SuppressWarnings("deprecation")
public class rcdemo {
public static void main(String[] args) throws InterruptedException {
// Instatiate the RC Server
Selenium selenium = new DefaultSelenium("localhost", 4444 , "firefox", "http://www.calculator.net");
selenium.start(); // Start
selenium.open("/"); // Open the URL
selenium.windowMaximize();
// Click on Link Math Calculator
selenium.click("xpath=.//*[#id='menu']/div[3]/a");
Thread.sleep(2500); // Wait for page load
// Click on Link Percent Calculator
selenium.click("xpath=.//*[#id='menu']/div[4]/div[3]/a");
Thread.sleep(4000); // Wait for page load
// Focus on text Box
selenium.focus("name=cpar1");
// enter a value in Text box 1
selenium.type("css=input[name=\"cpar1\"]", "10");
// enter a value in Text box 2
selenium.focus("name=cpar2");
selenium.type("css=input[name=\"cpar2\"]", "50");
// Click Calculate button
selenium.click("xpath=.//*[#id='content']/table[1]/tbody/tr[2]/td/input[2]");
// verify if the result is 5
Thread.sleep(4000);
String result = selenium.getText("xpath=.//*[#id='content']/p[2]/font/b");
//String result = selenium.getValue("xpath=.//*[#id='cpar3']");
System.out.println("result"+result);
if (result.equals("5")/*== "5"*/){
System.out.println("Pass");
}
else{
System.out.println("Fail");
}
}
}
Pretty sure you need to add xpath= inside your quotes. Or do:
String result = selenium.findElement(By.xpath('path')).getText();
Your answer (result) doesn't exist in the second p. After closer inspect the xpath is:
/html/body/table[2]/tbody/tr/td[1]/div[1]/p[2]/span
The statement
String result = selenium.getText(".//*[#id='content']/p[2]");
missing the "xpath=".
The correct statement
String result = selenium.getText("xpath=.//*[#id='content']/p[2]");
But this will return the result "10% of 50 = 5", which of course != "5". The exact xpath is for the element "5" is "xpath=.//*[#id='content']/p[2]/span/font/b". So the statement should be
String result = selenium.getText("xpath=.//*[#id='content']/p[2]/span/font/b");
You'll still get "Fail" in comparing the String literals. Suggest to use equals() or compareTo() method when comparing strings:
if (result.equals("5"))
{
System.out.println("Pass");
}else
{
System.out.println("Fail");
}
Hope this helps.
Thread.sleep(2000);
// verify if the result is 5
String result = selenium.getText("xpath=.//*[#id='content']/p[2]/span/font/b");
if (result.equals("5")){
System.out.println("Pass");
}
else{
System.out.println("Fail");
}
correct me if I am wrong
the % calculation module in calculator web application is failed to pass test case, may be the application code requires a bug fix , the result is not displaying on the rhs(cpar3) side
xpath=.//*[#id='cpar3']==>RHS xpath
here is the selenium code which works fine for me if i manually enter the result value to 5
package selRcDemo;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
public class RcDemo {
/**
* #param args
*/
public static void main(String[] args) throws InterruptedException {
// Instatiate the RC Server
Selenium selenium = new DefaultSelenium("localhost", 4444, "firefox",
"http://www.calculator.net");
selenium.start(); // Start
selenium.open("/"); // Open the URL
selenium.windowMaximize();
// Click on Link Math Calculator
selenium.click("xpath=.//*[#id='menu']/div[3]/a");
Thread.sleep(2500); // Wait for page load
// Click on Link Percent Calculator
selenium.click("xpath=.//*[#id='menu']/div[4]/div[3]/a");
Thread.sleep(4000); // Wait for page load
// Focus on text Box
selenium.focus("name=cpar1");
// enter a value in Text box 1
selenium.type("css=input[name=\"cpar1\"]", "10");
// enter a value in Text box 2
selenium.focus("name=cpar2");
selenium.type("css=input[name=\"cpar2\"]", "50");
// Click Calculate button
selenium.click("xpath=.//*[#id='content']/table[1]/tbody/tr[2]/td/input[2]");
Thread.sleep(2500);
// verify if the result is 5
String result = selenium.getText("xpath=.//*[#id='cpar3']");
// result="5";
System.out.println(result);
// result is not equal to 5 due to bug in application code its returning
// "" (no value)
if (result.equals("5")) {
System.out.println("Pass");
} else {
System.out.println("Fail");
}
}
}