StaleElementReferenceException in datepicker - java

I am able to select date, day and year from date picker, but after selecting, the page is refreshed and the Webdriver element is detached and getting StaleElementReferenceException. I am not understanding how to build the object instance as its a date picker, it cant be clicked again.

WebElement dateWidget = getDriver().findElement(DATEPICKER_WIDGET);
List<WebElement> rows = dateWidget.findElements(By.tagName("tr"));
for (WebElement row : rows) {
List<WebElement> columns = row.findElements(By.tagName("td"));
for (WebElement cell : columns) {
try{
if (cell.getText().equals(String.valueOf(calendar.get(Calendar.DATE)))) {
cell.findElement(By.linkText(String.valueOf(dayValue))).click();
boolean flag = commonpage.isAlertPresent();
if (flag == true) {
String text = commonpage.closeAlertAndGetItsText();
addScreenshot("Alert text: " + text);
}
break;
}}catch(StaleElementReferenceException e){
}
The problem is after picking the correct date, I got an alert box and that too handled perfectly. But after alert box, the page is refreshed, and selenium is having problem in identifying what is cell (WebElement) as the page is refreshed. Not understanding how to re-instantiate WebElement cell.

Related

Click on table row if text is found

I use this Java code with Selenium to select table row based on found text:
WebElement tableContainer = driver.findElement(By.xpath("//div[#class='ag-center-cols-container']"));
List<WebElement> list = tableContainer.findElements(By.xpath("./child::*"));
// check for list elements and print all found elements
if(!list.isEmpty())
{
for (WebElement element : list)
{
System.out.println("Found inner WebElement " + element.getText());
}
}
// iterate sub-elements
for ( WebElement element : list )
{
System.out.println("Searching for " + element.getText());
if(element.getText().equals(valueToSelect))
{
element.click();
break; // We need to put break because the loop will continue and we will get exception
}
}
Full code: https://pastebin.com/ANMqY01y
For some reason table text is not clicked. I don't have exception. Any idea why it's not working properly?
See there are 2 divs with //div[#class='ag-center-cols-container'] with this xpath.
first div does not have anything, while second div has child divs.
I would suggest you to use :
List<WebElement> list = driver.findElements(By.xpath("//div[#class='ag-center-cols-container']//div"));
Remove this line from your code :
WebElement tableContainer = driver.findElement(By.xpath("//div[#class='ag-center-cols-container']"));

Double click on table row and insert value

I use this code to double click on table row and insert a value into input filed:
WebElement element = driver.findElement(By.xpath("/......iv[3]"));
Actions builder = new Actions(driver);
builder.doubleClick(element).perform();
Thread.sleep(3000);
// Insert into Accessorial Tasks screen Actual value
insertInputFieldByXPath(driver, "...../input",
"3");
protected void insertInputFieldByXPath(WebDriver driver, String input_id, String value){
WebDriverWait webDriverWait = new WebDriverWait(driver, 15);
WebElement webElement = webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(input_id)));
webElement.clear(); // First we delete the old value in case if this is a spinner
webElement.sendKeys(value);
}
When I double click with Selenium the table row becomes input field. But when I try to enter some value the id is not found. Maybe it's not found because the input field ID is dynamically added when I double click.
Do you know how this issue can be solved?

Java Selenium - Fetching data from HandsonTable

I am trying to fetch data from Handsontable. The table contains 700 data, however when i am locating through the Xpath, At first only 27 data found out of 55 and when i scroll down it changes to 22 out of 40. every time its taking random data. Below I have tried to create a scroll and getColumnData functions.
private void scrollDown() {
JavascriptExecutor js = (JavascriptExecutor) driver();
js.executeScript("arguments[0].scrollIntoView({block: 'center'});", rows().get(rows().size()-1));
}
protected LinkedList<WebElement> getColumnWebElement(String columnName)
{
LinkedList<WebElement> columnElement = new LinkedList<WebElement>();
int indexColumn = getLocationOfColumnInHeader(columnName) + 3;
WebElement headerRow = this.headerRow();
List<WebElement> rows = this.rows();
System.out.println(this.rows());
for (WebElement currentRow : rows)
if (currentRow != headerRow)
{
scrollDown();
WebElement td = driver.getValidatedElementNoWait(currentRow, By.xpath("./td[" + indexColumn + "]"));
if (td != null)
{
columnElement.add(td);
}
}
return columnElement;
}
Is there anyway to read all dynamic changing data based on Column name.
Thanks in Advance!
I used below workaround.
public void changeTableAttribute() {
JavascriptExecutor js = (JavascriptExecutor) driver();
WebElement element = driver().findElement(By.xpath("//hot-table/div[#class='handsontable-container handsontable htColumnHeaders']"));
js.executeScript("arguments[0].setAttribute('style', 'height:15000px')", element);
}

I am getting StaleElementReferenceException: element is not attached to the page document

HTMLCODE
I am getting StaleElementReferenceException: element is not attached to the page document. I went through some of the solutions that are already there in StackOverflow. It did not work and it continues to throw the same error. Here is the code I am using which is throwing the stale reference error
WebElement table2 = driver.findElement(By.cssSelector("body > div:nth-child(74) > div.sp-palette-container"));
List<WebElement> allrows2 = table2.findElements(By.tagName("div"));
for(WebElement row2: allrows2){
List<WebElement> cells = row2.findElements(By.tagName("span"));
for(WebElement cell:cells){
if (cell.getAttribute("title").equals("rgb(0, 158, 236)")) {
cell.click();
}
}
}
Because clicking the found cell lead some HTML changes on the current page , due to this changes selenium will treat the page(after click) is an "new" page (even though not redirect to another page actually).
In the next iteration of the loop, the loop still refer to element belongs to "previous" page, this is the root cause of "StateElementReference" exception.
So you need to find those elements again on the "new" page to change the reference of element comes from "new" page.
WebElement table2 = driver.findElement(By.cssSelector("body > div:nth-child(74) > div.sp-palette-container"));
List<WebElement> allrows2 = table2.findElements(By.tagName("div"));
int rowSize, cellSize = 0;
rowSize = allrows2.sie();
for(int rowIndex=0;rowIndex<rowSize;rowIndex++){
WebElement row2 = allrows2.get(rowIndex);
List<WebElement> cells = row2.findElements(By.tagName("span"));
cellSize = cells.size();
for(int cellIndex=0;cellIndex<cellSize;cellIndex++){
WebElement cell = cells.get(cellIndex);
if (cell.getAttribute("title").equals("rgb(0, 158, 236)")) {
cell.click();
// find cells again on "new" page
cells = row2.findElements(By.tagName("span"));
// find rows again on "new" page
allrows2 = table2.findElements(By.tagName("div"));
}
}
}
If your usecase is to click() on the elements with title as rgb(0, 158, 236) you can use the following code block :
String baseURL = driver.getCurrentUrl();
List<WebElement> total_cells = driver.findElements(By.xpath("//div[#class='sp-palette-container']//div//span"));
int size = total_cells.size();
for(int i=0;i<size;i++)
{
List<WebElement> cells = driver.findElements(By.xpath("//div[#class='sp-palette-container']//div//span"));
if (cells.get(i).getAttribute("title").contains("rgb(0, 158, 236)"))
{
cells.get(i).click();
//do your other tasks
driver.get(baseURL);
}
}
Use a "break" after clicking on the element found. The exception occurs because, after clicking on your element, the loop continues.
WebElement table2 = driver.findElement(By.cssSelector("body > div:nth-child(74) > div.sp-palette-container"));
List<WebElement> allrows2 = table2.findElements(By.tagName("div"));
for(WebElement row2: allrows2){
List<WebElement> cells = row2.findElements(By.tagName("span"));
for(WebElement cell:cells){
if (cell.getAttribute("title").equals("rgb(0, 158, 236)")) {
cell.click();
break;
}
}
}

How to select all list options from drop downlist loop through them selcet each option and click submit button using selenium webdriver

Here is the link to print name and meaning columns of all pages using drop down
Try to build the script for following:
1. Go to http://babynames.merschat.com/index.cgi?function=Search&origin=Sanskrit&gender=f
2. print the name and meaning columns to syso.
I was able to print page 1 as it is a default page.
Here is the code:
public class BabyNamesAndMeanings {
WebDriver driver = new FirefoxDriver();
#BeforeClass
public void setUp() {
driver.get("http://babynames.merschat.com/index.cgi?function=Search&origin=Sanskrit&gender=f");
driver.manage().window().maximize();
}
#Test
public void printBabyNamesAndMeaningsOfFirstPage() {
WebElement baby_names = driver
.findElement(By
.xpath("//tbody/tr[7]/td[3]/table[2]/tbody/tr[2]/td[2]/font/table[1]/tbody"));
List<WebElement> names = baby_names.findElements(By
.xpath("//tr/td[1]/font/a"));
List<WebElement> meanings = baby_names.findElements(By
.xpath("//tr/td[4]/font/a"));
for (int i = 0; i < names.size(); i++) {
System.out.println("Name: " + names.get(i).getText()
+ " Meaning: " + meanings.get(i).getText());
}
}
I don't know how to loop through rest of the options in the drop down list at the bottom of the page and hit submit button to print name and meaning of all the pages.
There are 100+ pages.
Thanks in advance.
The code below will do your job.
driver.get("http://babynames.merschat.com/index.cgi?function=Search&origin=Sanskrit&gender=f");
List<WebElement> pageOptions = new Select(driver.findElement(By.xpath("//select[#name='page']"))).getOptions();//Get all options in dropdown
ArrayList<String> pageDd = new ArrayList<String>();
for(WebElement eachPage:pageOptions){
pageDd.add(eachPage.getText());//Save text of each option
}
int i=1;
for(String eachVal:pageDd){
new Select(driver.findElement(By.xpath("//select[#name='page']"))).selectByVisibleText(eachVal);//Select page
driver.findElement(By.xpath("//input[#value='Go']")).click();//Click on go
List<WebElement> names = driver.findElements(By.xpath("//a[contains(#title,' meanings and popularity')]"));//Get all names on page
for(WebElement eachName:names){
String name = eachName.getText(); //Get each name's text
WebElement mean = eachName.findElement(By.xpath("./../../..//a[contains(#title,'Names for baby with meanings like ')]"));//Get meaning for that name
String meaning = mean.getText();//Get text of meaning
System.out.println(i+") Name: " +name+ " Meaning: " + meaning);//Print the data
i++;
}
}
Try and understand the way requirement is achieved. If you have any doubt ask.
Another method to iterate and select all the Dropdown values
Select dropdown= new Select(WebUIDriver.webDr.findElement(By.xpath("enter xpath")));
int noOfDropDownValues= dropdown.getOptions().size()-1;
for(int i=0;i<noOfDropDownValues;i++){
new Select(WebUIDriver.webDr.findElement(By.xpath("Enter Xpath']"))).selectByValue(String.valueOf(i));
}

Categories

Resources