System Testing Bookmarklets: Selenium
My switch search engine bookmarklet had two bugs. First when I deployed the page, the URL was screwed up (thanks for telling me Chris) and second my bookmarklet was incompatible with FireFox[1].
Conveniently the software engineering community has a solution to this class of problems and it's called system testing. In this context, System testing means interact with the web pages via a browser just like users do. I did some digging and I couldn't find a perfect (or awesome) tool for system testing web apps.
I was able to get a tool that could drive FireFox and Chrome (IE isn't working). This tool had some warts, and took some experimentation to get working, but it mostly meets the needs. Please comment if you find a better tool!
The tool I used is called Selenium, and it's scriptable via python (also Java and C#). Selenium is able to impersonate a user performing actions via the common web browsers. The code below should make reasonable sense to someone familiar with the DOM. As usual, the code is also available on bitbucket:
[1] InnerText isn't support in FF, need to use InnerHtml instead.
Conveniently the software engineering community has a solution to this class of problems and it's called system testing. In this context, System testing means interact with the web pages via a browser just like users do. I did some digging and I couldn't find a perfect (or awesome) tool for system testing web apps.
I was able to get a tool that could drive FireFox and Chrome (IE isn't working). This tool had some warts, and took some experimentation to get working, but it mostly meets the needs. Please comment if you find a better tool!
The tool I used is called Selenium, and it's scriptable via python (also Java and C#). Selenium is able to impersonate a user performing actions via the common web browsers. The code below should make reasonable sense to someone familiar with the DOM. As usual, the code is also available on bitbucket:
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import Select from selenium.common.exceptions import NoSuchElementException import unittest, time, re import urllib class RunTheClick(unittest.TestCase): def setUp(self): self.base_url = "http://ig2600.blogspot.com" self.drivers=[] def test_chrome(self): d = webdriver.Chrome() self.drivers.append(d) self.run_suite(d) def test_firefox(self): d = webdriver.Firefox() self.drivers.append(d) self.run_suite(d) def run_suite(self,driverToUse): self.driver = driverToUse driver = self.driver # Get Blog Page driver.get(self.base_url + "/2012/05/assembly-to-javascript-tsrs-to.html") bookmarklet = driver.find_element_by_partial_link_text("SwapSearchEngine") #bookmarkletURL starts with uri scheme(javascript:), remove it to get code bookmarkletURL = bookmarklet.get_attribute("href") bookmarkletCode = bookmarkletURL.split("javascript:")[1] # BUGBUG: bookmarkletCode is URLEncoded in FF but not in Chrome. # In future, unquoting might not be safe in chrome, find correct way to handle this. bookmarkletCode = urllib.unquote(bookmarkletCode) # click on bookmarklet in page and verify it throws a failure alert. bookmarklet.click() self.verify_and_dismess_not_on_google_or_bing_alert() # Selenium can't execute bookmarklet if there is an alert in play - that's too bad. # otherwise we'd do the below # driver.execute_async_script(bookmarkletCode) # self.verify_and_dismess_not_on_google_or_bing_alert() #go to google and search driver.get("http://google.com") # Very brittle (found it using web inspect in firefox developer tools) textBox = self.driver.find_element_by_id("gbqfq") textBox.send_keys ("a b c") textBox.send_keys (Keys.RETURN) time.sleep(2) # sleep to let autocomplete finish. self.assertEqual(driver.title,u"a b c - Google Search") # execute bookmarklet print bookmarkletCode driver.execute_script(bookmarkletCode); # verify we switched to bing self.assertEqual(driver.title,u"a b c - Bing") # execute bookmarklet driver.execute_script(bookmarkletCode); # verify back on google. self.assertEqual(driver.title,u"a b c - Google Search") def verify_and_dismess_not_on_google_or_bing_alert(self): # Click on the alert alert = self.driver.switch_to_alert() self.assertEqual(alert.text,u"Only works on a Google or Bing search") alert.accept() time.sleep(2) # sleep to let dialog go away. def tearDown(self): for d in self.drivers: d.quit() if __name__ == "__main__": unittest.main()Notes:
[1] InnerText isn't support in FF, need to use InnerHtml instead.
Comments