How to click child links of each menu in Selenium with Java - selenium

I am trying to use the link https://www.bloomingdales.com/
Click child links of each menu .Below is the code i tried .
public void iClickOnFOBSShouldVerifyTheRespectivePages() throws Throwable {
List allElements = Elements.findElements(By.xpath("//ul[#id='mainNav']/li/a"));
for (int i = 0; i <= allElements.size(); i++) {
List<WebElement> links = Elements.findElements(By.xpath("//ul[#id='mainNav']/li/a"));
WebElement ele = links.get(i);
ele.click();
List<WebElement> childlinks = Elements.findElements("left_facet.left_nav");
for (int j = 0; j <= childlinks.size(); j++) {
List<WebElement> ele2 = Elements.findElements(By.xpath("left_facet.left_nav"));
WebElement ele3 = links.get(i);
ele3.click();
Navigate.browserBack();
}
}
Below is the error i am getting
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document

Try This::List<WebElement>ele = driver.findElements(By.xpath("//ul[#id='mainNav']/li/a"));
Actions act =new Actions(driver);
Thread.sleep(4000);
for (int i = 0; i <= ele.size(); i++) {
WebElement a =ele.get(i);
act.moveToElement(a).build().perform();
Thread.sleep(2000);
List<WebElement>ChildMenu=driver.findElements(By.xpath("//nav[#id='nav']/div[2]/div/div/div[#class='flyoutCol']/div/ul/li"));
System.out.println("Sub-Menu="+ChildMenu.size());
for(int j=0;j<ChildMenu.size();j++){
ChildMenu.get(i).click();
Thread.sleep(2000);
driver.navigate().back();
Thread.sleep(2000);
act.moveToElement(a).build().perform();

On clicking any of the links, the browser will open a new page. At that moment the elements in the page corresponding to allElements, ele and ele2 disappear ("element is not attached to the page document") in the browser and are thus not valid anymore. I would expect that the first click on a submenu child would work but anything after that will fail.
What you could do is first check how many children each submenu has, store this in an array and then create a double loop somewhat similar to what you have already done. For each submenu and submenu child click, you can't use any of the webelements in memory of your program because their state was changed so you would need to initialize a completely new webelement.
With xpath you should be able to reference directly to an element like 'parent - 3rd submenu - 7th submenu child'.
I am unfortunately not able to quickly create working code, otherwise I would have done so.
What I am wondering is: what is the purpose of this code? You don't do any assertions, so if any submenu child click leads to an error page, your code will not fail. Is this desired? It might not even fail if clicking doesn't even open an error page. I guess this code would fail if some of the submenu children are present in the HTML but for some reason not visible.
If this is meant to be a test, I would recommend to make a handful of separate tests that cover a few examples (and assert that clicking leads to the expected page) instead of looping through everything. This will make the tests far more understandable for yourself and others.

Related

Waiting for elements with Selenium WebDriver

I am automating a web page that essentially has a button which, each time it is pressed, creates a new text field.
I am using the FindBy annotation with PageFactory to find the list of text fields.
I have a synchronization problem when I press the button several times, thus creating several text fields, and then try to write into one of them. Stepping through the debugger it works fine, but out of the debugger there is a delay before the FindBy finds all the text fields.
My current workaround performs sleeps until the required number of text fields are found but I find this quite unsatisfactory. Any suggestions how the synchronization could best be done?
#FindBy(how= How.XPATH, using="//*[contains(#id, 'TextField')]")
private List<WebElement> textFields;
:
:
public void enterText(Integer index, String text){
int attempts = 0;
// Check every 10th of a second for 10 seconds if all the textFields have been found
while ((textFields.size() <= index) && attempts < 100){
Thread.sleep(100);
}
textFields.get(index).sendKeys("blah blah");
}
First of all use Implicit wait for all element present in script.
This wait is wait for all element present in the script
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
Initiate above just after get.("URL");
Now for specific element which need additional time you can use below code:-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
Refer below:-
http://toolsqa.com/selenium-webdriver/wait-commands/
Hope it will help you :)

Selecting multiple elements with Selenium

I'm creating List of all available elements with below Xpath.
IList<IWebElement> test= Driver.FindElements(By.XPath("//*[#id='middle-container']//div[#class='middle-section match-list']//div[contains(#class,'title')]//span[contains(text(),'" + Event.Trim() + "')]//..//..//..//..//div[contains(#class,'drop-down-content')]//table[contains(#class,'hidden-xs')]//tr//td[contains(#class,'bettype')]//a[#class='bet']`//span"));
So all the elements available in that Xpath need to be clicked. Running foreach loop:
foreach (var item in availableSports)
{
item.Click();
}
}
My problem is let's say if test contains more than, I think, 10 elements, it is stopping the click event after around 8 to 9 clicks, and raising this error:
StaleElementReferenceException
So just wondering how can I write the method which will continue click until last available element without fail.
You are getting StaleElementReferenceException because something has changed in the DOM after you performed the FindElements operation.
You have mentioned that you are clicking on the items in the list. Does this click action reload the page or navigate to a different page. In both cases the DOM has changed. Hence the Exception.
You can handle this(hopefully) with the following logic. I am a JAVA guy and the following code is in JAVA. But I think you get the idea.
IList<IWebElement> test= Driver.FindElements(By.XPath("//*[#id='middle-container']//div[#class='middle-section match-list']//div[contains(#class,'title')]//span[contains(text(),'" + Event.Trim() + "')]//..//..//..//..//div[contains(#class,'drop-down-content')]//table[contains(#class,'hidden-xs')]//tr//td[contains(#class,'bettype')]//a[#class='bet']`//span"));
// Instead of using the for each loop, get the size of the list and iterate through it
for (int i=0; i<test.length; i++) {
try {
test.get(i).click();
} catch (StaleElementReferenceException e) {
// If the exception occurs, find the elements again and click on it
test = test= Driver.FindElements(By.XPath("//*[#id='middle-container']//div[#class='middle-section match-list']//div[contains(#class,'title')]//span[contains(text(),'" + Event.Trim() + "')]//..//..//..//..//div[contains(#class,'drop-down-content')]//table[contains(#class,'hidden-xs')]//tr//td[contains(#class,'bettype')]//a[#class='bet']`//span"));
test.get(i).click();
}
}
Hope this helps you.

How to click webelement that contains text i searched for using selenium webdriver?

I'm searching for some text using the foloowing code and trying to click on it, but for some reason i cant figure out no action takes place...why is that?
code:
for (int i=0; i<AllTableTd.size();i++){
if (AllTableTd.get(i).getText().toLowerCase().contains("autesting".toLowerCase())) {
AllTableTd.get(i).sendKeys(Keys.RETURN);
break;
}
If you want to use that web element do
WebElement we = driver.find element(your element);
we.click()
Or
driver.find element(your element).click();

StaleElementReferenceException when trying to reidentify the object

I am facing problem to identify the object when i move forward and comeback to parent page.
Here is the scenario. I would like to click on each link in a home page and print page title and navigate back to home page.
Following is the code which i tried. It works fine clicking on the first link and coming back to HomePage. At this point of time, the List Object needs to be identified excluding already visited links. How to do that?
In QTP, we have RefreshObject and Init to do this. Is there a similar method in WebDriver?
WebDriver driver = new FirefoxDriver();
driver.get("http://www.googl.com/");
driver.manage().window().maximize();
List<WebElement> objWEs = driver.findElements(By.tagName("a"));
for(WebElement e:objWEs)
{
if(!e.getText().isEmpty())
{
e.click();
System.out.println(driver.getTitle());
driver.navigate().back();
}
}
driver.close();
As soon as you navigate to another web-page, or even switch into an iframe in the same web-page, any WebElement object that you have in memory is potentially "stale".
One optional solution, is to list down all the element IDs, and then iterate that list instead:
Set<String> linkIds = new HashSet<String>();
List<WebElement> links = driver.findElements(By.tagName("a"));
for (WebElement link : links)
{
if(!link.getText().isEmpty())
linkIds.add(link.getAttribute("id"));
}
for (String linkId : linkIds)
{
driver.findElement(By.id(linkId)).click();
System.out.println(driver.getTitle());
driver.navigate().back();
}
Please note, however, that all the above is under the assumption that each link has a unique ID, and that all the links remain in the web-page when you navigate back into it. If this is not the case in the specific web-page that you are accessing, then an alternative approach is required here.
Instead of iterating the link-IDs, you can iterate the link-indexes, assuming that the links remain in the same order when you navigate in and out of the web-page. This is somewhat less efficient though, because you have to retrieve the entire list of all the links at the beginning of each iteration.
for (int i=0; true; i++)
{
List<WebElement> links = driver.findElements(By.tagName("a"));
if (i >= links.size())
break;
links.get(i).click();
System.out.println(driver.getTitle());
driver.navigate().back();
}
The code above should work even if the links do not remain in the same order when you navigate back into the web-page. However, under such scenario, you will most likely miss out on some of them.
Here is the complete code for my above problem.
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(1, TimeUnit.MINUTES);
driver.get("http://www.googl.com/");
driver.manage().window().maximize();
for (int i=0; true; i++)
{
List<WebElement> links = driver.findElements(By.tagName("a"));
if (i >= links.size())
break;
WebElement ele=links.get(i);
if(!ele.getText().isEmpty())
{
ele.click();
System.out.println(driver.getTitle());
driver.navigate().back();
}
}
driver.close();

How do you click on a checkbox from a list of checkboxes via Selenium/Webdriver in Java?

I'm using Selenium 2 (Webdriver) for automating tests on a webpage. However I wonder if there is way to check checkbox from the list of checkboxes using webdriver framework?
I tried this code but no avail:
IWebElement box = ffDriver.FindElement(By.XPath("//*[#id='ctl00_ContentPlaceHolder1_Adde_div']"));
List<IWebElement> chkbox = box.FindElements(By.TagName("input"));
ffDriver.FindElement(By.Id("ctl00_ContentPlaceHolder1_Add_lstCategory_0"));
//chkbox.g(2).click();
If you already know the id of the checkbox, you can use this method to click select it:
string checkboxXPath = "//input[contains(#id, 'lstCategory_0')]"
IWebElement elementToClick = driver.FindElement(By.XPath(checkboxXPath));
elementToClick.Click();
Assuming that you have several checkboxes on the page with similar ids, you may need to change 'lstCategory_0' to something more specific.
This is written in C#, but it shouldn't be difficult to adapt to other languages. Also, if you edit your post with some more information, I can fine-tune this example better.
Let me know if this works!
I've visited the site and successfully interacted with the checkboxes in the dropdown widget using this code:
/** Set XPath Variables **/
string dropdownWidgetXPath = "//span[contains(#id, 'selInd')]";
string checkboxXPath = "//input[contains(#id, 'selInd')]";
/** Navigate to the page **/
driver.Navigate().GoToUrl("http://www.jobserve.com/us/en/Job-Search/");
/** Click the dropdown widget **/
IWebElement dropdownWidgetElement = driver.FindElement(By.XPath(dropdownWidgetXPath));
dropdownWidgetElement.Click();
/** Identify all checkboxes present **/
var allCheckboxes = driver.FindElements(By.XPath(checkboxXPath));
/** Click each checkbox and wait so that results are visible **/
foreach(IWebElement checkbox in allCheckboxes)
{
checkbox.Click();
System.Threading.Thread.Sleep(500);
}
In Selenium webdriver you can do it like this :
All the check-boxes must be having some unique identifier then you can simply find it out by Id If they dont have a unique id (This is what I encountered while testing a web application) then it must be having some title and name attribute (or some other attribute).
Then you can try this :
driver = new FirefoxDriver();
driver.findElement(By.xpath("//input[#name='mycheckboxgroup' and #title='movies']")).click();
driver.findElement(By.xpath("//input[#name='mycheckboxgroup' and #title='songs']")).click();
By id of the checkbox you could use following code:
IWebElement elementToClick = driver.FindElement(By.ID(ctl00_ContentPlaceHolder1_Add_lstCategory_0));
elementToClick.Click();
If you don't know id then use below code by xpath:
String checkbox = "//input[#type='checkbox']"
IWebElement elementToClick = driver.FindElement(By.XPath(checkbox ));
elementToClick.Click();
The code in selenium is simple:
new WebDriverWait(driver, TimeSpan.FromSeconds(timeToHoldOn)).Until(ExpectedConditions.ElementExists((By.ClassName("ckb"))));
IWebElement dropdownWidgetElement = driver.FindElement(By.ClassName("ckb"));
dropdownWidgetElement.Click();
Thread.Sleep(1000);
var allCheckboxes = driver.FindElements(By.ClassName("ckb"));
foreach (IWebElement checkbox in allCheckboxes) {
checkbox.Click();
System.Threading.Thread.Sleep(250);
}
This is how I check and uncheck all my boxes, it has to have an Id or class.
Id example:
driver.FindElement(By.Id("someid")).click();
ClassName examaple:
driver.FindElement(By.ClassName("someid")).click();
Its short, its sweet and more importantly it works.
Try using this piece of code written in java
String checkboxes = "//*[#type='checkbox']";
List<WebElement> elementToClick = driver.findElements(By.xpath(checkboxes));
for (WebElement AllCheck : elementToClick) {
AllCheck.click();
}
Java, Clicking on multiple checkboxes at a time using the loop.
**Sample Xpath :**
CheckBox1 Xpath : //input[#class='mycheck' and #id='1']
CheckBox2 Xpath : //input[#class='mycheck' and #id='2']
Get all the elements checkbox using findelements:
List WebElement ele =
driver.findElements(By.xpath("//input[#class='mycheck']"));
Make the Xpath as string by leaving the ID and assign the ID as i.
for(int i=1; i<=ele.size(); i++) { driver.findElement(By.xpath("//input[#class='mycheck' and #id='" + + i + "']")).click(); }
i gets the value for every loop and the xpath matches the checkbox and click's it.
You can select each of the radio buttons/checkboxes by selecting the element which contains them and iterating through each one just like an array.
For example, here a ul element contains some radio buttons. I select the ul element first, then I can select each radio by using the correct index (inside the [])
//Select the ul containing the radio buttons I want to click/select
var ul = driver.FindElement(By.Id("ul_containing_radio_buttons"));
//use forloop to click each button in turn
for (var i = 2; i <= 0; i--)
{
var button= ul.FindElements(By.TagName("input"))[i];
//i is the index of the radio button in out ul element
button.Click();
}