Copy as Markdown 3.0: 里程碑

Copy as Markdown 是我自2012年開發至今的瀏覽器擴充套件,主要功能是把網頁上的超連結或分頁轉換成 Markdown,然後複製到剪貼簿。WAU大約一萬人。有在 ChromeFirefoxEdge 的官方商城上架。一直以來都維持低度維護,主要是工作之餘無暇兼顧。最近因為育嬰假有些空閒可以來改,而隨著育嬰假即將結束,也許不會再有時間改了,所以記錄一下這個里程碑。

過去三個月以來主要做了這些事情:

本文亦有英文版。This post is also available in English

E2E 測試

如前所述,向來都是低度維護的情況下,功能很少,測試工具都是靠手動,一時要加上新功能,就要各種瀏覽器各種OS交叉測試,過去12年也不時會把功能改爛。以往都是在 macOS 開發測試,從來沒有在 Windows 和 Linux 桌面好好測試過;最近買了一台二手的 PC,至少有 Windows 和 Linux 可以測。但手動測還是很累,所以研究了 E2E 測試。

所謂 E2E 測試,理想上還是直接發鍵盤滑鼠事件,但實際上要測試瀏覽器擴充套件並不是那麼容易,尤其要與原生UI互動,這其中包括分頁、鍵盤快速鍵、滑鼠右鍵選單、權限警告等。Chrome 官方的指南並不是很齊全,只大略列出有哪些工具可以用,例如 Selenium、WebDriver、Puppeteer等,但各家的指南也不是很齊全,花了不少時間自己摸索,也曾經考慮 Sikuli 和 Robot Framework,但工具鏈不是很好上手,所以作罷。又如 Puppeteer / WebDriver 是基於 Chrome Developer Protocol 的,只能控制瀏覽器裡面的網頁,摸不到 OS 的 native UI,也不太適合。

最後選用了 Selenium 的 Java 版本,因為可以調用 AWT 的 Robot 函式庫來對 OS 送出鍵盤滑鼠事件。事實證明這是對的決定,因為 Java 的跨平台特性讓我少掉很多麻煩,Selenium 和 AWT 也都是歷史悠久的工具,要找問答和奇怪的 tips & tricks 並不難。例如:

全部跑完大約要3分鐘左右,其實還算可以接受,但有點覺得是不是過度測試,而且 Windows 和 Linux (KDE) 還是有些問題無法全部通過。正在想把一些測試改到 Puppeteer,直接呼叫 background.js 的 event handlers 就算數,畢竟我可以假設瀏覽器本身可以正確呼叫鍵盤和右鍵選單的事件。但那又要折騰另一套 framework,所以暫時作罷。

開發的過程中,用了 JetBrains Aqua,及 PasteNow 來紀錄剪貼簿內容,很方便,推薦。

選配權限

Copy as Markdown 在很初期就有匯出分頁的功能,所以有 tabs 權限。日前加上了 tabGroups 的功能,可以同時匯出Chrome和Edge的分頁群組。當擴充套件要求新的權限時,Chrome就會出現警告。不久後就有零星的用戶抱怨「為什麼要看我的瀏覽紀錄?」而且也有很多使用者選擇解除安裝(大約5%)。原來是 Chrome 的權限警告會顯示「讀取您的瀏覽紀錄」,其實就是存取分頁的 tabs 權限。技術上也沒錯,因為可以拿到分頁的資料就表示可以隨時監控你瀏覽了什麼網頁,但老實說這實在是太嚇唬人了,一般用戶會覺得這個程式會無時無刻監控。

我覺得這個churning實在太傷,所以開始花時間改權限,目標是安裝時不會出現任何權限警告,把所有會出現警告的都放在選配,讓使用者自行決定,也做了功能讓使用者隨時取消,希望可以藉此止血。

沒錯,我的程式是開放原始碼,但我不可能期待那10000週活用戶都先看得懂程式碼再來用。作為一個實質上的PM,當然有義務改善這部分的UI。這件事的教訓就是,要給使用者選擇是否可以存取敏感的資訊。

在過去三個月裡,除了原本的分頁 tabs 改成了選配,新功能分頁群組 tabGroups 和書籤 bookmarks 也改成了選配。後者必須是選配,因為相關功能只支援 Firefox。

Firefox 版回歸 Manifest V2(暫時)

Manifest 的版本可以簡單理解為瀏覽器擴充套件的 API 版本。現在的最新版是 V3,名義上是某 W3C 群組主導的規格,實務上是 Chrome 挾市場地位主導的。MV3 在 Chrome 已經變成必備,舊版 MV2 已經無法上架,但因為各種原因,Firefox 目前是 MV2 和 MV3 都同時支援。兩者之間的 API 大同小異,主要差異在 Promise,但那些小異已經讓我必須加入一大堆 if (typeof chrome.xyz === 'undefined') ,以及 callback-to-Promise wrapper,相當煩人。

由於 Chrome 力推 MV3,帶著 Firefox 被迫跟上。原本我也是抱持 MV3 會統一天下,加上程式碼的維護考量,所以在 Firefox 上了 MV3。豈料 Firefox 因此出現了神秘的右鍵選單消失問題,我試了好幾種 hack 都無法解決,最後還是退回了 MV2。

然而這就回到了 callback vs Promise API 的問題。本來是覺得只有幾個 API 就自己包,但愈寫愈覺得麻煩,於是就導入了 Mozilla 出的 webextension-polyfill.js ,至少現在大部分的程式都可以用 async/await 寫了。

長期目標還是想要改為 MV3,但現在能動就暫時放著吧,反正有 E2E 測試不怕改爛(?

鳴謝

這三個月有時間可以來做大改動,是來自育嬰假,首先感謝我的女兒 Rena 出生,這個 3.0 版是為了紀念她而跳的版號。第二是孩子的媽,我的太太 Serena,她同時也是全職 UI/UX 設計師,在 UI 設計的過程中給了我很多寶貴意見。此外也要感謝我的公司 BONX Inc 讓我休育嬰假,我們的軟體開發團隊長期在徵才(日本東京)。最後也要感謝日本政府的育嬰假津貼。


附帶一提,現在 Copy as Markdown 有贊助連結,如果想要贊助的話請隨緣~