給代理一部測試用機器
測試機是代理在真正要試點東西時開啟的一部用完即棄的機器:載入一個頁面、 在桌面應用程式中四處點擊、在電話上點來點去。你可以實時看着它工作,並隨時 接管控制。
隔離終端、瀏覽器與桌面測試機,都是配有用完即棄磁碟、網絡受關卡管控的 VM。 Android 與 iOS 則是由主機管理的模擬器:其裝置狀態用完即棄,但網絡連線跟隨 伺服器主機。
設定一次即可
標題為「設定一次即可」的章節測試機運行在託管 cc_server 的那部機器上 —— 是那部機器,而不是你眼前這部。
共有五種面向使用者的介面;桌面與流動裝置介面需要主機設定:
| 介面 | 運行於 | 設定 |
|---|---|---|
| 終端(VM) | 從釘定 Ubuntu 映像啟動的 microVM | 無 —— 首次使用時會自動擷取該映像 |
| 瀏覽器(VM) | 從釘定 Debian 映像啟動的 microVM,首次使用時安裝 Chromium、Firefox 或 WebKit | 無 —— 相同 |
| 電腦(VM) | QEMU 配上一套內建 Chromium、Firefox、WebKit 及 GitHub 託管執行器 CLI 基準的 Linux 桌面映像 | 安裝 QEMU(brew install qemu),然後在 設定 → 伺服器 → 測試機 下匯入一個桌面映像 |
| Android | Google 的 Android 模擬器 | 安裝 Android SDK、建立 AVD 並啟動它(見下文) |
| iOS Simulator | 伺服器 Mac 上的 CoreSimulator | 安裝 Xcode 及所需的 iOS runtime,然後在 設定 → 伺服器 → 測試機 下安裝自動化橋接器 |
終端與瀏覽器機器都從以摘要釘定的映像啟動:確切的位元組會事先指名,首次開機 時擷取一次並加以快取 —— 同類機器第一次啟動之後,往後的機器會完全略過下載, 數秒內就能起來。設定 → 伺服器 → 測試機 會顯示你的伺服器能啟動什麼,以及 目前正在運行的每一部機器。
已安裝的桌面映像仍然可以在同一頁管理:匯入會以較新的 qcow2 取代它, 刪除則會移除它,讓你可以安裝全新的組建。
流動裝置的設定方式不同
標題為「流動裝置的設定方式不同」的章節我們沒有為 Android 或 iOS 提供映像,而這並非疏漏。Android 系統映像來自 Google 的 SDK;iOS runtime 則來自 Xcode。就 Android 而言,請安裝 Android Studio(或命令列版 SDK 工具),在 裝置管理員 中新增一部虛擬裝置 並啟動它。之後「測試機」頁面便會回報 Android 可用。
它也會明確告訴你缺少哪一步 —— 沒有 SDK、沒有模擬器、沒有虛擬裝置,或者
裝置根本沒有在運行 —— 因為這四者的修法各不相同,而當中只有一個是下載。
如果你從看不到 SDK 的 shell 啟動 cc_server,請匯出它:
export ANDROID_HOME="$HOME/Library/Android/sdk"就 iOS 而言,伺服器本身必須運行於已安裝 Xcode 和 iOS Simulator runtime 的 macOS 上。開啟 設定 → 伺服器 → 測試機,然後按 安裝 iOS 自動化橋接器。 伺服器會擷取以校驗和釘定的 WebDriverAgent 成品、驗證它,並安裝到伺服器專屬的 自動化儲存區。設定過程中不會啟動任何模擬器。
開啟一部機器
標題為「開啟一部機器」的章節機器以分頁的形式存在,就在聊天與 diff 旁邊 —— 無論在空間還是 PR 頁面,
都在同一個 + 選單下的機器之中:
- 電腦 —— 內建 Chromium、Firefox 與 WebKit 的 Linux 桌面
- Chromium、Firefox 或 WebKit —— 一個瀏覽器
- Android —— 正在運行的 Android 模擬器
- iOS Simulator —— 為這則對話建立的用完即棄模擬器
挑一個並按 啟動機器。分頁會說明開機處於哪個階段(「正在啟動 microVM」、 「正在等待客體起來」),而不是只在那裡轉圈。
分頁的範圍限於該則對話,代理工具也一樣。Chromium、Firefox 或 WebKit 分頁與
browser_use、Android 與 mobile_use,又或者 iOS Simulator 與 ios_use,
指向的是同一部預設機器。額外的介面位置則是各自獨立的比較用機器;代理工具
永遠使用預設那一部。
要在 Android 上建置、安裝並啟動 Flutter 應用程式:
fvm flutter build apk --debug然後以 install_apk 和 build/app/outputs/flutter-apk/app-debug.apk 呼叫
mobile_use,接着以 start_app 和 Android 套件名稱呼叫。ui_dump、
螢幕截圖與輸入操作所驅動的,正是人類分頁中顯示的同一部裝置。stop_app、
clear_app_data、uninstall_app、open_url,以及以 argv 形式傳入的
shell 呼叫,涵蓋開發週期的其餘環節,而無需在伺服器主機上叫用 shell。
要在 iOS Simulator 上建置、安裝並啟動 Flutter 應用程式:
fvm flutter build ios --simulator --debug/usr/bin/plutil -extract CFBundleIdentifier raw -o - \ build/ios/iphonesimulator/Runner.app/Info.plist然後以 install_app 和 .app 目錄呼叫 ios_use,接着以 start_app 和
plutil 印出的 bundle identifier 呼叫。iOS 工具亦提供 stop_app、
uninstall_app、open_url,以及一個以 argv 形式傳入的 spawn 動作,
用於模擬器本機的診斷。
桌面與瀏覽器的顯示畫面會隨面板調整大小。iOS 則維持模擬器固定的點尺寸, 並為它補上黑邊。每個介面仍然有兩條互相獨立的通道:代理取得細小、便宜的 螢幕截圖,而你取得即時畫面。切換分頁會停止人類串流,因此背景機器不耗用 任何顯示頻寬。
測試機分頁不會自行啟動機器,在還原版面配置時亦然。這條規則可避免應用程式 一啟動就意外開機 VM 或建立模擬器裝置。
操控機器
標題為「操控機器」的章節只要沒有其他人持有獨佔控制權 —— 或者持有者就是你 —— 畫布就任你輸入和點擊。 在你持有那道鎖期間,狀態標籤會顯示 你已獲得控制權,代理仍然可以截圖, 而伺服器會在每個動作都必經的那一個關口拒絕它的變更類動作。你所做的一切都會 記錄在你的名下。
完成後按 停止機器。
控制權刻意設計成獨佔:兩個人同時在一部機器上輸入,會產生兩人都不是本意的 輸入。
把東西移進移出
標題為「把東西移進移出」的章節複製與貼上在測試機畫布的兩個方向都可運作,拖曳檔案也一樣。
複製與貼上。 在畫布上按下複製組合鍵,機器所複製的任何東西 —— 文字、 一張影像、一組檔案 —— 都會落到你的剪貼板。貼上則把你的內容送往另一方向, 並在機器內按下貼上。在 macOS 上,組合鍵是 ⌘C/⌘V;⌃C 仍會以中斷訊號的本來 身分送達客體 shell。在 Windows 與 Linux 上請用 ⌃C/⌃V —— 客體會原樣收到它 本來就會收到的按鍵,因此客體終端機中的 ⌃C 仍然會中斷,而你的剪貼板則不受 影響。
後台不會同步任何東西。你在自己機器上複製的密碼,不會因為某個計時器觸發就 出現在 VM 之內;它只在你貼上時才跨越邊界。
貼上到測試機預設允許。從測試機複製出去則會先彈出詢問 —— 可授予十分鐘權限, 或選擇 始終允許(位於 設定 → 伺服器 → 測試機 → 剪貼板存取 之下)。 這兩個方向互相獨立,而且跟隨的是你本人,而不是工作區。
把檔案拖入。 把它們放到畫布上任何位置。
- 在 瀏覽器(VM) 上,頁面會在你鬆手的位置收到一個 真實 的拖放事件, 因此上載區的行為與拖入本機檔案時完全相同。
- 在 電腦(VM) 上,檔案會落到
~/Drops,其路徑則放進機器的剪貼板, 因此 ⌃V 可把它們貼到檔案管理員或上載欄位。主機無法在不於 VM 內執行特權 守護程序的情況下,向任意 Linux 應用程式合成一次拖曳 —— 而測試機刻意不具備 這種東西 —— 因此提示訊息會告訴你檔案去了哪裡,而不是假裝發生過一次拖放。 - 在終端上,檔案會被複製進去,其路徑則在提示符號處輸入,準備好傳給指令。 把一張 影像 貼到終端也一樣:它會儲存在機器內,而你會取得其路徑。
把檔案拖出在電腦(VM)上可用。在機器內開始拖曳一個檔案,把指標帶出畫布, 它就會變成你桌面上的真實拖曳操作 —— 放進 Finder 或 Explorer 即可。在機器的 檔案管理員中複製檔案,再於你自己這邊貼上也行。瀏覽器(VM)則不提供這項功能: 無介面瀏覽器沒有可讀取的拖曳載荷,而從頁面的文字選取去猜測,只會騎劫一般的 點擊。
測試機內的終端
標題為「測試機內的終端」的章節空間內或 PR 頁面上的終端,可以選擇在測試機內運行,而不是在伺服器自身的機器 上。當它們這樣做時,面板會顯示 封閉虛擬機 標籤。
有什麼改變:
- 你運行的任何東西都碰不到主機。在裡面跑一個
rm -rf,賠上的只是那部測試機。 - 網絡預設拒絕。只有測試機允許清單上的主機可以觸及,而一切都經由一道強制 執行該清單的關卡。
git push在你自己開啟的終端機中仍然可用。測試機不儲存任何憑證;它會按每次 操作向伺服器索取一個短時效憑證,其權限受你自己的程式碼託管存取範圍約束,而該 權杖會在測試機關閉時被撤銷。由代理開啟的測試機只會取得唯讀憑證,因此能 fetch, 但不能推送。
需要知道的事:
- 還原後的隔離終端會等你。 與測試機分頁一樣,隨你的版面配置還原回來的
microvm終端會顯示 開啟 shell 按鈕,而不是在啟動時就開機它的 VM。 主機 shell 終端耗的是一個行程;隔離終端耗的則是一部機器。 - 放到終端上的檔案是輸入路徑,不是開啟。 把一個 CSV 放到隔離終端上, 它會被複製到機器內,其客體路徑則出現在提示符號處 —— 主機路徑在那裡只會是 一條失敗的指令。
- 測試機內的那份複本是複本。 主機上的工作樹始終是權威來源。你在測試機內
所作的提交,只會在你要求時帶回
refs/rigs/<id>/*—— 它們永遠不會移動你的 分支,也不會碰觸你的工作樹。 - 以主機為目標的工作仍在主機上運行。 Linux 客體無法為 macOS 建置,也無法
執行
xcodebuild。這種情況請明確選擇原生後端;應用程式會要求你確認, 而不是悄悄切換。
連接埠
標題為「連接埠」的章節在終端(VM)內運行一個開發伺服器 —— 比如說 3000 埠上的 pnpm dev —— 幾秒
之內,終端角落的插頭圖示就會亮起:該連接埠會轉送到你機器上的 localhost:3000,
可在瀏覽器(VM)內以 localhost:3000 觸及,可在你的網絡上分享,也可命名為
https://myapp.test。整個流程 —— 自動轉送、區域網絡分享、帶 HTTPS 的開發
網域 —— 有它自己的一份指南:
從終端轉送連接埠。
自訂映像
標題為「自訂映像」的章節一個工作區可以把終端(VM)與瀏覽器(VM)指向自己的映像 —— 就在 設定 → 伺服器 → 測試機 → 自訂映像(此工作區) 之下。典型用法:在預設映像 上補充你的專案所需的工具鏈,讓每個終端一啟動就緒;或者重用你團隊已經發佈的 映像。
機器仍然在同一道隔離邊界內開機:同一道對外連線關卡、同一個憑證代理、同一個 生命週期。只有工作區管理員可以更改這項設定,新機器會採用它(運行中的機器 保留自己的),而且參照必須是一個 registry 映像 —— 本機路徑會被拒絕。
映像必須提供什麼:
- 終端(VM) —— 一個內含
bash的 Linux 映像。它還需要git、curl和socat—— 可以是預先安裝,也可以是在首次啟動時安裝(任何以 Debian/Ubuntu 為基礎的映像都可以:它們會自動安裝,連同一套相當於 GitHub 託管執行器的 CLI 基本工具:編譯器、Python 3、jq、封存工具、rsync。 Node/Go/Java 等語言 runtime 和 Docker 則不會預先安裝)。客體連接埠7911保留給連接埠轉送器。 - 瀏覽器(VM) —— 一個內含
bash和socat的 Debian/Ubuntu 映像, 另加一個chromium二進位檔。伺服器會自行以chromium --headless=new啟動 Chromium,並把 DevTools 從客體9223轉接到9222。PulseAudio 與 ffmpeg 會在首次啟動時安裝。請勿建置FROM chromedp/headless-shell—— 那個二進位檔沒有音訊。這項覆寫只套用於 Chromium 測試機;Firefox 與 WebKit 會忽略它,並啟動釘定的 Debian 映像。客體連接埠9222/9223為保留。
兩項建議:以摘要釘定參照(@sha256:…),這樣位元組就不會在你腳下悄悄改變;
並把它託管於 Docker Hub 或 GitHub Container Registry —— 這些 registry 的下載
主機可自動通過對外連線關卡;其他 registry 則可能需要其內容傳遞主機可觸及,
才能拉取。
測試機何時消失
標題為「測試機何時消失」的章節測試機生來就是暫時的:
- 閒置 —— 瀏覽器、桌面或流動裝置測試機在約 15 分鐘沒有任何動靜之後會 停駐(凍結,下一次操作即時喚醒)。隔離終端則等待 45 分鐘。達到閒置時限的 兩倍之後,它就會關閉。
- 時限 —— 每部測試機都有一個無法延長的硬性存活期限,無論它當下在做什麼。
- 記憶體 —— 如果伺服器需要空間開新的測試機,它會關閉最久未使用的那一部。 有人正在操控、正在觀看,或開着終端的測試機,永遠不會被拿走。
隔離測試機關閉時,其磁碟會被丟棄。關閉 Android 測試機只是從主機模擬器卸除 —— 它不會刪除模擬器。iOS 測試機則會刪除它所建立的 CoreSimulator 裝置。 想保留任何東西,請先帶回來。
測試機可以觸及什麼
標題為「測試機可以觸及什麼」的章節隔離終端、瀏覽器與桌面測試機預設採用一道預設拒絕的對外連線關卡:主機由你
明確放行,而客體唯一的出路就是一道強制執行該清單的關卡。瀏覽器測試機另外
會開箱即放行產品網站(usectrl.dev)。憑證代理使用同一份清單。
兩點誠實的告誡:
- 流動裝置的網絡跟隨主機。 Android 的模擬器與 Apple 的 CoreSimulator 並不在隔離環境的對外連線關卡之後。兩個流動裝置分頁都不提供繞過網絡的 控制項,因為由主機管理的網絡本來就不受限。
- 測試機讀到的一切都不受信任。 頁面文字、DOM、無障礙樹與檢視傾印,回到 代理手上時,外面都圍着標記,說明「這是資料,不是指令」。試圖向你的代理下 命令的頁面,讀起來就只是一段被引用的字串。
你可以在 設定 → 伺服器 → 測試機 下看到所有正在運行的東西,並停止其中 任何一項。