【问题标题】:Test if a file has been downloaded Selenium/C# (Google Chrome)测试是否已下载文件 Selenium/C# (Google Chrome)
【发布时间】:2019-07-30 03:38:33
【问题描述】:

我想点击一个on click下载文件的按钮,并测试是否已经下载了预期的文件。

我已经用谷歌搜索了这个,但不幸的是没有找到关于这个主题的任何具体答案,我发现的很多帖子都已经过时了(2014 年),我敢打赌 Selenium 现在一定已经改变了 API 定义。

【问题讨论】:

    标签: c# selenium


    【解决方案1】:

    此代码验证文件是否已下载,然后将其删除。

    private static bool CheckFileDownloaded(string filename)
    {
        bool exist = false;
        string Path = System.Environment.GetEnvironmentVariable("USERPROFILE") + "\\Downloads";
        string[] filePaths = Directory.GetFiles(Path);
        foreach (string p in filePaths)
        {
            if(p.Contains(filename))
            {
                FileInfo thisFile = new FileInfo(p);
                //Check the file that are downloaded in the last 3 minutes
                if (thisFile.LastWriteTime.ToShortTimeString() == DateTime.Now.ToShortTimeString() ||
                thisFile.LastWriteTime.AddMinutes(1).ToShortTimeString() == DateTime.Now.ToShortTimeString() ||
                thisFile.LastWriteTime.AddMinutes(2).ToShortTimeString() == DateTime.Now.ToShortTimeString() ||
                thisFile.LastWriteTime.AddMinutes(3).ToShortTimeString() == DateTime.Now.ToShortTimeString())
                exist = true;
                File.Delete(p);
                break;
            }
        }
        return exist;
    }
    

    希望这会有所帮助。 C# 中的代码。

    【讨论】:

    • 来自 Resharper 和 MS Test Explorer 的 FWR 测试运行器似乎在其他地方下载文件 - 我能够修改您的解决方案 - 谢谢!:stackoverflow.com/a/54635540/314291
    【解决方案2】:

    使用下面的代码:-

    import org.openqa.selenium.By;
    import java.io.File;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.firefox.FirefoxProfile;
    import org.testng.Assert;
    import org.testng.annotations.AfterClass;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.Test;
    
    public class FileDownloadVerify {
    
     private WebDriver driver;
    
     private static String downloadPath = "D:\\siva";
     private String URL="http://all-free-download.com/free-photos/download/in_love_cosmos_flower_garden_220378.html";
    
     @BeforeClass
     public void testSetup() throws Exception{
      driver = new FirefoxDriver(firefoxProfile()); 
      driver.manage().window().maximize();
     }
    
      @Test
     public void example_VerifyExpectedFileName() throws Exception {
      driver.get(URL);
         driver.findElement(By.xpath(".//*[@id='detail_content']/div[2]/a")).click();
    
         Thread.sleep(10000);
         File getLatestFile = getLatestFilefromDir(downloadPath);
         String fileName = getLatestFile.getName();
         Assert.assertTrue(fileName.equals("in_love_cosmos_flower_garden_220378.zip"), "Downloaded file name is not matching with expected file name");
     }
    
    
     @AfterClass
     public void tearDown() {
      driver.quit();
     }
    public static FirefoxProfile firefoxProfile() throws Exception {
    
      FirefoxProfile firefoxProfile = new FirefoxProfile();
      firefoxProfile.setPreference("browser.download.folderList",2);
      firefoxProfile.setPreference("browser.download.manager.showWhenStarting",false);
      firefoxProfile.setPreference("browser.download.dir",downloadPath);
      firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk","application/zip");
    
      return firefoxProfile;
     }
    public boolean isFileDownloaded(String downloadPath, String fileName) {
     boolean flag = false;
        File dir = new File(downloadPath);
        File[] dir_contents = dir.listFiles();
    
        for (int i = 0; i < dir_contents.length; i++) {
            if (dir_contents[i].getName().equals(fileName))
                return flag=true;
                }
    
        return flag;
    }
    
    private boolean isFileDownloaded_Ext(String dirPath, String ext){
     boolean flag=false;
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        if (files == null || files.length == 0) {
            flag = false;
        }
    
        for (int i = 1; i < files.length; i++) {
         if(files[i].getName().contains(ext)) {
          flag=true;
         }
        }
        return flag;
    }
    
    private File getLatestFilefromDir(String dirPath){
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        if (files == null || files.length == 0) {
            return null;
        }
    
        File lastModifiedFile = files[0];
        for (int i = 1; i < files.length; i++) {
           if (lastModifiedFile.lastModified() < files[i].lastModified()) {
               lastModifiedFile = files[i];
           }
        }
        return lastModifiedFile;
    }
    }
    

    希望对你有帮助:)

    【讨论】:

      【解决方案3】:

      一个简单的解决方案是使用文件观察器来检测文件的创建。 它可以让您等待下载开始和完成:

      string folder = Environment.GetEnvironmentVariable("USERPROFILE") + "\\Downloads";
      using (var watcher = new FileSystemWatcher(folder)) {
      
          // wait for new file to be created
          var result = watcher.WaitForChanged(WatcherChangeTypes.Created, 5000);
          if (result.TimedOut)
              throw new WebDriverTimeoutException("Dowmload failed");
          Console.WriteLine("Download started for : " + Path.Combine(folder, result.Name));
      
          // wait for the temporary file to be deleted
          var result2 = watcher.WaitForChanged(WatcherChangeTypes.Deleted, 10000);
          if (result2.TimedOut)
              throw new WebDriverTimeoutException("Dowmload failed");
          Console.WriteLine("Download finished for : " + Path.Combine(folder, result.Name));
      }
      

      【讨论】:

      • 不幸的是 FileSystemWatcher 有一个奇怪的行为,它很可能无法在您的 selenium 测试中很好地同步。
      【解决方案4】:

      这是我的通用 C# 解决方案

      /// <summary>
      /// Start a download and wait for a file to appear
      /// https://stackoverflow.com/a/46440261/1141876
      /// </summary>
      /// <param name="expectedExtension">If we don't know the extension, Chrome creates a temp file in download folder and we think we have the file already</param>
      protected List<FileInfo> ActAndWaitForFileDownload(
          Action action
          , string expectedExtension
          , TimeSpan maximumWaitTime)
      {
          Directory.CreateDirectory(DownloadDirectory);
          var fileCountbefore = Directory.GetFiles(DownloadDirectory).Length;
          var stopwatch = Stopwatch.StartNew();
      
          action();
      
          var isTimedOut = false;
          var extensionFilter = $"*{expectedExtension}";
      
          Func<bool> fileAppearedOrTimedOut = () =>
          {
              isTimedOut = stopwatch.Elapsed > maximumWaitTime;
              var isFilePresent = Directory
                                      .GetFiles(DownloadDirectory, extensionFilter)
                                      .Length == fileCountbefore;
      
              return isFilePresent && !isTimedOut;
          };
      
          do
          {
              Thread.Sleep(500);
              Log($"Waited {stopwatch.Elapsed} (max={maximumWaitTime}) for download '{extensionFilter}'...");
          }
          while (fileAppearedOrTimedOut());
      
          var files = Directory
                          .GetFiles(DownloadDirectory)
                          .Select(s => new FileInfo(s))
                          .ToList();
      
          if (isTimedOut)
          {
              Log($"Timed out: {filenamesForLog}");
          }
          else
          {
              var filenamesForLog = string.Join(",", files.Select(f => f.Name));
              Log($"File downloaded: {filenamesForLog}");
          }
      
          return files;
      }
      

      这是用法

      // Wait for a PDF
      var downloadedFiles = ActAndWaitForFileDownload(() => buttonElement.click(), ".pdf", TimeSpan.FromSeconds(30));
      

      【讨论】:

      • 这个不要下载指定目录的文件!该怎么做?
      【解决方案5】:

      FWR,我尝试过的两个测试运行程序(Resharper 和 MS 测试资源管理器)都将 Selenium 文件放在以下文件夹中。

      MySolution\MyProject\bin\Debug\Downloads
      

      事实上 Se 在这里添加了一个 readme.txt 包含:

      这个文件夹是供 Selenium 下载文件的

      但是,我能够相应地修改@Sudeepthi 的答案:

      private static readonly string SeleniumDownloadPath = 
           AppDomain.CurrentDomain.BaseDirectory + "\\Downloads";
      private static bool CheckFileDownloaded(string filename)
      {
          var firstFile = Directory
              .GetFiles(SeleniumDownloadPath)
              .FirstOrDefault(fp => fp.Contains(filename));
          if (firstFile != default)
          {
              var fileInfo = new FileInfo(firstFile);
              var isFresh = DateTime.Now - fileInfo.LastWriteTime < TimeSpan.FromMinutes(3);
              File.Delete(firstFile);
              //Check the file that are downloaded in the last 3 minutes
              return isFresh;
          }
          return false;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-09
        • 1970-01-01
        • 2017-12-26
        • 2021-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-23
        相关资源
        最近更新 更多