Robot Framework: Click button using execute javascript - 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.

Related

How do I dump entire dom structure using selenium webdriver

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.

Javascript automate onclick

I'm trying to automate clicking a few links on a webpage
For example, in Google Chrome if I type Javascript:setDisplayType('source'); then it runs the function in the html defined as
<input type="radio" name="DisplayType" value="source"
onclick="setDisplayType('source');">
So far so good. However, I'm unsure about how to do the same with the following
<td id="4124321351_U923" class="o bgc b" onclick="s(this,'329803656','40745906','9/2');b(this,'5.5','5.5');">5.5</td>
I've tried the following without success
Javascript:s(this,'329803656','40745906','9/2');
Javascript:b(this,'5.5','5.5');
Javascript:s(this,'329803656','40745906','9/2');b(this,'5.5','5.5');
Please can someone explain why it's not working and how to fire this onclick event using a similar method?
if you're not using JQuery or similar, then something like:
document.getElementById("4124321351_U923").click();
might work. In short, your examples above don't work because the 'this' magic variable needs to be initialised to point to the link being clicked. You could either try to initiate a click event on the element (as per my example) or you could manually grab a reference to the link, and pass that in instead of this
Problem is with this argument because it's not called from the element and you called it outside.
Javascript:s(this,'329803656','40745906','9/2');
Try proving a proper argument like this,
Javascript:s(document.getElementById('4124321351_U923'),'329803656','40745906','9/2');

jquery postback failing

I'm trying to initiate a postback invoking the click function of a server-running element, as to run some C# code, in the event of a particular jquery dialog button click.
I am using a modal dialog with buttons as per this jQuery UI example. I have attempted using all of the different answers for javascript/jquery postback invocations in this question.
I've set a couple of breakpoints in my C# code to see if these postbacks are getting called, but nothing is getting hit.
I have this dummy element in my ascx file to use:
<a id="anchorId" runat="server" onclick="return true;" onserverclick="TryLogin"></a>
I've attempted to get this postback to occur a few different ways:
$("#anchorId").click(); //just simply does nothing
document.getElementById("anchorId").click(); //This one gives me a null javascript error
$("document").getElementById("#anchorId").click(); //tells me [object] doesn't have a getElementById
__doPostBack('<%=anchorId.UniqueID %>', '');//Also does nothing in the jQuery code, but works in standard javascript code
Lastly I did try retrieving the unique ID in the code behind as:
string id = anchorId.UniqueID;
and replaced in the javascript this way:
__doPostBack('Softening_Main$anchorId', '');//Still does nothing, and no javascript error
I really need some help here, any ideas?
There are couple of issues in your code.
$("document") will not select document instead will look for document tag element on the page. You should use $(document) removing the quotes.
Also getElementById is a JavaScript method of document object which is used to find element by id. When you use getElementById don't specify # in the id. # is used by jQuyer to differentiate between various selectors.
Remove inline onclick="return true;" from anchor and try this.
$("#anchorId").click(function(e){
__doPostBack('<%=anchorId.UniqueID %>', '');
return false;
});

Executing function on a click event in a mustache template

I have a page that is driven by a mustache template (along with javascript and jquery), and I can't figure out how to insert a function into this template. Essentially what I want is to add a link or button to the page that executes a function, "onTaskSelected(taskId)", when the user clicks on it. I've been searching for a way to accomplish this for several days now, and extensive mustache documentation/support/examples are woefully hard to find. Does anyone know how this could be accomplished?
Edit - Here is some of the code that I've tried:
data["B" + task.taskId] = {
changeTask : function(taskId) {
var self = this;
self.onTaskSelected(taskId);
},
taskId : task.taskId
};
Data gets loaded into the mustache template, which has the following within it:
<button onClick="{{#B8.changeTask}}B8.taskId{{/B8.changeTask}}">Change to task 8</button>
I've debugged the code to the point where data gets sent to the template to be converted to html, and B8 has set both changeTask and taskId correctly. However, by the time the html is displayed, the button looks like this:
<button onclick>Change to task 8</button>
Why is the onclick getting zapped, and how can I fix it? It doesn't need to be a button, but I do need a clickable element on the page with that text.
Update: I have since updated my template as follows:
<button onClick="{{#B8}}{{#changeTask}}8{{/changeTask}}{{/B8}}">Change to task 8</button>
Apparently I needed to nest my data templating in order to access the variables inside the "B8" object. However, now the problem I have is that it's trying to execute the "changeTask" function when it creates the html from the template. How can I get it to wait to execute until I click the button?
Finally got it working, but I ended up going a completely different route. Wanted to post it here in case anyone else had the same problem. I formatted the mustache to give the button a name rather than try to insert the onClick method, then I cycled through every button in that section of the DOM using jquery and add an onClick method to the buttons that had the right names.
Edit: Technically I also changed my buttons to links, which I'll show in the code below, but it should also work for buttons as well.
template:
<a name="{{{B8}}}">Change to task 8</a>
jquery (partial example):
$('a[name="' + buttonData[B8].name + '"]').click(function() {
self.onTaskSelected(buttonData[B8].taskId);
});
Hope that is helpful for others.
While your own answer is correct in essence, there is an easier option to select with jQuery:
$(link+'[name|="'+buttonData[B8].name+'"]')
Hope this helps u in the future.
Btw - I am myself still searching for a solution to the original problem...

Invoking jQuery function without an element

So, I use jQuery quite extensively and I am well aware of the "right" way to do the below, but there are times where I want to solve it in a more generic way. I'll explain.
So, I may have a link, like this: <a href='menu' class='popup'>Show menu</a>. Now, I have a jQuery function that fires on click for all a.popup that takes the href-attribute and shows the <div id='menu'></div> item (in this case). It also handles URL's if it can't find a DOM item with that ID.
No problem here. But, there are times when I don't have the same control over the coe where I can create a selectable target that way. Either because the code isn't created by me or because it is created through a chain of function that would all need a huge ovrhaul which I won't do.
So, from time to time, I would like to have this code:
Show menu
This would be in a case where I can only submit the label and the HREF for a link. No class, no nothing.
Problem here is that the function popup() has no idea about what element invoked it, and in most cases that's not a problem for me, since I only need to know where the mouse cursor was upon invokation.
But in some cases, I use someone elses jQuery functions, like qTip or something else. so I still want to fire off qTip(); when clicking a link that runs this JS function, but what do I attach it to to make it show? I can't just runt $().qTip(); because that implies $(this) and "this" is undefined inside the function.
So how do I do it? Any ideas?
Is there anyway you change the javascript method to javascript:popup('menu', this);? I've used this method successfully many times.
Instead of referring to "this" try referring to $('a:focus') to refer to the link that was clicked.
Here's a quick and, as #Crescent Fresh would add, dirty (☺) sample:
<body>
<p>Show popup()</p>
<div id="menu" style="display:none">Today's menu</div>
<script type="text/javascript">
function popup(elm) {
$('#' + elm).show();
alert( $('a:focus').text() )
}
</script>
</body>
I tried just ":focus" but IE7 returned too much content. I tested this in FF 3.6.3, IE7, Chrome 4.1.249.1064 (all on Windows) and it seems OK, but I see now (when I was just about to hit "Post Your Answer") this relies on the browser's native support for querySelectorAll - see this jQuery Forum post ":focus selector filter?" and the jQuery.expr entry in the jQuery Source Viewer (where it appears Paul's idea was not implemented).
How about
Show menu
Once you get the event object you can virtually do anything to it.

Categories