poium一直我在維護的一個開源項目,它的定位是以極簡的方式在自動化項目中Page Objects設計模式。我在以前的文章中也有介紹。css
本篇文章主要介紹一個JavaScript元素操做的封裝原理。python
爲何要封裝JavaScript的API?git
由於有些場景下Selenium提供的API並不能知足咱們需求。好比,滑動瀏覽滾動條,控制元素的顯示/隱藏,日曆控件的操做等,均可以經過JavaScrip實現,並且Selenium爲咱們提供了 execute_script()
方法能夠用來運行JavaScrip腳本。github
先看舊的設計代碼和調用。web
# =====封裝代碼====== class Page(object): def __init__(self, driver): self.driver = driver def set_text(self, css_selector, value): """ JavaScript API, Only support css positioning Simulates typing into the element. """ js = """var elm = document.querySelector("{css}"); elm.style.border="2px solid red"; elm.value = "{value}";""".format(css=css_selector(), value=value) self.driver.execute_script(js) def click(self, css_selector): """ JavaScript API, Only support css positioning Click element. """ js = """var elm = document.querySelector("{css}"); elm.style.border="2px solid red"; elm.click();""".format(css=css_selector()) self.driver.execute_script(js) class CSSElement(object): def __init__(self, css): self.css = css def __call__(self): return self.css # =======調用代碼============== from selenium import webdriver class baiduPage(Page): search_input = CSSElement("#kw") search_button = CSSElement("#su") dr = webdriver.Chrome() dr.get("http://www.baidu.com") page = baiduPage(dr) page.set_text(page.search_input, "poium") page.click(page.search_button) dr.close()
若是你看不懂上面的封裝代碼的話,能夠重點看下面的調用代碼,針對元素的點擊和輸入。設計模式
page.set_text() page.click()
表示操做的方法,在Page
類中實現。學習
page.search_input page.search_button
表示操做的對象,在Page
的繼承類baiduPage
中定義。設計
page.set_text(page.search_input, "poium") page.click(page.search_button)
操做的動做 和 操做的對象 都是以 page.
調用,萬一我要操做的對象也命名爲 click
那不就和操做的動做 傻傻分不清楚了, 因此,這樣的語法不是很怪麼?code
因此,這個問題一直困擾我挺久的,我一直沒想到更好的設計。orm
直到前幾天又從新學習了Python的 __get__
和 __set__
內置方法,才把這個問題解決。
# =====封裝代碼====== class Page(object): def __init__(self, driver): self.driver = driver class CSSElement(object): driver = None def __init__(self, css): self.css = css def __get__(self, instance, owner): if instance is None: return None global driver driver = instance.driver return self def set_text(self, value): global driver driver.execute_script("""var elm = document.querySelector("{css}"); elm.style.border="2px solid red"; elm.value = "{value}";""".format(css=self.css, value=value)) def click(self): global driver driver.execute_script("""var elm = document.querySelector("{css}"); elm.style.border="2px solid red"; elm.click();""".format(css=self.css)) # =======調用代碼============== from selenium import webdriver class baiduPage(Page): search_input = CSSElement("#kw") search_button = CSSElement("#su") dr = webdriver.Chrome() dr.get("http://www.baidu.com") page = baiduPage(dr) page.search_input.set_text("poium") page.search_button.click() dr.close()
若是看不懂封裝代碼的話,直接看調用代碼。
page.search_input.set_text("poium") page.search_button.click()
page
表示頁面; search_input
表示頁面上的某個對象; set_text()
表示對象的動做。
這樣的語法是否是要比前面好了不少?而保持了與Selenium API 封裝的語法一致性。
項目地址:https://github.com/defnngj/poium
作開源項目的生活就是這麼樸實無華,且有趣!