...как в Selenium выбрать дату в jQuery Datepicker?
Image source: Artan Sinani

...как в Selenium выбрать дату в jQuery Datepicker?

Datepicker – это поле ввода, предназначенное для ввода даты. Но это не простое текстовое поле ввода. При нажатии на него появляется календарик, в котором можно выбрать нужную дату. Демонстрацию различных вариантов представления этого элемента можно найти на сайте jQuery.

Не знаю, насколько удобно человеку работать с этим календариком по сравнению с обычным текстовым полем. Но для автоматизатора это кромешный ужас. Для того, чтобы просто ввести дату, надо сделать множество действий – кликнуть в поле ввода, чтобы появился календарик, многочисленными кликами по стрелочкам влево и вправо выбрать нужный месяц и год, а потом выбрать нужный день месяца из таблицы. Столько нажатий кнопки мыши лишь для того, чтобы заполнить одно поле ввода! Да ещё и проверки, чтобы понять, нужный месяц и год находится правее или левее уже выбранного. Но и это ещё не всё! Календарик анимированный, поэтому нужно ещё добавить ожидание появления элементов и ожидание завершения анимации перед каждым кликом. В общем, можно потратить не один час на написание функции для заполнения этого поля.

Есть ли альтернатива?

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

public void SetDatepicker(IWebDriver driver, string cssSelector, string date)
{
    new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until<bool>(
        d => driver.FindElement(By.CssSelector(cssSelector)).Displayed);
    driver.FindElement(By.CssSelector(cssSelector)).SendKeys(date);
}

(примеры кода здесь и ниже на языке C#)

Проблема в том, что в тот момент, когда мы начинаем вводить текст – автоматически появляется календарик, и он не закрывается после того, как ввод текста завершён.

Для того, чтобы он закрылся, надо фокус ввода переместить в какое-нибудь другое место – например, на другое поле ввода, или можно кликнуть “в любое свободное место на странице”:

public void SetDatepicker(IWebDriver driver, string cssSelector, string date)
{
    new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until<bool>(
        d => driver.FindElement(By.CssSelector(cssSelector)).Displayed);
    driver.FindElement(By.CssSelector(cssSelector)).SendKeys(date);
    driver.FindElement(By.CssSelector("body")).Click();
}

Однако кликнуть по другому полю может быть сложно, потому что календарик его закрывает, а если кликнуть в произвольное место страницы, оно может оказаться не “свободным”, и мы нечаянно попадём по какой-нибудь ссылке или кнопке, что вызовет нежелательный эффект.

Но главная проблема подстерегает нас в другом месте. Иногда текстовое поле ввода нельзя редактировать, а бывает так, что его вообще нет! Календарик есть, а текстового поля ввода нет!

Что же делать?

Есть другой путь – использовать jQuery API для взаимодействия с этим элементом. У календарика есть метод setDate, и обратиться к нему можно вот так:

public void SetDatepicker(IWebDriver driver, string cssSelector, string date)
{
    new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until<bool>(
        d => driver.FindElement(By.CssSelector(cssSelector)).Displayed);
    (driver as IJavaScriptExecutor).ExecuteScript(
        String.Format("$('{0}').datepicker('setDate', '{1}')", cssSelector, date));
}

Ну и пример использования:

IWebDriver driver = new FirefoxDriver();
driver.Url = @"http://jqueryui.com/datepicker/";
driver.SwitchTo().Frame(
    driver.FindElement(By.CssSelector("iframe.demo-frame")));
SetDatepicker(driver, "#datepicker", "02/20/2002");

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

Но может быть он “нечестный”? Не пропускаем ли мы при этом какие-то баги? Возможно. Если разработчики взяли “бракованную” версию jQuery, в которой API работает, а с GUI проблемы – наши автотесты этого не заметят. Если вас это беспокоит, тогда забудьте всё вышенаписанное и продолжайте кликать мышкой.

А если вы доверяете разработчикам jQuery – тогда можете смело использовать API, и ваши тесты станут быстрее и стабильнее.

Да, доверие творит чудеса!


Алексей Баранцев

Автор:

Если вам понравилась эта статья, вы можете поделиться ею в социальных сетях (кнопочки ниже), а потом вернуться на главную страницу блога и почитать другие мои статьи.
Ну а если вы не согласны с чем-то или хотите что-нибудь дополнить – оставьте комментарий ниже, может быть это послужит поводом для написания новой интересной статьи.

Мои тренинги
А ещё есть? Конечно!