English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
File upload is a headache problem that all UI automation tests have to face. Today, the blogger shares his experience in dealing with file upload here, hoping it can help all the seleniumers who have been trapped by file upload.
Firstly, we need to distinguish the types of upload buttons. Generally, there are two types: one is the input box, and the other is more complex, implemented through js, flash, etc., and the tag is not input
We will analyze these two separately:
1.input tag
It is widely known that the input tag can be directly used with send_keys, and this is no exception. Let's look at the code example:
Example URL: http://www.sahitest.com/demo/php/fileUpload.htm
代码:
# -*- coding: utf-8 -*- from selenium import webdriver driver = webdriver.Firefox() driver.get('http:)//sahitest.com/demo/php/fileUpload.htm') upload = driver.find_element_by_id('file') upload.send_keys('d:\\baidu.py') # send_keys print upload.get_attribute('value') # check value driver.quit()
Result:
baidu.py
It is obvious that for input upload, send_keys is the simplest solution.
2.Non-input type upload
Next, the difficulty level will be upgraded. What should we do for uploads that are not implemented by input boxes? This kind of upload is very strange, there are a tags, divs, buttons, and objects. We cannot directly handle these uploads on the web page. The only way is to open the OS pop-up and handle the pop-up.
The problem comes again, the level involved in the OS pop-up is not solved by selenium, what to do? It's very simple, use OS-level operations to handle it, by now we have basically found the solution to the problem.
Generally, there are the following solutions:
1.autoIT, with the help of external forces, we call the generated au3or exe file.
2.Python pywin32library, identifies the dialog handle, and then operates
3.SendKeys library
4.keybd_event, with3Similar, but it is a simulation of keystrokes, ctrl+a, ctrl+c, ctrl+v…
At present, I only know the above four methods, if there are other methods, please leave a message to tell me, so that I can learn from it.
Let's take a look one by one:
1. autoIT
I have already explained the methods of autoIT upload and parameterization in another article, please refer to selenium's autoit command line parameters. No more repetition here.
2.win32gui
No more废话,let's show the code first:
Example URL: http://www.sahitest.com/demo/php/fileUpload.htm
代码:
# -*- coding: utf-8 -*- from selenium import webdriver import win32gui import win32con import time dr = webdriver.Firefox() dr.get('http://sahitest.com/demo/php/fileUpload.htm') upload = dr.find_element_by_id('file') upload.click() time.sleep(1) # win32gui dialog = win32gui.FindWindow('#32770', u'File Upload') # Dialog box ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None) Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) # The above three sentences find objects in turn until the handle of the input box Edit object is found button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # Determine the button Button win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 'd:\\baidu.py') # Input the absolute address into the input box win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) # Press button print upload.get_attribute('value') dr.quit()
Result:
baidu.py
Here you need a very important small tool: Spy++There are many, Baidu one, of course, you can also use the tool built-in autoIT, but it's not as good as this, I suggest you download one.
and, you need to install pywin32library, you can go tohereFind the library corresponding to your Python version, note32is64must correspond to the Python version you installed.
After installation, you can see PyWin in the 【Start Menu Python Folder】32Documentation 【Python for Windows Documentation】, where you can find the corresponding method API.
A brief introduction to several used:
win32gui.FindWindow(lpClassName=None, lpWindowName=None):
•Start from the top-level window and find the window that matches the conditions, and return the handle of this window.
•lpClassName: Class name, in the Spy++you can see
•lpWindowName: Window name, the name you can see on the title bar
•Example code used to find the upload window, you can use only one of them, using classname is susceptible to interference from other things, using windowname is unstable, different upload dialog boxes may have different window_name, how to locate depends on your situation.
win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)
•Search for the window with matching class name and window name, and return the handle of this window. If not found, return 0.
•hwndParent: If not 0, it searches for the child windows of the window handle hwndParent.
•hwndChildAfter: If not 0, it searches according to the z-;index starts searching from hwndChildAfter in reverse order, otherwise it starts from the first child window.
•lpClassName: Character type, it is the class name of the window form, which can be found in the Spy++find.
•lpWindowName: Character type, it is the window name, that is, the title you can see on the title bar.
•Example code used to search for input boxes and the OK button layer by layer
win32gui.SendMessage(hWnd, Msg, wParam, lParam)
•hWnd: Integer, the window handle receiving the message
•Msg: Integer, the message to be sent, these messages are predefined by Windows, and you can refer to the system-defined messages (System-Defined Messages)
•wParam: Integer, the wParam parameter of the message
•lParam: Integer, the lParam parameter of the message
•Example code used to input file address into the input box and click the OK button
As for win32The api module and other methods are not described here. If you want to know more, please search Baidu or check pywin32Documentation.
3.SendKeys
First, you need to install the SendKeys library, which can be installed using pip
pip install SendKeys
Code Example:
Example URL: http://www.sahitest.com/demo/php/fileUpload.htm
代码:
# -*- coding: utf-8 -*- from selenium import webdriver import win32gui import win32con import time dr = webdriver.Firefox() dr.get('http://sahitest.com/demo/php/fileUpload.htm') upload = dr.find_element_by_id('file') upload.click() time.sleep(1) # SendKeys SendKeys.SendKeys('D:\\baidu.py') # Send the file address SendKeys.SendKeys("{ENTER}") # Send the Enter key print upload.get_attribute('value') dr.quit()
Result:
baidu.py
You can directly input information into the focus through the SendKeys library, but you should pay attention to add a little waiting time when opening the window, otherwise it is easy to fail to send the first letter (or you can add a useless character before the address), but I think this method is unstable and not recommended.
4.keybd_event
win32api provides a keybd_event() method to simulate keystrokes, but this method is麻烦 and unstable, so it is not recommended. Below is a partial code example. If you want to study it, please search Baidu yourself.
# Find an input box, enter the address of the file to be uploaded, and copy it to the clipboard video.send_keys('C:\\Users\\Administrator\\Pictures\\04b20919fc78baf41fc993fd8ee2c5c9.jpg') video.send_keys(Keys.CONTROL, 'a') # selenium's send_keys (ctrl+a) video.send_keys(Keys.CONTROL, 'x') # (ctrl+x) driver.find_element_by_id('uploadImage').click() # Click the upload button to open the upload box # Paste (ctrl + v) win32api.keybd_event(17, 0, 0, 0) # Press the key ctrl win32api.keybd_event(86, 0, 0, 0) # Press the key v win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0) # Lift the key v win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按键 ctrl time.sleep(1) # 回车(enter) win32api.keybd_event(13, 0, 0, 0) # 按下按键 enter win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按键 enter ...
是不是很麻烦,当然,你甚至可以用按键把整个路径输入进去,不过,我想没人愿意这么做的。而且在此过程中你不能随意移动鼠标,不能使用剪贴板,太不稳定了,所以非常不建议你用这种办法。。
3.多文件上传
接下来还有一种情况值得我们考虑,那就是多文件上传。如何上传多个文件,当然我们还是往输入框里输入文件路径,所以唯一要搞清楚的就是多文件上传时,文件路径是怎么写的。
我来告诉你吧,多文件上传就是在文件路径框里用引号括起单个路径,然后用逗号隔开多个路径,就是这么简单,例如:
"D:\a.txt" "D:\b.txt"
但需要注意的是:只有多个文件在同一路径下,才能这样用,否则是会失败的(下面的写法是不可以的):
"C:\a.txt" "D:\b.txt"
接下来找一个例子试试:
示例网址:http://www.sucaijiayuan.com/api/demo.php?url=/demo/20150128-1
代码:
# -*- coding: utf-8 -*- from selenium import webdriver import win32gui import win32con import time dr = webdriver.Firefox() dr.get('http://www.sucaijiayuan.com/api/demo.php?url=/demo/20150128-1) dr.switch_to.frame('iframe') # 一定要注意frame dr.find_element_by_class_name('filePicker').click() time.sleep(1) dialog = win32gui.FindWindow('#32770', None) ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None) Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # The code is the same as the example above, but the parameters are different here. If you like, you can write an upload function to encapsulate the upload feature win32gui.SendMessage(Edit, win32con.WM_SETTEXT, 0, '"d:\\baidu.py" "d:\\upload.py" "d:\\1.html"') win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) print dr.find_element_by_id('status_info').text dr.quit()
Result:
Selected3File(s), Total1.17KB.
As can be seen, multi-file uploading is not that complex and is also very simple. The only difference is that the input parameters are different. autoIT can also implement this. If you are interested, you can try it yourself.
And we can find a point, that is, the code in this window is basically the same as that in the previous example, indicating that we can extract the uploading part and write a function, so that each time we need to upload, we can directly call the function and pass in the parameters.
Look, uploading is actually very easy to handle.
That's all for this article. I hope it will be helpful to everyone's learning, and I also hope everyone will support the Nahan tutorial more.
Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, does not edit the content manually, and does not assume any relevant legal responsibility. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report, and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.)