mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-08 20:41:44 +08:00
refactor: IDriver
This commit is contained in:
@@ -40,7 +40,7 @@ func launchAppDriver(pkgName string) (driverExt *uixt.XTDriver, err error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = driver.Homescreen()
|
err = driver.Home()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ func watchVideo(driver *uixt.XTDriver) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// 未找到横屏图标,该页面可能不是横版视频(直播|广告|Feed)
|
// 未找到横屏图标,该页面可能不是横版视频(直播|广告|Feed)
|
||||||
// 退出回到推荐页
|
// 退出回到推荐页
|
||||||
driver.PressBack()
|
driver.Back()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ func watchVideo(driver *uixt.XTDriver) (err error) {
|
|||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
// 返回视频页面
|
// 返回视频页面
|
||||||
err = driver.PressBack()
|
err = driver.Back()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ func watchVideo(driver *uixt.XTDriver) (err error) {
|
|||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
// 返回推荐页
|
// 返回推荐页
|
||||||
err = driver.PressBack()
|
err = driver.Back()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ func watchVideo(driver *uixt.XTDriver) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// 未找到横屏图标,该页面可能不是横版视频(直播|广告|Feed)
|
// 未找到横屏图标,该页面可能不是横版视频(直播|广告|Feed)
|
||||||
// 退出回到推荐页
|
// 退出回到推荐页
|
||||||
driver.PressBack()
|
driver.Back()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ func watchVideo(driver *uixt.XTDriver) (err error) {
|
|||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
// 返回视频页面
|
// 返回视频页面
|
||||||
err = driver.PressBack()
|
err = driver.Back()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ func watchVideo(driver *uixt.XTDriver) (err error) {
|
|||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
// 返回推荐页
|
// 返回推荐页
|
||||||
err = driver.PressBack()
|
err = driver.Back()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v5.0.0+2502111606
|
v5.0.0+2502111708
|
||||||
|
|||||||
@@ -163,12 +163,8 @@ func (ad *ADBDriver) WindowSize() (size types.Size, err error) {
|
|||||||
return size, nil
|
return size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) Scale() (scale float64, err error) {
|
// Back simulates a short press on the BACK button.
|
||||||
return 1, nil
|
func (ad *ADBDriver) Back() (err error) {
|
||||||
}
|
|
||||||
|
|
||||||
// PressBack simulates a short press on the BACK button.
|
|
||||||
func (ad *ADBDriver) PressBack(opts ...option.ActionOption) (err error) {
|
|
||||||
// adb shell input keyevent 4
|
// adb shell input keyevent 4
|
||||||
_, err = ad.runShellCommand("input", "keyevent", fmt.Sprintf("%d", KCBack))
|
_, err = ad.runShellCommand("input", "keyevent", fmt.Sprintf("%d", KCBack))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -195,18 +191,18 @@ func (ad *ADBDriver) Orientation() (orientation types.Orientation, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) Homescreen() (err error) {
|
func (ad *ADBDriver) Home() (err error) {
|
||||||
return ad.PressKeyCodes(KCHome, KMEmpty)
|
return ad.PressKeyCode(KCHome, KMEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) Unlock() (err error) {
|
func (ad *ADBDriver) Unlock() (err error) {
|
||||||
// Notice: brighten should be executed before unlock
|
// Notice: brighten should be executed before unlock
|
||||||
// brighten android device screen
|
// brighten android device screen
|
||||||
if err := ad.PressKeyCodes(KCWakeup, KMEmpty); err != nil {
|
if err := ad.PressKeyCode(KCWakeup, KMEmpty); err != nil {
|
||||||
log.Error().Err(err).Msg("brighten android device screen failed")
|
log.Error().Err(err).Msg("brighten android device screen failed")
|
||||||
}
|
}
|
||||||
// unlock android device screen
|
// unlock android device screen
|
||||||
if err := ad.PressKeyCodes(KCMenu, KMEmpty); err != nil {
|
if err := ad.PressKeyCode(KCMenu, KMEmpty); err != nil {
|
||||||
log.Error().Err(err).Msg("press menu key to unlock screen failed")
|
log.Error().Err(err).Msg("press menu key to unlock screen failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +215,7 @@ func (ad *ADBDriver) Backspace(count int, opts ...option.ActionOption) (err erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if count == 1 {
|
if count == 1 {
|
||||||
return ad.PressKeyCode(KCDel)
|
return ad.PressKeyCode(KCDel, KMEmpty)
|
||||||
}
|
}
|
||||||
keyArray := make([]KeyCode, count)
|
keyArray := make([]KeyCode, count)
|
||||||
|
|
||||||
@@ -231,7 +227,7 @@ func (ad *ADBDriver) Backspace(count int, opts ...option.ActionOption) (err erro
|
|||||||
|
|
||||||
func (ad *ADBDriver) combinationKey(keyCodes []KeyCode) (err error) {
|
func (ad *ADBDriver) combinationKey(keyCodes []KeyCode) (err error) {
|
||||||
if len(keyCodes) == 1 {
|
if len(keyCodes) == 1 {
|
||||||
return ad.PressKeyCode(keyCodes[0])
|
return ad.PressKeyCode(keyCodes[0], KMEmpty)
|
||||||
}
|
}
|
||||||
strKeyCodes := make([]string, len(keyCodes))
|
strKeyCodes := make([]string, len(keyCodes))
|
||||||
for i, keycode := range keyCodes {
|
for i, keycode := range keyCodes {
|
||||||
@@ -242,11 +238,7 @@ func (ad *ADBDriver) combinationKey(keyCodes []KeyCode) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) PressKeyCode(keyCode KeyCode) (err error) {
|
func (ad *ADBDriver) PressKeyCode(keyCode KeyCode, metaState KeyMeta) (err error) {
|
||||||
return ad.PressKeyCodes(keyCode, KMEmpty)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ad *ADBDriver) PressKeyCodes(keyCode KeyCode, metaState KeyMeta) (err error) {
|
|
||||||
// adb shell input keyevent [--longpress] KEYCODE [METASTATE]
|
// adb shell input keyevent [--longpress] KEYCODE [METASTATE]
|
||||||
if metaState != KMEmpty {
|
if metaState != KMEmpty {
|
||||||
// press key with metastate, e.g. KMShiftOn/KMCtrlOn
|
// press key with metastate, e.g. KMShiftOn/KMCtrlOn
|
||||||
@@ -410,18 +402,13 @@ func (ad *ADBDriver) ForceTouchFloat(x, y, pressure float64, second ...float64)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) SendKeys(text string, opts ...option.ActionOption) (err error) {
|
func (ad *ADBDriver) Input(text string, opts ...option.ActionOption) error {
|
||||||
err = ad.SendUnicodeKeys(text, opts...)
|
err := ad.SendUnicodeKeys(text, opts...)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
err = ad.InputText(text, opts...)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ad *ADBDriver) InputText(text string, opts ...option.ActionOption) error {
|
|
||||||
// adb shell input text <text>
|
// adb shell input text <text>
|
||||||
_, err := ad.runShellCommand("input", "text", text)
|
_, err = ad.runShellCommand("input", "text", text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "send keys failed")
|
return errors.Wrap(err, "send keys failed")
|
||||||
}
|
}
|
||||||
@@ -454,7 +441,7 @@ func (ad *ADBDriver) SendUnicodeKeys(text string, opts ...option.ActionOption) (
|
|||||||
log.Warn().Err(err).Msgf("encode text with modified utf7 failed")
|
log.Warn().Err(err).Msgf("encode text with modified utf7 failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = ad.InputText("\""+strings.ReplaceAll(encodedStr, "\"", "\\\"")+"\"", opts...)
|
err = ad.Input("\""+strings.ReplaceAll(encodedStr, "\"", "\\\"")+"\"", opts...)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,10 +502,6 @@ func (ad *ADBDriver) SendKeysByAdbKeyBoard(text string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) Input(text string, opts ...option.ActionOption) (err error) {
|
|
||||||
return ad.SendKeys(text, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ad *ADBDriver) AppClear(packageName string) error {
|
func (ad *ADBDriver) AppClear(packageName string) error {
|
||||||
if _, err := ad.runShellCommand("pm", "clear", packageName); err != nil {
|
if _, err := ad.runShellCommand("pm", "clear", packageName); err != nil {
|
||||||
log.Error().Str("packageName", packageName).Err(err).Msg("failed to clear package cache")
|
log.Error().Str("packageName", packageName).Err(err).Msg("failed to clear package cache")
|
||||||
@@ -528,11 +511,6 @@ func (ad *ADBDriver) AppClear(packageName string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) PressButton(devBtn types.DeviceButton) (err error) {
|
|
||||||
err = types.ErrDriverNotImplemented
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ad *ADBDriver) Rotation() (rotation types.Rotation, err error) {
|
func (ad *ADBDriver) Rotation() (rotation types.Rotation, err error) {
|
||||||
err = types.ErrDriverNotImplemented
|
err = types.ErrDriverNotImplemented
|
||||||
return
|
return
|
||||||
@@ -729,7 +707,7 @@ func (ad *ADBDriver) GetSession() *Session {
|
|||||||
return ad.Session
|
return ad.Session
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) GetForegroundApp() (app types.AppInfo, err error) {
|
func (ad *ADBDriver) ForegroundInfo() (app types.AppInfo, err error) {
|
||||||
packageInfo, err := ad.runShellCommand(
|
packageInfo, err := ad.runShellCommand(
|
||||||
"CLASSPATH=/data/local/tmp/evalite", "app_process", "/",
|
"CLASSPATH=/data/local/tmp/evalite", "app_process", "/",
|
||||||
"com.bytedance.iesqa.eval_process.PackageService", "2>/dev/null")
|
"com.bytedance.iesqa.eval_process.PackageService", "2>/dev/null")
|
||||||
@@ -768,14 +746,14 @@ func (ad *ADBDriver) SetIme(imeRegx string) error {
|
|||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
pid, _ := ad.runShellCommand("pidof", packageName)
|
pid, _ := ad.runShellCommand("pidof", packageName)
|
||||||
if strings.TrimSpace(pid) == "" {
|
if strings.TrimSpace(pid) == "" {
|
||||||
appInfo, err := ad.GetForegroundApp()
|
appInfo, err := ad.ForegroundInfo()
|
||||||
_ = ad.AppLaunch(packageName)
|
_ = ad.AppLaunch(packageName)
|
||||||
if err == nil && packageName != option.UnicodeImePackageName {
|
if err == nil && packageName != option.UnicodeImePackageName {
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
nextAppInfo, err := ad.GetForegroundApp()
|
nextAppInfo, err := ad.ForegroundInfo()
|
||||||
log.Info().Str("beforeFocusedPackage", appInfo.PackageName).Str("afterFocusedPackage", nextAppInfo.PackageName).Msg("")
|
log.Info().Str("beforeFocusedPackage", appInfo.PackageName).Str("afterFocusedPackage", nextAppInfo.PackageName).Msg("")
|
||||||
if err == nil && nextAppInfo.PackageName != appInfo.PackageName {
|
if err == nil && nextAppInfo.PackageName != appInfo.PackageName {
|
||||||
_ = ad.PressKeyCodes(KCBack, KMEmpty)
|
_ = ad.PressKeyCode(KCBack, KMEmpty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -799,102 +777,6 @@ func (ad *ADBDriver) GetIme() (ime string, err error) {
|
|||||||
return currentIme, nil
|
return currentIme, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) AssertForegroundApp(packageName string, activityType ...string) error {
|
|
||||||
log.Debug().Str("package_name", packageName).
|
|
||||||
Strs("activity_type", activityType).
|
|
||||||
Msg("assert android foreground package and activity")
|
|
||||||
|
|
||||||
app, err := ad.GetForegroundApp()
|
|
||||||
if err != nil {
|
|
||||||
log.Warn().Err(err).Msg("get foreground app failed, skip app/activity assertion")
|
|
||||||
return nil // Notice: ignore error when get foreground app failed
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert package
|
|
||||||
if app.PackageName != packageName {
|
|
||||||
log.Error().
|
|
||||||
Interface("foreground_app", app.AppBaseInfo).
|
|
||||||
Str("expected_package", packageName).
|
|
||||||
Msg("assert package failed")
|
|
||||||
return errors.Wrap(code.MobileUIAssertForegroundAppError,
|
|
||||||
"assert foreground package failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(activityType) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert activity
|
|
||||||
expectActivityType := activityType[0]
|
|
||||||
activities, ok := androidActivities[packageName]
|
|
||||||
if !ok {
|
|
||||||
msg := fmt.Sprintf("activities not configured for package %s", packageName)
|
|
||||||
log.Error().Msg(msg)
|
|
||||||
return errors.Wrap(code.MobileUIAssertForegroundActivityError, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
expectActivities, ok := activities[expectActivityType]
|
|
||||||
if !ok {
|
|
||||||
msg := fmt.Sprintf("activity type %s not configured for package %s",
|
|
||||||
expectActivityType, packageName)
|
|
||||||
log.Error().Msg(msg)
|
|
||||||
return errors.Wrap(code.MobileUIAssertForegroundActivityError, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// assertion
|
|
||||||
for _, expectActivity := range expectActivities {
|
|
||||||
if strings.HasSuffix(app.Activity, expectActivity) {
|
|
||||||
// assert activity success
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert activity failed
|
|
||||||
log.Error().
|
|
||||||
Interface("foreground_app", app.AppBaseInfo).
|
|
||||||
Str("expected_activity_type", expectActivityType).
|
|
||||||
Strs("expected_activities", expectActivities).
|
|
||||||
Msg("assert activity failed")
|
|
||||||
return errors.Wrap(code.MobileUIAssertForegroundActivityError,
|
|
||||||
"assert foreground activity failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
var androidActivities = map[string]map[string][]string{
|
|
||||||
// DY
|
|
||||||
"com.ss.android.ugc.aweme": {
|
|
||||||
"feed": []string{".splash.SplashActivity"},
|
|
||||||
"live": []string{".live.LivePlayActivity"},
|
|
||||||
},
|
|
||||||
// DY lite
|
|
||||||
"com.ss.android.ugc.aweme.lite": {
|
|
||||||
"feed": []string{".splash.SplashActivity"},
|
|
||||||
"live": []string{".live.LivePlayActivity"},
|
|
||||||
},
|
|
||||||
// KS
|
|
||||||
"com.smile.gifmaker": {
|
|
||||||
"feed": []string{
|
|
||||||
"com.yxcorp.gifshow.HomeActivity",
|
|
||||||
"com.yxcorp.gifshow.detail.PhotoDetailActivity",
|
|
||||||
},
|
|
||||||
"live": []string{
|
|
||||||
"com.kuaishou.live.core.basic.activity.LiveSlideActivity",
|
|
||||||
"com.yxcorp.gifshow.detail.PhotoDetailActivity",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// KS lite
|
|
||||||
"com.kuaishou.nebula": {
|
|
||||||
"feed": []string{
|
|
||||||
"com.yxcorp.gifshow.HomeActivity",
|
|
||||||
"com.yxcorp.gifshow.detail.PhotoDetailActivity",
|
|
||||||
},
|
|
||||||
"live": []string{
|
|
||||||
"com.kuaishou.live.core.basic.activity.LiveSlideActivity",
|
|
||||||
"com.yxcorp.gifshow.detail.PhotoDetailActivity",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// TODO: SPH, XHS
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ad *ADBDriver) ScreenRecord(duration time.Duration) (videoPath string, err error) {
|
func (ad *ADBDriver) ScreenRecord(duration time.Duration) (videoPath string, err error) {
|
||||||
timestamp := time.Now().Format("20060102_150405") + fmt.Sprintf("_%03d", time.Now().UnixNano()/1e6%1000)
|
timestamp := time.Now().Format("20060102_150405") + fmt.Sprintf("_%03d", time.Now().UnixNano()/1e6%1000)
|
||||||
fileName := filepath.Join(config.ScreenShotsPath, fmt.Sprintf("%s.mp4", timestamp))
|
fileName := filepath.Join(config.ScreenShotsPath, fmt.Sprintf("%s.mp4", timestamp))
|
||||||
|
|||||||
@@ -201,21 +201,13 @@ func (ud *UIA2Driver) WindowSize() (size types.Size, err error) {
|
|||||||
return size, nil
|
return size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PressBack simulates a short press on the BACK button.
|
// Back simulates a short press on the BACK button.
|
||||||
func (ud *UIA2Driver) PressBack(opts ...option.ActionOption) (err error) {
|
func (ud *UIA2Driver) Back() (err error) {
|
||||||
// register(postHandler, new PressBack("/wd/hub/session/:sessionId/back"))
|
// register(postHandler, new PressBack("/wd/hub/session/:sessionId/back"))
|
||||||
_, err = ud.httpPOST(nil, "/session", ud.Session.ID, "back")
|
_, err = ud.httpPOST(nil, "/session", ud.Session.ID, "back")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ud *UIA2Driver) Homescreen() (err error) {
|
|
||||||
return ud.PressKeyCodes(KCHome, KMEmpty)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ud *UIA2Driver) PressKeyCode(keyCode KeyCode) (err error) {
|
|
||||||
return ud.PressKeyCodes(keyCode, KMEmpty)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ud *UIA2Driver) PressKeyCodes(keyCode KeyCode, metaState KeyMeta, flags ...KeyFlag) (err error) {
|
func (ud *UIA2Driver) PressKeyCodes(keyCode KeyCode, metaState KeyMeta, flags ...KeyFlag) (err error) {
|
||||||
// register(postHandler, new PressKeyCodeAsync("/wd/hub/session/:sessionId/appium/device/press_keycode"))
|
// register(postHandler, new PressKeyCodeAsync("/wd/hub/session/:sessionId/appium/device/press_keycode"))
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
@@ -449,7 +441,7 @@ func (ud *UIA2Driver) GetPasteboard(contentType types.PasteboardType) (raw *byte
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendKeys Android input does not support setting frequency.
|
// SendKeys Android input does not support setting frequency.
|
||||||
func (ud *UIA2Driver) SendKeys(text string, opts ...option.ActionOption) (err error) {
|
func (ud *UIA2Driver) Input(text string, opts ...option.ActionOption) (err error) {
|
||||||
// register(postHandler, new SendKeysToElement("/wd/hub/session/:sessionId/keys"))
|
// register(postHandler, new SendKeysToElement("/wd/hub/session/:sessionId/keys"))
|
||||||
// https://github.com/appium/appium-uiautomator2-server/blob/master/app/src/main/java/io/appium/uiautomator2/handler/SendKeysToElement.java#L76-L85
|
// https://github.com/appium/appium-uiautomator2-server/blob/master/app/src/main/java/io/appium/uiautomator2/handler/SendKeysToElement.java#L76-L85
|
||||||
actionOptions := option.NewActionOptions(opts...)
|
actionOptions := option.NewActionOptions(opts...)
|
||||||
@@ -524,10 +516,6 @@ func (ud *UIA2Driver) SendActionKey(text string, opts ...option.ActionOption) (e
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ud *UIA2Driver) Input(text string, opts ...option.ActionOption) (err error) {
|
|
||||||
return ud.SendKeys(text, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ud *UIA2Driver) Rotation() (rotation types.Rotation, err error) {
|
func (ud *UIA2Driver) Rotation() (rotation types.Rotation, err error) {
|
||||||
// register(getHandler, new GetRotation("/wd/hub/session/:sessionId/rotation"))
|
// register(getHandler, new GetRotation("/wd/hub/session/:sessionId/rotation"))
|
||||||
var rawResp DriverRawResponse
|
var rawResp DriverRawResponse
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ func TestDriver_Drag(t *testing.T) {
|
|||||||
func TestDriver_SendKeys(t *testing.T) {
|
func TestDriver_SendKeys(t *testing.T) {
|
||||||
setupAndroidUIA2Driver(t)
|
setupAndroidUIA2Driver(t)
|
||||||
|
|
||||||
err := driverExt.SendKeys("辽宁省沈阳市新民市民族街36-4",
|
err := driverExt.Input("辽宁省沈阳市新民市民族街36-4",
|
||||||
option.WithIdentifier("test"))
|
option.WithIdentifier("test"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -208,7 +208,7 @@ func TestDriver_SendKeys(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDriver_PressBack(t *testing.T) {
|
func TestDriver_PressBack(t *testing.T) {
|
||||||
err := driver.PressBack()
|
err := driver.Back()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ func TestDriver_GetOrientation(t *testing.T) {
|
|||||||
_, _ = driverExt.AppTerminate("com.quark.browser")
|
_, _ = driverExt.AppTerminate("com.quark.browser")
|
||||||
_ = driverExt.AppLaunch("com.quark.browser")
|
_ = driverExt.AppLaunch("com.quark.browser")
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
_ = driverExt.Homescreen()
|
_ = driverExt.Home()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_getFreePort(t *testing.T) {
|
func Test_getFreePort(t *testing.T) {
|
||||||
@@ -265,7 +265,7 @@ func TestDriver_IsAppInForeground(t *testing.T) {
|
|||||||
err := driverExt.AppLaunch("com.android.settings")
|
err := driverExt.AppLaunch("com.android.settings")
|
||||||
checkErr(t, err)
|
checkErr(t, err)
|
||||||
|
|
||||||
app, err := driverExt.GetForegroundApp()
|
app, err := driverExt.ForegroundInfo()
|
||||||
checkErr(t, err)
|
checkErr(t, err)
|
||||||
if app.PackageName != "com.android.settings" {
|
if app.PackageName != "com.android.settings" {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@@ -273,22 +273,6 @@ func TestDriver_IsAppInForeground(t *testing.T) {
|
|||||||
if app.Activity != ".Settings" {
|
if app.Activity != ".Settings" {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = driverExt.AssertForegroundApp("com.android.settings")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
_, err = driverExt.AppTerminate("com.android.settings")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = driverExt.AssertForegroundApp("com.android.settings")
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDriver_KeepAlive(t *testing.T) {
|
func TestDriver_KeepAlive(t *testing.T) {
|
||||||
@@ -345,7 +329,7 @@ func TestDriver_ShellInputUnicode(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = driver.SendKeys("test中文输入&")
|
err = driver.Input("test中文输入&")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,48 +41,42 @@ type IDriver interface {
|
|||||||
Status() (types.DeviceStatus, error)
|
Status() (types.DeviceStatus, error)
|
||||||
DeviceInfo() (types.DeviceInfo, error)
|
DeviceInfo() (types.DeviceInfo, error)
|
||||||
BatteryInfo() (types.BatteryInfo, error)
|
BatteryInfo() (types.BatteryInfo, error)
|
||||||
|
ForegroundInfo() (app types.AppInfo, err error)
|
||||||
WindowSize() (types.Size, error)
|
WindowSize() (types.Size, error)
|
||||||
Scale() (float64, error)
|
|
||||||
ScreenShot() (*bytes.Buffer, error)
|
ScreenShot() (*bytes.Buffer, error)
|
||||||
ScreenRecord(duration time.Duration) (videoPath string, err error)
|
ScreenRecord(duration time.Duration) (videoPath string, err error)
|
||||||
Source(srcOpt ...option.SourceOption) (string, error)
|
Source(srcOpt ...option.SourceOption) (string, error)
|
||||||
|
Orientation() (orientation types.Orientation, err error)
|
||||||
|
Rotation() (rotation types.Rotation, err error)
|
||||||
|
|
||||||
|
// config
|
||||||
|
SetRotation(rotation types.Rotation) error
|
||||||
|
SetIme(ime string) error
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
Homescreen() error
|
Home() error
|
||||||
Unlock() (err error)
|
Unlock() error
|
||||||
|
Back() error
|
||||||
// tap
|
// tap
|
||||||
TapXY(x, y float64, opts ...option.ActionOption) error
|
TapXY(x, y float64, opts ...option.ActionOption) error
|
||||||
DoubleTapXY(x, y float64, opts ...option.ActionOption) error
|
DoubleTapXY(x, y float64, opts ...option.ActionOption) error
|
||||||
|
TouchAndHold(x, y float64, opts ...option.ActionOption) error
|
||||||
TapByText(text string, opts ...option.ActionOption) error // TODO: remove
|
TapByText(text string, opts ...option.ActionOption) error // TODO: remove
|
||||||
TapByTexts(actions ...TapTextAction) error // TODO: remove
|
TapByTexts(actions ...TapTextAction) error // TODO: remove
|
||||||
// swipe
|
// swipe
|
||||||
Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
|
Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
|
||||||
Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
|
Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
|
||||||
TouchAndHold(x, y float64, opts ...option.ActionOption) error
|
|
||||||
// input
|
// input
|
||||||
SendKeys(text string, opts ...option.ActionOption) error
|
|
||||||
Input(text string, opts ...option.ActionOption) error
|
Input(text string, opts ...option.ActionOption) error
|
||||||
// press key
|
Backspace(count int, opts ...option.ActionOption) error
|
||||||
PressButton(devBtn types.DeviceButton) error
|
|
||||||
PressBack(opts ...option.ActionOption) error
|
|
||||||
PressKeyCode(keyCode KeyCode) (err error)
|
|
||||||
Backspace(count int, opts ...option.ActionOption) (err error)
|
|
||||||
|
|
||||||
// app related
|
// app related
|
||||||
AppLaunch(packageName string) error
|
AppLaunch(packageName string) error
|
||||||
AppTerminate(packageName string) (bool, error)
|
AppTerminate(packageName string) (bool, error)
|
||||||
AppClear(packageName string) error
|
AppClear(packageName string) error
|
||||||
GetForegroundApp() (app types.AppInfo, err error)
|
|
||||||
AssertForegroundApp(packageName string, activityType ...string) error // TODO: remove
|
|
||||||
|
|
||||||
Orientation() (orientation types.Orientation, err error)
|
|
||||||
SetRotation(rotation types.Rotation) (err error)
|
|
||||||
Rotation() (rotation types.Rotation, err error)
|
|
||||||
|
|
||||||
SetIme(ime string) error
|
|
||||||
|
|
||||||
// triggers the log capture and returns the log entries
|
// triggers the log capture and returns the log entries
|
||||||
StartCaptureLog(identifier ...string) (err error)
|
StartCaptureLog(identifier ...string) error
|
||||||
StopCaptureLog() (result interface{}, err error)
|
StopCaptureLog() (result interface{}, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +102,7 @@ type IDriverExt interface {
|
|||||||
TapByOCR(ocrText string, opts ...option.ActionOption) error
|
TapByOCR(ocrText string, opts ...option.ActionOption) error
|
||||||
TapXY(x, y float64, opts ...option.ActionOption) error
|
TapXY(x, y float64, opts ...option.ActionOption) error
|
||||||
TapAbsXY(x, y float64, opts ...option.ActionOption) error
|
TapAbsXY(x, y float64, opts ...option.ActionOption) error
|
||||||
TapOffset(param string, xOffset, yOffset float64, opts ...option.ActionOption) (err error)
|
TapOffset(param string, xOffset, yOffset float64, opts ...option.ActionOption) error
|
||||||
TapByUIDetection(opts ...option.ActionOption) error
|
TapByUIDetection(opts ...option.ActionOption) error
|
||||||
|
|
||||||
// swipe
|
// swipe
|
||||||
@@ -123,8 +117,8 @@ type IDriverExt interface {
|
|||||||
CheckPopup() (popup *PopupInfo, err error)
|
CheckPopup() (popup *PopupInfo, err error)
|
||||||
ClosePopupsHandler() error
|
ClosePopupsHandler() error
|
||||||
|
|
||||||
DoAction(action MobileAction) (err error)
|
DoAction(action MobileAction) error
|
||||||
DoValidation(check, assert, expected string, message ...string) (err error)
|
DoValidation(check, assert, expected string, message ...string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type XTDriver struct {
|
type XTDriver struct {
|
||||||
@@ -177,15 +171,20 @@ func (dExt *XTDriver) assertOCR(text, assert string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dExt *XTDriver) assertForegroundApp(appName, assert string) (err error) {
|
func (dExt *XTDriver) assertForegroundApp(appName, assert string) error {
|
||||||
err = dExt.AssertForegroundApp(appName)
|
app, err := dExt.ForegroundInfo()
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Msg("get foreground app failed, skip app assertion")
|
||||||
|
return nil // Notice: ignore error when get foreground app failed
|
||||||
|
}
|
||||||
|
|
||||||
switch assert {
|
switch assert {
|
||||||
case AssertionEqual:
|
case AssertionEqual:
|
||||||
if err != nil {
|
if app.PackageName != appName {
|
||||||
return errors.Wrap(err, "assert foreground app equal failed")
|
return errors.Wrap(err, "assert foreground app equal failed")
|
||||||
}
|
}
|
||||||
case AssertionNotEqual:
|
case AssertionNotEqual:
|
||||||
if err == nil {
|
if app.PackageName == appName {
|
||||||
return errors.New("assert foreground app not equal failed")
|
return errors.New("assert foreground app not equal failed")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ func (dExt *XTDriver) DoAction(action MobileAction) (err error) {
|
|||||||
}
|
}
|
||||||
return fmt.Errorf("app_terminate params should be bundleId(string), got %v", action.Params)
|
return fmt.Errorf("app_terminate params should be bundleId(string), got %v", action.Params)
|
||||||
case ACTION_Home:
|
case ACTION_Home:
|
||||||
return dExt.Homescreen()
|
return dExt.Home()
|
||||||
case ACTION_SetIme:
|
case ACTION_SetIme:
|
||||||
if ime, ok := action.Params.(string); ok {
|
if ime, ok := action.Params.(string); ok {
|
||||||
err = dExt.SetIme(ime)
|
err = dExt.SetIme(ime)
|
||||||
@@ -276,7 +276,7 @@ func (dExt *XTDriver) DoAction(action MobileAction) (err error) {
|
|||||||
param := fmt.Sprintf("%v", action.Params)
|
param := fmt.Sprintf("%v", action.Params)
|
||||||
return dExt.Input(param)
|
return dExt.Input(param)
|
||||||
case ACTION_Back:
|
case ACTION_Back:
|
||||||
return dExt.PressBack()
|
return dExt.Back()
|
||||||
case ACTION_Sleep:
|
case ACTION_Sleep:
|
||||||
if param, ok := action.Params.(json.Number); ok {
|
if param, ok := action.Params.(json.Number); ok {
|
||||||
seconds, _ := param.Float64()
|
seconds, _ := param.Float64()
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ func (sad *ShootsAndroidDriver) close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sad *ShootsAndroidDriver) Status() (types.DeviceStatus, error) {
|
func (sad *ShootsAndroidDriver) Status() (types.DeviceStatus, error) {
|
||||||
app, err := sad.GetForegroundApp()
|
app, err := sad.ForegroundInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.DeviceStatus{}, err
|
return types.DeviceStatus{}, err
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ func (sad *ShootsAndroidDriver) Status() (types.DeviceStatus, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sad *ShootsAndroidDriver) Source(srcOpt ...option.SourceOption) (source string, err error) {
|
func (sad *ShootsAndroidDriver) Source(srcOpt ...option.SourceOption) (source string, err error) {
|
||||||
app, err := sad.GetForegroundApp()
|
app, err := sad.ForegroundInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func TestIOSSource(t *testing.T) {
|
|||||||
|
|
||||||
func TestIOSForeground(t *testing.T) {
|
func TestIOSForeground(t *testing.T) {
|
||||||
setupShootsIOSDriver(t)
|
setupShootsIOSDriver(t)
|
||||||
app, err := shootsIOSDriver.GetForegroundApp()
|
app, err := shootsIOSDriver.ForegroundInfo()
|
||||||
checkErr(t, err)
|
checkErr(t, err)
|
||||||
t.Log(app)
|
t.Log(app)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ func (dExt *XTDriver) swipeToTapTexts(texts []string, opts ...option.ActionOptio
|
|||||||
|
|
||||||
func (dExt *XTDriver) SwipeToTapApp(appName string, opts ...option.ActionOption) error {
|
func (dExt *XTDriver) SwipeToTapApp(appName string, opts ...option.ActionOption) error {
|
||||||
// go to home screen
|
// go to home screen
|
||||||
if err := dExt.Homescreen(); err != nil {
|
if err := dExt.Home(); err != nil {
|
||||||
return errors.Wrap(err, "go to home screen failed")
|
return errors.Wrap(err, "go to home screen failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,11 +80,7 @@ func (hd *HDCDriver) WindowSize() (size types.Size, err error) {
|
|||||||
return size, err
|
return size, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hd *HDCDriver) Scale() (float64, error) {
|
func (hd *HDCDriver) Home() error {
|
||||||
return 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hd *HDCDriver) Homescreen() error {
|
|
||||||
return hd.uiDriver.PressKey(ghdc.KEYCODE_HOME)
|
return hd.uiDriver.PressKey(ghdc.KEYCODE_HOME)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,16 +128,11 @@ func (hd *HDCDriver) AppTerminate(packageName string) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hd *HDCDriver) GetForegroundApp() (app types.AppInfo, err error) {
|
func (hd *HDCDriver) ForegroundInfo() (app types.AppInfo, err error) {
|
||||||
// Todo
|
// Todo
|
||||||
return types.AppInfo{}, types.ErrDriverNotImplemented
|
return types.AppInfo{}, types.ErrDriverNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hd *HDCDriver) AssertForegroundApp(packageName string, activityType ...string) error {
|
|
||||||
// Todo
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hd *HDCDriver) Orientation() (orientation types.Orientation, err error) {
|
func (hd *HDCDriver) Orientation() (orientation types.Orientation, err error) {
|
||||||
return types.OrientationPortrait, nil
|
return types.OrientationPortrait, nil
|
||||||
}
|
}
|
||||||
@@ -204,10 +195,6 @@ func (hd *HDCDriver) SetIme(ime string) error {
|
|||||||
return types.ErrDriverNotImplemented
|
return types.ErrDriverNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hd *HDCDriver) SendKeys(text string, opts ...option.ActionOption) error {
|
|
||||||
return hd.uiDriver.InputText(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hd *HDCDriver) Input(text string, opts ...option.ActionOption) error {
|
func (hd *HDCDriver) Input(text string, opts ...option.ActionOption) error {
|
||||||
return hd.uiDriver.InputText(text)
|
return hd.uiDriver.InputText(text)
|
||||||
}
|
}
|
||||||
@@ -216,11 +203,7 @@ func (hd *HDCDriver) AppClear(packageName string) error {
|
|||||||
return types.ErrDriverNotImplemented
|
return types.ErrDriverNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hd *HDCDriver) PressButton(devBtn types.DeviceButton) error {
|
func (hd *HDCDriver) Back() error {
|
||||||
return types.ErrDriverNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hd *HDCDriver) PressBack(opts ...option.ActionOption) error {
|
|
||||||
return hd.uiDriver.PressBack()
|
return hd.uiDriver.PressBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,10 +211,6 @@ func (hd *HDCDriver) Backspace(count int, opts ...option.ActionOption) (err erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hd *HDCDriver) PressKeyCode(keyCode KeyCode) (err error) {
|
|
||||||
return types.ErrDriverNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hd *HDCDriver) PressHarmonyKeyCode(keyCode ghdc.KeyCode) (err error) {
|
func (hd *HDCDriver) PressHarmonyKeyCode(keyCode ghdc.KeyCode) (err error) {
|
||||||
return hd.uiDriver.PressKey(keyCode)
|
return hd.uiDriver.PressKey(keyCode)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ func TestHarmonyInput(t *testing.T) {
|
|||||||
|
|
||||||
func TestHomeScreen(t *testing.T) {
|
func TestHomeScreen(t *testing.T) {
|
||||||
setupHarmonyDevice(t)
|
setupHarmonyDevice(t)
|
||||||
err := driver.Homescreen()
|
err := driver.Home()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ func TestUnlock(t *testing.T) {
|
|||||||
|
|
||||||
func TestPressBack(t *testing.T) {
|
func TestPressBack(t *testing.T) {
|
||||||
setupHarmonyDevice(t)
|
setupHarmonyDevice(t)
|
||||||
err := driver.PressBack()
|
err := driver.Back()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ func TestLaunch(t *testing.T) {
|
|||||||
|
|
||||||
func TestForegroundApp(t *testing.T) {
|
func TestForegroundApp(t *testing.T) {
|
||||||
setupHarmonyDevice(t)
|
setupHarmonyDevice(t)
|
||||||
appInfo, err := driver.GetForegroundApp()
|
appInfo, err := driver.ForegroundInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ func (dev *IOSDevice) NewDriver() (driver IDriver, err error) {
|
|||||||
|
|
||||||
if dev.Options.ResetHomeOnStartup {
|
if dev.Options.ResetHomeOnStartup {
|
||||||
log.Info().Msg("go back to home screen")
|
log.Info().Msg("go back to home screen")
|
||||||
if err = wdaDriver.Homescreen(); err != nil {
|
if err = wdaDriver.Home(); err != nil {
|
||||||
return nil, errors.Wrap(code.MobileUIDriverError,
|
return nil, errors.Wrap(code.MobileUIDriverError,
|
||||||
fmt.Sprintf("go back to home screen failed: %v", err))
|
fmt.Sprintf("go back to home screen failed: %v", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,6 +254,18 @@ func (wd *WDADriver) WindowSize() (size types.Size, err error) {
|
|||||||
return wd.Session.windowSize, nil
|
return wd.Session.windowSize, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wd *WDADriver) Scale() (float64, error) {
|
||||||
|
if !builtin.IsZeroFloat64(wd.Session.scale) {
|
||||||
|
return wd.Session.scale, nil
|
||||||
|
}
|
||||||
|
screen, err := wd.Screen()
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(code.MobileUIDriverError,
|
||||||
|
fmt.Sprintf("get screen info failed: %v", err))
|
||||||
|
}
|
||||||
|
return screen.Scale, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (wd *WDADriver) Screen() (screen ai.Screen, err error) {
|
func (wd *WDADriver) Screen() (screen ai.Screen, err error) {
|
||||||
// [[FBRoute GET:@"/wda/screen"] respondWithTarget:self action:@selector(handleGetScreen:)]
|
// [[FBRoute GET:@"/wda/screen"] respondWithTarget:self action:@selector(handleGetScreen:)]
|
||||||
var rawResp DriverRawResponse
|
var rawResp DriverRawResponse
|
||||||
@@ -284,18 +296,6 @@ func (wd *WDADriver) ScreenShot() (raw *bytes.Buffer, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *WDADriver) Scale() (float64, error) {
|
|
||||||
if !builtin.IsZeroFloat64(wd.Session.scale) {
|
|
||||||
return wd.Session.scale, nil
|
|
||||||
}
|
|
||||||
screen, err := wd.Screen()
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.Wrap(code.MobileUIDriverError,
|
|
||||||
fmt.Sprintf("get screen info failed: %v", err))
|
|
||||||
}
|
|
||||||
return screen.Scale, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WDADriver) toScale(x float64) float64 {
|
func (wd *WDADriver) toScale(x float64) float64 {
|
||||||
return x / wd.Session.scale
|
return x / wd.Session.scale
|
||||||
}
|
}
|
||||||
@@ -372,7 +372,7 @@ func (wd *WDADriver) Lock() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *WDADriver) Homescreen() (err error) {
|
func (wd *WDADriver) Home() (err error) {
|
||||||
// [[FBRoute POST:@"/wda/homescreen"].withoutSession respondWithTarget:self action:@selector(handleHomescreenCommand:)]
|
// [[FBRoute POST:@"/wda/homescreen"].withoutSession respondWithTarget:self action:@selector(handleHomescreenCommand:)]
|
||||||
_, err = wd.httpPOST(nil, "/wda/homescreen")
|
_, err = wd.httpPOST(nil, "/wda/homescreen")
|
||||||
return
|
return
|
||||||
@@ -490,7 +490,7 @@ func (wd *WDADriver) AppDeactivate(second float64) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *WDADriver) GetForegroundApp() (appInfo types.AppInfo, err error) {
|
func (wd *WDADriver) ForegroundInfo() (appInfo types.AppInfo, err error) {
|
||||||
activeAppInfo, err := wd.ActiveAppInfo()
|
activeAppInfo, err := wd.ActiveAppInfo()
|
||||||
appInfo.BundleId = activeAppInfo.BundleId
|
appInfo.BundleId = activeAppInfo.BundleId
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -514,29 +514,6 @@ func (wd *WDADriver) GetForegroundApp() (appInfo types.AppInfo, err error) {
|
|||||||
return appInfo, err
|
return appInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *WDADriver) AssertForegroundApp(bundleId string, viewControllerType ...string) error {
|
|
||||||
log.Debug().Str("bundleId", bundleId).
|
|
||||||
Strs("viewControllerType", viewControllerType).
|
|
||||||
Msg("assert ios foreground bundleId")
|
|
||||||
|
|
||||||
app, err := wd.GetForegroundApp()
|
|
||||||
if err != nil {
|
|
||||||
log.Warn().Err(err).Msg("get foreground app failed, skip bundleId assertion")
|
|
||||||
return nil // Notice: ignore error when get foreground app failed
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert package
|
|
||||||
if app.BundleId != bundleId {
|
|
||||||
log.Error().
|
|
||||||
Interface("foreground_app", app.AppBaseInfo).
|
|
||||||
Str("expected_package", bundleId).
|
|
||||||
Msg("assert package failed")
|
|
||||||
return errors.Wrap(code.MobileUIAssertForegroundAppError,
|
|
||||||
"assert foreground package failed")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WDADriver) TapXY(x, y float64, opts ...option.ActionOption) (err error) {
|
func (wd *WDADriver) TapXY(x, y float64, opts ...option.ActionOption) (err error) {
|
||||||
// [[FBRoute POST:@"/wda/tap/:uuid"] respondWithTarget:self action:@selector(handleTap:)]
|
// [[FBRoute POST:@"/wda/tap/:uuid"] respondWithTarget:self action:@selector(handleTap:)]
|
||||||
actionOptions := option.NewActionOptions(opts...)
|
actionOptions := option.NewActionOptions(opts...)
|
||||||
@@ -657,11 +634,7 @@ func (wd *WDADriver) SetIme(ime string) error {
|
|||||||
return types.ErrDriverNotImplemented
|
return types.ErrDriverNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *WDADriver) PressKeyCode(keyCode KeyCode) (err error) {
|
func (wd *WDADriver) Input(text string, opts ...option.ActionOption) (err error) {
|
||||||
return types.ErrDriverNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WDADriver) SendKeys(text string, opts ...option.ActionOption) (err error) {
|
|
||||||
// [[FBRoute POST:@"/wda/keys"] respondWithTarget:self action:@selector(handleKeys:)]
|
// [[FBRoute POST:@"/wda/keys"] respondWithTarget:self action:@selector(handleKeys:)]
|
||||||
actionOptions := option.NewActionOptions(opts...)
|
actionOptions := option.NewActionOptions(opts...)
|
||||||
data := map[string]interface{}{"value": strings.Split(text, "")}
|
data := map[string]interface{}{"value": strings.Split(text, "")}
|
||||||
@@ -687,18 +660,12 @@ func (wd *WDADriver) Backspace(count int, opts ...option.ActionOption) (err erro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *WDADriver) Input(text string, opts ...option.ActionOption) (err error) {
|
|
||||||
return wd.SendKeys(text, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WDADriver) AppClear(packageName string) error {
|
func (wd *WDADriver) AppClear(packageName string) error {
|
||||||
return types.ErrDriverNotImplemented
|
return types.ErrDriverNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// PressBack simulates a short press on the BACK button.
|
// Back simulates a short press on the BACK button.
|
||||||
func (wd *WDADriver) PressBack(opts ...option.ActionOption) (err error) {
|
func (wd *WDADriver) Back() (err error) {
|
||||||
actionOptions := option.NewActionOptions(opts...)
|
|
||||||
|
|
||||||
windowSize, err := wd.WindowSize()
|
windowSize, err := wd.WindowSize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -707,16 +674,6 @@ func (wd *WDADriver) PressBack(opts ...option.ActionOption) (err error) {
|
|||||||
fromY := wd.toScale(float64(windowSize.Height) * 0.5)
|
fromY := wd.toScale(float64(windowSize.Height) * 0.5)
|
||||||
toX := wd.toScale(float64(windowSize.Width) * 0.6)
|
toX := wd.toScale(float64(windowSize.Width) * 0.6)
|
||||||
toY := wd.toScale(float64(windowSize.Height) * 0.5)
|
toY := wd.toScale(float64(windowSize.Height) * 0.5)
|
||||||
if len(actionOptions.Offset) == 4 {
|
|
||||||
fromX += float64(actionOptions.Offset[0])
|
|
||||||
fromY += float64(actionOptions.Offset[1])
|
|
||||||
toX += float64(actionOptions.Offset[2])
|
|
||||||
toY += float64(actionOptions.Offset[3])
|
|
||||||
}
|
|
||||||
fromX += actionOptions.GetRandomOffset()
|
|
||||||
fromY += actionOptions.GetRandomOffset()
|
|
||||||
toX += actionOptions.GetRandomOffset()
|
|
||||||
toY += actionOptions.GetRandomOffset()
|
|
||||||
|
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"fromX": fromX,
|
"fromX": fromX,
|
||||||
@@ -725,9 +682,6 @@ func (wd *WDADriver) PressBack(opts ...option.ActionOption) (err error) {
|
|||||||
"toY": toY,
|
"toY": toY,
|
||||||
}
|
}
|
||||||
|
|
||||||
// update data options in post data for extra WDA configurations
|
|
||||||
actionOptions.UpdateData(data)
|
|
||||||
|
|
||||||
_, err = wd.httpPOST(data, "/session", wd.Session.ID, "/wda/dragfromtoforduration")
|
_, err = wd.httpPOST(data, "/session", wd.Session.ID, "/wda/dragfromtoforduration")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func TestNewUSBDriver(t *testing.T) {
|
|||||||
func TestDriver_DeviceScaleRatio(t *testing.T) {
|
func TestDriver_DeviceScaleRatio(t *testing.T) {
|
||||||
setup(t)
|
setup(t)
|
||||||
|
|
||||||
scaleRatio, err := driver.Scale()
|
scaleRatio, err := driver.(*WDADriver).Scale()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ func Test_remoteWD_Screen(t *testing.T) {
|
|||||||
func Test_remoteWD_Homescreen(t *testing.T) {
|
func Test_remoteWD_Homescreen(t *testing.T) {
|
||||||
setup(t)
|
setup(t)
|
||||||
|
|
||||||
err := driver.Homescreen()
|
err := driver.Home()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -317,7 +317,7 @@ func Test_Relative_Drag(t *testing.T) {
|
|||||||
func Test_remoteWD_SendKeys(t *testing.T) {
|
func Test_remoteWD_SendKeys(t *testing.T) {
|
||||||
setup(t)
|
setup(t)
|
||||||
// driver.StartCaptureLog("hrp_wda_log")
|
// driver.StartCaptureLog("hrp_wda_log")
|
||||||
err := driver.SendKeys("test", option.WithIdentifier("test"))
|
err := driver.Input("test", option.WithIdentifier("test"))
|
||||||
// result, _ := driver.StopCaptureLog()
|
// result, _ := driver.StopCaptureLog()
|
||||||
// err := driver.SendKeys("App Store", WithFrequency(3))
|
// err := driver.SendKeys("App Store", WithFrequency(3))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -329,17 +329,17 @@ func Test_remoteWD_SendKeys(t *testing.T) {
|
|||||||
func Test_remoteWD_PressButton(t *testing.T) {
|
func Test_remoteWD_PressButton(t *testing.T) {
|
||||||
setup(t)
|
setup(t)
|
||||||
|
|
||||||
err := driver.PressButton(types.DeviceButtonVolumeUp)
|
err := driver.(*WDADriver).PressButton(types.DeviceButtonVolumeUp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 1)
|
||||||
err = driver.PressButton(types.DeviceButtonVolumeDown)
|
err = driver.(*WDADriver).PressButton(types.DeviceButtonVolumeDown)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 1)
|
||||||
err = driver.PressButton(types.DeviceButtonHome)
|
err = driver.(*WDADriver).PressButton(types.DeviceButtonHome)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -413,7 +413,7 @@ func Test_remoteWD_Source(t *testing.T) {
|
|||||||
|
|
||||||
func TestGetForegroundApp(t *testing.T) {
|
func TestGetForegroundApp(t *testing.T) {
|
||||||
setup(t)
|
setup(t)
|
||||||
app, err := driver.GetForegroundApp()
|
app, err := driver.ForegroundInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ func foregroundAppHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
appInfo, err := dExt.GetForegroundApp()
|
appInfo, err := dExt.ForegroundInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg(fmt.Sprintf("[%s]: failed to unlick screen", c.HandlerName()))
|
log.Err(err).Msg(fmt.Sprintf("[%s]: failed to unlick screen", c.HandlerName()))
|
||||||
c.JSON(http.StatusInternalServerError,
|
c.JSON(http.StatusInternalServerError,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func sourceHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app, err := dExt.GetForegroundApp()
|
app, err := dExt.ForegroundInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg(fmt.Sprintf("[%s]: failed to get foreground app", c.HandlerName()))
|
log.Err(err).Msg(fmt.Sprintf("[%s]: failed to get foreground app", c.HandlerName()))
|
||||||
c.JSON(http.StatusInternalServerError,
|
c.JSON(http.StatusInternalServerError,
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/httprunner/httprunner/v5/code"
|
|
||||||
"github.com/httprunner/httprunner/v5/pkg/uixt"
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
|
"github.com/httprunner/httprunner/v5/code"
|
||||||
)
|
)
|
||||||
|
|
||||||
func unlockHandler(c *gin.Context) {
|
func unlockHandler(c *gin.Context) {
|
||||||
@@ -37,7 +37,7 @@ func homeHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = dExt.Homescreen()
|
err = dExt.Home()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg(fmt.Sprintf("[%s]: failed to enter homescreen", c.HandlerName()))
|
log.Err(err).Msg(fmt.Sprintf("[%s]: failed to enter homescreen", c.HandlerName()))
|
||||||
c.JSON(http.StatusInternalServerError,
|
c.JSON(http.StatusInternalServerError,
|
||||||
@@ -51,30 +51,3 @@ func homeHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, HttpResponse{Code: 0, Message: "success"})
|
c.JSON(http.StatusOK, HttpResponse{Code: 0, Message: "success"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func keycodeHandler(c *gin.Context) {
|
|
||||||
dExt, err := GetContextDriver(c)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var keycodeReq KeycodeRequest
|
|
||||||
if err := c.ShouldBindJSON(&keycodeReq); err != nil {
|
|
||||||
handlerValidateRequestFailedContext(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = dExt.PressKeyCode(uixt.KeyCode(keycodeReq.Keycode))
|
|
||||||
if err != nil {
|
|
||||||
log.Err(err).Msg(fmt.Sprintf("[%s]: failed to input keycode %d", c.HandlerName(), keycodeReq.Keycode))
|
|
||||||
c.JSON(http.StatusInternalServerError,
|
|
||||||
HttpResponse{
|
|
||||||
Code: code.GetErrorCode(err),
|
|
||||||
Message: err.Error(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
c.Abort()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, HttpResponse{Code: 0, Message: "success"})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ func (r *Router) Init() {
|
|||||||
// Key operations
|
// Key operations
|
||||||
apiV1PlatformSerial.POST("/key/unlock", r.HandleDeviceContext(), unlockHandler)
|
apiV1PlatformSerial.POST("/key/unlock", r.HandleDeviceContext(), unlockHandler)
|
||||||
apiV1PlatformSerial.POST("/key/home", r.HandleDeviceContext(), homeHandler)
|
apiV1PlatformSerial.POST("/key/home", r.HandleDeviceContext(), homeHandler)
|
||||||
apiV1PlatformSerial.POST("/key", r.HandleDeviceContext(), keycodeHandler)
|
|
||||||
// App operations
|
// App operations
|
||||||
apiV1PlatformSerial.GET("/app/foreground", r.HandleDeviceContext(), foregroundAppHandler)
|
apiV1PlatformSerial.GET("/app/foreground", r.HandleDeviceContext(), foregroundAppHandler)
|
||||||
apiV1PlatformSerial.POST("/app/clear", r.HandleDeviceContext(), clearAppHandler)
|
apiV1PlatformSerial.POST("/app/clear", r.HandleDeviceContext(), clearAppHandler)
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ func inputHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = dExt.SendKeys(inputReq.Text,
|
err = dExt.Input(inputReq.Text,
|
||||||
option.WithFrequency(inputReq.Frequency))
|
option.WithFrequency(inputReq.Frequency))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg(fmt.Sprintf("[%s]: failed to input text %s", c.HandlerName(), inputReq.Text))
|
log.Err(err).Msg(fmt.Sprintf("[%s]: failed to input text %s", c.HandlerName(), inputReq.Text))
|
||||||
|
|||||||
@@ -195,11 +195,11 @@ func (s *StepMobile) DoubleTap(params string, opts ...option.ActionOption) *Step
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepMobile) Back(opts ...option.ActionOption) *StepMobile {
|
func (s *StepMobile) Back() *StepMobile {
|
||||||
action := uixt.MobileAction{
|
action := uixt.MobileAction{
|
||||||
Method: uixt.ACTION_Back,
|
Method: uixt.ACTION_Back,
|
||||||
Params: nil,
|
Params: nil,
|
||||||
Options: option.NewActionOptions(opts...),
|
Options: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.obj().Actions = append(s.obj().Actions, action)
|
s.obj().Actions = append(s.obj().Actions, action)
|
||||||
@@ -666,7 +666,7 @@ func runStepMobileUI(s *SessionRunner, step IStep) (stepResult *StepResult, err
|
|||||||
},
|
},
|
||||||
StartTime: startTime.Unix(),
|
StartTime: startTime.Unix(),
|
||||||
}
|
}
|
||||||
if app, err1 := uiDriver.GetForegroundApp(); err1 == nil {
|
if app, err1 := uiDriver.ForegroundInfo(); err1 == nil {
|
||||||
attachments["foreground_app"] = app.AppBaseInfo
|
attachments["foreground_app"] = app.AppBaseInfo
|
||||||
} else {
|
} else {
|
||||||
log.Warn().Err(err1).Msg("save foreground app failed, ignore")
|
log.Warn().Err(err1).Msg("save foreground app failed, ignore")
|
||||||
|
|||||||
Reference in New Issue
Block a user