ドキュメントに自動更新されるスクリーンショットを入れる
(interblah.net)- 実行中の Web アプリケーションで スクリーンショットを自動キャプチャし、ヘルプ文書のビルドとあわせて更新するフローを作ることで、UI 変更後も文書画像を 最新の状態 に保つ
- Markdown 内の
SCREENSHOTコメントに対象パス、キャプチャ方法、CSS selector のような指示を持たせ、ビルド過程でこれを読み取って実際の画像で埋め込む - Rake タスクが Capybara と Cuprite を通じて headless Chrome を実行し、チームごとに作業をまとめて一度ログインしたあと複数の URL を巡回しながらキャプチャする
- キャプチャは element、full_page、viewport の 3 つのモードをサポートし、
click、wait、crop、torn、hideのようなオプションで開いた状態の UI や不要な要素もあわせて制御する rails manual:buildを一度実行するだけでスクリーンショット生成とヘルプページのビルドが一緒に走り、コードと文書を 同じ PR や commit の中で揃えやすくなるため、手動キャプチャや手動クロップの摩擦が大きく減る
自動更新されるスクリーンショット方式
- 運用中の Jelly(チーム向け共有メール受信トレイサービス) のヘルプセンターでは、実行中の Web アプリケーションで スクリーンショットを自動キャプチャし、再ビルド時にあわせて更新されるよう構成されている
- 文書は Markdown で書かれ、Self-updating screenshots の本文をもとに Redcarpet で HTML に処理したあと、Rails アプリの ERB ビューとしてレンダリングされる
- Markdown 内には
SCREENSHOTコメントを入れ、ここに対象パス、キャプチャ方法、CSS selector などの指示をあわせて記述する<!-- SCREENSHOT: acme-tools/inbox | element | selector=#inbox-brand-new-section -->- すぐ下の画像タグが結果を差し込む位置として使われる
- UI の色、ボタン位置、文言が少し変わるだけでも既存の文書スクリーンショットは簡単に古くなるが、このフローはそうした手動更新の負担を減らす
キャプチャパイプラインと保守性の効果
- 内部的には Rake タスクが Capybara と Cuprite を通じて headless Chrome を実行し、すべての Markdown ファイルの
SCREENSHOTコメントをスキャンする - スクリーンショット作業はチーム単位でまとめて処理され、同じチームでは 一度だけログインしたあと複数の URL を巡回するよう構成されている
- 対応するキャプチャモードは 3 つある
- element: CSS selector で特定の DOM 要素をキャプチャする
- full_page: ページ全体をキャプチャし、必要なら高さ基準で切り取れる
- viewport: ブラウザウィンドウで現在見えている領域だけをキャプチャする
- 詳細オプションとして click、wait、crop を指定でき、ボタンをクリックしたあとに現れる状態やアニメーション後の画面も自動で取得できる
<!-- SCREENSHOT: nectar-studio/manage/rules | full_page | click=".rule-create-button" wait=200 crop=0,800 -->- ボタンを押してフォームを開いたあと 200ms 待ち、特定領域に切り取ってキャプチャするよう動作する
- 追加オプションとして torn と hide もある
tornは CSS のclip-pathを使って、破れた紙の縁のような効果を適用するhideは dev toolbar や cookie banner のように画面に出てほしくない要素を一時的に隠す
- パイプライン全体は
rails manual:buildコマンド 1 つで実行され、すべてのスクリーンショットキャプチャと ヘルプページのビルドをまとめて処理する - 文書ソースは
public/manual/以下に basics、setup、advanced のようなセクション別で整理されている - ビルド段階でこれらの Markdown ファイルは
app/views/help/以下の ERB ビューに変換され、breadcrumb とセクションナビゲーションもあわせて生成される - 機能開発とヘルプ更新を同じコードベース内で一緒に扱えるため、コードと文書の同期を同じ PR や同じ commit の中で保ちやすくなる
- スクロールが必要な要素、クリックしないと開かない popover、不要部分を避けるための crop といった 例外処理 は実装により多くの時間を要したが、構築後はヘルプセンターをはるかに頻繁に更新できるようになった
- UI を変更してビルドを再実行し、その結果を commit するだけの流れでスクリーンショットを常に最新状態にできるため、手動キャプチャと手動クロップの摩擦がほぼなくなる
1件のコメント
Hacker Newsのコメント
プログラムでスクリーンショットを生成するついでに、アプリの light/dark theme 2バージョンも一緒に作って、
prefers-color-scheme: darkに合わせて差し替えればよいです。こうした要素は GitHub README でもうまく動きます: https://github.com/CyberShadow/CyDo#readme
モバイルアプリでは Nix で使い捨ての Android エミュレータを立ち上げて最新のスクリーンショットを生成するようにしていて、事前設定も不要ですし、実行後にデータも残りません。
自分の場合、設定自体もそれほど大変ではなく、むしろアイデアを思いつく方が難しく、Nix コードはお気に入りの LLM で一発で作りました。
手動でスクリーンショットを更新するのは世界でいちばんつらい作業というわけではありませんが、
upload-apk + take-screenshot + transfer-back-to-PC + editという流れがいつも微妙に面倒で、結局ほとんどやらなくなってしまいます。文脈からだいたい推測はできましたが、それでも不便でした。
アプリストアではスクリーンショットが必須ですが、画面サイズの数とローカライズの数だけ画像を作らなければならず、すぐに面倒になります。
以前はこのために自分でスクリプトを書いていましたが、今では https://fastlane.tools/ のような Fastlane ツールが大いに役立っています。
自分のロジックパズルゲーム Nonoverse にも Fastlane を使っていて、App Store のページでサンプルスクリーンショットを見ることができます: https://apps.apple.com/us/app/nonoverse-nonogram-puzzles/id6...
App Preview 動画の録画も複数シーンを含めて自動化していて、興味のある人がいれば別記事にまとめる価値のあるテーマだと思います。
自分が vibe coding で作っている小さなカジュアルゲームは、いつもアプリが CLI でヘッドレス実行できて、オフスクリーンテクスチャレンダリング、スクリーンショット命令、パフォーマンス計測まで可能な状態から始めています。
これを入れるのにほとんど時間はかかりませんし、エージェントが UI を自動化して重要なポイントを確認できる経路もできます。
おかげで、エージェントにスクリーンショットを更新させるのもとても簡単になります。
ビルド工程に完全に溶け込んだ形ほどきれいではありませんが、そこも今後追加してみようと思っています。
offscreen screenshot path と world pos/camera view vector を指定する CLI 引数もあり、テキストベースの入力形式でスクリプト化されたベンチマークを回しています。
この形式は、名前付きセグメント複数行と、セグメントごとの
nゲームティック長、そして各セグメントのコントロール入力で構成されています。ゲームコードを触りながらビジュアルとパフォーマンスを A/B テスト するときに、これをかなり多用しています。
自分も vibe coding がゲーム開発をどれだけ簡単にするのか、とても関心があります。
Adobe Flash の時代にはインディーゲームの生態系が本当に活気に満ちていましたが、その後はあれほどの開発しやすさに触れたものはほとんどありませんでした。
vibe coding は、その水準を初めて超えるツールのように見えます。
これを入れるのにほとんど時間はかからないという話はケースバイケースです。どの エンジン を使っているのか気になります。
Markdown 文書の中に スクリーンショット宣言 をインラインで入れられる点が、とくに気に入りました。
自分のデスクトップアプリでは、複数言語と light/dark モードのスクリーンショットを生成し、ノイズを除去し、Windows/macOS のウィンドウフレームまで適用するソリューションを作ってあります。
ここにまとめています: https://maxschmitt.me/posts/cakedesk-website-redesign#screen...
今は別スクリプトなので保守がかなり面倒ですが、markdown/mdx の一部として組み込む方向を見てみようと思います。
良い刺激を受けました。
誰も気づかない X 最高の仕事 みたいなミームとして使ってもいいくらいです。
自分が作った https://github.com/zombocom/rundoc にも似た機能があります。
主な目的は チュートリアル生成 なので、実行したコマンドの出力も文書の中に再挿入してくれます。
ツールのライブプレビューを長方形の中に入れるような形です。
ツールが軽量なら、見た目としても最適かもしれませんし、ブラウザのアクセシビリティ設定やユーザーアドオンのようなレンダリング設定もそのまま反映できます。
iommi のドキュメントでは実際にそうしています: https://kodare.net/2025/01/14/iframes-not-screenshots.html
文書用の
docs/も同じリポジトリに置いて、文書を更新する中で新しいスクリーンショットが必要になったら新しいテストを追加する、という形ならうまく合いそうです。自分も数年前にまさにこれを作り始めましたが、最終的には https://picshift.io/ のように、より汎用的な方向へ抽象化しました。
それでも スクリーンショットのユースケース は今でも本当に気に入っていて、このプロジェクトの元の名前も
ScreenSyncでした。