- Quy trình tự động chụp ảnh màn hình từ ứng dụng web đang chạy và cập nhật cùng lúc với bản build tài liệu hướng dẫn, giúp hình ảnh trong tài liệu luôn ở trạng thái mới nhất ngay cả sau khi UI thay đổi
- Chú thích
SCREENSHOT trong Markdown chứa các chỉ thị như đường dẫn đích, cách chụp, CSS selector, và trong quá trình build, các chỉ thị này sẽ được đọc để điền ảnh thực tế vào
- Rake task chạy headless Chrome thông qua Capybara và Cuprite, nhóm công việc theo từng team để sau khi đăng nhập một lần có thể lần lượt truy cập nhiều URL và chụp
- Việc chụp hỗ trợ ba chế độ element, full_page, viewport, cùng các tùy chọn như
click, wait, crop, torn, hide để kiểm soát cả UI đang mở hoặc các thành phần không cần thiết
- Chỉ với một lần chạy
rails manual:build, việc tạo ảnh chụp màn hình và build trang trợ giúp sẽ cùng diễn ra, giúp dễ đồng bộ code và tài liệu trong cùng một PR hoặc commit, giảm mạnh ma sát của việc chụp và crop thủ công
Cách làm ảnh chụp màn hình tự cập nhật
- Trung tâm trợ giúp của Jelly được thiết kế để tự động chụp ảnh màn hình từ ứng dụng web đang chạy và cập nhật chúng mỗi khi build lại
- Tài liệu được viết bằng Markdown, và theo bài viết Self-updating screenshots, chúng được xử lý sang HTML bằng Redcarpet rồi render qua ERB view của ứng dụng Rails
- Trong Markdown có chèn chú thích
SCREENSHOT, nơi chứa các chỉ thị như đường dẫn đích, cách chụp, CSS selector
<!-- SCREENSHOT: acme-tools/inbox | element | selector=#inbox-brand-new-section -->
- Thẻ ảnh ngay bên dưới được dùng làm vị trí để chèn kết quả
- Chỉ cần màu sắc UI, vị trí nút bấm hoặc câu chữ thay đổi một chút là ảnh chụp màn hình trong tài liệu cũ rất dễ lỗi thời; quy trình này giúp giảm gánh nặng cập nhật thủ công đó
Pipeline chụp và hiệu quả bảo trì
- Bên trong, một Rake task chạy headless Chrome thông qua Capybara và Cuprite để quét chú thích
SCREENSHOT trong mọi file Markdown
- Các công việc chụp màn hình được gom nhóm theo team, và trong cùng một team thì chỉ cần đăng nhập một lần trước khi lần lượt đi qua nhiều URL
- Có ba chế độ chụp được hỗ trợ
- element: chụp một phần tử DOM cụ thể bằng CSS selector
- full_page: chụp toàn bộ trang, và nếu cần có thể cắt theo chiều cao
- viewport: chỉ chụp vùng hiện đang nhìn thấy trong cửa sổ trình duyệt
- Các tùy chọn chi tiết gồm click, wait, crop, nhờ đó có thể tự động chụp cả trạng thái xuất hiện sau khi bấm nút hoặc sau khi animation kết thúc
<!-- SCREENSHOT: nectar-studio/manage/rules | full_page | click=".rule-create-button" wait=200 crop=0,800 -->
- Hệ thống sẽ bấm nút để mở form, đợi 200ms rồi cắt và chụp vùng xác định
- Ngoài ra còn có các tùy chọn torn và hide
torn dùng CSS clip-path để áp dụng hiệu ứng mép giấy bị xé
hide tạm thời ẩn các phần tử không nên xuất hiện trên màn hình như dev toolbar hoặc cookie banner
- Toàn bộ pipeline được chạy chỉ với một lệnh
rails manual:build, xử lý cùng lúc mọi ảnh chụp màn hình và build các trang trợ giúp
- Mã nguồn tài liệu được sắp xếp trong
public/manual/ theo các mục như basics, setup, advanced
- Ở bước build, các file Markdown này được chuyển thành ERB view dưới
app/views/help/, đồng thời tạo luôn breadcrumb và điều hướng theo từng mục
- Vì có thể xử lý việc phát triển tính năng và cập nhật tài liệu trợ giúp trong cùng một codebase, nên việc đồng bộ code và tài liệu trong cùng một PR hoặc cùng một commit trở nên dễ dàng hơn
- Các xử lý ngoại lệ như phần tử cần cuộn, popover phải bấm mới mở, hoặc crop để tránh vùng không cần thiết đòi hỏi nhiều thời gian triển khai hơn, nhưng sau khi xây dựng xong thì trung tâm trợ giúp được cập nhật thường xuyên hơn hẳn
- Chỉ cần thay đổi UI, chạy lại bản build rồi commit kết quả là có thể luôn giữ ảnh chụp màn hình ở trạng thái mới nhất, gần như loại bỏ hoàn toàn ma sát của việc chụp và crop thủ công
1 bình luận
Ý kiến trên Hacker News
Nhân lúc tạo screenshot bằng chương trình, có thể làm luôn cả hai phiên bản light/dark theme của ứng dụng rồi thay thế theo
prefers-color-scheme: darkNhững thứ như vậy cũng hoạt động tốt trong GitHub README: https://github.com/CyberShadow/CyDo#readme
Với app di động, tôi dùng Nix để chạy một Android emulator dùng một lần nhằm tạo screenshot mới nhất; không cần cấu hình sẵn và cũng không để lại dữ liệu sau khi chạy
Với tôi thì phần cấu hình cũng không quá khó, cái khó hơn là nghĩ ra ý tưởng, còn code Nix thì tôi tạo một phát bằng LLM yêu thích
Việc cập nhật screenshot thủ công không phải việc khổ nhất trên đời, nhưng quy trình
upload-apk + take-screenshot + transfer-back-to-PC + editlúc nào cũng hơi phiền, nên rốt cuộc tôi gần như không làmTôi vẫn có thể đoán đại bằng ngữ cảnh, nhưng dù vậy vẫn khá bất tiện
App store bắt buộc phải có screenshot, mà phải tạo ảnh theo từng kích thước màn hình và từng bản địa hóa nên rất nhanh thành phiền phức
Trước đây tôi từng tự viết script cho việc này, còn bây giờ những công cụ Fastlane như https://fastlane.tools/ giúp được rất nhiều
Tôi cũng đang dùng Fastlane cho game giải đố logic Nonoverse của mình, và có thể xem screenshot mẫu trên trang App Store: https://apps.apple.com/us/app/nonoverse-nonogram-puzzles/id6...
Tôi cũng đã tự động hóa cả việc quay video App Preview, bao gồm nhiều cảnh khác nhau; nếu ai quan tâm thì đây khá đáng để viết thành một bài riêng
Những game casual nhỏ mà tôi làm bằng vibe coding thì luôn bắt đầu trong trạng thái app có thể chạy headless bằng CLI, có render vào offscreen texture, lệnh chụp screenshot, và cả đo hiệu năng
Mất rất ít thời gian để thêm cái này vào, đồng thời cũng mở ra một lối cho agent tự động hóa UI và kiểm tra những điểm quan trọng
Nhờ vậy, việc để agent cập nhật screenshot cũng trở nên rất dễ
Dù chưa gọn gàng bằng kiểu tích hợp hoàn toàn vào quy trình build, nhưng giờ tôi cũng định thêm phần đó
Tôi có cả tham số CLI cho offscreen screenshot path và world pos/camera view vector, đồng thời chạy benchmark script bằng một định dạng input dạng text
Định dạng này gồm nhiều dòng segment được đặt tên, độ dài
ngame tick cho từng segment, và input điều khiển của mỗi segmentTôi dùng nó rất nhiều khi A/B test hình ảnh và hiệu năng trong lúc làm code game
Tôi cũng rất quan tâm việc vibe coding đã làm cho phát triển game trở nên dễ đến mức nào
Thời Adobe Flash, hệ sinh thái game indie thực sự rất sôi động, và từ đó đến nay hầu như không có thứ gì chạm tới mức dễ phát triển như vậy
vibe coding có vẻ là công cụ đầu tiên vượt qua được ngưỡng đó
Mất rất ít thời gian để thêm cái này vàocòn tùy trường hợpTôi tò mò không biết bạn dùng engine nào
Tôi đặc biệt thích điểm có thể nhúng khai báo screenshot ngay inline trong tài liệu Markdown
Với ứng dụng desktop của mình, tôi đã làm một giải pháp có thể tạo screenshot cho nhiều ngôn ngữ và chế độ light/dark, khử nhiễu, rồi còn thêm cả khung cửa sổ Windows/macOS
Tôi đã viết về nó ở đây: https://maxschmitt.me/posts/cakedesk-website-redesign#screen...
Hiện tại nó là một script riêng nên bảo trì khá phiền; chắc tôi nên tìm cách đưa nó vào như một phần của markdown/mdx
Tôi đã có thêm cảm hứng hay
Thậm chí có thể dùng làm meme kiểu tác phẩm tuyệt vời nhất mà chẳng ai nhận ra
https://github.com/zombocom/rundoc mà tôi làm cũng có tính năng tương tự
Mục đích chính là tạo tutorial, nên nó còn đưa cả output của lệnh đã chạy ngược trở lại vào tài liệu
Kiểu đặt live preview của công cụ vào trong một hình chữ nhật
Nếu công cụ nhẹ thì có thể còn tối ưu hơn về mặt hình ảnh, đồng thời cũng phản ánh nguyên trạng các thiết lập render như cài đặt accessibility của trình duyệt hay addon của người dùng
Tài liệu của iommi thực sự đang làm như vậy: https://kodare.net/2025/01/14/iframes-not-screenshots.html
Nếu để cả
docs/cho tài liệu trong cùng repository, rồi mỗi khi cập nhật tài liệu mà cần screenshot mới thì thêm test mới, có vẻ sẽ rất hợpVài năm trước tôi cũng bắt đầu làm đúng thứ này, rồi cuối cùng trừu tượng hóa nó theo hướng tổng quát hơn như https://picshift.io/
Nhưng tôi vẫn rất thích use case screenshot, và tên gốc của dự án này cũng từng là
ScreenSync