Загрузка файлов в Selenium (Windows вариант)
Загрузить файл довольно просто если у вас есть обычное HTML поле для загрузки файла, вам просто нужно выполнить .find_element_by_id('id_photo').send_keys(<full path to file>)
. Но часто для красоты это поле заменяется на что-то другое и прячется, в таком случае мы не можем выполнять send_keys
к спрятанным элементам и этот способ больше не работает. Но если доступно диалоговое окно открытия файла и тест работает в Windows тогда можно подключит pywinauto или другую утилиту с помощью которой можно управлять окнами и загрузить файл.
С помощью pywinauto можно вставить путь к файлу в поле редактирования и нажать кнопку “Открыть”. Для подключения pywinauto к браузеру нужен его process id, для Firefox pid можно найти прямо в инстансе драйвера, если же используется Chrome то нужен process id вкладки, в моем примере у меня всего одна вкладка поэтому я просто беру первый дочерний процесс. Так же перед тем как использовать диалог нужно проверить что он открылся или же просто “спать” что бы дать открыться диалогу.
Дальше есть небольшой пример кода по загрузке файла.
#!/usr/bin/python
import psutil
from unittest import TestCase
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from pywinauto.application import Application
class UploadTestCase(TestCase):
def setUp(self):
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser, 10)
def tearDown(self):
self.browser.close()
def get_pid(self):
if isinstance(self.browser, webdriver.Chrome):
process = psutil.Process(self.browser.service.process.pid)
return process.children()[0].pid # process id of browser tab
if isinstance(self.browser, webdriver.Firefox):
return self.browser.service.process.pid # process id of browser
assert Exception('driver does not supported')
def upload_file(self, filename):
path = os.path.join(
os.path.realpath('.'),
'fixtures',
filename
)
assert os.path.exists(path)
for i in range(10):
app = Application()
app.connect(process=self.get_pid()) # connect to browser
dialog = app.top_window_() # get active top window (Open dialog)
if not dialog.Edit.Exists(): # check if Edit field is exists
time.sleep(1) # if no do again in 1 second (waiting for dialog after click)
continue
dialog.Edit.TypeKeys('"{}"'.format(path)) # put file path
dialog['&OpenButton'].Click() # click Open button
return
raise Exception('"Open File" dialog not found')
def test_upload_small_logo(self):
el_logo_upload = self.wait.until(
EC.presence_of_element_located(
(By.NAME, ‘upload-logo')
)
)
el_logo_upload.click()
self.upload_file('logo_small.png')
# checking