Skip to content

feat: accept driver instances instead of {type, ...} config objects - #260

Merged
gmegidish merged 4 commits into
mainfrom
feat/instance-based-driver-config
Aug 5, 2026
Merged

feat: accept driver instances instead of {type, ...} config objects#260
gmegidish merged 4 commits into
mainfrom
feat/instance-based-driver-config

Conversation

@gmegidish

Copy link
Copy Markdown
Member

Summary

  • defineConfig({ driver }) now takes a driver instance (e.g. new MobileNextDriver({ apiKey })) instead of a { type: 'mobilenext', ... } config object. Omit driver entirely for the MobilecliDriver default.
  • MobilewrightDriver (in @mobilewright/protocol) gained allocate/release — the separate DeviceAllocator/MobilecliAllocator/MobileNextAllocator layer and the three driver.type-switch sites (allocator-factory.ts, launchers.ts ×2) are gone. A driver package now only needs to implement one interface.
  • Two new optional hooks on MobilewrightDriver: prepare()/dispose() for driver-owned lifecycle (mobilecli's local server auto-start/kill now lives inside MobilecliDriver itself), and configureReporting() for drivers that want to auto-inject a reporter (mobile-next's upload reporter, previously wired via a driver.type === 'mobilenext' check in core config.ts).
  • url/autoStart/mobilecliPath moved off the top-level config and into MobilecliDriver's own constructor options; mobilecliPath is now actually wired through to binary resolution (previously declared but unused).
  • Dropped the region option on MobileNextDriver — confirmed unused anywhere in the codebase.
  • Updated the init template, both e2e configs, and three docs pages to the new syntax.
  • Along the way, fixed a real bug surfaced while validating against a live mobile-next device: e2e/tsconfig.json was missing project references for driver-mobilecli/driver-mobilenext (needed once the e2e config started importing them directly), and e2e/mobilewright.config.ts's timeout: 60_000 was too short for real cloud device provisioning (~74-120s), causing every test to time out mid-allocation.

Test plan

  • npm run build — clean
  • npm run lint — clean
  • npm test — 551 passed, 1 skipped
  • Verified end-to-end against a live mobile-next iOS device (e2e/, test:mobilenext): allocation → connect → WebSocket → RPC → real device control all confirmed working; remaining failures in that run are pre-existing e2e test/environment gaps (missing app install on cloud device), unrelated to this change
  • Manual run against mobilecli (local device) — not yet verified by a human

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e5764d64-6ffc-400c-8013-ca298309e319

📥 Commits

Reviewing files that changed from the base of the PR and between 8e2320a and 3d96c00.

📒 Files selected for processing (2)
  • packages/driver-mobilecli/src/driver.ts
  • packages/mobilewright/src/device-pool/application/device-pool.ts

Walkthrough

The change replaces tagged driver configuration objects and allocator classes with concrete MobilewrightDriver instances. The protocol now defines allocation, release, lifecycle, and reporting contracts. MobileCLI manages server and local-device lifecycle. Mobile Next uses Fleet sessions for cloud-device allocation and reporting. Mobilewright integrates drivers into configuration, launchers, setup, and DevicePool. Tests, end-to-end configuration, dependencies, and documentation use the new driver instances.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description accurately summarizes the driver-instance migration, allocator removal, lifecycle changes, documentation updates, and test results.
Title check ✅ Passed The title clearly states the main change: driver instances replace type-based configuration objects.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/instance-based-driver-config

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/driver-mobilecli/src/driver.ts (1)

277-300: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Keep server ownership through connect().

Line 280 clears a handle created by prepare() when the server is already reachable. A later disconnect() or dispose() cannot stop that process.

If RPC connection, device resolution, or agent setup fails after this call starts a server, this.session remains unset. disconnect() then cannot clean up the server.

Preserve an existing handle when ensured.serverProcess is undefined. Use a failure cleanup path for the process started by this connect() call.

Proposed fix
 const ensured = await ensureMobilecliReachable(url, { autoStart: this.autoStart, binaryPath: this.mobilecliPath });
