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?
Related
I want to just print runs scored by all batsman during the cricket match in selenium using CSS selector. All rows have same classname and the runs are in 3rd row so I used CSS selector to select 3rd row only, but I am not able to print runs. Here is my code:
package SomeBasicAutomationPractice;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class tableGrid_Practice {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "G:\\AutomationPractice\\src\\drivers\\chromedriver.exe");
WebDriver driver= new ChromeDriver();
driver.get("http://www.cricbuzz.com/live-cricket-scorecard/18970/pak-vs-sl-2nd-t20i-pakistan-v-sri-lanka-in-uae-2017");
Thread.sleep(5000);
WebElement table=driver.findElement(By.cssSelector("div[class='cb-col cb-col-100 cb-ltst-wgt-hdr']"));
int count=table.findElements(By.cssSelector("div[classname='cb-col cb-col-100 cb-scrd-itms'] div:nth-child(3)")).size();
System.out.println(count);
for(int i=0;i<count;i++)
{
//table.findElements(By.cssSelector("div[classname='cb-col cb-col-100 cb-scrd-itms'] div:nth-child(3)")).get(i);
System.out.println(table.findElements(By.cssSelector("div[classname='cb-col cb-col-100 cb-scrd-itms'] div:nth-child(3)")).get(i));
}
}
}
To print the print runs scored by all batsman during the first innings within the website https://www.cricbuzz.com/live-cricket-scorecard/18970/pak-vs-sl-2nd-t20i-pakistan-v-sri-lanka-in-uae-2017 you need to induce WebDriverWait for the visibilityOfAllElementsLocatedBy() and you can use the following css-selectors based Locator Strategy:
Code Block:
driver.get("https://www.cricbuzz.com/live-cricket-scorecard/18970/pak-vs-sl-2nd-t20i-pakistan-v-sri-lanka-in-uae-2017");
List<WebElement> runs = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("div.ng-scope#innings_1>div div div.text-bold:nth-child(3)")));
for(WebElement run:runs) { System.out.println(run.getText()); }
driver.quit();
Console Output:
R
51
19
32
1
3
1
6
0
1
2
4
Alternative using Java 8 stream()
As an alternative you can use Java8 stream() and map() as follows:
Code Block:
driver.get("https://www.cricbuzz.com/live-cricket-scorecard/18970/pak-vs-sl-2nd-t20i-pakistan-v-sri-lanka-in-uae-2017");
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("div.ng-scope#innings_1>div div div.text-bold:nth-child(3)"))).stream().map(element->element.getAttribute("innerHTML")).collect(Collectors.toList()));
Console Output:
[R, 51, 19, 32, 1, 3, 1, 6, 0, 1, 2, 4]
Reference
You can find a relavant discussion in:
How to extract the dynamic values of the id attributes of the table elements using Selenium and Java
In the above snippet, you are actually printing WebElement. findElements method returns List and get method on this list will return ith webelement. In order to print runs, you have to use getText() or getAttribute("attribute_name") on webelement, according to HTML structure of the page.
You can modify your code something like this:
List<WebElement> list=table.findElements(By.cssSelector("div[classname='cb-col cb-col-100 cb-scrd-itms'] div:nth-child(3)"));
for(int i=0; i<list.size(); i++){
System.out.println(list.get(i).getText());
}
Please modify your script accordingly and you will be able to print the runs.
Thanks!
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());
Purpose: My code should get the all the links that are available under a drop down menu. It should print all those links under that specific menu.
Site used for testing: http://test1.absofttrainings.com and the specific menu option is Test Pages.
Question/Problem: The code is not printing 2 values that I am expecting, there are 2 links under Test Pages.
Code:
WebDriver driver= new FirefoxDriver();
driver.get("http://test1.absofttrainings.com/#");
//Step1: Create a List of WebElements to put all the links
// the //a will give me all the links associated
List<WebElement> drop_downs= driver.findElements(By.xpath("//a[contains(text(), 'Test Pages')]//a"));
for(int i=0;i<drop_downs.size(); i++){
WebElement e= drop_downs.get(i);
String text=e.getAttribute("innerHTML");
System.out.println("Links are " + text);
}
Thanks in advance for your time.
Code snippet
//find all the links of sibling(s) of the 'Test Pages'
List<WebElement> drop_downs= driver.findElements(By.xpath("//*[contains(text(), 'Test Pages')]/following-sibling::*//a"));
for(WebElement links : drop_downs){
System.out.println(links.getAttribute("innerHTML"));
}
I'm new to Selenium webdriver. I came across a requirement where I have to run my test which clicks on all links with in a section. Can someone help me with the Java code for this. Attached a image which shows firebug properties of that particular section.
I have tried the below code but it returns me a null list.
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("https://dev.www.tycois.com/");
driver.manage().window().maximize();
List<WebElement> allElements = driver.findElements(By.xpath("html/body/div[10]/div/div[1]/div[3]/ul[1]/li[5]"));
System.out.println(allElements);
for (WebElement element: allElements) {
System.out.println(element.getText());
element.click();
}
}
Thanks in advance.
The details aren't clear but it looks like you are trying to print the links in the INDUSTRIES section of the footer. If that's true, this should work.
driver.get("https://dev.www.tycois.com/");
WebElement industries = driver.findElement(By.cssSelector("div.columns.three.alpha > ul"));
List<WebElement> links = industries.findElements(By.tagName("li"));
for (int i = 1; i < links.size(); i++)
{
System.out.println(links.get(i).getText());
}
You can't click the links in this loop because once you click the first one, you will no longer be on the page. I would suggest that you store the URLs from each link in an array and then driver.get(url) for each one. Or you could store the expected URLs in an array and compare the URLs from the links to the expected URLs and not have to navigate at all. The choice is up to you...
The solution from JeffC works with the tweak detailed below -
driver.get("https://dev.www.tycois.com/");
WebElement industries =
driver.findElement(By.cssSelector("div.columns.three.alpha > ul"));
List<WebElement> links = industries.findElements(By.tagName("li"));
for (int i = 0; i < links.size(); i++)
{
System.out.println(links.get(i).getText());
}
The alternate answer above, which I cannot comment on because I'm new to the site had
for(int i=1; i < links.size(); i++)
However this misses off the first element in the list. The suggested fix to use -
for(int i=1; i <= links.size(); i++)
will cause an IndexOutOfBoundsException.
To fix, simply set your iterator to start at 0 instead of 1
You could use like for example:
driver.findElements(By.xpath("//li[contains(#class,'managed-services')]/ul/li/a"));
It is usually bad idea to use XPath attached to root of html i.e Absolute xpath, you should always try to use the shortest selectors possible i.e Relative xpath.
Also remember that if links are hidden, you need to trigger action, which enables them - like open menu for instance.
You can try with the below code.
Just change the xpath according to your application.
List<WebElement> liElements = driver.findElements(By.xpath(".//*[#id='fk-mainhead-id']/div[2]/div/div/ul/li"));
System.out.println(liElements);
for(int i=1; i <= liElements.size(); i++)
{
WebElement linkElement = driver.findElement(By.xpath(".//*[#id='fk-mainhead-id']/div[2]/div/div/ul/li[" + i + "]/a"));
System.out.println(linkElement.getText());
}
WebElement industries = driver.findElement(obj.getElement("history_list"));
List<WebElement> links = industries.findElements(By.tagName("li"));
boolean a = false;
Thread.sleep(10000);
for (WebElement option : links) {
System.out.println("value =" + option.getText());
String s = option.getText();
if (s.equals(new_site_name)) {
a = true;
break;
} else {
continue;
}
}
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