问题
I have an instance of FirefoxDriver that performs several operations and starts downloading several files. Those files may have various sizes and when it finishes the loop and shuts down it interrupts unfinished downloads. Is there a way I can check whether there are pending downloads and then wait until they are all complete before closing Firefox Window? This is for VB.NET but I can understand C# solutions too. Thanks!
回答1:
Firefox and Chrome when downloads a file creates and intermediate file extensions. For chrome it's crdownload, I don't remember what it's for Firefox. However, you can download a large file and check. Once download is completed this intermediate file is renamed to actual file name.
All you need to do it write a code which check if any file with crdownload extension is exist or not. if not, your download is completed.
回答2:
With Firefox, it's possible to inject some JavaScript at a browser level, which means that you can do almost anything. But the command to set the context is not implemented in the .Net client, so you'll have to extend the class.
This example waits for at least one download and for all the downloads to be successful and then returns the full path of each file:
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));
}
}
来源:https://stackoverflow.com/questions/47462118/how-to-detect-when-all-downloads-finished-with-selenium-webdriver-and-firefox