В разных книгах по автоматизации тестирования дано много умных советов, как избежать загрузки файлов. Но может возникнуть множество ситуаций, когда загрузка необходима.
Например, загружаемый файл должен быть сравнен с эталоном. Или генерируется отчет, который будет использован для последующей вивисекции на предмет установления попадает ли туда нужная информация или нет.
Короче, нужно взять и загрузить. Но Хром при попытке загрузки вываливает предупреждение, работать с которым силами Селениума, увы, невозможно. А в моем случае сервер генерировал не банальные pdf или html, а целый exe (при выборе соответствующего пункта; другие варианты были менее злобными), и это приводило еще к одному предупреждению. К счастью, это все можно отключить. Но чтобы найти способ, оказалось недостаточно искать по форумам и StackOverflow, кое-что я выяснил непосредственно из исходников Хромиума (Хром, если кто не знает, это версия открытого браузера Хромиум с некоторыми вставками от Гугла; говорят, что там – анальные зонды, точно утверждать не берусь, но дома пользуюсь исключительно Хромиумом).
Итак, вот она, настоящая магия:
ChromeOptions options = new ChromeOptions();
options.addArguments("safebrowsing-disable-download-protection");
Map<String, Object> prefs = new HashMap<>();
prefs.put("safebrowsing.enabled", "true");
prefs.put("select_file_dialogs.allowed", "false");
prefs.put("download.prompt_for_download", "false");
prefs.put("download.directory_upgrade", "true");
options.setExperimentalOption("prefs", prefs);
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
WebDriver driver = new ChromeDriver(capabilities);
Кое-что нужно добавить. В последних версиях Хром стал обнаруживать присутствие Селениума и зачем-то выводить гнусные сообщения о том, что он управляется извне, а также предлагать залогиниться. Мешает. Бесит. Зачем эта глупость понадобилась – не понимаю... Поэтому надо добавлять куда-то между первой и последней строкой еще три команды:
prefs.put("credentials_enable_service", Boolean.FALSE);
prefs.put("profile.password_manager_enabled", Boolean.FALSE);
options.addArguments("disable-infobars");
Тут же возникает резонный вопрос: а почему в одном случае используется "false", а в другом Boolean.FALSE? Честно отвечу, что не знаю. Вот так оно работает, а по другому – нет. У меня, по крайней мере; возможно, у кого-то сработает чуть-чуть по-другому: когда имеешь дело с Windows, возможны любые чудеса...