WebDriver Level 2

Chrome DevTool Protocol,

這超新的,新到其實什麼都還沒有,不過總之記錄一下,有兩條路線匯流:

第一條是 E2E 測試,E2E 測試比較早期是 Selenium 一家獨大,以前不知道是用什麼方法控制瀏覽器,就我瞭解應該不是太正規的方式,後來到 Selenium 2 開始發展 WebDriver,而且各家 browser vendor 都還蠻支持的,也朝向標準化的方向前進,標準文件現在也已經是 CR 了,由 Browser Testing and Tools 工作小組在維護,不過看了看 mailing list,該工作小組目前活躍度好像不高。標準化的好處就是大家都可以照著做,除了 Selenium WebDriver 之外的實做,現在還有 WebDriverIO 這個 nodejs 環境的實做,理論上可以只用 WebDriverIO 加上瀏覽器各自的 driver 而不用透過 Selenium 來做自動化測試

另外一條路線是 remote debugging,這個一開始是為了 debug 手機上的瀏覽器,後,讓手機上的 browser 傳送訊息到桌機上,用桌機瀏覽器的開發工具來顯示資訊,方便除錯,發展到後來,變成開發工具和瀏覽器之間的溝通協定都走同一套,也就是說現在桌機瀏覽器也是用 remote debugging 同樣的溝通方式在跟自己的開發工具溝通,兩者耦合就這樣拉開了,我最早知道可以這樣拆開的是 Opera 以前的 Dragonfly,然後可以想見每家瀏覽器的協定內容不一樣,然後就有一位 Kenneth Auchenberg 的人出來說這應該要有個標準!然後弄了個 remotedebug.org,初期計畫是希望大家都有個 adapter 可以轉譯自家的協定到公用的協定,像是 Mozilla 的 Valence,然後接著就開始有一些利用這些協定的各種發展,像是幫 Node 程式除錯、或是 iOS App、Electron 應用程式的除錯,甚至是除錯工具的開發也是用除錯工具自己 remote debug 自己,同時 Kenneth Auchenberg 也在推動 W3C 的標準化,一開始(約三年前)就是找上 Browser Testing and Tools 工作小組,不過一開始不太順利,因為那邊的都是自動化測試專門的人,和除錯工具關係其實不大。

Remote debug protocol 的資訊種類和訊息量其實都很大,目前看起來也只有 Google Chrome 的 DevTool Protocol 整理的比較完整,而 Firefox 的 Valence 其實已經沒維護了,他們的 README 上說要盡量相容 Chrome 的 protocol,這點讓我有點失望也不太意外,一來是擴充套件的 API 已經被 Google 帶著走了,二來是 debug 用的資訊太多太雜,不好維護,而且這樣似乎也是比較快可以統一的方式。而標準化的工作其實在去年有點進展,也就是 Browser Testing and Tools 工作小組 終於接納,要把他放進 WebDriver Level 2 裡面了,這其實是去年十月底的消息,在 remotedebug 的 twitter 上有發消息,也有工作小組章程修改的 commit 連結證實,接下來就看他們要怎麼標準化了,畢竟複雜度比 WebDriver Level 1 複雜許多,還有些部分是不穩定可能隨時會變動的。


CodeceptJS + puppeteer

看起來一切似乎都很美好,直到真的下去用。

這幾天就在這組合裡面打滾,昨天還花了幾乎半天在查一個問題,總之先條列一下目前覺得幾個重點:

  • CodeceptJS 文件裡面有 code sample 用 generator function 的非同步取值,現在支援用 async await 了,不過 code sample 還沒改。
  • 每種 helper 可以用的 method 不完全相同,大部分一樣,不過也沒列出基本組合,所以好像也不是很好一組 test 測所有 helper。
  • Puppeteer helper 裡面其實有很多地方是直接跟 CDP(Chrome DevTools Protocol) 溝通的,這部分也可以印 debug log:env DEBUG="puppeteer:protocol" codeceptjs run --steps --verbose
  • 開 CDP 的 log 的話資訊量會超多,訊息內容還算好理解,細節網路上也有文件,左邊 sidebar 有很多不同領域的,上面的 DEBUG 參數也可以自己修改只顯示想要的,詳見 puppeteer 文件
  • puppeteer 的page.goto有個選項是 waitUntil,預設是 load 事件,不過我發現這個事件有時候會觸發不到,雖然我看開發工具的 network 圖是有線出來,不過總之我後來會這樣的案例就先都改成networkidle2了。

然後昨天花很多時間查的問題已經上去發了 issue,總之就是發點擊事件點連結後,要檢查新頁面的內容會出現錯誤:

Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined

目前探究下來狀況應該是:puppeteer 的點擊回傳的 promise,在點擊完成就 resolve 了,這時候瀏覽器去開新網頁,才要開始發出請求,新的網頁還沒準備好,所以要做檢查的時候就會沒有 context。然後我有用 Nightwatch helper 測試過,是沒這問題的,總之就是個實做問題,puppeteer 目前這樣邏輯上也不算是錯誤的設計,不知道最後會怎麼修改,當然簡單一點就是 click 觸發 browser navigate 到別的網頁時就要等新網頁回來。目前的 work around 是自己多 wait 一下。

最後就是,我終於可以順暢的把 puppeteer 這個單字打出來了QQ



更之前的文章