The when_present method polls the DOM every .1 seconds (by default) until the desired element is present. Other than the .1 second delay incurred by using it, is there any reason to use the standard .click method without when_present?
Why shouldn't I just make my own .better_click method that incorporates both waiting and clicking?
No, there is no reason for you to not wait for whatever you want to wait for in your methods.
The original Watir api was blocking for page loading, and javascript interaction was not as important. The current implementation of Watir is closely tied to selenium-webdriver, so most of the behaviors of selenium are duplicated in Watir. Some developers like the added control over exactly what they are waiting for at all times.
Related
I need to stop this carousel in order to perform validation on it
Tried to set autoplay=false
The autoplay function is based on setInterval() which is able to be controlled by Cypress.
See the Cypress documentation for clock
cy.clock() overrides native global functions related to time allowing them to be controlled synchronously via cy.tick() or the yielded clock object. This includes controlling:
setTimeout
clearTimeout
setInterval
clearInterval
Date Objects
So you should be able to freeze the carousel by putting the cy.clock() command at the top of your test, or before the cy.visit() page load.
In case you want to test the second slide and the third slide, etc, you can issue a cy.tick(5000) to move the autoplay on for one slide each time, since you configured autoplaySpeed: 5000.
I'm working on a custom cross platform UI library that needs a synchronous "ShowPopup" method that shows a popup, runs an event loop until it's finished and automatically cancels when clicking outside the popup or pressing escape. Keyboard, mouse and scroll wheel events need to be dispatched to the popup but other events (paint, draw, timers etc...) need to be dispatched to their regular targets while the loop runs.
Edit: for clarification, by popup, I mean this kind of menu style popup window, not an alert/dialog etc...
On Windows I've implemented this fairly simply by calling GetMessage/DispatchMessage and filtering and dispatching messages as appropriate. Works fine.
I've much less experience with Cocoa/OS X however and finding the whole event loop/dispatch paradigm a bit confusing. I've seen the following article which explains how to implement a mouse tracking loop which is very similar to what I need:
http://stpeterandpaul.ca/tiger/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/chapter_5_section_4.html
but... there's some things about this that concern me.
The linked article states: "the application’s main thread is unable to process any other requests during an event-tracking loop and timers might not fire". Might not? Why not, when not, how to make sure they do?
The docs for nextEventMatchingMask:untilDate:inMode:dequeue: states "events that do not match one of the specified event types are left in the queue.". That seems a little odd. Does this mean that if an event loop only asks for mouse events then any pressed keys will be processed once the loop finishes? That'd be weird.
Is it possible to peek at a message in the event queue without removing it. eg: the Windows version of my library uses this to close the popup when it's clicked outside, but leaves the click event in the queue so that clicking outside the popup on a another button doesn't require a second click.
I've read and re-read about run loop modes but still don't really get it. A good explanation of what these are for would be great.
Are there any other good examples of implementing an event loop for a popup. Even better would be pseudo-code for what the built in NSApplication run loop does.
Another way of putting all this... what's the Cocoa equivalent of Windows' PeekMessage(..., PM_REMOVE), PeekMessage(..., PM_NOREMOVE) and DispatchMessage().
Any help greatly appreciated.
What exactly is a "popup" as you're using the term? That term means different things in different GUI APIs. Is it just a modal dialog window?
Update for edits to question:
It seems you just want to implement a custom menu. Apple provides a sample project, CustomMenus, which illustrates that technique. It's a companion to one of the WWDC 2010 session videos, Session 145, "Key Event Handling in Cocoa Applications".
Depending on exactly what you need to achieve, you might want to use an NSAlert. Alternatively, you can use a custom window and just run it modally using the -runModalForWindow: method of NSApplication.
To meet your requirement of ending the modal session when the user clicks outside of the window, you could use a local event monitor. There's even an example of just such functionality in the (modern, current) Cocoa Event Handling Guide: Monitoring Events.
All of that said, here are (hopefully no longer relevant) answers to your specific questions:
The linked article states: "the application’s main thread is unable to process any other requests during an event-tracking loop and
timers might not fire". Might not? Why not, when not, how to make
sure they do?
Because timers are scheduled in a particular run loop mode or set of modes. See the answer to question 4, below. You would typically use the event-tracking mode when running an event-tracking loop, so timers which are not scheduled in that mode will not run.
You could use the default mode for your event-tracking loop, but it really isn't a good idea. It might cause unexpected re-entrancy.
Assuming your pop-up is similar to a modal window, you should probably use NSModalPanelRunLoopMode.
The docs for nextEventMatchingMask:untilDate:inMode:dequeue:
states "events that do not match one of the specified event types are
left in the queue.". That seems a little odd. Does this mean that if
an event loop only asks for mouse events then any pressed keys will be
processed once the loop finishes? That'd be weird.
Yes, that's what it means. It's up to you to prevent that weird outcome. If you were to read a version of the Cocoa Event Handling Guide from this decade, you'd find there's a section on how to deal with this. ;-P
Is it possible to peek at a message in the event queue without removing it. eg: the Windows version of my library uses this to close
the popup when it's clicked outside, but leaves the click event in the
queue so that clicking outside the popup on a another button doesn't
require a second click.
Yes. Did you notice the "dequeue:" parameter of nextEventMatchingMask:untilDate:inMode:dequeue:? If you pass NO for that, then the event is left in the queue.
I've read and re-read about run loop modes but still don't really get it. A good explanation of what these are for would be great.
It's hard to know what to tell you without knowing what you're confused about and how the Apple guide failed you.
Are you familiar with handling multiple asynchronous communication channels using a loop around select(), poll(), epoll(), or kevent()? It's kind of like that, but a bit more automated. Not only do you build a data structure which lists the input sources you want to monitor and what specific events on those input sources you're interested in, but each input source also has a callback associated with it. Running the run loop is like calling one of the above functions to wait for input but also, when input arrives, calling the callback associated with the source to handle that input. You can run a single turn of that loop, run it until a specific time, or even run it indefinitely.
With run loops, the input sources can be organized into sets. The sets are called "modes" and identified by name (i.e. a string). When you run a run loop, you specify which set of input sources it should monitor by specifying which mode it should run in. The other input sources are still known to the run loop, but just ignored temporarily.
The -nextEventMatchingMask:untilDate:inMode:dequeue: method is, more or less, running the thread's run loop internally. In addition to whatever input sources were already present in the run loop, it temporarily adds an input source to monitor events from the windowing system, including mouse and key events.
Are there any other good examples of implementing an event loop for a popup. Even better would be pseudo-code for what the built in
NSApplication run loop does.
There's old Apple sample code, which is actually their implementation of GLUT. It provides a subclass of NSApplication and overrides the -run method. When you strip away some stuff that's only relevant for application start-up or GLUT, it's pretty simple. It's just a loop around -nextEventMatchingMask:... and -sendEvent:.
Is there any function available in Watir Webdriver to wait for a new window tab to load?
What happens right now is the tests are not waiting for the tab to load and my scripts are failing because of that.
I know that i can wait for some elements available in the web page. But i dont want to do that for each web page.
If there is no method available, i would like to write a new method for the same as a library in my framework.
I am new to watir webdriver and ruby programming. So please help me to write a library function in case not available...
I may be misunderstanding, but your question seems to say two different things. On the one hand, you say that Watir doesn't wait for the page to load. But then you say you know that Watir can wait but you don't want to do that on every page.
In my experience, and again I may be misunderstanding, if Watir is going too fast and your page isn't loading, you have no choice but to have Watir wait on any page where this is a problem. What else did you have in mind?
If your page loads within 30 seconds you can use .wait_until_present or .when_present. (i.e., Watir will move on as soon as the element is available and will time out after half a minute).
For example, if your loaded page has the text "Hello" in a div, you can make Watir wait for up to 30 seconds for that text to appear by
browser.div(:text, 'Hello').wait_until_present
and then let your test pick up where it left off.
Or, if there is (as an example) a button with id "buttonId" that you want to click when the page loads, you can make Watir wait for up to 30 seconds until the button is loaded and clickable:
browser.button(:id, 'buttonId').when_present.click
I almost always use .wait_until_present or .when_present. for each new page load. Under normal circumstances 30 seconds is long enough for the page to be ready for Watir, and these two methods work very well.
See also http://watirwebdriver.com/waiting/
In a simple Ajax based website we are making some HttpRequests requests synchronously (I realize "synchronous Ajax" is somewhat of an oxymoron). The primary reason this is being done synchronously vs. asynchronously is in order to simplify the programming model for some of those involved (long story).
Anyway, we want to be able to make a styling change (specifically, overlay the screen with semi transparent white as Google search does) right before the request is made, and then take it away when results come back. Essentially this looks like:
load:function(url) {
....
busyMask.className="Shown"; //display=block; absolute positioned full screen semi-transparent
var dta=$.ajax({type:"GET",dataType:"json",url:url,async: false}).responseText;
busyMask.className="Hidden"; //sets display=none;
...
return JSON.parse(dta);
}
It is well known a synchronous requests will lock the UI. So not surprisingly, the white overlay never shows up in Safari and Chrome (it does in Firefox interestingly). I've tried slowing the response way down and using a pink overlay so that it will be painfully obvious, but it just won't update the UI until after the request is complete. Leaving the 'busyMask.className="Hidden"' part out will show the mask-- but only after the ajax request is complete.
I've seen many many tricks for forcing the UI to repaint (e.g. Why HourGlass not working with synchronous AJAX request in Google Chrome?, http://ajaxian.com/archives/forcing-a-ui-redraw-from-javascript), but they all seem to be in conjunction with trying to show actual "permanent" DOM or styling updates, not with temporarily showing a style change while a synchronous request is made.
So is there a way to do this or am I fighting a losing battle? It may be that we'll just need to switch to asynchronous requests on a case by case basis for the worst performing requests, which might be a decent way to tackle the learning curve issue... But I'm hoping there is an outside the box answer here.
Ok for the purpose of this question I will ignore the justification for why you require synchronous XHR requests. I understand that sometimes work constraints don't allow the use of the best practice solution and so we "make do" in order to get the job done. So lets focus on how to get synchronous ajax with visual updated working for you!
Well considering you are using jQuery for your XHR request, I'm going to assume its ok to use jQuery to show/hide the loading indicator and to handle any timing issues.
First let's set up a loading indicator in our markup:
<div id="loading" style="display:none;">Loading...</div>
Now lets create some javascript:
// Show the loading indicator, then start a SYNCRONOUS ajax request
$('#loading').show().delay(100).queue(function() {
var jqxhr = $.ajax({type:"GET",dataType:"json",url:"www.yoururl.com/ajaxHandler",async: false}).done(function(){
//Do your success handling here
}).fail(function() {
//Do your error handling here
}).always(function() {
//This happens regardless of success/failure
$('#loading').hide();
});
$(this).dequeue();
});
First, we want to show our loading indicator and then give the browser a moment delay to repaint before our syncronous XHR request gets started. By using jQuery's .queue() method we are putting our .ajax() call in the default fx queue so that it won't execute until after the .delay() completes, which of course doesn't happen until after the .show() completes.
The jQuery .show() method changes the target element's CSS display style to block (or restores its initial value if assigned). This change in CSS will cause the browser to reflow (aka "redraw") as soon as it is able. The delay ensures that it will be able to reflow before the ajax call. The delay is not necessary in all browsers, but won't hurt any more than the number of milliseconds you specify (as usual, IE will be the limiting factor here, the other browsers are happy with a 1ms delay, IE wanted something a little more significant to repaint).
Here's a jsfiddle for you to test in a few browsers: jsfiddle example
Why do you think:
doSomethingBeforeRequest();
response = synchronousAjax();
doSomethingToTheDataAfterRequest(response);
that much "simpler" than:
doSomethingBeforeRequest();
properAjax(onSuccess(response){
doSomethingToTheDataAfterRequest(response);
};
for your team? I'm not trying to argue, but I'm seriously curious of the justification...
The only benefit of the synchronous code i can think of is that you save a few curly braces; at the cost of freezing the browser.
If the browser doesn't complete the repaint before the request*, the only option I can think of is using a delay (as BenSwayne suggests); which would make the code as complex as the async call, and still make the browser unresponsive during the request.
EDIT (some kind of an answer):
Since JavaScript lacks threads; timeouts and ajax calls (that allows the browser to do something else before it's run; somewhat like sleep() in a threaded language is used ), is fairly fundamental to how you program JavaScript. I know it can be a bit of a learning curve at first (I know I was confused), but there is not really any sensible way to avoid learning it.
One situation I know people may be tempted to make synchronous calls is when several requests have to be made to the server in sequence; but you can do that asynchronous too, by nesting several calls like this:
doSomethingBeforeRequest1();
ajax(onSuccess(response1){
doSomethingToTheDataAfterRequest1(response1);
ajax(onSuccess(response2){
doSomethingToTheDataAfterRequest2(response2);
};
};
But unless each call is fairly slow to finish and you want to indicate progress at each step or something; I would rather recommend that you create a new service to combine the two operations with one call. (This service could just use the two existing services in sequence, if you still need them separately in some other cases).
(* I'm more surprised that Firefox DOES update the dom...)
I've maded some tests and came with some points:
http://jsfiddle.net/xVHWs/1/
Change your code to use jQuery's hide(), show() or animate({ opacity: 'show' }, 'fast') and animate({ opacity: 'hide' }, 'fast')
If you leave de functions without a time param or specify a 0 ms time, Firefox will show the overlay and hides it, the other browsers execute it to fast for you to see. Put a 100 millisecond in show, hide, or animate calls and you will see it.
$.ajaxSetup({async:false});
busyMask.className="Shown"; //display=block; absolute positioned full screen semi-transparent
var dta=$.ajax({type:"GET",dataType:"json",url:url}).responseText;
busyMask.className="Hidden"; //sets display=none;
$.ajaxSetup({async:true});
I am currently involved with an Application where I need to design the UI part of the Application and current I am in the process of implementation of UI which would be displayed to end user while his or her request is being processed behind the scenes.
So my question is that:
What is the best UI approach/symbol/suggestions to be displayed to end User while his or her request is still being processed behind the scenes ?
Thanks.
Any sort of throbber is adequate enough. Here's a nice throbber generator you can use.
And there's nothing wrong with progress bars, unless there the kind of progress bars that start over without actually indicating progress.
If you don't take your program too seriously, this one is always a crowd pleaser:
This is going to take a while, so to pass the time, here's a dancing bunny:
http://img251.imageshack.us/img251/4828/thdancingbunny.gif
A Loading screen of some sort may work.
It depends on how long your user must wait. If it will be <10 seconds, then just show the spinning pie of death as an animated GIF (or flash if you prefer to be non-accessible) (a simple jquery hide/show with CSS)
If it is a longer wait, like >10 seconds, you may want to implement a short but entertaining caption system. Something like the old "Reticulating Splines" type system to give the users a bit of humor while they wait.. see https://stackoverflow.com/questions/182112/what-are-some-funny-loading-statements-to-keep-users-amused for a list of such statements.
If you've got a long running background process, I'd simply display a progress bar with a message below it that states in the least technical terms possible what the current task is. And then, if possible, a cancel button in case the user gets impatient or mistakenly started the process.
I can't provide any specific links to back me up, but I believe its been proven that just the presence of a progress bar can make a longer task seem shorter than a task without the progress bar.
The worst thing you can do is nothing. Users have been conditioned to think that no feedback = locked up program.
Note on typical implementation (that I use):
jQuery has the .ajax function. When I call the function (onClick or whatever) I .remove() the contents of the (div or whatever seems appropriate) and add a css class of waiting which looks like:
.waiting {
background-color: #eee;
background-image: url('some-spinner.png');
}
the .ajax function has a success callback where I remove the .waiting class and put in the new data I got back from ajax (or put back the data I took out with .remove().
Additionally you may change default mouse cursor to wait or progress states with CSS.
Details about changing cursor with CSS here.