Java selenium avoiding iframe address bar element - java

Currently I wrote a short program that traverses through a page and looks for web elements with the tagname = "input", then uses sendkeys to send data to the element, then submits it. The problem I have is that although it works most of the time, if I have an iframe on the page, and I traverse through the webpage looking for an element with the tagname = "input", it focuses on the addressbar of the iframe and sends data to it, then tries to submit it causing an error (when I printed the tagname of the addressbar in the iframe, it printed out "input" on the console).
Is there a way to avoid the addressbar on an iframe from being picked up as an element with the tagname = "input"?
Im using the following to check if an element has tagname of "input":
List<WebElement> element = driver.findElements(By.xpath("//*"));
int mainSize = element.size();
for ( int j = 0; j < mainSize; j++ ) {
if(frameElement.get(j).getTagName().toString().equals("input")){
//do something
}
}
Some notes:
-This occurs when going through the webpage elements searching through tagnames for "input" elements BEFORE switching to the iframe element with the switchTo() method.

In order to avoid the address bar, you can introduce one more check to ensure that the input element is not an address bar. Following is the updated code to achieve this:
List<WebElement> element = driver.findElements(By.xpath("//*"));
int mainSize = element.size();
for ( int j = 0; j < mainSize; j++ ) {
if(element.get(j).getTagName().toString().equals("input") &&
!element.get(j).getAttribute("class").equals("urlbar")){
//do something
}
}
UPDATE 1
We can retry when unexpected browser search bar appears. Try following:
List<WebElement> element = driver.findElements(By.xpath("//*"));
int mainSize = element.size();
for ( int j = 0; j < mainSize; j++ ) {
if(element.get(j).getTagName().toString().equals("input") &&
!element.get(j).getAttribute("class").equals("urlbar")){
//do something
try {
element.get(j).sendKeys(somedata);
element.get(j).submit();
} catch (WebDriverException we) {
System.out.println("It seems browser search bar has been appeared. Retrying...");
//Pressing escape key to get rid of browser search bar
element.get(j).sendKeys(Keys.ESCAPE);
//Retrying
element.get(j).sendKeys(somedata);
element.get(j).submit();
}
}
}
Let me know, if you have any further queries.

Related

Issues in finding elements of the hashtag posts in Instagram

