Commit c2d1a2156d

c2d1a2156d18f83775faac47e21565e25f8d638f

parent: 869d0abff4

Verified · cmc

cmc <hello@cleberg.net> · 2026-10-16 19:32 UTC

App Store header and screenshots from 1.14.1

AppStore/ follows orgstar's ios/AppStore layout. header.html renders the
21:9 and 16:9 product page headers: three iPhones over the app's indigo
(#4338ca), as on krz.sh/apps/gitbay. Screenshots are light mode, taken by
the checkpoint tests as cmc on the iPhone 18 Pro Max and iPad Pro 13-inch
(M5) simulators; the 6.3" set is resized from the 6.9" one.

testScreenshotCheckpoint now captures the MR detail at its header, before
scrolling to the diff row. testIPadScreenshotCheckpoint opens the first
dashboard item so the split view's detail is not the empty placeholder.

Layout: unified · split

AppStore/header-16x9.png added

Binary file not shown.

AppStore/header-21x9.png added

Binary file not shown.

AppStore/header.html added +42
@@ -0,0 +1,42 @@
1<!doctype html>
2<!-- Product page header, after the krz.sh hero: three iPhones fanned over the app's indigo (#4338ca).
3 header.html renders the 21:9 header (3840x1646), header.html#wide the 16:9 one (5244x2950),
4 with headless Chromium, then the alpha channel is removed:
5 Chromium --headless --hide-scrollbars --force-device-scale-factor=1 --window-size=3840,1646 --screenshot=header-21x9.png header.html
6 Chromium --headless --hide-scrollbars --force-device-scale-factor=1 --window-size=5244,2950 --screenshot=header-16x9.png "file://$PWD/header.html#wide"
7 magick header-21x9.png -alpha off PNG24:header-21x9.png -->
8<html>
9<head>
10<meta charset="utf-8">
11<style>
12 :root { --u: 1px; --top: 180px; }
13 * { box-sizing: border-box; }
14 html, body { margin: 0; width: 3840px; height: 1646px; overflow: hidden; }
15 body {
16 position: relative;
17 background:
18 radial-gradient(ellipse 55% 75% at 50% 30%, #6d64e8 0%, #4338ca 35%, #272080 70%, #120f3d 100%);
19 }
20 .iphone {
21 position: absolute; left: 50%; top: var(--top);
22 width: calc(860 * var(--u)); height: calc(1868 * var(--u));
23 padding: calc(24 * var(--u)); border-radius: calc(140 * var(--u)); background: #0c0c12;
24 box-shadow: 0 calc(50 * var(--u)) calc(120 * var(--u)) rgba(0, 0, 0, 0.5);
25 }
26 .iphone img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; border-radius: calc(116 * var(--u)); }
27 .center { transform: translateX(-50%); z-index: 2; }
28 .left { transform: translate(calc(-50% - 760 * var(--u)), calc(120 * var(--u))) rotate(-8deg); }
29 .right { transform: translate(calc(-50% + 760 * var(--u)), calc(120 * var(--u))) rotate(8deg); }
30
31 /* 16:9, 5244x2950. */
32 html.wide { --u: 1.6px; --top: 420px; }
33 html.wide, .wide body { width: 5244px; height: 2950px; }
34</style>
35<script>if (location.hash === "#wide") document.documentElement.className = "wide";</script>
36</head>
37<body>
38 <div class="iphone left"><img src="screenshots/iphone-6.9/02-repo.png"></div>
39 <div class="iphone right"><img src="screenshots/iphone-6.9/03-mr-list.png"></div>
40 <div class="iphone center"><img src="screenshots/iphone-6.9/01-dashboard.png"></div>
41</body>
42</html>
AppStore/icon-64.png added

Binary file not shown.

AppStore/screenshots/ipad/01-dashboard.png added

Binary file not shown.

AppStore/screenshots/ipad/02-explore.png added

Binary file not shown.

AppStore/screenshots/ipad/03-repo.png added

Binary file not shown.

AppStore/screenshots/ipad/04-feed.png added

Binary file not shown.

AppStore/screenshots/ipad/05-profile.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/01-dashboard.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/02-repo.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/03-mr-list.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/04-mr-detail.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/05-diff.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/01-dashboard.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/02-repo.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/03-mr-list.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/04-mr-detail.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/05-diff.png added

Binary file not shown.

gitbayUITests/LiveSmokeUITests.swift +14 −3
@@ -1156,11 +1156,14 @@ extension LiveSmokeUITests {
11561156 snap("mr-list")
11571157
11581158 mrNumber.tap()
1159 // The detail opens at its header; the diff row sits below the
1160 // fold and a List does not build rows it has not shown.
1159 // Captured at its header, before scrolling down to the diff row.
1160 XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 15), "MR detail did not open")
1161 snap("mr-detail")
1162
1163 // The diff row sits below the fold and a List does not build rows
1164 // it has not shown.
11611165 let diffRow = app.staticTexts["Diff"].firstMatch
11621166 XCTAssertTrue(scrollTo(diffRow), "MR detail has no diff row")
1163 snap("mr-detail")
11641167
11651168 diffRow.tap()
11661169 XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 15))
@@ -1553,6 +1556,14 @@ extension LiveSmokeUITests {
15531556 /// deferred. Tabs and a list row work on both.
15541557 func testIPadScreenshotCheckpoint() throws {
15551558 signInIfNeeded()
1559 // The split view's detail is empty until a row is chosen; open the
1560 // first issue or merge request so the shot is not half placeholder.
1561 let item = app.staticTexts
1562 .matching(NSPredicate(format: "label MATCHES '.+/.+[#!][0-9]+'")).firstMatch
1563 XCTAssertTrue(item.waitForExistence(timeout: 20), "dashboard listed no items")
1564 item.tap()
1565 XCTAssertTrue(waitForDisappearance(app.staticTexts["Nothing selected"].firstMatch, timeout: 15),
1566 "dashboard detail did not open")
15561567 snap("dashboard")
15571568
15581569 selectTab("Explore")