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
Related
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.
There's a certain website I need to access multiple times each day that requires me to enter my login name/password first, every time. To save some time, I copied-and-pasted the HTML source code and pre-populated the text fields with my info, then saved that to my desktop. Now I can just open that doc in my browser and click "submit" without having to type anything.
I'm wondering if I can go a step further. Whatever data is sent when I click "submit" — I'd like to start with that step.
From what I understand, the form info is converted into a POST request and sent to the web server. Is there some way I can concoct that request manually (without using their login screen) and then execute that request each time I need to access the site?
Thanks!
wow, what a safe site! Anyhow yes you could do this lots of ways. Not a good idea to transmit tho locally. Have you ever just tried using one of the form auto forms plugins for FireFox? one button and it will populate your form for you.
https://addons.mozilla.org/en-US/firefox/addon/autofill-forms/
I assume you want to do this in an active browser because you want to be able to interact with the site after logging in, correct?
A really simple way to do this and end up with a workable browser might be to try using WatiN. The library itself is generally used to automated in-browser testing. But at the hear of it, that's kind of what you're doing here. You just want an executable that will open a browser, navigate to a page, populate a form, submit, and present the result.
This isn't so much from the perspective of crafting the POST request manually, but rather just automating the UI interaction.
Ultimately, though, it's going to be a matter of testing it for what your user experience is like. Does it take longer than you want? Does it leave the application running in the background unnecessarily? etc.
Honestly, this might really be overkill. Browsers have form auto-population these days. Maybe a browser plugin to take advantage of that instead? How transparent does it need to be?
I have an ASP.NET (C#) page that has a long load time (like 2 minutes). The user is presented with a little animation and a "please wait" message. If the user accidentally loads this page, they need to wait for it to load.
My question is: Is there a way to stop the page load?
Thank you
If you want to stop the server side processing then its a tricky operation. Generally once a request is made that page is rendering on its own independant of other thigns going on. What you would probably need to do is re-engineer that page to check at regular intervals whether a stop command has been issued and abort whatever it is doing at that point. The stop flag could be put in session and should be cleared out after the stoppage.
You may also need to consider how to properly identify the right one to stop (in case there is more than one running). This could be done by returning a unique ID that can be used in part of a call to the "abort" page.
My approach though rather than this complciated rigmarole is to make efforts to stop the user from making this accident. Possibly make whatever link they are clicking pop up an alert saying "the following page will take several minutes to render, do you wish to continue" and then hopefully you will effectively be aborting the page request before it is even made.
I should note that I've never tried to do this sort of thing before so there may be easier ways to do it but this is how I'd probably think abotu going about the problem.
Try window.stop() in JavaScript.
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?
I'm working on a web application import program. Currently an admin user can upload a formatted csv file that my page will parse. I'm experiencing an execution duration issue as each line pertains to a file that has to be saved to Scribd, S3, as well as some internal processing.
What would you guys recommend for improving execution time? Since this is an admin only page, I doubt it would get run more than once a week, so my hope is to get it out the door asap.
I've looked some at the Async="true" flag, but I wasn't sure if that was the direction I wanted to go, or if I should look more that a windows server.
Two options come to mind:
Threads: In your code setup a collection of threads, join them and then have each one process a single file. Once all the threads complete you'll be able to return the page. This will increase your turn around time, but could still leave something to be desired on page returns
Queue: Have the user submit the csv file and provide a GUID/Hash/Whatever ID where the admin could then go to the "status" page, input their ID and check the details of their job. This solution will provide a quick feedback to the user and allow them to keep track of the results without having to wait around.
A quick and dirty option might be to set Page.Server.ScriptTimeout to a really high value on that page. (I think it maxes at Int.MaxValue).
Probably advisable to block the submit button after its been clicked, and inform the user that they may want to go make a coffee.
I'd suggest using AJAX to have an internal post back occur that would handle the asynchronous processing. You can periodically poll the state, and prevent your master page from having the "processing" wheel constantly churning on the page for the lengthy process.
I have a web page that takes a long time to process a mailing list so I kick it off in it's own thread. When the process is done, a report can be seen from another link on the result page. I have a runable MailSender class. The ASPX script has a bit in it that looks like this:
// prep the MailSender
MailSender ms = new MailSender(people, Subject, FileName....);
if (SendAsync) {
ThreadStart ts = new ThreadStart(ms.run);
Thread WorkerThread = new Thread(ts);
WorkerThread.Start();
} else {
ms.run();
}
If you want to speed your code up, try to break it into parallelizable pieces if you can and write a class for each piece. You could then kick off a new thread for each bit and monitor the status somewhere so the user can be informed when to come back to the results. You said that each line of your input would generate it's own output file. Sounds like a great candidate for multi-threading. Won't speed things up much if you don't have multi-cores availabe on the server though.
One problem with this whole scheme is that server restarts or application pool recycling will kill your long running process. This can be a problem if you threads are going to run for an hour or two.
As external factors are involved in the processing time, you need to consider if performance improvements would affect "actual" performance, if most of the time is in processing it and sending it to the thirdparty (ie Scribd,S3), then making improvements on your end might not have a huge affect and might increase the complexity for a simple task.
What I would do is have the aspx page only doing what aspx does best; ie handling the user interface part only (ie the upload), so once the upload is complete as far as the user is concerned their part is done. You could implement a progress indicator using AJAX to make it nicer but as its an admin section I wouldnt bother with the niceties,
Then have simple console application sheduled to fire at specific intervals, or a windows service watching a directory (depending on how timecritical the updates are), once the app runs as it is in the back ground and does not require user interaction, time is not a critical factor (ie you dont have a user waiting for context to be returned)..
it will appear to the user that things are very snappy (ie the time it takes to upload the file) and you are keeping needless complexity out of your solution.
I think the simplest solution to what you want is to use asynchronous pages in ASP.NET. Is there any particular reason why you don't want to go that route?
I can think of an alternative, which is to have some background process (like a process triggered by a scheduled task in Windows, or a Windows service) that will look at a queue of waiting jobs (say, from a database table) and process those jobs. This way you will have to upload that CSV somewhere and insert a db record so that the background process will see that CSV and use it when it comes around. But to me it seems like more work, so I'd rather use asynchronous pages :)
Here's a nice tutorial on ASP.NET asynchronous pages