Ожидание загрузки страницы в Selenium леко исправить с помощью написания простого скрипта. Идеально если у вас классное приложение и на момент загрузки данных показывает какой-нибудь spinner. В этом случае можно просто проверять наличие такого элемента на страничке и если его нет, то, вероятнее всего, все даные подгрузились и можно продолжать взаимодействие с элементами. Можно ждать body элемент, можно проверять readyState у документа. Но сегодня я раскажу вам еще одну вожможноть - это PerformanceTiming.

loading

PerformanceTiming предоставляет информацию о разных событиях которые возникают в момент загрузки страницы. Получить этот объект можно с помощью window.performance.timing свойства вашей страницы и IJavaScriptExecutor интерфейса и его метода ExecuteScript.

IWebDriver driver;
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
long loadEventEnd = (long)js.ExecuteScript("return window.performance.timing.loadEventEnd");

Можно написать метод, который ожидает загрузку страницы:

public void WaitForPageLoaded()
{
    IWebDriver driver;
    IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
    long loadEventEnd = 0;
    do
    {
        loadEventEnd = (long) js.ExecuteScript("return window.performance.timing.loadEventEnd");
    } while (loadEventEnd == 0);
}

Дальше я просто перечислю список свойств, которые предоставляет объект PerformanceTiming и их краткое описание.

PerformanceTiming.navigationStart

Этот атрибут должен вернуть время сразу после того, как браузер завершит запрос на выгрузку предыдущего документа. Если предыдущего документа нет, этот атрибут должен возвращать то же значение, что и PerformanceTiming.fetchStart.

PerformanceTiming.unloadEventStart

Если предыдущий документ и текущий документ имеют одинаковое происхождение, этот атрибут должен вернуть время непосредственно перед тем, как браузер начнет выгрузку предыдущего документа. Если предыдущего документа нет или предыдущий документ имеет другое происхождение, чем текущий документ, этот атрибут должен возвращать ноль.

PerformanceTiming.unloadEventEnd

Если предыдущий документ и текущий документ имеют одинаковое происхождение, этот атрибут должен вернуть время сразу после того, как браузер завершит событие разгрузки предыдущего документа. Если предыдущего документа нет или предыдущий документ имеет другое происхождение, чем текущий документ или выгрузка еще не завершена, этот атрибут должен возвращать ноль.

PerformanceTiming.redirectStart

Если при навигации есть HTTP-переадресация или эквивалент, и если все переадресации или эквивалентные данные имеют один и тот же источник, этот атрибут должен вернуть начальное время извлечения, которая инициирует перенаправление. В противном случае этот атрибут должен возвращать ноль.

PerformanceTiming.redirectEnd

Если при навигации и переадресации и эквивалентах есть перенаправления HTTP или их эквиваленты от одного источника, этот атрибут должен возвращать время сразу после получения последнего байта ответа последнего перенаправления. В противном случае этот атрибут должен возвращать ноль.

PerformanceTiming.fetchStart

Если новый ресурс должен быть получен с использованием HTTP GET или эквивалентного, fetchStart должен вернуть время непосредственно перед тем, как браузер начнет проверять любые соответствующие кэши приложения. В противном случае он должен вернуть время, когда браузер начинает выборку ресурса.

PerformanceTiming.domainLookupStart

Этот атрибут должен возвращать время непосредственно перед тем, как агент пользователя начнет поиск имени домена для текущего документа. Если используется постоянное соединение или текущий документ извлекается из соответствующих кэшей приложений или локальных ресурсов, этот атрибут должен возвращать то же значение, что и PerformanceTiming.fetchStart.

PerformanceTiming.domainLookupEnd

Этот атрибут должен возвращать время сразу после того, как браузер завершит поиск имени домена для текущего документа. Если используется постоянное соединение или текущий документ извлекается из соответствующих кэшей приложений или локальных ресурсов, этот атрибут должен возвращать то же значение, что и PerformanceTiming.fetchStart.

PerformanceTiming.connectStart

Этот атрибут должен вернуть время непосредственно перед тем, как браузер начнет устанавливать соединение с сервером для получения документа. Если используется постоянное соединение или текущий документ извлекается из соответствующих кэшей приложений или локальных ресурсов, этот атрибут должен возвращать значение PerformanceTiming.domainLookupEnd.

PerformanceTiming.connectEnd

Этот атрибут должен вернуть время сразу после того, как браузер завершит установление соединения с сервером для извлечения текущего документа. Если используется постоянное соединение или текущий документ извлекается из соответствующих кэшей приложений или локальных ресурсов, этот атрибут должен возвращать значение PerformanceTiming.domainLookupEnd.

PerformanceTiming.secureConnectionStart

Этот атрибут является необязательным. Пользовательские агенты, которые не имеют этого атрибута, должны установить его как неопределенное. Когда этот атрибут доступен, если схема текущей страницы является HTTPS, этот атрибут должен вернуть время непосредственно перед тем, как браузер начнет процесс установления связи, чтобы защитить текущее соединение. Если этот атрибут доступен, но HTTPS не используется, этот атрибут должен возвращать ноль.

PerformanceTiming.requestStart

Этот атрибут должен возвращать время непосредственно перед тем, как браузер начнет запрашивать текущий документ с сервера или из соответствующих кэшей приложений или из локальных ресурсов.

PerformanceTiming.responseStart

Этот атрибут должен возвращать время сразу после того, как браузер получит первый байт ответа от сервера или из соответствующих кэшей приложений или из локальных ресурсов.

PerformanceTiming.responseEnd

Этот атрибут должен возвращать время сразу после того, как браузер получит последний байт текущего документа или непосредственно перед закрытием транспортного соединения, в зависимости от того, что наступит раньше. Документ здесь может быть получен либо с сервера, либо с кэшами приложений, либо с локальных ресурсов.

PerformanceTiming.domLoading

Этот атрибут должен возвращать время непосредственно перед тем, как браузер устанавливает текущую готовность документа к «loading».

PerformanceTiming.domInteractive

Этот атрибут должен возвращать время непосредственно перед тем, как браузер устанавливает текущую готовность документа к «interactive».

PerformanceTiming.domContentLoadedEventStart

Этот атрибут должен возвращать время непосредственно перед тем, как браузер запускает событие DOMContentLoaded в документе.

PerformanceTiming.domContentLoadedEventEnd

Этот атрибут должен возвращать время сразу после завершения события DOMContentLoaded документа.

PerformanceTiming.domComplete

Этот атрибут должен возвращать время непосредственно перед тем, как браузер устанавливает текущую готовность документа к «complete».

PerformanceTiming.loadEventStart

Этот атрибут должен возвращать время непосредственно перед запуском события загрузки текущего документа. Он должен возвращать ноль, если событие загрузки еще не запущено.

PerformanceTiming.loadEventEnd

Этот атрибут должен возвращать время завершения события загрузки текущего документа. Он должен возвращать ноль, когда событие загрузки не запускается или не завершено.