2011-09-21 17 views
10

Sto provando a provare il download del file con Watin 2.1.0 contro IE9. Ho usato il codice suggerito dalla risposta accettata alla domanda Downloading a file with Watin in IE9, in questo modo:Come testare il download del file con Watin/IE9?

var downloadHandler = new FileDownloadHandler(fname); 
WebBrowser.Current.AddDialogHandler(downloadHandler); 
link.ClickNoWait(); 
downloadHandler.WaitUntilFileDownloadDialogIsHandled(15); 
downloadHandler.WaitUntilDownloadCompleted(200); 

Tuttavia, i tempi di chiamata downloadHandler.WaitUntilFileDownloadDialogIsHandled(15) fuori. Cosa dovrei fare?

+0

Prova ad aspettare più a lungo? Per un file di grandi dimensioni, la finestra di dialogo Download del file potrebbe richiedere del tempo. 15 secondi non sembrano abbastanza lunghi –

+0

@Jeremy McGee Il file è molto piccolo e ho verificato che la finestra di dialogo del download appaia. L'ho persino cancellato manualmente e WaitUntilFileDownloadDialogIsHandled è ancora scaduto. – aknuds1

+0

Provate a usare DialogHandlerHelper per identificare cosa WATIN pensa che la finestra di dialogo di download di IE9 sia effettivamente, poiché mi sembra che il dialogo di download di IE9 non contenga i criteri utilizzati da WATIN per trovarlo. –

risposta

8

IE9 non utilizza più una finestra di dialogo per il salvataggio dei file. Invece, utilizza la barra di notifica per impedire che l'attenzione venga rimossa dal sito web. Vedere http://msdn.microsoft.com/en-us/ie/ff959805.aspx in "Download Manager" come riferimento.

Sfortunatamente, ciò significa che l'attuale FileDownloadHandler in WatiN non funzionerà. Crea un'istanza di una classe "DialogWatcher" per istanza del browser che è un pump di messaggi di base per qualsiasi tipo di finestra secondaria. Quando vengono rilevate finestre secondarie, DialogWatcher controlla se la finestra è specificamente una finestra di dialogo (che non è la barra di notifica). Se si tratta di una finestra di dialogo, quindi itera su istanze IDialogHandler registrate che chiamano "CanHandleDialog". Anche se la barra di notifica era una finestra di dialogo, è di un diverso stile di finestra (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx), che è il modo in cui WatiN rileva il tipo di finestra di dialogo.

Da quello che posso vedere, non c'è ancora un supporto per il rilevamento della barra di notifica di IE 9 e dei relativi prompt in WatiN. Fino a quando non verrà aggiunto il supporto, non sarai in grado di automatizzare il download dei file in IE9.

+1

Argh, probabilmente hai ragione anche se non sono stato in grado di confermare altrimenti. – aknuds1

+1

L'uso di watin 2.1 non è possibile, ma utilizzando il metodo seguente su UIAutomation *, è possibile eseguire tutti i comandi della barra gialla-bianca, inclusi open e save-as. – tomsv

21

La finestra di dialogo per il download del file non funziona in IE9 (Windows7) NetFramework 4.0.

seguente frammento di codice potrebbe aiutare a risolvere il problema:

In primo luogo è necessario aggiungere i riferimenti UIAutomationClient e UIAutomationTypes al progetto di test.

After In Ie9 Strumenti -> Visualizza download -> Opzioni definiscono il percorso della cartella di salvataggio.

Il metodo successivo estende la classe Browser

