This post documents how to set up an Ubuntu 14.04 64-bit machine with everything you need to develop automated tests with Selenium-WebDriver, Google Chrome, and ChromeDriver, using the Python 2.7 release that ships with Ubuntu.
These steps might be useful to someone in the near term, and perhaps in the future this post could make for an interesting time capsule - remembering the WebDriver that was!
All steps assume you’ve just booted a fresh Ubuntu 14.04 64-bit machine and are at the command prompt:
1. Download and install the latest Google Chrome release
Using virtualenv allows you to install the Selenium Python bindings (and any other Python modules you might want) into an isolated environment, rather than the global packages dir, which (among other benefits) can help make your test environment easily reproducible on other machines:
That’s all you need to get started - the next step I would suggest is to explore how to run
Selenium scripts using pytest or unittest. That sounds like good territory to cover in a subsequent post, so perhaps I’ll revisit it!
I feel it’s worth mentioning that troubleshooting GhostDriver tests can seem like a challenge in and of itself if you’re used to having a browser GUI to help you visually pinpoint problems in your tests.
This post describes a technique intended to make GhostDriver troubleshooting easier: How to capture a screenshot automatically if your test raises an exception.
#!/usr/bin/env python# * Note: phantomjs must be in your PATH## This script:# - Navigates to www.google.com# - Intentionally raises an exception by searching for a nonexistent element# - Leaves behind a screenshot in exception.pngimportunittestfromseleniumimportwebdriverfromselenium.webdriver.support.eventsimportEventFiringWebDriverfromselenium.webdriver.support.eventsimportAbstractEventListenerclassScreenshotListener(AbstractEventListener):defon_exception(self,exception,driver):screenshot_name="exception.png"driver.get_screenshot_as_file(screenshot_name)print("Screenshot saved as '%s'"%screenshot_name)classTestDemo(unittest.TestCase):deftest_demo(self):pjsdriver=webdriver.PhantomJS("phantomjs")d=EventFiringWebDriver(pjsdriver,ScreenshotListener())d.get("http://www.google.com")d.find_element_by_css_selector("div.that-does-not-exist")if__name__=='__main__':unittest.main()
While working on a stackoverflow answer about Sikuli today, I noted that installing Sikuli on Ubuntu 12.04 isn’t a one-step process - there are a few dependencies that need manual intervention before you even install it.
Here’s the rundown of the steps that worked for me to get a simple Sikuli script working:
1. Install the Oracle JRE
I used version 1.7.0_51:
$ java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
Make sure java is in your PATH, or else the Sikuli IDE will have issues.
To create a similar archive with 7zip (specifically, the 7z, 7z.exe, or 7za.exe binaries), use the 7z a command:
7z a foo.7z foo
Interestingly, with 7zip you can also omit the name of the archive file to create; this results in an archive file with a .7z extension, otherwise named after the archived dir:
7z a foo
Also note that the 7z format is the default archive type created, unless you specify an alternative type with the -t option.
Extract an archive, recreating paths
This is simple enough, and quite similar between the two tools:
tar xf foo.tar.gz
7z x foo.7z
Note that the 7z e command (which you may discover before 7z x) will ignore the directory structure inside the archive, and extract every file and dir into your current dir. That behavior will come in handy for a later task.
Determine whether a given file is in the archive
With 7z, this is pretty straightforward when using the 7z l (list) command combined with the -r (recurse) option:
7z l -r foo.7z hi.txt
With GNU tar, there are several ways to approach this task.
You can pass the full path to the file to tar tf, along with the archive file name, and tar will error out if there’s no match inside the archive:
tar tf foo.tar.gz foo/level1/level2/hi.txt
Or, if the original, unarchived dir structure is still present on disk, you can pass it to tar d (–diff), and tar will compare the archive with the unarchived dir:
tar df foo.tar.gz foo/level1/level2/hi.txt
Note that BSD tar does not appear to have anything like the d/–diff option.
After all is said and done, piping tar t output to grep may be the most suitable option here:
tar tf foo.tar.gz | grep hi.txt
Extract a single file from an archive into the current dir
This scenario is interesting, in that the task is noticeably simpler when using 7zip.
Let’s say you want to extract hi.txt from the archive, placing the file in your current dir.
With 7z, you can use 7z e -r to retrieve the file (in this case hi.txt), even if it’s several levels down in the archive:
7z e -r foo.7z hi.txt
With GNU or BSD tar you’ll need to count how many levels deep in the archive’s dir hierarchy your file lives, and pass that number of leading dirs to remove from the output, using –strip-components:
tar --strip-components=3 -xf foo.tar.gz foo/level1/level2/hi.txt
$ psql "dbname=YOUR_DB_NAME host=YOUR_EC2_HOST user=YOUR_USER password=YOUR_PASS port=5432 sslmode=require"
No relations found.
CREATE TABLE artists (id int, name varchar(80));
CREATE TABLE releases (id int, name varchar(80));
CREATE TABLE recordings (id int, artist_id int, release_id int, name varchar(80));
INSERT INTO artists (id, name) VALUES (1, 'Underworld');
INSERT INTO releases (id, name) VALUES (1, 'Oblivion With Bells');
INSERT INTO recordings (id, artist_id, release_id, name) VALUES (1, 1, 1, 'To Heal');
INSERT INTO artists (id, name) VALUES (2, 'Stars');
INSERT INTO releases (id, name) VALUES (2, 'In Our Bedroom After the War');
INSERT INTO recordings (id, artist_id, release_id, name) VALUES (2, 2, 2, 'The Night Starts Here');
/* Get all recordings of each artist, and show the release */
SELECT rec.name AS recording, a.name AS artist, rel.name AS release
FROM recordings AS rec
INNER JOIN artists AS a
ON rec.artist_id = a.id
INNER JOIN releases AS rel
ON rec.release_id = rel.id;
recording | artist | release
To Heal | Underworld | Oblivion With Bells
The Night Starts Here | Stars | In Our Bedroom After the War
GhostDriver is a project that lets you write Selenium WebDriver automation tests that run using the PhantomJS headless WebKit, instead of a traditional web browser.
Put another way, PhantomJS can replace Firefox and friends in your WebDriver scripts - and it doesn’t require a display, so testing complex web apps from the command line is just about as easy as using a GUI browser. Very cool!
Getting your system ready to run Python scripts that use GhostDriver can be done in a few brief steps, if you have homebrew on OS X.
A natural next step, when developing automated test cases based on experiments like the one above, is to start storing your code into a Python unittest script.
Here’s an example of how one might start organizing the code above:
If all is right with the world, running the above script will print output along the lines of the text below.
current_url is now 'http://www.google.com/search?hl=en&source=hp&q=selenium&gbv=2&oq=selenium'
Ran 1 test in 2.770s
That’s all for the moment. Now, go forth and Ghost Drive!