基於Selenium的Web自動化框架增強篇


在寫完上一篇“基於Selenium的Web自動化框架”(http://www.cnblogs.com/AlwinXu/p/5836709.html)之后一直沒有時間重新審視該框架,正好趁着給同事分享的機會,重新分析了一下框架,發現了很多不足之處,所以才有了這篇增強版。

 

到底在框架的哪一部分做了增強呢?這次主要從設計模式的角度來簡單介紹一下。

首先我們來看一下之前是如何書寫頁面模式中的類的:

BasePage:

class BasePage(object):
    """description of class"""

    #webdriver instance
    def __init__(self, driver):
        self.driver = driver

GoogleMainPage:

from BasePage import BasePage

from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

class GoogleMainPage(BasePage):
    """description of class"""
    searchbox = (By.ID,'lst-ib')

    def inputSearchContent(self,searchContent):
        searchBox = self.driver.find_element(*self.searchbox)
        searchBox.send_keys(searchContent+Keys.RETURN)

重新審視之前的實現,我們可以發現在各個子類頁面中,均需要引用相當的selenium類庫(比如webdriver),並且需要用webdriver來定位頁面元素,這就會造成各個子類頁面與selenium類庫有較多的集成,並且也是書寫上的浪費。

現在來看一下做了結構調整的部分呈現:

BasePage:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import StaleElementReferenceException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

class BasePage(object):
    """description of class"""

    #webdriver instance
    def __init__(self, browser='chrome'):
        '''
        initialize selenium webdriver, use chrome as default webdriver
        '''

        if browser == "firefox" or browser == "ff":
            driver = webdriver.Firefox()
        elif browser == "chrome":
            driver = webdriver.Chrome()
        elif browser == "internet explorer" or browser == "ie":
            driver = webdriver.Ie()
        elif browser == "opera":
            driver = webdriver.Opera()
        elif browser == "phantomjs":
            driver = webdriver.PhantomJS()
        try:
            self.driver = driver
        except Exception:
            raise NameError("Not found %s browser,You can enter 'ie', 'ff' or 'chrome'." % browser)

    def findElement(self,element):
        '''
        Find element

        element is a set with format (identifier type, value), e.g. ('id','username')

        Usage:
        self.findElement(element)
        '''
        try:
            type = element[0]
            value = element[1]
            if type == "id" or type == "ID" or type=="Id":
                elem = self.driver.find_element_by_id(value)

            elif type == "name" or type == "NAME" or type=="Name":
                elem = self.driver.find_element_by_name(value)

            elif type == "class" or type == "CLASS" or type=="Class":
                elem = self.driver.find_element_by_class_name(value)

            elif type == "link_text" or type == "LINK_TEXT" or type=="Link_text":
                elem = self.driver.find_element_by_link_text(value)

            elif type == "xpath" or type == "XPATH" or type=="Xpath":
                elem = self.driver.find_element_by_xpath(value)

            elif type == "css" or type == "CSS" or type=="Css":
                elem = self.driver.find_element_by_css_selector(value)
            else:
                raise NameError("Please correct the type in function parameter")
        except Exception:
            raise ValueError("No such element found"+ str(element))
        return elem

    def findElements(self,element):
        '''
        Find elements

        element is a set with format (identifier type, value), e.g. ('id','username')

        Usage:
        self.findElements(element)
        '''
        try:
            type = element[0]
            value = element[1]
            if type == "id" or type == "ID" or type=="Id":
                elem = self.driver.find_elements_by_id(value)

            elif type == "name" or type == "NAME" or type=="Name":
                elem = self.driver.find_elements_by_name(value)

            elif type == "class" or type == "CLASS" or type=="Class":
                elem = self.driver.find_elements_by_class_name(value)

            elif type == "link_text" or type == "LINK_TEXT" or type=="Link_text":
                elem = self.driver.find_elements_by_link_text(value)

            elif type == "xpath" or type == "XPATH" or type=="Xpath":
                elem = self.driver.find_elements_by_xpath(value)

            elif type == "css" or type == "CSS" or type=="Css":
                elem = self.driver.find_elements_by_css_selector(value)
            else:
                raise NameError("Please correct the type in function parameter")
        except Exception:
            raise ValueError("No such element found"+ str(element))
        return elem

    def open(self,url):
        '''
        Open web url

        Usage:
        self.open(url)
        '''
        if url != "":
            self.driver.get(url)
        else:
            raise ValueError("please provide a base url")

    def type(self,element,text):
        '''
        Operation input box.

        Usage:
        self.type(element,text)
        '''
        element.send_keys(text)

    
    def enter(self,element):
        '''
        Keyboard: hit return

        Usage:
        self.enter(element)
        '''
        element.send_keys(Keys.RETURN)
    

    def click(self,element):
        '''
        Click page element, like button, image, link, etc.
        '''
        element.click()


    def quit(self):
        '''
        Quit webdriver
        '''
        self.driver.quit()


    def getAttribute(self, element, attribute):
        '''
        Get element attribute

        '''
        return element.get_attribute(attribute)

    def getText(self, element):
        '''
        Get text of a web element

        '''
        return element.text

    def getTitle(self):
        '''
        Get window title
        '''
        return self.driver.title

    def getCurrentUrl(self):
        '''
        Get current url
        '''
        return self.driver.current_url

    def getScreenshot(self,targetpath):
        '''
        Get current screenshot and save it to target path
        '''
        self.driver.get_screenshot_as_file(targetpath)

    def maximizeWindow(self):
        '''
        Maximize current browser window
        '''
        self.driver.maximize_window()

    def back(self):
        '''
        Goes one step backward in the browser history.
        '''
        self.driver.back()

    def forward(self):
        """
        Goes one step forward in the browser history.
        """
        self.driver.forward()

    def getWindowSize(self):
        """
        Gets the width and height of the current window.
        """
        return self.driver.get_window_size()

    def refresh(self):
        '''
        Refresh current page
        '''
        self.driver.refresh()
        self.driver.switch_to()

    
        

GoogleMainPage:

from BasePage import BasePage

class GoogleMainPage(BasePage):
    """description of class"""
    searchbox = ('ID','lst-ib')

    def __init__(self, browser = 'chrome'):
        super().__init__(browser)
        
    def inputSearchContent(self,searchContent):
        searchBox = self.findElement(self.searchbox)
        self.type(searchBox,searchContent)
        self.enter(searchBox)

Test

所做的改變:

  • 將與Selenium類庫相關的操作做二次封裝,放在BasePage中,其他子類頁面自動繼承相應的操作方法(如findelement,click等等)
  • 封裝了findelement方法,可以根據頁面元素的(類型,值)進行查找,只需要調用一個方法findelement(s),而不需要針對不同的類型調用不同的find方法(fine_element_by_xxxx())
  • 子類頁面不需要引用selenium的類庫,書寫更加簡單易讀
  • 測試用例中也不需要引用selenium的任何類庫,簡單易讀

 

 

代碼已更新到GitHub:https://github.com/AlvinXuCH/WebAutomaiton 歡迎提供改進意見

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM