From f158d1e05a2bd2bf8c03e500c7ca6301569d99f2 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 29 Jul 2022 18:09:18 +0800 Subject: [PATCH] feat: app launch and terminate --- hrp/step.go | 30 ++++++++++++--------- hrp/step_android_ui.go | 8 ------ hrp/step_ios_ui.go | 60 ++++++++++++++++++++++++++++++++---------- hrp/step_ui_test.go | 21 +++++++++++++++ 4 files changed, 84 insertions(+), 35 deletions(-) diff --git a/hrp/step.go b/hrp/step.go index 7f63767a..f4794a89 100644 --- a/hrp/step.go +++ b/hrp/step.go @@ -17,19 +17,23 @@ const ( type MobileMethod string const ( - appInstall MobileMethod = "install" - appStart MobileMethod = "app_start" - cameraStart MobileMethod = "camera_start" - cameraStop MobileMethod = "camera_stop" - recordStart MobileMethod = "record_start" - recordStop MobileMethod = "record_stop" - uiHome MobileMethod = "home" - uiClick MobileMethod = "click" - uiDoubleClick MobileMethod = "double_click" - uiLongClick MobileMethod = "long_click" - uiSwipe MobileMethod = "swipe" - uiInput MobileMethod = "input" - appClick MobileMethod = "app_click" + appInstall MobileMethod = "install" + appUninstall MobileMethod = "uninstall" + appStart MobileMethod = "app_start" + appLaunch MobileMethod = "app_launch" // 等待 app 打开并堵塞到 app 首屏加载完成,可以传入 app 的启动参数、环境变量 + appLaunchUnattached MobileMethod = "app_launch_unattached" // 只负责通知打开 app,不堵塞等待,不可传入启动参数 + appTerminate MobileMethod = "app_terminate" + appStop MobileMethod = "app_stop" + cameraStart MobileMethod = "camera_start" + cameraStop MobileMethod = "camera_stop" + recordStart MobileMethod = "record_start" + recordStop MobileMethod = "record_stop" + uiHome MobileMethod = "home" + uiClick MobileMethod = "click" + uiDoubleClick MobileMethod = "double_click" + uiLongClick MobileMethod = "long_click" + uiSwipe MobileMethod = "swipe" + uiInput MobileMethod = "input" ) type MobileAction struct { diff --git a/hrp/step_android_ui.go b/hrp/step_android_ui.go index 106c5a76..8ea3db2c 100644 --- a/hrp/step_android_ui.go +++ b/hrp/step_android_ui.go @@ -136,14 +136,6 @@ func (s *StepAndroid) Input(text string) *StepAndroid { return &StepAndroid{step: s.step} } -func (s *StepAndroid) StartAppByClick(name string) *StepAndroid { - s.step.Android.Actions = append(s.step.Android.Actions, MobileAction{ - Method: appClick, - Params: name, - }) - return &StepAndroid{step: s.step} -} - // Validate switches to step validation. func (s *StepAndroid) Validate() *StepAndroidValidation { return &StepAndroidValidation{ diff --git a/hrp/step_ios_ui.go b/hrp/step_ios_ui.go index 1f0e307d..e3406165 100644 --- a/hrp/step_ios_ui.go +++ b/hrp/step_ios_ui.go @@ -33,6 +33,30 @@ func (s *StepIOS) InstallApp(path string) *StepIOS { return s } +func (s *StepIOS) AppLaunch(bundleId string) *StepIOS { + s.step.IOS.Actions = append(s.step.IOS.Actions, MobileAction{ + Method: appLaunch, + Params: bundleId, + }) + return s +} + +func (s *StepIOS) AppLaunchUnattached(bundleId string) *StepIOS { + s.step.IOS.Actions = append(s.step.IOS.Actions, MobileAction{ + Method: appLaunchUnattached, + Params: bundleId, + }) + return s +} + +func (s *StepIOS) AppTerminate(bundleId string) *StepIOS { + s.step.IOS.Actions = append(s.step.IOS.Actions, MobileAction{ + Method: appTerminate, + Params: bundleId, + }) + return s +} + func (s *StepIOS) Home() *StepIOS { s.step.IOS.Actions = append(s.step.IOS.Actions, MobileAction{ Method: uiHome, @@ -113,14 +137,6 @@ func (s *StepIOS) Input(text string) *StepIOS { return &StepIOS{step: s.step} } -func (s *StepIOS) StartAppByClick(name string) *StepIOS { - s.step.IOS.Actions = append(s.step.IOS.Actions, MobileAction{ - Method: appClick, - Params: name, - }) - return &StepIOS{step: s.step} -} - // run last action with given times func (s *StepIOS) Times(n int) *StepIOS { if n <= 0 { @@ -377,9 +393,28 @@ func (w *wdaClient) doAction(action MobileAction) error { case appInstall: // TODO return errActionNotImplemented - case appStart: - // TODO - return errActionNotImplemented + case appLaunch: + if bundleId, ok := action.Params.(string); ok { + return w.Driver.AppLaunch(bundleId) + } + return fmt.Errorf("app_launch params should be bundleId(string), got %v", action.Params) + case appLaunchUnattached: + if bundleId, ok := action.Params.(string); ok { + return w.Driver.AppLaunchUnattached(bundleId) + } + return fmt.Errorf("app_launch_unattached params should be bundleId(string), got %v", action.Params) + case appTerminate: + if bundleId, ok := action.Params.(string); ok { + success, err := w.Driver.AppTerminate(bundleId) + if err != nil { + return errors.Wrap(err, "failed to terminate app") + } + if !success { + log.Warn().Str("bundleId", bundleId).Msg("app was not running") + } + return nil + } + return fmt.Errorf("app_terminate params should be bundleId(string), got %v", action.Params) case uiHome: return w.Driver.Homescreen() case uiClick: @@ -460,9 +495,6 @@ func (w *wdaClient) doAction(action MobileAction) error { // send \b\b\b to delete 3 chars param := fmt.Sprintf("%v", action.Params) return w.Driver.SendKeys(param) - case appClick: - // TODO - return errActionNotImplemented } return nil } diff --git a/hrp/step_ui_test.go b/hrp/step_ui_test.go index 388128a7..fa3fc767 100644 --- a/hrp/step_ui_test.go +++ b/hrp/step_ui_test.go @@ -66,6 +66,27 @@ func TestIOSSearchApp(t *testing.T) { } } +func TestIOSAppLaunch(t *testing.T) { + testCase := &TestCase{ + Config: NewConfig("启动 & 关闭 App"), + TestSteps: []IStep{ + NewStep("终止今日头条"). + IOS().AppTerminate("com.ss.iphone.article.News"), + NewStep("启动今日头条"). + IOS().AppLaunch("com.ss.iphone.article.News"), + NewStep("终止今日头条"). + IOS().AppTerminate("com.ss.iphone.article.News"), + NewStep("启动今日头条"). + IOS().AppLaunchUnattached("com.ss.iphone.article.News"), + }, + } + + err := NewRunner(t).Run(testCase) + if err != nil { + t.Fatal(err) + } +} + func TestIOSWeixin(t *testing.T) { testCase := &TestCase{ Config: NewConfig("ios ui action on 微信"),