- this.ownedServerProcess = ensured.serverProcess;
+ if (ensured.serverProcess) {
+   this.ownedServerProcess = ensured.serverProcess;
+ }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/driver-mobilecli/src/driver.ts` around lines 277 - 300, Update
connect() to preserve this.ownedServerProcess when ensured.serverProcess is
undefined, rather than clearing an existing handle created by prepare(). Track
the server process started by this connect() call and clean it up if RPC
connection, device resolution, or agent setup fails before this.session is
assigned, while retaining the successful connection behavior.
packages/driver-mobilecli/src/server.ts (1)

100-106: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle invalid configured binary paths.

resolveMobilecliBinary() returns any nonempty explicit path. If the path does not exist or is not executable, spawn() emits an unhandled error event and can terminate the process. Attach an error listener and reject startMobilecliServer() with an actionable error.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/driver-mobilecli/src/server.ts` around lines 100 - 106, Update
startMobilecliServer and its startMobilecliServer({ binaryPath, port }) spawn
flow to attach an error listener to the child process, reject the returned
promise with an actionable error when the configured binary cannot be found or
executed, and ensure the error event is handled without terminating the process.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/src/test/timeouts.md`:
- Around line 144-150: Add the missing defineConfig import to both standalone
MobileNextDriver examples, alongside the existing MobileNextDriver import, so
each example compiles independently.

In `@packages/driver-mobilenext/src/driver.ts`:
- Around line 527-535: Move the fleetSessionBySerial.delete(deviceId) call in
release so it executes only after fleetClient.releaseDevice(sessionId, deviceId)
completes successfully. Preserve the early return when no session mapping exists
and leave the release logging flow unchanged.
- Around line 218-221: Validate the configured apiUrl in the driver
initialization before constructing FleetApiClient, rejecting any non-HTTPS URL
when an apiKey is used. Keep test-only transport overrides separate from
credentialed requests, and ensure invalid credentialed URLs cannot reach the
FleetApiClient constructor.

In `@packages/mobilewright/src/config.test.ts`:
- Line 202: Remove the duplicate opts declarations in the affected test block,
retaining a single typed declaration for uploadEntry![1]. Ensure all existing
uses continue referencing that one opts variable.

In `@packages/mobilewright/src/config.ts`:
- Line 149: Update the captureGitInfo construction in the configuration merge to
preserve existing user options while enabling commit capture: spread the current
captureGitInfo values and then set commit to true when extra.captureGitInfo is
enabled. Keep unrelated configuration fields unchanged.

In `@packages/protocol/src/driver.ts`:
- Around line 176-180: Update DevicePool.startAllocationForWaiter and the
driver.allocate contract to enforce allocationTimeoutMs independently of
AbortSignal handling: document and require drivers to honor signal, race
driver.allocate against the pool timeout, and ensure any device returned after
timeout is released instead of published.

---

Outside diff comments:
In `@packages/driver-mobilecli/src/driver.ts`:
- Around line 277-300: Update connect() to preserve this.ownedServerProcess when
ensured.serverProcess is undefined, rather than clearing an existing handle
created by prepare(). Track the server process started by this connect() call
and clean it up if RPC connection, device resolution, or agent setup fails
before this.session is assigned, while retaining the successful connection
behavior.

In `@packages/driver-mobilecli/src/server.ts`:
- Around line 100-106: Update startMobilecliServer and its
startMobilecliServer({ binaryPath, port }) spawn flow to attach an error
listener to the child process, reject the returned promise with an actionable
error when the configured binary cannot be found or executed, and ensure the
error event is handled without terminating the process.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f9d7e4f7-8bb5-476f-9bb0-28031fea2e8d

📥 Commits

Reviewing files that changed from the base of the PR and between 53f18f4 and 52de6b1.

📒 Files selected for processing (34)
  • docs/src/guides/docker.md
  • docs/src/test/configuration.md
  • docs/src/test/timeouts.md
  • e2e/mobilewright.config.ts
  • e2e/package.json
  • e2e/tsconfig.json
  • packages/driver-mobilecli/src/driver.ts
  • packages/driver-mobilecli/src/index.ts
  • packages/driver-mobilecli/src/resolve-binary.ts
  • packages/driver-mobilecli/src/server.ts
  • packages/driver-mobilenext/src/driver.ts
  • packages/mobilewright-core/src/device.test.ts
  • packages/mobilewright-core/src/expect.test.ts
  • packages/mobilewright-core/src/locator.test.ts
  • packages/mobilewright-core/src/screen.test.ts
  • packages/mobilewright/src/cli.ts
  • packages/mobilewright/src/config.test.ts
  • packages/mobilewright/src/config.ts
  • packages/mobilewright/src/device-pool/adapters/http-client.test.ts
  • packages/mobilewright/src/device-pool/adapters/http-server.test.ts
  • packages/mobilewright/src/device-pool/adapters/mobilecli-allocator.test.ts
  • packages/mobilewright/src/device-pool/adapters/mobilecli-allocator.ts
  • packages/mobilewright/src/device-pool/adapters/mobilenext-allocator.test.ts
  • packages/mobilewright/src/device-pool/adapters/mobilenext-allocator.ts
  • packages/mobilewright/src/device-pool/allocator-factory.ts
  • packages/mobilewright/src/device-pool/application/device-pool.test.ts
  • packages/mobilewright/src/device-pool/application/device-pool.ts
  • packages/mobilewright/src/device-pool/application/ports.ts
  • packages/mobilewright/src/device-pool/setup.ts
  • packages/mobilewright/src/index.ts
  • packages/mobilewright/src/launchers.ts
  • packages/protocol/src/driver.ts
  • packages/protocol/src/index.ts
  • packages/test/src/fixtures.ts
💤 Files with no reviewable changes (5)
  • packages/mobilewright/src/device-pool/adapters/mobilecli-allocator.test.ts
  • packages/mobilewright/src/device-pool/adapters/mobilecli-allocator.ts
  • packages/mobilewright/src/device-pool/allocator-factory.ts
  • packages/mobilewright/src/device-pool/adapters/mobilenext-allocator.test.ts
  • packages/mobilewright/src/device-pool/adapters/mobilenext-allocator.ts

Comment thread docs/src/test/timeouts.md
Comment thread packages/driver-mobilenext/src/driver.ts
Comment thread packages/driver-mobilenext/src/driver.ts
expect(driver.testResult?.environment).toBe('staging');
const reporters = config.reporter as Array<[string, unknown]>;
const uploadEntry = reporters.find(([path]) => String(path).includes('reporter'));
const opts = uploadEntry![1] as { testResult: { uploadReport: string; name: string; tags: string[]; environment: string } };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Remove the duplicate opts declarations.

Line 202 declares const opts multiple times in the same block. TypeScript will reject the test file with a block-scoped variable redeclaration error. Keep one declaration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/mobilewright/src/config.test.ts` at line 202, Remove the duplicate
opts declarations in the affected test block, retaining a single typed
declaration for uploadEntry![1]. Ensure all existing uses continue referencing
that one opts variable.

