I am writing a small scraping program, it navigates to a page with a list of links,
It clicks on the first link, opens a new page, gets some details, then navigates back to the page with the list of links,
it then tries to find the next link, but i get :
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
any idea how i can avoid this ?
package scraping;
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.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class yell {
private WebDriver driver;
#BeforeClass
public void beforeClass() {
System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\ChromeDriver\\chromedriver.exe");
driver = new ChromeDriver();
}
#Test
public void verifySearchButton() throws InterruptedException {
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get(
"https://www.yell.com/ucs/UcsSearchAction.do?scrambleSeed=1634428901&keywords=farmers&location=bedfordshire");
List<WebElement> linkList = driver.findElements(By.xpath("//a [#class='businessCapsule--title']"));
Thread.sleep(2000);
for (int i = 0; i < linkList.size(); i++) {
System.out.println(linkList.get(i).getText());
System.out.println(linkList.get(i).getAttribute("href"));
linkList.get(i).click();
System.out.println("count start = " + i);
Thread.sleep(2000);
WebElement Add1 = driver.findElement(By.xpath("//span[contains(#itemprop,'streetAddress')]"));
String Add1val = Add1.getText();
WebElement Add2 = driver.findElement(By.xpath("//span[contains(#itemprop,'addressLocality')]"));
String Add2val = Add2.getText();
WebElement Add3 = driver.findElement(By.xpath("//span[contains(#itemprop,'postalCode')]"));
String Add3val = Add3.getText();
WebElement tel = driver.findElement(By.xpath("//span[contains(#class,'business--telephoneNumber')]"));
String telval = tel.getText();
System.out.println(Add1val + " , " + Add2val + " , " + Add3val + " , " + telval);
driver.navigate().back();
System.out.println("count end = " + i);
}
}
#AfterClass
public void afterClass() {
driver.quit();
}
}
The moment you follow the link, DOM is being reconstructed, causing every element you have in linklist to lose any relation to the current page, hence the StaleElementReferenceException.
If you want to visit all links listed on the first page, it's better to keep the links, not the elements themselves.
List<String> linkList = driver.findElements(By.xpath("//a [#class='businessCapsule--title']"))
.stream()
.map(element -> element.getAttribute("href"))
.collect(Collectors.toList());
Now, when you have the list of links, instead of clicking a specific element, you can follow any subsequent link directly.
driver.get(linkList.get(i));
Related
I want to capture all the headers of a table using the selenium using the. I am using the
Xpath to capture the webelement using Xpath.
Xpath:
"//div[#class='dataTables_scrollHeadInner']//tr[#id='report-data-table-header-0']/th"
and it shows all the elements of the div i.e (9 th's),but when I capture it using selenium I only get 7 elements.
All the xpaths are mentioned are required the and the commented block of code is function call of homePage.view_report_values(textString).
Source Code:
package Onsight.Framework;
import java.util.ArrayList;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import com.github.javafaker.Faker;
import avdhut.onsight.commonutils.BaseComponenets;
import avdhut.onsight.pageobject.HomePage;
import avdhut.onsight.pageobject.LoginPage;
import io.github.bonigarcia.wdm.WebDriverManager;
public class Webtable {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
String urlString = "https://oinsightsvm1.westindia.cloudapp.azure.com:444/ctsOInsightsBMS/res/createReport.html";
String userEmailString = "User66";
String userPassword = "Avdhut#5201";
String titleString;
String textString="Clarita";
Faker faker = new Faker();
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
// options.addArguments("--ignore-ssl- errors=yes");
options.addArguments("--ignore-certificate-errors");
WebDriver driver = new ChromeDriver(options);
driver.get(urlString);
LoginPage loginPage = new LoginPage(driver);
loginPage.login_username(userEmailString);
loginPage.click0nsubmit();
loginPage.EnterPassword(userPassword);
loginPage.click0nsubmit();
HomePage homePage = new HomePage(driver);
homePage.view_report_values(textString);
}
}
//tr[class='odd'] em[class='fa fa-table']
Page Object file:
[![public class HomePage extends BaseComponenets {
WebDriver driver;
By createReportBy=By.cssSelector("button\[data-target*='#addReportModal'\]");
By baseTableBy=By.xpath("//table\[#id='query-table'\]");
By report_name_rowsBy=By.xpath("//tbody/tr");
By viewBy=By.xpath("//button\[contains(#title,'View')\]");
By view_dataBy=By.xpath("//button\[contains(#title,'View data')\]");
By dataBy=By.xpath("//table\[#id='reportDataTable-0'\]/tbody/tr ");
By teable_headingBy=By.xpath("//div\[#class='dataTables_scrollHeadInner'\]//tr\[#id='report-data-table-header-0'\]/th");
By next_paginateBy=By.xpath("//li\[#id='reportDataTable-0_next'\]");
By paginateBy=By.xpath("//div\[#id='reportDataTable-0_paginate'\]/ul\[#class='pagination'\]/li\[#class='paginate_button page-item '\]");
By no_of_pagesBy=By.xpath("//div\[#id='reportDataTable-0_info'\]");
public HomePage(WebDriver driver) {
super(driver);
// TODO Auto-generated constructor stub
this.driver=driver;
}
public void CreateReport_Button() {
IsClickable(createReportBy);
WebElement create_Report=driver.findElement(createReportBy);
create_Report.click();
}
public void get_headers() {
IsVisible(teable_headingBy);
List<WebElement> table_headerElement=driver.findElements(teable_headingBy);
for (WebElement header : table_headerElement) {
System.out.println(header.getText());
}
}
public void view_report_values(String report_title) throws InterruptedException {
IsVisible(baseTableBy);
WebElement baseTable=driver.findElement(baseTableBy);
List<WebElement> table_roWebElement=baseTable.findElements(report_name_rowsBy);
List<String> list=new ArrayList<String>();
for (WebElement webElement : table_roWebElement) {
if (webElement.getText().contains(report_title)) {
System.out.println(true);
IsClickable(viewBy);
System.out.println(webElement.getText());
webElement.findElement(viewBy).click();
IsClickable(view_dataBy);
driver.findElement(view_dataBy).click();
IsVisible(next_paginateBy);
List<WebElement> pagebar=driver.findElements(paginateBy);
for(WebElement page:pagebar) {
list.add(page.getText());
}
// name(list);
if (driver.findElement(next_paginateBy).isDisplayed()) {
for (int i = 1; i <= 30; i++) {
if (i==1) {
System.out.println("first_page");
get_headers();
}
// Thread.sleep(10000);
}
} else {
}
//
}
}][1]][1]
Console O/P:
TIMESTAMP
SOURCE NAME
SOURCE STATE
ACK STATE
MESSAGE TEXT
LAST NOTES
After that I googled and then found some articles and then In order to test I used console of google chrome
document.getElementsByClassName('dataTables_scrollBody').scrollLeft += 250", "
It gave me an error , then, I used:
document.getElementsByClassName('dataTables_scrollBody').scrollLeft +=250
Then,
I got the message :
NaN
This is the table I want to scroll also the classname mentioned in belongs to same div of the table in image
After login, add the below code and try:
driver.findElement(By.xpath(".//button[#class='toast-close-button']")).click();
driver.findElement(By.xpath("(.//td[text()='random']//parent::tr//td/button)[1]")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("(.//div[#class='modal-content']//button[#type='button' and #title='View data'])[1]")).click();
Thread.sleep(2000);
JavascriptExecutor js=(JavascriptExecutor)driver;
List<WebElement> headers = driver.findElements(By.xpath(".//div[#class='dataTables_scrollHead']//th"));
System.out.println("Total no. of headers: " + headers.size());
System.out.println("Headers: ");
System.err.println("========");
for (WebElement header : headers) {
js.executeScript("arguments[0].scrollIntoView(true);", header);
System.out.println(header.getText());
}
Output:
Total no. of headers: 9
Headers:
========
TIMESTAMP
SOURCE NAME
SOURCE STATE
ACK STATE
MESSAGE TEXT
LAST NOTES
ALL NOTES
ALARM VALUE
LOW LIMIT
I answered your previous question also, check that, if it works for you, mark that as answer.
Naukari error img: I am getting This error on naukari page but on doing manually it does not appear
I am trying to automate Naukari.com so that it gets updated daily on its own instead of me visiting the website daily to do it. My script is as follows:
package naukariUpdate;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import naukariLoginPOM.LoginPOM;
public class NaukariUpdater {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver","./driver/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.naukri.com/");
driver.getTitle();
String mainWindowTitle = driver.getTitle();
String mainWindowID = driver.getWindowHandle();
Set<String> s = driver.getWindowHandles();
for (String handleID : s)
{
driver.switchTo().window(handleID);
System.out.println(driver.getTitle());
String windowID = driver.getTitle();
if (!windowID.equals(mainWindowTitle))
{
driver.close();
}
}
driver.switchTo().window(mainWindowID);
driver.findElement(By.xpath("(//div[text()='Login'])[1]")).click();
driver.findElement(By.xpath("//a[.='Google']")).click();
Set<String> window = driver.getWindowHandles();
System.out.println();
for (String handleID : window)
{
driver.switchTo().window(handleID);
String windowTitle = driver.getTitle();
System.out.println(windowTitle+"\t"+mainWindowTitle);
if (!windowTitle.equals(mainWindowTitle))
{
System.out.println("in IF");
driver.switchTo().window(handleID);
break;
}
}
System.out.println("out of switching "+driver.getTitle());
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement webElement = driver.findElement(By.xpath("//input[#id='identifierId']"));
wait.until(ExpectedConditions.visibilityOf(webElement));
LoginPOM POM = new LoginPOM(driver);
WebElement logIN = POM.getLogIn();
logIN.sendKeys("Sorry type in your own email ID bro");
WebElement nextBtn = POM.NextButton();
nextBtn.click();
wait.until(ExpectedConditions.visibilityOf(POM.getPassword()));
WebElement pswd = POM.getPassword();
pswd.sendKeys("Sorry type in your own password bro");
nextBtn.click();
}
}
This is the POM:
package naukariLoginPOM;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class LoginPOM {
public LoginPOM(WebDriver driver)
{
PageFactory.initElements(driver , this);
}
#FindBy(xpath = "//input[#id='identifierId']")
private WebElement LogIn;
public WebElement getLogIn()
{
return LogIn;
}
#FindBy(xpath = "//input[#type='password']")
private WebElement Pswd;
public WebElement getPassword()
{
return Pswd;
}
#FindBy(xpath = "//content[.='Next']")
private WebElement NextBtn;
public WebElement NextButton()
{
return NextBtn;
}
}
I don't get where I made the mistake. Everything seems to run fine, yet I get error 1001 in the end. This does not happen when I carry out the process manually by clicking and typing. How can I resolve it?
Error #1001 is an issue with adobe flash player. You will need to redeploy (reinstall) your adobe flash player as it either missing critical libraries or those libraries are corrupted. This is a documented error with Adobe. You can read more about the issue from this link here:
https://forums.adobe.com/thread/258374?start=0&tstart=0
Unfortunately, this is not an issue that is related to Selenium.
The solution is to reinstall your adobe flash player. If your permissions on your workstation are not high enough to do this, ask your IT team.
I am getting the error message:
NoSuchElementException: no such element: Unable to locate element:
{"method":"xpath","selector":"html/body/form/input[1]"}
when I try running the code below.
And the xpath is correct I already double checked
package Package;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
//import org.openqa.selenium.firefox.FirefoxDriver;
public class Selenium1 {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver","C:/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.w3schools.com/Html/tryit.asp?filename=tryhtml_checkbox");
WebElement ele =driver.findElement(By.xpath("html/body/form/input[1]"));
boolean displayedstatus = ele.isDisplayed();
System.out.println("The display status :"+displayedstatus);
boolean enablestatus = ele.isEnabled();
System.out.println("The enable status :"+enablestatus);
boolean selectedstatus = ele.isSelected();
System.out.println("The selected status :"+selectedstatus);
ele.click();
selectedstatus = ele.isSelected();
System.out.println("The selected status :"+selectedstatus);
}
}
Whenever you try searching for the elements within the iframe you must have to switch the focus to the iframe that you are dealing with.
Try this before searching for the elements within the iframe:
driver.switchTo().frame(driver.findElement(By.name("iframeTitle")));
In this case, the iframe Title is : iframeResult
Below is the code:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
//import org.openqa.selenium.firefox.FirefoxDriver;
public class Selenium1 {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver","C:/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.w3schools.com/Html/tryit.asp?filename=tryhtml_checkbox");
//switching focus to iframe
driver.switchTo().frame(driver.findElement(By.name("iframeResult")));
WebElement ele =driver.findElement(By.xpath("html/body/form/input[1]"));
boolean displayedstatus = ele.isDisplayed();
System.out.println("The display status :"+displayedstatus);
boolean enablestatus = ele.isEnabled();
System.out.println("The enable status :"+enablestatus);
boolean selectedstatus = ele.isSelected();
System.out.println("The selected status :"+selectedstatus);
ele.click();
selectedstatus = ele.isSelected();
System.out.println("The selected status :"+selectedstatus);
}
}
If you want to handle one of two checkboxes, you need to switch to iframe first and then search for the element.
driver.get("https://www.w3schools.com/Html/tryit.asp?filename=tryhtml_checkbox");
driver.switchTo().frame("iframeResult");
WebElement ele =driver.findElement(By.xpath("//input[#value='Bike']"));
If after that you want to handle elements outside iframe, you might need to switch back with
driver.switchTo().defaultContent();
I am trying to capture the prices in a list and print them. However the execution stops in the search result page and does not print the prices. I think it is because of the level of Xpath (probably I am not selecting from the upper levels?). I am confused because the Xpath I have created, when I use that in the Firepath it selects 39 matching nodes.
Thanks in advance for your time and advice.
Code:
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Flight {
public static WebDriver driver;
//This following section is for browser and getting the url
public static WebDriver browser(){
driver= new FirefoxDriver();
driver.get("https://www.orbitz.com/Flights");
return driver;
}
//this following section is getting the properties of the page
public static void getPageProperties(String ff,String ft, String fd, String rd){
WebElement flyFrom= driver.findElement(By.id("flight-origin"));
WebElement flyTo= driver.findElement(By.id("flight-destination"));
WebElement flyDate= driver.findElement(By.id("flight-departing"));
WebElement returnDate= driver.findElement(By.id("flight-returning"));
WebElement flight_search_btn= driver.findElement(By.id("search-button"));
flyFrom.sendKeys(ff);
flyTo.sendKeys(ft);
flyDate.sendKeys(fd);
returnDate.sendKeys(rd);
flight_search_btn.click();
}
// this following section will have the arguments that we will provide for flight search
public static void testFligthSearch(){
Flight f= new Flight();
f.browser();
f.getPageProperties("MSP", "SEA", "05/01/2017", "05/05/2017");
List<WebElement> pricelist= driver.findElements(By.xpath("//span[contains(#class,'dollars')]"));
for(WebElement e: pricelist){
System.out.println("The prices are: " + e.getText());
}
}
public static void main (String [] args){
Flight f= new Flight();
f.testFligthSearch();
}
}
Problem: No price is printed.
You are facing this problem because all the results have not been loaded yet so you have to wait until all search results are loaded, so you need to wait until the search results progress bar has reached 100% as following :
WebElement progressBar = driver.findElement(By.cssSelector("#acol-interstitial > div > div"));
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.attributeContains(progressBar, "style", "width: 100%;"));
List<WebElement> pricelist= driver.findElements(By.cssSelector("ul#flightModuleList div.offer-price.urgent > span.visuallyhidden"));
for(WebElement e: pricelist){
System.out.println("The prices are: " + e.getText());
}
How to count number of images available on a web page using selenium webdriver? The web page contains a lots of image some are visible and some are hidden (display:none). I only wants to count images which are visible(not hidden).
I tried this but it doesn't work for only visible images.
#Test
public void imagetest()
{
driver.get("http://uat.tfc.tv/");
List<WebElement> listwebelement = driver.findElements(By.className("img-responsive"));
int i=0;
for (WebElement Element : listwebelement) {
i = i+1;
System.out.println(Element.getTagName());
System.out.println(Element.getText());
String link = Element.getAttribute("alt");
System.out.println(link);
}
System.out.println("total objects founds " + i);
}
Here you wanted to find out the no. of images in a page, so better check with tag name like below:
driver.findElements(By.tagName("img")
Here is the complete code for your reference
#Test
public void findNoOfDisplayeImages() throws InterruptedException
{
WebDriver driver=new FirefoxDriver();
Integer counter=0;
driver.get("http://uat.tfc.tv/");
Thread.sleep(20000);
List<WebElement> listImages=driver.findElements(By.tagName("img"));
System.out.println("No. of Images: "+listImages.size());
for(WebElement image:listImages)
{
if(image.isDisplayed())
{
counter++;
System.out.println(image.getAttribute("alt"));
}
}
System.out.println("No. of total displable images: "+counter);
driver.close();
}
You need to apply isDisplayed() check on each image element in the loop:
for (WebElement Element : listwebelement) {
if (!Element.isDisplayed()) {
continue;
}
...
}
package p1;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class CountImages {
public static void main(String[] args) {
System.setProperty("webdriver.gecko.driver","/home/mcastudent/Downloads/software/geckodriver" );
WebDriver driver=new FirefoxDriver();
driver.get("https://opensource-demo.orangehrmlive.com/index.php/dashboard");
List<WebElement> listImages=driver.findElements(By.tagName("img"));
System.out.println("No. of Images: "+listImages.size());
}
}