Как можно проверить что файл загрузился не используя Thread.Sleep?
Через проверку в файловой системе я так понимаю не получится сделать без слипов?
Вроде как-то можно сделать через проверку состояния js-события.
Как это можно реализовать на C#?
Проверив состояние js события, ты проверишь только то, как завершилось это самое js событие, что не означает, что файл загружен. Валидной проверкой будет всё же наличие файла в системе.
А чем тебя sleep в этом случае не устраивает? Просто сделай его более умным - проверяй наличие файла, скажем, каждые 500 миллисекунд на протяжении 15 секунд (цифры отфонарные).
И да, наверняка есть библиотека, которая будет ждать появления файла, но там будет тот же слип внутри
А если файл большой, тогда нужно проверять что и размер не изменяется
Обычно, браузер создаёт темповый файл, когда скачивает, а по завершении удаляет его и остаётся только загруженный файл. Попробуй ждать именно своего файла, если знаешь его имя, или часть имени. Если не получится, то да, надо б ждать постоянства размера файла
Есть отличная библиотечка Awaitility для того чтобы красиво подождать какое то событие (будь то загрузка файла или ещё что то)
Прмерно так
await().atMost(30, SECONDS).untilAsserted(() → assertThat(fileIsUploaded().isTrue());
На jave реализуется через создание кастомного ExpectedCondition, которое затем передается в WebDriverWait. В ExpectedCondition пишете функцию, в которой лучше всего чекать имя файла и то что его размер больше 0. На c# принцип такой же:
- Пишется своя функция ожидания
- В функции реализуется проверка по имени и размеру файла.
- Функция передается в webdriver.
public static void WaitForFile(string filePath, int timeout)
{
var sw = Stopwatch.StartNew();
while (sw.ElapsedMilliseconds <= timeout)
{
if (File.Exists(filePath))
return;
Thread.Sleep(TimeSpan.FromMilliseconds(500));
}
throw new TimeoutException($"Timeout {timeout} milliseconds exceeded while waiting for file '{filePath}' appearance.");
}
как нибудь вот так
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using System;
using System.IO;
String filename = "...";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(wait_seconds));
wait.Until(o => {
// ignore WebDriver argument
bool FileExists = File.Exists(Filename);
// print some debugging info if needed
return FileExists;
}
);
документация говорит
public bool OpenQA.Selenium.Support.UI.DefaultWait<OpenQA.Selenium.IWebDriver>.Until<TResult>(Func<IWebDriver, bool> condition);
// Summary: Repeatedly applies this instance’s input value to the given function until one of the following occurs:
• the function returns neither null nor false
• the function throws an exception that is not in the list of ignored exception types
• the timeout expires
Type parameter TResult: The delegate’s expected return type.
condition: A delegate taking an object of type T as its parameter, and returning a TResult.
Returns: The delegate’s return value.