Playwright 模擬微信瀏覽器

杨腾發表於2024-05-06

前言

我正在使用 Playwright 對公司的 H5 專案進行 UI 自動化測試,但是這個 H5 是基於微信瀏覽器上實現,只是單純的使用 Playwright 進行模擬測試的話會遇到不少卡點,經過一番折騰後終於完成了模擬測試的實現,這邊文章主要是分享下我所遇到的問題和處理方式,希望能幫助遇到同樣問題的小夥伴。

整個實現過程中主要解決了如下問題:

  • 1.使用 Playwright 模擬手機端瀏覽器解析度
  • 2.修改瀏覽器簽名以跳過微信訪問認證
  • 3.Mock 驗籤介面繞過登入環節
  • 4.Mock 微信瀏覽器內建物件 wx 規避異常

前兩個問題都比較簡單,翻閱網上帖子都可以找到類似答案,後兩個問題在每個系統上處理的方案可能都不一樣,下邊分享下處理如上問題的思路與方式

處理方案

1.使用 Playwright 模擬手機端瀏覽器解析度

日常我們使用 web 自動化測試工具開啟任一個 H5 頁面,預設使用的都是 PC 端的解析度,如下圖這個聯通的廣告頁,它會變形,不方便測試和報告截圖

這個問題,使用 Playwright 的瀏覽器初始化引數 devices 就可以解決,它可以模擬的裝置解析度與 Chrome 一致,下邊是實現測試的部分程式碼,模擬的是 iPhone 12 Pro:

iphone = context.play_sync.devices["iPhone 12 Pro"]
context.context = context.browser.new_context(**iphone)

完成後可以達到如下解析度

2.修改瀏覽器簽名以跳過微信訪問認證

正常我們直接訪問公眾號的內容,會出現如下提示 “請使用微信瀏覽器開啟連結”。

這個提示一般是對於瀏覽器簽名 user_agent 的驗證,只需要修改預設的請求頭帶上微信瀏覽器的標識即可。在 Playwright 中的處理則是變更模擬裝置的 ['user_agent'] 引數,下邊是實現測試的部分程式碼:

iphone['user_agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) WindowsWechat(0x6309080f) XWEB/8461 Flue'
iphone = context.play_sync.devices["iPhone 12 Pro"]
context.context = context.browser.new_context(**iphone)

3.Mock 驗籤介面繞過登入環節

如上兩個方案足以訪問大多數的公眾號平臺,但是對於一些需要進行微信授權登入的平臺就需要進一步的處理,我這用手頭的系統簡單舉個例子,當前系統的整個鑑權驗證過程大致如下:

可以看到,整個鑑權過程中,系統在拿到 openID 或 unionID 等身份標識後,就不在與微信介面服務進行互動了。我們只需要 mock 返回自定義登入狀態的介面,冒充開發者伺服器返回預先定義好的身份標識就可以實現登入。

下邊是實現 mock 的部分程式碼(每個系統都不一樣,思路供大家參考):
我這準備了一個 handle 檔案儲存預定義好的身份響應資料,這樣在前端請求登入的時候,我可以冒充開發者伺服器告知前端它已登入成功

{
  "code": "000000",
  "message": "成功",
  "debugTrace": null,
  "data": {
    "access_token": "76_JVpSad55vObpDKF_UE4HlMExZTtwX6A66WxnWKKY0VAQjTefJmOWfxWi0ap9phdb6kLkABHORZ3ikfYD_9AxAJ4K8E0CjlEMQlgCKuq1EBs",
    "openid": "o33NMs-U0tpD2IB8Oxx11sZwTJ2Y",
    "unionid": "oe-p46Fl1Elb3K7ku2-22cbrZXcA",
  }
}

在 Playwright 註冊 mock

context.main_page = MainPage(context.page)
#*/**/public/mobile/login是系統前端的登入請求
context.page.route("*/**/public/mobile/login", handle)

4.Mock 微信瀏覽器內建物件 wx 規避異常

處理完鑑權後,系統前端可能還存在一些微信瀏覽器的內建物件呼叫,如果執行過程中恰好呼叫了這些方法,會因為 chrome 瀏覽器沒有內建這些物件而導致報錯,常見的可能 window.wx。
遇見這種情況的話,可以使用 add_init_script,在頁面上下文建立時注入自建的物件,可以規避一部分報錯。
下邊是部分程式碼

async def mock_wx_sdk():  
    # 返回一個模擬 wx 物件的 JavaScript 字串  
    return """  
        Object.defineProperty(window, 'wx', {  
            value: {  
                config: function(options) {  
                    // 模擬 wx.config 的邏輯  
                    console.log('Mock wx.config called with options:', options);  
                },  
                ready: function(callback) {  
                    // 假設 ready 是立即執行的  
                    callback();  
                },  
                error: function(callback) {  
                    // 模擬錯誤處理的邏輯  
                },  
                // ... 其他需要模擬的 wx API  
            },  
            writable: false, // 防止被重寫  
            enumerable: true, // 使其可列舉  
            configurable: false // 防止被刪除或修改  
        });  
    """  

async def test_webpage_with_mock_wx():  
    async with async_playwright() as playwright:  
        browser = await playwright.chromium.launch()  
        context = await browser.new_context()  
        page = await context.new_page()  

        # 在頁面上下文建立時注入模擬的 wx 物件  
        await page.add_init_script(mock_wx_sdk())  

        # 載入網頁  
        await page.goto('your-webpage-url')

相關文章