Using Watir with Chrome browser to find element on just opened web page - watir-webdriver

I try to find button on just opened page without sleep command.
HTML:
<span id="create-user-button" class="ui-button ui-widget ui-state-default
ui-corner-all ui-button-text-only" role="button" aria-disabled="false">
<span class="ui-button-text">Create‌·User</span>
</span>
Initialization of my element:
span(:create_user_button, :id => "create-user-button")
def open_user_creation_dialog
sleep 1
self.create_user_button_element.when_visible.click
end
When i use piece of code without sleep for Chrome browser, my page is closed and i can't find defined button. There isn't such problem for FF.
I try to use a lot of variants to fix it, like :
self.create_user_button_element.when_visible(2).click
self.create_user_button_element.when_present(2).click
Solution was found :
My page doesn't use Ajax, but there is very big table with users on my page, it takes a lot of time to download.
So i am waiting for download big table and after that i find very well my element.
My problem was solved.
div(:total_users_number, :id => "users-table_info")
def open_user_creation_dialog
self.wait_until(10, "No users displayed") do
self.total_users_number_element.when_visible.text != ""
end
self.create_user_button_element.when_visible.click
end

I have page with a very loadful content, namely list of users, so i should wait for element with big content. I do it, this way :
div(:total_users_number, :id => "users-table_info")
self.wait_until(10, "No users displayed") do
self.total_users_number_element.when_visible.text != ""
end
When this element loaded, i can find my sought element
self.create_user_button_element.when_visible.click

Related

Protractor can't find element by binding

I'm trying to find a element by binding, the problem is that the the element is an toast.
I'm using:
element(by.css('.btn-primary3')).click()
To simulate the click. As a result the toast does appear in the browser during the test.
Then I'm trying to store the element in a variable and test if the text value of the toast is equal to the expected value.
var toast = element(by.binding('toast.toast.title'));
expect(toast.getText()).toEqual('Inloggen mislukt');
But here the error pops up.
Failed: No element found using locator: by.binding("toast.toast.tile")
When I check the toast element in the the Chrome dev tools it shows up like this,
<div data-ng-repeat="toast in activeToasts">
<span data-ng-bind="toast.toast.title" class="ng-binding"> Inloggen mislukt</span>
</div>
I think the problem comes from the fact that that the span containing the binding doesn't exist on the dom when the page is loaded. It gets created when the button is clicked.
If this is the case, wait for the presence of the element after clicking the button:
element(by.css('.btn-primary3')).click();
var toast = element(by.binding('toast.toast.title'));
browser.wait(EC.presenceOf(toast), 5000);
expect(toast.getText()).toEqual('Inloggen mislukt');
May you should try:
<div data-ng-repeat="toast in activeToasts">
<span data-ng-bind="toast.toast.title" class="ng-binding"> Inloggen mislukt</span>
</div>

Extra script added to Phonegap app slowing performance nativeFetchMessages()

Using Phonegap and Kendo Mobile UI, my application fills several different listviews dynamically from an SQL db accessed through the openDatabase() in phonegap. When I first start the app and click through several different lists the application navigates and populates the views very quickly. After flipping through the screens more than 15-20 times the entire app starts to slow down, and eventually crawls to a point where its hard to use.
Running on an iPhone4 - 5 or simulator doesnt make a difference.
Starting the app fresh I am greeted with the first list view.
Inspecting the web view and looking at the file list I can see index.html.
Under that the normal folders: Scripts, Images, Fonts ect..
Clicking on a list item drills into another listview. Once the page is changed and the new listview is populated I now notice a new folder under the index.html parent item. A folder called: "Extra Scripts"
Inside the Extra Scripts folder I find a new index.html file (with no children). Clicking on it opens its contents, 1 line:
cordova.require('cordova/exec').nativeFetchMessages()
Clicking on another item drills down further by changing the view again and populating another list view. On this third screen now, I notice there are 2 index.html files in the Extra Scripts folder.
In short: Anytime these views with lists on them are shown, a new file is attached to Extra Scripts. Once the number of these files gets over 12 or so, the device slows down. I do have other views in my application that do not contain dynamically populated list views, these pages do not cause an Extra Script to be created.
I am not sure if the issue exists with the Kendo Mobile ListViews or Phonegap 2.4 itself. I have also upgraded Phonegap to 2.9 which did not help.
I also have another application running the same version (2.4) and it does not experience any of these issues, although it does not concentrate on listviews has heavily, several listviews exist and no issue arises.
Another big difference between the two apps is that the broken one fills it's data from phonegaps WebSQL database plugin, where as the app that works pulls its data from ajax calls contacting a REST service.
Below is an example of how I create and initialize my list views
<div data-role="view" id="equipmentPage" data-title="My Network" data-layout="mobile-tabstrip" >
<ul data-role="listview" class="equipmentlist" data-source="equipmentDS" data-template="equipmentListItemTemplate">
</ul>
</div>
<script type="text/x-kendo-template" id="equipmentListItemTemplate">
<div class="left wide liname">${name}</div>
<div class="hiddenField" style='display: none'>${id}</div>
<div class="right">
<div class="hiddenField" style='display: none'>${id}</div>
<div class="km-button badgeButton" id="badgeequipment_#=id#"></div>
<button class="editEquipment" style="vertical-align: top" data-role="button" data-icon="compose"> </button>
</div>
</script>
function equipmentliTemplateInit(){
lockOverlay = true
showLoadOverlay()
console.log("equipmentInit")
dbSelect("Select * from Equipment WHERE active = 1 and userId = " + ((temp.selected.friend > 0)?temp.selected.friend:temp.user.userID) + " AND siteId = " + temp.selected.site + "", function(tx, results){
var equipment = new Array();
for(var i = 0; i < results.rows.length; i++)
{
equipment.push(results.rows.item(i))
}
fillEquipment(equipment)
lockOverlay =false
hideLoadOverlay()
})
}
function fillEquipment(equipment)
{
equipment.sort(function(a, b){
var nameA = a.name.toLowerCase();
var nameB = b.name.toLowerCase();
if(nameA < nameB)
return -1
if(nameA > nameB)
return 1
return 0;
})
/*$(".equipmentlist").data('kendoMobileListView').destroy()
$(".equipmentlist").html("");
$(".equipmentlist").kendoMobileListView({
dataSource: kendo.data.DataSource.create({data: equipment }),
template: $("#equipmentListItemTemplate").html()
});*/
equipmentDS.data(equipment)
setBadges()
if(equipment.length < 1)
$(".equipmentlist").html("<li><center>There are no equipment to display.<br>Use the + button to add one.</center></li>");
defineListItemActions()
}
I tried to upload images but new users are unable to.

