ScreenStack integration
ScreenStack integration
Section titled “ScreenStack integration”ScreenStack is VooStack’s visual-regression product. The FlightStack integration captures Flutter test screenshots in CI, diffs them against your baseline branch, and (optionally) pushes the approved set to App Store Connect and Google Play.
What you get
Section titled “What you get”- Pixel diffs on every PR. Side-by-side view of changed widgets, light vs. dark, every device profile you configure.
- Approval gates. Pull requests can be blocked until visual changes are explicitly approved.
- Store sync. When you’re ready to ship, push the approved set directly to App Store Connect and Play Console — no manual screenshot wrangling.
Setup overview
Section titled “Setup overview”- Create a ScreenStack project and link it to your FlightStack org.
- Instrument your tests with the
screenstackFlutter package. - Add the ScreenStack job to your CI pipelines.
- (Optional) Add the Upload Store Screenshots job to your release pipelines.
1. Link the project
Section titled “1. Link the project”In the FlightStack dashboard, Settings → Integrations → ScreenStack. Authorize the connection, pick the project you want this org to default to. You can override per pipeline.
2. Instrument
Section titled “2. Instrument”import 'package:flutter_test/flutter_test.dart';import 'package:screenstack/screenstack.dart';
import 'package:my_app/login_page.dart';
void main() { testWidgets('Login — empty', (tester) async { await tester.pumpWidget(const MyApp(home: LoginPage())); await ScreenStack.capture(tester, 'login/empty'); });
testWidgets('Login — error', (tester) async { await tester.pumpWidget(const MyApp(home: LoginPage(error: 'bad creds'))); await ScreenStack.capture(tester, 'login/error'); });}ScreenStack.capture() renders the current widget tree at the configured device profile +
theme variant and queues it for upload. The actual upload happens through the job, so unit
tests still run offline.
3. CI pipeline
Section titled “3. CI pipeline”┌──────────┐ ┌────────┐ ┌──────────────┐│ On PR │───▶│ Tests │───▶│ Screen Stack │└──────────┘ └────────┘ └──────────────┘ │ ▼ ┌──────────────┐ │ Notification │ │ (Slack PR) │ └──────────────┘See the ScreenStack job for inputs.
4. Release pipeline
Section titled “4. Release pipeline”┌────────────┐ ┌────────────┐ ┌──────────────┐ ┌────────────────────┐│ On Tag │───▶│ Build iOS │───▶│ Screen Stack │───▶│ Approval ││ v* │ │ │ │ │ │ "ship screenshots?"│└────────────┘ └────────────┘ └──────────────┘ └────────────────────┘ │ ▼ ┌────────────────────┐ │ Upload Store │ │ Screenshots │ └────────────────────┘Device profile recommendations
Section titled “Device profile recommendations”| Family | Profile | Use for |
|---|---|---|
| iPhone 6.7” | iphone-15-pro-max | Required for App Store submissions |
| iPhone 6.5” | iphone-15-pro | Required for older devices |
| iPad 13” | ipad-13 | Required if you target tablet |
| Pixel | pixel-7 | Required for Play Store submissions |
| Android tablet | nexus-tablet | Required if you target Android tablet |
Marketing-quality screenshots usually need a separate, polished pipeline run with mocked data
and explicit pumpAndSettle() calls. Don’t ship debug-mode screenshots to the App Store.
Troubleshooting
Section titled “Troubleshooting”Captures missing on the dashboard
Check the agent logs for screenstack/upload failures. The most common cause is an
expired ScreenStack project token — re-authorize the integration in dashboard settings.
Random diffs from font rendering
Lock the test font with --dart-define=FONT=NotoSans or use Flutter’s loadAppFonts() in
your test harness — system fonts drift between CI agents.
See also
Section titled “See also”- ScreenStack job — job reference
- Upload Store Screenshots job — promote to the stores