Using Selenium for website automation
Some time ago, a friend of mine approached me with a problem: Working on a flight base, they needed specialized, daily weather reports, which needed to be generated - by hand.
So each and every morning, one employee would click through skybriefing.com, logging in, entering the same data about the base (position, scope of weather report etc.) to generate two PDFs, which were then sent to the other employees.
skybriefing.com
Automation to the rescue
Having worked with Selenium in the past, that was the first thing which came to mind - Although nowadays, most of my frontend testing experience is based on Protractor (and Cypress, which was not yet existing back then).
Some dreaded memories include dealing with timeouts over again, adding or increasing sleep()
commands until the test would pass again (for some time).
Nonetheless Selenium seemed the easiest to use with Python and I decided to give it a try (Python 2.7):
import selenium.webdriver as webdriver
from pyvirtualdisplay import Display
import time
# Set up a virtual display
print 'Setting up virtual display and driver...'
display = Display(visible=0, size=(800, 600))
display.start()
# Set up Firefox
profile = webdriver.FirefoxProfile()
profile.set_preference(...)
print 'Opening website...'
driver.get("http://www.skybriefing.com/portal")
time.sleep(10)
## Download DABS PDF
print 'Downloading first PDF...'
element = driver.find_elements_by_xpath('//*[@id="v-dabsportlet_WAR_ibsportletdabs_LAYOUT_10454"]...')[0]
element.click()
time.sleep(10)
This simple script starts up a virtual Display
, opens the page and downloads the first, publicly available PDF. The CSS selector for the download link had to be adjusted later, but this part was set up pretty quick.
Logging in and
Next up was entering loggin in and entering the actual information.
Here I kind of went with the most simple selectors, to just make it work in the first step (also with sending out the Email). Surprisingly, this kept working! I guess sometimes you can be lucky too with Selenium :-)
Some of the input fields (like the login) have IDs (although generated):
This ID can then be referenced in the script, for example to enter a text (send_keys()
):
element = driver.find_element_by_id('_com_liferay_login_web_portlet_LoginPortlet_login')
element.send_keys(USER)
time.sleep(2)
Here we can see it in action, with the orange address bar, indicating that a "bot" is running the commands:
Here's the original script:
# Information Area
element = Select(driver.find_elements_by_css_selector('div.v-select:nth-child(1) > select:nth-child(1)')[0])
element.select_by_visible_text('Switzerland')
time.sleep(2)
# Flugplatz
element = driver.find_elements_by_css_selector('input.v-widget:nth-child(1)')[0]
element.send_keys(FLUGPLATZ)
time.sleep(2)
# Lower FL
element = driver.find_elements_by_css_selector('#gwt-uid-5')[0]
element.send_keys(LOWER_FL)
time.sleep(2)
# Upper FL
element = driver.find_elements_by_css_selector('#gwt-uid-15')[0]
element.send_keys(UPPER_FL)
time.sleep(2)
print 'Entered flight information and pressed Enter, this could take a while...'
element.send_keys(Keys.ENTER)
time.sleep(60)
print 'Downloading generated PDF...'
element = driver.find_elements_by_css_selector('...')[0]
element.click()
time.sleep(20)
The script was then setup on a Raspberry Pi and an Email was sent out in the morning. With some maintenance the script for at least 3-4 years, saving a lot of manual work.
You can find the code in this Github repo: skybriefing-dabs.
Thanks for reading!
Bonus: Relevant XKCD: