Freeze/pause a web page activity to retrieve elements properties - c#

I'm trying to parse data from a page which is constantly updated by JavaScript and Web Workers. I need to get all elements in a list but often when I try to retrieve element properties I receive StaleElementReferenceException because such element was already removed from DOM. Is there a way to temporarily freeze DOM or suspend Web Workers network activity so that I can parse everything without errors?

The Window stop() Method stops window loading and can be used as follows:
((IJavaScriptExecutor)driver).ExecuteScript("window.stop();");

Related

C# How to implement Threading or BackgroundWorker tasks

I can't seem to figure out how to use either the threading or Backgroundworker task. My problem is that I am loading a large XML file into a TreeView and would like to display a progress bar while doing so. The issue right now is that the app freezes when it's loading and says the app is non-responsive.
Threading / Background worker tasks is new to me so I am not exactly sure how to make this work.
First we will start with my button to get the user details
So we get the users's details and call CreateXML for the user detail object. So we have the XML in one big string called strXML. Then I call dom.LoadXml to load xml sting into the dom object. Then we initialize the tree view control and add the nodes etc.
So during this whole process the app hangs and indicates that it's not responding while it's busy churning thought the XML and creating it into a treeview. I want to put in a progress bar so the end user see's that something is actually going on and they don't think the app just died on them.
How would i implement some sort of progress bar with a thread or back ground worker?
Please just don't redirect me to link after link because that never really works for me.
Thanks
I was able to implement multi-threading which then I was able to achieve the progress bar moving while the data was being loaded. Sometimes people need to wait for data to be loaded and a simple indicator is all that's needed so users know the app is working.

WebBrowserDocumentCompletedEventHandler Don't wait for Ajax Async to complete