Comment thread packages/mobilewright/src/config.ts Outdated
Comment thread packages/protocol/src/driver.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/mobilewright/src/device-pool/application/device-pool.ts`:
- Around line 159-182: In the allocation error path around the awaited
driver.allocate call, remove the reserved slot by its slot object identity
rather than the stale slotIndex captured before await. Locate the slot created
for this waiter, find its current index after the await, and splice only that
matching slot while preserving the existing waiter cleanup and timeout handling.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8ce9d7b4-99bb-45ff-ad7f-b5a3ecd11b73

📥 Commits

Reviewing files that changed from the base of the PR and between 52de6b1 and 8e2320a.

📒 Files selected for processing (5)
  • docs/src/test/timeouts.md
  • packages/driver-mobilenext/src/driver.ts
  • packages/mobilewright/src/config.ts
  • packages/mobilewright/src/device-pool/application/device-pool.ts
  • packages/protocol/src/driver.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • docs/src/test/timeouts.md
  • packages/protocol/src/driver.ts
  • packages/mobilewright/src/config.ts
  • packages/driver-mobilenext/src/driver.ts

Comment thread packages/mobilewright/src/device-pool/application/device-pool.ts
@gmegidish
gmegidish merged commit cb80150 into main Aug 5, 2026
7 checks passed
@gmegidish
gmegidish deleted the feat/instance-based-driver-config branch August 5, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant