The solution is Python of course (as usual on this blog). The aptly-named Selenium allows you to automate this sort of thing from the point of view of writing tests. It's available in several languages (I think they all use the same server backend) but I'm going to focus here on the Python. "pip install selenium" on Windows installs the basics; this will allow you to test against Firefox and Safari. For Chrome and IE, you need to download two additional files and add them to the PATH.
The Selenium docs are a bit confusing because (a) they keep referring back to an earlier version of the software (Selenium 1) which had different behaviour and (b) the commands for the Selenium IDE are very similar but not the same as the commands for the Python bindings.
Anyhoo, here's a modified version of the Selenium script that I'm using just to give some idea of how it works. When you run this at the command-line, a new Firefox window pops up, resizes to the specified dimensions, flies through the test, shuts down, and then I get the usual unittest output from the Python script. Specifying a browser name (e.g. Chrome) runs the test against Chrome instead.
import sys import unittest from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import selenium.webdriver.support.ui as ui browsers = {"firefox": webdriver.Firefox, "ie": webdriver.Ie, "chrome": webdriver.Chrome, "safari": webdriver.Safari} class Tests(unittest.TestCase): def setUp(self): self.driver = browser() self.driver.set_window_size(1380, 880) self.driver.get("file:///C:/Tools/myfile.htm") # Convenience functions self.driver.by_id = self.driver.find_element_by_id self.driver.by_xpath = self.driver.find_element_by_xpath self.wait = ui.WebDriverWait(self.driver, 5) def test_the_webpage(self): d = self.driver d.refresh() self.drag_and_drop(d.by_id("ID1"), d.by_xpath("//div[@id='things']/img[3]")) self.wait.until(lambda d: d.by_xpath("//table[@id='results']")) self.assertEqual("45", d.by_xpath("//table[@id='results']/tbody/tr/td[2]").text) d.by_id("thingy").click() self.wait.until(lambda d: d.by_xpath("//table[@id='results']")) self.assertEqual("64", d.by_xpath("//table[@id='results']/tbody/tr/td[2]").text) def drag_and_drop(self, elem, target): ActionChains(self.driver).drag_and_drop(elem, target).perform() def tearDown(self): self.driver.quit() if __name__ == "__main__": browsername = "firefox" if len(sys.argv) == 2: browsername = sys.argv[1].lower() browser = browsers[browsername] suite = unittest.TestLoader().loadTestsFromTestCase(Tests) unittest.TextTestRunner().run(suite)Note: For another Python project related to browser automation, see also twill.
What Python version are you running? I am getting an error line 13, in setUp
ReplyDeleteself.driver = browser()
NameError: global name 'browser' is not defined
I can't remember, but I'd assume Python 2.7. Probably a better way of organising the code is where browser is defined in the SetUp of each of four subclasses of a main test class. This wouldn't then rely on any globals.
ReplyDeleteHi,
ReplyDeleteCan you please confirm me one thing. I have worked on selenium using Java and TestNG framework. Now, I am switching to Python + Selenium.
Can I use testNG with this combination too. If yes, how or if no, which alternate is available ?
self.driver = browser() should be self.driver = browsers()
ReplyDeleteThere is a bug in the code.
ReplyDelete# this Global variable browser does not exist
def setUp(self):
self.driver = browser()
#change it to this
def setUp(self):
self.driver = browsers()
There is a bug in the code
ReplyDelete#global var browser i snot defined
def setUp(self):
self.driver = browser()
#should be changed to this
def setUp(self):
self.driver = browsers()