J'essaie de créer un programme pour cloner plusieurs bogues à la fois via l'interface Web de notre système de suivi des défauts. Comment puis-je attendre avant qu'une page soit complètement chargée avant de continuer?
//This is pseudo code, but this should give you an idea of what I'm trying to do. The
//actual code uses multi-threading and all that good stuff :).
foreach (string bug in bugs)
{
webBrowser.Navigate(new Uri(url));
webBrowser.Document.GetElementById("product").SetAttribute("value", product);
webBrowser.Document.GetElementById("version").SetAttribute("value", version);
webBrowser.Document.GetElementById("commit").InvokeMember("click");
//Need code to wait for page to load before continuing.
}
Essayez l'événement DocumentCompleted
webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser.Document.GetElementById("product").SetAttribute("value", product);
webBrowser.Document.GetElementById("version").SetAttribute("value", version);
webBrowser.Document.GetElementById("commit").InvokeMember("click");
}
Ce code m'a été très utile. Peut-être que ça pourrait aussi être pour toi
wb.Navigate(url);
while(wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
MessageBox.Show("Loaded");
La meilleure façon de le faire sans bloquer le thread d'interface utilisateur est d'utiliser Async et Await introduits dans .net 4.5.
Vous pouvez coller ceci dans votre code, changez simplement le navigateur en nom de navigateur Web. De cette façon, votre thread attend la page à charger, si elle ne fonctionne pas à temps, elle cesse d'attendre et votre code continue de s'exécuter:
private async Task PageLoad(int TimeOut)
{
TaskCompletionSource<bool> PageLoaded = null;
PageLoaded = new TaskCompletionSource<bool>();
int TimeElapsed = 0;
Browser.DocumentCompleted += (s, e) =>
{
if (Browser.ReadyState != WebBrowserReadyState.Complete) return;
if (PageLoaded.Task.IsCompleted) return; PageLoaded.SetResult(true);
};
//
while (PageLoaded.Task.Status != TaskStatus.RanToCompletion)
{
await Task.Delay(10);//interval of 10 ms worked good for me
TimeElapsed++;
if (TimeElapsed >= TimeOut * 100) PageLoaded.TrySetResult(true);
}
}
Et vous pouvez l'utiliser comme ceci, avec une méthode asynchrone ou un événement de clic de bouton, faites-le simplement async:
private async void Button1_Click(object sender, EventArgs e)
{
Browser.Navigate("www.example.com");
await PageLoad(10);//await for page to load, timeout 10 seconds.
//your code will run after the page loaded or timeout.
}
Découvrez le projet WatiN :
Inspiré par Watir , le développement de WatiN a commencé en décembre 2005 pour rendre possible un type similaire de test d'application Web pour les langages .Net. Depuis lors, WatiN est devenu un framework facile à utiliser, riche en fonctionnalités et stable. WatiN est développé en C # et vise à vous apporter un moyen simple d'automatiser vos tests avec Internet Explorer et FireFox en utilisant .Net ...
La méthode de tâche a fonctionné pour moi, sauf que Browser.Task.IsCompleted doit être remplacé par PageLoaded.Task.IsCompleted.
Désolé, je n'ai pas ajouté de commentaire, car j'ai besoin d'une réputation plus élevée pour ajouter des commentaires.
le code yuna et bnl a échoué dans le cas ci-dessous;
exemple manquant:
Le 1er attend la fin. Mais le 2ème avec le membre invokem ("soumettre") ne l'a pas fait. invoquer des œuvres. mais ReadyState.Complete agit comme son Completed avant sa VRAIMENT terminée:
wb.Navigate(url);
while(wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
MessageBox.Show("ok this waits Complete");
//navigates to new page
wb.Document.GetElementById("formId").InvokeMember("submit");
while(wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
MessageBox.Show("webBrowser havent navigated yet. it gave me previous page's html.");
var html = wb.Document.GetElementsByTagName("HTML")[0].OuterHtml;
comment corriger cette situation indésirable:
usage
public myForm1 {
myForm1_load() { }
// func to make browser wait is inside the Extended class More tidy.
WebBrowserEX wbEX = new WebBrowserEX();
button1_click(){
wbEX.Navigate("site1.com");
wbEX.waitWebBrowserToComplete(wb);
wbEX.Document.GetElementById("input1").SetAttribute("Value", "hello");
//submit does navigation
wbEX.Document.GetElementById("formid").InvokeMember("submit");
wbEX.waitWebBrowserToComplete(wb);
// this actually waits for document Compelete. worked for me.
var processedHtml = wbEX.Document.GetElementsByTagName("HTML")[0].OuterHtml;
var rawHtml = wbEX.DocumentText;
}
}
//put this extended class in your code.
//(ie right below form class, or seperate cs file doesnt matter)
public class WebBrowserEX : WebBrowser
{
//ctor
WebBrowserEX()
{
//wired aumatically here. we dont need to worry our sweet brain.
this.DocumentCompleted += (o, e) => { webbrowserDocumentCompleted = true;};
}
//instead of checking readState, get state from DocumentCompleted Event
// via bool value
bool webbrowserDocumentCompleted = false;
public void waitWebBrowserToComplete()
{
while (!webbrowserDocumentCompleted )
{ Application.DoEvents(); }
webbrowserDocumentCompleted = false;
}
}
Essayez Selenium ( http://seleniumhq.org ) ou WatiN ( http://watin.sourceforge.net ) pour vous épargner du travail.
while (true)
{//ie is the WebBrowser object
if (ie.ReadyState == tagREADYSTATE.READYSTATE_COMPLETE)
{
break;
}
Thread.Sleep(500);
}
J'ai utilisé cette méthode pour attendre le chargement de la page.
Si vous utilisez l'objet COM InternetExplorer.Application, vérifiez la propriété ReadyState pour la valeur 4.
Je pense que l'événement DocumentCompleted du contrôle WebBrowser devrait vous amener là où vous devez aller.
En supposant que l'élément "commit" représente un bouton d'envoi de formulaire standard, vous pouvez attacher un gestionnaire d'événements à l'événement WebBrowsers Navigated.