From e49bdf3eb3fffa4857ccfe9c7d5618aaccb040c4 Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Sun, 13 Sep 2026 12:30:53 +0200 Subject: [PATCH] Take the website's screenshots with one command composer screenshots runs Pest browser tests in tests/Screenshots, outside every test suite: fixed demo data under a frozen clock, desktop (MacBook 14, 2x) and phone (iPhone 15 Pro, 3x) in light and dark, each capture published at once as WebP at two widths into website/img/screenshots. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy --- .ai/rules/index.md | 2 + .ai/rules/screenshots.md | 9 + .dockerignore | 3 + .gitignore | 2 + composer.json | 5 + docs/plans/screenshots-and-website.md | 255 ++++++++++++++++++ tests/Pest.php | 2 +- tests/Screenshots/DemoData.php | 89 ++++++ tests/Screenshots/Publisher.php | 56 ++++ tests/Screenshots/ScreenshotsTest.php | 153 +++++++++++ tests/Unit/ScreenshotPublisherTest.php | 32 +++ .../desktop/dark/01-upload-1600.webp | Bin 0 -> 22272 bytes .../desktop/dark/01-upload-800.webp | Bin 0 -> 9472 bytes .../desktop/dark/02-share-created-1600.webp | Bin 0 -> 19684 bytes .../desktop/dark/02-share-created-800.webp | Bin 0 -> 7698 bytes .../desktop/dark/03-qr-code-1600.webp | Bin 0 -> 18662 bytes .../desktop/dark/03-qr-code-800.webp | Bin 0 -> 10108 bytes .../desktop/dark/04-download-1600.webp | Bin 0 -> 15454 bytes .../desktop/dark/04-download-800.webp | Bin 0 -> 6090 bytes .../desktop/dark/05-admin-dashboard-1600.webp | Bin 0 -> 33492 bytes .../desktop/dark/05-admin-dashboard-800.webp | Bin 0 -> 13556 bytes .../desktop/dark/06-admin-settings-1600.webp | Bin 0 -> 26566 bytes .../desktop/dark/06-admin-settings-800.webp | Bin 0 -> 9902 bytes .../desktop/light/01-upload-1600.webp | Bin 0 -> 23342 bytes .../desktop/light/01-upload-800.webp | Bin 0 -> 9784 bytes .../desktop/light/02-share-created-1600.webp | Bin 0 -> 19968 bytes .../desktop/light/02-share-created-800.webp | Bin 0 -> 7714 bytes .../desktop/light/03-qr-code-1600.webp | Bin 0 -> 18304 bytes .../desktop/light/03-qr-code-800.webp | Bin 0 -> 10136 bytes .../desktop/light/04-download-1600.webp | Bin 0 -> 16116 bytes .../desktop/light/04-download-800.webp | Bin 0 -> 6320 bytes .../light/05-admin-dashboard-1600.webp | Bin 0 -> 34158 bytes .../desktop/light/05-admin-dashboard-800.webp | Bin 0 -> 13672 bytes .../desktop/light/06-admin-settings-1600.webp | Bin 0 -> 27760 bytes .../desktop/light/06-admin-settings-800.webp | Bin 0 -> 10396 bytes .../phone/dark/01-upload-1080.webp | Bin 0 -> 57108 bytes .../screenshots/phone/dark/01-upload-540.webp | Bin 0 -> 25280 bytes .../phone/dark/02-password-1080.webp | Bin 0 -> 28764 bytes .../phone/dark/02-password-540.webp | Bin 0 -> 11472 bytes .../phone/dark/03-download-1080.webp | Bin 0 -> 42192 bytes .../phone/dark/03-download-540.webp | Bin 0 -> 17950 bytes .../phone/dark/04-qr-code-1080.webp | Bin 0 -> 27864 bytes .../phone/dark/04-qr-code-540.webp | Bin 0 -> 14334 bytes .../phone/light/01-upload-1080.webp | Bin 0 -> 59394 bytes .../phone/light/01-upload-540.webp | Bin 0 -> 26236 bytes .../phone/light/02-password-1080.webp | Bin 0 -> 31132 bytes .../phone/light/02-password-540.webp | Bin 0 -> 12526 bytes .../phone/light/03-download-1080.webp | Bin 0 -> 45124 bytes .../phone/light/03-download-540.webp | Bin 0 -> 19002 bytes .../phone/light/04-qr-code-1080.webp | Bin 0 -> 26622 bytes .../phone/light/04-qr-code-540.webp | Bin 0 -> 13926 bytes 51 files changed, 607 insertions(+), 1 deletion(-) create mode 100644 .ai/rules/screenshots.md create mode 100644 docs/plans/screenshots-and-website.md create mode 100644 tests/Screenshots/DemoData.php create mode 100644 tests/Screenshots/Publisher.php create mode 100644 tests/Screenshots/ScreenshotsTest.php create mode 100644 tests/Unit/ScreenshotPublisherTest.php create mode 100644 website/img/screenshots/desktop/dark/01-upload-1600.webp create mode 100644 website/img/screenshots/desktop/dark/01-upload-800.webp create mode 100644 website/img/screenshots/desktop/dark/02-share-created-1600.webp create mode 100644 website/img/screenshots/desktop/dark/02-share-created-800.webp create mode 100644 website/img/screenshots/desktop/dark/03-qr-code-1600.webp create mode 100644 website/img/screenshots/desktop/dark/03-qr-code-800.webp create mode 100644 website/img/screenshots/desktop/dark/04-download-1600.webp create mode 100644 website/img/screenshots/desktop/dark/04-download-800.webp create mode 100644 website/img/screenshots/desktop/dark/05-admin-dashboard-1600.webp create mode 100644 website/img/screenshots/desktop/dark/05-admin-dashboard-800.webp create mode 100644 website/img/screenshots/desktop/dark/06-admin-settings-1600.webp create mode 100644 website/img/screenshots/desktop/dark/06-admin-settings-800.webp create mode 100644 website/img/screenshots/desktop/light/01-upload-1600.webp create mode 100644 website/img/screenshots/desktop/light/01-upload-800.webp create mode 100644 website/img/screenshots/desktop/light/02-share-created-1600.webp create mode 100644 website/img/screenshots/desktop/light/02-share-created-800.webp create mode 100644 website/img/screenshots/desktop/light/03-qr-code-1600.webp create mode 100644 website/img/screenshots/desktop/light/03-qr-code-800.webp create mode 100644 website/img/screenshots/desktop/light/04-download-1600.webp create mode 100644 website/img/screenshots/desktop/light/04-download-800.webp create mode 100644 website/img/screenshots/desktop/light/05-admin-dashboard-1600.webp create mode 100644 website/img/screenshots/desktop/light/05-admin-dashboard-800.webp create mode 100644 website/img/screenshots/desktop/light/06-admin-settings-1600.webp create mode 100644 website/img/screenshots/desktop/light/06-admin-settings-800.webp create mode 100644 website/img/screenshots/phone/dark/01-upload-1080.webp create mode 100644 website/img/screenshots/phone/dark/01-upload-540.webp create mode 100644 website/img/screenshots/phone/dark/02-password-1080.webp create mode 100644 website/img/screenshots/phone/dark/02-password-540.webp create mode 100644 website/img/screenshots/phone/dark/03-download-1080.webp create mode 100644 website/img/screenshots/phone/dark/03-download-540.webp create mode 100644 website/img/screenshots/phone/dark/04-qr-code-1080.webp create mode 100644 website/img/screenshots/phone/dark/04-qr-code-540.webp create mode 100644 website/img/screenshots/phone/light/01-upload-1080.webp create mode 100644 website/img/screenshots/phone/light/01-upload-540.webp create mode 100644 website/img/screenshots/phone/light/02-password-1080.webp create mode 100644 website/img/screenshots/phone/light/02-password-540.webp create mode 100644 website/img/screenshots/phone/light/03-download-1080.webp create mode 100644 website/img/screenshots/phone/light/03-download-540.webp create mode 100644 website/img/screenshots/phone/light/04-qr-code-1080.webp create mode 100644 website/img/screenshots/phone/light/04-qr-code-540.webp diff --git a/.ai/rules/index.md b/.ai/rules/index.md index 999bf21..8813282 100644 --- a/.ai/rules/index.md +++ b/.ai/rules/index.md @@ -7,3 +7,5 @@ Before planning or editing, find the row whose globs match the file's path and r | config/livewire-material.php | .ai/rules/config.md | | resources/css/material-scheme.* | .ai/rules/css.md | | resources/views/livewire/share-download.blade.php | .ai/rules/livewire.md | +| tests/Screenshots/** | .ai/rules/screenshots.md | +| website/** | .ai/rules/website.md | diff --git a/.ai/rules/screenshots.md b/.ai/rules/screenshots.md new file mode 100644 index 0000000..41e3285 --- /dev/null +++ b/.ai/rules/screenshots.md @@ -0,0 +1,9 @@ +--- +paths: + - 'tests/Screenshots/**' +--- + +# Screenshots + +## Screenshots come from composer screenshots, before a release +Run `composer screenshots` whenever the interface changes and before a release; it builds assets and runs tests/Screenshots (not part of any test suite or CI), publishing WebP files to website/img/screenshots. Demo data (DemoData) and the clock are fixed so runs are reproducible. Traps: Pest only starts its browser for a test whose body calls `visit(` after whitespace; Livewire's temporary-upload cleanup must stay off under the frozen clock or it deletes the selected files; the in-process server's random port is shown as https://files.example.com and the QR redrawn for it; upload_max_filesize/post_max_size are set to 4G by the script so the admin settings hint does not show the machine's PHP limit. diff --git a/.dockerignore b/.dockerignore index f6ce8d5..784bd04 100644 --- a/.dockerignore +++ b/.dockerignore @@ -25,6 +25,9 @@ Dockerfile # Testing tests + +# Website (published separately) +website phpunit.xml .phpunit.cache diff --git a/.gitignore b/.gitignore index 90d3d5f..446c387 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ yarn-error.log **/caddy frankenphp frankenphp-worker.php + +/tests/Browser/Screenshots diff --git a/composer.json b/composer.json index f714b1a..a83b47c 100644 --- a/composer.json +++ b/composer.json @@ -84,6 +84,11 @@ ], "pre-package-uninstall": [ "Illuminate\\Foundation\\ComposerScripts::prePackageUninstall" + ], + "screenshots": [ + "Composer\\Config::disableProcessTimeout", + "npm run build", + "@php -d upload_max_filesize=4G -d post_max_size=4G vendor/bin/pest tests/Screenshots" ] }, "extra": { diff --git a/docs/plans/screenshots-and-website.md b/docs/plans/screenshots-and-website.md new file mode 100644 index 0000000..53a0c8c --- /dev/null +++ b/docs/plans/screenshots-and-website.md @@ -0,0 +1,255 @@ +# Screenshots and the SealShare website + +## Goal + +Two things that feed each other. First, one command — `composer screenshots` — produces every +screenshot of SealShare from fixed demo data, desktop and phone, light and dark, ready for the web. +Second, a static website at **sealshare.nonameweb.ch**, made the way mailifysms.nonameweb.ch is: +hand-written HTML and CSS in `website/`, uploaded by hand. The site presents SealShare as what it +is — software a company installs to run **its own upload platform**, so it exchanges files with +customers securely without relying on an outside service — shows the screenshots, compares +SealShare with hosted transfer services and with other self-hosted tools, and tells how to install +it. It goes live with 2.0.0. The README gets a few of the same screenshots, and its encryption +wording is corrected. + +## Context + +**MailifySMS, the model** (`../MailifySMS`): + +- `website/` holds `index.html`, `privacy_policy.html`, `terms_and_conditions.html`, + `css/theme.css` (a palette sampled from the app's screenshots), `css/device-frame.css` (a phone + bezel shared with the store canvases), self-hosted Poppins (`fonts/`, OFL) and `img/` + (`icon.png`, `hero.jpg`, `screenshots/{light,dark}/NN-name.png` at 540px). +- `index.html`: sticky nav with a phone toggle, hero, "How it works", "Key features", a screenshot + gallery with a Light/Dark switch (`data-light`/`data-dark` on each ``), FAQ accordion, + contact card (`surtic86@gmail.com`), footer (quick links, legal). Plausible: + `