Flutter Screenshots
ArchivedJune 1, 2020
A fork of mmcc007/screenshots — a CLI tool for automating Flutter app screenshots across devices. A deep dive into the technical challenges of automated testing in Flutter, generating App Store screenshots through auth flows, and navigating Apple's strict but necessary publishing requirements.
Purpose
Forked the screenshots CLI to try to automate the most tedious part of app publishing: generating properly sized screenshots for every required device type. Apple requires specific screenshot dimensions for each device family (iPhone 6.7", 6.5", 5.5", iPad Pro, etc.) and the manual process of running the app on each simulator, navigating to each screen, and capturing screenshots is soul-crushing at scale.
Stack
What I Learned
- Apple requires screenshots in specific pixel dimensions for each device class: 1290x2796 (iPhone 6.7"), 1284x2778 (iPhone 6.5"), 1242x2208 (iPhone 5.5"), 2048x2732 (iPad Pro 12.9"). Each localization (language) needs its own set. For an app supporting 5 screens across 4 device sizes in 3 languages, that is 60 screenshots — manually. This is the problem automated screenshot tools try to solve.
- Flutter integration testing (flutter_test + integration_test) can drive the app through real UI flows: tap buttons, enter text, scroll, navigate between screens. The screenshots package hooks into this by pausing at key moments and capturing the simulator's screen. The theory is elegant: write a test that walks through your app, capture screenshots at each important screen, output them in every required dimension.
- The practice is harder. Testing through authentication against production systems means your test needs real credentials or a test account, the auth flow must be deterministic (no CAPTCHAs, no 2FA prompts, no rate limiting), and the test environment must be indistinguishable from production visually. Most auth systems are designed to resist automation — which is exactly what you are trying to do.
- Flutter on web has additional testing limitations: the web renderer (CanvasKit vs HTML) produces different visual output, browser security sandboxes interfere with file system access for saving screenshots, and web-specific features (URL routing, browser history, responsive breakpoints) require a different testing approach than mobile. Full-screen capture on web often requires Puppeteer or Playwright wrapping the Flutter web app.
- The iOS simulator is the bottleneck for automated screenshots. Each device type requires booting a different simulator, which takes time and memory. Running screenshots across all required device types sequentially can take 30+ minutes. Parallel execution helps but requires enough RAM to run multiple simulators simultaneously. CI environments (GitHub Actions, Codemagic) often have memory limits that constrain parallelism.
- Apple's App Store Review Guidelines are strict but necessary. They require: screenshots that accurately represent the app (no misleading mockups), metadata that matches the app's functionality, privacy labels that disclose all data collection, and age ratings that reflect content. Apps that crash during review are rejected. Apps that request unnecessary permissions are rejected. The process takes 24-48 hours and results in either approval or a specific rejection reason. The strictness protects users — every app on the store has passed a human review.
Key Insights
- The App Store publishing pipeline is a state machine with high stakes: Prepare Submission → Upload Build → Submit for Review → In Review → Approved/Rejected. Each transition has requirements that must be met exactly. Missing a single screenshot size, an incorrect privacy label, or a crash on a reviewer's device resets you to the beginning. Understanding this pipeline — and automating everything that can be automated — is what separates developers who ship one app from developers who maintain several.
- Automated screenshot generation is an underappreciated DevOps problem. Most developers treat screenshots as a one-time manual task during initial launch. But every UI update, every new feature, every localization addition means the screenshots are stale. The teams that automate this into their CI pipeline (Fastlane + screenshots, or Flutter's integration_test + screenshot capture) save days of manual work per release cycle.
- Apple's strictness is a feature, not a bug. The App Store review process is the reason users trust that downloaded apps will not steal their data, crash their phone, or misrepresent their functionality. Every developer who has been rejected knows the frustration. Every user who has never installed malware from the App Store knows the benefit. The tension is intentional and correct.
- The broader lesson from this project: the hardest parts of shipping software are rarely the code. They are the compliance, the metadata, the screenshots, the descriptions, the privacy policies, the review responses. The app itself might take a month. Getting it through the App Store pipeline takes another week of non-code work. Automating that non-code work is where the real efficiency gains live.
This post was composed through a conversation between Brett Owers and Claude Code (Anthropic). The content reflects Brett's recollection of each project and the lessons drawn from it. Some details may be approximate or omitted — the purpose is to paint an honest picture of a software engineer's development over time, not to serve as a precise historical record.