Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions devices/wda_foreground_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ package devices

import (
"fmt"
"strings"

"github.com/mobile-next/mobilecli/devices/devicekit"
)

// springboardBundleID is the home screen. A real device lists it among its
// installed apps as "SpringBoard"; a simulator does not list it, and WDA names
// it with a single space.
const springboardBundleID = "com.apple.springboard"

// wdaForegroundApp asks WDA which app is in the foreground and enriches the
// answer with version details from the device's installed-app list. Shared by
// the physical-device and simulator implementations, which both talk to WDA.
Expand All @@ -22,23 +28,42 @@ func wdaForegroundApp(client *devicekit.DeviceKitClient, listApps func(onlyLaunc
return nil, fmt.Errorf("failed to list apps: %w", err)
}

// find the matching app to get full details
return foregroundAppFromWDA(activeApp, apps), nil
}

// foregroundAppFromWDA describes the app WDA reports in the foreground, using
// the installed-app entry when there is one.
func foregroundAppFromWDA(activeApp *devicekit.ActiveAppInfo, apps []InstalledAppInfo) *ForegroundAppInfo {
for _, app := range apps {
if app.PackageName == activeApp.BundleID {
return &ForegroundAppInfo{
PackageName: app.PackageName,
AppName: app.AppName,
Version: app.Version,
Activity: activeApp.ViewController,
}, nil
}
}
}

// if app not found in list (e.g., system app), return info from WDA only
// not in the list (e.g., a system app): describe it from WDA alone
return &ForegroundAppInfo{
PackageName: activeApp.BundleID,
AppName: activeApp.Name,
AppName: wdaAppName(activeApp),
Version: "",
Activity: activeApp.ViewController,
}, nil
}
}

// wdaAppName is the name WDA reports for an app, or, when that name is blank,
// the name a real device lists for the home screen and the bundle ID for any
// other app, as the Android foreground app does for an app without a label.
func wdaAppName(activeApp *devicekit.ActiveAppInfo) string {
name := strings.TrimSpace(activeApp.Name)
if name != "" {
return name
}
if activeApp.BundleID == springboardBundleID {
return "SpringBoard"
}
return activeApp.BundleID
}
45 changes: 45 additions & 0 deletions devices/wda_foreground_app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package devices

import (
"testing"

"github.com/mobile-next/mobilecli/devices/devicekit"
)

func activeApp(bundleID string, name string) *devicekit.ActiveAppInfo {
return &devicekit.ActiveAppInfo{BundleID: bundleID, Name: name, ViewController: "SomeController"}
}

func TestForegroundAppNamesTheHomeScreenSpringBoardWhenWDAGivesABlankName(t *testing.T) {
app := foregroundAppFromWDA(activeApp("com.apple.springboard", " "), nil)

if app.AppName != "SpringBoard" {
t.Errorf("got app name %q, want %q", app.AppName, "SpringBoard")
}
}

func TestForegroundAppFallsBackToTheBundleIDWhenWDAGivesABlankName(t *testing.T) {
app := foregroundAppFromWDA(activeApp("com.example.system", " "), nil)

if app.AppName != "com.example.system" {
t.Errorf("got app name %q, want the bundle ID", app.AppName)
}
}

func TestForegroundAppKeepsTheNameWDAReports(t *testing.T) {
app := foregroundAppFromWDA(activeApp("com.example.system", "System Thing"), nil)

if app.AppName != "System Thing" {
t.Errorf("got app name %q, want %q", app.AppName, "System Thing")
}
}

func TestForegroundAppPrefersTheInstalledAppEntry(t *testing.T) {
installed := []InstalledAppInfo{{PackageName: "com.example.app", AppName: "Example", Version: "1.2"}}

app := foregroundAppFromWDA(activeApp("com.example.app", " "), installed)

if app.AppName != "Example" || app.Version != "1.2" || app.Activity != "SomeController" {
t.Errorf("got %+v, want the installed app's name and version with WDA's activity", app)
}
}
13 changes: 13 additions & 0 deletions test/simulator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,19 @@ test.describe('iOS Simulator Tests', () => {
verifySpringBoardIsForeground(foregroundAfterHome);
});

test('should name the home screen SpringBoard, as a real device does', async () => {
test.skip(!simulatorId, 'simulator not found');

pressButton(simulatorId, 'HOME');
await eventually(
() => getForegroundApp(simulatorId).data.packageName,
'the home screen never came to the front',
).toBe('com.apple.springboard');

// the agent reports springboard's name as a single space
expect(getForegroundApp(simulatorId).data.appName).toBe('SpringBoard');
});

test('should set and read back clipboard text', async () => {
test.skip(!simulatorId, 'simulator not found');

Expand Down