Selenium "Element not found" due to incorrect XPath expression - java

I am completely new to Selenium and XPath. Today is the first time I am trying to execute a simple script using Selenium RC. Please find the code below.
package com.rcdemo;
import org.junit.Test;
import org.openqa.selenium.By;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
public class MathTest {
#SuppressWarnings("deprecation")
public static void main(String[] args) throws InterruptedException {
// Instatiate the RC Server
Selenium selenium = new DefaultSelenium("localhost", 4444 , "*firefox C:/Program Files (x86)/Mozilla Firefox/firefox.exe", "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(4500); // Wait for page load
// Click on Link Percent Calculator
selenium.click("xpath=//*[#id='content']/ul/li[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 the Calculate button
selenium.click("xpath=.//*[#id='content']/table/tbody/tr/td[2]/input");
// Verify if the result is 5
String result = selenium.getText("//*[#id='content']/p[2]/span/font/b");
System.out.println(result);
if (result == "5") {
System.out.println("Pass");
} else {
System.out.println("Fail");
}
}
}
The issue is when executing the above code, an exception is happening at the getText() line. I copied that XPath from the developer tools of Google Chrome. Even when I checked manually once, the same XPath expression is showing. I have tried to find the solution for this from today morning. How can I get Selenium to find the element?
PS: In the result variable I have to capture the result after a calculation. For example, 10 % 50 = 5. This 5 I need to capture.

You need to wait for "Result" to get populated.
Here is the updated code snippet. It should work for you:
// Add this line
if (!selenium.isElementPresent("//*[#id='content']/p[2]/span/font/b"))
{
Thread.sleep(2000);
}
// Verify if the result is 5
String result = selenium.getText("//*[#id='content']/p[2]/span/font/b");
System.out.println(result);
// Update this line
if (result.trim().equals("5"))
{
System.out.println("Pass");
}
else
{
System.out.println("Fail");
}
And you need to use the .equals method to compare the two string values.
Note - A better approach is to replace Thread.sleep with dynamic wait methods, like waitForPageToLoad, waitForElementPresent (custom methods), etc.

Related

Getting correct search result page numbers- Selenium Java

I am trying to get correct page number for Seattle which is 7 and then click on every pages from 1 to 7. I have 2 problems see the parts with asterisk ** below:
1) I am not sure how to write the xpath so that I get 7 instead of 11
2) The while loop is an infinite loop
public class Job {
public static WebDriver driver;
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Shahriar\\Downloads\\chromedriver_win32\\chromedriver.exe");
driver= new ChromeDriver();
driver.get("https://web.expeditors.com/careers/#/listTop");
driver.manage().window().maximize();
//Disable the cookie notification at bottom
driver.findElement(By.xpath("//a[#id='hs-eu-decline-button']")).click();
// Find more cities and scroll down
driver.findElement(By.xpath("//a[#id='moreCity']")).click();
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("window.scrollBy(0,5500)", "");
//Locate US-Seattle and click and verify
driver.findElement(By.xpath("//label[#class='ng-binding']//input[#id='us~Seattle']")).click();
String state=driver.findElement(By.xpath("//a[contains(text(),'United States - Seattle')]")).getText();
Assert.assertEquals(state, "United States - Seattle");
**//Number of search pages found should be 7
List<WebElement> resultPages=driver.findElements(By.xpath("//a[#href='#listTop']"));
Assert.assertEquals(7, resultPages.size());**
**//Go to each page by clicking on page number at bottom
int count=0;
WebElement next_button=driver.findElement(By.xpath("//a[#ng-click='setCurrent(pagination.current + 1)']"));
while (resultPages.size()!=0){
next_button.click();
count++;
System.out.println("Current page is "+ count);
}**
//driver.close();
}
}
I could use some help. Thanks in advance for your time.
Here is the logic that you need.
//Number of search pages found should be 7
List<WebElement> resultPages=driver.findElements(By.xpath("//a[#href='#listTop' and #ng-click='setCurrent(pageNumber)']"));
Assert.assertEquals(7, resultPages.size());
for (int i = 1; i <= resultPages.size(); i++) {
driver.findElement(By.xpath("(//a[#href='#listTop' and #ng-click='setCurrent(pageNumber)'])[" + i +"]")).click();
System.out.println(driver.findElement(By.xpath("(//a[#href='#listTop' and #ng-click='setCurrent(pageNumber)'])[" + i +"]")).getText());
}
Your while loop is counting pages, but the condition itself appears to be static (I can't tell without the actual page). You probably want something more like
int count=0;
WebElement next_button=driver.findElement(By.xpath("//a[#ng-click='setCurrent(pagination.current + 1)']"));
while (next_button != null){
next_button.click();
count++;
System.out.println("Current page is "+ count);
next_button=driver.findElement(By.xpath("//a[#ng-click='setCurrent(pagination.current + 1)']"));
}
As for your 7 vs 11 result pages, again it's hard to tell without the HTML, but your XPath search is for By.xpath("//a[#href='#listTop']") so I'd check and see what's in your HTML with listTop. Perhaps other elements are somehow using that anchor tag?

Selenium-Java-FireBug : FirePath returns 9 matching nodes where as List<WebElement> is returning 18 elements

FirePath is returning 9 matching nodes where as List is returning 18 elements.
OS: Win8 Pro, 64 bit
Java: jdk1.8.0_77
Selenium: 3.4.0 (selenium-server-standalone)
GeckoDriver: 0.17.0
Browser: Mozilla Firefox 53.0
IDE: Eclipse Neon.2 Release (4.6.2)
FireBug: 2.0.18
URL: https://demos.devexpress.com/aspxeditorsdemos/ListEditors/MultiSelect.aspx
XPATH: //table[#id='ContentHolder_lbFeatures_LBT']/tbody/tr/td
I am trying to get the number of items from a List Box with Multiple Selection. When I provide the xpath in FireBug/FirePath, it returns me "9 matching nodes".
Moving forward, through my script, I add the WebElements in a generic List of type WebElement through findElements method. Next when I call size() method for the List<WebElement>, it returns me 18 Elements
Update:
(Apologies, I made a mistake in putting up the Question with exact steps while trying to narrow down to the exact problem)
Here is the complete issue.
Steps Required:
Access the URL.
Click on Selection mode as Multiple
From Phone features table, I need to select Blue Tooth, Memory Card Slot and Touch screen. The List may vary, so I want to keep it in a List<String>.
Here is my script:
package demo;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Q45065876_keyDown {
public static void main(String[] args) {
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.navigate().to("https://demos.devexpress.com/aspxeditorsdemos/ListEditors/MultiSelect.aspx");
driver.findElement(By.xpath("//input[#id='ContentHolder_lbSelectionMode_I']")).click();
List<WebElement> selection_list = driver.findElements(By.xpath("//table[#id='ContentHolder_lbSelectionMode_DDD_L_LBT']/tbody/tr/td"));
for (WebElement ele:selection_list)
{
if(ele.getAttribute("innerHTML").contentEquals("Multiple"))
ele.click();
break;
}
driver.findElement(By.id("ContentHolder_lbSelectionMode_DDD_L_LBI1T0")).click();
List<WebElement> phone_feature_list = driver.findElements(By.xpath("//table[#id='ContentHolder_lbFeatures_LBT']/tbody/tr/td"));
System.out.println("Number of Elements : "+phone_feature_list.size());
List<String> item_list = new ArrayList<String>();
item_list.add("Bluetooth");
item_list.add("Memory Card Slot");
item_list.add("Touch screen");
System.out.println("Number of Elements : "+item_list.size());
for (int i=0; i<phone_feature_list.size(); i++)
{
WebElement my_element = phone_feature_list.get(i);
String innerhtml = my_element.getAttribute("innerHTML");
System.out.println("INNER HTML : "+innerhtml);
for (int j=0; j<item_list.size(); j++)
{
item_list.get(j).contentEquals(innerhtml);
my_element.click();
}
}
}
}
Can you please help me out to understand whats wrong happening here? Thank you all for all the help.
It take a second or two for the site to refresh. The xpath
"//table[#id='ContentHolder_lbFeatures_LBT']/tbody/tr/td"
includes those checkboxes so you are getting 18 results. You can wait until there is different number of results
List<WebElement> phone_feature_list = driver.findElements(By.xpath("//table[#id='ContentHolder_lbFeatures_LBT']/tbody/tr/td[contains(#class, 'dxeT')]"));
int size = phone_feature_list.size();
// choose an option from the dropdown
// wait for the size to change
while ((phone_feature_list = driver.findElements(By.xpath("//table[#id='ContentHolder_lbFeatures_LBT']/tbody/tr/td[contains(#class, 'dxeT')]"))).size() == size);
System.out.println("Number of Elements : " + phone_feature_list.size());

How to find the total number of checkboxes present on web page using Selenium Webdriver - Java?

Environment: Selenium Webdriver Using Java
1) run a Search
2) after search 5 items will be displayed with 5 check-boxes against them
3) I want to get the number of check-boxes
4) check-boxes have class name "checkbox"
Please suggest
Thanks !!
Quickest and simplest method is to find a list of the checkbox elements by the className you've provided.
List<WebElement> boxes = driver.findElements(By.className("checkbox"));
int numberOfBoxes = boxes.length();
If you want the number of checkboxes per search result, you'd need to loop for each result.
List<WebElement> results = driver.findElements(By.xpath("//relevant_xpath_from_your_html"));
for (Webelement result : results){
List<WebElement> boxes = result.findElements(By.className("checkbox"));
int numberOfBoxes = boxes.length()
}
The following will show all checkboxes present on a page
System.out.println(
driver.findElements(By.cssSelector("input[type='checkbox']")).size()
);
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
public class Checkbox {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "E:\\java\\WebDriver\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://rahulshettyacademy.com/AutomationPractice/");
driver.findElement(By.cssSelector("input[id='checkBoxOption1']")).click();//select checkbox 1
Assert.assertTrue(driver.findElement(By.cssSelector("input[id='checkBoxOption1']")).isSelected());//validated checkbox selection
//Thread.sleep(4000);//delay process to see the check and uncheck activity
driver.findElement(By.cssSelector("input[id='checkBoxOption1']")).click();//deselect checkbox 1
Assert.assertFalse(driver.findElement(By.cssSelector("input[id='checkBoxOption1']")).isSelected());//validated checkbox deselection
//to get checkbox counts on the page.
System.out.println("The checkbox count is "+ driver.findElements(By.cssSelector("input[type='checkbox']")).size());//select checkbox 1
}
}

Selenium is unable to locate any element in html page

I'm trying to make a small java app. that can log in to my university portal, I used Selenium in the following code:
//some import statements
public class Portal{
public Portal(){
File file = new File("C:/chromedriver.exe");
System.setProperty("webdriver.chrome.driver", file.getAbsolutePath());
HtmlUnitDriver driver = new HtmlUnitDriver();
String target = "http://portal.kfupm.edu.sa/cp/home/loginf";
driver.get(target);
ArrayList <WebElement> inputs = (ArrayList<WebElement>) driver.findElements(By.tagName("input"));
System.out.println(inputs.size());
for(WebElement input : inputs){
System.out.println(input.getAttribute("value") + " " + input.getAttribute("name"));
// to insure the link is displaying something
ChromeDriver driver1 = new ChromeDriver();
driver1.get(driver.getCurrentUrl());
}
public static void main(String [] args){
new Portal();
}
}
the problem is when I use this target (my university portal) I get inputs.size() = 0; although, I'm sure there are elements with (input) tagName. Also I get the same resulst whatever was the method of (By) class I used.
However, when I change the target to any link (for example: "http://www.google.com" or "http://www.facebook.com" , I get elements in the inputs ArrayList (all elements of tagName (input) that are in the target html page). Can any body please tell me what is the problem and how can I solve it? thanks in advance..
The reason that you find zero elements with tag input is that all the elements lie inside a frame tag. Selenium is able to see to current window and all the elements that are defined inside frame tag (i.e. are inside a frameset) are invisile to it.
To see the element you will need to switch frame first, So that selenium has control inside the target frame and not in the outer window. Try this
driver.swtichTo().frame(0); // this will move selenium control inside first frame

How to switch between frames in Selenium WebDriver using Java

I am using java with WebDriver.I have to switch between two frames. I have recorded the test case in selenium IDE and in that I got the values as selectFrame relative=top select Frame=middle Frame
But there is a problem it is not able to recognize the relative=top and middleFrame. How can I solve this problem in Selenium WebDriver with Java?
WebDriver's driver.switchTo().frame() method takes one of the three possible arguments:
A number.
Select a frame by its (zero-based) index. That is, if a page has three
frames, the first frame would be at index 0, the second at index 1
and the third at index 2. Once the frame has been selected, all
subsequent calls on the WebDriver interface are made to that frame.
A name or ID.
Select a frame by its name or ID. Frames located by matching name
attributes are always given precedence over those matched by ID.
A previously found WebElement.
Select a frame using its previously located WebElement.
Get the frame by it's id/name or locate it by driver.findElement() and you'll be good.
to switchto a frame:
driver.switchTo.frame("Frame_ID");
to switch to the default again.
driver.switchTo().defaultContent();
First you have to locate the frame id and define it in a WebElement
For ex:- WebElement fr = driver.findElementById("id");
Then switch to the frame using this code:- driver.switchTo().frame("Frame_ID");
An example script:-
WebElement fr = driver.findElementById("theIframe");
driver.switchTo().frame(fr);
Then to move out of frame use:- driver.switchTo().defaultContent();
You can also use:
driver.switch_to.frame(0)
(0) being the first iframe on the html.
to switch back to the default content:
driver.switch_to.default_content()
Need to make sure once switched into a frame, need to switch back to default content for accessing webelements in another frames. As Webdriver tend to find the new frame inside the current frame.
driver.switchTo().defaultContent()
There is also possibility to use WebDriverWait with ExpectedConditions (to make sure that Frame will be available).
With string as parameter
(new WebDriverWait(driver, 5)).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("frame-name"));
With locator as a parameter
(new WebDriverWait(driver, 5)).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("frame-id")));
More info can be found here
This code is in groovy, so most likely you will need to do some rework. The first param is a url, the second is a counter to limit the tries.
public boolean selectWindow(window, maxTries) {
def handles
int tries = 0
while (true) {
try {
handles = driver.getWindowHandles().toArray()
for (int a = handles.size() - 1; a >= 0 ; a--) { // Backwards is faster with FF since it requires two windows
try {
Log.logger.info("Attempting to select window: " + window)
driver.switchTo().window(handles[a]);
if (driver.getCurrentUrl().equals(window))
return true;
else {
Thread.sleep(2000)
tries++
}
if (tries > maxTries) {
Log.logger.warn("Cannot select page")
return false
}
} catch (Exception ex) {
Thread.sleep(2000)
tries++
}
}
} catch (Exception ex2) {
Thread.sleep(2000)
tries++
}
}
return false;
}

Categories