What the agent does
The agent maps LiveViews to tests before writing anything. In fly-apps/live_beats, lib/live_beats_web/live/ holds profile_live.ex, player_live.ex, settings_live.ex and sign_in_live.ex, with upload UI in profile_live/upload_form_component.ex. Presence is lib/live_beats_web/channels/presence.ex (LiveBeatsWeb.Presence on Phoenix.Presence). mix.exs declares Elixir ~> 1.12, Phoenix ~> 1.7.1, and phoenix_live_view from the Phoenix GitHub override, with floki only in test.
It reads test/live_beats_web/live/profile_live_test.exs. That file already covers own-profile upload of test/support/fixtures/silence1s.mp3 through #song-form, artist/title validation and delete-modal confirm, using Phoenix.LiveViewTest helpers (live/2, render_click, file_input, render_upload, assert_patch). Sections invalid uploads and viewing other profiles are still TODO. There is no LiveView test module for PlayerLive, and nothing drives two connected users through presence joins on a profile topic.
New tests extend those gaps: invalid upload content types; a second logged-in user viewing another profile; player controls (phx-click handlers in player_live.ex for play/pause/next/prev) with songs seeded via LiveBeats.AccountsFixtures and MediaLibrary fixtures; presence updates by connecting two live/2 sessions and asserting the presence list in LiveBeatsWeb.Presence / badge markup. It reuses ConnCase, log_in_user and the presence mocks under test/support/presence/ instead of inventing a parallel harness.
It runs mix test (or a focused mix test test/live_beats_web/live) in the sandbox with the app's Postgres test config, fixes flaky selectors against the HEEx templates, and opens a pull request that adds test files only unless a fixture helper must grow. Player coverage reads player_live.ex for the js_prev / next / play controls and the presence badge markup in presence.ex (presence-#{id} list items). Tests seed songs through LiveBeats.MediaLibrary helpers and test/support/fixtures/media_library_fixtures.ex so playback clicks operate on real rows instead of empty profiles.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Write Phoenix.LiveViewTest tests for this app's LiveViews that have none: the profile page, song uploads and playback controls, including presence updates between two connected users. Run mix test and open a pull request.",
"resources": [
{
"url": "https://github.com/your-org/your-phoenix-app"
}
]
}- Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
- Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
- Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.
What comes back
What comes back is a pull request that fills test/live_beats_web/live/ (extending profile_live_test.exs and adding coverage for PlayerLive and two-user presence). Application LiveViews and channels are left alone; fixtures under test/support/fixtures/ may gain helpers for a second user session.
The pull request description lists the mix test invocation that passed and which LiveViews each describe block covers. The trajectory stores ExUnit output, including any assert_patch or render HTML mismatches fixed before the final push.
Before merging, a reviewer checks that selectors (#upload-btn, #song-form, player buttons, presence list ids) still match the HEEx, that presence tests do not depend on wall-clock sleeps when assert_has / render retries suffice, and that CI's existing mix test job remains the required check.
Run it on every LiveView module changed
Hook a GitHub webhook for pulls that touch lib/live_beats_web/live/** or channels/presence.ex and POST this session request with the repo in resources. Each run gets its own Mix and database sandbox so presence processes do not collide with a developer's mix phx.server.
Use the API key's webhook URL to receive run.completed with the session link and notify the Phoenix channel. Keep within max_concurrent when backfilling several LiveView modules.
The use case this job follows, with its automation and trigger: Write the missing tests.
Why run it on Rush?
LiveView tests need a compiled OTP app, database and often two Browser-less LiveView connections to assert presence. That is awkward on a laptop already running the app. Rush isolates Mix, Postgres and the BEAM nodes in one sandbox so the agent can iterate on mix test without stopping your server. Settings and sign-in LiveViews already have lighter coverage elsewhere; this job concentrates on profile, player and presence where the TODOs and missing modules are.
The pull request is the proof: new ExUnit files, green mix test in the trajectory, and no claim about a manual click-through. You can run the same request on every LiveView-heavy service without serialising engineers on one machine.
Frequently asked questions
Does it use Wallaby or a real browser?
No. It uses Phoenix.LiveViewTest inside ExUnit, the same approach as profile_live_test.exs. Browser e2e is out of scope unless you ask for it separately.
How does it test presence between two users?
It logs in two users with the existing fixtures, opens two live/2 connections on the profile path, and asserts on presence markup or LiveBeatsWeb.Presence state. It prefers the mocks under test/support/presence/ when the suite already uses them.
Will it overwrite the existing upload test?
It keeps the passing own-profile upload example and implements the TODO blocks and missing PlayerLive coverage. Edits to existing asserts only happen if selectors in the templates have drifted.
What Elixir and Phoenix versions?
Whatever mix.exs pins. LiveBeats uses Elixir ~> 1.12, Phoenix ~> 1.7.1, and LiveView from GitHub with override: true. The sandbox installs Hex deps from mix.lock.