Over on the SauceLabs blog Santiago Suarez Ordoñez has a nice description of how to use the
attach_file method in Selenium 1, and some of the restrictions that pertain to it. One of those restrictions is that the file that
attach_file operates on has to be available from the root level of an HTTP server. To quote Santi:
using the following URL will not work:
while the following will:
So, you could drop your test files into the root directory of some Apache server you have control over, but Python offers a more flexible solution: run an adhoc server to serve files from your test files directory:
python -m SimpleHTTPServer 8000
Nice, but you still have to make sure that adhoc server is running or you tests will fail. With a little work I was able to come up with a way to make my tests self-contained by starting up the server to handle requests from
attach_file in a text class setup method. The key is that the server has to run in its own thread, otherwise it blocks the tests from executing:
AttachmentFileRequestHandler is there to override
SimpleHTTPRequestHandler to that the upload test files are served from a sub-directory of the test suite.
ThreadedTCPServer just uses
SocketServer.ThreadingMixIn to enable the server to run in its own thread.
The server is started before the tests run by the
setUpClass class method and shutdown when they finish by
tearDownClass, another class method. Those methods are courtesy of Michael Foord’s excellent improvements to the
unittest module; available from PyPI as
unittest2 for Python 2.4, 2.5, and 2.6, and from the standard library as
unittest for Python 2.7, and 3.2 and up.
The test I’ve shown here is trivial - just confirming that the value of the input tag is set in the HTML fragment:
In my real tests I confirm that the uploaded file has been stored as an attachment to a CouchDB object, and then use
httplib to do a download request for the attachment and confirm that the response headers are correct.
As also Santi points out in his post,
attach_file only works if you run your tests against Firefox.
The introduction of webdriver in Selenium 2 make things easier. No more need for
attach_file and a server to handle its requests - just use the
send_keys method to put the absolute path of the test upload file into the input element.
You can test against a local instance of Firefox as shown in
test_firefox_upload_file or use the standalone Selenium server to test against a remote browser. In
test_remote_htmlunit_upload_file I’ve used that approach to run the test against the
HtmlUnit driver which is blazingly fast because it doesn’t render content to a screen. It’s not available directly in Python, hence the use of
One caveat: Selenium 2 doesn’t support the file selector input element yet for WebKit (Chrome, Safari, …) browsers.
The code above is based on the selenium2.0b3 Python bindings available from PyPI. The Selenium 1 example and the Remote Selenium 2 test were run against selenium-server-standalone-2.0b3.jar available from the Selenium project repository on code.google.com.
No Pingbacks for this post yet...
A private blog for life, cycling, and my computing fiddlings.
|<< <||> >>|