{"id":347,"date":"2014-05-21T00:51:21","date_gmt":"2014-05-21T04:51:21","guid":{"rendered":"http:\/\/qxf2.com\/blog\/?p=347"},"modified":"2017-07-06T14:46:52","modified_gmt":"2017-07-06T18:46:52","slug":"running-selenium-automation-using-sauce-labs-part-3","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/running-selenium-automation-using-sauce-labs-part-3\/","title":{"rendered":"Running Selenium automation using Sauce Labs: Part 3"},"content":{"rendered":"<p><span style=\"font-weight: bold; font-style: inherit;\"><strong>Problem:<\/strong><\/span> Different test runs require different configuration on <a href=\"https:\/\/saucelabs.com\/\">Sauce Labs<\/a>. In this post, we will show you how to make your automated test runs to use specific configuration parameters of Sauce Labs.<\/p>\n<hr>\n<h2>TWEAKING SAUCE LABS CONFIGURATION<\/h2>\n<p>Some nightly automated selenium checks that we run at <a href=\"http:\/\/qxf2.com\">Qxf2 Services<\/a> need to be run only on specific browsers. Further some of our nightly tests were running a lot slower on Sauce labs. We decided to tweak a few configuration parameters on Sauce Labs to improve performance. We also added some useful reporting parameters like build and tag to help testers identify different runs easily. This post will walk you through the steps you need to do to be able to map your automated test runs to use specific configuration parameters of Sauce Labs. For this example, we are going to show you how to set the following parameters:<br \/>\n1. browser<br \/>\n2. browser version<br \/>\n3. platform<br \/>\n4. name: name of the test run<br \/>\n5. build: version of your application the test was running against<br \/>\n6. tag: tag your test cases to different groups<br \/>\n7. record-video<br \/>\n8. video-upload-on-pass<br \/>\n9. record-screenshots<\/p>\n<p>The configuration parameters will be listed in a file and read via the Python module <a href=\"http:\/\/pymotw.com\/2\/ConfigParser\/\">ConfigParser<\/a>.<\/p>\n<hr>\n<h2>OVERVIEW<\/h2>\n<p>1. Create a configuration file<br \/>\n2. Accept command line options for configuration file and test run name<br \/>\n3. Use ConfigParser to read the configuration<br \/>\n4. Run the tests<br \/>\n5. Check the result on Sauce Labs<\/p>\n<p><span style=\"font-weight: bold; font-style: inherit;\">STEP 1: Create a configuration file<\/span><br \/>\nWe can create a configuration file that uses the test run name to identify sections and list the desired configuration under it. For this example we created a file called <strong>test_configuration.ini<\/strong>. Add the contents below to your configuration file and tweak the parameter values as you like. In this example we are showing you two test runs (Nightly Run and Acceptance Run) using different configurations.<\/p>\n<pre lang=\"python\">[Nightly Run]\r\nbrowser = ff\r\nversion = 28\r\nplatform = Windows 8\r\nname = 20-May-2013 nightly run\r\nbuild = Build-17.23\r\ntag = capa_20-May-2013\r\nrecord-video = false\r\nvideo-upload-on-pass = false\r\nrecord-screenshots = false\r\n\r\n[Acceptance Run]\r\nbrowser = ie\r\nversion = 8\r\nplatform = Windows 7\r\nname = Acceptance test run\r\nbuild = Build-17.23\r\ntag = capa_20-May-2013\r\nrecord-video = false\r\nvideo-upload-on-pass = false\r\nrecord-screenshots = false\r\n<\/pre>\n<p>NOTE: We have chosen to disable video recording, screenshot, video upload on pass to speed up our test runs.<\/p>\n<p><span style=\"font-weight: bold; font-style: inherit;\">STEP 2: Accept command line options for configuration file and test run name<\/span><\/p>\n<p>In our <a href=\"https:\/\/qxf2.com\/blog\/running-selenium-automation-using-sauce-labs-part-2\/\">previous post<\/a>, we showed you an example of accepting command line arguments in our test scripts. In this post we will modify the command line parameters to accept the configuration file and test run name. The code snippet to accept the configuration file and command line is given below.<\/p>\n<pre lang=\"python\">#---START OF SCRIPT\r\nif __name__ == '__main__':\r\n    #Lets accept some command line options from the user\r\n    #We have chosen to use the Python module optparse \r\n    usage = \"usage: %prog -c  -t  \\nE.g.1: %prog -c C:\\\\tests\\\\conf\\\\test_configuration.ini -t \\\"Nightly Run\\\"\\n---\"\r\n    parser = OptionParser(usage=usage)\r\n    parser.add_option(\"-c\",\"--config\",dest=\"config_file\",help=\"The full path of the configuration file\")\r\n    parser.add_option(\"-t\",\"--test_run\",dest=\"test_run\",help=\"The name of the test run\")\r\n    (options,args) = parser.parse_args()\r\n<\/pre>\n<p><span style=\"font-weight: bold; font-style: inherit;\">STEP 3: Use ConfigParser to read the configuration <\/span><br \/>\n<a href=\"http:\/\/qxf2.com\">Qxf2 Services<\/a> loves, and I mean *loves*, Python. We have chosen to use the module ConfigParser to read our configuration file. Python newbies can use either <a href=\"http:\/\/pymotw.com\/2\/ConfigParser\/\">this link (pmotw)<\/a> or <a href=\"https:\/\/wiki.python.org\/moin\/ConfigParserExamples\">this link (Python wiki)<\/a> to get started with ConfigParser. On our end, we are modifying our Selenium2OnSauce class to look like the snippet below:<\/p>\n<pre lang=\"python\">class Selenium2OnSauce(unittest.TestCase):\r\n    \"Example class written to run Selenium tests on Sauce Labs\"\r\n    def __init__(self,config_file,test_run):\r\n        \"Constructor: Accepts the configuration file and the test run name as parameters\"\r\n        self.config_file = config_file\r\n        self.test_run = test_run\r\n\r\n    def setUp(self):\r\n        \"Setup for this test involves spinning up the right virtual machine on Sauce Labs\"\r\n        parser = SafeConfigParser() #THE MAGIC STARTS HERE\r\n        parser.read(self.config_file) \r\n        \r\n        if parser.get(self.test_run, 'browser').lower()=='chrome':\r\n            desired_capabilities = webdriver.DesiredCapabilities.CHROME\r\n        if parser.get(self.test_run, 'browser').lower()in ['firefox','ff']:\r\n            desired_capabilities = webdriver.DesiredCapabilities.FIREFOX\r\n        if parser.get(self.test_run, 'browser').lower()in ['internet explorer','ie']:\r\n            desired_capabilities = webdriver.DesiredCapabilities.INTERNETEXPLORER\r\n        \r\n        desired_capabilities['version'] = parser.get(self.test_run, 'version')\r\n        desired_capabilities['platform'] = parser.get(self.test_run, 'platform')\r\n        desired_capabilities['name'] = parser.get(self.test_run, 'name') \r\n        desired_capabilities['build'] = parser.get(self.test_run, 'build')\r\n        desired_capabilities['tags'] = parser.get(self.test_run, 'tag')\r\n        desired_capabilities['record-video'] = parser.get(self.test_run, 'record-video')\r\n        desired_capabilities['video-upload-on-pass'] = parser.get(self.test_run, 'video-upload-on-pass')\r\n        desired_capabilities['record-screenshots'] = parser.get(self.test_run, 'record-screenshots')\r\n        \r\n        self.driver = webdriver.Remote(\r\n            desired_capabilities=desired_capabilities,\r\n            command_executor=\"http:\/\/$USERNAME:$ACCESS-ID@ondemand.saucelabs.com:80\/wd\/hub\"\r\n        )\r\n        self.driver.implicitly_wait(30)\r\n<\/pre>\n<p><span style=\"font-weight: bold; font-style: inherit;\">STEP 4. Run the tests <\/span><br \/>\nBringing everything together, your script should look something like the code below<\/p>\n<pre lang=\"python\">import logging, unittest, sys\r\nfrom optparse import OptionParser\r\nfrom selenium import webdriver\r\nfrom selenium.webdriver.common.keys import Keys\r\nfrom ConfigParser import SafeConfigParser\r\n\r\nclass Selenium2OnSauce(unittest.TestCase):\r\n    \"Example class written to run Selenium tests on Sauce Labs\"\r\n    def __init__(self,config_file,test_run):\r\n        \"Constructor: Accepts the configuration file and the test run name as parameters\"\r\n        self.config_file = config_file\r\n        self.test_run = test_run\r\n\r\n    def setUp(self):\r\n        \"Setup for this test involves spinning up the right virtual machine on Sauce Labs\"\r\n        parser = SafeConfigParser()\r\n        parser.read(self.config_file)\r\n        \r\n        if parser.get(self.test_run, 'browser').lower()=='chrome':\r\n            desired_capabilities = webdriver.DesiredCapabilities.CHROME\r\n        if parser.get(self.test_run, 'browser').lower()in ['firefox','ff']:\r\n            desired_capabilities = webdriver.DesiredCapabilities.FIREFOX\r\n        if parser.get(self.test_run, 'browser').lower()in ['internet explorer','ie']:\r\n            desired_capabilities = webdriver.DesiredCapabilities.INTERNETEXPLORER\r\n        \r\n        desired_capabilities['version'] = parser.get(self.test_run, 'version')\r\n        desired_capabilities['platform'] = parser.get(self.test_run, 'platform')\r\n        desired_capabilities['name'] = parser.get(self.test_run, 'name')\r\n        desired_capabilities['build'] = parser.get(self.test_run, 'build')\r\n        desired_capabilities['tags'] = parser.get(self.test_run, 'tag')\r\n        desired_capabilities['record-video'] = parser.get(self.test_run, 'record-video')\r\n        desired_capabilities['video-upload-on-pass'] = parser.get(self.test_run, 'video-upload-on-pass')\r\n        desired_capabilities['record-screenshots'] = parser.get(self.test_run, 'record-screenshots')\r\n        \r\n        self.driver = webdriver.Remote(\r\n            desired_capabilities=desired_capabilities,\r\n            command_executor=\"http:\/\/$USERNAME:$ACCESS_KEY@ondemand.saucelabs.com:80\/wd\/hub\"\r\n        )\r\n        self.driver.implicitly_wait(30)\r\n\r\n        \r\n    def test_search_in_python_org(self):\r\n        \"An example test: Visit python.org and search for BeautifulSoup\"\r\n        #Go to the URL \r\n        self.driver.get(\"http:\/\/www.python.org\")\r\n\r\n        #Assert that the title is correct\r\n        self.assertIn(\"Python\", self.driver.title)\r\n\r\n        #Identify the xpath and send the string you want\r\n        elem = self.driver.find_element_by_xpath(\"\/\/input[@id='id-search-field']\")\r\n        print \"About to search for the string BeautifulSoup on python.org\"\r\n        elem.send_keys(\"BeautifulSoup\")\r\n        elem.send_keys(Keys.RETURN)\r\n        print \"Search for the string BeautifulSoup on python.org was successful\"\r\n\r\n        \r\n    def tearDown(self):\r\n        \"Finish the test run\"\r\n        self.driver.quit()\r\n\r\n\r\n#---START OF SCRIPT\r\nif __name__ == '__main__':\r\n    #Lets accept some command line options from the user\r\n    #We have chosen to use the Python module optparse \r\n    usage = \"usage: %prog -c  -t  \\nE.g.1: %prog -c C:\\\\tests\\\\conf\\\\test_configuration.ini -t \\\"Nightly Run\\\"\\n---\"\r\n    parser = OptionParser(usage=usage)\r\n    parser.add_option(\"-c\",\"--config\",dest=\"config_file\",help=\"The full path of the configuration file\")\r\n    parser.add_option(\"-t\",\"--test_run\",dest=\"test_run\",help=\"The name of the test run\")\r\n    (options,args) = parser.parse_args()\r\n\r\n    #Create a test obj with our parameters\r\n    test_obj = Selenium2OnSauce(config_file=options.config_file,test_run=options.test_run)\r\n\r\n    #We are explicitly calling setup snd tearDown because what we are showing is technically not a unit test\r\n    test_obj.setUp()\r\n\r\n    #Run the test itself. NOTE: This is NOT a unit test\r\n    test_obj.test_search_in_python_org()\r\n\r\n    #We are explicitly calling setup snd tearDown because what we are showing is technically not a unit test\r\n    test_obj.tearDown()\r\n<\/pre>\n<p>You can run the test script the normal way you do. We run it via the command prompt. Here is a screenshot from our machine.<\/p>\n<figure id=\"attachment_368\" aria-describedby=\"caption-attachment-368\" style=\"width: 640px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/05\/sauce_labs_additional_config_cmd.jpg\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-368\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/05\/sauce_labs_additional_config_cmd.jpg\" alt=\"Run the test on Sauce Labs\" width=\"640\" height=\"356\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/05\/sauce_labs_additional_config_cmd.jpg 640w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/05\/sauce_labs_additional_config_cmd-300x166.jpg 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption id=\"caption-attachment-368\" class=\"wp-caption-text\">Here is a screenshot from our machine.<\/figcaption><\/figure>\n<p><span style=\"font-weight: bold; font-style: inherit;\">STEP 5: Check the result on Sauce Labs <\/span><br \/>\nYou can see the results on your web account. Login to your Sauce Labs account and you should see a result table like the screen shot below.<\/p>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/05\/Part3_Result1.jpg\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-376 size-large\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/05\/Part3_Result1-1024x154.jpg\" alt=\"Result on Sauce Labs\" width=\"474\" height=\"71\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/05\/Part3_Result1-1024x154.jpg 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/05\/Part3_Result1-300x45.jpg 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/05\/Part3_Result1.jpg 1341w\" sizes=\"auto, (max-width: 474px) 100vw, 474px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<hr>\n<p>Voila! You can run your automated Selenium test runs with different configurations.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Problem: Different test runs require different configuration on Sauce Labs. In this post, we will show you how to make your automated test runs to use specific configuration parameters of Sauce Labs. TWEAKING SAUCE LABS CONFIGURATION Some nightly automated selenium checks that we run at Qxf2 Services need to be run only on specific browsers. Further some of our nightly [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[38,15,18,31,30],"tags":[37,24,33,32,34],"class_list":["post-347","post","type-post","status-publish","format-standard","hentry","category-automation","category-how-to","category-python","category-sauce-labs","category-selenium","tag-cross-browser-automation","tag-python-2","tag-sauce-labs-2","tag-selenium-2","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/347","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=347"}],"version-history":[{"count":34,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/347\/revisions"}],"predecessor-version":[{"id":6385,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/347\/revisions\/6385"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}