Диалог выбора и загрузки файла (WebDriver)

Всем привет! В автоматизации я новичек. Задача следующая: есть кнопка по нажатию на которую появляется стандартный виндовый диалог выбора файла (к примеру фото). Вопрос : как это реализовать средствами WebDriver, возможно нужно испльзовать сторонние библиотеки ? просьба поделиться опытом.

Заранее благодарю.

Всё просто.
Находишь элемент <input type="file">, и заполняешь его путём до файла element.send_keys '/Users/username/filename.ext'.
Для наглядности сделал тему в Базе знаний Загрузка файла через WebDriver.

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

Сразу же кидаю темы, в которых похожее обсуждалось:

чета никак не выходит((( делал вот как:

 try {
		element = driver.findElement(By.xpath("//input[@type='file']']"));
		element.sendKeys("c:\\teacher.jpg");

	} catch (Exception e) {
		System.out.println("can't upload the file " + e);
	}
}

в итоге

[TestNG] Running:
  C:\Users\shcegula-os\AppData\Local\Temp\testng-eclipse--2075063559\testng-customsuite.xml

can't upload the file java.lang.NullPointerException

походу оно елемент найти не могет(

вот

У вас ошибка в локаторе - лишняя одинарная кавычка и квадратная скобка.

1 лайк
element = driver.findElement(By.xpath("//input[@type='file']"));

поправил но все равно

can't upload the file java.lang.NullPointerException

может я не тот елемент ищу ?

страница

По данному коду NPE может быть в случае driver==null, в любом случае данный эксепшен никак не означает, что элемент не найден.

согласен с предыдущим оратором, стек трейс бы по полнее , как и код.
Но правда если до этого действия совершались - драйвер не будет null.

FAILED: testSetProfilePositiv
java.lang.NullPointerException
	at com.exigen.shegula.ds_pages.EditProfilePage.uploadPhoto(EditProfilePage.java:65)
	at com.exigen.shegula.tests.DSTestProfile.testSetProfilePositiv(DSTestProfile.java:51)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
	at org.testng.TestRunner.privateRun(TestRunner.java:767)
	at org.testng.TestRunner.run(TestRunner.java:617)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
	at org.testng.SuiteRunner.run(SuiteRunner.java:240)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
	at org.testng.TestNG.run(TestNG.java:1057)
	at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)

кусочек кода

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.Select;

import com.exigen.shegula.util.PageBase;

public class EditProfilePage extends PageBase {
	@FindBy(id = "TeacherSince")
	private WebElement TeacherSince;
	@FindBy(id = "DsSince")
	private WebElement DsSince;
	@FindBy(id = "Phone")
	private WebElement Phone;
	@FindBy(id = "MyLanguage")
	private WebElement MyLanguage;
	@FindBy(id = "Info")
	private WebElement Info;
	@FindBy(xpath = ".//input[@name='file']")
	private WebElement uploadPhoto;
	@FindBy(id = "profileSubmit")
	private WebElement profileSubmit;

	private WebDriver driver;
	private WebElement element;

	public EditProfilePage(WebDriver driver) {
		super(driver);

	}

	public void setTeacherSince(String text) {
		TeacherSince.clear();
		TeacherSince.sendKeys(text);
	}

	public void setDsSince(String text) {
		DsSince.clear();
		DsSince.sendKeys(text);
	}

	public void setPhone(String text) {
		Phone.clear();
		Phone.sendKeys(text);
	}

	public void setLang(String text) {
		final Select selectBox = new Select(MyLanguage);
		selectBox.selectByVisibleText(text);
	}

	public void setInfo(String text) {
		Info.clear();
		Info.sendKeys(text);
	}

	public void submit() {
		profileSubmit.click();
	}

	public void uploadPhoto() {
		try {
			element = driver.findElement(By.xpath("//input[@type='file']"));
			element.sendKeys("c:\\teacher.jpg");

		} catch (Exception e) {
			System.out.println("can't upload the file " + e);
		}

	}

	public boolean isPageOpened() {
		return TeacherSince.isDisplayed();

	}
}

По коду приватный филд driver не инициализируется - т.е. равен null.

проблему решил 
    public class EditProfilePage {
// ...
// skipped
//...
    	private WebDriver driver;
    	private WebElement element;
    
    	public EditProfilePage(WebDriver driver) {
    		// super(driver); <== driver передавался родителю, а локальная переменная оставалась не инциализированной. Сделал инициализацию локальной переменной
    		this.driver = driver;
    
    	}
// ...
// skipped
//...

Странное решение. То есть была иерархия классов страниц, с вынесением общих методов в родительские классы, всё как по канонам ООП. А ты убрал наследование и теперь для каждой страницы будешь реализовывать общую логику?

В таких случаях принято оставлять driver приватным полем родителя, но при этом в родителе добавлять метод

protected WebDriver getDriver() {
    return this.driver;
}

который будет доступен страницам-наследникам

попробывал код выше в родительском классе и вроде пашет) спасибо

Всем привет!
У меня возникла следующая проблема:
На странице есть две кнопки: add files и upload files, но вторая - невидимая, пока фалы не добавлены в окошко, т.е я не могу по ней кликнуть пока не выберу в виндоус окне файл и не нажму open.

  WebElement element = driver.findElement(By.xpath("//input[@type='file']"));
        element.sendKeys("src/main/resources/testJPG.jpeg");
        startUpload.click();

т.е путь к файлу отправляется, но по сути ничего не происходит. на интерфейсе все это выглядит: Screenshot by Lightshot

Может, есть у кого идеи, как это можно решить?
Спасибо!

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

  • значение свойства display равно none;
  • значение свойства visibility равно hidden;
  • значение свойства opacity равно 0 (кроме операции клика);
  • значение атрибута type равно hidden (если это input);
    offsetWidth и offsetHeight равны нулю.
    У меня была похожая пролема для моб. сайтов

вот такой вот инпут был

<form id="ProfilePhotoUploadForm" action="/photo/upload" data-role="submit-image" style="position: relative; overflow: hidden; direction: ltr;">
< input type="file" accept="jpeg,jpg,gif,png,image/*;capture=camera" name="file" style="position: absolute; right: 0px; top: 0px; font-family: Arial; font-size: 118px; margin: 0px; padding: 0px; cursor: pointer; opacity: 0;">
< /form>

и все тоже не получалось залить фотку (
решение нашлось очень простое
вставил эту строку

((JavascriptExecutor) driver).executeScript("$('#ProfilePhotoUploadForm').find('input').attr('style','position: relative; direction: ltr;');");

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

так же пробывал роботом работать с окном файл аплодера, но у меня он чего то не захотел ничего делать, с браузером норм отрабатывал, а вот с аплодером беда (
Но можешь попробывать, вдруг пойдет

StringSelection ss = new StringSelection("Путь к файлу");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);

driver.findElement(By.xpath("//input[@type='file']")).click();
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);

вот как то так попробуй

1 лайк

всем привет! Пожалуйста подскажите, можно ли загрузить файл если тесты запускаются на удаленном сервере а не локадьно(если да, то интересует какой будет путь к файлу) проект лежит на репозитории в битбакет, тесты запускаются на
jenkins

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

Начнем с простого: как вы взаимодействуете с нативным окном загрузки файлов? Где физически запускается тест? Ответ - на Jenkins - заведомо неверный. И если это так, то вам следует для начала почитать зачем нужны CI сервера, и попытаться проанализировать, подходят ли они для работы с браузерами в рамках высокоуровневого тестирования.

взаимодействую sendkeys
python 3.6 x64
система winserver 2012 r2 x64

import win32com.client

    pyperclip.copy(file_path1)
    load.sendKeys("^v")
    load.Sendkeys("~")

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