Waiting for page to be fully loaded using WatiN - c#

I have two questions related to the same problem...
Q1) I am using WatiN(3.5) for automation of a website.
The situation is that I want to obtain a div tag when the result page is fully loaded but WatiN don't wait for that page to be campletely loaded and tries to obatin that div which results in getting div with null. This div is populated by AJAX. This is th code that I am using to avoid that error but it does not work.
while (resultDiv == null)
{
browser.Div("ui-tabs-1").WaitUntilExists();
resultDiv = browser.Div("ui-tabs-1");
}
So how I can wait for a page to be completely loaded by using WatiN?
Q2) I found a solution for above problem here but I stuck at a point as I could not find a reference of library for these interfaces i.e. IElement and IBrowser. These interfaces are bring used in the extension methods.
I have also asked the author of that article and waiting for his reply.
I am making this apllication by usng WatiN 2.5 and .Net framework 3.5 in VS 2010.

I have ran into similar problem with watin on a site using Ajax.
This is the workaround for this.
//After click on link/Tab/Button on which the result is loaded in non Ajax websites.
We have a function here, browser.WaitForComplete() but it works only when the page is in loading state. but in case of Ajax on a part of browser window gets updated. so no loading state for browser.
So one solution for this problem is
Use Thread.Sleep(10000); This time can vary upon the normal time the website takes to load the required div.

Thread.Sleep can be used but for anything other than a proof of concept that waiting for something to load is indeed the issue Thread.Sleep should be avoided. Sleeps add in unnecessary idle time if you sleep for the max time the action is going to take, and give false positive failures when waiting less time.
See Jeroen's link in his response here if you are testing an ASP.NET Ajax site: In WatiN how to wait until postback is complete - WaitForAsyncPostbackToComplete. I used this idea for some methods and properties to rid my code of a lot of long Sleep calls. Tests ran faster and results were much more reliable.
If the specific JS call won't work as you're using a different clientside framework, using the basic polling concept with shorter sleeps in a loop is going to do you better than long sleeps.

Related

Why is Selenium + Firefox freezing while loading pages?

I'm running the latest version of Firefox and Selenium in C#. I'm automating a crawler to find data in a web app. The server is super slow, so I've had to add in many waits plus put in initial wait using thread sleep.
So my crawler gets a list of items, then iterates: it has to load the details of each item by clicking on its id. Then it goes back (these navigation controls are all built into the web app, no browser controls used), rinse and repeat. The server shows a progress spinner during loading details and going back. The crawler reaches the same item each time and locks, eg: the progress spinner freezes and Firefox crashes.
I've tried a couple of different things including using background threads, deleting all cookies, and checking if my memory is overloading. I haven't noticed any peaks in memory (in task manager). I also tried restarting web driver but it doesn't really work out well because this is a web app.
Is there something I'm overlooking? (I tried to be as clear and elaborate as possible)
Forgot to mention, when I stop the program the page 'unfreezes' and I can continue use from that point.
This was a known problem with C# selenium web bindings 2.39 and earlier. This should now be fixed in 2.40. The problem was to do with a deadlock in the web bindings code when redirecting console logging from firefox. If you upgrade to 2.40 it should solve it. See here under the heading 'Update 25th Feb 2014' for more information.

Issues in automation framework for web page testing

Currently I am in process of building an automation tool for testing webpages. Already aware of selenium tool but will not be using that currently as our framework has already been built and requires minor changes to make it reliable. While testing this framework with test pages (html and javascript only) I encounter issues such as webpage takes a lot if time to load(happens like 1 out of 20 times). And when you try to find the co-ordinate and click the button or try to find the element in the webpage and click it sometimes it fails as button doesn't even exists at that point of time.
Currently using Thread.sleep or retry n number of times. Are there any better solutions to remove this flaky behavior?
look into WebDriverWait class. There is a respective binding for c# as well. Also, I have discussed the WebDriverWait here.
You can try to use Implicit waits
Read about it here http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp
Basically you set it once per session. If you can't find an element, selenium waits the amount of time you set before throwing the exception.

How to wait for the post back in Watin?

In my C# code, I am using Watin to navigate the web, to log in to a page, I need to click the log in button, but right after I want to log out, so I have the click log out button right after, but the log out part doesn't work. I even tried closing the browser (using the close method) after logging in, but it didn't work. It feels like as soon as the page gets changed (i.e. after logging in) no more commands from the c# will work.
Does anyone know whats wrong?
As mentioned in another answer Thread.Sleep(milliseconds) is a way to wait for a time period for something to load. Very, very easy to implement, but it is far from optimal due to varying load times, and if you make it long enough so that it will always wait long enough you'll end up with a lot of wasted time. On one test this is not a big deal, but for instance if you have to wait 5 seconds and you have 1000 tests.... etc etc etc.
The route I've gone is:
Put in Thread.Sleep()s to determine if it is a "wait" issue.
If the the code with the Sleep() is going to be used more than once figure out what is causing the need for the sleep().
Refactor out the Sleep() using various Wait...() methods. WaitTilExists, WaitForAttributeEqualsWhatever, WaitForAsyncToFinish <- Not real methods, but WatiN has a bunch built in
The big cause of waits for me now is JQuery asynchronous calls in ASP.NET and I made a static helper class that works well for me to wait for async calls to finish. These tend to be very specific to what framework(s) the sites you're testing are written in.
The watin click command wait until the browser is loaded so practically it wait for the postback.
In case if you using ClickNoWait() command it will not wait.
So if your code looks like this it should work:
browser.GoTo("www.your-site.com");
// fill user/pass
browser.Button(Find.ByClass("login-class")).Click();
browser.Button(Find.ByClass("logout-class")).Click();
In case it's still not working you can add this after login click browser.WaitForComplete();
In Watin you will encounter many situations where the code is non blocking (you'll execute a line of code and will immediately keep going) so for those cases you'll need to find a different way to know that the next page (action, etc.) is already there. For example, on a login page you could check if that pages has a TextBox called UserName:
<code>
TextField uName = browser.TextField(Find.ByName("userName"));
if(uName.Exists)
{
// Then do the login code....
}
</code>
In the same way you should control that the page after the login is there before you keep going executing your code. So for example, if you are logging in into a page that you know that will contain the text: "Your Account Details" you might do something like this:
<code>
browser.GoTo("http://www.yourdomain.com/login.aspx");
//do your login code
browser.WaitUntilContainsText("Your Account Details", 240); // the second parameter indicates the seconds it will wait before it times out.
// your code to deal with the page after the login.
</code>
Using Thread.Sleep is a recipe for confusion and that's a problem for sure, you will NEVER get the timing right with a web page (even if you think it will take 10 seconds it might never come back and at that point the server will be terminating the opened connection).
Hope it helps.
Use Thread.sleep in your scripts to sync with logout and login...
or
instead of logout you directly close application and use ie instance to relogin to application

How can i automatically have a page save the current time to the DB in 5 minute intervals w/o postback?

Basically i have a C# Web App where a user views a streaming video. While they are viewing it, i have a timer running in the code behind. When they finish viewing the video, they hit a submit button which takes the difference from the start time and end time and emails the total viewing time to me.
The issue is, if they lose their session or their internet connection drops out for a brief moment, the time is lost and i have no proof how long they viewed the 1.5 hour video for.
I was wondering where to start to have it automatically save the time to the database like every 5 minutes behind the scenes without it affecting the streaming video or posting back, that way they have record of how much viewing time there was up until they lost connection.
We used the information from this blog post to accomplish it in our apps. There are code samples that show exactly how to do it. Adjust the
window.setInterval('SaveUserInput()', 10000);
line as needed to change the interval.
You could store the start time in a hidden field when page loads, and then use javascript to post to a webservice at a set interval with the start time.
One option would be to setup an ajax call to talk to the server on an interval to say "I'm still here" - if your ajax call sends a video ID or some other type of session identifier, it can update your database with the appropriate time.
I'd suggest looking into using jQuery for this along with [WebMethods]. It makes it quite simple to accomplish. Here's a nicely written article that talks about how to accomplish it with asp.net: http://dotnetslackers.com/articles/ajax/Using-jQuery-with-ASP-NET.aspx
You say "without a postback" - but does that mean a whole page postback? Otherwise it should be pretty easy to make an AJAX call back to the server from some JavaScript. You could use the JQuery library to easily make the call. Here's a pretty good page discussing how to call a page method from JQuery: http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/
Suggestions to use JQuery or other AJAX library to make ajax call every 5 min are good but if you are new to this, you can use the asp.net ajax extensions Timer object (Toolbox->AJAX Extensions->Timer). its not hard to use, it follows a typical event driven model like other ASP.NET controls

run asp.net function when The page is closing

I have an asp.net page
when Loading this page it creates a Thread to do some thing
My Question is :
How to kill this thread when the user close the page ?
I have tried with "onUnload" event
but it just works with javascript function (as I know)
and we can't use asp.net code in javascript function
Do You have a way to help me ...
thanks a lot
Edit:
It 's difficult to explain what I am Trying to do.. The asp.net page must show a message to the user and this message must appear directly without refreshing so I was trying to use a thread which listen wait the message and then run an AJAX code to show the message ..
You can't. The browser and the codebehind (the C#) live in different worlds, and once the Page Lifecycle completes (shortly after RenderComplete), the server is done with the request.
It sends the generated HTML to the client and never looks back.
In the onunload event in javascript, you could send an AJAX request to the server to tell it that the user is leaving the page, but that would be highly unreliable, and if you depended on that exclusively to kill threads you would have a major problem on your hands.
Generally, what you're trying to accomplish would be better accomplished another way - so as others have said, let us know what you're trying to do and we'll give suggestions.
You can do this with PageMethods which works with Ajax
First you catch the onunload event on your script page :
body onunload='javascript:PageMethods.UnloadForm();'
then u enable PageMethods on the scriptManager AJAX you have to add to your page :
asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true"
runat="server"
after, you create your PageMethods Code-behind method in C#:
[System.Web.Services.WebMethod]
public static void UnloadForm()
{
// your stuff
}
Hope this will help you.
My actual pb is that Onunload event is generated without closing my page cause of an AJAX timer. But if you don't add a timer, you shouldn't have this pb.
There is no request sent when the page is closing, so right out of the box, the answer is no. However, you have a few options.
One is to send an XmlHttpRequest (Ajax call) from the javascript onUnload event to a WebMethod.
Another is to execute code at the next beginning of the next pageload, which would cover cases besides those in which the user leaves your site for another or closes their browser.
Finally, there are server-side events you can use for, say, session expiration.
What is it exactly that you're trying to do? Maybe we can help come up with a better way to accomplish it.
Just curious: what kind of threaded process are you running? To your question, the only place you're going to be able to capture the event of the browser being closed is in Javascript... you could make an ajax call back to the server to kill whatever thread you've got running for the session, but as others have said, this isn't reliable.
In short there's no direct way to do what you're wanting to do. The best you could hope for is to hook the Sesion_OnEnd event.
It is a poor coding practice to start a worker thread that is dependent upon a page closing for its cleanup as you have little control over what happens on the client browser. Perhaps you could re-think the architecture of this, or at least expound on what this worker thread is actually doing so a better solution can be recommended for that.
If the work that the worker thread is set up to do has a clear path to code completion, the garbage collector will handle the cleanup and there is no cause for concern. If your using a thread from the thread pool to perform your background task via the QueueUserWorkItem construct, then the thread will make itself available for use again in the pool once the work is completed, and you have nothing to worry about as long as you ensure proper disposal of unmanaged resources if any.
As Mike pointed out in a comment, you should really set up a web service that some JavaScript on the page can poll periodically - this would then go and interagate the queue, check for messages, and if it finds one, display a message to the user.
This site has a function very similar to that when you are answering a question - it has a "Heartbeat" javascript call that polls the server looking for new answers - if it finds some, an orange message bar appears at the top of the page telling you there are new answers, and would you like to view them?

Categories

Resources