How do I dump entire dom structure using selenium webdriver - javascript

I am new at selenium and python, and I am having problems finding the best way to identify the page elements I need for my automation.
I have a webpage with a lot of javascript on it. When I use firefox's inspect element for the username field in the login form, I see an input tag with an id, but when I ask selenium to find that id it says it can't be found.
I want to double-check that what I saw in firefox is actually what selenium is seeing, so I tried:
with open("login.html","w") s f:
f.write(driver.page_source)
I see no input elements at all in the resulting file.
Based on another stackoverflow question I tried:
DOM=driver.execute_script("return document.documentElement.outerHTML")
with open("login.html","w") as f:
f.write(DOM)
Still no input elements.
Is there a better way to see all the dom elements and/or find the correct xpath/ids to sue for my selenium script ?

Try get all body HTML by document.body.innerHTM
html = driver.execute_script("return document.body.innerHTML;")
with open("login.html","w") as f:
f.write(html)

#yong, your suggestion of adding a long sleep before the execute_script was the right answer. Now I can see the entire html source in the file I created.
In addition now my PageObject code works to fill in the login form and submit it. I do another sleep and then print the pageurl and title to make sure I have moved on to the next page.
Final code:
driver = webdriver..Firefox()
driver.set_page_load_time(60)
driver.get(URL)
time.sleep(60)
print("URL: "+driver.current_url)
print("Title: "driver.title)
page=LoginPage(driver)
page.username="username"
page.password="password"
page.signin_button.click()
time.sleep(60)
print("URL: "+driver.current_url)
print("Title: "+driver.title)
driver.quit()
Thank you everyone for the suggestions.

Related

Robot Framework: Click button using execute javascript

This is the web inspection
<span jsslot="">
<button class="LkLjZd ScJHi IfEcue HPiPcc KXT7c" jsaction="click:yTqzwd" jsname="HxVe9c" autofocus="">Install</button>
</span>
I want to click on this element using the keyword Execute Javascript. I try like this
Execute JavaScript document.evaluate("//button[contains(text(),'Install')]",document.body,null,9,null).singleNodeValue.click()
After run test, it is PASS but no any action on web. It's still at the same. Could you please help?
I've already found the solution. According to there are several iframe, so should be select expected iframe before execute above command like this
Select Frame xpath=//*[#id="obj"]/div[5]/iframe
Execute JavaScript document.evaluate("//button[contains(text(),'Install')]",document.body,null,9,null).singleNodeValue.click()
Robot Framework: Click Element using Execute JavaScript
Already there is a answer for your question in the above link. Just copied and pasting one of the solution here.
${element_xpath}= Replace String ${element_xpath} \" \\\"
Execute JavaScript document.evaluate("${element_xpath}", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0).click();
Also there are multiple solution in the link, try that.

How toiterate though the website search results using selenium?

I am trying to iterate though pages of search results on this website. Here is a snippet of the HTML code they have for the paging section:
Paging HTML:
Link that I want to use to go to the next page:
Next >>
I was trying to do:
next_page_link = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//a[#href='/Catalogue/search?Query=face%20mask&QueryType=All&HideMaskedProducts=False&WasCorrected=False&Page=2&PageSize=10&TotalRecordCount=932&SortDescending=False&CoreListRequest=BrowseAll'")))
next_page_link.click()
but it doesn't seem to work. When I print out next_page_link, it does return an element, so I think the code itself if alright. Is it something wrong with the link? Can I use it the way I am trying to or is there any other way I can iterate thought the result pages?
Thank you!
Your XPATH is probably causing the issue here, so the click is not going to the correct element.
Try something like this
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//a/text()[contains(.,"Next")]/parent::*'))).click()
If you want to assign it to the variable and the call the click you can also do it:
next_page_link = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//a/text()[contains(.,"Next")]/parent::*')))
next_page_link.click()

How to send text within a textarea having the attribute style="display: none;" through C# and Selenium

