...как в Selenium

...как в Selenium "прицепить" файл к невидимому полю ввода?

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

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

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

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

Причина создания таких полей тоже вполне уважительная – красота и кроссплатформенность.

Пара ссылок, которые поясняют, как это работает:

В двух словах, идея следующая. Поскольку файловое поле ввода выглядит некрасиво и во всех браузерах по разному, нужно его заменить на какую-нибудь красивую кнопку, которая выглядит везде одинаково. А сверху над этой кнопкой поместить то самое файловое поле ввода, а чтобы его не было видно - надо сделать его прозрачным (opacity:0). И тогда пользователь будет думать, что он кликает по красивой кнопке, хотя на самом деле он при этом кликает по находящемуся над ней файловому полю ввода, открывается диалог выбора файла и пользователь выбирает файл. В общем, дальше всё как обычно, как если бы файловое поле было видимым.

В общем, у человека всё хорошо, потому что его так легко обмануть.

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

Баг это или фича - вопрос отдельный и неоднозначный, пока не будем заострять на нём внимание. Вместо этого попробуем ответить на простой практический вопрос: что делать? Как прикрепить файл к этому невидимому полю ввода?

Ответ прост и очевиден: надо сделать его видимым.

Тогда возникает следующий вопрос: а как сделать его видимым?

А для этого у нас есть возможность исполнять произвольный JavaScript-код, и мы ею воспользуемся, чтобы поменять стиль элемента – убрать прозрачность, уменьшить шрифт до нормального, отменить все трансформации.

public void unhide(WebDriver driver, WebElement element) {
  String script = "arguments[0].style.opacity=1;"
    + "arguments[0].style['transform']='translate(0px, 0px) scale(1)';"
    + "arguments[0].style['MozTransform']='translate(0px, 0px) scale(1)';"
    + "arguments[0].style['WebkitTransform']='translate(0px, 0px) scale(1)';"
    + "arguments[0].style['msTransform']='translate(0px, 0px) scale(1)';"
    + "arguments[0].style['OTransform']='translate(0px, 0px) scale(1)';"
    + "return true;";
  ((JavascriptExecutor) driver).executeScript(script, element);
}

public void attachFile(WebDriver driver, By locator, String file) {
  WebElement input = driver.findElement(locator);
  unhide(driver, input);
  input.sendKeys(file);
}

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

Возможно, этот список необходимых корректировок стиля неполон, может быть вам понадобится ещё дополнительно что-то делать с элементом, чтобы он стал видимым.

А теперь примеры использования на разных сайтах:

WebDriver driver = new FirefoxDriver();

driver.get("http://blueimp.github.io/jQuery-File-Upload/basic.html");
attachFile(driver, By.id("fileupload"), "C:\\temp\\image.png");

driver.get("http://imgup.net/");
attachFile(driver, By.id("image_image"), "C:\\temp\\image.png");

driver.get("http://www.2imgs.com/");
attachFile(driver, By.id("f_file"), "C:\\temp\\image.png");

Работает? Вот и отлично!


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

Автор:

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

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