使用 Macaca 測試 Electron 桌面 App

Super-Ps發表於2019-09-26

繼上一篇分享解決了部分問題,本次分享完整的 Macaca 整合 Eletron APP 測試方案。

Macaca 交付過程分析

為了使 Macaca 有測試 Electron 的能力,回顧之前試驗的方案 selenmiu-webdriver ,其方式是:傳遞 chromeDriver 9515服務埠,啟動該埠建立連線,傳遞 binary 引數,指明 app 的路勁,傳遞 forBrowser 引數,指明平臺型別,所以現在思考的問題是,Macaca 是否通過傳遞同樣的引數能實現?通過 Macaca 官方示例來 分析1下原理,精簡一下程式碼

const wd = require('macaca-wd');
var browser = process.env.browser || 'electron' || 'puppeteer';
browser = browser.toLowerCase();

describe('macaca-test/desktop-browser-sample.test.js', function() {
this.timeout(5 * 60 * 1000);

var driver = wd.promiseChainRemote({
host: 'localhost',
port: process.env.MACACA_SERVER_PORT || 3456
});

before(() => {
return driver
.init({
platformName: 'desktop',
browserName: browser,
userAgent: `Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0 Safari/537.36 Macaca Custom UserAgent`,
deviceScaleFactor: 2
})
.setWindowSize(800, 600);
});

上面程式碼是 Macaca web 端的示例,對應 macaca 服務端的包就是 macaca-chrome ,為什麼用它,因為它是基於 chromedriver 的,與我要做的 electron 整合方案底層服務相同。根據以上一段指令碼來簡要分析1下 macaca 互動過程

  1. 先啟動服務,啟動方式是 命令列輸入 macaca-server 啟動服務時 macaca-cli 執行 macaca-cli-server,之後呼叫 webdriver-server 的 inded.js,然後啟動 koa 服務,載入中介軟體,路由,監聽埠,等待客戶端請求。
  2. 客戶端指令碼引入 macaca-wd,它是 macaca 客戶端支援node.js的包,包括了webdriver的各種操作。
  3. 客戶端呼叫 promiseChainRemote 是 macaca-wd/wd/lib/main.js 檔案的方法,解析傳遞進來的引數,加上 ./promise-webdriver 支援的鏈式呼叫,這裡指的是解析了 host,port兩個引數,並得到了一個driver物件可以鏈式呼叫各種方法。
  4. 進入測試用例套件,呼叫init方法, 該方法在 commands.js ,通過webdriver.js 的 _init 方法傳送指令碼內傳遞的引數到服務端 3456埠, 執行用例之前我們就啟動的服務端,所以一直有監聽。
  5. webdriver-server / responseHandler.js 接受客戶端請求,並返回給客戶端,在服務端命令列可以檢視到詳細的互動資訊。
  6. macaca-chrome 呼叫 macaca-chromedriver.start(caps) , caps 引數就是指令碼 init 裡面的引數,此時 macaca-chromedriver 構造時初始化了一系列屬性,proxyHost, proxyPort, urlBase ,獲取版本,下載預設版本,或者自動下載與瀏覽器對應的 chromedriver 版本,啟動 9515 服務。
  7. macaca-chromedrive 呼叫 proxy.js 代理請求 傳送 status ,session 請求到 9515服務。
  8. 最後總結1下順序:啟動 macaca-server --> macaca-wd --> webdriver-server --> macaca-chrome --> macaca-chromedrive.proxy --> 9515 ,響應按原路返回。

順手附草圖一張,可以根據順序找下原始碼檔案
alt 原始碼檔案圖

熟悉了過程之後要解決 2 個問題:

  1. 如何傳遞 electron 應用的路勁?
  2. 該引數誰處理? 根據移動端示例引數的傳遞可以做為參考,實踐1下,將程式碼改寫為:
before(() => {
return driver
.init({
platformName: 'desktop',
browserName: browser,
app: "/Applications/macaca-electron-builder.app/Contents/MacOS/macaca-electron-builder"
})
});

執行結果報錯了!通過列印 log,引數是已經傳遞到了步驟6,步驟7,引數傳遞到了,但是 9515 服務沒處理,反覆跟蹤 macaca 執行過程找問題,折騰很久最後得高人指點查詢Chromedriver 的引數才恍然大悟,原來 capabilities 是有提供引數的, 引數沒傳遞正確,格式跟引數名字都不對,這裡需要一個 chromeOptions Objiect 修正之後長這樣

before(() => {
return driver
.init({
platformName: 'desktop',
browserName: browser,
chromeOptions: { //設定chromeDriver chromeOptions object 引數
binary: '/Applications/macaca-electron-builder.app/Contents/MacOS/macaca-electron-builder' // 填寫自己的執行檔案路勁或者安裝之後的檔案路勁
})
});

所以,當代理轉發引數到裝置端時,大多數情況裝置端已經實現了該引數,按照規則去設定就能調起來應用了,兩個在思考的問題都已解決,下面就描述1下完整的方案。

測試 Electron Demo

目前該方案已經提交 macaca 官方並通過了,如果大家想體驗示例,可以直接從 macaca 官方網站 或者 官方示例庫裡檢視,這裡描述1下 mac 的操作步驟,如果你已經懂得如何傳遞引數,請忽略了以下步驟。

  1. clone 示例庫 到本地
  2. 安裝依賴 $ npm i $ npm run build $ npm run dist
  3. 啟動服務並執行測試用例 $ npm run mac-start $ npm run test
  4. 測試用例示例,因程式碼格式渲染有問題,直接附上完整的 testCase地址

最後

本著解決自己專案難題的目的,最終卻輸出了兩次分享,過程中不斷遇到問題,解決問題,把分析過程跟思考記錄下來是希望鼓勵更多人,最終沉澱出來的方案是希望幫忙更多人,同時自己也在不斷成長,用積累回饋社群。
歡迎大家試用,一起探討,學習,更加完善示例庫,比如有興趣的同學可以完善 electron 示例應用的UI開發,針對各種場景新增case等等。

相關文章