After reading Dianyang Wu article and this excellent post I managed to build a small .net app (almost a C&P from Wu source code) to automatize tests (let's call it protoTestApp). My final goal is to open a dozen small windows and in each simulate a different user interacting with a web app to stress it.
It works for some extend but after I logon on the web app (let's call it InternalTestSubject) it calls a external url (let's call it ExternalTestSubject) and injects it's content on a iFrame. This particular external url is another web app and it ill look up for the parent window to get some parameters. Opening ExternalTestSubject directly is not a option.
My problem is at my protoTestApp I want to also interact with that ExternalTestSubject (find a button by id, click it, etc) but at my CompletedEvent handler the iFrame is still empty.
The WebBrowser shows both web apps full loaded and working, so I suppose the handler is just not waiting for the iFrame content to load since it's done by a Ajax async call.
Any advice to acomplish it?
I think I explained this in the answer you linked (and in more details in another related answer). AJAX pages are non-determinustic, so there is no generic approach.
Use periodic asynchronous polling to watch the page's current HTML snapshot or DOM for changes, the linked post illustrates how to do that. You can poll the frame's content in the same way.
I can imagine the frame reports to be ready but it actually does not. For instance, the frame contains frames, you have no way to know whether all these frames are loaded by using DocumentCompleted event.
In short: Using a frame to load external stuff and do the testing is not a good approach. Even if you use a timer to check the loading status manually. But according to security considerations, you will have many problems to access the DOM.
I have two suggestions for you:
Create a WebBrowser instance and open external test subject into it. You will have a very good chance to know, whether document (and its frames) have been loaded completely. You still have the full control to access any elements of the WebBrowser or cookies or click elements or change elements.
Use 3rd tool such as Selenium as test driver.
Update 1:
As the questioner does not want any 3rd tool, I'd suggest let the internal test subject query the loading completeness of the target frame periodically. Possible code can be check document.readyState == 'complete'.
So far as I know, as the external test subject is embedded as frame, due to security consideration, you might not able to access the DOM of the frame. In other words, you cannot do mouse clicks, etc., unless you change the security settings for the Webbrowser control first.

asp.net C# ajax running 'async' batch job

I'm quite new to asp.net and C# so bear with me. Also my apologies if this have been asked before... if so please direct me to a page which is of help.
What I have:
A page: With 4 updatepanels
1st UpdatePanel which contains a (item) gridview, user display options (not important to this question) and button which perform a database search which returns a list of items displayed to the grid. User selects an item on this grid...
2nd UpdatePanel contains a dropdownlist containing a list of available task loaded from an XML. User will select a task, which displays a bunch of available options/parameters (also loaded from XML file) to another (parameter) gridview in 2nd updatepanel. Gridview here will always have one row of data. I'm using gridview here because it is easier rather than creating dynamic controls (paramaters are different to each task ). User is able to enter parameter values into the grid. User clicks on an Add button and the the task is added to another gridview in the 3rd updatepanel.
3rd UpdatePanel contains a (task) gridview which contains all the task added by user. There's also a button which is suppose to batch run all the task. When the button is clicked, it goes through the (task) gridview looking for pending task to run. For each pending task, it calls a web service which handles the task appropriately. Web service returns the task result together with log output.
4th UpdatedPanel for now just contains a div that displays the log output returned from web service.
What I want to further work on and not know how is:
how do I perform an 'asynchronous' batch job? What i'm trying to achieve is that, when user clicks on the batch run button, the 3rd (task) updatepanel together with all it's control get disabled while the batch jobs run 'behind the scene'. Depending on the task, each task could take up to 5seconds each. If user had created 60 tasks, I would think this will also cause the page to timeout?
While the batch job is running, user can further search for other items in (item) UpdatePanel and add new tasks using (parameter) updatepanel to (task) updatepanel.
(Task) UpdatePanel will be showing a 'Job in progress...' overlay of some sort when job is running.
Hope you understand my question. Much appreciated if someone could be kind enough to give some guidance and/or directions on how to tackle this task
Further info:
Using Framework 3.5
Using Asp.net C# + Ajax
Web Service is of gSoap on a solaris box
Many thanks in advance.
Sorry for being a noob, i was trying to reply to your help but found that there's a limited of characters i can put in. I'll just update my own comments for now.
Thanks for your suggestion. Sorry for the late response, I've been looking around the other day and had made some changes, getting it to work with 'PageAsyncTask' and 'IAsyncResult'. I've created a web service class which will be called by the page. The new web service class will than called the gSoap web service. I've managed to some sort of running it 'asynchronously'.
I have a button which executes:
protected void StartASyncJob()
{
PageAsyncTask task = new PageAsyncTask(
new BeginEventHandler(BeginAsyncCommandTask),
new EndEventHandler(EndAsyncCommandTask),
new EndEventHandler(AsyncCommandTaskTimeOut), null);
RegisterAsyncTask(task);
}
BeginAsyncCommandTask will go through the grid, get the first pending task and calls the web service.
EndAsyncCommandTask will then retrieve the return results, writes out the (log) UpdatePanel. It will then execute StartASyncJob() again looking for the next pending record to process.
All this works ONLY if don't do anything else on the page.
If I was (while the asynchronous process was running ) to do a search for more items in (item) gridview or select a new task from
(task) dropdownlist, the event will not fire till the asynchronous web service process has completed. And when it's completed, the dropdownlist or search event fires, my log details returned from the web service is not updated.
I guess the 'wait' is caused by 'PageAsyncTask' being 'spawn' from the same page thread?
I would have thought having the 'asynchronous' web service will enable the user to do more than one thing at a time giving better user experience. But it seems I'm wrong and/or have not done it right.
I have not tried your suggestion of using QueueUserWorkItem; but before I do, may i ask if it will give the same effect as using 'PageAsyncTask'. Will using QueueUserWorkItem has the same effect of 'spawning from same page thread' ?
Many thanks in advance. Sorry if i've not explained myself well and please do let me know if you need me to post my code.
there are a few solutions, but depends on how much control you have on the server.
If you have full access control to server, you may create a separate application which will take care of the Tasks; the application can be a Windows Service, and the communication between your page and the application would be either a database or MSMMQ (the communication mainly means the list of the Tasks and their states - 1. to be executed, 2. executing 3. finished).
Another solution is in case you don't have full access control to server, but it will require to implement some communication between threads. Instead of having the application I described at point 1. you can have a separate thread, which can be started this way:
System.Threading.ThreadPool.QueueUserWorkItem(foo => LauchTaskRunner());
Suppose you implemented a method called LaunchTaskRunner which in a loop just processes the list of existing Tasks, the above line will start it into a separate process. You can communicate with this method (which is running in a separate thread) through some static variable (declared in the page), e.g.:
public class YourPage : System.Web.UI.Page{
static IList<Task> tasks;
static void LauchTaskRunner(){
// here make use of tasks variable
}
}
Everytime the (tasks)updatepanel gets refreshed, it should render based on tasks variable.

Loading content from an xml file using a background thread?

I've run into a situation with loading content from an xml file. Basically there can very well be hundreds of items in one of these xml files at a time. Now when I navigate to a page I have to databind these objects to a listbox control and display them to a user. Now I was using the OnNavigatedTo Event and was loading the content using LINQ. The problem was as more items were added to the xml file, the page started taking longer to load.
Then I waited until I navigated to the page and it was displayed to call the xml file, but the UI became unresponsive for about a second and a half.
So the thought that came to my mind was to see if there was someway to load the xml file on a background thread so that it doesn't affect the UI. Is this possible, and if so can you point me to a resource where I can get some more info.
BackgroundWorker is exactly what you need: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
Basically, it executes the DoWork method in a background thread, then executes the WorkerCompleted method where you can update the UI with the result of the calculations.

delay loading of a silverlight page

How would i go about delaying the total load of a SilverLight Page? I take a parameter out of the querystring on the page load of a Silverlight web page, and then send it to a web service boolean function to process. The result of the return value is used to determine whether to fully load and display the page, or direct to another page. The system works pretty much fine, however when the result from the web service returns, even if it is decided that i need to navigate away to another page, it still displays the initial page for a very short time. How can I stop this brief showing of the initial page?
Take a look at this article: http://www.codeproject.com/KB/webservices/CodeOptimizationTechnique.aspx
The point is that you must not do anything until you receive the data back from the webserice. When you receive it only when you can send the user to the right side, and remember also to consider that maybe you do not get a response from the server sometimes.

Categories