Commit graph

66 commits

Author SHA1 Message Date
Adam Brown
22520baca3
Fix flaky iOS scene-editor save UI test (#786)
tapUntilGone gated the save tap solely on isHittable. Under CI load the
top-bar save button's accessibility frame can never settle to hittable
within the timeout, so the loop waited out the whole budget without ever
tapping and failed with 'Element still present after 20.0s'.

Keep the proven isHittable hit-tested fast path and add a geometry
fallback: once the button's frame has settled (fully below the status
bar, ruling out the transient dead-pixel position, and stable across two
samples) tap it via tapCenter. This guarantees a tap eventually fires
even when isHittable never flips true, while still avoiding the
dead-pixel/scroll-away hazard the isHittable gate originally fixed.
2026-07-28 22:38:18 -07:00
Adam Brown
fdeab5b992 Prepared for release: v3.7.2 2026-07-27 13:45:42 -07:00
Adam Brown
3375d81b55 Prepared for release: v3.7.1 2026-07-23 14:36:28 -07:00
Adam Brown
8742202de5 Prepared for release: v3.7.0 2026-07-21 09:10:11 -07:00
Adam Brown
fab1da62de Revert "Prepared for release: v3.7.0"
This reverts commit 9bfc9ec8e1.
2026-07-21 09:01:45 -07:00
Adam Brown
9bfc9ec8e1 Prepared for release: v3.7.0 2026-07-21 00:56:45 -07:00
Adam Brown
8bc1322c82
Retry the focus tap in the iOS UI test type() helper (#757)
A dropped coordinate tap left the field unfocused, so the software
keyboard never rose and the test failed on the single 10s wait.
Re-focus until the keyboard appears, matching typeIntoEditor.
2026-07-20 10:29:31 -07:00
Adam Brown
57f4f2a9fe
Harden flaky iOS scene-editor UI test with tap-retry helpers (#741)
* Harden flaky iOS scene-editor UI test with tap-retry helpers

SceneEditorWorkflowUITests.testEditSceneTextThenSave intermittently timed
out (most visibly waiting 20s for the save affordance to disappear). The
UI is Compose Multiplatform, which renders to a single surface, so
XCUITest taps are best-effort coordinate taps onto that surface. An
individual tap can be silently dropped (mid-relayout, under simulator
load, or while the software keyboard geometry is shifting). A lone tap
followed by one long wait is the classic XCUITest flake: a single dropped
tap costs the whole timeout and fails the test.

Add a small retry primitive and route the flake-prone taps through it:

- tapUntil(element, until:) re-taps on a short sub-timeout until the app
  demonstrably reacts, converging instead of eating the full timeout on
  one dropped tap.
- tap(_:expecting:) drives each scene-creation step by the element its
  tap surfaces (add menu, then the create-item dialog).
- tapUntilGone(_:) replaces the lone save tap + long wait; it also covers
  a late IME keystroke re-dirtying the buffer right after a save.
- openProjectCard re-taps the card until the project root's nav rail
  renders (same dropped-tap resilience), keeping its existing
  name/firstMatch card selection.

Validated by running the full iosUITests scheme on freshly-erased
simulators across 6 consecutive runs (all four UI test classes green
every run).

* Fix save-tap flake: only tap the save button when it's settled/hittable

CI surfaced the actual flake this test was meant to harden: the save tap
timed out because the button's accessibility frame is briefly stale right
after the edit that surfaces it — reported up under the status bar (a dead
pixel) until the top-bar layout settles. Blindly re-tapping that stale
coordinate never saved and could even scroll the app away from the editor,
so the re-tap loop ran the full timeout and failed.

Make tapUntilGone tap only when the button reports itself hittable
(settled), using a hit-tested tap() that re-resolves its real position;
otherwise wait for it to settle. Left untouched, the button stays hittable
even under load, so this converges cleanly instead of fighting a dead spot.

Scoped to the save helper; the navigation/card taps are unchanged.

Validated on a CI-sized simulator (iPhone 16e, 390x844) across 6 runs
under CPU load, all green.
2026-07-16 17:56:29 -07:00
Wavesonics
cfd3fefb5c Promote iOS scene editor UI test to full edit+save flow
The iOS SceneEditorWorkflowUITests was scoped to "scene opens" rather than
the Android-parity edit->save flow because the scene-editor-save affordance
never surfaced to XCUITest. Root cause: the iOS EditorTopBar save IconButton
was missing the SCENE_EDITOR_SAVE_TAG testTag that the Android/desktop
variants carry, so even once the edit dirtied the buffer and the button
rendered, XCUITest had no accessibility identifier to find.

- Tag the iOS EditorTopBar save button with SCENE_EDITOR_SAVE_TAG.
- Add a typeIntoEditor(_:into:until:) helper to HammerUITest that re-focuses
  and re-injects until the edit propagates, mirroring the Android
  typeIntoEditor retry loop (guards the enabled=hasReceivedInitialBuffer
  gate on the initial buffer load).
- Promote testCreateSceneOpensEditor to testEditSceneTextThenSave: type into
  the editor, assert save appears, tap it, assert it disappears — matching
  SceneEditorWorkflowTest.editSceneTextThenSave.

Verified on iPhone 16 (iOS 18.6) simulator: TEST SUCCEEDED.
2026-07-14 23:01:08 -07:00
Adam Brown
c5c42f2938 Prepared for release: v3.6.1 2026-07-12 23:30:39 -07:00
Adam Brown
501de2e597 Prepared for release: v3.6.0 2026-07-07 23:22:53 -07:00
Adam Brown
177e4bbe4f Prepared for release: v3.5.3 2026-06-30 15:16:45 -07:00
Adam Brown
43a836844d
Add iOS UI smoke tests (XCUITest) (#707)
* Add iOS UI smoke tests (XCUITest)

Adds an iOS UI smoke-test suite that drives the real app on a simulator via
XCUITest, the iOS analogue of the android/src/androidTest Compose UI tests.
The whole iOS UI is Compose Multiplatform, and CMP (1.8+) maps Compose testTags
to iOS accessibilityIdentifiers automatically, so the tests target the same
testTags the Android suite uses.

Workflows covered (all green on simulator):
- LaunchSmoke: app boots through the SwiftUI entry point, Koin + data migration
  run, project selection renders.
- ProjectWorkflow: create + open a project (exercises the create dialog text
  entry and navigation into the editor).
- SceneEditorWorkflow: create a scene and confirm it opens in the editor.
- NotesWorkflow: navigate to Notes and open the create-note screen.

Setup:
- ios/scripts/add_ui_test_target.rb idempotently creates the iosUITests
  UI-testing target + shared scheme via the xcodeproj gem (the folder previously
  had source files but no actual target).
- ios/scripts/disable_sim_hardware_keyboard.sh forces the software keyboard so
  XCUITest text entry lands (Compose fields need it).
- ios-ui-tests CI job runs the suite on a simulator and uploads the xcresult on
  failure.
- composeUi ProjectCreateDialog: tag the name field so the create flow is
  targetable (also benefits Android).

Known limitation: the app's custom rich-text editors (scene body, note body via
MarkdownEditField) do not report keyboard focus to XCUITest, so their text entry
can't be driven (only standard Compose text fields can). The scene and notes
tests therefore stop at "editor opens" / "creation screen opens"; the full
edit/create-with-body paths remain covered by the Android suite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* iOS UI tests: type into note body via composetexteditor 2.3.0

composetexteditor 2.3.0 publishes text-editing accessibility semantics on its
editor, so XCUITest can now drive text entry into it. Bump the dependency and
promote the Notes UI test to the full Android-parity flow: create a note by
typing into the body, then assert its card appears.

The scene edit+save flow stays scoped to "scene opens" for now — text entry
works, but the scene editor's initial-buffer gating + dirty-driven save make
the save affordance unreliable to assert from an IME-driven edit; promoting it
is a follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 10:39:04 -07:00
Adam Brown
57de1c6522 Prepared for release: v3.5.2 2026-06-29 22:15:55 -07:00
Adam Brown
46ce5042d3 Prepared for release: v3.5.1 2026-06-27 23:51:29 -07:00
Adam Brown
1a0a50bd76 Prepared for release: v3.5.0 2026-06-27 00:39:39 -07:00
Adam Brown
3b23dc6cf0 Prepared for release: v3.4.2 2026-06-23 10:10:05 -07:00
Adam Brown
77f1eb1884 Prepared for release: v3.4.1 2026-06-23 00:45:34 -07:00
Adam Brown
080c403619 Prepared for release: v3.4.0 2026-06-22 22:02:40 -07:00
Adam Brown
49ba08b55a Prepared for release: v3.3.1 2026-06-16 00:34:56 -07:00
Adam Brown
18bcc4652f Prepared for release: v3.3.0 2026-06-13 12:44:51 -07:00
Adam Brown
6fd3fd15ae
Prepared for release: v3.2.1 2026-06-10 19:41:32 -07:00
Adam Brown
93de0e7fd1
Prepared for release: v3.2.0 2026-06-08 00:08:51 -07:00
Wavesonics
97bc5a1b1a Prepared for release: v3.1.3 2026-06-04 21:56:12 -07:00
Adam Brown
35ecc7b750
Prepared for release: v3.1.2 2026-06-03 00:37:43 -07:00
Adam Brown
6c705d11bb
Prepared for release: v3.1.1 2026-06-02 00:29:07 -07:00
Adam Brown
28d0d2bdf1
Prepared for release: v3.1.0 2026-06-01 23:10:53 -07:00
Wavesonics
2517bb80c6 Add manifest-driven asset generation pipeline
Replace ad-hoc icon scripts with a single source-of-truth manifest
  (scripts/assets.yaml) and a Python generator that renders every app icon,
  store-listing graphic, MSIX tile, favicon, and the Play feature graphic from
  two SVG sources. Compositions (icon + "Hammer" wordmark in Kingthings
  Trypewriter) are defined once as percentages of canvas and reused across the
  Play feature graphic, MSIX wide/splash tiles, and the Snap featured banner.

  Adds the missing snap store icon, fixes the snap desktop icon to the correct
  256x256 hicolor size, and routes uploads-only assets to build/store-assets/
  (gitignored).

  See docs/ASSET-GENERATION.md for the manifest schema.
2026-05-22 19:26:49 -07:00
Wavesonics
246914d10f Cleanup plist 2026-05-20 23:27:12 -07:00
Wavesonics
331ff2336c Prep iOS Info.plist + profile reference for App Store submission
Declare ITSAppUsesNonExemptEncryption=false so App Store Connect stops
asking on every upload, drop the legacy armv7 UIRequiredDeviceCapabilities
entry, and align CFBundleShortVersionString with the shared codebase
version (3.0.3) in gradle/libs.versions.toml. pbxproj now references the
freshly-issued "Hammer AppStore iOS" provisioning profile.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:16:31 -07:00
Wavesonics
496e05d934 clean up ios user files 2026-05-20 22:45:14 -07:00
Wavesonics
a3b077824a Add iOS support via Compose Multiplatform
iOS now runs the same shared Compose UI as Android and Desktop. The
existing Decompose component graph (IosRoot, ProjectSelection,
ProjectRoot) is reused; the Swift app shrinks to an AppDelegate, a
Koin bootstrap, and a UIViewControllerRepresentable that hands off to
a Kotlin ComposeUIViewController. The SwiftUI starter under
/ios/ios/ui and /ios/ios/DecomposeHelpers is deleted.

Hammer.framework moves from :common to :composeUi so the framework
ships the Compose entry point; Xcode's Run Script invokes
:composeUi:embedAndSignAppleFrameworkForXcode. iosArm64 and
iosSimulatorArm64 targets are declared with libbacktrace source-info
so K/N crashes report file:line. 17 expects across composeUi get iOS
actuals (file pickers via filekit, image loading via Coil3,
LanguageUtil via NSLocale.preferredLanguages, etc).

The adaptive nav scaffolds — bottom bar at compact width, side nav
rail otherwise — are extracted from the Android activities into
shared ProjectSelectScaffold and ProjectRootScaffold in
composeUi/commonMain, along with their Modifier helpers and the
close-confirm dialogs. Android activities are now thin shells that
delegate to these; iOS calls the same scaffolds, so phone/tablet
layout is unified across all three platforms.

App icon and CFBundleDisplayName set so the home screen reads
"Hammer" with the brand logo instead of the blueprint placeholder.
2026-05-20 00:36:29 -07:00
Wavesonics
327b5322cb Remove macos AppImage target format 2026-05-18 21:24:06 -07:00
Adam Brown
244cc78e3c
Drop iosX64 target (removed from Compose Multiplatform 1.11) 2026-05-13 21:58:48 -07:00
Adam Brown
4552279d75
Ios example project (#225)
* Implemented iOS example project installer zip file handling
2024-01-20 20:04:57 -08:00
Wavesonics
50ecb4f5f4 working on ios proj install 2024-01-15 13:33:05 -08:00
Wavesonics
baa193baca iOS proj select screen work 2024-01-15 13:26:01 -08:00
Wavesonics
3b5849a38d iOS seems to be up and running? 2024-01-15 13:10:05 -08:00
Wavesonics
c5f46cf71d ProjectList ios UI still sorta working 2024-01-15 00:30:38 -08:00
Wavesonics
50fb8a9569 Fix ios build 2024-01-15 00:05:56 -08:00
Wavesonics
13e99cf466 Fix ios build 2023-11-22 15:45:53 -08:00
Wavesonics
2a81346d02 Switch provisioning profile 2023-06-27 23:02:30 -07:00
Bill Booth
6cfe1a8388 Add ios build stage 2023-05-08 21:24:52 -07:00
Wavesonics
d9045cf741 ios signing 2023-05-07 22:26:44 -07:00
Wavesonics
0372f3f64e ios is building again 2023-04-17 23:57:31 -07:00
Adam Brown
f1165d3bf4 Upgraded to Decompose 2.0.0 alpha
- Kotlin 1.8.20
- Fixed some light/dark theme issues on Android
2023-04-13 20:23:37 -07:00
Bill Booth
24eeaf61ac Get previews working in ios
Use the preview from app_iosApp.swift. The other views require data not easily accessible.
2023-03-21 23:56:31 -07:00
Bill Booth
562c4e815f Shift ios support to IOS16 and up
If we make 16.0 our min version, it gives a little more flexibility in the swiftui stuff we do.
2023-03-21 23:54:32 -07:00
Wavesonics
1a17da9a6a Dont have top level State class 2023-03-19 12:42:59 -07:00
Wavesonics
39bab2e1fc Fix ios build 2023-03-19 12:31:57 -07:00