Selenium for cats, or, Chad does not code while other people are watching. This was not designed without Chad speaking in the background.
Set-up
mkvirtualenv selenium
pip install -r requirements.txt
cd html
python -m SimpleHTTPServer 16981 > /dev/null 2>&1&
cd ..
Or you can leave SimpleHTTPServer
running in anoher terminal tab.
Everyone's assignment for next meeting: Study Hasan's e2e tests legacy.
Introducing what Selenium does. See ghostwriter.py
.
Notes:
driver.get
waits until the moment the browser'sonload
event has fired. This is problematic if your page fetches data even afteronload
, say via AJAX. For this, you have to wait.- What happens when an error occurs before
driver.close()
? How is that relevant for unit testing?
Links:
Motivating question: Is our UI too fancy for Selenium? For instance, dealing with
select
elements is easy---see plain_select.py
.
But we use ui-select2
! What do? See uiselect2.py
Heart-attack pop quiz: How about file uploads? Keep in mind that, at least for candidate resume, the upload functionality is wrapped inside a profiler. (Bawal sumagot: Tim, Cassie).
What happens when the selector applies to more than one element? You can locate
via CSS selectors but it is still not
as flexible as jQuery. You could use XPath but it is messy. jQuery is the bestest!!!!111!
See multielement.py
.
How about links that open new tabs/windows, of which we have plenty?! See
new_window.py
. But, just by using the code we have now, this is prone to
memory leaks.
(Source not included.)
There are two ways:
- Log-in "like a real user" by loading the log-in page, selecting input boxes, and sending them your user credentials.
- Setting the cookies for yourself.
- As a real user, you can execute JavaScript in the browser's console. In
Selenium, you can do the same via the driver's
execute_async_script
andexecute_script
methods. - Selenium does not play well with unexpected browser dialogs (alerts, prompts, etc.).
The code itself is easy
from selenium import webdriver
import unittest
class SeleniumTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def test_star(self):
"""
In these tests, we usually just assert certain properties in the
elements, or do a "happy path" run through a form. Then we are happy as
long as there are no exceptions raised.
"""
pass
def tearDown(self):
self.driver.quit()
But remember these tests will usually (should) be run in a server. Will it matter that the server is "headless"? Spoiler: the answer is "yes".