總結一下端對端測試中常用的 Puppeteer 操作,比如模擬用戶輸入、執行 JavaScript 腳本、獲取某個 DOM 節點中的文本等。
讓所有操作可見
還記得上篇博客中的端對端測試的動圖演示嗎?
想實現這個效果,就需要將 Puppeteer 的 headless
選項設為 false
,並將 slowMo
設為 20-100 中的某個值,前者使得所有瀏覽器自動化操作可見,后者控制了動作之間的間隔,使其變慢,從而通過人眼可以看清每步操作。示例代碼:
browser = await puppeteer.launch({ headless: false, slowMo: 20 });
導航到某個頁面
這個操作太常用了!第一步是啟動瀏覽器,那么第二步就是導航到某個頁面,代碼示例:
page = await browser.newPage(); await page.goto('https://baidu.com');
上述代碼會開啟一個新頁面,並將其導航到 https://baidu.com
。
等待某個 DOM 節點出現
在進行某些頁面操作前,我們必須要等待指定的 DOM 加載完成后才能操作,比如,一個 Input 沒有加載出來時,你是無法在里面輸入字符的等等。在 Puppeteer 中,你可以使用 page.waitForSelector
和選擇器來等待某個 DOM 節點出現:
await page.waitForSelector('#loginForm');
上述代碼會等待 ID 為 loginForm
的節點出現。
等待幾毫秒
有時候,你找不到某個特定的時刻,只能通過時間間隔來確定,那么此時你可以使用 page.waitFor(number)
來實現:
await page.waitFor(500);
上述代碼會等待 500 毫秒。
等待某個 JavaScript 函數返回 true
有時候,你需要等待某個復雜的時刻,這個時刻只能通過一些復雜的 JavaScript 函數來判斷,那么此時你可以使用 page.waitFor(Function)
來實現:
await page.waitFor(()=> !document.querySelector('.ant-spin.ant-spin-spinning'));
上述代碼會等待 Antd 中的旋轉圖標消失。
向某個 Input 中輸入字符
為了模擬用戶登陸或僅僅就是輸入某個表單,我們經常會向某個 Input 中輸入字符,那么我們可以使用這個方法:
await page.type('#username', 'lewis');
上述代碼向 ID 為 username
的 Input 中輸入了 lewis
。值得一提的是,該方法還會觸發 Input 的 keydown
、 keypress
, 和 keyup
事件,所以如果你有該事件的相關功能,也會被測試到哦,是不是很強大?
點擊某個節點
在 Puppeteer 中模擬點擊某個節點,非常簡單,只需要:
await page.click('#btn-submit');
上述代碼點擊了 ID 為 btn-submit
的節點。
在瀏覽器中執行一段 JavaScript 代碼
有時候我們需要在瀏覽器中執行一段 JavaScript 代碼,此時你可以這樣寫:
page.evaluate(()=> alert('1'));
上述代碼會在瀏覽器執行 alert('1')
。
獲取某一個節點的某個屬性
有時候我們需要獲取某個 Input 的 value
,某個鏈接的 href
,某個節點的文本 textContent
,或者 outerHTML
,那么你可以使用這個方法:
const searchValue = await page.$eval('#search', el => el.value); const preloadHref = await page.$eval('link[rel=preload]', el => el.href); const text = await page.$eval('.text', el => el.textContent); const html = await page.$eval('.main-container', e => e.outerHTML);
獲取某一類節點的某個屬性集合
有時候我們需要獲取某一類節點的某個屬性集合,那么你可以這么寫:
const textArray = await page.$$eval('.text', els => Array.from(els).map(el=> el.textContent));
上述代碼將頁面中所有類為 text
的節點中的文本拼裝為數組放到了 textArray
中。