WebDriver features: Работа с Upload popup (Windows native окно) при помощи Selenium Web Driver

Это третья статья из цикла статей "WebDriver features", в которых рассматриваться примеры нестандартных ситуаций, которые могут возникнуть при автоматизации на Selenium WebDriver.

WebDriver features: Работа с Upload popup (Windows native окно) при помощи Selenium Web Driver

Тот случай, когда в автоматизации web-ориентировочных приложений используются какие-то особенности, связанные с операционными системами, хорошо демонстрирует пример с Upload pop-ом в браузерах. Многие считают, что тест-кейсы с upload-ом и загрузкой файлов с браузера лучше обходить стороной автоматизации, но все же сделать это возможно.

Итак, если говорить о функции download файла с браузера, то здесь все просто - кликаем на какой-то контрол, который вызывает загрузку файла с вашего web-проэкта, и загрузка пошла. Соотвественно, нужно в настройках броузера отключить поп-апы с предложениям сохранения в конкретную папку. Лучше такие случаи хар-кодить наглым образом. Потом просто проверять загрузился ли файл, или нет, стандартным образом:

Using java.io.File
File f = new File(filePathString);
if(f.exists()) { 
	/* do something */ 
	}

Что касаеться upload-pop-а (для загрузки файла в web-приложение), то здесь история немного другая.

В основном web driver хорошо справляется со следующей конструкцией:

File file = new File(filepath);
driver.findElement(By.xpath(locator)).sendKeys(file.getAbsolutePath()); //and click upload button

Но что делать, если данная конструкция по разным причинам не работает ? И нужно вручную бороться с окном операционной системы.

Такой пример неработоспособности данного метода можно посмотреть на форуме в linkedin, где есть множество предложений.

Рекомендую  подход с использованием AUTO IT скрипта для роботы с upload - pop-up-ом. Метод очень, скажем так, “некрасивый”, но рабочий, я бы сказал с успешностью в 70%.

Итак, что нам понадобиться:

  • ​Качаем AUTO IT тулзу для автоматизации. Устанавливаем ее.

    AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI and general scripting. (вот что пишет о самой тулзе ее оф. сайт).

    Открываем SciTe Script Editor с директории, куда установился AUTO IT. Пишем следующий код (команды AUTO IT можна посмотреть здесь.):

WinWaitActive("Open") // ждем активности Windows окна Open
Send("D:\AutoIT-commands\TestingVideo.mp4") //Отправляем иму путь к файлу (фокус по умолчанию стоит на текст-боксе где прописываеться путь к файлу)
Send("{ENTER}") //эмулируем нажатие клавиши Enter (а-ля загрузить)

У вас должно что то подобное получиться:

  • Файл со скриптом сохраняем. Он получит формат AUTO IT и будет иметь расширение “.au3”.  Этот файл не исполнительный. Так как нам нужно имитировать действия пользователя в нашем коде, что и сделает AUTO IT сценарий скрипта (имеется ввиду код автоматизации для нашего web приложения), то нужно будет этот файл запускать с помощью языка программирования внутри скрипта автоматизации.

  • Преобразование в исполнительный файл делается следующим образом: идем в директорию, куда установился AUTO IT и запускаем Compile Script to .exe (x64) или Compile Script to .exe (x86), в зависимости от вашей системы. Выбираем Вами сохраненный скрипт в шаге 2 с расширением “.au3”, указываем destination нашего будущего “.exe” файла и жмем Convert.

(Конвертация с “.au3” в “.exe”)

Сконвертированый “.exe” файл у нас есть. Пишем функцию file upload для автоматизации с помощью web driver + AUTO IT:

protected void uploadFile(String uploadButtonId,final String uploadAutoITcommand, String filename) throws InterruptedException{
   	 driver.findElement(By.id(uploadButtonId)).click();
   	 Thread thread = new Thread(){ //запускаем наш exe-шник в новом потоке
   	 	public void run(){
   			 try {
   		       	String[] commands = new String[]{};
   		       	commands = new String[]{"D:\\AutoIT-commands\\" + uploadAutoITcommand + ".exe"}; //location of the autoit executable, пусть конечно же к файлу должен быть такой как у вас.
   		       	Runtime.getRuntime().exec(commands);
   		    	} catch (IOException e) {}
   	 	}
   	 };
   	 thread.start();
   	   while(!driver.findElement(By.id(uploadButtonId)).getAttribute("value").contains(filename)){//...Thread is uploading the file, пока нам в value не запишеться значение нашего файла.
   	 }
    }

Конечно же, нужно проверить, реально ли загрузился файл в Ваше web-приложение, так как унивирсальности тут не придумаешь. Напишу только лишь то, что в большинстве случаев реализации после upload еще нужно проверить появился ли текст лейбл с надписью окончания upload процесса. 

2 лайка

А если теперь представить, что в тестах мы создаем/генерим 100 узеров и каждому нужно загрузить фотографию

так создавать для каждого пользователя просто надоест где-то на 10 файле, если не раньше. Я использую другой вариант (оговорюсь, что он работает конкретно в моем случаи).

Я использую java robot class.

Пример:

0) Копирую в буфер обмена системы заранее готовый путь к файлу

функция

public static void setClipboard(String str) {
        StringSelection ss = new StringSelection(str);
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
    }

вызов ее перед тем как нужно вставить

setClipboard("С:\\Folder\\TestFile.zip");
driver.findElement(By.name("uploads[]")).click();

1) Кликаю по кнопке выпадает Upload popup (Windows native окно)

Robot robot = new Robot();
// Ctrl-V + Enter on Win
robot.delay(3000);
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);

2) Все окошко закрылось, и я дальше продолжаю работать с элементами страници.

Это срабатывает на Chrome, IE возможно будет работать и в Opera. Не Работает в FF. Как не пробовал ничего не помогает, если кто разберется или найдет решение пусть напишет решение.

Мое решение пока Chrome, из 100% таких кликов загружаются все, правда там нужно поработать еще с time out, знаю плохо но пока использую функцию Thread.sleep();

Спасибо за статью

1 лайк

а в ФФ и не будет работать

я уже писал об этом

ну может быть кто-то нашел обход, хотя я очень сомневаюсь

Что-то не найдена страница. :frowning:

Поправил

1 лайк

Спасибо!

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

Что мешает вместо копирования из clipboard, при помощи setValue или sendKeys написать путь к файлу?

*рАбота…с буквой а в русском языке.

Большое спасибо за пример! прям класс))