WPF browser: how to wait till a page loads - c#

I have a problem with WPF browser. i want to load a web page.
Wait for it load completely and then put few search inputs and then retrieve the result and put it in excel.
I am unable to do so, main program loads and completes the execution before the pagecomplete_event is loaded. The scenario is:
load a component provider website
go to the search option and search for the part number which I am reading for a EXCEL file
put the part number in the search bar and click search
download the details
repeat the steps for MANY parts
I have done this with WinForms, and it works well. The problem is calling DOEVENTS. It sometimes makes my program hang, especially if operating on a big list. So wanted to do it in WPF.
I have put the Load_Complete event, but as I mentioned, it comes to that event after the main program has finished.
I searched and got this link: How to create and use WebBrowser in background thread. But it doesn't seem to help - there seems to be no System.Windows.Deployment in WPF - I get red squiggly underline. No other solutions that I have found seem to help, either.

This was troubling me for some time, and finally found the solution. Now I'm fairly new to vb.net so this may not be the best way, but it did work. This is in vb.net, you could probably easily convert to c#.
AddHandler (webbrowser1.LoadCompleted), AddressOf WebpageLoaded
webbrowser1.Navigate("http://www.myWebsite.net/admin/")
This creates an event that triggers the WebpageLoaded sub.
I used this to wait for the page to load and then login to my account.
Here is how I did that.
Private Sub WebpageLoaded()
If webbrowser1.Url.ToString = "http://www.myWebsite.net/admin/" Then
webbrowser1.Document.GetElementById("username").ScrollIntoView(True)
webbrowser1.Document.GetElementById("username").SetAttribute("value", "myUsername")
webbrowser1.Document.GetElementById("password").SetAttribute("value", "myPassword")
End If
End Sub
I do hope this helps. You probably don't need to ScrollIntoView I just used this to see the progress as I finally got it to work.

Related

Coded UI - Programmatically check if control is blocked?

Is there any way to check if a control is blocked before acting on it? I'm having an issue automating a silverlight application. Certain controls in a table intermittently appear as blocked when playing back when other times they can be accessed. There does not seem to be any reason for the blockage because it works more often than not. I've tried adding wait statements, I've tried both hand coding the control reference and recording it, I've even tried accessing other parts of the cell and tried tabbing to the cell... it just occasionally appears to be blocked.
To make things trickier, the control only appears to be blocked during playback. If I run in debug mode, the control is always visible.
There are a number of WaitForControl... methods that may help. See also On Document Ready equivalent

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

Process.StandardOutput.ReadLine() not "syncing" properly

I've tried to read up on a few articles about this, but some of them were over my head at the moment.
I run a program that re-caches some SQL data from an external source. I call this from a WinForm application which manipulates the aforementioned data.
While the Console app is running, I lay over the controls with a panel (with a textbox on it) and try to capture the Console app's stdout into the textbox. It "works", but has some issues with repeating lines and missing lines. Reading the stream after the process ends works fine, but I'm having issues with real-time.
CODE
It worked well for me in asynchronous way. Unfortunately I'm not so familiar with .net to write code from my memory...
Upd:
Spent a couple of minutes and found the page in MSDN. Use Process.BeginOutputReadLine Method, here is the description of the function and a sample of its usage.

C# Label not showing at loading screen

In an application that I'm writing I have to load a lot of data in a listview after I push a certain button. Because this might take a while, I want to show a simple loading-screen to the user.
I did this by creating a very simple form with 1 label on it. I do a Form.Show() before I start fetching the data, and a Form.Close() once it's finished. This works partially: I get the loading screen, it closes at the right time, but as you can see the label isn't displayed.
I know I should program this loagind screen-problem with the help of a BackgroundWorker, but I'm not a very experienced C# programmer so if I could just somehow force the label to display I would be more than happy.
Is it possible to force this label to display immediately, or do I have to find another solution?
The UI Message pump has no time to update the label / refresh the screen since the loading process takes up all resources.
You can try to force the update of the label, by calling Application.DoEvents(). Although, using 'Application.DoEvents' is imho a 'code-smell', and thus indicates that the design is not that good. So, it should be avoided.
Therefore, using DoEvents is surely not the best solution to this problem. It is merely a symptom-fix.
You've mentionned the best solution already yourself: use another thread to load all the data. (You can indeed use a BackGroundWorker for this purpose, since this will abstract away a lot of plumbing code).
BackgroudWorker is very easy to use , even c# is very powerful and simple langugage
See Here
i am almost sure that , you would not need any more help with BackGroundWorker but if you have any query , you canm always post on SO ?? Collabartive Intelligence is what SO is?

reload the sourcecode of a C# app on command

i have a C# application, and id like to be able to make a system, so that within the program, you can display the sourcecode of the application. easy enough so far right?
well, i need them to be able to edit that code, almost like the debug break option... then load the new code and continue without stopping the program. so my problem is, that when this app loads its several thousand lines of code, and it takes a good block of time. after its loaded, it needs to do several hundred operations before allowing user input the first time it loads. also, it has a tcp client in it, and it is very important that it does not get disconnected.
i want people to be able to edit the source, click a button, and wait a few seconds, and have the new code inserted and "rehashed" so to speak, without having to break the overall function of the application.
im looking thorough code examples where possible and an input weather this is possible or not
~ thanks
If you want to allow people to make arbitrary changes to your program, that would be very complex. However, if you want to let them change specific behavior (like rewriting a calculation algorithm) you could have a look at Microsoft.CSharp.CSharpCodeProvide as discussed here.
I don't think you can do that (change a .net app without rebuilding it) but you can have dynamic code loaded and run at any time..
Some people use plugins with Boo, people can change the plugins and these can be loaded at any time by the main app.
But I would suggest you have a look at the Ruby usage inside SilverLight..
This is something completely different, but its something I'm reading on how to start playing with Dynamic code handling: here

Categories

Resources