watir-webdriver: how to select (and click) a javascript link? - javascript

I'm trying to write a test for a mobile webapp with cucumber+watir-webdriver, but one particular link on a splash message is giving me trouble.
The link I want to select is <a class="btn" href="#">Close button</a>, which is created on the page by javascript.
I tried these selectors:
browser.link :text => 'Close button'
browser.link(:class,"btn")
browser.div(:id,"vf_dialog_desc").link(:class,"btn") # with encompassing div
browser.div(:xpath,"//div[#id='vf_dialog_desc']/descendant::a[text()='Close button']")
However, all of them fail with a variant of the error:
Error: {"message":"Unable to locate an element with the xpath expression (...snip xpath expression...) because of the following error:\nTypeError: Object #<an HTMLDocument> has no method 'evaluate'"}
Strangely enough, browser.html.include? 'Close button' is evaluating to true, so watir can access the element.
Note that, unlike other similar questions, this page is not in a frame.
The page structure is:
<html>
<head>...</head>
<body>
<div id="home">
<div id="vf_dialog_holder" class=" show">
(...)
<div id="vf_dialog_wrap">
<h4 id="vf_dialog_head" style="display: block;" class=" vf_dialog_info_icon">Welcome to xpto</h4>
<div id="vf_dialog_desc">
<img src="884857.jpg">
<p>Blurb.</p>
<a class="btn" href="#">Close button</a>
</div>
<div class="clr">
</div>
</div>
I am running watir-webdriver (0.6.4) on ruby-2.0.0-p247.

Since the button is created via javascript, I am guessing that watir is trying to interact with the button before it becomes visible. Try explicitly waiting for the element.
If you just want to wait for the link to be present:
browser.link(:class => "btn").wait_until_present
If you want to do something with it (eg click it) once the link appears:
browser.link(:class => "btn").when_present.click

Related

Google Analytics - Get nested span event click without class and id

I am using Tag manager and Anayltics 360.
My code as follows,
<div rel="ABC_Links" class="ak_widget" >
<!-- BEGIN: Widget - Links -->
<section class="mfb-30">
<div class="widget_links">
<div class="widget_container">
<div class="widget_content">
<button type="button" class="buttonShadow" onclick="window.open('https://somepagelink.aspx); return false;">
<div class="widget_item">
<div class="widget_icon">
<svg>123</svg>
</div>
<div class="widget_text"><span style="overflow-wrap: normal;">ABCD TEXT</span></div>
</div>
</button>
<button type="button" class="buttonShadow" onclick="window.open('https://somepagelink.aspx); return false;">
<div class="widget_item">
<div class="widget_icon">
<svg> 12345</svg>
</div>
<div class="widget_text"><span style="overflow-wrap: normal;">XYZ TEXT</span></div>
</div>
</button>
</div>
</div>
</div>
</section>
<!-- END: Widget Links --></div>
I have 12 buttons in this same format. Here i have given an example of two buttons.
Button name i can change later so i can not take it as hard coded for "Click Text" in tag manager.
I can use only rel= "ABC_Links" as unique identifier. I can not use any of below class as they are not unique.
I have used Custome javascript to get parent child relationship but didn't work.
I have used DOM element variable but it did not work.
Now Question is, Is there any way to trigger event in tag manager when i click on any of the button below and get the info in real time event in Anayltics 360 ???
One way to achieve this would be to create a User-Defined Custom JavaScript variable in GTM to set isABCLink=true on button click.
On the Variables screen under Built-In Variables make sure you have "Click Element" ticked.
Create a User-Defined Variable
Name: isABCLink
Type: Custom JavaScript
Code:
function() {
return {{Click Element}}.matches("div[rel=ABC_Links] button, div[rel=ABC_Links] button *");
}
Create a Trigger
Trigger Type: Click - All Elements
This trigger fires on: Some Clicks
Conditions: isABCLink equals true
Set up your tag firing on above trigger
Once caveat to point out is that the exact element clicked on could be the button or one of the child elements of the button such as the <svg> which might make it hard to set up your tag depending on what exactly you need.

Replace href with another href from the same page

I want to make a button that will have href that is same as another button.
I have one button on my website that not all users see but its almost hidden and hard to reach. This button has specific UR for every user and contains his ID. On another page I want to create a button that will copy the same href from the other button:
Here is an example:
<div class="row exsisting-button button-hard-to-reach">
See my offers
</div>
<div class="row new-button">
Here are you offers
</div>
You can use querySelector to find element and getAttribute getAttribute to set get href
document.querySelector('.btn-href').setAttribute('href',
document.querySelector('.your-offers').getAttribute('href')
);
<div class="row exsisting-button button-hard-to-reach">
See my offers
</div>
<div class="row new-button">
Here are you offers
</div>

Click on a specific ng-click in class using selenium protractor for ang js apps

I have this in view source
<div class="row-fluid:>
<div class="span4">
<div class="well tile table-clickable" ng-click="move('mjass')">
<h3> Music Jass </h3>
<div class="row-fluid cellBody">
<div class="span5">
<i class=" some text"
</div>
There are 4 more div classes like the complete section above. One section for rock, one more section for classical so I want to click specific to a particular ng-Click. (only jass or rock or classical) for example I should click only "move('mjass') here
In Protractor in using chrome driver with selenium in .js file
I used, element(by.className('well tile table-cilckable')).click() and it worked successfully
But since there are lots of different classes, it always takes the first and clicks it, so instead i need to use both class and ng-click.
You can use a partial match on the ng-click attribute:
$("[ng-click*=mjass]").click();
where $ is a shortcut to element(by.css()).
Or, you can add use an XPath expression and check the section title (a little bit less recommended by the Style Guide):
element(by.xpath("//div[contains(#class, 'table-clickable') and contains(h3, 'Music Jass')]")).click();

Many different popups needed; Is it better to use one abstracted popup to handle every scenario

