How to Detect Dynamic frame in selenium webdriver? - selenium

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}

Related

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/

Not able to click or page not responding to click in phantomjs-selenium in java

I am doing project on different crawlers and trying to mimic user actions. As part of it, I am crawling this url. Here there is a zip code box and I am trying to click on it and extract text from the drop down which will appear after that. I wrote the below code but not sure why it is not working at all. Can anyone please help? I did exhaustive search to find root cause but got nothing. Any suggestions would be much much appreciated.
driver.getUrl(aboveUrl);
WebElement inputBox = driver.findElement(By.id("pincodeInputId"));
inputBox.click();
System.out.println(driver.findElement(By.className("_3mWImx")).getText());
-- This gives null;
Awaiting help !
The reason is the node that you picked is the parent node of the element that has the text
You should use
System.out.println(driver.findElement(By.css("_3mWImx span")).getText());
And that would work. Also note that there are multiple element with the class _3mWImx, so this will only give you the first one. If you are interested in all of them, then you should be using driver.findElements and looping through the result
Actually there are more than one values in the drop down if you want to print all you have to used findElements(). Use this code it will give you desired result :
WebDriver driver=new FirefoxDriver( );
driver.manage().window().maximize();
driver.get("https://www.flipkart.com/moto-e4-plus-fine-gold-32-gb/p/itmevqynuz4fwxca");
WebElement inputBox = driver.findElement(By.id("pincodeInputId"));
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
inputBox.click();
List<WebElement> elements=driver.findElements(By.className("_3mWImx"));
for(WebElement ele:elements)
{
System.out.println(ele.getText()); //It will print innertext of each element
}
Output :
From Saved Addresses
Loginto see your saved addresses

Xpaths are changing dynamically

Im currently auotmating an web application using a selenium framework.For locating the elements im using xpath. For particular drop downs(with a filter in it) in the application the xpaths are getting changed frequently(for the available options in the drop down).The options in the drop down are inside the span section. Is there are any way to handle the dynamic xpath? Currently im using firebug to get the xpaths.
You can always use XPATH text matching if you know what to expect.
//*[text()='DropdownValue']
if you have list elements in the dropdown:
//li[text()='DropdownValue']
If you could provide example of the dropdown structure or just the HTML code of your case, it would be much easier to find a suitable solution.
You could get every element inside your dropdown, get the index of the element which contains the text and then click it:
List<WebElement>elems = driver.findElements(By.xpath("xpath from every element"));
elems.get(getIndex(elems, "Abereen District")).click();
private int getIndex(List<WebElement>elems, String elemText) {
for(int i = 0; i < elems.size(); i++)
{
if(elems.get(i).getText().contains(elemText))
return i;
}
return -1;
}

Element is no longer attached to the DOM - for a Button

Issue - Getting 'Element is no longer attached to the DOM'
Approach -
1. Check if the element is displayed on the webpage
2. Trying to click the element
Code -
System.out.println("boolean value of Confirm order is" +driver.findElement(By.id("confirmOrder")).isDisplayed());
if (driver.findElement(By.id("confirmOrder")).isDisplayed() == true) { driver.findElement(By.id("confirmOrder")).click();
//driver.findElement(By.id("confirmOrder")).sendKeys("{Enter}");
//actions.moveToElement(driver.findElement(By.id("confirmOrder"))).build().perform();
//actions.click().perform();
System.out.println("button clicked");
}
Output
boolean value of Confirm order istrue
button clicked
Tried couple of approaches but none seems to be working. Any help is appreciated.
I think you are not using implicit or explicit waits, refer this for more info,a very neat explanation is provided on this issue...
On Windows 7, certain web elements such as button doesn’t gets clicked using the below line of code:-
driver.findElement(By.id("ButtonID")).click();
Tried using XPath as well but that didn’t used to work always.
Following is the thread that list down the issue with Windows 7: https://code.google.com/p/selenium/issues/detail?id=6112
This is the workaround:-
WebElement element = driver.findElement(By.id("ButtonID"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);

How to select a frame using 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'))