I am automating a webpage using selenium.
My Problem is selenium is unable to type the text in hidden fields. I used
selenium.type("xpath of hidden field","some text");
But it is not working. It's not giving any error, but not typing anything into that hidden field.
Example: Typing text into Gmail's body field(in composing mail). this is the exact example of my issue
This is Rad Editor. So code is something like this(here the text is saving inside iframe-->html-->body)
<iframe id="iframe1">
<html>
<body> This is some text </body>
</html>
</iframe>
There's just no way you'll force Selenium to type into a hidden element.
Would this work? It uses Javascript's document.evaluate() to find the element by XPath and then types directly into the found element's value.
selenium.GetEval(
"var xpath = '//XPath/to/your/element';" +
"var text = 'some text to input into the element'" +
"var elem = window.document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);" +
"elem.singleNodeValue.value = text;" );
If not, try to run it in FireBug and post the result (or error) here.
The next thing to try would be to try to make the element visible...
EDIT - the above won't work
You have like all the problems in one place :)
An iframe. You must select it before trying to interact with anything inside.
If the iframe loads anything from a different domain, then the Same origin policy for JavaScript kicks in. And since Selenium RC is written in pure JavaScript, it can't do anything. You can either switch to WebDriver which doesn't suffer from this, or try to reopen the browser on the internal address of the iframe. Might not work, though.
The body tag in the iframe is contenteditable which is a problem solved by WebDriver. Selenium RC should be able to type() into it just as well.
An invisible textarea. That's your last problem. If you really needed to write into it (there's the editable body), you you'll have to use JavaScript, because Selenium RC refuses to work with invisible elements.
As this is a RadEditor the text is going inside iframe-->html-->body (This is in my case. It may be different for different Editors)
So in order to write text, first we need to select the iframe. And then we have to enter the text. This can be done as
selenium.SelectFrame("xpath_of_iframe"); //Selecting the iframe
selenium.Type("//html/body","Thank you"); //Inserting the text
So now the code changes to
<iframe id="iframe1">
<html>
<body> Thank you </body>
</html>
</iframe>
Thank you.
Related
I am trying to automate Salesforce application Using Selenium and getting NoSuchelementException though XPATH is correct and valid for particular object. When i have searched the issue, it might be reason for Shadow DOM.
For EX:
So XAPTH i have written like,
driver.findElement(By.xpath("//input[#name='Name']")).sendKeys("Jams");
or
driver.findElement(By.xpath("//input[#id='input-299']")).sendKeys("Jams");
This XPATH is highlighting in Console as well. But while automating it throws nosuchelement error.
So while checking for ShadowDOM option, am getting option like this for Name Object.
#shadow-root(user-agent)
Shadowroot DIV
-- nothing mentioned in div. it just open and closed tags.
How to automate this?
You can check if there are any iframes in your Dom. Simply do //iframe in your page developer mode(F12)> elements tab > search (Ctrf+F) area. If there are any, you will get the number of iframes.
Now if your textbox is in any of iframe use below code to go inside particular iframe first
driver.switch_to.frame("<name or Id of frame>")
then come out to frame use below:
driver.switch_to.parent_frame()
Also, if the issue is not related to frames check below for shadow-root related issue:
you can check below for shadow-root element ( Question is for Java, but you can co-relate):
How to interact with the elements within #shadow-root (open) while Clearing Browsing Data of Chrome Browser using cssSelector
The website contents are mostly created now using javascript. You may have to wait for certain elements to load before doing anything to it.
https://seleniumbyexamples.github.io/wait
For the portal I am testing now, I came with the problem that I could not create any xpath locators, after some time I figured out that it was because of an '#document', this cuts the path and makes the simple "copy xpath" to direct the path to a completely different element.
<iframe id="FRAMENAME" src="/webclient/workspace/launch-task/REMbl?ds=BP" width="100%" height="100%" frameborder="0" data-navitemname="navitemname" style="" xpath="1">
#document
<html>
CODE....
</html>
I found the solution for this is it is simply add a switchTo like this:
driver.switchTo().frame("FRAMENAME");
This works and makes the rest of the code to work properly but, takes some extra time processing this command till the code moves to the next line.
So I would like to ask, is there is a better solution for this? something smarter/faster?
I am concerned that when the point where I have lots of scripts comes, the execution time will take too long.
I don't use id locators for example because they are all dynamic so sometimes a xpath is required.
Thank you!
To work with elements inside iframe you must switch to this specific iframe.
Your solution .switchTo().frame("FRAMENAME"); is correct. Selenium does not have any other ways to work with iframe wrappers.
inline frames
As per the documentation in Using inline frames, an inline frame is a construct which embeds a document into an HTML document so that embedded data is displayed inside a subwindow of the browser's window. This does not mean full inclusion and the two documents are independent, and both them are treated as complete documents, instead of treating one as part of the other.
iframe structure and details
Generally, an iframe element is in the form of:
<iframe src="URL" more attributes>
alternative content for browsers which do not
support iframe
</iframe>
Browsers which support iframe display the document referred to by the URL in a subwindow, typically with vertical and/or horizontal scroll bars. Such browsers ignore the content of the iframe element (i.e. everything between the start tag <iframe...> and the end tag </iframe>). Browsers which do not support iframe (or have such support disabled) does the opposite, i.e. process the content as if the <iframe...> and </iframe> tags were not there. Thus, the content matters, despite being ignored by some browsers.
So to summarize, inline frames do not mean an include feature, although it might sometimes serve similar purposes.
Note that, when inline frames are used, the browser (if it supports them) sends a request to the server referred to by the URL in the iframe element, and after getting the requested document displays it inside an inline frame. In this sense inline frames are a joint browser-server issue, but only the browser needs to be specifically iframe-aware; from the server's point of view, there's just a normal HTTP request for a document, and it sends the document without having (or needing) any idea on what the browser is going to do with it.
Something Smarter
As per the best practices while switching to an iframe you need to induce WebDriverWait as follows:
Switch through Frame Name (Java Sample Code):
new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.name("frame_name")));
Switch through iframe XPath (Python Sample Code):
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='ptifrmtgtframe' and #name='TargetContent']")))
Switch through iframe CssSelector (C# Sample Code):
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe#twitter-widget-0")));
Reference
You can find a couple of relevant discussions in:
Python: How can I select a html element no matter what frame it is in in selenium?
Java: Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?
C#: How to wait for a frame to load before locating an element?
tl; dr
Inline frames vs. normal frames
What command in webdriver should I use to make sure it clicks the specific text i.e Last Month
the code is
<div class="dt_padded_medium_div">
<a onclick="setLastMonth()" href="#">Last Month</a>
I tried xpath by using firepath but still doesnt work
it was
//*[#id='block-2']/div/div[3]/table/tbody/tr[1]/td[5]
I used
driver.findElement(By.xpath("//*[#id='block-2']/div/div[3]/table/tbody/tr[1]/td[5]")).click();
but still didnt work, am I missing something?
Update:
Got the Code working guys, thanks for the help!
If there is only one 'a' element in the page with this text, try this XPath:
//a[text()='Last Month']
If there are more than one element, please, post the full HTML tree else we're unable to write a xpath without know the tag path and ensure it will work
Are you sure your xPath is correct?
Install FirePath on Firefox and experiment with your xPath as on screenshot below.
Also, that does look like a long and brittle xPath. Look up xPath cheat sheets to learn how to make your xPath more robust.
In your case I would imagine something like:
//*[#id='block-2']/descendant::a[text()='Last Month']
(get the element with a particular ID, then search for an <a></a> in that element, no matter how deep, with a particular text)
In your question, you have used a "id" that is not shown in your code, where is #id='block-2'. It is possible for you to have used the wrong id. For us to help you, can you please provide the whole HTML code?
What I can suggest based on the information you have provided is:
Making sure the Xpath you have provided is unique, there is an add-on for Firefox called Firebug you can use. It will help you find out the xpath you are after fast and easy. What you need to do is basically:
download firefox and install it;
download firebug add-on and install it to firefox;
you will notice there is a small bug symbol to the top right of your tool bar, please enable it;
you will see a console pops out, click on inspection button and click on any web element you want to inspect and its html code will be highlighted in the console;
right click on the highlighted code and choose to copy its xpath to clipboard. This way you will never get your xpath wrong.
Here is a quick tutorial:
http://www.wikihow.com/Find-XPath-Using-Firebug
P.S. There are more than one way to locate a webelement, please consider using the following options as well:
Css selector
class name
id
This link will direct you to an awesome cheat cheet.
http://scraping.pro/res/xpath-cheat/xpath_css_dom_recipes.pdf
Hope it helps.
Please try to use below code to click on the text Last Month
driver.findElement(By.xpath(".//a[text()='Last Month']")).click();
Hope this helps.
You can use below code to click on the link containing the text 'Last Month'
driver.findElement(By.linkText("Last Month")).click();
First of all make sure that your xpath works correctly, try to use more specific xpath other than just td[5] or smthn like that, for example above could be like:
//div[#class='dt_padded_medium_div']/a[#href] - meaning, we need to find <div> element with specific parent and within it <a> element that has href property
There are a few possibilities.
If you're site doesn´t get rewritten to much you could just go for the link name via
driver.findElement(By.linkName("Last Month");
You could also go for any of the attributes if your site is subject of many rewrites like this and just put "href" and "#" or "onclick" and "setLastMonth()" as arguments when calling it.
static WebElement getLink(String Attribute, String Value /*String ItemText*/){
List<WebElement> Elements = driver.findElements(By.tagName("a"));
for(int Counter = 0, Counter < Elements.size(); Counter++){
if(Elements.get(Counter).getAttribute(Attribute).contains(Value) /* && Elements.get(Counter).getText().equals(ItemText){
return Elements.get(Counter);
}
}
return null;
}
If you remove the comments it will go completely sure and check for the Attributes and the displayed text.
I'm working in selenium with Firefox browser.
The Html code shown in View Source (CTRL+U) is different from the html code i see when inspecting the elements in Firefox.
When i run the driver.getPageSource() i only get the View source (CTRL + U) codes.
Is there is any way to access the Inspect element code instead of View source code?
I think your question is answered here.
The View Source html is what is sent by the server. I think of it as compile time html, or the initial state of the DOM.
The Inspect Element html could have been updated by ajax responses or javascript so will not necessarily be the same. I think of it as runtime html, or the current state of the DOM.
The GetAttribute() method queries the current DOM element state. You can return a particular html attribute value directly
webElement.GetAttribute("class")
or get the whole html string.
webElement.GetAttribute("innerHTML")
There are some fundamental difference between the markup shown through View Source i.e. using ctrl + U and the markup shown through Inspector i.e. using ctrl + shift + I.
Both the methods are two different browser features which allows users to look at the HTML of the webpage. However, the main difference is the View Source shows the HTML that was delivered from the web server (application server) to the browser. Where as, Inspect element is a Developer Tool e.g. Chrome DevTools to look at the state of the DOM Tree after the browser has applied its error correction and after any Javascript have manipulated the DOM. Some of those activities may include:
HTML error correction by the browser
HTML normalization by the browser
DOM manipulation by Javascript
In short, using View Source you will observe the Javascript but not the HTML. The HTML errors may get corrected in the Inspect Elements tool. As an example:
With in View Source you may observe:
<h1>The title</h2>
Whereas through Inspect Element that would have corrected as:
<h1>The title</h1>
getPageSource() always returns the markup obtained through View Source.
I have an html page that has a small piece of JavaScript that further embeds an HTML form in a div tag (this div is identified by an ID).
I want to use Selenium IDE to test the form. I recorded a basic test to test the embedded form but Selenium seems to be failing. It cannot find the elements or the text.
I got the source of the parent html page but it does not have any Form html. Firefox allows you to see the Form html by going to 'This Frame->View Source'. The embedded html is whole html page not just the form - I mean it starts and ends with <html> tag
I was wondering how could I test the embedded form using Selenium IDE ? I searched a lot and found 'SelectFrame' but all the examples on the web include Java code (that I do not wish to get into) as opposed to plain HTML (I would like my test to be plain HTML Selenium test cases and would like to keep it simple).
Also, I doubt if 'SelectFrame' is going to help as the form gets embedded in a 'Div' tag and not in the frame.
Any help is greatly appreciated.
Thanks
you have a frame and frame have some name, please use this and let me know
selectFrame | frame name |
verifytext | text
selectWindow | null - this for release the frame
please show me once your script so that I will help you futher
use
driver.switchTo().frame("marco");
replace "marco" with your own frame name