I have 3 different types of modal windows to handle different events. They popup to handle either:
1) Warnings, i.e. "hey, if you leave the page you will lose your work" kind of messages.
2) Dynamic data from a form the user previously filled out, i.e. "you are about to create a page with DataX: Data X, DataY: DataY, Date: March 28, 2012.
3) Form for the user to fill out.
I was originally trying to handle all 3 of the above scenarios with one set of html/css/javascript, just passing in data and modifying divs depending on situation. As I have expanded things, i'm noticing things being harder to maintain cleanly without being sloppy about it. I have a few questions which i'll list after I walk through how things are now.
Simplified HTML for modal popups:
<div id ="popup" style="display:none;">
<div class="modal-container">
<div class="modal">
<div class="modal-header">
<a class="close" href="# " title="Press Esc to close"><div id="close-label" title="Press Esc to close">Close</div></a>
<span id="top-header">WARNING</span>
</div>
<div class="modal-body">
<div class="modal-subhead">
<img class="subhead-icon" border="0" src="">
<span id= "header">WARNING</span>
</div>
<div class="modal-message"><span>If you leave this page, you will lose unsaved changed.</span></div>
<div class="modal-input-first">
<div class="modal-label"></div>
<div id="modal-input"></div>
</div>
<div class="modal-input-second">
<div class="modal-label"></div>
<div id="modal-input"></div>
</div>
<div class="modal-footer">
<a class="secondary" href="#">Cancel</a>
<span id = "button-secondary-label">or</span>
<span class="btn_container">
<span class="btn_left"></span>
<span class="btn_center">Continue</span>
<span class="btn_right"></span>
</span>
</div>
</div>
Right now this is located in a separate file with it's css and javascript and is loaded when the page is loaded.
In the main file I am changing the popup depending on what triggered the popup, just using jquery as such:
$('.modal-message').html('New Message');
$('.modal-subhead #header').text('New header');
The dynamic data is filled in similarly after first making the ajax request to get the data.
As I said, as things grow, i'm having to change a lot of this, and it's starting to feel sloppy. Especially as i'm having to make pixel perfect changes to the css for individual elements. Would it be best to have 3 completely separate sets of html to handle these? Where is the best place for this to live, is the separate file approach?
Is it better to keep adding separate elements as I need specific ones for certain instances, like so:
<div class="modal-input-specific-thing">
<div class="modal-label"></div>
<div id="modal-input"></div>
<div id="modal-input-2"></div>
</div>
Or to use jquery to change the structure of the html on the fly?
var new_input = 'modal-input' + count;
$('#modal-input').attr('id', new_input);
Is there a better method for pushing only the elements needed to a popup like this?
If I had 10-12 scenarios, which is possible as I keep expanding this. Is there a big enough performance hit to parsing 12 different sets of html/css every time page is loaded vs doing what i'm trying to do now...Making a generic/abstracted popup window, and push elements/data to it as the user needs?
Thanks!
I should do this with jQuery and jQuery UI. The jQuery UI has a real nice popup function called dialog. ( http://jqueryui.com/demos/dialog/ )
A working version that reconstruct your situation you will see here. ( http://jsfiddle.net/7GVmz/ )
There are a lot of options you can add so as buttons, callbacks on opening and closing. You can read all of it in the documentation on the jqueryui website ( http://jqueryui.com/demos/dialog/#option-disabled )
Html
<div id="popup-1" title="popup-1">
Hello World
</div>
<div id="popup-2" title="popup-2">
Hello World
</div>
<div id="popup-3" title="popup-3">
Hello World
</div>
JS
$(document).ready(function() {
$('#popup-1').dialog();
$('#popup-2').dialog();
$('#popup-3').dialog();
});​
Note
Its important that you load the jquery library and the jquery ui library.
​
I use SweetAlert for all my JavaScript alerts, it's a Better JavaScript Popup Box than the default and is really simple to use.
swal({<br>
title: "Are you sure you want to leave?",<br>
text: "You have unsaved changes!",<br>
type: "warning",<br>
showCancelButton: true,<br>
confirmButtonClass: "btn-danger",<br>
confirmButtonText: "Yes, Exit!",<br>
closeOnConfirm: false<br>
},<br>
function(){<br>
swal("Deleted!", "Your imaginary file has been deleted.", "success");<br>
});<br>
A full tutorial is here - https://kodesmart.com/kode/javascript-replacement-alert-box

Can I get some help decoding this bit of a Facebook page?

I'm trying to figure out just how a particular function works on a Facebook page, and being no friend of JS syntax, am having trouble. Here's the question mark bit:
<a href="#" clicktoshowdialog="my_dialog" onclick="
(new Image()).src = '/ajax/ct.php?app_id=4949752878&action_type=3&post_form_id=3b933f46f9c4c44981e51b90c754bfce&position=2&' + Math.random();
FBML.clickToShowDialog("app4949752878_my_dialog");
return false;">
<img src="linktopicture" title="Are your friends fans?" width="190" height="230" />
</a>
<div style="display:none">
<div id="app4949752878_my_dialog" fbcontext="aa3fcff8e653">
<div class="app_content_4949752878" style="padding:10px">
<div with hidden then exposed content...
The functionality of this is an image that, when clicked, pops out the previously hidden div. I know that the app###### is prepended to all JS used in Facebook to limit its scope. I'm confused by the anchor parameter of
clicktoshowdialog="mydialog"
What is that identifying, and how is it targeting the div that's exposed when the image is clicked? Thanks for any clarification, and let me know if I can post any more sample code.
According to the wiki it's just for opening the dialog (which is defined at the bottom). Facebook generates the JS to open the dialog. The attribute got post-processed and the JS code (that you see in the onclick= attribute) was generated on it's basis.

Categories

Resources