Day 09|不只看畫面:教同事檢查 Console
前言
Day 8 教會它留證,一輪跑完會交回截圖、console、network、trace 四份檔案。今天面對下一個問題:四份檔案攤在面前,你怎麼知道該看哪一份?底下的數字都是 2026-08-02 對 automationexercise.com 實跑量到的,證據在 output/evidence/20260802-automationexercise/。
為什麼要分辨證據來源
留證有個陷阱:檔案愈多,愈像做完了。實際上那四份檔案回答的是四個不同的問題,而它們之間有縫。
截圖說得出症狀,說不出原因。network 說得出發了哪些請求,說不出回 200 的那一筆內容是錯的。console 說得出程式報了什麼錯,說不出畫面因此長成什麼樣。
縫的代價是漏。缺陷同時落在兩份檔案上,一份寫症狀、一份寫原因,只讀其中一份的人會判它通過。更糟的是這種漏不會留下痕跡:你手上有完整的證據包,報告寫「未發現異常」,兩件事並存,沒有任何人會發現。
所以今天要立的規矩是:先問這個症狀該由誰回答,再去開對應的那份檔案。
實驗:整站字型掉回預設,只有 console 說得出為什麼
首頁。看起來沒事,這就是問題所在。
打開首頁,console 固定 3 筆錯誤:
[ERROR] Mixed Content: The page at 'https://automationexercise.com/' was loaded over HTTPS,
but requested an insecure stylesheet 'http://fonts.googleapis.com/css?family=Roboto:...'.
This request has been blocked; the content must be served over HTTPS.
三筆都是同一類:HTTPS 頁面去載 HTTP 的字型 CSS,被瀏覽器擋下。network 加了 --static 之後也看得到,形式不太一樣:
[GET] http://fonts.googleapis.com/css?family=Roboto:400,300,... => [FAILED] mixed-content
[GET] http://fonts.googleapis.com/css?family=Open+Sans:400,800,... => [FAILED] mixed-content
[GET] http://fonts.googleapis.com/css?family=Abel => [FAILED] mixed-content
注意它不是 4xx,是 FAILED。只挑非 2xx 狀態碼看的人會漏掉,因為它根本沒有走到有狀態碼的那一步。
畫面上的症狀是什麼?網站的 CSS 寫著 font-family: Roboto, sans-serif,但 Roboto 的字型檔被擋了,所以整站掉回系統預設的 sans-serif。
同一件事在三種來源上長成三個樣子:
| 來源 | 它說什麼 |
|---|---|
| 截圖 | 字型跟設計稿不一樣,而且你多半不會發現 |
| console | Mixed Content,被擋掉了,連網址都給你 |
| network |
[FAILED] mixed-content,沒有狀態碼
|
截圖只會告訴你「字看起來跟設計稿不太一樣」,甚至你根本不會注意到,console 才說得出為什麼。症狀和原因,往往不在同一份證據裡。
跑這一輪的指令長這樣:
/evidence-package 打開 automationexercise.com 首頁,記錄 console 與 network 有沒有異常
/evidence-package 進商品頁與購物車,比對 console 新增了哪幾筆、分別來自哪個網域
授權提醒:automationexercise 是共用練習站。createAccount、deleteAccount、updateAccount 這幾個端點會留下副作用,示範一律只用讀取類端點。訂閱與聯絡表單會真的送出,不要按。
四種證據來源,各自看不見什麼
| 來源 | 指令 | 擅長抓什麼 | 抓不到什麼 |
|---|---|---|---|
| 截圖 |
playwright-cli screenshot --full-page --filename <路徑>
|
版面、文案、看得見的症狀 | 為什麼會這樣 |
| Trace |
playwright-cli tracing-start / tracing-stop
|
事後逐步回放,四種訊號都在裡面 | 要有人去點開對的那一格 |
| Network |
playwright-cli network --raw(看靜態資源要加 --static)
|
狀態碼、請求數、哪個請求沒成功 | 回 200 但內容是錯的 |
| Video |
playwright-cli video-start <檔名> / video-chapter / video-stop
|
動態過程、卡頓、閃現的畫面 | 精確數值 |
Network 預設會濾掉圖片字型這類靜態資源。這是今天最關鍵的開關:不加 --static,上一節那個缺陷你一個字都看不到。
Video 實測可用,video-stop 會回傳檔案路徑,短流程約 537 KB 的 .webm。Day 8 講過只在失敗時留影片與 trace,這一輪只驗了能錄、能停、能插章節,保留策略還沒實測。
Trace 這一輪也只是帶過。它把四種訊號都包在一份檔案裡,代價是要有人去點開對的那一格,而這一天沒有示範怎麼點。
還有第五種來源,它不在任何一份檔案裡:耗時。這個站的首頁載入量到 9.05 秒,共 125 個請求。時間要自己量,而且量到了也只是一個數字,是網路慢、伺服器慢、還是 125 個請求太多,今天沒有分辨。
console 有兩種訊息,數錯的那一種比較嚴重
console 收得到兩類訊息,但它們前綴不一樣。實測:
playwright-cli eval '() => { setTimeout(() => { throw new Error("UNCAUGHT_TEST_ERROR"); }, 0); console.error("CONSOLE_ERROR_TEST"); }'
playwright-cli console --raw
輸出:
Total messages: 2 (Errors: 2, Warnings: 0)
[ERROR] CONSOLE_ERROR_TEST @ :0
Error: UNCAUGHT_TEST_ERROR
at eval (eval at <anonymous> ...)
console.error() 印出來的有 [ERROR] 前綴,未捕捉的例外沒有。
所以這一行是錯的:
grep -c '^\[ERROR\]' console.log # 數到 1
摘要行說 Errors: 2。少掉的那一筆,正是未捕捉的 JS 例外,通常是比較嚴重的那一種。
你的過濾器決定了你看得到什麼。用行首前綴數錯誤,會系統性地漏掉未捕捉的例外。要嘛讀摘要行,要嘛連沒有前綴的堆疊一起看。
這個坑我自己踩過:今天前面幾輪的「console error 數」都是用那條 grep 數的。
噪音要跟缺陷分開
購物車頁的 console 有 4 筆錯誤,其中 3 筆是站方自己的 Mixed Content,第 4 筆長這樣:
[ERROR] Attestation check for Shared Storage on https://www.googleadservices.com failed.
那是第三方廣告腳本的問題,跟受測產品無關。每一輪都要重新判斷一次同一筆噪音,是很貴的浪費。這種東西該進一份已知噪音清單(output/known-false-positives.yaml),下一輪直接略過。
判斷的方法很土但有效:看網域。 請求打去 googleadservices.com、backtrace.io 這種第三方,跟受測產品無關;打去自己網域的才要追。
這份清單今天只說了該有,格式與比對方式要等第四週處理誤報與去重時才寫得完整。
小結
看到一個症狀,先問它該由哪一種來源回答,再去開那份檔案;開之前確認過濾器沒有先幫你篩掉東西(network 的 --static、你自己那條 grep 的行首前綴);讀到的錯誤先分掉第三方網域的噪音,剩下的才是候選。症狀與原因分屬兩份檔案時,兩份都要附進證據包,缺一份,下一個人就得再跑一次。
一個症狀
│
┌───────────────┼───────────────┬───────────────┐
▼ ▼ ▼ ▼
截圖 console network video
看得見什麼 為什麼會這樣 發了哪些請求 動態過程
│ │ │ │
└───────────────┴───────┬───────┴───────────────┘
▼
先檢查過濾器有沒有騙你
(--static?行首前綴?只挑非 2xx?)
│
▼
分掉第三方網域的噪音
│
▼
症狀 + 原因,湊成一筆才算數
症狀和原因常常不在同一份證據裡,截圖看到字型不對,只有 console 說得出為什麼。預設的過濾器與你自己寫的過濾器也都會騙你:network 不加 --static 看不到字型請求,grep '^\[ERROR\]' 漏掉未捕捉的例外。而噪音要先分掉再談缺陷,第三方網域的錯誤每一輪都會再出現一次,不進清單就每一輪都要重判。
下一步
今天是被動讀已經留下的證據:東西已經在檔案裡,差別只在你開哪一份。
明天換一種姿勢。挑一個 UI 動作,主動追它到底做了什麼,然後面對一種今天四種來源全部乾淨、卻確實有缺陷的情況:什麼都沒發生。
---
參考資料
- Playwright — Videos - 錄影的開關與檔案落地
- Playwright — Network - 攔截、觀察、mock 請求
- Playwright — Trace Viewer - Console/Network/DOM 各自在哪一格
- Playwright API — ConsoleMessage - console 訊息的型別與來源
- Playwright API —
page.on('pageerror')- 未捕捉的例外,跟 console 是兩條事件,本篇第三節的依據 - MDN — Mixed content - 為什麼 HTTPS 頁面載 HTTP 資源會被擋
- Chrome DevTools — Console - 給讀者對照手動除錯的經驗
- Automation Exercise - 本篇的受測站
- 本篇證據
output/evidence/20260802-automationexercise/- 截圖、console、network 的原始檔