《最新出爐》系列初窺篇-Python+Playwright自動化測試-5-元素定位大法-上篇

1.簡介

說到元素定位,小夥伴或者童鞋們肯定會首先想到 selenium 的八大元素定位大法。同理Playwright也有自己的元素定位的方法。今天就給小夥伴或者童鞋們講解和分享一下Playwright的元素定位方法。

宏哥對UI自動化的理解:定位元素--->操作元素---->斷言。

2.定位器

定位器(Locator)是 Playwright 的自動等待和重試能力的核心部分。定位器是一種隨時在網頁上查找元素的方法,用於在元素上執行諸如 .click、.fill 之類的操作。可以使用 page.locator(selector, **kwargs) 方法創建自定義定位器。

選擇器(Selector)是用於創建定位器的字符串。Playwright 支持許多不同的選擇器,比如 Text、CSS、XPath 等。閱讀 in-depth guide 文檔,瞭解更多關於可用的選擇器以及如何進行選擇的信息。

3.內置定位器

這些是 playwright 推薦的內置定位器。

  • page.get_by_role()通過顯式和隱式可訪問性屬性進行定位。
  • page.get_by_text()通過文本內容定位。
  • page.get_by_label()通過關聯標籤的文本定位表單控件。
  • page.get_by_placeholder()按佔位符定位輸入。
  • page.get_by_alt_text()通過替代文本定位元素,通常是圖像。
  • page.get_by_title()通過標題屬性定位元素。
  • page.get_by_test_id()根據data-testid屬性定位元素(可以配置其他屬性)。

當然除了這些,還有其他定位方法,selenium的8種by元素定位,id、xpath、css等都可使用,還有W3C標準規定的webDriver協議爲5種定位方式CSS、Link text、Partial link text、Tag name、XPath

playwright把這些定位歸類成3種,分別是:css、xpath、text。

如:

page.locator("xpath=//h2")
page.locator("text=文本輸入") 
page.locator("#s-usersetting-top")
page.locator("input[name=\"wd\"]").click()
page.get_by_role("button", name="百度一下").click()
page2.get_by_placeholder("唱片名、表演者、條碼、ISRC").click()
page2.get_by_text("或者,親自來幫豆瓣添加:").click()

官方文檔給出一個登錄系統的使用示例如下:

page.get_by_label("User Name").fill("John")

page.get_by_label("Password").fill("secret-password")

page.get_by_role("button", name="Sign in").click()

expect(page.get_by_text("Welcome, John!")).to_be_visible()

3.1角色定位-page.get_by_role()

Playwright帶有多個內置定位器。爲了使測試具有彈性,我們建議優先考慮面向用戶的屬性和顯式協定,例如page.get_by_role()。例如:以下 DOM 結構。

button通過名稱爲“登錄”的角色定位元素。

page.get_by_role("button", name="Sign in").click()

每次將定位器用於操作時,都會在頁面中找到一個最新的 DOM 元素。在下面的代碼片段中,底層 DOM 元素將被定位兩次,一次在每個動作之前。這意味着如果 DOM 由於重新渲染而在調用之間發生變化,則將使用與定位器對應的新元素。

locator = page.get_by_role("button", name="Sign in")

locator.hover()
locator.click()

請注意,所有創建定位器的方法(例如page.get_by_label() )也可用於Locator和FrameLocator類,因此您可以將它們鏈接起來並迭代地縮小定位器的範圍。

locator = page.frame_locator("my-frame").get_by_role("button", name="Sign in")

locator.click()

page.get_by_role ()定位器反映了用戶和輔助技術如何感知頁面,例如某個元素是按鈕還是複選框。按角色定位時,通常還應傳遞可訪問的名稱,以便定位器準確定位元素。

例如,考慮以下 DOM 結構。

 您可以通過其隱式角色定位每個元素:

expect(page.get_by_role("heading", name="Sign up")).to_be_visible()

page.get_by_role("checkbox", name="Subscribe").check()

page.get_by_role("button", name=re.compile("submit", re.IGNORECASE)).click()