How to wait in watir-webdriver to load next page and then do assert on some random text

I am new to watir, and (believe me) I tried all the options that are avaliable here for adding wait and assert but have not been successful in doing so.
Here's a brief description of what I'm trying to do and appreciate your help.
I log into my website
I login using userid/password and hit click button.
I want watir to wait until next page is loaded
I want to do some assert to verify the login was successful.
My step 3 and step 4 are failing with the error element not found.
If I login manually and login is successful, I see text Hello,username at the top of the second page and this is what I've been trying to key off of but not having any success. It could be something very simple, but since I'm new to watir, I'm unable to figure it out.
Here are all the commands I tried:
$b.button(:id, 'usernameLogfaceinButton').click
#$b.wait_until($b.text.include?("Hello"))
#($b.text.include?("Hello")).wait_until_present
#$b.text_field(:text, "Hello").wait_until_present
if $b.text.include? "Hello"
puts "Test Passed. Found the test string: Hello- Actual Results match Expected Results."
else
puts "Test Failed! Could not find: Hello"
end
HTML on Page:
<body id="myAccounts" class="cardholderLayout ">
<div id="content">
<div id="navigationContainer">
<div id="headerNavigationMenu" class="innerContents">
<div class="logo"><img alt="xxx" src="/images/xxx.png?xxxxxxxx"></div>
<ul class="menu">
<li class="menuItem">
Hello, Bob
I hope someone can help me or point me in the right direction.
Try:
$b.link(:text => /^Hello/).wait_until_present
Notice that:
It is $b.link instead of $b.text_field. The method needs to match the type of element you are looking for.
The text in the locator is /^Hello/ instead of "Hello". If you pass a string (ie "Hello", watir will look for an element where the text exactly matches. If you want to do a partial text match, then you need to use a regular expression. The expression /^Hello/ says to find a text starting with "Hello".

How to reuse codeigniter form on multiple pages

I have a simple search form I want to reuse across multiple pages in my codeigniter application. For example, right now I have a search form in the sidebar and I'm planning on displaying that sidebar on the index, about, and other pages.
I want to have the form validation display errors on the same page the users submits the form from.
For example:
User is on About page.
User submits form with invalid data
User sees error in the sidebar on the About page
and
User is on Index page.
User submits form with invalid data
User sees error in the sidebar on the Index page
But I'd like to reuse that form validation logic. I just want it to display the error on whichever page the user posted from.
Any ideas how to do that? Sorry for the noob question, I'm pretty new to CI.
Here you have to think globally.
Step.1 : Make one view file : display.php
which contains :
<div id = "main">
<div id = "header">
[load header file here]
</div>
<?php
if(validation_errors() != '') {
?>
<div id = "error">
<?=validation_errors()?>
</div>
<?php
}
?>
<div id = "content">
<?=$page?>
</div>
<div id = "footer">
[load footer file here]
</div>
</div>
Step.2 : About us Page.(controlller)
.... Your data ....
at end of controller function
$data['page'] = 'aboutus';
$this->load->view('display',$data);
With regards to your comment on the above question you could use Flash data
With the assumption that you have the session library loaded, here is a helper function.
function last_page($page = null){
$ci = get_instance();
if($page === null)
return $ci->session->flashdata('last_page');
$ci->session->set_flashdata('last_page', $page);
}
then you can call last_page('about'); at the top of the about page, and then when you want to find out what the last page you were on was you can just call last_page(); with no params.
In the User Guide, there's different ways to configure sets/groups of rules. Then you can simply have something like:
if ($this->form_validation->run('signup') == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
Which will run your "signup" group of validations. To me, this is the cleanest way to achieve reusable validation rules.
This is a perfectly valid question.
I'm not a PHP expert, nor a CI expert, but the fact is sometimes you want to post to a controller that didn't create the view from which you're posting. Which means posting back to itself is not going to work.
I came across this post on the Ellislab forum:
http://ellislab.com/forums/viewthread/217176/
On this page, There are 2 methods of going about it. Both of which use flashdata and both of which are totally valid, IMHO.
The first: create a helper function
http://ellislab.com/forums/viewreply/1003010/
The second: extend the CI_Form_Validation Class.
http://ellislab.com/forums/viewreply/1047536/
The second is the way I went as it seems cleanest although some may argue whether the form validation class should know anything about flash data.

simple database query in lift framework web page

I'm starting out with Lift and been reading a few tutorials and books that are available online. Coming from a JSP (or GWT) background, it's a huge leap, especially since I'm still learning Scala too.
Anyway... I've created the basic site by downloading the lift tar.gz stuff from their site, copied the lift_blank" directory and renamed it to "test". Did the whole "sbt update ~jetty-run" thing etc etc.
What I want to do is modify the "index.html" page to simply have a text field for input, and a button that says "search". Basic idea, you type your firstname, hit "Search", a database query is executed for finding records with a firstname of "what-you-entered-in-the-text-field", and then the results are formatted and displayed on the web page; after the page has refreshed, the text field needs to contain the name that was entered as well.. You type in a different name, hit "search", and new results are displayed on the page. Initially (first time visiting the page), the results are of course empty. Simple stuff...
However, the examples I've all seen use html forms and POST backs etc; I really dislike this, for example users get all flustered when refreshing the page and they get a firefox popup "To display this page, Iceweasel must send information that will repeat any action (such as a search or order confirmation) that was performed earlier."... the page is also refreshed which is something I'd like to avoid.
Previously when I would build this in JSP, I would use all javascript; no "form" tags or anything, just a simple field with javascript events for hitting enter or hitting a "button"... events thaen get channeled to a main javascript function "onQuery" which then creates an AJAX request; when the result comes back from the server, javascript would modify a wrapper "div" element by changing the "innerHTML" value etc. The nice thing here is that the page doesn't refresh, just a tiny subsection of it does, the "table" (actually a div) which holds the results.
How would I re-create a very similar thing in Lift? I'm kind of lost here. I've followed a few examples in the past few days, but again they all use POST / forms. I can handle the scala database querying, and I understand how Lift's templates works, it's just the snippet / comet stuff that I could use a few pointers on.
You can try to use the SHtml.ajaxText function to get the input and to use Wiring on server's side to deal with the request and change automatically the result.
However, with this solution, you no longer need the submit button, but as you don't want a form it should not matter much.
Here is what I think about for the HTML file :
<div id="myHtml" class="lift:surround?with=default;at=content">
<form class="lift:form.ajax">
<input class="lift:SearchForm.name"/>
</form>
Value searched : <span class="lift:SearchForm.display">
</div>
Now on server's side it is a little bit more complicated
class SearchForm{
val name = SHtml.ajaxText("", s=>{ SearchWiring.name.set(s); Noop})
def display = {
WiringUI.apply(SearchWiring.name)(name:String => {"*" #> name} )
}
}
object SearchWiring{
val name = ValueCell("All")
}
I don't know if this is totally rigorous but it is my best thought for your problem. You will find more details about wiring on the official liftweb demo and on Seven Things blog. I hope it will help!
Below is what I ended up using. The one thing I dislike about Lift is all the "magic" that needs to be inserted at various points. I can understand most of this, but the whole " ++ hidden" thing could use some explaining...
The "index.html" page, everything including the "body" tag:
<body class="lift:content_id=main">
<div id="main" class="lift:surround?with=default;at=page">
<lift:Search.search>
Search Query: <query:text/> <query:button/><br/>
<div id="results">
</div>
</lift:Search.search>
</div>
</body>
The "Snippet" code, in a class called "Search.scala" (some of the import statements are unused, a leftover result of attempting different approaches):
package code
package snippet
import scala.xml.{NodeSeq, Text}
import net.liftweb.util._
import net.liftweb.common._
import java.util.Date
import code.lib._
import Helpers._
import common.Main
import common.solr.{Hitlist, Solr}
import net.liftweb.http.{S, StatefulSnippet, SHtml}
import net.liftweb.http.js.JsCmds.SetHtml
import _root_.net.liftweb.http.SHtml._
import _root_.net.liftweb.util.Log
import net.liftweb.http.js.JsCmd
import net.liftweb.http.js.JE.JsRaw
object Search {
def search(xhtml:NodeSeq):NodeSeq = {
var queryText = "(initial)"
def runQuery() = {
println("\n\nQuery: " + queryText)
SetHtml("results", <span>Query: {queryText}</span>)
}//runQuery
ajaxForm(
bind("query", xhtml,
"text" -> text(queryText, queryText = _),
"button" -> submit("Post", runQuery)
) ++ hidden(runQuery _)
)
}//search
}//Search