Skip to content

Conversation

@gmegidish
Copy link
Member

@gmegidish gmegidish commented Nov 25, 2025

Summary by CodeRabbit

  • New Features

    • Progress callbacks for agent startup and screen capture; progress messages can be streamed alongside capture data.
    • Structured config objects for device operations (agent startup and screen capture) with progress and data callbacks.
  • Improvements

    • Server streaming now embeds progress notifications in multipart responses for better realtime visibility.
    • Screen capture flow supports format/quality/scale via config.
  • Tests

    • Added unit tests for Android display parsing logic.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

Walkthrough

Refactors device APIs to accept configuration structs: StartAgent(StartAgentConfig) and StartScreenCapture(ScreenCaptureConfig). Adds StartAgentConfig and ScreenCaptureConfig with progress/data callbacks. Updates device implementations, CLI call sites, server streaming, and adds Android display parsing tests.

Changes

Cohort / File(s) Summary
Config & Interface
devices/common.go
Added StartAgentConfig and ScreenCaptureConfig types (fields: OnProgress, OnData, Format, Quality, Scale). Updated ControllableDevice interface signatures to StartAgent(config StartAgentConfig) and StartScreenCapture(config ScreenCaptureConfig).
Android implementation & tests
devices/android.go, devices/android_display_test.go
Updated StartAgent and StartScreenCapture to accept config structs, added progress reporting and multi-display capture logic. Added unit tests for display ID parsing (android_display_test.go).
iOS implementation
devices/ios.go
Converted StartAgent and StartScreenCapture to config-based signatures; inserted OnProgress notifications at key steps and switched screen capture to ScreenCaptureConfig usage.
Simulator implementation
devices/simulator.go
Converted InstallWebDriverAgent, StartAgent, and StartScreenCapture to accept progress callbacks/configs; threaded progress reporting through install/start/capture flows and guarded nil callbacks.
CLI callers
cli/device.go, cli/screenshot.go, ... commands/*
commands/dump.go, commands/info.go, commands/input.go, commands/orientation.go, commands/screenshot.go, commands/url.go
Added devices imports where needed and updated all StartAgent() call sites to StartAgent(devices.StartAgentConfig{...}) (often empty) and adapted screen-capture callers to ScreenCaptureConfig with OnProgress/OnData.
Server & streaming
server/server.go
Reworked handleScreenCapture and handleDeviceInfo to start the agent with StartAgentConfig{OnProgress: ...} and begin screen capture with ScreenCaptureConfig wiring OnProgress (JSON-RPC notifications) and OnData to stream MJPEG parts and progress messages in one multipart response.

Sequence Diagram(s)

sequenceDiagram
    participant Client as CLI / Server HTTP
    participant Device as Device (Android/iOS/Simulator)
    participant Agent as WebDriverAgent

    Client->>Device: StartAgent(StartAgentConfig{OnProgress})
    Note right of Device: report progress via OnProgress
    Device->>Device: Install/Launch agent steps
    Device->>Agent: Wait for ready
    Agent-->>Device: Ready
    Device-->>Client: StartAgent returns

    Client->>Device: StartScreenCapture(ScreenCaptureConfig{Format,OnProgress,OnData})
    Note right of Device: OnProgress("Starting video stream")
    Device->>Device: Initialize MJPEG / stream client
    Device-->>Client: Frame bytes via OnData
    Note over Client,Device: Progress messages interleaved via OnProgress
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay extra attention to:
    • devices/simulator.go — threading of progress callbacks through install/start/capture and nil-check coverage.
    • server/server.go — JSON-RPC progress encoding inside multipart MJPEG and correct flushing/escaping.
    • devices/android.go — multi-display logic and new parsing helpers exercised by tests.

Possibly related PRs

Poem

🐰 I hopped through code with careful taps,
Configs in paw and progress maps,
Agents wake with gentle chime,
Frames hop out, one byte at a time,
A rabbit cheers — the stream's sublime! 📸

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'feat: add progress notifications on wda installation' focuses narrowly on WDA installation progress, but the changeset encompasses a much broader refactoring that introduces config-based APIs for StartAgent and StartScreenCapture across all device types, affecting numerous command files and core device implementations. Revise the title to reflect the main change: 'refactor: introduce config-based APIs for agent startup and screen capture' or similar, as this better represents the comprehensive scope of the changes across the codebase.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-add-progress-notifications-on-wda-installation

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (2)
devices/android.go (1)

684-690: Potential nil dereference if config.OnData is nil.

If a caller invokes StartScreenCapture without setting OnData, line 686 will panic. Consider adding a nil check or validating OnData is not nil at the start of the function.

+	if config.OnData == nil {
+		return fmt.Errorf("OnData callback is required")
+	}
+
 	if config.OnProgress != nil {
 		config.OnProgress("Installing DeviceKit")
 	}

Alternatively, add the validation at function entry (around line 639).

devices/simulator.go (1)

651-669: Add nil check for config.OnData before passing to mjpegClient.

The OnData callback is documented without an "optional" designation (unlike OnProgress), but it's passed to mjpegClient.StartScreenCapture without a nil check. At line 39 of devices/wda/mjpeg/screencapture.go, the callback is invoked directly: if !callback(buffer[:n]). In Go, invoking a nil function value causes a panic. If a caller passes nil for OnData, this will crash at runtime.

The same issue exists in devices/ios.go:656 and devices/android.go:686 (which calls config.OnData directly without a guard).

🧹 Nitpick comments (2)
server/server.go (2)

717-720: Consider handling errors in progress callback.

The json.Marshal and Write errors are ignored, while the OnData callback (line 740) properly checks write errors. If progress updates are truly non-critical and best-effort, this is acceptable; otherwise, consider at least logging failures.

Apply this diff if you'd like to add minimal error logging:

 progressCallback := func(message string) {
-	statusJSON, _ := json.Marshal(map[string]string{"message": message})
+	statusJSON, err := json.Marshal(map[string]string{"message": message})
+	if err != nil {
+		log.Printf("Error marshaling progress message: %v", err)
+		return
+	}
 	mimeMessage := fmt.Sprintf("--BoundaryString\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n%s\r\n", len(statusJSON), statusJSON)
-	_, _ = w.Write([]byte(mimeMessage))
+	if _, err := w.Write([]byte(mimeMessage)); err != nil {
+		log.Printf("Error writing progress message: %v", err)
+	}

734-752: Inconsistent error logging on line 742.

The OnData callback uses fmt.Println while the rest of the file consistently uses log.Printf (e.g., line 195). Consider using log.Printf for consistency.

Apply this diff:

 		OnData: func(data []byte) bool {
 			_, writeErr := w.Write(data)
 			if writeErr != nil {
-				fmt.Println("Error writing data:", writeErr)
+				log.Printf("Error writing data: %v", writeErr)
 				return false
 			}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12528fd and abcd114.

📒 Files selected for processing (13)
  • cli/device.go (2 hunks)
  • cli/screenshot.go (1 hunks)
  • commands/dump.go (1 hunks)
  • commands/info.go (1 hunks)
  • commands/input.go (7 hunks)
  • commands/orientation.go (3 hunks)
  • commands/screenshot.go (2 hunks)
  • commands/url.go (2 hunks)
  • devices/android.go (4 hunks)
  • devices/common.go (3 hunks)
  • devices/ios.go (4 hunks)
  • devices/simulator.go (7 hunks)
  • server/server.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (10)
commands/input.go (1)
devices/common.go (1)
  • StartAgentConfig (30-32)
cli/device.go (1)
devices/common.go (1)
  • StartAgentConfig (30-32)
commands/orientation.go (1)
devices/common.go (1)
  • StartAgentConfig (30-32)
commands/screenshot.go (1)
devices/common.go (1)
  • StartAgentConfig (30-32)
commands/url.go (1)
devices/common.go (1)
  • StartAgentConfig (30-32)
devices/android.go (2)
devices/common.go (2)
  • StartAgentConfig (30-32)
  • ScreenCaptureConfig (21-27)
utils/logger.go (1)
  • Verbose (19-23)
commands/dump.go (1)
devices/common.go (1)
  • StartAgentConfig (30-32)
commands/info.go (1)
devices/common.go (1)
  • StartAgentConfig (30-32)
server/server.go (1)
devices/common.go (2)
  • StartAgentConfig (30-32)
  • ScreenCaptureConfig (21-27)
cli/screenshot.go (2)
devices/common.go (4)
  • StartAgentConfig (30-32)
  • ScreenCaptureConfig (21-27)
  • DefaultMJPEGQuality (13-13)
  • DefaultMJPEGScale (15-15)
commands/commands.go (1)
  • NewErrorResponse (26-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build_on_windows
  • GitHub Check: build_on_macos
  • GitHub Check: build_on_linux
🔇 Additional comments (18)
devices/common.go (2)

20-32: Well-designed config structs for extensibility.

The config struct pattern is a good approach for adding optional callbacks and parameters. The inline documentation clearly explains the callback semantics (OnProgress is optional, OnData returns false to stop).


55-65: All implementations of ControllableDevice have been properly updated.

Verified that StartAgent and StartScreenCapture accept the new config structs across all device implementations:

  • StartAgent: SimulatorDevice, IOSDevice, AndroidDevice all accept StartAgentConfig and use config.OnProgress for notifications
  • StartScreenCapture: SimulatorDevice, AndroidDevice, IOSDevice all accept ScreenCaptureConfig and properly extract fields (Format, Quality, Scale, OnProgress, OnData) for their operations

The interface changes are complete and consistent.

devices/simulator.go (2)

304-320: Progress callbacks correctly guarded with nil checks.

The nil checks before invoking onProgress properly handle the case when callers don't provide a progress callback.


458-557: StartAgent implementation looks correct.

Progress notifications are well-placed at key stages: WebDriverAgent installation, launching, and waiting for startup. The config is properly threaded through to InstallWebDriverAgent.

commands/orientation.go (2)

33-36: Correct migration to new StartAgent API.

Using an empty StartAgentConfig{} is appropriate here since CLI commands don't need progress callbacks.


63-66: Consistent usage with OrientationGetCommand.

commands/screenshot.go (1)

57-60: Correct migration to new StartAgent API.

Using an empty StartAgentConfig{} is consistent with the other command implementations.

devices/android.go (2)

387-395: StartAgent correctly accepts config struct.

Even though Android devices don't require an agent for online devices, the method signature correctly matches the interface. The unused parameter is acceptable since the interface requires this signature.


638-645: Good format validation and nil check for OnProgress.

The format validation ensures only "mjpeg" is accepted, providing a clear error message for unsupported formats.

commands/dump.go (1)

27-27: LGTM!

The update to use devices.StartAgentConfig{} correctly adapts to the new configuration-driven API. Passing an empty config is appropriate here since this command doesn't require progress reporting.

commands/url.go (1)

5-6: LGTM!

The import addition and StartAgent call update correctly align with the new configuration-driven API.

Also applies to: 26-26

commands/input.go (1)

7-7: LGTM!

All StartAgent calls are consistently updated to use the new configuration-driven API across all input command handlers.

Also applies to: 63-63, 89-89, 115-115, 141-141, 167-167, 208-208

cli/device.go (1)

7-7: LGTM!

The import and StartAgent call update correctly adapt to the new API. The empty config is appropriate for this info command.

Also applies to: 51-51

commands/info.go (1)

20-20: LGTM!

The StartAgent call correctly uses the new configuration struct.

devices/ios.go (1)

242-244: Good progress notification integration.

The StartAgent method now properly emits progress notifications at key stages (starting tunnel, launching WDA, waiting for agent). The nil checks before invoking OnProgress are correctly implemented.

Also applies to: 286-294, 317-343

cli/screenshot.go (1)

73-100: Well-structured progress and data callbacks.

Good implementation:

  • Progress messages correctly go to stderr, keeping stdout clean for binary data
  • OnData properly returns false on write errors to stop the capture gracefully
  • Error messages in OnData are written to stderr
server/server.go (2)

533-533: LGTM: Config struct migration.

The empty config is appropriate here since device info retrieval doesn't require progress notifications.


726-731: LGTM: Structured config with progress callback.

The agent is correctly started with progress notifications before screen capture begins.

Comment on lines +645 to +656
func (d IOSDevice) StartScreenCapture(config ScreenCaptureConfig) error {
// configure mjpeg framerate
err := d.wdaClient.SetMjpegFramerate(DefaultMJPEGFramerate)
if err != nil {
return err
}

return d.mjpegClient.StartScreenCapture(format, callback)
if config.OnProgress != nil {
config.OnProgress("Starting video stream")
}

return d.mjpegClient.StartScreenCapture(config.Format, config.OnData)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify if Quality and Scale from config should be utilized.

ScreenCaptureConfig includes Quality and Scale fields, but only Format and OnData are passed to mjpegClient.StartScreenCapture. If these fields are intentionally unused for iOS MJPEG capture, consider documenting this. Otherwise, they may need to be applied.


🏁 Script executed:

#!/bin/bash
# Check if mjpegClient.StartScreenCapture or SetMjpegFramerate methods accept quality/scale parameters
ast-grep --pattern $'func ($_, $_) StartScreenCapture($$$) {
  $$$
}'

# Also check the wda client for any quality/scale settings
rg -n "Quality|Scale" --type go -C 3

Length of output: 9091


I need to search for the mjpegClient interface and implementation to determine if quality/scale can be configured for iOS.


🏁 Script executed:

#!/bin/bash
# Find mjpegClient definition and its StartScreenCapture method signature
rg -n "type.*mjpegClient|interface.*mjpegClient" --type go

# Find mjpegClient.StartScreenCapture method definition
ast-grep --pattern 'func ($_, $_) StartScreenCapture($$$) {
  $$$
}'

# Search for mjpegClient initialization to see what type it is
rg -n "mjpegClient.*=" --type go -B 2 -A 2

# Look for quality/scale related methods in wda or mjpeg packages
rg -n "SetQuality|SetScale|Quality|Scale" devices/wda/ --type go

Length of output: 691


🏁 Script executed:

#!/bin/bash
# Alternative: search more broadly for mjpeg-related interfaces
rg -n "StartScreenCapture" --type go -B 3 -A 6

Length of output: 5468


🏁 Script executed:

#!/bin/bash
# Find mjpegClient definition and its type
rg -n "mjpegClient" --type go -B 2 -A 2

# Search for mjpeg client implementations or interfaces
fd -e go | xargs grep -l "mjpeg" | head -20

Length of output: 1178


Let me check if wdaClient has methods to configure quality or scale for the MJPEG stream:


🏁 Script executed:

#!/bin/bash
# Search for wdaClient interface and its available methods
rg -n "type WdaClient|func.*wdaClient" --type go -A 3

# Look for SetMjpeg methods on wdaClient
rg -n "SetMjpeg|SetQuality|SetScale" --type go devices/wda/

# Check WdaClient definition
fd -e go devices/wda/ | head -10

Length of output: 613



🏁 Script executed:

#!/bin/bash
# Find all methods on WdaClient
rg -n "func \(c \*WdaClient\)" --type go

# Also check the appium-settings file for all SetMjpeg methods
cat devices/wda/appium-settings.go

Length of output: 2880


Unused Quality and Scale parameters in iOS StartScreenCapture implementation need resolution.

The iOS (and Simulator) StartScreenCapture method receives Quality and Scale from ScreenCaptureConfig but does not use them. Unlike Android, which passes these parameters to its external MJPEG server (devices/android.go:663), the iOS implementation only passes Format and OnData to mjpegClient.StartScreenCapture (devices/ios.go:656).

The WdaClient interface provides only SetMjpegFramerate for MJPEG configuration; there are no SetMjpegQuality or SetMjpegScale methods. Either:

  • These fields should be removed from the iOS/Simulator code paths, or
  • If WDA supports quality/scale configuration through Appium settings, add corresponding methods to WdaClient and invoke them in StartScreenCapture.
🤖 Prompt for AI Agents
In devices/ios.go around lines 645-656, StartScreenCapture currently sets only
the MJPEG framerate and ignores ScreenCaptureConfig.Quality and .Scale; either
remove those fields for iOS/simulator or (preferred) extend WdaClient with
SetMjpegQuality(int) and SetMjpegScale(float64) (and implement them) and call
them here before starting the mjpeg client, only invoking them when
config.Quality/Scale are non-zero/nonnull; preserve the existing framerate call,
keep the OnProgress message, and then call
mjpegClient.StartScreenCapture(config.Format, config.OnData).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
devices/android.go (1)

746-802: Ensure MJPEG child process is reaped and guard OnData in Android StartScreenCapture

StartScreenCapture does a good job of:

  • Validating config.Format == "mjpeg".
  • Emitting progress messages for installing DeviceKit and starting the MJPEG server.
  • Passing config.Quality and config.Scale down to the Java MjpegServer.
  • Streaming stdout chunks into config.OnData.

Two things are worth tightening up:

  1. Child process reaping
    cmd.Start() is called, but cmd.Wait() is never invoked. Even though you Kill the process at the end, not waiting for it can leave zombies around in a long-lived server. A simple defer after Start fixes this:

    stdout, err := cmd.StdoutPipe()
    if err != nil {
        return fmt.Errorf("failed to create stdout pipe: %v", err)
    }
    
    if err := cmd.Start(); err != nil {
        return fmt.Errorf("failed to start MJPEG server: %v", err)
    }
  • // Ensure the MJPEG process is properly reaped
  • defer func() { _ = cmd.Wait() }()
    @@
  • _ = cmd.Process.Kill()
  • return nil
  • _ = cmd.Process.Kill()
  • return nil
    }

This preserves the existing behavior (including killing the process when the callback asks to stop) while ensuring the OS reclaims the child.

2. **OnData nil-guard**  
The implementation assumes `config.OnData` is non-nil. If a caller ever omits it, this will panic on the first chunk. A small upfront check makes the contract explicit:

```diff
func (d *AndroidDevice) StartScreenCapture(config ScreenCaptureConfig) error {
+      if config.OnData == nil {
+          return fmt.Errorf("StartScreenCapture: OnData callback is required")
+      }
    if config.Format != "mjpeg" {
        return fmt.Errorf("unsupported format: %s, only 'mjpeg' is supported", config.Format)
    }

Together these changes would make the Android MJPEG capture path more robust in long-running and misconfiguration scenarios.

♻️ Duplicate comments (2)
devices/ios.go (1)

638-650: Clarify / honor Quality & Scale and guard against nil OnData in iOS screen capture

StartScreenCapture now uses ScreenCaptureConfig but still only consumes Format and OnData; Quality and Scale remain unused on iOS/simulator, unlike Android where they’re forwarded to the MJPEG server. If WDA truly has no knobs for these, consider either documenting that they’re ignored on iOS/simulator or exposing platform-specific configuration so callers don’t assume they apply uniformly. Also, config.OnData is required for mjpegClient.StartScreenCapture to function; a defensive nil-check with a clear error would make misuse fail early instead of panicking later.

Example tweak:

func (d IOSDevice) StartScreenCapture(config ScreenCaptureConfig) error {
+	if config.OnData == nil {
+		return fmt.Errorf("StartScreenCapture: OnData callback is required")
+	}
 	// configure mjpeg framerate
 	err := d.wdaClient.SetMjpegFramerate(DefaultMJPEGFramerate)
 	if err != nil {
 		return err
 	}
@@
-	return d.mjpegClient.StartScreenCapture(config.Format, config.OnData)
+	return d.mjpegClient.StartScreenCapture(config.Format, config.OnData)
}
devices/simulator.go (1)

654-672: Align simulator screen capture config semantics with iOS and guard OnData

Similar to the iOS implementation, StartScreenCapture for simulators uses config.Format and config.OnData but ignores Quality and Scale. If those fields are intended to be Android-specific, consider documenting that they are no-ops on iOS/simulator; otherwise, you might later want to plumb them through if WDA ever exposes corresponding controls. Also, since config.OnData is required for mjpegClient.StartScreenCapture to do anything useful, a small upfront nil-check (returning a clear error) would prevent accidental panics.

Example:

func (s *SimulatorDevice) StartScreenCapture(config ScreenCaptureConfig) error {
+	if config.OnData == nil {
+		return fmt.Errorf("StartScreenCapture: OnData callback is required")
+	}
 	mjpegPort, err := s.getWdaMjpegPort()
 	if err != nil {
 		return fmt.Errorf("failed to get MJPEG port: %w", err)
 	}
@@
-	mjpegClient := mjpeg.NewWdaMjpegClient(fmt.Sprintf("http://localhost:%d", mjpegPort))
-	return mjpegClient.StartScreenCapture(config.Format, config.OnData)
+	mjpegClient := mjpeg.NewWdaMjpegClient(fmt.Sprintf("http://localhost:%d", mjpegPort))
+	return mjpegClient.StartScreenCapture(config.Format, config.OnData)
}
🧹 Nitpick comments (2)
devices/android_display_test.go (1)

74-110: Consider adding a case where first display is OFF and second is ON

Current Test_parseDisplayIdFromDumpsysState covers “first ON” and invalid input. An extra case where the first display is OFF and a later one is ON would document how parseDisplayIdFromDumpsysState behaves when multiple displays exist and only a later one is active.

server/server.go (1)

681-767: Streaming progress notifications through the MJPEG response is coherent with the new config model

The handleScreenCapture changes cleanly wire:

  • A progressCallback that wraps messages as JSON-RPC notifications and writes them as application/json parts in the same multipart/x-mixed-replace stream.
  • StartAgent(devices.StartAgentConfig{OnProgress: progressCallback}) so WDA/DeviceKit startup progress is surfaced to clients.
  • StartScreenCapture(devices.ScreenCaptureConfig{Format, Quality, Scale, OnProgress: progressCallback, OnData: ...}) so both setup progress and MJPEG bytes flow through one HTTP response.

Headers and flushing behavior look appropriate for long-lived streaming. One minor nit: fmt.Println("Error writing data:", writeErr) writes to stdout; if you care about log routing, consider using the existing logging approach (e.g., log.Printf or utils.Verbose/utils.Info) instead, but this is purely cosmetic.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abcd114 and a39d40d.

📒 Files selected for processing (6)
  • cli/screenshot.go (2 hunks)
  • devices/android.go (6 hunks)
  • devices/android_display_test.go (1 hunks)
  • devices/ios.go (4 hunks)
  • devices/simulator.go (7 hunks)
  • server/server.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
devices/android.go (2)
devices/common.go (2)
  • StartAgentConfig (30-32)
  • ScreenCaptureConfig (21-27)
utils/logger.go (1)
  • Verbose (19-23)
devices/simulator.go (2)
devices/common.go (2)
  • StartAgentConfig (30-32)
  • ScreenCaptureConfig (21-27)
devices/wda/mjpeg/types.go (1)
  • NewWdaMjpegClient (7-11)
devices/ios.go (1)
devices/common.go (3)
  • StartAgentConfig (30-32)
  • ScreenCaptureConfig (21-27)
  • DefaultMJPEGFramerate (17-17)
server/server.go (1)
devices/common.go (2)
  • StartAgentConfig (30-32)
  • ScreenCaptureConfig (21-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint
  • GitHub Check: Analyze (go)
🔇 Additional comments (11)
devices/android_display_test.go (2)

5-38: Display ID parsing tests match implementation behavior

The Test_parseDisplayIdFromCmdDisplay table cases accurately reflect parseDisplayIdFromCmdDisplay’s logic (first ON entry wins; invalid input yields empty string) and will guard regressions on the cmd-display path.


40-72: Viewport-based display parsing tests are well targeted

Test_parseDisplayIdFromDumpsysViewport directly exercises the regex path for isActive=true INTERNAL viewports and the local: prefix stripping, which is exactly what parseDisplayIdFromDumpsysViewport implements.

devices/ios.go (1)

242-359: StartAgent progress callbacks are wired sensibly for iOS real devices

The new StartAgent(config StartAgentConfig) wiring uses OnProgress at the most relevant phases (tunnel start, WDA launch, agent wait) and avoids sending progress in the “WDA not installed” error path, addressing the earlier misleading message concern. Callers that don’t care about progress can still pass a zero-value config without behavior changes.

cli/screenshot.go (1)

73-101: CLI screencapture integration with config-based APIs looks solid

The transition to StartAgent(devices.StartAgentConfig{OnProgress: ...}) and StartScreenCapture(devices.ScreenCaptureConfig{...}) is consistent with the new device interface. Progress is funneled cleanly through utils.Verbose, and the OnData callback correctly stops the stream on stdout write errors. This path should behave like before while adding useful progress output.

devices/android.go (3)

59-97: ANDROID_HOME existence check is a safe improvement

The additional os.Stat check before returning ANDROID_HOME avoids constructing tool paths from a non-existent SDK directory and lets the function fall back to well-known defaults instead. This is a backward-compatible robustness win.


174-287: Multi-display screenshot flow is reasonable with sane fallbacks

The new getDisplayCount, parseDisplayIdFrom*, getFirstDisplayId, and captureScreenshot functions add proper support for multi-display devices:

  • getDisplayCount uses dumpsys SurfaceFlinger --display-id and falls back to assuming a single display on error.
  • getFirstDisplayId sensibly prefers cmd display get-displays, then dumpsys display via viewport and state parsers.
  • TakeScreenshot keeps backward compatibility (single-display/older Android → default screencap) while targeting the first active display when multiple are present.

Combined with the new tests in devices/android_display_test.go, this should make screenshot behavior much less surprising on multi-display setups while remaining safe on older or quirky devices.


495-503: Android StartAgent ignoring progress config is acceptable

Given Android doesn’t require a separate agent process, updating the signature to StartAgent(config StartAgentConfig) while returning early for offline devices and otherwise doing nothing is fine. It keeps the interface consistent across platforms without introducing unnecessary work on Android.

server/server.go (2)

76-91: CORS preflight max-age header is fine

Adding Access-Control-Max-Age: 86400 to the CORS middleware is a straightforward optimization for browsers and doesn’t affect non-CORS clients.


519-545: device_info now uses the config-based StartAgent API consistently

Calling targetDevice.StartAgent(devices.StartAgentConfig{}) keeps the JSON-RPC device_info path in sync with the new device interface without changing existing behavior, since no progress callback is required here.

devices/simulator.go (2)

304-362: Simulator WDA installation progress is integrated cleanly

InstallWebDriverAgent(onProgress) now reports "Downloading WebDriverAgent" when a progress callback is provided, which ties nicely into the broader StartAgent progress story. The rest of the install pipeline is unchanged, so this adds observability without altering behavior.


452-560: Simulator StartAgent progress covers all key phases

StartAgent(config StartAgentConfig) for simulators now:

  • Waits for boot completion with a "Waiting for Simulator to boot" message in the Booting state.
  • Emits "Installing WebDriverAgent on Simulator" and passes config.OnProgress down into InstallWebDriverAgent.
  • Announces "Starting WebDriverAgent" before launch and "Waiting for agent to start" before WaitForAgent.

This gives clients good visibility into what’s happening while remaining backward compatible when OnProgress is nil.

@gmegidish gmegidish merged commit 80ef81c into main Nov 26, 2025
11 checks passed
@gmegidish gmegidish deleted the feat-add-progress-notifications-on-wda-installation branch November 26, 2025 15:06
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.

2 participants