角色定位器包括按鈕、複選框、標題、鏈接、列表、表格等,並遵循ARIA 角色、ARIA 屬性和可訪問名稱的 W3C 規範。

請注意:許多html元素如:<button>都有一個隱式定義的角色,該角色可被角色定位器識別。

請注意,角色定位器不會取代可訪問性審覈和一致性測試,而是提供有關 ARIA 指南的早期反饋。

3.1.1何時使用角色定位器

我們建議優先使用角色定位器來定位元素,因爲這是最接近用戶和輔助技術感知頁面的方式。

3.2標籤定位-page.get_by_label()

大多數表單控件通常都有專用標籤,可以方便地用於與表單交互。在這種情況下,您可以使用page.get_by_label()通過其關聯標籤定位控件。例如:以下 DOM 結構。

您可以在通過標籤文本定位後填寫輸入:

page.get_by_label("Password").fill("secret")
3.2.1何時使用標籤定位器

定位表單區域時,使用標籤定位器。

3.3佔位符定位-page.get_by_placeholder()

輸入可能具有佔位符屬性,以向用戶提示應輸入的值。您可以使用page.get_by_placeholder()定位此類輸入。例如:以下 DOM 結構。

 您可以在通過佔位符文本定位後填充輸入:

page.get_by_placeholder("[email protected]").fill("[email protected]")
3.3.1何時使用佔位符定位器

在定位沒有標籤但具有佔位符文本的表單元素時,使用此定位器。

3.4文本定位-page.get_by_text()

根據元素包含的文本查找元素。使用page.get_by_text()時,您可以通過子字符串、精確字符串或正則表達式進行匹配。例如:以下 DOM 結構。

 您可以通過元素包含的文本來查找該元素:

expect(page.get_by_text("Welcome, John")).to_be_visible()

設置完全匹配:

expect(page.get_by_text("Welcome, John", exact=True)).to_be_visible()

與正則表達式匹配:

expect(page
    .get_by_text(re.compile("welcome, john", re.IGNORECASE)))
    .to_be_visible()
注意:按文本匹配始終規範化空格,即使完全匹配也是如此。例如,它將多個空格轉換爲一個空格,將換行符轉換爲空格,並忽略前導和尾隨空格。
3.4.1何時使用文本定位器

建議使用文本定位器來查找非交互式元素,如div, span, p 等。對於交互式元素,如請button, a, input, 使用角色定位器。

您還可以按文本進行篩選,這在嘗試在列表中定位特定項目時很有用。

3.5替代文本定位-page.get_by_alt_text()

所有圖像都應該有一個alt描述圖像的屬性。您可以使用page.get_by_alt_text()根據替代文本定位圖像。例如:以下 DOM 結構。

 可以在通過替代文本選項找到圖像後單擊它:

page.get_by_alt_text("playwright logo").click()
3.5.1何時使用替代文本定位器
當您的元素支持替代文本(例如img和area元素)時使用此定位器。

3.6標題定位-page.get_by_title()

使用page.get_by_title()找到具有匹配 title 屬性的元素。例如:以下 DOM 結構。

 您可以在通過標題文本找到它後檢查問題數:

expect(page.get_by_title("Issues count")).to_have_text("25 issues")
3.6.1何時使用標題定位器

當您的元素具有該title屬性時使用此定位器。

3.7測試id定位-page.get_by_test_id()

通過測試 ID 進行測試是最具彈性的測試方式,因爲即使您的文本或屬性角色發生變化,測試仍會通過。QA 和開發人員應該定義明確的測試 ID 並使用page.get_by_test_id()查詢它們。但是,通過測試 ID 進行的測試不是面向用戶的。如果角色或文本值對您很重要,那麼請考慮使用面向用戶的定位器,例如角色定位器和文本定位器。例如:以下 DOM 結構。

 您可以通過它的測試 ID 定位到該元素:

page.get_by_test_id("directions").click()
3.7.1何時使用測試id定位器

當你選擇使用測試id的方法,或者角色、文本無法定位時,你也可以使用測試id進行定位。

3.7.2設置自定義測試id屬性

