1

私はいくつかの操作を実行し、いくつかのファイルのダウンロードを開始するFirefoxDriverのインスタンスを持っています。これらのファイルにはさまざまなサイズがあり、ループが終了してシャットダウンすると、未完成のダウンロードが中断されます。保留中のダウンロードがあるかどうかを確認し、Firefoxウィンドウを閉じる前に完全に完了するまで待つ方法はありますか?これはVB.NET用ですが、C#ソリューションも理解できます。ありがとう!Selenium WebdriverとFirefoxですべてのダウンロードが完了したことを検出する方法

答えて

1

FirefoxとChromeは、ファイルをダウンロードしてファイル拡張子を作成するときに使用します。クロムについては、のcrdownloadですが、私はそれがFirefoxのために何かを覚えていません。ただし、大きなファイルをダウンロードして確認することはできます。ダウンロードが完了すると、この中間ファイルは実際のファイル名に変更されます。

crdownload拡張子を持つファイルが存在するかどうかを確認するコードを記述するだけです。そうでない場合は、ダウンロードが完了します。

+1

良いアイデアを! Firefoxは2つのファイルを作成します:0バイトの 'a_file.pdf'とストリームが書き込まれる' a_file.pdf.part'です。ダウンロードが完了すると、Firefoxは 'a_file.pdf.part'を' a_file.pdf'にコピーし、最初のファイルを削除します。私は 'FileSystemWatcher'を使って' .part'ファイルの作成と削除を検出します。作成された '.part'ファイルもそれぞれ削除されると、ダウンロードが終了するとみなされます。 – VBobCat

1

Firefoxでは、ブラウザレベルでJavaScriptを注入することができます。つまり、ほとんど何でもできます。しかし、コンテキストを設定するコマンドは.NETクライアントでは実装されていないため、クラスを拡張する必要があります。

この例では、少なくとも1つのダウンロードのために、すべてのダウンロードを成功させるために待機した後、各ファイルの完全なパスを返します。

var options = new FirefoxOptions(); 
options.SetPreference("browser.download.dir", "C:\\temp"); 
options.SetPreference("pdfjs.disabled", true); 
options.SetPreference("pdfjs.enabledCache.state", false); 
options.SetPreference("browser.download.folderList", 2); 
options.SetPreference("browser.download.useDownloadDir", true); 
options.SetPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf"); 

var driver = new FirefoxDriverEx(options); 
driver.Url = "https://support.mozilla.org/en-US/kb/use-adobe-reader-view-pdf-files-firefox"; 
driver.FindElementByCssSelector("[href*='mozilla_privacypolicy.pdf']").Click(); 

string[] files = driver.GetDownloads(1, TimeSpan.FromSeconds(120)); 
class FirefoxDriverEx : FirefoxDriver { 

    public FirefoxDriverEx(FirefoxOptions options) : base(options) { 
     var commands = CommandExecutor.CommandInfoRepository; 
     commands.TryAddCommand("SetContext", new CommandInfo("POST", "/session/{sessionId}/moz/context")); 
    } 

    public string[] GetDownloads(int minimum, TimeSpan timeout) { 
     const string JS_GET_DOWNLOADS = @" 
      var minimum = arguments[0], callback = arguments[1]; 
      Components.utils.import('resource://gre/modules/Downloads.jsm', {}).Downloads 
      .getList(Downloads.ALL).then(list => list.getAll()) 
      .then(items => items.length >= minimum && items.every(e => e.succeeded) ? items.map(e => e.target.path) : null) 
      .then(callback);"; 

     try { 
      SetContext("chrome"); 

      for (var endtime = DateTime.UtcNow + timeout; ; Thread.Sleep(1000)) { 
       Object result = ExecuteAsyncScript(JS_GET_DOWNLOADS, minimum); 
       if (result != null) 
        return ((IEnumerable<object>)result).Cast<string>().ToArray(); 
       if (DateTime.UtcNow > endtime) 
        throw new TimeoutException("No download available or one is not complete."); 
      } 
     } finally { 
      SetContext("content"); 
     } 
    } 

    public void SetContext(string context) { 
     var parameters = new Dictionary<string, object> { { "context", context } }; 
     CommandExecutor.Execute(new Command(this.SessionId, "SetContext", parameters)); 
    } 
} 
関連する問題