How to select a frame using selenium? - selenium

I'm using Java to create selenium test cases. My system is based on portlets connected to each other. I'm using "selectFrame" command to select the portlet.
I tried many things but it seems it is not working like this:
driver.switchTo().frame("//iframe[contains(#src,'FUN_UnitList_FilterByLevelIndexOne')]");
driver.findElement(By.id("//iframe[contains(#src,'FUN_UnitList_FilterByLevelIndexOne')]"));
Can anyone help me?

You have an XPath expression that is supposed to get you the IFrame element you need. However you are not telling Selenium it's an XPath expression. The below is what you need:
driver.switchTo().frame(driver.findElement(By.xpath("//iframe[contains(#src,'FUN_UnitList_FilterByLevelIndexOne')]"));
Note, my Java is not it's best, so this may cause compilation issues but you should see the idea.
Find the element first, by telling Selenium it's an XPath expression you are giving it, then use that element and stick it right in the 'switch to frame' expression.

driver.switchTo().defaultContent();
driver.switchTo().frame(driver.findElement(By.xpath("//iframe[contains(#src,'FUN_UnitList_FilterByLevelIndexOne')]")));

We can give frame name, id, index and WebElement locator for identification
Syntax:-
driver.switchTo().frames(); // Switch to window to frame
driver.switchTo().defaultContent(); // Switch to Frame to window
If we know the total number of frames on the web page, then we can use “ index”.
Index values help to easily switch between frames.
An index will start from Zero i.e.
if a web page has only one frame then its index will be Zero.
If we don’t know the number of frames we can use “findElementBytabname()” method
Syntax: -
try
{
driver.switchTo().frame(indexnumber);
}
catch(NoSuchFrameException e)
{
System.out.println(e.getMessage());
}
We have use try and catch if now frame will not available this throw exception NoSuchFrameException()
Use name as locater to find frame
Syntax: -
try
{
driver.switchTo().frame(“frameName”);
}
catch(NoSuchFrameException e)
{
System.out.println(e.getMessage());
}
Use WebElement for switching frame
Syntax: -
try
{
WebElement button=driver.findElement(By.xpath(""));
driver.switchTo().frame(button);
}
catch (NoSuchFrameException e)
{
System.out.println(e.getMessage());
}

You can switch to a frame, using its name or id easily:
driver.switchTo().frame("frame_name");
When you have selected a frame to switch to another frame you have to switch to the parent or root first with something like:
driver.switchTo().defaultContent();
driver.switchTo().frame("other_frame_name");

I was able to select an "src" frame with no name or ID using this method & Python Selenium. I found the xpath of the element, and did this code to get selenium to select the frame properly (using Python 2.7):
driver.switch_to.frame(driver.find_element_by_xpath('//*[#id="Detail-innerCT"]/iframe'))

Related

MoveTargetOutOfBoundsException exception is thrown while using move to element even when element is in view port

I am using a method to hover on an element and the select a value from dropdown which appears after hovering. the same element and same method is used in two different test cases. This works perfectly fine in one test case and throws exception in another test case.
i tried using scrolling to the element using javascript, also tried separating the actions, but it did not work.
WebElement bpardingPointFilterNew= driver.findElement(By.cssSelector("#bpliner"));
action.moveToElement(bpardingPointFilterNew).click(bpardingPointFilterNew).perform();
// js.executeScript("arguments[0].click();",bpardingPointFilterNew);
// action.click(bpardingPointFilterNew).perform();
// bpardingPointFilterNew.click();
return this;
}

Unable to recognize Element with relative xpath or other locator

