6d455c9098
## Summary - Remove the compose FAB, the new chat FAB, the "load latest" button and the Discover/Following inline composer prompt. The new chat entry point still needs a replacement. - Add `features/composePrompt`: screens register a pill config (label, accessibility text, an `open` callback) and the bottom bar renders a single pill driven by that context. Registration follows the screen's presence, so the pill fades in and out with pushes, pops and swipe-back, and the label switches to whichever screen is most present mid-transition. The bar's top border hides while a pill is registered. - The pill is a Liquid Glass view with `isInteractive`, toggling its glass style with the system animation as it comes and goes, with a gradient behind it that fades further than the thread version so content shows through the glass. It includes the camera and gallery buttons from the old feed prompt. - When the bottom bar hides, the pill drops into the bar's space and scales down, inset equally from the left, right and bottom edges so its corners sit concentric with the device bevels; while the bar shows it hugs the edges. - Home, Notifications, Feeds, custom feeds and lists open the composer; a profile pre-fills a mention as the FAB did; a thread opens the reply composer, including media picked from the pill. ## Test plan - [ ] Home: pill above the bar; tap opens composer; camera/gallery open with media - [ ] Home: scroll down hides the bar and the pill drops, shrinks and sits inset from the bevels; scroll up restores it - [ ] Push a thread from Home: label crossfades to "Write your reply" mid-transition; tap opens the reply composer - [ ] Thread with replies disabled: pill fades out on push and back in on pop - [ ] Profile of another user: composer opens with their handle - [ ] Search tab / Messages tab: pill fades out; pill fades back when returning - [ ] Conversation screen: pill fades out while the bar slides away - [ ] Android / iOS < 26: plain pill fallback fades in and out - [ ] Mobile web: pill shows above the web bottom bar Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QoggCVt9XgpKbjrTZjoJD9
186 lines
5.4 KiB
YAML
186 lines
5.4 KiB
YAML
appId: xyz.blueskyweb.app
|
|
---
|
|
- runScript:
|
|
file: ../setupServer.js
|
|
env:
|
|
SERVER_PATH: "?users&follows"
|
|
- runFlow:
|
|
file: ../setupApp.yml
|
|
|
|
# Login, create a thread, and log out
|
|
- tapOn:
|
|
id: "e2eSignInAlice"
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "viewHeaderHomeFeedPrefsBtn"
|
|
- assertVisible:
|
|
id: "composePromptPill"
|
|
- tapOn:
|
|
id: "composePromptPill"
|
|
- inputText: "Test thread"
|
|
- tapOn:
|
|
id: "composerPublishBtn"
|
|
# Wait for the composer to close and the home feed to settle before signing
|
|
# out. Without a settle guard the next action can race the closing composer.
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "composePromptPill"
|
|
timeout: 10000
|
|
|
|
# Login, reply to the thread, and log out
|
|
- tapOn:
|
|
id: "e2eSignOut"
|
|
- tapOn:
|
|
id: "e2eSignInBob"
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "viewHeaderHomeFeedPrefsBtn"
|
|
- tapOn:
|
|
id: "replyBtn"
|
|
# Wait for the composer to fully open before typing.
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "composerPublishBtn"
|
|
timeout: 10000
|
|
- inputText: "Reply 1"
|
|
- tapOn:
|
|
id: "composerPublishBtn"
|
|
# Wait for the composer to close before signing out.
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "composePromptPill"
|
|
timeout: 10000
|
|
|
|
# Login, confirm notification exists, mute thread, and log out
|
|
- tapOn:
|
|
id: "e2eSignOut"
|
|
- tapOn:
|
|
id: "e2eSignInAlice"
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "viewHeaderHomeFeedPrefsBtn"
|
|
- tapOn:
|
|
id: "bottomBarNotificationsBtn"
|
|
- assertVisible: ".*Reply 1.*"
|
|
- tapOn: ".*Reply 1.*"
|
|
- tapOn:
|
|
id: "postDropdownBtn"
|
|
childOf:
|
|
id: "postThreadItem-by-bob.test"
|
|
- tapOn: "Mute thread"
|
|
|
|
# Login, reply to the thread twice, and log out
|
|
- tapOn:
|
|
id: "e2eSignOut"
|
|
- tapOn:
|
|
id: "e2eSignInBob"
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "viewHeaderHomeFeedPrefsBtn"
|
|
- tapOn:
|
|
id: "bottomBarProfileBtn"
|
|
- tapOn:
|
|
id: "profilePager-selector-1"
|
|
# Both replies target the thread root ("Test thread" by alice), which sits at
|
|
# the top of bob's Replies tab. That tab renders each post in the thread with
|
|
# its own replyBtn, so scope the tap to the root post's card
|
|
# (feedItem-by-alice.test) rather than relying on which replyBtn Maestro picks
|
|
# first. This keeps both reply taps deterministic regardless of list order or
|
|
# how many posts have rendered.
|
|
#
|
|
# Even with the close-gating below, the replyBtn tap can land on a recycled list
|
|
# row while the author feed re-renders after a publish, and be swallowed so the
|
|
# composer never opens. Wrapping the tap + open-wait in retry makes opening the
|
|
# composer idempotent: a swallowed tap just re-taps until the publish button
|
|
# appears. A first-try success does not retry.
|
|
- retry:
|
|
maxRetries: 3
|
|
commands:
|
|
- tapOn:
|
|
id: "replyBtn"
|
|
childOf:
|
|
id: "feedItem-by-alice.test"
|
|
# Wait for the composer to fully open before typing.
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "composerPublishBtn"
|
|
timeout: 10000
|
|
- inputText: "Reply 2"
|
|
- tapOn:
|
|
id: "composerPublishBtn"
|
|
# Wait for the composer to actually close before opening it again. replyBtn
|
|
# stays in the accessibility tree behind the open composer sheet, so waiting on
|
|
# its visibility returns immediately and does not gate on the close animation or
|
|
# the author-feed re-render that follows a post - the next replyBtn tap then
|
|
# fires mid-transition and is swallowed, so the composer never opens. Gate on
|
|
# the publish button disappearing (the composer is gone), then confirm the
|
|
# reply button underneath is back and let animations settle.
|
|
- extendedWaitUntil:
|
|
notVisible:
|
|
id: "composerPublishBtn"
|
|
timeout: 15000
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "replyBtn"
|
|
timeout: 10000
|
|
- waitForAnimationToEnd
|
|
# As with Reply 2: even after gating on the composer close, this tap can hit a
|
|
# recycled row during the post-publish feed re-render and be swallowed, so wrap
|
|
# the open in retry to make it idempotent.
|
|
- retry:
|
|
maxRetries: 3
|
|
commands:
|
|
- tapOn:
|
|
id: "replyBtn"
|
|
childOf:
|
|
id: "feedItem-by-alice.test"
|
|
# Wait for the composer to fully open before typing.
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "composerPublishBtn"
|
|
timeout: 10000
|
|
- inputText: "Reply 3"
|
|
- tapOn:
|
|
id: "composerPublishBtn"
|
|
# Wait for the composer to actually close before signing out. As above,
|
|
# replyBtn stays visible behind the sheet, so gate on the publish button
|
|
# disappearing first, then confirm the reply button underneath has returned.
|
|
- extendedWaitUntil:
|
|
notVisible:
|
|
id: "composerPublishBtn"
|
|
timeout: 15000
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "replyBtn"
|
|
timeout: 10000
|
|
|
|
# Login, confirm notifications dont exist, unmute the thread, ~~confirm notifications exist~~
|
|
# Mute thread behaviour no longer change old notifications after muting/unmuting a thread -sfn
|
|
- tapOn:
|
|
id: "e2eSignOut"
|
|
- tapOn:
|
|
id: "e2eSignInAlice"
|
|
- extendedWaitUntil:
|
|
visible:
|
|
id: "viewHeaderHomeFeedPrefsBtn"
|
|
- tapOn:
|
|
id: "bottomBarNotificationsBtn"
|
|
- assertVisible: ".*Reply 1.*"
|
|
- assertNotVisible: ".*Reply 2.*"
|
|
- assertNotVisible: ".*Reply 3.*"
|
|
- tapOn: ".*Reply 1.*"
|
|
- tapOn:
|
|
id: "postDropdownBtn"
|
|
childOf:
|
|
id: "postThreadItem-by-bob.test"
|
|
- tapOn: "Unmute thread"
|
|
- tapOn:
|
|
id: "bottomBarNotificationsBtn"
|
|
- swipe:
|
|
from:
|
|
id: "notifsFeed"
|
|
direction: DOWN
|
|
- assertVisible: ".*Reply 1.*"
|
|
- assertNotVisible: ".*Reply 2.*"
|
|
- assertNotVisible: ".*Reply 3.*"
|