mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-14 00:01:03 +00:00
8963180006
- iOS: microphone usage text for "Take Video", no-export-compliance flag, ExportOptions.plist for App Store Connect uploads, the unused push forwarders gone; CI builds with Xcode 26 and lints the property lists. - Android: version and signing from Gradle properties (unsigned without them), R8 with keep rules for TREK's and Capacitor's reflective classes, no Auto Backup of the session cookie, no external file provider path, template and Firebase leftovers removed, keystores and service accounts ignored, full-size adaptive icon layers with a monochrome layer; CI also builds the release APK. - native-release.yml: signed bundle to a Play testing track and archive to TestFlight, by hand or on a v* tag, behind the store environment. - Version handshake: the server reports nativeApi 1, the app refuses a server below its minimum and tolerates an app older than the offline copy. - Address screen: privacy policy link, "Try the demo" and "What is a TREK server?"; the privacy link also in the app's server settings. Three new native strings in all 27 locales. - Donation links and the notices asking for one are hidden in the app. - Store listings for "TREK Travel Planner" in client/fastlane: texts, review notes with placeholders, privacy and account deletion page drafts, the feature graphic and icon, a length and image check in CI, and a Playwright store project with the scripts that turn its captures into screenshots. - Docs: wiki/Native-Apps.md, README no longer says there is no store app.
73 lines
3.0 KiB
TypeScript
73 lines
3.0 KiB
TypeScript
import { test, type Page } from '@playwright/test';
|
|
import { mkdirSync } from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
import { E2E_STATE_FILE } from '../../playwright.config';
|
|
import { clearNotices, seed } from '../screenshots/shot';
|
|
|
|
/**
|
|
* The store screenshots (`npm run store:shots`, then `npm run store:promote`).
|
|
*
|
|
* The same seeded demo trip the wiki pictures show, captured at the sizes App
|
|
* Store Connect and Google Play ask for: the iPhone 6.9" and iPad 13" displays,
|
|
* and a Play phone, 7" and 10" tablet. Below 768 px the phone shell answers, so
|
|
* the phone pictures show the phone UI; the tablets get the desktop layout they
|
|
* get on a real device.
|
|
*
|
|
* Raw captures go to e2e/.tmp/store/<device>/; scripts/store-screenshots.mjs
|
|
* flattens them (the stores refuse an alpha channel) and copies them into
|
|
* fastlane/. Nothing here asserts behaviour, and the run is not part of CI.
|
|
*/
|
|
|
|
const STORE_OUT_DIR = path.join(process.cwd(), 'e2e', '.tmp', 'store');
|
|
|
|
const DEVICES = [
|
|
{ name: 'iphone69', viewport: { width: 440, height: 956 }, deviceScaleFactor: 3, isMobile: true },
|
|
{ name: 'ipad13', viewport: { width: 1032, height: 1376 }, deviceScaleFactor: 2, isMobile: true },
|
|
{ name: 'play-phone', viewport: { width: 360, height: 640 }, deviceScaleFactor: 3, isMobile: true },
|
|
{ name: 'play-7in', viewport: { width: 810, height: 1440 }, deviceScaleFactor: 2, isMobile: true },
|
|
{ name: 'play-10in', viewport: { width: 1280, height: 720 }, deviceScaleFactor: 1.5, isMobile: true },
|
|
] as const;
|
|
|
|
/** The screens, in the order the listings show them. */
|
|
const SCREENS: { name: string; path: () => string }[] = [
|
|
{ name: 'dashboard', path: () => '/dashboard' },
|
|
{ name: 'plan', path: () => `/trips/${seed.tripId}?tab=plan` },
|
|
{ name: 'bookings', path: () => `/trips/${seed.tripId}?tab=buchungen` },
|
|
{ name: 'costs', path: () => `/trips/${seed.tripId}?tab=finanzplan` },
|
|
{ name: 'lists', path: () => `/trips/${seed.tripId}?tab=listen` },
|
|
{ name: 'journal', path: () => (seed.journeyId ? `/journey/${seed.journeyId}` : '/journey') },
|
|
];
|
|
|
|
/** Waits until the page has drawn what it is going to draw: fonts, images, no pending fade. */
|
|
async function settle(page: Page): Promise<void> {
|
|
await page.waitForLoadState('networkidle', { timeout: 5_000 }).catch(() => undefined);
|
|
await page.evaluate(async () => {
|
|
await document.fonts.ready;
|
|
});
|
|
await page.waitForTimeout(800);
|
|
}
|
|
|
|
for (const device of DEVICES) {
|
|
test.describe(device.name, () => {
|
|
test.use({
|
|
storageState: E2E_STATE_FILE,
|
|
viewport: device.viewport,
|
|
deviceScaleFactor: device.deviceScaleFactor,
|
|
isMobile: device.isMobile,
|
|
hasTouch: true,
|
|
});
|
|
|
|
SCREENS.forEach((screen, index) => {
|
|
test(`${index + 1} ${screen.name}`, async ({ page }) => {
|
|
const dir = path.join(STORE_OUT_DIR, device.name);
|
|
mkdirSync(dir, { recursive: true });
|
|
await page.goto(screen.path());
|
|
await clearNotices(page);
|
|
await settle(page);
|
|
await page.screenshot({ path: path.join(dir, `${index + 1}_${screen.name}.png`) });
|
|
});
|
|
});
|
|
});
|
|
}
|