美文网首页
[笔记]Selenium Testing Tools Cookb

[笔记]Selenium Testing Tools Cookb

作者: elf_fff | 来源:发表于2020-01-21 23:44 被阅读0次

    Chapter9 Extending Selenium

    9.1 Creating an extension class for web tables

    Create a new class WebTable, which we will use to implement support for the table elements

    from selenium import webdriver
    from selenium.common.exceptions import NoSuchElementException
    
    class WebTable:
        def __init__(self,webTable):
            self._webTable = webTable
    
        # retrieve rows
        def getRowCount(self):
            self.tableRows = self._webTable.find_elements_by_tag_name('tr')
            return len(self.tableRows)
    
        #retrieve columns
        def getColumnCount(self):
            self.tableRows = self._webTable.find_elements_by_tag_name('tr')
            self.headerRow = self.tableRows[0]
            self.tableCols = self.headerRow.find_elements_by_tag_name('td')
            return len(self.tableCols)
    
        # retrieve data from a specific cell of the table
        def getCellData(self,rowIdx,colIdx):
            self.tableRows = self._webTable.find_elements_by_tag_name('tr')
            self.currentRow = self.tableRows[rowIdx-1]
            self.tableCols = self.currentRow.find_elements_by_tag_name('td')
            self.cell = self.tableCols[colIdx-1]
            return self.cell.text
    
        # retrieve the cell editor element
        def getCellEditor(self,rowIdx,colIdx,editorIdx):
            try:
                self.tableRows = self._webTable.find_elements_by_tag_name('tr')
                self.currentRow = self.tableRows[rowIdx-1]
                self.tableCols = self.currentRow.find_elements_by_tag_name('td')
                self.cell = self.tableCols[colIdx-1]
                self.cellEditor = self.cell.find_elements_by_tag_name('input')[editorIdx]
                return self.cellEditor
            except NoSuchElementException:
                raise NoSuchElementException('Failed to get cell editor')
    

    Create a Test Class:

    import unittest
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from WebTable import WebTable
    
    class WebTableTests(unittest.TestCase):
        def setUp(self):
            chrome_options = Options()
            chrome_options.add_argument('--no-sandbox')   #让chrome在root权限下跑
            chrome_options.add_argument('--disable-dev-shm-usage') 
            chrome_options.add_experimental_option('useAutomationExtension',False)
            self.driver = webdriver.Chrome(executable_path='D:/elf_private/test/chromedriver',options=chrome_options)
            self.driver.implicitly_wait(30)
            self.driver.maximize_window()
            self.driver.get("file:///D:/elf_private/test/sele/table_example.html")
    
        def testWebTableTest(self):
            self.table = WebTable(self.driver.find_element_by_tag_name('table'))
            print('Table Row Count: ' + str(self.table.getRowCount()))
            print('Table Column Count: ' + str(self.table.getColumnCount()))
            print('Row3 Col1 is ' + self.table.getCellData(2,1))
    
        def tearDown(self):
            self.driver.quit()
    
    if __name__ == '__main__':
        unittest.main()
    

    9.2 Creating an extension for the jQueryUI tab widget

    Example jQuery UI tabs widget: http://jqueryui.com/demos/tabs/
    Create a JQueryUITab class to represent the tab widget

    from selenium import webdriver
    
    class JQueryUITab:
        def __init__(self,jQueryUITab):
            self._jQueryUITab = jQueryUITab
    
        def getTabCount(self):
            self.tabs = self._jQueryUITab.find_elements_by_css_selector(".ui-tabs-nav > li")
            return len(self.tabs)
    
        def getSelectedTab(self):
            self.tab = self._jQueryUITab.\
            find_element_by_css_selector(".ui-tabs-nav > li[class*='ui-state-active']")
            return self.tab.text
    
        def selectTab(self,driver,tabName):
            self.idx = 0
            self.found = False
            self.tabs = self._jQueryUITab.find_elements_by_css_selector(".ui-tabs-nav > li")
            for tab in self.tabs:
                if tab.text == tabName:
                    driver.execute_script(\
                        "jQuery(arguments[0]).tabs().tabs('option','active',arguments[1]);",\
                        self._jQueryUITab,self.idx)
                    self.found = True
                    break
                idx += 1
            if self.found == False:
                raise IllegalArgumentException("Could not find tab '" + tabName +"'")
    

    test code:

    import unittest
    from selenium import webdriver
    from JQueryUITab import JQueryUITab
    
    class WebTableTests(unittest.TestCase):
        def setUp(self):
            self.driver = webdriver.Firefox(executable_path='/usr/local/bin/geckodriver')
            self.driver.implicitly_wait(30)
            self.driver.maximize_window()
            self.driver.get("file:///Users/elf/selenium/jquery/index.html")
    
        def testJianShu(self):
            self.tab = JQueryUITab(self.driver.find_element_by_css_selector("div#tabs"))
            print(str(self.tab.getTabCount()))
            self.tab.selectTab(self.driver,"First")
            print(self.tab.getSelectedTab())
    
        def tearDown(self):
            self.driver.quit()
    
    if __name__ == '__main__':
        unittest.main()
    

    9.3 Implementing an extension for the WebElement object to set the element attribute values

    Setting an element's attribute can be useful in various situations where the test needs to manipulate properties of an element. For example, for a masked textbox, the send_keys() method may not work well, and setting the value of the textbox will help to overcome these issues.
    setAttribute() method:

    class WebElementExtender:
        @staticmethod
        def setAttribute(driver,element,attributeName,value):
            driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])",\
                element,attributeName,value)
    

    An example on using this method:
    In this case, this can be done by clear() and send_keys()

    search = driver.find_element_by_id("q")
    WebElementExtender.setAttribute(driver,search,"placeholder","abc")
    

    9.4 Implementing an extension for the WebElement object to highlight elements

    highlightElement method

    @staticmethod
    def highlightElement(driver,element):
        driver.execute_script("arguments[0].setAttribute('style',arguments[1]);",\
            element,"background:green ;border:2px solid red;")
    

    An example on using this method:

    search = driver.find_element_by_id("q")
    
    WebElementExtender.highlightElement(driver,search)
    # wait 3s to see the highlight effect
    time.sleep(3)
    search.send_keys("abc")
    

    9.5 Creating an object map for Selenium tests

    Create a .xml file to store the elements

    <elements>
        <element>
            <name>SignUp</name>
            <type>id</type>
            <value>sign_up</value>
        </element>
        <element>
            <name>SignIn</name>
            <type>id</type>
            <value>sign_in</value>
        </element>
        <element>
            <name>Download</name>
            <type>classname</type>
            <value>app-download-btn</value>
        </element>
        <element>
            <name>SearchArea</name>
            <type>name</type>
            <value>q</value>
        </element>
        <element>
            <name>SearchButton</name>
            <type>classname</type>
            <value>search-btn</value>
        </element>
    </elements>
    

    Implement the ObjectMap class to read the xml file and provide the locator information to the test

    from selenium import webdriver
    from xml.dom.minidom import parse
    
    class ObjectMap:
        def __init__(self,mapFile):
            self.domTree = parse(mapFile)
            self.rootNode = self.domTree.documentElement
    
        def getLocator(self,driver,logicalElementName):
            self.locators = self.rootNode.getElementsByTagName("element")
            for locator in self.locators:
                #print(locator.getElementsByTagName("name")[0].childNodes[0].data)
                if locator.getElementsByTagName("name")[0].childNodes[0].data == logicalElementName:
                    try:
                        self.locatorType = locator.getElementsByTagName("type")[0].childNodes[0].data
                        self.locatorValue = locator.getElementsByTagName("value")[0].childNodes[0].data
                        return self.getLocatorByType(driver)
                    except Exception:
                        raise Exception("Failed to generate locator for '" + logicalElementName + "'")
    
        def getLocatorByType(self,driver):
            if self.locatorType.lower() == "id":
                return driver.find_element_by_id(self.locatorValue)
            elif self.locatorType.lower() == "name":
                return driver.find_element_by_name(self.locatorValue)
            elif self.locatorType.lower() == "classname":
                return driver.find_element_by_class_name(self.locatorValue)
            elif self.locatorType.lower() == "linktext":
                return driver.find_element_by_link_text(self.locatorValue)
            elif self.locatorType.lower() == "partiallinktext":
                return driver.find_element_by_partial_link_text(self.locatorValue)
            elif self.locatorType.lower() == "css":
                return driver.find_element_by_css_selector(self.locatorValue)
            elif self.locatorType.lower() == "xpath":
                return driver.find_element_by_xpath(self.locatorValue)
            elif self.locatorType.lower() == "tagname":
                return driver.find_element_by_tag_name(self.locatorValue)
            else:
                raise Exception("Locator Type '" + self.locatorType +"' not supported!")
    

    Create a test code:

    import unittest
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from ObjectMap import ObjectMap
    
    class WebTableTests(unittest.TestCase):
        def setUp(self):
            chrome_options = Options()
            chrome_options.add_argument('--no-sandbox')   #让chrome在root权限下跑
            chrome_options.add_argument('--disable-dev-shm-usage') 
            chrome_options.add_experimental_option('useAutomationExtension',False)
            self.driver = webdriver.Chrome(executable_path='D:/elf_private/test/chromedriver',options=chrome_options)
            self.driver.implicitly_wait(30)
            self.driver.maximize_window()
            #self.driver.get("file:///D:/elf_private/test/sele/table_example.html")
            self.driver.get("https://www.jianshu.com")
    
        def testJianShu(self):
            self.map = ObjectMap('mapFile.xml')
            print(self.map.getLocator(self.driver,"SignUp").text)
            print(self.map.getLocator(self.driver,"SignIn").text)
            print(self.map.getLocator(self.driver,"Download").text)
            Search_Area = self.map.getLocator(self.driver,"SearchArea")
            Search_Area.send_keys("abc")
            Button = self.map.getLocator(self.driver,"SearchButton")
            Button.click()
    
        def tearDown(self):
            self.driver.quit()
    
    if __name__ == '__main__':
        unittest.main()
    

    9.6 Capturing screenshots of elements in the Selenium WebDriver

    There are screenshot APIs in selenium for Python. So no need to create interface ourselves ^_^

    • selenium.webdriver.remote.webdriver
      • get_screenshot_as_base64()
      • get_screenshot_as_file(filename)
      • get_screenshot_as_png()
    • selenium.webdriver.remote.webelement
      • screenshot(filename)
      • screenshot_as_base64
      • screenshot_as_png
    button = driver.find_element_by_id("sign_up")
    # get the screenshot of the button
    button.screenshot('signup.png')
    # get the screenshot of the current window
    driver.get_screenshot_as_file('currentwindow.png')
    

    9.7 Comparing images in Selenium

    use PIL module for python
    Implement Compare class to compare two images

    from PIL import Image
    from PIL import ImageChops
    
    class Compare:
        @staticmethod
        def CompareImage(PathOne,PathTwo,DiffPath):
            ImgOne = Image.open(PathOne)
            ImgTwo = Image.open(PathTwo)
            try:
                DiffImg = ImageChops.difference(ImgOne,ImgTwo)
                if DiffImg.getbbox() is None:
                    print("Images are same!")
                else:
                    DiffImg.save(DiffPath)
            except ValueError as e:
                raise ValueError("Paste another image into this image.")
    

    test code:

    self.driver.get_screenshot_as_file("New.png")
    Compare.CompareImage("Base.png","New.png","Diff.png")
    

    9.8 Measuring performance with the Navigation Timing API

    Navigation Timing is a W3C Standard JavaScript API to measure performance on the Web. The API provides a simple way to get accurate and detailed timing statistics natively for page navigation and load events. It is available on IE9, Google Chrome, Firefox and WebKit-based browsers.
    The API is accessed via the properties of the timing interface of the window.performance object using JavaScript

    driver.get("https://www.jianshu.com")
    # get the Load Event End
    loadEventEnd = driver.execute_script("return window.performance.timing.loadEventEnd")
    # get the Navigation Event Start
    navigationStart = driver.execute_script("return window.performance.timing.navigationStart")
    # print Page Load Time
    print("Page Load Time is " + str((loadEventEnd - navigationStart)/1000) + " seconds.")
    

    相关文章

      网友评论

          本文标题:[笔记]Selenium Testing Tools Cookb

          本文链接:https://www.haomeiwen.com/subject/rseyzctx.html