Scenario:
Login with username and password
Search with hashtag
Click on each post and click on like button
Code for searching post and liking:
List<WebElement> postlinks =
driver.findelements("//a[starts-with(#href, '/p')]");
for(int i=0;i<postlinks.size();i++){
postlinks.get(i).click();
Like.click();.
}
My Issue:
Size of postlinks is 21 at first but it increases after scrolling.
Size changes whenever it is scrolled.
Here
List<WebElement> postlinks =
driver.findelements("//a[starts-with(#href, '/p')]");
you are collecting the links, lets say size is 21.
Gone for forLoop
for(int i=0;i<postlinks.size();i++){
Inside of this performing some clicks, if you think that it leads to increase the links but still you are using postlinks which is fixed 21.
Try using while loop
List<WebElement> postlinks = driver.findelements("//a[starts-with(#href, '/p')]");
// define maximum post count to click
int MaxCount = 40;
int i = 0;
while(i < MaxCount) {
postlinks.get(i).click();
Like.click();
i++;
if(i == postlinks.size()) // index of 20, 40,... then get new element
postlinks = driver.findelements("//a[starts-with(#href, '/p')]");

Get TH index number using Xpath in selenium

Hi I just want to get the index number of TH column using unique Xpath. Like A loop will run and check on which TH column Xpath match and return the index number. Is there any way i can do this in selenium ? Till now im able to get the tag index and run the the loop but now I have check the on each TH with xpath rather its matched or not and give me the index number. Please let me know is there anything with Im able to achieve this with this logic or any other any Xpath techniques.
Table = driver.findElement(By.xpath("//table/thead[#class='ui-datatable-thead']"))
List<WebElement> rows_head = Table.findElements(By.tagName('th'))
int head_size= rows_head.size()
System.out.println(head_size);
for (int c = 1; c <= head_size; c++) {
driver.findElement(By.xpath(
"//th[4][#class='ui-state-default ui-unselectable-text ui-sortable-column']")
)
// Here is something I want loop will check the each TH with above given
// Xapth and return the TH index in the table on match TH xpath index.
}
Selenium doesn't supply an API to return the xpath of found element. So you can't archive your goal by comparing xpath.
But Selenium supply API to get the attribute value of found element, you can compare with it to see it's your desired element or not.
WebElement thead = driver.findElement(By.xpath("//table/thead[#class='ui-datatable-thead']"));
List<WebElement> heads = thead.findElements(By.tagName('th'));
int head_size= heads.size()
System.out.println(head_size);
String expectedClass = "ui-state-default ui-unselectable-text ui-sortable-column"
int i = 1;
for (; i <= head_size; i++) {
if(heads[i].getAttribute("class").equal(expectedClass))
// check attribute class value is as expect
// you can change to other attribute or check more than one attribute
break;
)
}
System.out.println("Matched th index: " + i);

“StaleElementReferenceException” in Selenium for a List<WebElement>

Please refer the below code, this code will fetch all the orderID from findtable method and it passes all of the orderID to clickonIndividualOrderID method
so the cursor moves to each orderid and it clicks on it, a new page will come and it fetch the status and clicks on done and it comes back to old page now if we try to select next orderID, it will throw the exeception
Could you please suggest some approaches to resolve this issue
Thanks in advance
List<WebElement> orderID = new ArrayList<WebElement>();
List<WebElement> statusID = new ArrayList<WebElement>();
public void OrderandReleases()
{
orderID = outboxpage.findtable(orderID);
util.pause("1");
statusID = outboxpage.findordernumber(statusID, orderID);
}
public List<WebElement> findOrderID(List<WebElement> orderID) {
WebElement table = driver.findElement(By.id("_kod7c3"));
List<WebElement> allRows = table.findElements(By.tagName("tr"));
//And iterate over them, getting the cells
for (int i = 1; i < allRows.size(); i++) {
List<WebElement> alltd = allRows.get(i).findElements(By.tagName("td"));
for (int j = 0; j < alltd.size(); j++) {
if (j == 1) {
orderID.add(alltd.get(j));
continue;
}
}
}
return orderID;
}
public List<WebElement> clickonIndividualOrderID(List<WebElement>
statusID,List<WebElement> orderID){
for (int i = 0; i < orderID.size(); i++) {
WebElement table = driver.findElement(By.id("_kod7c3"));
if (table.isDisplayed()) {
System.out.println("Clicking on
order="+orderID.get(i).getText()); -> //first time it will run fine , second time when it loops back it will thow the execption StaleElementReferenceException here
orderID.get(i).click(); -> //it is clicking on a order link and it will take me to next page
driver.findElement(By.id("_jxndro")).click();
WebElement table2 = driver.findElement(By.xpath("//*
[#id=\"_mfb\"]"));
List<WebElement> allRows2 =
table2.findElements(By.tagName("tr"));
String col = "";
for (int j = 1; j < allRows2.size(); j++) {
List<WebElement> alltd2 =
allRows2.get(j).findElements(By.tagName("td"));
int flag = 0;
for (int k = 0; k < alltd2.size(); k++) {
col = alltd2.get(k).getText().toString().trim();
System.out.println(col);
if (col.equals("Failed")||col.contains("FE-")) {
statusID.add(alltd2.get(++k));
driver.findElement(By.id("_uvsub")).click(); --> // it will take me back to the first page
flag =1;
break;
}
}
if(flag==1)
break;
}
}
}
return statusID;
}
Whenever you find a specific exception from any third party code, you should look for information in the official documentation of said code if available. You can find information about the "StaleElementReferenceException" here
In said page you will find this
The most frequent cause of this is that page that the element was part of has been refreshed, or the user has navigated away to another page.
You're navigating to another page, so all the references will be lost. The driver do not have the knowledge that its the same page, with the same objects.
You need to look for a different way to keep track of which links you already clicked, or open the links in a new tab/window, to do whatever you need to, and then dispose the tab/window instead of navigating back.
The official documentation for StaleElementReferenceException says:
Indicates that a reference to an element is now "stale" --- the element no longer appears on the DOM of the page.
If you are navigating back and forth between pages, as you are doing, then this is the expected behaviour.
The normal way to approach this is to not keep track of the WebElements outside of the loop, but find them inside the loop during each iteration. Something like this:
// this will not change, but you need to adjust for your case!
By pageLocator = By.tagName("a");
int pageCount = driver.findElements(pageLocator).size();
for (int i = 0; i < pageCount; i++) {
WebElement pageLink = driver.findElements(pageLocator).get(i);
pageLink.click();
// at this point pageLink is gone stale!
// do some stuff
driver.navigate().back();
}

How to print list of categories and click on each category one by one in selenium/appium?

I want to print and then click on list of all items like home top stories, latest news, opinion etc each and every category as you can see in image but did get success please help..
List<WebElement> list=driver.findElements(By.id("com.readwhere.whitelabel.prabhatkhabar:id/left_drawer_list"));
for(int i=0;i<list.size();i++)
{
System.out.println(list.get(i).getText()+"\n");
}
Most probably you are trying to find the list with wrong id. If in this window only category names are present as text, try find with texts.
After trying findElements with valid id, you need to click each category and then return to window containing the list again. Try this way:
// Trying to find the list with texts
List<WebElement> list = driver.findElements(By.className("android.widget.TextView"));
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i).getText() + "\n");
list.get(i).click(); // clicking on each category
// navigate back to previous window
}
For navigating back, you can use this code:
driver.navigate().back();
try with the below code:
List<WebElement> listForSize =driver.findElements(By.id("com.readwhere.whitelabel.prabhatkhabar:id/left_drawer_list"));
int size = listForSize.size();
for (int i=0; i< size;i++)
{
//this is taken again because you are navigate back again
List<WebElement> list = driver.findElements(By.id("com.readwhere.whitelabel.prabhatkhabar:id/left_drawer_list"));
System.out.println(list.get(i).getText() + "\n");
list.get(i).click();
driver.navigate().back();
Thread.sleep(2000);//avoid this kind of waiting. wait using until
}
let me know if any error occurs.

How to get all "li" elements of "ul" class in Selenium WebDriver

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;
}
}

Categories