I need to write in the textarea with the simple sendkeys function in selenium.
This textarea (ID = 'txtSkillsTaught-Value') is followed by a script tag where the visibility of the textarea is hidden i guess due to which I am not able to write text.
tried the simple
driver.findelment(By.Id("txtSkillsTaught-Value")).sendkeys("text");
even tried switching to the iframe above but didnt worked
attached the image of HTML code
thanks,
Amey
In one hand if it is not visible maybe is not a good idea put text inside... But, in the other hand I need made things like that sometimes. I usually change the visibility for this element before send the keys with a javascript execution in my selenium code (I use java but for C# should be more or less the same):
executeScript("$('.yui-button.yui-link-button').find(\"textarea[id='txtSkillsTaught-Value']\").css({'opacity':'1', 'visibility':'visible', 'display':'block', 'position':'relative', 'transform':'none'})");
driver.findelment(By.Id("txtSkillsTaught-Value")).sendkeys("text");
That should work.
As per the HTML you have provided the <textarea> is out of the <iframe> but having the attribute style="display: none;". So to send a character sequence to the <textarea> you can use the following solution:
IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//td[#class='t-editable-area']//textarea[#class='t-content t-raw-content' and #id='txtSkillsTaught-value']")));
((IJavaScriptExecutor)driver).ExecuteScript("return arguments[0].removeAttribute('style')", element);
element.SendKeys("Amey");

How can you see which Javascript script generated a certain html line?

I have some crazy app done almost 100% by manipulating the DOM and I find myself in the unfortunate position of changing something in it. As there are probably around 100 different scripts that do God knows what, I have no clue in which file should I look to make my changes. So, I want to ask, is there a way (using Firebug maybe or something similar) to know where a specific piece of html was generated? I'm a C developer, so I'm not very good at this, it drives me crazy.
Are all the elements added at the page load, or partially in the response to the user input? (clicking etc.)
for stuff added with the response to your actions, you can use Firebug's "Break On Next" button in the "Script" tab. To active BON you have to click it, or, in just-shipped Firebug 1.10.0a8, use keyboard shortcut ALT-CTRL-B (useful when you have event listeners bound to mouse movements). Then, when any piece of JS is going to be executed in reaction to your click etc., you will hit a breakpoint.
for stuff added at page load time, you may use the trick of extending the native functions (this might sound crazy - yeah it is, don't do it in production!) like appendChild, insertBefore, replaceChild. Just insert the appropriate code at the very top of your main HTML file, so all the code below will "see" the change.
Unfortunately, this does not work in Firefox due to a bug. But works in Opera and I guess in Chrome as well.
When you extend the native function, you can inject any code before really adding the node to the page. For instance, call console.log or create a breakpoint, to inspect the current page state. You can try playing with breakpoints to see the available variables properties inside those function to adjust what you push to console.log.
For this code:
<!doctype html>
<html>
<head>
<script type="text/javascript">
// this should work in Firefox but it does not -- https://bugzilla.mozilla.org/show_bug.cgi?id=618379
// works at least in Opera, probably Chrome too
Node.prototype._appendChild = Node.prototype.appendChild;
Node.prototype.appendChild = function(child) {
console.log("appending " + child + " to " + this);
return this._appendChild(child); // call the original function with the original parameters
}
// this works in Firefox
document._createElement = document.createElement;
document.createElement = function(tagName){
console.log("creating " + tagName);
return this._createElement(tagName);
}
</script>
</head>
<body>
<script type="text/javascript">
var p = document.createElement("p");
p.appendChild( document.createTextNode("abc"));
document.body.appendChild(p);
</script>
</body>
</html>
Opera outputs:
creating p appendChild.html:14
appending [object Text] to [object HTMLParagraphElement] appendChild.html:7
appending [object HTMLParagraphElement] to [object HTMLBodyElement] appendChild.html:7
To overcome the weakness of Firefox (that you can't override appendChild), you may use the trick: place the code below instead in the top of your HTML
<script>
Node.prototype._appendChild = function(child) {
console.log("appending " + child + " to " + this);
return this.appendChild(child)
};
</script>
and then, use Fiddler proxy by creating auto-responders (WMV tutorial, 9.9 MB) where you manually replace all calls to .appendChild with ._appendChild (you can use Notepad++ for "find replace in all opened files"). Creating auto-responders and hand-tampering requests can be mundane, but it's extremely powerful. To quickly create auto-responder rule, load the page when Fiddler is active, then drag'n'drop files as in the picture below. For each file, right click and choose "Generate File" from menu (this will put a file on the desktop) or create a file by yourself in different location. (it's good to open Fiddler-generated files and remove response headers from them; BTW "Generate file" puts real contents only if the response header was 200, so make sure to load the page with CTRL-F5 to skip the cache).
In Chrome you can inspect an element and right click on it. This menu gives you some options to break when something below the element is changed or when it's own attributes change. Maybe one of those breakpoints will find what you are looking for?
Assuming you've got access to the raw (hopefully un-minified/obfuscated) JS files, maybe just search them for text strings related to DOM manipulation and/or attributes of the node you're trying to find the creation of? I'd try things like "appendChild" "createElement" and the node's ID/class names.
You could also set break points all over the script files, and step through them as the page loads to help you narrow down where to look. Might help to start by just "pausing" the JS execution and stepping through from the very beginning.
If you can share the code (a link to the live site would do fine) I'd be happy to take a look.
If you are using the jQuery framework in your javascript to make the DOM changes then you may find the fireQuery plugin for FireBug in the firefox browser may get you the information you need.
Example:
It adds additional information to the standard HTML view by superimposing additional jquery element information to the display to provide a deeper insight into how your javascript is amending the page content.
I hope that helps you out.

How to copy html source of a link to the clipboard and parse as a link in Lotus Notes?

How do you copy the html code of a link to the clipboard and parse it as a link in Lotus Notes?
For example, in Javascript put <a href='http://www.stackoverflow.com'>StackOverFlow</a> into clipboard, and then parse it as a link in Lotus Notes while writing a new email. It should only show a link as StackOverFlow in new message.
I found a function window.clipboardData.setData("Text",link), but it can only copy the text into clipboard.
Any tips for me?
#Carlos has the basic user-level way to do it but it seems you want to do this programattically. I think the most effective approach is to have an action such as "paste link" that:
accesses the clipboard
parses the text into a basic html fragment
saves that fragment to disk
imports that html into the rich text field
here's an example on how to get to the clipboard.
To import the link into notes, build a rudimentary HTML file from your action, along the lines of:
<html><body>
<a id="myLink" href="http://www.google.com">Google Site</a>
</body></html>
save it and then import it using code like:
dim ws as New NotesUIWorkspace
dim d as NotesUIDocument
set d = ws.currentDocument
call d.import( "HTML File", "c:\foo.html" )
(assuming you saved your file as "c:\foo.html").
Depending on what exactly you are trying to achieve and what you're most comfortable with, you may want to compose the HTML outside of Notes and just have the action do the import bit. If you take this approach then the need to play with the clipboard is gone.
Note the following:
the method `NotesUIDocument.Import()` injects the contents of the HTML file wherever the cursor is in the rich text (body) field. You need to have your cursor in the right place.if you've got the cursor in a non-rich text field you will probably get an error.the method `NotesUIDocument.Import()` mirrors the functionality of the menu item `File \ Import` so you don't even have to write any code in Notes if you don't want to.
window.clipboardData is an Internet Explorer only feature. Other browser vendors view meddling with the clipboard as a security threat and potentially really really annoying so it isn't implemented in Firefox, for example.
The only way I know to do it cross-browser is to use a Flash movie, and you can find out more about that here: http://www.jeffothy.com/weblog/clipboard-copy/
If you're happy with supporting IE only, then the way to get the full outer HTML of an element (not just the innerHTML) would be to duplicate the link into another element and get the innerHTML of that element.
The javascript looks something like this (sorry, it's untested)
var newEl = myLink.cloneNode()
var div = document.createElement('div');
div.appendChild(newEl);
var outerHTML = div.innerHTML; // <-- this is the variable you want.
To create a link in a Lotus Notes email you have to:
Write the Text for the link example: Stackoverflow
Select the text
Click Create->Hotspot->Link Hotspot...
Enter the url in the Value field
This is for Notes 7. Not sure if it was Notes 8 or 8.0.2 where they added a button on the toolbar to make it easy to do this.
Hope this helps

Categories