1

여러 작업을 수행하고 여러 파일 다운로드를 시작하는 FirefoxDriver의 인스턴스가 있습니다. 이러한 파일은 다양한 크기를 가질 수 있으며 루프를 완료하고 종료하면 완료되지 않은 다운로드가 중단됩니다. 보류중인 다운로드가 있는지 확인한 다음 Firefox 창이 닫히기 전에 모두 완료 될 때까지 기다릴 수있는 방법이 있습니까? 이것은 VB.NET 용이지만 C# 솔루션도 이해할 수 있습니다. 감사!Selenium Webdriver 및 Firefox로 모든 다운로드가 완료된 것을 감지하는 방법

답변

1

파일을 다운로드 할 때 Firefox 및 Chrome에서 파일 확장명을 생성하고 중간 파일을 생성합니다. 크롬의 경우는 이고 다운로드는입니다. Firefox 용으로 기억 나지 않습니다. 그러나 큰 파일을 다운로드하여 확인할 수 있습니다. 다운로드가 완료되면이 중간 파일이 실제 파일 이름으로 바뀝니다.

crdownload 확장자가있는 파일이 있는지 확인하는 코드를 작성하기 만하면됩니다. 그렇지 않은 경우 다운로드가 완료됩니다.

+1

좋은 생각을! 파이어 폭스는 두 개의 파일을 생성한다 : 0 바이트를 갖는'a_file.pdf'와 스트림이 쓰여지는'a_file.pdf.part'. 다운로드가 끝나면 Firefox는'a_file.pdf.part'를'a_file.pdf'에 복사 한 다음 첫 번째 파일을 삭제합니다. 'FileSystemWatcher'를 사용하여'.part' 파일의 생성과 삭제를 감지 할 것입니다. 생성 된 각각의 .part 파일이 삭제 될 때 완료 될 것으로 간주되는 다운로드. – VBobCat

1

Firefox에서는 브라우저 수준에서 일부 JavaScript를 주입 할 수 있습니다. 즉, 거의 모든 것을 할 수 있습니다. 그러나 컨텍스트를 설정하는 명령은 .Net 클라이언트에서 구현되지 않으므로 클래스를 확장해야합니다.

이 예는 적어도 하나 개의 다운로드를 기다립니다

모든 다운로드 성공 후 각 파일의 전체 경로를 반환 할 :

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)); 
    } 
}