mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-04 20:17:09 +00:00
feat(driver): clear-state via APK reinstall when pm clear is blocked
When an APK path is set, Android clear-state resets the app by uninstalling and reinstalling instead of asking the sidecar to pm clear, which hardened OEM builds (ColorOS) deny even to the adb shell user. Falls back to the sidecar clear path when no APK path is provided.
This commit is contained in:
1 parent
300af1305e
commit
015f619693
2 files changed
+111
-2
No files matched your search
@@ -2,6 +2,7 @@ package sidecar
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -300,6 +301,77 @@ func TestClient_LaunchAndTerminate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_LaunchClearStateReinstallsOnAndroid(t *testing.T) {
|
||||
state := newHarness(t)
|
||||
client, _ := Dial(state.address)
|
||||
defer client.Close()
|
||||
client.SetPlatform("android")
|
||||
client.SetClearStateReinstall("serial123", "/tmp/app.apk", io.Discard)
|
||||
|
||||
var got struct {
|
||||
serial, bundleID, apkPath string
|
||||
}
|
||||
called := 0
|
||||
client.reinstallApp = func(_ context.Context, serial, bundleID, apkPath string, _ io.Writer) error {
|
||||
called++
|
||||
got.serial, got.bundleID, got.apkPath = serial, bundleID, apkPath
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := client.Launch(context.Background(), "app.folio", true, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if called != 1 {
|
||||
t.Fatalf("reinstall called %d times, want 1", called)
|
||||
}
|
||||
if got.serial != "serial123" || got.bundleID != "app.folio" || got.apkPath != "/tmp/app.apk" {
|
||||
t.Errorf("reinstall args wrong: %+v", got)
|
||||
}
|
||||
// The sidecar must not also clear: the host reinstall already reset state.
|
||||
if state.fake.clearState {
|
||||
t.Error("sidecar clearState should be false after host reinstall")
|
||||
}
|
||||
if state.fake.launchedBundleID != "app.folio" {
|
||||
t.Errorf("launched bundle wrong: %q", state.fake.launchedBundleID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_LaunchClearStateReinstallFailureAborts(t *testing.T) {
|
||||
state := newHarness(t)
|
||||
client, _ := Dial(state.address)
|
||||
defer client.Close()
|
||||
client.SetPlatform("android")
|
||||
client.SetClearStateReinstall("", "/tmp/app.apk", io.Discard)
|
||||
client.reinstallApp = func(_ context.Context, _, _, _ string, _ io.Writer) error {
|
||||
return context.DeadlineExceeded
|
||||
}
|
||||
|
||||
if err := client.Launch(context.Background(), "app.folio", true, nil); err == nil {
|
||||
t.Fatal("expected launch to fail when reinstall fails")
|
||||
}
|
||||
if state.fake.launchedBundleID == "app.folio" {
|
||||
t.Error("sidecar launch should not be called after a failed reinstall")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_LaunchClearStateWithoutApkPathUsesSidecarClear(t *testing.T) {
|
||||
state := newHarness(t)
|
||||
client, _ := Dial(state.address)
|
||||
defer client.Close()
|
||||
client.SetPlatform("android")
|
||||
client.reinstallApp = func(_ context.Context, _, _, _ string, _ io.Writer) error {
|
||||
t.Fatal("reinstall should not run without an apk path")
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := client.Launch(context.Background(), "app.folio", true, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !state.fake.clearState {
|
||||
t.Error("without an apk path the sidecar clearState path must remain")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_TapAndTapSelector(t *testing.T) {
|
||||
state := newHarness(t)
|
||||
client, _ := Dial(state.address)
|
||||
|
||||
Reference in new issue
Block a user