I am pretty new to automation and watir-webdriver so forgive me if I don't sound super techy.
I am trying to log in to a website and the login form is inside of an iframe. There is also another iframe on the same page that contains an image.
This is the html:
<body>
<div class="topbar">
<div class="topbarcenter">
<ul>
<li id="logo" class="logo">
<div id="provider_logo">
<iframe id="logo_iframe" width="192px" height="128px" frameborder="0" src="http://social.onerecovery.com/modules/iframes/html/provider_logo.html?prov=microsites" onload="this.style.visibility = "visible";" style="visibility: visible;" allowtransparency="true">
</div>
</li>
<li class="login">
<iframe id="login_iframe" width="550px" height="70px" frameborder="0" src="http://social.onerecovery.com/modules/iframes/html/login.html" onload="this.style.visibility = "visible";" style="visibility: visible;" allowtransparency="true">
<html>
<head>
<body>
<div class="login_container">
<div id="login_div">
<form class="login_form" action="#" method="post">
<input type="text" maxlength="100" placeholder="Email Address..." class="email_input processed" name="email">
by the way I am using watir-webdriver 0.3.5 and automating on chrome 17
what I tried was:
$b.frame(:id => "login_iframe").form(:class => "login_form").text_field(:name => "email").set("username")
which I thought would work but in my command line I just get the error: Watir::Exception::UnknownObjectException: unable to locate element, using {:class=>"login_form", :tag_name=>"form"}
I also tried indexing the iframe to make sure I was in the second iframe and not the first but it still didn't work.
When I do
$b.frame(:id => "login_iframe").exists? in command line, I get
true
but when I do
$b.frame(:id => "login_iframe").form(:class => "login_form").exists? in command line, I get
false
The thing is that we have another page that someone can use to login to the same website and the only difference between that page and this page is that this page has a second iframe whereas the other page only has the login iframe and the code
$b.frame(:id => "login_iframe").form(:class => "login_form").text_field(:name => "email").set("username")
works perfectly fine.
Sorry for going on so long. Just wanted to make sure that I gave enough info. Thanks in advance for any help.
The short answer to solving your problem is to use browser.frame(:index => 2) instead of browser.frame(:id => "login_iframe").
Or if you want a slightly more robust solution:
frame = browser.frames.find{ |frame| frame.form(:class => "login_form").exists? }
frame.form(:class => "login_form").text_field(:name => "email").set("username")
That said, I really do not know why that works. It is like it thinks the login control is inside the invite_iframe, which it does not look like in the HTML. I will try to dig deeper, but sounds like a bug to me.
It appears that all of the iframes are shuffled funny. As you can see by the following, the number of text fields in each iframe does not match what is expected.
browser.frames.each{ |x| puts x.id + ' - ' + x.text_fields.length.to_s + ' text_fields' }
#=> logo_iframe - 3 text_fields
#=> login_iframe - 0 text_fields
#=> invite_iframe - 2 text_fields
For the latest versions, it is browser.iframes which lists all the iframes current window has.
browser.iframes.map {|iframe| iframe.src}
This will map src attributes of all iframes.
Related
Below I put an extract from an IMDb page, I purposely kept it short. My end goal is to get the 2 links. But I can't even figure out how to get a specific div with an id. Because obviously the class below is spread out all over the page. I've Googled, looking for an example using class and id, but still can't find he solution.
p.s. The only reason I have Dumper in there is so when I run it, I can instantly see how I still haven't got it.
my $ua = Mojo::UserAgent->new( max_redirects=>3, timeout => 30 );
my $dom = $ua->get($newrip)->result->dom;
my $module_list = $dom->find('div.article');
print Dumper $module_list;
exit;
<div class="article" id="titleDetails">
<span class=rightcornerlink>
Edit
</span>
<h2>Details</h2>
<div class="txt-block">
<h4 class="inline">Official Sites:</h4>
<a href="/offsite/?page-action=offsite-facebook&token=BCYtlGRCvvzcjTOrSRBQqjTPuEUBGkxbnkfQjRYZi0XJxm-A-A4vf0mzJF5WqH6HYLt2TZCuVR7c%0D%0A209QQMCwUe-51EwtDDYbNczYCnFRIRzctUhoXJCF2gsQJw6m050sV9g0sTJJEfiGP37rfeIIoXMS%0D%0ACfj2qgUNCaL2YaP_FeWVGCg39Bw-3dRsP5cB1Wk9FfobPd5tG8Q4WjVbUR2pTOvE0Pkc5QUK5E7U%0D%0AX7O9awNb0Kw%0D%0A&ref_=tt_pdt_ofs_offsite_0"
rel="nofollow">Official Facebook</a>
<span class="ghost">|</span>
Official site
<span class="see-more inline"></span>
</div>
I'm having a hard time trying to connect SUI modal with SilverStripe to generate them dynamically.
I want to achieve something like this:
I have button (attach events) to trigger modal with some content. I wanted to loop that elements (GridField) to generate everything dynamically. But the only thing I can achieve is multiple modals with the same "trigger class" and it doesn't matter which button I have clicked (first, last or whatever). I only have one modal (the last in hierarchy). Without SUI the solution is easy - put "this" to fetch the closest element and I can have as many different modals as I want, but SUI seems to complicate things.
I think the best solution will be to generate a class/id with SilverStripe and pass it to the JavaScript to use with modal or use one class for every modal and to "somehow inform" that this button triggers this modal.
Basically I need one code snippet to handle many modals, not many snippets to handle many modals. I hope it's clear enough what the the problem is.
Here is my code:
HTML/SS
(without specific SilverStripe tags)
<% loop SomeName %>
<div class="job-offers">
<a class="ui right floated button job-application">Click here</a>
</div>
<div class="ui basic modal job-application">
<div class="job-application-sheet">
(...)
<div class="job-application-sheet-content">
<div class="ui grid">
(...)
<div class="ui center aligned container job-application-action">
<p>Lorem ipsum</p>
<button class="ui primary button">Click here</button>
</div>
</div>
</div>
</div>
</div>
<% end_loop %>
JavaScript
$('.ui.basic.modal.job-application')
.modal({
autofocus : false,
observeChanges: true
})
.modal('attach events', '.job-application', 'show');
As you can see "job-application" class is a trigger for modal, so is this possible to change it to "(this)" so I don't have to write "specific" class for each button/modal. Or maybe there is a different/easier solution?
first i generated a data-type attribute for each of my elements that are going to display a modal when they are clicked, and in send as a local the same index to the modal this way:
<% #relateds_array.each.with_index do |related,i| %>
<div class="card custom" data-id="<%=i%>">
<%= render partial: 'my_modal', locals: {index: i} %>
</div>
<% end %>
the i put the modal in the partial that i called my_modal for this example and used the index that i sent as a local to create an unique id for each my modals, like this:
<div class="ui modal" id="modal-<%=index%>">
<p>blabla things inside this modal.</p>
</div>
and then with javascript, simply get the data-id of the element clicked and select the element that contain the id for that data-id, like this:
$('.element_that_you_want_to_open_moda_on_click').click(function(event){
var card_clicked = $(this).attr('data-id');
$('#modal-' + card_clicked).modal('show');
});
Hope this was useful for you.
Note that i used Ruby on Rails for this example, but the behaviour that you should use should be something similar to this, no matter what framework you use.
Answer based on Sebastian's solution. I did some minor tweaks to meet my needs, like I've used ID variable to automatically get DataObject ID which is generated dynamically.
Basically to dynamically add Semantic UI (SUI) modal in SilverStripe, first you should add "data-id" in a modal trigger, for example:
Template.ss
<a class="ui button custom-trigger" data-id="my-item-$ID">Click here</a>
then inside modal container add an "id" tag, for example:
<div id="modal-my-item-$ID" class="ui basic modal">
(...)
</div>
Finally in JavaScript file:
$('.custom-trigger').click(function(event){
var triggerItem = $(this).attr('data-id');
$('#modal-' + triggerItem).modal('show');
});
I meet problem with SUI autofocus, so after a modal opens, screen went to the bottom and button placed there was highlighted.
I tweaked original snippet adding SUI settings:
$('.custom-trigger').click(function(event){
var triggerItem = $(this).attr('data-id');
$('.ui.modal')
.modal({
autofocus: false,
observeChanges: true
})
$('#modal-' + triggerItem).modal('show');
});
If someone wants to write "data-id trigger" manually using fields in CMS, then change $ID to $SomeField variable. Then normally add that field in .php file and in Page Controller add something like this:
public function init() {
parent::init();
Requirements::javascriptTemplate($this->ThemeDir().'/js/script.js', array(
'SomeField' => $this->SomeField
));
}
Hope this helps someone.
Is there a way to verify that element 'Adam Slodowy' is bold in Selenium IDE?
This is the fragment of site code:
...
<div class='thread-content-row.thread-content-row-1'>
<div class='thread-content-row-left'>
<div class='thread-content-row-right'>
<div class='discussion-info'>
<b>Daria Ogrodowska</b>
do
<span>super</span>
,
<span>Adam Slodowy</span>
</div>
<div class="discussion-content"> bla bl balkjbasdfsdfsdfdsfsdf sdfsdf sdf sdf </div>
</div>
</div>
I've tried to use verifyEval command:
Command: verifyEval
Target: var elem = window.document.querySelector("div.thread-content-row.thread-content-row-1 > div.thread-content-row-right > div.discussion-info span"); window.getComputedStyle(elem,null).getPropertyValue("font-weight");
Value: 700
but I have no idea how in querySelector refer to second span - querySelector("div.thread-content-row.thread-content-row-1 > div.thread-content-row-right > div.discussion-info span[2]") doesn't work.
It is really much more practical for a human person to check styles as even if it was bold it could look really bad and Selenium wouldn't be able to tell if it looked "bad" or not.
That being said, you would probably want to utilize xpath query on this one.
xpath=//span[contains(text(), 'Adam Slodowy')
or if you have more than one of those in your web page.
xpath=//div[#class='discussion-info']/span[contains(text(), 'Adam Slodowy')
the // indicates to look through the web page for an element that matches whatever follows. Which is very beneficial so that you don't have to include entire xpath which is very fragile if any of the structure changes.
where is this nested div construction defined, that the user-login form doesnt has:
<div class="form-item form-type-password form-item-pass-pass1 password-parent">
<div>
<input>Password Input</input>
<div>Password Strength</div>
</div>
<div>
<input>Password Confirm</input>
</div>
i have looked in form.inc, the user-module folder but no luck. as stated, the user-login form is printed plain without any nesting like this, so where is this determination done?
This is added with js. Look into ROOT/modules/user/user.js for the code.
I have the HTML as
<li>
<div data-track="discovered_spots" data-filter="discovered_spots" class="button filter-button">
<span class="icon-compass"></span>
Discoveries (2)
</div>
</li>
I am trying to click the button link
#browser.div(:class =>'button filter-button').span(:text => ' Discoveries (2) ').click
Just not working or producing any errors.
I have also tried using the xpath
##browser.div(:xapth => "//div[#data-track='discovered_spots']").click
##browser.div(:text => "Discoveries").click
but that produce errors.
I have also viewed and tried the code present in other questions chains but none worked any help will be very useful.
Try:
#browser.div(:text, /Discoveries/).click
Regex for the attribute should hit the text. Not specifying \d anchor will cast a wider net in case that value of 2 fluctuates by only looking for the match of Discoveries in text and ignoring the number and parentheses.