默認情況下,page.get_by_test_id()將根據data-testid屬性定位元素,但您可以在測試配置中或通過調用selectors.set_test_id_attribute()對其進行配置。

設置測試 ID 以使用自定義數據屬性進行測試。

playwright.selectors.set_test_id_attribute("data-pw")

在您的 html 中,您現在可以使用data-pwtest id 而不是 default data-testid。

 然後像往常一樣定位元素:

page.get_by_test_id("directions").click()

4.CSS或Xpath定位

如果必須使用 CSS 或 XPath 定位器,則可以使用 page.locator()創建一個定位器,該定位器採用描述如何在頁面中定位元素的選擇器。Playwright 支持 CSS 和 XPath 選擇器,並在省略前綴css=或xpath=時自動檢測它們。它會自動判斷你寫的是css還是xpath語法,前提是你語法沒有錯誤。

page.locator("css=button").click()
page.locator("xpath=//button").click()

page.locator("button").click()
page.locator("//button").click()

XPath 和 CSS 選擇器可以綁定到 DOM 結構或實現。當 DOM 結構更改時,這些選擇器可能會中斷。下面的長 CSS 或 XPath 鏈是導致測試不穩定的不良做法的示例:

page.locator(
    "#tsf > div:nth-child(2) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input"
).click()

page.locator('//*[@id="tsf"]/div[2]/div[1]/div[1]/div/div[2]/input').click()

4.1何時使用CSS或Xpath定位器

不建議使用 CSS 和 XPath,因爲 DOM 經常會發生變化,從而導致無彈性測試。相反,請嘗試提出一個接近用戶感知頁面的定位器,例如角色定位器,或使用測試 ID 定義顯式測試協定。

5.文本選擇器定位-text()

文本選擇器是一個非常實用的定位方式,根據頁面上看到的text文本就可以定位了,比如我們經常使用xpath 的文本選擇器定位。

  • 完全匹配文本 //*[text()="北京-宏哥"]
  • 包含某個文本 //*[contains(text(),"北京-宏哥")

playwright 封裝了text文本定位的方式,也可以支持2種文本定位方式

page.click("text=北京-宏哥")
page.click("text='北京-宏哥'")

text=北京-宏哥和text='北京-宏哥'的區別:

  • text=北京-宏哥 沒有加引號(單引號或者雙引號),模糊匹配,對大小寫不敏感
  • text='北京-宏哥' 有引號,精確匹配,對大小寫敏感

text文本除了可以定位a標籤,還可以定位 button 按鈕,input標籤的button 按鈕,有value="百度一下" 文本值

<input type=button value="百度一下">

或者是button 標籤的按鈕

<button>百度一下</button>

6.HTML屬性選擇器定位

HTML 屬性選擇器, 根據html元素的id 定位

page.fill("id=kw", "北京-宏哥")

7.select選擇器組合定位

定位目標元素,我們有時候可以使用>>(兩個大於號)連接不同的selector可組合使用,例如:我們定位百度首頁的登錄

#id 屬性+ css
page.fill('form >> [name="username"]', "北京-宏哥")
page.fill('form >> #TANGRAM__PSP_11__password', "aa123456")
page.click("text=登錄")

form >> [name="username"] 定位方式等價於

#page.fill('form >> [name="username"]', "北京-宏哥")
page.locator("form").locator('[name="username"]').fill("北京-宏哥")

相當於是根據父元素找到子元素了

登錄按鈕的值是value="登錄 > ",可以用text文本定位的方式,模糊匹配到,這種人性化的設計提高了定位的效率。

<input id="TANGRAM__PSP_11__submit" type="submit" value="登錄" class="pass-button pass-button-submit">

8.小結

今天這一篇主要是講解我們日常工作中在使用Playwright進行元素定位的一些比較常用的定位方法的理論基礎知識以及在什麼情況下推薦使用,當然了這不是一成不變的,希望大家在使用中可以靈活的應用。

好了,今天時間也不早了,宏哥就講解和分享到這裏,感謝您耐心的閱讀,希望對您有所幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章