Can we Traverse on another page when executing foreach loop? - selenium

There is Table on the page, I do need to retrieve information row by row. That is handle by for-each. Execution on same page for retrieving information is working fine.
But, Can we handle Detail page of particular Row ? Here "Test 1" has its own detail page. There are some operation which need to handle on detail page. How can we manage it and get back to actual execution.
As of now I am dealing it with for-each loop, and getting StaleElementReferenceException which is correct as webElement lost its actual ListElement<WebElement>
List<WebElement> findList = driver.findElements(By.xpath("//a[#class='*****']));
for (WebElement webElement : findList) {
...
//detail page is access by clicking webElement
webElement.click();
findList = driver.findElements(By.xpath("//a[#class='*****']));
}
If there is any way, Please suggest. Thanks.

You can do something like this :
List<WebElement> findList = driver.findElements(By.xpath("//a[#class='*****']));
for(int i = 1 ; i<=findList.size() ; i++){
driver.findElement(By.xpath("(//a[#class='***'])[" + i + "]")).click();
// extract some data from next page which is invoked by clicking on Test1 hyperlink.
}
in this way every time you are looking for //a[#class='***'][i] web element i , starting from 1 and till the end point.
P.S : You need to check this in devtool //a[#class='***'][1], whether it indicates the Test1 hyperlink or not.
Hope this helps.

Try to collect urls to detail pages of all and then open them.

There are two scenarios i can think of :
Clicking the link e.g. Test1 opens a new tab :
In this case you can just switch to new tab inside your loop , finish your operation on this tab and finally close the second tab / switch to first tab before continuing with your next iteartion. This should also not cause StaleElementException.
Clicking the link e.g. Test1 redirects to some other url in same tab :
For each iteration of loop, click on target link , perform some operation on new page.Before you continue with next iteration , Navigate to page containing your table again and lookup all the row elements again. Now , for next iteration you won't get StaleElementException. You will want to use the for loop so that you can maintain the index outside instead of a foreach variant.
findList = driver.findElements(By.xpath("//a[#class='*****']))
I would recommend the first option since that would be more clean and you can perform a shift + click on your link e.g. Test1 to force it open in a new tab instead of redirecting in same page. You can perform a shift + click using "Actions api" available in Selenium.

Related

Tosca: How to scan Dropdown textbox which disapper upon opening xScan

I have a problem in scanning a drop-down menu which disappears upon opening the xScan. I need to get the module id of the dropdown menu to verify some test steps.
Do you have any solution with this if it is not really possible to get the module id of the dropdown menu?
Open developer tools in your browser of choice (F12), navigate to the console and input the following code:
var fulldoc='';
var scrollX=0;
var scrollY=0;
document.addEventListener("keydown",function(event){
if(event.key=='q' && event.altKey){
fulldoc=document.body.outerHTML;
scrollY=window.pageYOffset;
scrollX=window.pageXOffset;
}
if(event.key=='w' && event.altKey){
document.body.outerHTML=fulldoc;
document.body.scrollTo(scrollX,scrollY);
}
});
When the window looks the way you would want to scan, press 'Alt + Q', then press 'Alt + W'.
Now your window will freeze and then you can scan your page.
To steer the objects you need to refresh your browser.
You can resolve the issue with below 2 steps
1 - Add some text in textbox which will populate the dropdown below it .
2 - Use Send Keys Module to scroll down and select the value.
I had a similar issue where we had a popup that only appeared when clicking on a text box. The solution we received from the Tricentis trainer was as follows:
Part One
1. Open your application in Chrome
2. Right click the inspect
3. In the inspector window, on the Elements tab, navigate to your html element where it should be (you can do that by clicking on the element and check that you can see the html in the element)
4. Use the debugger to add a break point there, this should pause it and you should be able to see the elements you need to steer it.
5. Once you found the element, you will need the type of element (e.g. div, span, etc), and the class name
Part two
1. Rescan your module and select any element that matches the criteria of your element selected in Part One #5
2. Identify it by only it's class name property and tag
3. Save and close
4. Edit the element in the module view by changing the class name. This should help you steer it
Note: if the element class name is not unique, you might need to use Explicit name.
Good luck

Having issue in selecting drop down element under makemytrip website

Having issue in selecting drop down element under the following website
http://flights.makemytrip.com/makemytrip/fareCal.do?intid=NewHP_to_DF_FC_Menu
I'm unable to select any one of the cities listed below.
Please help me out resolving the same.
Scenarios Tried
driver.findElement(By.className("chzn-single")).click();
driver.findElement(By.xpath("//span[contains,'NewDelhi']")).click();
driver.findElement(By.xpath("//span[#id='fromcity_chzn']")).click();
This works:
WebElement leavingFrom = driver.findElement(By.xpath("//*[#id='fromcity_chzn']/a"));
WebElement goingTo = driver.findElement(By.xpath("//*[#id='tocity_chzn']/a"));
leavingFrom.click();
leavingFrom.sendKeys("Bangalore");
leavingFrom.sendKeys(Keys.RETURN);
goingTo.click();
goingTo.sendKeys("Goa");
goingTo.sendKeys(Keys.RETURN);
Here is working sample:
//First get main dropDowns
var leavingFromDropDown = driver.FindElement(By.Css("#fromcity_chzn"));
var goingToDropDown = driver.FindElement(By.Css("#tocity_chzn"));
//Select value from first dropDown using dropDown items index
//First click on dropDown to open it
leavingFromDropDown.click();
//Now find items in it and click on any item using it's index (also can be used method to access this elements using their names
leavingFromDropDown.FindElements(By.Css(".active-result"))[1].click();
//this dropDown closes automatically, but if not you need to click on it again to close
//Same perform with second element
goingToDropDown.click();
goingToDropDown.FindElements(By.Css(".active-result"))[2].click();
If you want to use input box to enter any value from DropDown you need to find that element and using sendKeys set it's value. E.g.:
leavingFromDropDown.click();
var input = leavingFromDropDown.FindElement(By.Css(".chzn-search > input"));
input.sendKeys('Goa');
input.sendKeys(Keys.Enter);//or tab

How to Handle the multiple DropDowns in selenium(Country/State/City) --Selenium WebDriver Data Driven Frame Work

I have written a selenium data driven code, which will fetch data from the excel file and will ,fill up in the web page.
the Webpage contains
drop downs for Country ,State and City,
Text Field 1 and Text Field 2
Add/update Button and Clear Button
Steps
1-select country,state,city ,enter text field 1 and Add/Update button.
Issue
When I perform above action, when Add/update is clicked ,I want page to wait until again starting the loop ,so that the country drop downs resets again.
as of now it is not waiting and causing even a new country is selected the state drop-down shows previously selected country's provinces.Example(If I select India and provinces for the 1st record, than next time for United states the "State-drop down" displays ,Indian States but not the United States"
I tried using wait until technique even the driver.manage().timeouts().implicitlyWait(20, TimeUnit.MILLISECONDS), even thread.currentthread.sleep
but none of them are consistent as after some records I am getting error as element not found because of the above mentioned issue.
I want post Add/update button is clicked the driver to wait till it again resets the page with default value of the country set Secondly when I pass a value for the country the driver again to wait so that it can load it corresponding States .
I hope this could be handled in this way:
Step 1: Write small method where in you send a Webelement and the desired value that you need to select.
Step 2: In that method, before selecting a value from drop down, read the value from it and check for the desired value you looking for.
Step 3: If you don't find the desired value then wait for say 'x' seconds and then loop it again for desired value that you are looking for.
Step 4: Once you get desired value, select it and exit the loop.
By this above method, you can handle as many combo boxes as you like.
For reference: how to read values from combo box
In my opinion you should use some intelligent wait condition here so that it waits until the element gets activated or enabled.
Select any value from first drop down
Wait until page to be loaded completely
Wait until second drop down gets activated
Select any value from second drop down
Wait until page to be loaded completely
Wait until second drop down gets activated
If above solution doesn't work then go for 'refresh', code should be able to refresh the page before selecting any value from first drop down.
// Code to wait until page get completely loaded
public void waitUntilPageIsLoaded() {
ExpectedCondition<Boolean> condition = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
};
WebDriverWait wait = new WebDriverWait(driver, timeout);
wait.until(condition);
}

How to check all the links dynamically?

The following thing I have to do using VBScript in QTP 10/11:
The VBScript opens one login page. After the login it counts the number of links in that page and then prints all the links. Afterwards it opens every link one by one.
I am having issues with finding all the dynamic links.
You can get all the links on a page by using the Page's (or Frame's) ChildObject method.
Set desc = Description.Create()
desc("html tag").Value = "a"
Set links = Browser("B").Page("P").ChildObjects(desc)
For i = 0 to links.Count - 1
Print links(i).GetRoProperty("inner_text") & " => " & links(i).GetRoProperty("href")
Next
As for clicking them, that's a bit more complicated since after clicking a link you cause a navigation that invalidates the links object, you should either perform the ChildObjects each time (while keeping track of the index) or open the links in a different browser/tab.

How to manipulate user selected text using webdriver?

Lets say i have the following snippet in my web page:
<p> This is some text </p>
I want WebDriver to select "some" in this text, as if the user selected it. How should i do this? I know how to get the <p>-element:
WebElement editable = getDriver().findElement(By.id("someId"));
editable = editable.findElement(By.tagName("p"));
System.out.println(p.getText());
The println prints "This is some text".
I tried sending keys to the element, and that used to work(in selenium 2.0b), but i'm using selenium 2.6.0 now, and it stopped working:
editable.sendKeys(Keys.chord(Keys.SHIFT, Keys.LEFT));
Does anyone have ideas? I'm using the FirefoxDriver.
I did this once for Firefox using Javascript. Basically I used the range object in Firefox to select the text. Change the start and end range index based on what you want to select. This would not work in IE, because selecting range is conceptually different in IE. I don't have the IE code handy but since you are concerned about FF, you could give this a shot.
Let me know if you interested in IE text range.
String script = "var range = document.createRange();" +
"var start = document.getElementById('idofthedivthatcontainstext');" +
"var textNode = start.getElementsByTagName('p')[0].firstChild;" +
"range.setStart(textNode, 8);" +
"range.setEnd(textNode, 13);" +
"window.getSelection().addRange(range);";
((JavascriptExecutor)driver).executeScript(script);
You are trying to select the contents of the p tag by drag select right I am not sure if that is objectively possible to be done by the user as your are suggesting.. Selenium now tries to mock the exact action that a user can perform on a browser. thus you just cant send a shift and left select key on the p tag and expect it to select unlike a textbox where it is very much possible but you might probably have to click on the text box first to get it into focus.
Here is what I would suggest to achieve this, not sure if it will work.
a) send the left click on the p tag
b) hold the shift key
c) drag the mouse to the end of the p tag.
Hope that helps.
Use the .Text property of the IWebElement
WebElement editable = getDriver().findElement(By.id("someId"));
editable = editable.findElement(By.tagName("p").Text).ToString();
editable.Replace("This is ", "").Replace(" text.");
System.out.println(p.getText());