public static void DownloadIEFile(this Browser browser) 
{ 
    // see information here (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515(v=vs.85).aspx) 
    Window windowMain = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(browser.hWnd, 5)); 
    System.Windows.Automation.TreeWalker trw = new System.Windows.Automation.TreeWalker(System.Windows.Automation.Condition.TrueCondition); 
    System.Windows.Automation.AutomationElement mainWindow = trw.GetParent(System.Windows.Automation.AutomationElement.FromHandle(browser.hWnd)); 

    Window windowDialog = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(windowMain.Hwnd, 5)); 
    // if doesn't work try to increase sleep interval or write your own waitUntill method 
    Thread.Sleep(1000); 
    windowDialog.SetActivate(); 
    System.Windows.Automation.AutomationElementCollection amc = System.Windows.Automation.AutomationElement.FromHandle(windowDialog.Hwnd).FindAll(System.Windows.Automation.TreeScope.Children, System.Windows.Automation.Condition.TrueCondition); 

    foreach (System.Windows.Automation.AutomationElement element in amc) 
    { 
     // You can use "Save ", "Open", ''Cancel', or "Close" to find necessary button Or write your own enum 
     if (element.Current.Name.Equals("Save")) 
     { 
      // if doesn't work try to increase sleep interval or write your own waitUntil method 
      // WaitUntilButtonExsist(element,100); 
      Thread.Sleep(1000); 
      System.Windows.Automation.AutomationPattern[] pats = element.GetSupportedPatterns(); 
      // replace this foreach if you need 'Save as' with code bellow 
      foreach (System.Windows.Automation.AutomationPattern pat in pats) 
      { 
       // '10000' button click event id 
       if (pat.Id == 10000) 
       { 
        System.Windows.Automation.InvokePattern click = (System.Windows.Automation.InvokePattern)element.GetCurrentPattern(pat); 
        click.Invoke(); 
       } 
      } 
     } 
    } 
} 

se si vuole fare clic su 'Salva con nome' sostituire il codice foreach con questo

System.Windows.Automation.AutomationElementCollection bmc = element.FindAll(System.Windows.Automation.TreeScope.Children, System.Windows.Automation.Automation.ControlViewCondition); 
System.Windows.Automation.InvokePattern click1 = (System.Windows.Automation.InvokePattern)bmc[0].GetCurrentPattern(System.Windows.Automation.AutomationPattern.LookupById(10000)); 
click1.Invoke(); 
Thread.Sleep(10000); 

System.Windows.Automation.AutomationElementCollection main = mainWindow.FindAll(System.Windows.Automation.TreeScope.Children 
,System.Windows.Automation.Condition.TrueCondition); 
foreach (System.Windows.Automation.AutomationElement el in main) 
{ 
    if (el.Current.LocalizedControlType == "menu") 
    { 
     // first array element 'Save', second array element 'Save as', third second array element 'Save and open' 
     System.Windows.Automation.InvokePattern clickMenu = (System.Windows.Automation.InvokePattern) 
        el.FindAll(System.Windows.Automation.TreeScope.Children,  System.Windows.Automation.Condition.TrueCondition) [1].GetCurrentPattern(System.Windows.Automation.AutomationPattern.LookupById(10000)); 
         clickMenu.Invoke(); 
     //add ControlSaveDialog(mainWindow, filename) here if needed 
     break; 

    } 
} 

Edit: anche se è necessario automatizzare il dialogo Salva con nome specificando un percorso e facendo clic su save puoi farlo aggiungendo questo codice appena prima della pausa;

private static void ControlSaveDialog(System.Windows.Automation.AutomationElement mainWindow, string path) 
{ 
    //obtain the save as dialog 
    var saveAsDialog = mainWindow 
         .FindFirst(TreeScope.Descendants, 
            new PropertyCondition(AutomationElement.NameProperty, "Save As")); 
    //get the file name box 
    var saveAsText = saveAsDialog 
      .FindFirst(TreeScope.Descendants, 
         new AndCondition(
          new PropertyCondition(AutomationElement.NameProperty, "File name:"), 
          new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit))) 
      .GetCurrentPattern(ValuePattern.Pattern) as ValuePattern; 
    //fill the filename box 
    saveAsText.SetValue(path); 

    Thread.Sleep(1000); 
    //find the save button 
    var saveButton = 
      saveAsDialog.FindFirst(TreeScope.Descendants, 
      new AndCondition(
       new PropertyCondition(AutomationElement.NameProperty, "Save"), 
       new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button))); 
    //invoke the button 
    var pattern = saveButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; 
    pattern.Invoke(); 
} 
+0

È davvero interessante, ma la finestra di dialogo salva come può essere automatizzata per salvare come nome file specifico? Ho provato a modificare il codice, ma quando cerco di trovare la finestra di dialogo Salva con nome ho problemi. – PeteT

+1

Elaborato automatizzando il salvataggio come percorso e facendo clic su Salva, quindi aggiunto il codice alla risposta. Spero che sia ok. – PeteT

+2

Puoi pubblicare un github gist della soluzione completa usando Salva come? Sto facendo fatica a farlo funzionare in IE10. – djbyter

Problemi correlati