I am facing an issue where I am unable to locate Element on webpage with any type of locator expect Absolute xpath. Here are details:
URL : https://semantic-ui.com/modules/dropdown.html#selection
Required Element Screen shot:
Manually created Xpath Screen shot( Please note that I am able to recognize Element in web application with manually created xpath but Same xpath is not working in selenium code)
But Same xpath is not working in selenium script.
PLEASE NOTE THAT I AM ABLE TO IDENTIFY SAME OBJECT WITH Absolute xpath
Please help to me to understand reason for this.
Here is code:
public static WebDriver driver;
public static void main(String[] args) {
driver= new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://semantic-ui.com/modules/dropdown.html");
//Selection
driver.findElement(By.xpath("//div[#class='ui selection dropdown upward']")).click();
driver.findElement(By.xpath("//div[#class='menu transition visible']/div[text()='Female']")).click();
System.out.println("Done");
This may be issue with your first x-path. You may try the following code. It may work.
driver.findElement(By.xpath("//div[#class='ui selection dropdown']").click();
driver.findElement(By.xpath("//div[#class='menu transition visible']/div[text()='Male']").click();
You are missing a preceding wildcard in you driver.FindElement XPath.
Instead of driver.findElement(By.xpath("//div..."));, do driver.findElement(By.xpath("//*div..."));.
Currently, what your code is doing is telling the XPath locator to find a first level div (not easily possible, as the first item is almost always the document body), but the wildcard of "*" tells it that it can look for the div at any level.
As an aside, please edit your answer up top with actual code instead of pictures so others with the same problem can find their solution easier.
Longshot:
You are using Chrome to look at the source, but Selenium is using Firefox.
There is a chance that the source is rendered differently between the two browsers. Specifically, your xpath is relying on an exact match of class. I do know that FireFox is notorious for modifying source output.
I haven't done any testing but I would not be surprised if the class is in a different order and it's failing on an exact match.
There are two solutions if that is the case:
Don't do a single exact match (xpath = "") but instead do a mix of contains joined with && (contains ui && contains selection && dropdown)
Don't rely on the output from the console tab. Instead "View Page Source" and view what is actually being sent instead of what is being interpreted by the browser
Find the dropdown container element firstly, then use it to find self descendant, like option etc.
driver.get("https://semantic-ui.com/modules/dropdown.html");
// find dropdown container element
WebElement dropdownWrapper = driver.findElement(
By.xpath("//div[#class='html']/div[input[#name='gender']]"));
// expand drop down options by click on the container element
dropdownWrapper.click();
// or click the down arrow
dropdownWrapper.findElement(By.css('i')).click();
// select option
dropdownWrapper.findElement(By.xpath(".//div[text()='Female']")).click();
To locate the element with text as Gender and select the option Female you can use the following Locator Strategy :
Code Block :
System.setProperty("webdriver.chrome.driver", "C:\\path\\to\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://semantic-ui.com/modules/dropdown.html#selection");
driver.findElement(By.xpath("//div[#class='another dropdown example']//div[#class='ui dropdown selection']")).click();
driver.findElement(By.xpath("//div[#class='another dropdown example']//div[#class='ui dropdown selection active visible']//div[#class='menu transition visible']//div[#class='item' and contains(.,'Female')]")).click();
System.out.println("Gender Female selected.");
Console Output :
Gender Female selected.
This might be helpful to clearify how selectors are working in general:
.(dot): Dot at starting represents the current node. It tells us that the processing will start from the current node.
. .(double dot): It will select parent of current node. For example, //table/. . will return div element because div is the parent of table element.
‘*’: is used to select all the element nodes descending from the current node. For example:
/table/*: It will select all child elements of a table element.
//*: It will select all elements in the document.
//*[#id = ‘username’]: It will select any element in document which has an attribute named “id” with the specified value “username”.
#: It represents an attribute which selects id, name, className, etc. For example:
#id: It will select all elements that are defined with the id attribute in the document. No matter where it is defined in the document.
//img/#alt: It will select all the img elements that are defined with the #alt attribute.
//td[#*]: It will select all td elements with any attribute.
Here is a link to the article:
https://www.scientecheasy.com/2020/07/selenium-xpath-example.html/

Selenium Web driver - loop over elements and click if matches

i'm in day 2 of my selenium class, need help in finding an efficient way of looping over elements and if matches click the link address.
I want to navigate from classFrame to navList and loop over to find the match and click.
public void switchFrames() {
driver.navigate().to("https://seleniumhq.github.io/selenium/docs/api/java/");
driver.switchTo().frame("classFrame");
/* List<WebElement> elements = driver.findElements(By.className("navList"));
for (WebElement element : elements) {
System.out.println(element.findElement(By.xpath(".//li/a")).getText());
}
*/
List<WebElement> items = driver.findElements(By.cssSelector("ul li"));
if ( items.size() > 0 ) {
for ( WebElement we: items ) {
we.findElement(By.linkText("Deprecated")).click();
}
}
driver.findElement(By.linkText("Deprecated")).click();
driver.close();
}
The main part you are missing and the reason you can't find the element you are looking for is because it's in a frame. In order to access elements in a frame with Selenium, you need to switch the driver context to the frame. You do that using driver.switchTo().frame(). Once you are done interacting with the frame, switch back to the default context using driver.switchTo().defaultContent().
Having said that... let me offer you some more advice since you are just starting out. There are several ways to do this. One way is like what you attempted... grab an element, find a child, loop through those children looking for the link you want. I prefer the more direct approach since we can search for the exact link using an XPath. What you want to do is to click the DEPRECATED link on the navbar. You could just use the By.linkText() locator and that will work but you want to be careful, especially with a page like this that has so many links, to not click on a link you didn't intend to. The way you do that is to narrow the search to the specific area you expect the link to be in, the navbar. Once you narrow the search there, you can quickly and safely find the link you are looking for. I prefer to do it in a single search using an XPath but you could use say a CSS selector to find the navbar area and then use By.linkText() to find the link, e.g.
driver.findElement(By.cssSelector("ul[title='Navigation']").findElement(By.linkText("Deprecated").click();
In that case, you will be scraping the page twice. It's not likely a big performance hit, I just prefer to use a single locator when it makes sense. I would suggest that since you are likely to use this code over and over that you put it in a function and pass it the link name, e.g.
public void clickNavbar(String linkName)
{
driver.switchTo().frame(driver.findElement(By.cssSelector("frame[name='classFrame']")));
driver.findElement(By.xpath("//ul[#title='Navigation']//a[.='" + linkName + "']")).click();
driver.switchTo().defaultContent();
}
Then you can call it like, clickNavbar("Deprecated");

Not able to locate a class in Selenium

I want to locate a drop down arrow using this line of code:
driver.findElement(By.className("icon-caret-down")).click();
There is nothing wrong with the code but the same class name is used for another drop down arrow which resides before it. My script points to that drop down arrow in spite me wanting it to point to this one.
I cannot use id or xpath as these are dynamically changed
Xpaths can be used if if the elements change dynamically but if you left with no other options, below snippet should help
List<WebElement> commonElem=driver.findElements(By.className("icon-caret-down"));
for(i=0;i<commonElem.size();i++){
if(i=1){ //instead you can also use commonElem.getText()=="TextVal";
commonElem.click();
break;
}
}

How to Detect Dynamic frame in selenium webdriver?

I am trying to detect frame with dynamic target in selenium webdriver.
In selenium IDE i am getting details of frame like command "selectframe", Target="CitrixMainFrameWI_hghjghjhj355", In the target dropdown no other value is present ,
I tried to detect this frame using command
driver.switchto().frame("CitrixMainFrameWI_hghjghjhj355"). But this target value is dynamically generated so i got error .
Can you please suggest me any solution for this
Try it with frame(index) or by naming the frames and only searching for CitrixMainFrame
(contains("CitrixMainFrame").
More Details in this link:
http://joychester.blogspot.com/2010/09/switch-frame-and-windows-sample-code.html
Use this :
// First find the frame.
WebElement element = driver.findElement(By.cssSelector("div[id^= 'CitrixMainFrameWI_']"));
// id^ means the id starts with the given value.
// You din't specify the tags, so i assumed as div tag. change it according to your code.
driver.switchto().frame(element);
String expectedFrameID="abc";
List<WebElement> lst=d.findElements(By.tagName("iframe"));
System.out.println(lst.size());
int flag=0;
for(int i=0;i<lst.size();i++){
String actualFrameID=lst.get(i).getAttribute("id");
System.out.println(lst.get(i).getAttribute("id"));
if(expectedFrameID.equals(actualFrameID)){
flag=1;
break;
}
}
if(flag==1){//perform operation on frame}