refactor: move shoots driver to driver_ext

This commit is contained in:
lilong.129
2025-02-10 13:35:22 +08:00
parent 3038fb7430
commit 1ec383180b
19 changed files with 564 additions and 681 deletions
+1 -1
View File
@@ -1 +1 @@
v5.0.0+2502091051 v5.0.0+2502101335
-2
View File
@@ -153,8 +153,6 @@ func (dev *AndroidDevice) NewDriver() (driverExt IDriverExt, err error) {
var driver IDriver var driver IDriver
if dev.UIA2 || dev.LogOn { if dev.UIA2 || dev.LogOn {
driver, err = NewUIA2Driver(dev) driver, err = NewUIA2Driver(dev)
} else if dev.STUB {
driver, err = NewStubAndroidDriver(dev)
} else { } else {
driver, err = NewADBDriver(dev) driver, err = NewADBDriver(dev)
} }
+27 -36
View File
@@ -34,14 +34,13 @@ func NewADBDriver(device *AndroidDevice) (*ADBDriver, error) {
AndroidDevice: device, AndroidDevice: device,
Session: &Session{}, Session: &Session{},
} }
driver.NewSession(nil) driver.InitSession(nil)
return driver, nil return driver, nil
} }
type ADBDriver struct { type ADBDriver struct {
*AndroidDevice *AndroidDevice
*Session Session *Session
// DriverExt
} }
func (ad *ADBDriver) runShellCommand(cmd string, args ...string) (output string, err error) { func (ad *ADBDriver) runShellCommand(cmd string, args ...string) (output string, err error) {
@@ -59,7 +58,7 @@ func (ad *ADBDriver) runShellCommand(cmd string, args ...string) (output string,
} else { } else {
driverResult.Success = true driverResult.Success = true
} }
ad.addRequestResult(driverResult) ad.Session.addRequestResult(driverResult)
}() }()
// adb shell screencap -p // adb shell screencap -p
@@ -77,18 +76,18 @@ func (ad *ADBDriver) runShellCommand(cmd string, args ...string) (output string,
return output, err return output, err
} }
func (ad *ADBDriver) NewSession(capabilities option.Capabilities) (sessionInfo Session, err error) { func (ad *ADBDriver) InitSession(capabilities option.Capabilities) error {
ad.Reset() ad.Session = &Session{}
err = errDriverNotImplemented ad.Session.Reset()
return return nil
} }
func (ad *ADBDriver) DeleteSession() (err error) { func (ad *ADBDriver) DeleteSession() (err error) {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (ad *ADBDriver) Status() (deviceStatus types.DeviceStatus, err error) { func (ad *ADBDriver) Status() (deviceStatus types.DeviceStatus, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
@@ -97,17 +96,17 @@ func (ad *ADBDriver) GetDevice() IDevice {
} }
func (ad *ADBDriver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) { func (ad *ADBDriver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) Location() (location types.Location, err error) { func (ad *ADBDriver) Location() (location types.Location, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) BatteryInfo() (batteryInfo types.BatteryInfo, err error) { func (ad *ADBDriver) BatteryInfo() (batteryInfo types.BatteryInfo, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
@@ -145,9 +144,9 @@ func (ad *ADBDriver) getWindowSize() (size types.Size, err error) {
} }
func (ad *ADBDriver) WindowSize() (size types.Size, err error) { func (ad *ADBDriver) WindowSize() (size types.Size, err error) {
if !ad.windowSize.IsNil() { if !ad.Session.windowSize.IsNil() {
// use cached window size // use cached window size
return ad.windowSize, nil return ad.Session.windowSize, nil
} }
size, err = ad.getWindowSize() size, err = ad.getWindowSize()
@@ -166,12 +165,12 @@ func (ad *ADBDriver) WindowSize() (size types.Size, err error) {
size.Width, size.Height = size.Height, size.Width size.Width, size.Height = size.Height, size.Width
} }
ad.windowSize = size // cache window size ad.Session.windowSize = size // cache window size
return size, nil return size, nil
} }
func (ad *ADBDriver) Screen() (screen ai.Screen, err error) { func (ad *ADBDriver) Screen() (screen ai.Screen, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
@@ -487,17 +486,17 @@ func (ad *ADBDriver) ForceTouch(x, y int, pressure float64, second ...float64) e
} }
func (ad *ADBDriver) ForceTouchFloat(x, y, pressure float64, second ...float64) (err error) { func (ad *ADBDriver) ForceTouchFloat(x, y, pressure float64, second ...float64) (err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) SetPasteboard(contentType types.PasteboardType, content string) (err error) { func (ad *ADBDriver) SetPasteboard(contentType types.PasteboardType, content string) (err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes.Buffer, err error) { func (ad *ADBDriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes.Buffer, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
@@ -620,17 +619,17 @@ func (ad *ADBDriver) Clear(packageName string) error {
} }
func (ad *ADBDriver) PressButton(devBtn types.DeviceButton) (err error) { func (ad *ADBDriver) PressButton(devBtn types.DeviceButton) (err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) Rotation() (rotation types.Rotation, err error) { func (ad *ADBDriver) Rotation() (rotation types.Rotation, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) SetRotation(rotation types.Rotation) (err error) { func (ad *ADBDriver) SetRotation(rotation types.Rotation) (err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
@@ -660,14 +659,6 @@ func (ad *ADBDriver) Source(srcOpt ...option.SourceOption) (source string, err e
return return
} }
func (ad *ADBDriver) LoginNoneUI(packageName, phoneNumber string, captcha, password string) (info AppLoginInfo, err error) {
return info, errDriverNotImplemented
}
func (ad *ADBDriver) LogoutNoneUI(packageName string) error {
return errDriverNotImplemented
}
func (ad *ADBDriver) sourceTree(srcOpt ...option.SourceOption) (sourceTree *Hierarchy, err error) { func (ad *ADBDriver) sourceTree(srcOpt ...option.SourceOption) (sourceTree *Hierarchy, err error) {
source, err := ad.Source() source, err := ad.Source()
if err != nil { if err != nil {
@@ -750,27 +741,27 @@ func (ad *ADBDriver) searchNodes(nodes []Layout, text string, opts ...option.Act
} }
func (ad *ADBDriver) AccessibleSource() (source string, err error) { func (ad *ADBDriver) AccessibleSource() (source string, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) HealthCheck() (err error) { func (ad *ADBDriver) HealthCheck() (err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) GetAppiumSettings() (settings map[string]interface{}, err error) { func (ad *ADBDriver) GetAppiumSettings() (settings map[string]interface{}, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) SetAppiumSettings(settings map[string]interface{}) (ret map[string]interface{}, err error) { func (ad *ADBDriver) SetAppiumSettings(settings map[string]interface{}) (ret map[string]interface{}, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (ad *ADBDriver) IsHealthy() (healthy bool, err error) { func (ad *ADBDriver) IsHealthy() (healthy bool, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
-144
View File
@@ -1,144 +0,0 @@
package uixt
import (
"fmt"
"os"
"testing"
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
)
var androidStubDriver *StubAndroidDriver
func setupStubDriver(t *testing.T) {
device, err := NewAndroidDevice()
checkErr(t, err)
device.STUB = true
androidStubDriver, err = NewStubAndroidDriver(device)
checkErr(t, err)
}
func TestHello(t *testing.T) {
setupStubDriver(t)
status, err := androidStubDriver.Status()
if err != nil {
t.Fatal(err)
}
t.Log(status)
}
func TestSource(t *testing.T) {
setupStubDriver(t)
source, err := androidStubDriver.Source()
if err != nil {
t.Fatal(err)
}
t.Log(source)
}
func TestLogin(t *testing.T) {
setupStubDriver(t)
info, err := androidStubDriver.LoginNoneUI("com.ss.android.ugc.aweme", "12342316231", "8517", "")
if err != nil {
t.Fatal(err)
}
t.Log(info)
}
func TestLogout(t *testing.T) {
setupStubDriver(t)
err := androidStubDriver.LogoutNoneUI("com.ss.android.ugc.aweme")
if err != nil {
t.Fatal(err)
}
}
func TestSwipe(t *testing.T) {
setupStubDriver(t)
err := androidStubDriver.Swipe(878, 2375, 672, 2375)
if err != nil {
t.Fatal(err)
}
}
func TestTap(t *testing.T) {
setupStubDriver(t)
err := androidStubDriver.Tap(900, 400)
if err != nil {
t.Fatal(err)
}
}
func TestDoubleTap(t *testing.T) {
setupStubDriver(t)
err := androidStubDriver.DoubleTap(500, 500)
if err != nil {
t.Fatal(err)
}
}
func TestLongPress(t *testing.T) {
setupStubDriver(t)
err := androidStubDriver.Swipe(1036, 1076, 1036, 1076,
option.WithDuration(3))
if err != nil {
t.Fatal(err)
}
}
func TestInput(t *testing.T) {
setupStubDriver(t)
err := androidStubDriver.Input("\"哈哈\"")
if err != nil {
t.Fatal(err)
}
}
func TestSave(t *testing.T) {
setupStubDriver(t)
raw, err := androidStubDriver.Screenshot()
if err != nil {
t.Fatal(err)
}
source, err := androidStubDriver.Source()
if err != nil {
t.Fatal(err)
}
step := 14
file, err := os.Create(fmt.Sprintf("/Users/bytedance/workcode/wings_algorithm/testcases/data/cases/0/%d.jpg", step))
if err != nil {
t.Fatal(err)
}
file.Write(raw.Bytes())
file, err = os.Create(fmt.Sprintf("/Users/bytedance/workcode/wings_algorithm/testcases/data/cases/0/%d.json", step))
if err != nil {
t.Fatal(err)
}
file.Write([]byte(source))
}
func TestAppLaunch(t *testing.T) {
setupStubDriver(t)
err := androidStubDriver.AppLaunch("com.ss.android.ugc.aweme")
if err != nil {
t.Fatal(err)
}
}
func TestAppTerminal(t *testing.T) {
setupStubDriver(t)
_, err := androidStubDriver.AppTerminate("com.ss.android.ugc.aweme")
if err != nil {
t.Fatal(err)
}
}
func TestAppInfo(t *testing.T) {
setupStubDriver(t)
info, err := androidStubDriver.getLoginAppInfo("com.ss.android.ugc.aweme")
if err != nil {
t.Fatal(err)
}
t.Log(info)
}
+58 -70
View File
@@ -6,7 +6,6 @@ import (
"encoding/json" "encoding/json"
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"net"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@@ -20,10 +19,6 @@ import (
"github.com/httprunner/httprunner/v5/pkg/uixt/types" "github.com/httprunner/httprunner/v5/pkg/uixt/types"
) )
var errDriverNotImplemented = errors.New("driver method not implemented")
const forwardToPrefix = "forward-to-"
func NewUIA2Driver(device *AndroidDevice) (*UIA2Driver, error) { func NewUIA2Driver(device *AndroidDevice) (*UIA2Driver, error) {
log.Info().Interface("device", device).Msg("init android UIA2 driver") log.Info().Interface("device", device).Msg("init android UIA2 driver")
localPort, err := device.Forward(device.UIA2Port) localPort, err := device.Forward(device.UIA2Port)
@@ -32,16 +27,15 @@ func NewUIA2Driver(device *AndroidDevice) (*UIA2Driver, error) {
fmt.Sprintf("forward port %d->%d failed: %v", fmt.Sprintf("forward port %d->%d failed: %v",
localPort, device.UIA2Port, err)) localPort, device.UIA2Port, err))
} }
conn, err := net.Dial("tcp", fmt.Sprintf(":%d", localPort))
if err != nil {
return nil, fmt.Errorf("adb forward: %w", err)
}
driver := new(UIA2Driver) driver := new(UIA2Driver)
driver.client = convertToHTTPClient(conn) err = driver.Session.InitConnection(localPort)
if err != nil {
return nil, err
}
driver.Device = device.Device driver.Device = device.Device
driver.Logcat = device.Logcat driver.Logcat = device.Logcat
_, err = driver.NewSession(nil) err = driver.InitSession(nil)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "create UIA2 session failed") return nil, errors.Wrap(err, "create UIA2 session failed")
} }
@@ -53,81 +47,75 @@ type UIA2Driver struct {
} }
func (ud *UIA2Driver) resetDriver() error { func (ud *UIA2Driver) resetDriver() error {
session, err := ud.NewSession(option.NewCapabilities()) return ud.InitSession(option.NewCapabilities())
if err != nil {
return err
}
ud.sessionID = session.sessionID
return nil
} }
func (ud *UIA2Driver) httpRequest(method string, rawURL string, rawBody []byte) (rawResp rawResponse, err error) { func (ud *UIA2Driver) httpRequest(method string, rawURL string, rawBody []byte) (rawResp DriverRawResponse, err error) {
for retryCount := 1; retryCount <= 5; retryCount++ { for retryCount := 1; retryCount <= 5; retryCount++ {
rawResp, err = ud.Request(method, rawURL, rawBody) rawResp, err = ud.Session.Request(method, rawURL, rawBody)
if err == nil { if err == nil {
return return
} }
// wait for UIA2 server to resume automatically // wait for UIA2 server to resume automatically
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
oldSessionID := ud.sessionID oldSessionID := ud.Session.ID
if err2 := ud.resetDriver(); err2 != nil { if err2 := ud.resetDriver(); err2 != nil {
log.Err(err2).Msgf("failed to reset uia2 driver, retry count: %v", retryCount) log.Err(err2).Msgf("failed to reset uia2 driver, retry count: %v", retryCount)
continue continue
} }
log.Debug().Str("new session", ud.sessionID).Str("old session", oldSessionID).Msgf("successful to reset uia2 driver, retry count: %v", retryCount) log.Debug().Str("new session", ud.Session.ID).Str("old session", oldSessionID).Msgf("successful to reset uia2 driver, retry count: %v", retryCount)
if oldSessionID != "" { if oldSessionID != "" {
rawURL = strings.Replace(rawURL, oldSessionID, ud.sessionID, 1) rawURL = strings.Replace(rawURL, oldSessionID, ud.Session.ID, 1)
} }
} }
return return
} }
func (ud *UIA2Driver) httpGET(pathElem ...string) (rawResp rawResponse, err error) { func (ud *UIA2Driver) httpGET(pathElem ...string) (rawResp DriverRawResponse, err error) {
return ud.httpRequest(http.MethodGet, ud.concatURL(nil, pathElem...), nil) return ud.httpRequest(http.MethodGet, ud.Session.concatURL(nil, pathElem...), nil)
} }
func (ud *UIA2Driver) httpPOST(data interface{}, pathElem ...string) (rawResp rawResponse, err error) { func (ud *UIA2Driver) httpPOST(data interface{}, pathElem ...string) (rawResp DriverRawResponse, err error) {
var bsJSON []byte = nil var bsJSON []byte = nil
if data != nil { if data != nil {
if bsJSON, err = json.Marshal(data); err != nil { if bsJSON, err = json.Marshal(data); err != nil {
return nil, err return nil, err
} }
} }
return ud.httpRequest(http.MethodPost, ud.concatURL(nil, pathElem...), bsJSON) return ud.httpRequest(http.MethodPost, ud.Session.concatURL(nil, pathElem...), bsJSON)
} }
func (ud *UIA2Driver) httpDELETE(pathElem ...string) (rawResp rawResponse, err error) { func (ud *UIA2Driver) httpDELETE(pathElem ...string) (rawResp DriverRawResponse, err error) {
return ud.httpRequest(http.MethodDelete, ud.concatURL(nil, pathElem...), nil) return ud.httpRequest(http.MethodDelete, ud.Session.concatURL(nil, pathElem...), nil)
} }
func (ud *UIA2Driver) NewSession(capabilities option.Capabilities) (sessionInfo Session, err error) { func (ud *UIA2Driver) InitSession(capabilities option.Capabilities) (err error) {
// register(postHandler, new NewSession("/wd/hub/session")) // register(postHandler, new InitSession("/wd/hub/session"))
var rawResp rawResponse var rawResp DriverRawResponse
data := make(map[string]interface{}) data := make(map[string]interface{})
if len(capabilities) == 0 { if len(capabilities) == 0 {
data["capabilities"] = make(map[string]interface{}) data["capabilities"] = make(map[string]interface{})
} else { } else {
data["capabilities"] = map[string]interface{}{"alwaysMatch": capabilities} data["capabilities"] = map[string]interface{}{"alwaysMatch": capabilities}
} }
if rawResp, err = ud.POST(data, "/session"); err != nil { if rawResp, err = ud.Session.POST(data, "/session"); err != nil {
return Session{sessionID: ""}, err return err
} }
reply := new(struct{ Value struct{ SessionId string } }) reply := new(struct{ Value struct{ SessionId string } })
if err = json.Unmarshal(rawResp, reply); err != nil { if err = json.Unmarshal(rawResp, reply); err != nil {
return Session{sessionID: ""}, err return err
} }
sessionID := reply.Value.SessionId ud.Session = &Session{ID: reply.Value.SessionId}
ud.Reset() ud.Session.Reset()
ud.sessionID = sessionID return nil
return Session{sessionID: sessionID}, nil
} }
func (ud *UIA2Driver) DeleteSession() (err error) { func (ud *UIA2Driver) DeleteSession() (err error) {
if ud.sessionID == "" { if ud.Session.ID == "" {
return nil return nil
} }
if _, err = ud.httpDELETE("/session", ud.sessionID); err == nil { if _, err = ud.httpDELETE("/session", ud.Session.ID); err == nil {
ud.sessionID = "" ud.Session.ID = ""
} }
return err return err
@@ -135,9 +123,9 @@ func (ud *UIA2Driver) DeleteSession() (err error) {
func (ud *UIA2Driver) Status() (deviceStatus types.DeviceStatus, err error) { func (ud *UIA2Driver) Status() (deviceStatus types.DeviceStatus, err error) {
// register(getHandler, new Status("/wd/hub/status")) // register(getHandler, new Status("/wd/hub/status"))
var rawResp rawResponse var rawResp DriverRawResponse
// Notice: use Driver.GET instead of httpGET to avoid loop calling // Notice: use Driver.GET instead of httpGET to avoid loop calling
if rawResp, err = ud.GET("/status"); err != nil { if rawResp, err = ud.Session.GET("/status"); err != nil {
return types.DeviceStatus{Ready: false}, err return types.DeviceStatus{Ready: false}, err
} }
reply := new(struct { reply := new(struct {
@@ -154,8 +142,8 @@ func (ud *UIA2Driver) Status() (deviceStatus types.DeviceStatus, err error) {
func (ud *UIA2Driver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) { func (ud *UIA2Driver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) {
// register(getHandler, new GetDeviceInfo("/wd/hub/session/:sessionId/appium/device/info")) // register(getHandler, new GetDeviceInfo("/wd/hub/session/:sessionId/appium/device/info"))
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = ud.httpGET("/session", ud.sessionID, "appium/device/info"); err != nil { if rawResp, err = ud.httpGET("/session", ud.Session.ID, "appium/device/info"); err != nil {
return types.DeviceInfo{}, err return types.DeviceInfo{}, err
} }
reply := new(struct{ Value struct{ types.DeviceInfo } }) reply := new(struct{ Value struct{ types.DeviceInfo } })
@@ -168,8 +156,8 @@ func (ud *UIA2Driver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) {
func (ud *UIA2Driver) BatteryInfo() (batteryInfo types.BatteryInfo, err error) { func (ud *UIA2Driver) BatteryInfo() (batteryInfo types.BatteryInfo, err error) {
// register(getHandler, new GetBatteryInfo("/wd/hub/session/:sessionId/appium/device/battery_info")) // register(getHandler, new GetBatteryInfo("/wd/hub/session/:sessionId/appium/device/battery_info"))
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = ud.httpGET("/session", ud.sessionID, "appium/device/battery_info"); err != nil { if rawResp, err = ud.httpGET("/session", ud.Session.ID, "appium/device/battery_info"); err != nil {
return types.BatteryInfo{}, err return types.BatteryInfo{}, err
} }
reply := new(struct{ Value struct{ types.BatteryInfo } }) reply := new(struct{ Value struct{ types.BatteryInfo } })
@@ -185,13 +173,13 @@ func (ud *UIA2Driver) BatteryInfo() (batteryInfo types.BatteryInfo, err error) {
func (ud *UIA2Driver) WindowSize() (size types.Size, err error) { func (ud *UIA2Driver) WindowSize() (size types.Size, err error) {
// register(getHandler, new GetDeviceSize("/wd/hub/session/:sessionId/window/:windowHandle/size")) // register(getHandler, new GetDeviceSize("/wd/hub/session/:sessionId/window/:windowHandle/size"))
if !ud.windowSize.IsNil() { if !ud.Session.windowSize.IsNil() {
// use cached window size // use cached window size
return ud.windowSize, nil return ud.Session.windowSize, nil
} }
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = ud.httpGET("/session", ud.sessionID, "window/:windowHandle/size"); err != nil { if rawResp, err = ud.httpGET("/session", ud.Session.ID, "window/:windowHandle/size"); err != nil {
return types.Size{}, errors.Wrap(err, "get window size failed by UIA2 request") return types.Size{}, errors.Wrap(err, "get window size failed by UIA2 request")
} }
reply := new(struct{ Value struct{ types.Size } }) reply := new(struct{ Value struct{ types.Size } })
@@ -210,14 +198,14 @@ func (ud *UIA2Driver) WindowSize() (size types.Size, err error) {
size.Width, size.Height = size.Height, size.Width size.Width, size.Height = size.Height, size.Width
} }
ud.windowSize = size // cache window size ud.Session.windowSize = size // cache window size
return size, nil return size, nil
} }
// PressBack simulates a short press on the BACK button. // PressBack simulates a short press on the BACK button.
func (ud *UIA2Driver) PressBack(opts ...option.ActionOption) (err error) { func (ud *UIA2Driver) PressBack(opts ...option.ActionOption) (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.sessionID, "back") _, err = ud.httpPOST(nil, "/session", ud.Session.ID, "back")
return return
} }
@@ -240,14 +228,14 @@ func (ud *UIA2Driver) PressKeyCodes(keyCode KeyCode, metaState KeyMeta, flags ..
if len(flags) != 0 { if len(flags) != 0 {
data["flags"] = flags[0] data["flags"] = flags[0]
} }
_, err = ud.httpPOST(data, "/session", ud.sessionID, "appium/device/press_keycode") _, err = ud.httpPOST(data, "/session", ud.Session.ID, "appium/device/press_keycode")
return return
} }
func (ud *UIA2Driver) Orientation() (orientation types.Orientation, err error) { func (ud *UIA2Driver) Orientation() (orientation types.Orientation, err error) {
// [[FBRoute GET:@"/orientation"] respondWithTarget:self action:@selector(handleGetOrientation:)] // [[FBRoute GET:@"/orientation"] respondWithTarget:self action:@selector(handleGetOrientation:)]
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = ud.httpGET("/session", ud.sessionID, "/orientation"); err != nil { if rawResp, err = ud.httpGET("/session", ud.Session.ID, "/orientation"); err != nil {
return "", err return "", err
} }
reply := new(struct{ Value types.Orientation }) reply := new(struct{ Value types.Orientation })
@@ -280,7 +268,7 @@ func (ud *UIA2Driver) DoubleFloatTap(x, y float64) error {
}, },
} }
_, err := ud.httpPOST(data, "/session", ud.sessionID, "actions/tap") _, err := ud.httpPOST(data, "/session", ud.Session.ID, "actions/tap")
return err return err
} }
@@ -318,7 +306,7 @@ func (ud *UIA2Driver) Tap(x, y float64, opts ...option.ActionOption) (err error)
// update data options in post data for extra uiautomator configurations // update data options in post data for extra uiautomator configurations
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
_, err = ud.httpPOST(data, "/session", ud.sessionID, "actions/tap") _, err = ud.httpPOST(data, "/session", ud.Session.ID, "actions/tap")
return err return err
} }
@@ -336,7 +324,7 @@ func (ud *UIA2Driver) TouchAndHold(x, y float64, opts ...option.ActionOption) (e
"duration": int(duration * 1000), "duration": int(duration * 1000),
}, },
} }
_, err = ud.httpPOST(data, "/session", ud.sessionID, "touch/longclick") _, err = ud.httpPOST(data, "/session", ud.Session.ID, "touch/longclick")
return return
} }
@@ -368,7 +356,7 @@ func (ud *UIA2Driver) Drag(fromX, fromY, toX, toY float64, opts ...option.Action
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
// register(postHandler, new Drag("/wd/hub/session/:sessionId/touch/drag")) // register(postHandler, new Drag("/wd/hub/session/:sessionId/touch/drag"))
_, err = ud.httpPOST(data, "/session", ud.sessionID, "touch/drag") _, err = ud.httpPOST(data, "/session", ud.Session.ID, "touch/drag")
return return
} }
@@ -414,7 +402,7 @@ func (ud *UIA2Driver) Swipe(fromX, fromY, toX, toY float64, opts ...option.Actio
// update data options in post data for extra uiautomator configurations // update data options in post data for extra uiautomator configurations
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
_, err := ud.httpPOST(data, "/session", ud.sessionID, "actions/swipe") _, err := ud.httpPOST(data, "/session", ud.Session.ID, "actions/swipe")
return err return err
} }
@@ -432,7 +420,7 @@ func (ud *UIA2Driver) SetPasteboard(contentType types.PasteboardType, content st
"content": base64.StdEncoding.EncodeToString([]byte(content)), "content": base64.StdEncoding.EncodeToString([]byte(content)),
} }
// register(postHandler, new SetClipboard("/wd/hub/session/:sessionId/appium/device/set_clipboard")) // register(postHandler, new SetClipboard("/wd/hub/session/:sessionId/appium/device/set_clipboard"))
_, err = ud.httpPOST(data, "/session", ud.sessionID, "appium/device/set_clipboard") _, err = ud.httpPOST(data, "/session", ud.Session.ID, "appium/device/set_clipboard")
return return
} }
@@ -444,8 +432,8 @@ func (ud *UIA2Driver) GetPasteboard(contentType types.PasteboardType) (raw *byte
data := map[string]interface{}{ data := map[string]interface{}{
"contentType": contentType[0], "contentType": contentType[0],
} }
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = ud.httpPOST(data, "/session", ud.sessionID, "appium/device/get_clipboard"); err != nil { if rawResp, err = ud.httpPOST(data, "/session", ud.Session.ID, "appium/device/get_clipboard"); err != nil {
return return
} }
reply := new(struct{ Value string }) reply := new(struct{ Value string })
@@ -475,7 +463,7 @@ func (ud *UIA2Driver) SendKeys(text string, opts ...option.ActionOption) (err er
// new data options in post data for extra uiautomator configurations // new data options in post data for extra uiautomator configurations
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
_, err = ud.httpPOST(data, "/session", ud.sessionID, "/keys") _, err = ud.httpPOST(data, "/session", ud.Session.ID, "/keys")
} }
return return
} }
@@ -533,7 +521,7 @@ func (ud *UIA2Driver) SendActionKey(text string, opts ...option.ActionOption) (e
// new data options in post data for extra uiautomator configurations // new data options in post data for extra uiautomator configurations
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
_, err = ud.httpPOST(data, "/session", ud.sessionID, "/actions/keys") _, err = ud.httpPOST(data, "/session", ud.Session.ID, "/actions/keys")
return return
} }
@@ -543,8 +531,8 @@ func (ud *UIA2Driver) Input(text string, opts ...option.ActionOption) (err error
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 rawResponse var rawResp DriverRawResponse
if rawResp, err = ud.httpGET("/session", ud.sessionID, "rotation"); err != nil { if rawResp, err = ud.httpGET("/session", ud.Session.ID, "rotation"); err != nil {
return types.Rotation{}, err return types.Rotation{}, err
} }
reply := new(struct{ Value types.Rotation }) reply := new(struct{ Value types.Rotation })
@@ -564,8 +552,8 @@ func (ud *UIA2Driver) Screenshot() (raw *bytes.Buffer, err error) {
func (ud *UIA2Driver) Source(srcOpt ...option.SourceOption) (source string, err error) { func (ud *UIA2Driver) Source(srcOpt ...option.SourceOption) (source string, err error) {
// register(getHandler, new Source("/wd/hub/session/:sessionId/source")) // register(getHandler, new Source("/wd/hub/session/:sessionId/source"))
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = ud.httpGET("/session", ud.sessionID, "source"); err != nil { if rawResp, err = ud.httpGET("/session", ud.Session.ID, "source"); err != nil {
return "", err return "", err
} }
reply := new(struct{ Value string }) reply := new(struct{ Value string })
+11 -14
View File
@@ -30,8 +30,8 @@ var (
// current implemeted driver: ADBDriver, UIA2Driver, WDADriver, HDCDriver // current implemeted driver: ADBDriver, UIA2Driver, WDADriver, HDCDriver
type IDriver interface { type IDriver interface {
// NewSession starts a new session and returns the DriverSession. // InitSession starts a new session
NewSession(capabilities option.Capabilities) (Session, error) InitSession(capabilities option.Capabilities) error
// DeleteSession Kills application associated with that session and removes session // DeleteSession Kills application associated with that session and removes session
// 1) alertsMonitor disable // 1) alertsMonitor disable
@@ -143,9 +143,6 @@ type IDriver interface {
// Source Return application elements tree // Source Return application elements tree
Source(srcOpt ...option.SourceOption) (string, error) Source(srcOpt ...option.SourceOption) (string, error)
LoginNoneUI(packageName, phoneNumber string, captcha, password string) (info AppLoginInfo, err error)
LogoutNoneUI(packageName string) error
TapByText(text string, opts ...option.ActionOption) error TapByText(text string, opts ...option.ActionOption) error
TapByTexts(actions ...TapTextAction) error TapByTexts(actions ...TapTextAction) error
@@ -312,9 +309,9 @@ func (dExt *DriverExt) DoValidation(check, assert, expected string, message ...s
return nil return nil
} }
type rawResponse []byte type DriverRawResponse []byte
func (r rawResponse) checkErr() (err error) { func (r DriverRawResponse) CheckErr() (err error) {
reply := new(struct { reply := new(struct {
Value struct { Value struct {
Err string `json:"error"` Err string `json:"error"`
@@ -338,7 +335,7 @@ func (r rawResponse) checkErr() (err error) {
return return
} }
func (r rawResponse) valueConvertToString() (s string, err error) { func (r DriverRawResponse) ValueConvertToString() (s string, err error) {
reply := new(struct{ Value string }) reply := new(struct{ Value string })
if err = json.Unmarshal(r, reply); err != nil { if err = json.Unmarshal(r, reply); err != nil {
return "", errors.Wrapf(err, "json.Unmarshal failed, rawResponse: %s", string(r)) return "", errors.Wrapf(err, "json.Unmarshal failed, rawResponse: %s", string(r))
@@ -347,7 +344,7 @@ func (r rawResponse) valueConvertToString() (s string, err error) {
return return
} }
func (r rawResponse) valueConvertToBool() (b bool, err error) { func (r DriverRawResponse) ValueConvertToBool() (b bool, err error) {
reply := new(struct{ Value bool }) reply := new(struct{ Value bool })
if err = json.Unmarshal(r, reply); err != nil { if err = json.Unmarshal(r, reply); err != nil {
return false, err return false, err
@@ -356,7 +353,7 @@ func (r rawResponse) valueConvertToBool() (b bool, err error) {
return return
} }
func (r rawResponse) valueConvertToSessionInfo() (sessionInfo Session, err error) { func (r DriverRawResponse) ValueConvertToSessionInfo() (sessionInfo Session, err error) {
reply := new(struct{ Value struct{ Session } }) reply := new(struct{ Value struct{ Session } })
if err = json.Unmarshal(r, reply); err != nil { if err = json.Unmarshal(r, reply); err != nil {
return Session{}, err return Session{}, err
@@ -365,7 +362,7 @@ func (r rawResponse) valueConvertToSessionInfo() (sessionInfo Session, err error
return return
} }
func (r rawResponse) valueConvertToJsonRawMessage() (raw builtinJSON.RawMessage, err error) { func (r DriverRawResponse) ValueConvertToJsonRawMessage() (raw builtinJSON.RawMessage, err error) {
reply := new(struct{ Value builtinJSON.RawMessage }) reply := new(struct{ Value builtinJSON.RawMessage })
if err = json.Unmarshal(r, reply); err != nil { if err = json.Unmarshal(r, reply); err != nil {
return nil, err return nil, err
@@ -374,15 +371,15 @@ func (r rawResponse) valueConvertToJsonRawMessage() (raw builtinJSON.RawMessage,
return return
} }
func (r rawResponse) valueConvertToJsonObject() (obj map[string]interface{}, err error) { func (r DriverRawResponse) ValueConvertToJsonObject() (obj map[string]interface{}, err error) {
if err = json.Unmarshal(r, &obj); err != nil { if err = json.Unmarshal(r, &obj); err != nil {
return nil, err return nil, err
} }
return return
} }
func (r rawResponse) valueDecodeAsBase64() (raw *bytes.Buffer, err error) { func (r DriverRawResponse) ValueDecodeAsBase64() (raw *bytes.Buffer, err error) {
str, err := r.valueConvertToString() str, err := r.ValueConvertToString()
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to convert value to string") return nil, errors.Wrap(err, "failed to convert value to string")
} }
@@ -1,12 +1,8 @@
package uixt package driver_ext
import ( import (
"fmt" "fmt"
"net" "net"
"net/http"
"net/url"
"strconv"
"strings"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -14,116 +10,59 @@ import (
"github.com/httprunner/httprunner/v5/code" "github.com/httprunner/httprunner/v5/code"
"github.com/httprunner/httprunner/v5/internal/json" "github.com/httprunner/httprunner/v5/internal/json"
"github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/option" "github.com/httprunner/httprunner/v5/pkg/uixt/option"
"github.com/httprunner/httprunner/v5/pkg/uixt/types" "github.com/httprunner/httprunner/v5/pkg/uixt/types"
) )
const ( const (
StubSocketName = "com.bytest.device" shootsSocketName = "com.bytest.device"
DouyinServerPort = 32316 douyinServerPort = 32316
forwardToPrefix = "forward-to-"
) )
func NewStubAndroidDriver(device *AndroidDevice) (driver *StubAndroidDriver, err error) { func NewShootsAndroidDriver(device *uixt.AndroidDevice) (driver *ShootsAndroidDriver, err error) {
socketLocalPort, err := device.Forward(StubSocketName) socketLocalPort, err := device.Forward(shootsSocketName)
if err != nil { if err != nil {
return nil, errors.Wrap(code.DeviceConnectionError, return nil, errors.Wrap(code.DeviceConnectionError,
fmt.Sprintf("forward port %d->%s failed: %v", fmt.Sprintf("forward port %d->%s failed: %v",
socketLocalPort, StubSocketName, err)) socketLocalPort, shootsSocketName, err))
} }
serverLocalPort, err := device.Forward(DouyinServerPort)
if err != nil {
return nil, errors.Wrap(code.DeviceConnectionError,
fmt.Sprintf("forward port %d->%d failed: %v",
serverLocalPort, DouyinServerPort, err))
}
address := fmt.Sprintf("127.0.0.1:%d", socketLocalPort) address := fmt.Sprintf("127.0.0.1:%d", socketLocalPort)
conn, err := net.Dial("tcp", address) conn, err := net.Dial("tcp", address)
if err != nil { if err != nil {
log.Err(err).Msg(fmt.Sprintf("failed to connect %s", address)) log.Err(err).Msg(fmt.Sprintf("failed to connect %s", address))
return nil, err return nil, err
} }
driver = &ShootsAndroidDriver{
driver = &StubAndroidDriver{
socket: conn, socket: conn,
timeout: 10 * time.Second, timeout: 10 * time.Second,
} }
rawURL := fmt.Sprintf("http://forward-to-%d:%d", driver.InitSession(nil)
serverLocalPort, DouyinServerPort) serverLocalPort, err := device.Forward(douyinServerPort)
if driver.baseURL, err = url.Parse(rawURL); err != nil { if err != nil {
return nil, err return nil, errors.Wrap(code.DeviceConnectionError,
fmt.Sprintf("forward port %d->%d failed: %v",
serverLocalPort, douyinServerPort, err))
} }
rawURL := fmt.Sprintf("http://forward-to-%d:%d",
serverLocalPort, douyinServerPort)
driver.Session.Init(rawURL)
driver.NewSession(nil)
driver.Device = device.Device driver.Device = device.Device
driver.Logcat = device.Logcat driver.Logcat = device.Logcat
return driver, nil return driver, nil
} }
type StubAndroidDriver struct { type ShootsAndroidDriver struct {
*ADBDriver *uixt.ADBDriver
socket net.Conn socket net.Conn
seq int seq int
timeout time.Duration timeout time.Duration
} }
type AppLoginInfo struct { func (sad *ShootsAndroidDriver) sendCommand(packageName string, cmdType string, params map[string]interface{}, readTimeout ...time.Duration) (interface{}, error) {
Did string `json:"did,omitempty" yaml:"did,omitempty"`
Uid string `json:"uid,omitempty" yaml:"uid,omitempty"`
IsLogin bool `json:"is_login,omitempty" yaml:"is_login,omitempty"`
}
func (sad *StubAndroidDriver) httpGET(pathElem ...string) (rawResp rawResponse, err error) {
var localPort int
{
tmpURL, _ := url.Parse(sad.baseURL.String())
hostname := tmpURL.Hostname()
if strings.HasPrefix(hostname, forwardToPrefix) {
localPort, _ = strconv.Atoi(strings.TrimPrefix(hostname, forwardToPrefix))
}
}
conn, err := net.Dial("tcp", fmt.Sprintf(":%d", localPort))
if err != nil {
return nil, fmt.Errorf("adb forward: %w", err)
}
sad.client = convertToHTTPClient(conn)
return sad.Request(http.MethodGet, sad.concatURL(nil, pathElem...), nil)
}
func (sad *StubAndroidDriver) httpPOST(data interface{}, pathElem ...string) (rawResp rawResponse, err error) {
var localPort int
{
tmpURL, _ := url.Parse(sad.baseURL.String())
hostname := tmpURL.Hostname()
if strings.HasPrefix(hostname, forwardToPrefix) {
localPort, _ = strconv.Atoi(strings.TrimPrefix(hostname, forwardToPrefix))
}
}
conn, err := net.Dial("tcp", fmt.Sprintf(":%d", localPort))
if err != nil {
return nil, fmt.Errorf("adb forward: %w", err)
}
sad.client = convertToHTTPClient(conn)
var bsJSON []byte = nil
if data != nil {
if bsJSON, err = json.Marshal(data); err != nil {
return nil, err
}
}
return sad.Request(http.MethodPost, sad.concatURL(nil, pathElem...), bsJSON)
}
func (sad *StubAndroidDriver) NewSession(capabilities option.Capabilities) (Session, error) {
sad.Reset()
return Session{}, errDriverNotImplemented
}
func (sad *StubAndroidDriver) sendCommand(packageName string, cmdType string, params map[string]interface{}, readTimeout ...time.Duration) (interface{}, error) {
sad.seq++ sad.seq++
packet := map[string]interface{}{ packet := map[string]interface{}{
"Seq": sad.seq, "Seq": sad.seq,
@@ -150,24 +89,24 @@ func (sad *StubAndroidDriver) sendCommand(packageName string, cmdType string, pa
return nil, err return nil, err
} }
if resultMap["Error"] != nil { if resultMap["Error"] != nil {
return nil, fmt.Errorf("failed to call stub command: %s", resultMap["Error"].(string)) return nil, fmt.Errorf("failed to call shoots command: %s", resultMap["Error"].(string))
} }
return resultMap["Result"], nil return resultMap["Result"], nil
} }
func (sad *StubAndroidDriver) DeleteSession() error { func (sad *ShootsAndroidDriver) DeleteSession() error {
return sad.close() return sad.close()
} }
func (sad *StubAndroidDriver) close() error { func (sad *ShootsAndroidDriver) close() error {
if sad.socket != nil { if sad.socket != nil {
return sad.socket.Close() return sad.socket.Close()
} }
return nil return nil
} }
func (sad *StubAndroidDriver) Status() (types.DeviceStatus, error) { func (sad *ShootsAndroidDriver) Status() (types.DeviceStatus, error) {
app, err := sad.GetForegroundApp() app, err := sad.GetForegroundApp()
if err != nil { if err != nil {
return types.DeviceStatus{}, err return types.DeviceStatus{}, err
@@ -176,11 +115,11 @@ func (sad *StubAndroidDriver) Status() (types.DeviceStatus, error) {
if err != nil { if err != nil {
return types.DeviceStatus{}, err return types.DeviceStatus{}, err
} }
log.Info().Msg(fmt.Sprintf("ping stub result :%v", res)) log.Info().Msg(fmt.Sprintf("ping shoots result :%v", res))
return types.DeviceStatus{}, nil return types.DeviceStatus{}, nil
} }
func (sad *StubAndroidDriver) 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.GetForegroundApp()
if err != nil { if err != nil {
return "", err return "", err
@@ -198,7 +137,7 @@ func (sad *StubAndroidDriver) Source(srcOpt ...option.SourceOption) (source stri
return res.(string), nil return res.(string), nil
} }
func (sad *StubAndroidDriver) LoginNoneUI(packageName, phoneNumber string, captcha, password string) (info AppLoginInfo, err error) { func (sad *ShootsAndroidDriver) LoginNoneUI(packageName, phoneNumber string, captcha, password string) (info AppLoginInfo, err error) {
params := map[string]interface{}{ params := map[string]interface{}{
"phone": phoneNumber, "phone": phoneNumber,
} }
@@ -209,11 +148,11 @@ func (sad *StubAndroidDriver) LoginNoneUI(packageName, phoneNumber string, captc
} else { } else {
return info, fmt.Errorf("password and capcha is empty") return info, fmt.Errorf("password and capcha is empty")
} }
resp, err := sad.httpPOST(params, "/host", "/login", "account") resp, err := sad.Session.POST(params, "/host", "/login", "account")
if err != nil { if err != nil {
return info, err return info, err
} }
res, err := resp.valueConvertToJsonObject() res, err := resp.ValueConvertToJsonObject()
if err != nil { if err != nil {
return info, err return info, err
} }
@@ -231,12 +170,12 @@ func (sad *StubAndroidDriver) LoginNoneUI(packageName, phoneNumber string, captc
return info, nil return info, nil
} }
func (sad *StubAndroidDriver) LogoutNoneUI(packageName string) error { func (sad *ShootsAndroidDriver) LogoutNoneUI(packageName string) error {
resp, err := sad.httpGET("/host", "/logout") resp, err := sad.Session.GET("/host", "/logout")
if err != nil { if err != nil {
return err return err
} }
res, err := resp.valueConvertToJsonObject() res, err := resp.ValueConvertToJsonObject()
if err != nil { if err != nil {
return err return err
} }
@@ -254,7 +193,7 @@ func (sad *StubAndroidDriver) LogoutNoneUI(packageName string) error {
return nil return nil
} }
func (sad *StubAndroidDriver) LoginNoneUIDynamic(packageName, phoneNumber string, captcha string) error { func (sad *ShootsAndroidDriver) LoginNoneUIDynamic(packageName, phoneNumber string, captcha string) error {
params := map[string]interface{}{ params := map[string]interface{}{
"ClassName": "qe.python.test.LoginUtil", "ClassName": "qe.python.test.LoginUtil",
"Method": "loginSync", "Method": "loginSync",
@@ -269,7 +208,7 @@ func (sad *StubAndroidDriver) LoginNoneUIDynamic(packageName, phoneNumber string
return nil return nil
} }
func (sad *StubAndroidDriver) SetHDTStatus(status bool) error { func (sad *ShootsAndroidDriver) SetHDTStatus(status bool) error {
_, err := sad.Device.RunShellCommand("settings", "put", "global", "feedbacker_sso_bypass_token", "default_sso_bypass_token") _, err := sad.Device.RunShellCommand("settings", "put", "global", "feedbacker_sso_bypass_token", "default_sso_bypass_token")
if err != nil { if err != nil {
log.Warn().Msg(fmt.Sprintf("failed to disable sso, error: %v", err)) log.Warn().Msg(fmt.Sprintf("failed to disable sso, error: %v", err))
@@ -288,12 +227,12 @@ func (sad *StubAndroidDriver) SetHDTStatus(status bool) error {
return nil return nil
} }
func (sad *StubAndroidDriver) getLoginAppInfo(packageName string) (info AppLoginInfo, err error) { func (sad *ShootsAndroidDriver) getLoginAppInfo(packageName string) (info AppLoginInfo, err error) {
resp, err := sad.httpGET("/host", "/app", "/info") resp, err := sad.Session.GET("/host", "/app", "/info")
if err != nil { if err != nil {
return info, err return info, err
} }
res, err := resp.valueConvertToJsonObject() res, err := resp.ValueConvertToJsonObject()
if err != nil { if err != nil {
return info, err return info, err
} }
@@ -310,3 +249,9 @@ func (sad *StubAndroidDriver) getLoginAppInfo(packageName string) (info AppLogin
} }
return info, nil return info, nil
} }
type AppLoginInfo struct {
Did string `json:"did,omitempty" yaml:"did,omitempty"`
Uid string `json:"uid,omitempty" yaml:"uid,omitempty"`
IsLogin bool `json:"is_login,omitempty" yaml:"is_login,omitempty"`
}
@@ -0,0 +1,154 @@
package driver_ext
import (
"fmt"
"os"
"testing"
"github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
)
var shootsAndroidDriver *ShootsAndroidDriver
func setupShootsAndroidDriver(t *testing.T) {
device, err := uixt.NewAndroidDevice()
checkErr(t, err)
shootsAndroidDriver, err = NewShootsAndroidDriver(device)
checkErr(t, err)
}
func checkErr(t *testing.T, err error, msg ...string) {
if err != nil {
if len(msg) == 0 {
t.Fatal(err)
} else {
t.Fatal(msg, err)
}
}
}
func TestHello(t *testing.T) {
setupShootsAndroidDriver(t)
status, err := shootsAndroidDriver.Status()
if err != nil {
t.Fatal(err)
}
t.Log(status)
}
func TestSource(t *testing.T) {
setupShootsAndroidDriver(t)
source, err := shootsAndroidDriver.Source()
if err != nil {
t.Fatal(err)
}
t.Log(source)
}
func TestLogin(t *testing.T) {
setupShootsAndroidDriver(t)
info, err := shootsAndroidDriver.LoginNoneUI("com.ss.android.ugc.aweme", "12342316231", "8517", "")
if err != nil {
t.Fatal(err)
}
t.Log(info)
}
func TestLogout(t *testing.T) {
setupShootsAndroidDriver(t)
err := shootsAndroidDriver.LogoutNoneUI("com.ss.android.ugc.aweme")
if err != nil {
t.Fatal(err)
}
}
func TestSwipe(t *testing.T) {
setupShootsAndroidDriver(t)
err := shootsAndroidDriver.Swipe(878, 2375, 672, 2375)
if err != nil {
t.Fatal(err)
}
}
func TestTap(t *testing.T) {
setupShootsAndroidDriver(t)
err := shootsAndroidDriver.Tap(900, 400)
if err != nil {
t.Fatal(err)
}
}
func TestDoubleTap(t *testing.T) {
setupShootsAndroidDriver(t)
err := shootsAndroidDriver.DoubleTap(500, 500)
if err != nil {
t.Fatal(err)
}
}
func TestLongPress(t *testing.T) {
setupShootsAndroidDriver(t)
err := shootsAndroidDriver.Swipe(1036, 1076, 1036, 1076,
option.WithDuration(3))
if err != nil {
t.Fatal(err)
}
}
func TestInput(t *testing.T) {
setupShootsAndroidDriver(t)
err := shootsAndroidDriver.Input("\"哈哈\"")
if err != nil {
t.Fatal(err)
}
}
func TestSave(t *testing.T) {
setupShootsAndroidDriver(t)
raw, err := shootsAndroidDriver.Screenshot()
if err != nil {
t.Fatal(err)
}
source, err := shootsAndroidDriver.Source()
if err != nil {
t.Fatal(err)
}
step := 14
file, err := os.Create(fmt.Sprintf("/Users/bytedance/workcode/wings_algorithm/testcases/data/cases/0/%d.jpg", step))
if err != nil {
t.Fatal(err)
}
file.Write(raw.Bytes())
file, err = os.Create(fmt.Sprintf("/Users/bytedance/workcode/wings_algorithm/testcases/data/cases/0/%d.json", step))
if err != nil {
t.Fatal(err)
}
file.Write([]byte(source))
}
func TestAppLaunch(t *testing.T) {
setupShootsAndroidDriver(t)
err := shootsAndroidDriver.AppLaunch("com.ss.android.ugc.aweme")
if err != nil {
t.Fatal(err)
}
}
func TestAppTerminal(t *testing.T) {
setupShootsAndroidDriver(t)
_, err := shootsAndroidDriver.AppTerminate("com.ss.android.ugc.aweme")
if err != nil {
t.Fatal(err)
}
}
func TestAppInfo(t *testing.T) {
setupShootsAndroidDriver(t)
info, err := shootsAndroidDriver.getLoginAppInfo("com.ss.android.ugc.aweme")
if err != nil {
t.Fatal(err)
}
t.Log(info)
}
@@ -1,4 +1,4 @@
package uixt package driver_ext
import ( import (
"bytes" "bytes"
@@ -12,6 +12,7 @@ import (
"github.com/httprunner/httprunner/v5/code" "github.com/httprunner/httprunner/v5/code"
"github.com/httprunner/httprunner/v5/internal/builtin" "github.com/httprunner/httprunner/v5/internal/builtin"
"github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/ai" "github.com/httprunner/httprunner/v5/pkg/uixt/ai"
"github.com/httprunner/httprunner/v5/pkg/uixt/option" "github.com/httprunner/httprunner/v5/pkg/uixt/option"
"github.com/httprunner/httprunner/v5/pkg/uixt/types" "github.com/httprunner/httprunner/v5/pkg/uixt/types"
@@ -22,14 +23,14 @@ const (
defaultDouyinServerPort = 32921 defaultDouyinServerPort = 32921
) )
func NewStubIOSDriver(device *IOSDevice) (driver *StubIOSDriver, err error) { func NewShootsIOSDriver(device *uixt.IOSDevice) (driver *ShootsIOSDriver, err error) {
localStubPort, err := builtin.GetFreePort() localShootsPort, err := builtin.GetFreePort()
if err != nil { if err != nil {
return nil, errors.Wrap(code.DeviceHTTPDriverError, return nil, errors.Wrap(code.DeviceHTTPDriverError,
fmt.Sprintf("get free port failed: %v", err)) fmt.Sprintf("get free port failed: %v", err))
} }
if err = device.forward(localStubPort, defaultBightInsightPort); err != nil { if err = device.Forward(localShootsPort, defaultBightInsightPort); err != nil {
return nil, errors.Wrap(code.DeviceHTTPDriverError, return nil, errors.Wrap(code.DeviceHTTPDriverError,
fmt.Sprintf("forward tcp port failed: %v", err)) fmt.Sprintf("forward tcp port failed: %v", err))
} }
@@ -39,61 +40,54 @@ func NewStubIOSDriver(device *IOSDevice) (driver *StubIOSDriver, err error) {
return nil, errors.Wrap(code.DeviceHTTPDriverError, return nil, errors.Wrap(code.DeviceHTTPDriverError,
fmt.Sprintf("get free port failed: %v", err)) fmt.Sprintf("get free port failed: %v", err))
} }
if err = device.forward(localServerPort, defaultDouyinServerPort); err != nil { if err = device.Forward(localServerPort, defaultDouyinServerPort); err != nil {
return nil, errors.Wrap(code.DeviceHTTPDriverError, return nil, errors.Wrap(code.DeviceHTTPDriverError,
fmt.Sprintf("forward tcp port failed: %v", err)) fmt.Sprintf("forward tcp port failed: %v", err))
} }
host := "localhost" host := "localhost"
timeout := 10 * time.Second timeout := 10 * time.Second
driver = &StubIOSDriver{} driver = &ShootsIOSDriver{}
driver.device = device driver.device = device
driver.bightInsightPrefix = fmt.Sprintf("http://%s:%d", host, localStubPort) driver.bightInsightPrefix = fmt.Sprintf("http://%s:%d", host, localShootsPort)
driver.serverPrefix = fmt.Sprintf("http://%s:%d", host, localServerPort) driver.serverPrefix = fmt.Sprintf("http://%s:%d", host, localServerPort)
driver.timeout = timeout driver.timeout = timeout
driver.client = &http.Client{
Timeout: time.Second * 10, // 设置超时时间为 10 秒
}
return driver, nil return driver, nil
} }
type StubIOSDriver struct { type ShootsIOSDriver struct {
*WDADriver *uixt.WDADriver
bightInsightPrefix string bightInsightPrefix string
serverPrefix string serverPrefix string
timeout time.Duration timeout time.Duration
device *IOSDevice device *uixt.IOSDevice
} }
func (s *StubIOSDriver) setUpWda() (err error) { func (s *ShootsIOSDriver) setUpWda() (err error) {
if s.WDADriver == nil { if s.WDADriver == nil {
capabilities := option.NewCapabilities() capabilities := option.NewCapabilities()
capabilities.WithDefaultAlertAction(option.AlertActionAccept) capabilities.WithDefaultAlertAction(option.AlertActionAccept)
driver, err := s.device.NewHTTPDriver(capabilities) driver, err := s.device.NewHTTPDriver(capabilities)
if err != nil { if err != nil {
log.Error().Err(err).Msg("stub driver failed to init wda driver") log.Error().Err(err).Msg("failed to init WDA driver for shoots IOS")
return err return err
} }
s.WDADriver = driver.(*WDADriver) s.WDADriver = driver.(*uixt.WDADriver)
} }
return nil return nil
} }
// NewSession starts a new session and returns the DriverSession. // InitSession starts a new session and returns the DriverSession.
func (s *StubIOSDriver) NewSession(capabilities option.Capabilities) (Session, error) { func (s *ShootsIOSDriver) InitSession(capabilities option.Capabilities) error {
err := s.setUpWda() return s.WDADriver.InitSession(capabilities)
if err != nil {
return Session{}, err
}
return s.WDADriver.NewSession(capabilities)
} }
// DeleteSession Kills application associated with that session and removes session // DeleteSession Kills application associated with that session and removes session
// 1. alertsMonitor disable // 1. alertsMonitor disable
// 2. testedApplicationBundleId terminate // 2. testedApplicationBundleId terminate
func (s *StubIOSDriver) DeleteSession() error { func (s *ShootsIOSDriver) DeleteSession() error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -101,7 +95,7 @@ func (s *StubIOSDriver) DeleteSession() error {
return s.WDADriver.DeleteSession() return s.WDADriver.DeleteSession()
} }
func (s *StubIOSDriver) Status() (types.DeviceStatus, error) { func (s *ShootsIOSDriver) Status() (types.DeviceStatus, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return types.DeviceStatus{}, err return types.DeviceStatus{}, err
@@ -109,7 +103,7 @@ func (s *StubIOSDriver) Status() (types.DeviceStatus, error) {
return s.WDADriver.Status() return s.WDADriver.Status()
} }
func (s *StubIOSDriver) DeviceInfo() (types.DeviceInfo, error) { func (s *ShootsIOSDriver) DeviceInfo() (types.DeviceInfo, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return types.DeviceInfo{}, err return types.DeviceInfo{}, err
@@ -117,7 +111,7 @@ func (s *StubIOSDriver) DeviceInfo() (types.DeviceInfo, error) {
return s.WDADriver.DeviceInfo() return s.WDADriver.DeviceInfo()
} }
func (s *StubIOSDriver) Location() (types.Location, error) { func (s *ShootsIOSDriver) Location() (types.Location, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return types.Location{}, err return types.Location{}, err
@@ -125,7 +119,7 @@ func (s *StubIOSDriver) Location() (types.Location, error) {
return s.WDADriver.Location() return s.WDADriver.Location()
} }
func (s *StubIOSDriver) BatteryInfo() (types.BatteryInfo, error) { func (s *ShootsIOSDriver) BatteryInfo() (types.BatteryInfo, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return types.BatteryInfo{}, err return types.BatteryInfo{}, err
@@ -136,7 +130,7 @@ func (s *StubIOSDriver) BatteryInfo() (types.BatteryInfo, error) {
// WindowSize Return the width and height in portrait mode. // WindowSize Return the width and height in portrait mode.
// when getting the window size in wda/ui2/adb, if the device is in landscape mode, // when getting the window size in wda/ui2/adb, if the device is in landscape mode,
// the width and height will be reversed. // the width and height will be reversed.
func (s *StubIOSDriver) WindowSize() (types.Size, error) { func (s *ShootsIOSDriver) WindowSize() (types.Size, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return types.Size{}, err return types.Size{}, err
@@ -144,7 +138,7 @@ func (s *StubIOSDriver) WindowSize() (types.Size, error) {
return s.WDADriver.WindowSize() return s.WDADriver.WindowSize()
} }
func (s *StubIOSDriver) Screen() (ai.Screen, error) { func (s *ShootsIOSDriver) Screen() (ai.Screen, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return ai.Screen{}, err return ai.Screen{}, err
@@ -152,7 +146,7 @@ func (s *StubIOSDriver) Screen() (ai.Screen, error) {
return s.WDADriver.Screen() return s.WDADriver.Screen()
} }
func (s *StubIOSDriver) Scale() (float64, error) { func (s *ShootsIOSDriver) Scale() (float64, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return 0, err return 0, err
@@ -161,7 +155,7 @@ func (s *StubIOSDriver) Scale() (float64, error) {
} }
// Homescreen Forces the device under test to switch to the home screen // Homescreen Forces the device under test to switch to the home screen
func (s *StubIOSDriver) Homescreen() error { func (s *ShootsIOSDriver) Homescreen() error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -169,7 +163,7 @@ func (s *StubIOSDriver) Homescreen() error {
return s.WDADriver.Homescreen() return s.WDADriver.Homescreen()
} }
func (s *StubIOSDriver) Unlock() (err error) { func (s *ShootsIOSDriver) Unlock() (err error) {
err = s.setUpWda() err = s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -179,7 +173,7 @@ func (s *StubIOSDriver) Unlock() (err error) {
// AppLaunch Launch an application with given bundle identifier in scope of current session. // AppLaunch Launch an application with given bundle identifier in scope of current session.
// !This method is only available since Xcode9 SDK // !This method is only available since Xcode9 SDK
func (s *StubIOSDriver) AppLaunch(packageName string) error { func (s *ShootsIOSDriver) AppLaunch(packageName string) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -189,7 +183,7 @@ func (s *StubIOSDriver) AppLaunch(packageName string) error {
// AppTerminate Terminate an application with the given package name. // AppTerminate Terminate an application with the given package name.
// Either `true` if the app has been successfully terminated or `false` if it was not running // Either `true` if the app has been successfully terminated or `false` if it was not running
func (s *StubIOSDriver) AppTerminate(packageName string) (bool, error) { func (s *ShootsIOSDriver) AppTerminate(packageName string) (bool, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return false, err return false, err
@@ -198,7 +192,7 @@ func (s *StubIOSDriver) AppTerminate(packageName string) (bool, error) {
} }
// GetForegroundApp returns current foreground app package name and activity name // GetForegroundApp returns current foreground app package name and activity name
func (s *StubIOSDriver) GetForegroundApp() (app types.AppInfo, err error) { func (s *ShootsIOSDriver) GetForegroundApp() (app types.AppInfo, err error) {
err = s.setUpWda() err = s.setUpWda()
if err != nil { if err != nil {
return types.AppInfo{}, err return types.AppInfo{}, err
@@ -207,7 +201,7 @@ func (s *StubIOSDriver) GetForegroundApp() (app types.AppInfo, err error) {
} }
// StartCamera Starts a new camera for recording // StartCamera Starts a new camera for recording
func (s *StubIOSDriver) StartCamera() error { func (s *ShootsIOSDriver) StartCamera() error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -216,7 +210,7 @@ func (s *StubIOSDriver) StartCamera() error {
} }
// StopCamera Stops the camera for recording // StopCamera Stops the camera for recording
func (s *StubIOSDriver) StopCamera() error { func (s *ShootsIOSDriver) StopCamera() error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -224,7 +218,7 @@ func (s *StubIOSDriver) StopCamera() error {
return s.WDADriver.StopCamera() return s.WDADriver.StopCamera()
} }
func (s *StubIOSDriver) Orientation() (orientation types.Orientation, err error) { func (s *ShootsIOSDriver) Orientation() (orientation types.Orientation, err error) {
err = s.setUpWda() err = s.setUpWda()
if err != nil { if err != nil {
return types.OrientationPortrait, err return types.OrientationPortrait, err
@@ -233,7 +227,7 @@ func (s *StubIOSDriver) Orientation() (orientation types.Orientation, err error)
} }
// Tap Sends a tap event at the coordinate. // Tap Sends a tap event at the coordinate.
func (s *StubIOSDriver) Tap(x, y float64, opts ...option.ActionOption) error { func (s *ShootsIOSDriver) Tap(x, y float64, opts ...option.ActionOption) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -242,7 +236,7 @@ func (s *StubIOSDriver) Tap(x, y float64, opts ...option.ActionOption) error {
} }
// DoubleTap Sends a double tap event at the coordinate. // DoubleTap Sends a double tap event at the coordinate.
func (s *StubIOSDriver) DoubleTap(x, y float64, opts ...option.ActionOption) error { func (s *ShootsIOSDriver) DoubleTap(x, y float64, opts ...option.ActionOption) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -253,7 +247,7 @@ func (s *StubIOSDriver) DoubleTap(x, y float64, opts ...option.ActionOption) err
// TouchAndHold Initiates a long-press gesture at the coordinate, holding for the specified duration. // TouchAndHold Initiates a long-press gesture at the coordinate, holding for the specified duration.
// //
// second: The default value is 1 // second: The default value is 1
func (s *StubIOSDriver) TouchAndHold(x, y float64, opts ...option.ActionOption) error { func (s *ShootsIOSDriver) TouchAndHold(x, y float64, opts ...option.ActionOption) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -263,7 +257,7 @@ func (s *StubIOSDriver) TouchAndHold(x, y float64, opts ...option.ActionOption)
// Drag Initiates a press-and-hold gesture at the coordinate, then drags to another coordinate. // Drag Initiates a press-and-hold gesture at the coordinate, then drags to another coordinate.
// WithPressDurationOption option can be used to set pressForDuration (default to 1 second). // WithPressDurationOption option can be used to set pressForDuration (default to 1 second).
func (s *StubIOSDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error { func (s *ShootsIOSDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -272,7 +266,7 @@ func (s *StubIOSDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.Acti
} }
// SetPasteboard Sets data to the general pasteboard // SetPasteboard Sets data to the general pasteboard
func (s *StubIOSDriver) SetPasteboard(contentType types.PasteboardType, content string) error { func (s *ShootsIOSDriver) SetPasteboard(contentType types.PasteboardType, content string) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -283,7 +277,7 @@ func (s *StubIOSDriver) SetPasteboard(contentType types.PasteboardType, content
// GetPasteboard Gets the data contained in the general pasteboard. // GetPasteboard Gets the data contained in the general pasteboard.
// //
// It worked when `WDA` was foreground. https://github.com/appium/WebDriverAgent/issues/330 // It worked when `WDA` was foreground. https://github.com/appium/WebDriverAgent/issues/330
func (s *StubIOSDriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes.Buffer, err error) { func (s *ShootsIOSDriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes.Buffer, err error) {
err = s.setUpWda() err = s.setUpWda()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -291,7 +285,7 @@ func (s *StubIOSDriver) GetPasteboard(contentType types.PasteboardType) (raw *by
return s.WDADriver.GetPasteboard(contentType) return s.WDADriver.GetPasteboard(contentType)
} }
func (s *StubIOSDriver) SetIme(ime string) error { func (s *ShootsIOSDriver) SetIme(ime string) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -302,7 +296,7 @@ func (s *StubIOSDriver) SetIme(ime string) error {
// SendKeys Types a string into active element. There must be element with keyboard focus, // SendKeys Types a string into active element. There must be element with keyboard focus,
// otherwise an error is raised. // otherwise an error is raised.
// WithFrequency option can be used to set frequency of typing (letters per sec). The default value is 60 // WithFrequency option can be used to set frequency of typing (letters per sec). The default value is 60
func (s *StubIOSDriver) SendKeys(text string, opts ...option.ActionOption) error { func (s *ShootsIOSDriver) SendKeys(text string, opts ...option.ActionOption) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -311,7 +305,7 @@ func (s *StubIOSDriver) SendKeys(text string, opts ...option.ActionOption) error
} }
// Input works like SendKeys // Input works like SendKeys
func (s *StubIOSDriver) Input(text string, opts ...option.ActionOption) error { func (s *ShootsIOSDriver) Input(text string, opts ...option.ActionOption) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -319,7 +313,7 @@ func (s *StubIOSDriver) Input(text string, opts ...option.ActionOption) error {
return s.WDADriver.Input(text, opts...) return s.WDADriver.Input(text, opts...)
} }
func (s *StubIOSDriver) Clear(packageName string) error { func (s *ShootsIOSDriver) Clear(packageName string) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -328,7 +322,7 @@ func (s *StubIOSDriver) Clear(packageName string) error {
} }
// PressButton Presses the corresponding hardware button on the device // PressButton Presses the corresponding hardware button on the device
func (s *StubIOSDriver) PressButton(devBtn types.DeviceButton) error { func (s *ShootsIOSDriver) PressButton(devBtn types.DeviceButton) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -337,7 +331,7 @@ func (s *StubIOSDriver) PressButton(devBtn types.DeviceButton) error {
} }
// PressBack Presses the back button // PressBack Presses the back button
func (s *StubIOSDriver) PressBack(opts ...option.ActionOption) error { func (s *ShootsIOSDriver) PressBack(opts ...option.ActionOption) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -345,7 +339,7 @@ func (s *StubIOSDriver) PressBack(opts ...option.ActionOption) error {
return s.WDADriver.PressBack(opts...) return s.WDADriver.PressBack(opts...)
} }
func (s *StubIOSDriver) PressKeyCode(keyCode KeyCode) (err error) { func (s *ShootsIOSDriver) PressKeyCode(keyCode uixt.KeyCode) (err error) {
err = s.setUpWda() err = s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -353,7 +347,7 @@ func (s *StubIOSDriver) PressKeyCode(keyCode KeyCode) (err error) {
return s.WDADriver.PressKeyCode(keyCode) return s.WDADriver.PressKeyCode(keyCode)
} }
func (s *StubIOSDriver) Screenshot() (*bytes.Buffer, error) { func (s *ShootsIOSDriver) Screenshot() (*bytes.Buffer, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -374,7 +368,7 @@ func (s *StubIOSDriver) Screenshot() (*bytes.Buffer, error) {
//return bytes.NewBuffer(imageBytes), nil //return bytes.NewBuffer(imageBytes), nil
} }
func (s *StubIOSDriver) TapByText(text string, opts ...option.ActionOption) error { func (s *ShootsIOSDriver) TapByText(text string, opts ...option.ActionOption) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -382,7 +376,7 @@ func (s *StubIOSDriver) TapByText(text string, opts ...option.ActionOption) erro
return s.WDADriver.TapByText(text, opts...) return s.WDADriver.TapByText(text, opts...)
} }
func (s *StubIOSDriver) TapByTexts(actions ...TapTextAction) error { func (s *ShootsIOSDriver) TapByTexts(actions ...uixt.TapTextAction) error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -391,7 +385,7 @@ func (s *StubIOSDriver) TapByTexts(actions ...TapTextAction) error {
} }
// AccessibleSource Return application elements accessibility tree // AccessibleSource Return application elements accessibility tree
func (s *StubIOSDriver) AccessibleSource() (string, error) { func (s *ShootsIOSDriver) AccessibleSource() (string, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return "", err return "", err
@@ -404,7 +398,7 @@ func (s *StubIOSDriver) AccessibleSource() (string, error) {
// Checks health of XCTest by: // Checks health of XCTest by:
// 1) Querying application for some elements, // 1) Querying application for some elements,
// 2) Triggering some device events. // 2) Triggering some device events.
func (s *StubIOSDriver) HealthCheck() error { func (s *ShootsIOSDriver) HealthCheck() error {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -412,7 +406,7 @@ func (s *StubIOSDriver) HealthCheck() error {
return s.WDADriver.HealthCheck() return s.WDADriver.HealthCheck()
} }
func (s *StubIOSDriver) GetAppiumSettings() (map[string]interface{}, error) { func (s *ShootsIOSDriver) GetAppiumSettings() (map[string]interface{}, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -420,7 +414,7 @@ func (s *StubIOSDriver) GetAppiumSettings() (map[string]interface{}, error) {
return s.WDADriver.GetAppiumSettings() return s.WDADriver.GetAppiumSettings()
} }
func (s *StubIOSDriver) SetAppiumSettings(settings map[string]interface{}) (map[string]interface{}, error) { func (s *ShootsIOSDriver) SetAppiumSettings(settings map[string]interface{}) (map[string]interface{}, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -428,7 +422,7 @@ func (s *StubIOSDriver) SetAppiumSettings(settings map[string]interface{}) (map[
return s.WDADriver.SetAppiumSettings(settings) return s.WDADriver.SetAppiumSettings(settings)
} }
func (s *StubIOSDriver) IsHealthy() (bool, error) { func (s *ShootsIOSDriver) IsHealthy() (bool, error) {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return false, err return false, err
@@ -437,7 +431,7 @@ func (s *StubIOSDriver) IsHealthy() (bool, error) {
} }
// triggers the log capture and returns the log entries // triggers the log capture and returns the log entries
func (s *StubIOSDriver) StartCaptureLog(identifier ...string) (err error) { func (s *ShootsIOSDriver) StartCaptureLog(identifier ...string) (err error) {
err = s.setUpWda() err = s.setUpWda()
if err != nil { if err != nil {
return err return err
@@ -445,7 +439,7 @@ func (s *StubIOSDriver) StartCaptureLog(identifier ...string) (err error) {
return s.WDADriver.StartCaptureLog(identifier...) return s.WDADriver.StartCaptureLog(identifier...)
} }
func (s *StubIOSDriver) StopCaptureLog() (result interface{}, err error) { func (s *ShootsIOSDriver) StopCaptureLog() (result interface{}, err error) {
err = s.setUpWda() err = s.setUpWda()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -453,7 +447,7 @@ func (s *StubIOSDriver) StopCaptureLog() (result interface{}, err error) {
return s.WDADriver.StopCaptureLog() return s.WDADriver.StopCaptureLog()
} }
func (s *StubIOSDriver) GetDriverResults() []*DriverRequests { func (s *ShootsIOSDriver) GetDriverResults() []*uixt.DriverRequests {
err := s.setUpWda() err := s.setUpWda()
if err != nil { if err != nil {
return nil return nil
@@ -461,7 +455,7 @@ func (s *StubIOSDriver) GetDriverResults() []*DriverRequests {
return s.WDADriver.GetDriverResults() return s.WDADriver.GetDriverResults()
} }
func (s *StubIOSDriver) Source(srcOpt ...option.SourceOption) (string, error) { func (s *ShootsIOSDriver) Source(srcOpt ...option.SourceOption) (string, error) {
resp, err := s.Request(http.MethodGet, fmt.Sprintf("%s/source?format=json&onlyWeb=false", s.bightInsightPrefix), []byte{}) resp, err := s.Request(http.MethodGet, fmt.Sprintf("%s/source?format=json&onlyWeb=false", s.bightInsightPrefix), []byte{})
if err != nil { if err != nil {
return "", err return "", err
@@ -469,7 +463,7 @@ func (s *StubIOSDriver) Source(srcOpt ...option.SourceOption) (string, error) {
return string(resp), nil return string(resp), nil
} }
func (s *StubIOSDriver) LoginNoneUI(packageName, phoneNumber string, captcha, password string) (info AppLoginInfo, err error) { func (s *ShootsIOSDriver) LoginNoneUI(packageName, phoneNumber string, captcha, password string) (info AppLoginInfo, err error) {
params := map[string]interface{}{ params := map[string]interface{}{
"phone": phoneNumber, "phone": phoneNumber,
} }
@@ -488,7 +482,7 @@ func (s *StubIOSDriver) LoginNoneUI(packageName, phoneNumber string, captcha, pa
if err != nil { if err != nil {
return info, err return info, err
} }
res, err := resp.valueConvertToJsonObject() res, err := resp.ValueConvertToJsonObject()
if err != nil { if err != nil {
return info, err return info, err
} }
@@ -507,12 +501,12 @@ func (s *StubIOSDriver) LoginNoneUI(packageName, phoneNumber string, captcha, pa
return info, nil return info, nil
} }
func (s *StubIOSDriver) LogoutNoneUI(packageName string) error { func (s *ShootsIOSDriver) LogoutNoneUI(packageName string) error {
resp, err := s.Request(http.MethodGet, fmt.Sprintf("%s/host/loginout/", s.serverPrefix), []byte{}) resp, err := s.Request(http.MethodGet, fmt.Sprintf("%s/host/loginout/", s.serverPrefix), []byte{})
if err != nil { if err != nil {
return err return err
} }
res, err := resp.valueConvertToJsonObject() res, err := resp.ValueConvertToJsonObject()
if err != nil { if err != nil {
return err return err
} }
@@ -526,17 +520,17 @@ func (s *StubIOSDriver) LogoutNoneUI(packageName string) error {
return nil return nil
} }
func (s *StubIOSDriver) TearDown() error { func (s *ShootsIOSDriver) TearDown() error {
s.client.CloseIdleConnections() s.WDADriver.TearDown()
return nil return nil
} }
func (s *StubIOSDriver) getLoginAppInfo(packageName string) (info AppLoginInfo, err error) { func (s *ShootsIOSDriver) getLoginAppInfo(packageName string) (info AppLoginInfo, err error) {
resp, err := s.Request(http.MethodGet, fmt.Sprintf("%s/host/app/info/", s.serverPrefix), []byte{}) resp, err := s.Request(http.MethodGet, fmt.Sprintf("%s/host/app/info/", s.serverPrefix), []byte{})
if err != nil { if err != nil {
return info, err return info, err
} }
res, err := resp.valueConvertToJsonObject() res, err := resp.ValueConvertToJsonObject()
if err != nil { if err != nil {
return info, err return info, err
} }
@@ -553,6 +547,6 @@ func (s *StubIOSDriver) getLoginAppInfo(packageName string) (info AppLoginInfo,
return info, nil return info, nil
} }
func (s *StubIOSDriver) GetSession() *Session { func (s *ShootsIOSDriver) GetSession() *uixt.Session {
return s.Session return s.Session
} }
@@ -1,4 +1,4 @@
package uixt package driver_ext
import ( import (
"fmt" "fmt"
@@ -7,71 +7,71 @@ import (
"testing" "testing"
"github.com/httprunner/httprunner/v5/internal/builtin" "github.com/httprunner/httprunner/v5/internal/builtin"
"github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/option" "github.com/httprunner/httprunner/v5/pkg/uixt/option"
) )
var ( var (
iOSStubDriver IDriverExt shootsIOSDriver uixt.IDriverExt
iOSDevice *IOSDevice iOSDevice *uixt.IOSDevice
) )
func setupiOSStubDriver(t *testing.T) { func setupShootsIOSDriver(t *testing.T) {
var err error var err error
iOSDevice, err = NewIOSDevice( iOSDevice, err = uixt.NewIOSDevice(
option.WithWDAPort(8700), option.WithWDAPort(8700),
option.WithWDAMjpegPort(8800), option.WithWDAMjpegPort(8800))
option.WithIOSStub(false))
checkErr(t, err) checkErr(t, err)
iOSStubDriver, err = iOSDevice.NewDriver() shootsIOSDriver, err = iOSDevice.NewDriver()
checkErr(t, err) checkErr(t, err)
} }
func TestIOSLogin(t *testing.T) { func TestIOSLogin(t *testing.T) {
setupiOSStubDriver(t) setupShootsIOSDriver(t)
info, err := iOSStubDriver.GetDriver().LoginNoneUI("", "12342316231", "8517", "") info, err := shootsIOSDriver.(*ShootsIOSDriver).LoginNoneUI("", "12342316231", "8517", "")
checkErr(t, err) checkErr(t, err)
t.Log(info) t.Log(info)
} }
func TestIOSLogout(t *testing.T) { func TestIOSLogout(t *testing.T) {
setupiOSStubDriver(t) setupShootsIOSDriver(t)
err := iOSStubDriver.GetDriver().LogoutNoneUI("") err := shootsIOSDriver.(*ShootsIOSDriver).LogoutNoneUI("")
checkErr(t, err) checkErr(t, err)
} }
func TestIOSIsLogin(t *testing.T) { func TestIOSIsLogin(t *testing.T) {
setupiOSStubDriver(t) setupShootsIOSDriver(t)
err := iOSStubDriver.GetDriver().LogoutNoneUI("") err := shootsIOSDriver.(*ShootsIOSDriver).LogoutNoneUI("")
checkErr(t, err) checkErr(t, err)
} }
func TestIOSSource(t *testing.T) { func TestIOSSource(t *testing.T) {
setupiOSStubDriver(t) setupShootsIOSDriver(t)
source, err := iOSStubDriver.GetDriver().Source() source, err := shootsIOSDriver.GetDriver().Source()
checkErr(t, err) checkErr(t, err)
t.Log(source) t.Log(source)
} }
func TestIOSForeground(t *testing.T) { func TestIOSForeground(t *testing.T) {
setupiOSStubDriver(t) setupShootsIOSDriver(t)
app, err := iOSStubDriver.GetDriver().GetForegroundApp() app, err := shootsIOSDriver.GetDriver().GetForegroundApp()
checkErr(t, err) checkErr(t, err)
t.Log(app) t.Log(app)
} }
func TestIOSSwipe(t *testing.T) { func TestIOSSwipe(t *testing.T) {
setupiOSStubDriver(t) setupShootsIOSDriver(t)
iOSStubDriver.GetDriver().Swipe(540, 0, 540, 1000) shootsIOSDriver.GetDriver().Swipe(540, 0, 540, 1000)
} }
func TestIOSSave(t *testing.T) { func TestIOSSave(t *testing.T) {
setupiOSStubDriver(t) setupShootsIOSDriver(t)
raw, err := iOSStubDriver.GetDriver().Screenshot() raw, err := shootsIOSDriver.GetDriver().Screenshot()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
source, err := iOSStubDriver.GetDriver().Source() source, err := shootsIOSDriver.GetDriver().Source()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -90,12 +90,12 @@ func TestIOSSave(t *testing.T) {
} }
func TestListen(t *testing.T) { func TestListen(t *testing.T) {
setupiOSStubDriver(t) setupShootsIOSDriver(t)
localPort, err := builtin.GetFreePort() localPort, err := builtin.GetFreePort()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = iOSDevice.forward(localPort, 8800) err = iOSDevice.Forward(localPort, 8800)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
+28 -12
View File
@@ -3,6 +3,7 @@ package uixt
import ( import (
"bytes" "bytes"
"context" "context"
"fmt"
"io" "io"
"net" "net"
"net/http" "net/http"
@@ -19,9 +20,9 @@ import (
type Session struct { type Session struct {
// ctx context.Context // ctx context.Context
sessionID string ID string
baseURL *url.URL baseURL *url.URL
client *http.Client client *http.Client
// cache to avoid repeated query // cache to avoid repeated query
scale float64 scale float64
@@ -43,14 +44,18 @@ func (d *Session) addRequestResult(driverResult *DriverRequests) {
d.requests = append(d.requests, driverResult) d.requests = append(d.requests, driverResult)
} }
func (d *Session) Init(baseUrl string) error {
var err error
d.baseURL, err = url.Parse(baseUrl)
return err
}
func (d *Session) Reset() { func (d *Session) Reset() {
d.screenResults = make([]*ScreenResult, 0) d.screenResults = make([]*ScreenResult, 0)
d.requests = make([]*DriverRequests, 0) d.requests = make([]*DriverRequests, 0)
d.e2eDelay = nil d.e2eDelay = nil
} }
type Attachments map[string]interface{}
func (d *Session) GetData(withReset bool) Attachments { func (d *Session) GetData(withReset bool) Attachments {
data := Attachments{ data := Attachments{
"screen_results": d.screenResults, "screen_results": d.screenResults,
@@ -67,6 +72,8 @@ func (d *Session) GetData(withReset bool) Attachments {
return data return data
} }
type Attachments map[string]interface{}
type DriverRequests struct { type DriverRequests struct {
RequestMethod string `json:"request_method"` RequestMethod string `json:"request_method"`
RequestUrl string `json:"request_url"` RequestUrl string `json:"request_url"`
@@ -91,11 +98,11 @@ func (wd *Session) concatURL(u *url.URL, elem ...string) string {
return tmp.String() return tmp.String()
} }
func (wd *Session) GET(pathElem ...string) (rawResp rawResponse, err error) { func (wd *Session) GET(pathElem ...string) (rawResp DriverRawResponse, err error) {
return wd.Request(http.MethodGet, wd.concatURL(nil, pathElem...), nil) return wd.Request(http.MethodGet, wd.concatURL(nil, pathElem...), nil)
} }
func (wd *Session) POST(data interface{}, pathElem ...string) (rawResp rawResponse, err error) { func (wd *Session) POST(data interface{}, pathElem ...string) (rawResp DriverRawResponse, err error) {
var bsJSON []byte = nil var bsJSON []byte = nil
if data != nil { if data != nil {
if bsJSON, err = json.Marshal(data); err != nil { if bsJSON, err = json.Marshal(data); err != nil {
@@ -105,11 +112,11 @@ func (wd *Session) POST(data interface{}, pathElem ...string) (rawResp rawRespon
return wd.Request(http.MethodPost, wd.concatURL(nil, pathElem...), bsJSON) return wd.Request(http.MethodPost, wd.concatURL(nil, pathElem...), bsJSON)
} }
func (wd *Session) DELETE(pathElem ...string) (rawResp rawResponse, err error) { func (wd *Session) DELETE(pathElem ...string) (rawResp DriverRawResponse, err error) {
return wd.Request(http.MethodDelete, wd.concatURL(nil, pathElem...), nil) return wd.Request(http.MethodDelete, wd.concatURL(nil, pathElem...), nil)
} }
func (wd *Session) Request(method string, rawURL string, rawBody []byte) (rawResp rawResponse, err error) { func (wd *Session) Request(method string, rawURL string, rawBody []byte) (rawResp DriverRawResponse, err error) {
driverResult := &DriverRequests{ driverResult := &DriverRequests{
RequestMethod: method, RequestMethod: method,
RequestUrl: rawURL, RequestUrl: rawURL,
@@ -179,7 +186,7 @@ func (wd *Session) Request(method string, rawURL string, rawBody []byte) (rawRes
return nil, err return nil, err
} }
if err = rawResp.checkErr(); err != nil { if err = rawResp.CheckErr(); err != nil {
if resp.StatusCode == http.StatusOK { if resp.StatusCode == http.StatusOK {
return rawResp, nil return rawResp, nil
} }
@@ -189,13 +196,22 @@ func (wd *Session) Request(method string, rawURL string, rawBody []byte) (rawRes
return return
} }
func convertToHTTPClient(conn net.Conn) *http.Client { func (wd *Session) InitConnection(localPort int) error {
conn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", localPort))
if err != nil {
return fmt.Errorf("create tcp connection error %v", err)
}
wd.client = NewHTTPClientWithConnection(conn, 30*time.Second)
return nil
}
func NewHTTPClientWithConnection(conn net.Conn, timeout time.Duration) *http.Client {
return &http.Client{ return &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
return conn, nil return conn, nil
}, },
}, },
Timeout: 30 * time.Second, Timeout: timeout,
} }
} }
+34 -42
View File
@@ -41,18 +41,19 @@ func NewHDCDriver(device *HarmonyDevice) (driver *HDCDriver, err error) {
return nil, err return nil, err
} }
driver.uiDriver = uiDriver driver.uiDriver = uiDriver
driver.NewSession(nil) driver.InitSession(nil)
return return
} }
func (hd *HDCDriver) NewSession(capabilities option.Capabilities) (Session, error) { func (hd *HDCDriver) InitSession(capabilities option.Capabilities) error {
hd.Reset() hd.Session = &Session{}
hd.Session.Reset()
hd.Unlock() hd.Unlock()
return Session{}, errDriverNotImplemented return nil
} }
func (hd *HDCDriver) DeleteSession() error { func (hd *HDCDriver) DeleteSession() error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) GetSession() *Session { func (hd *HDCDriver) GetSession() *Session {
@@ -60,7 +61,7 @@ func (hd *HDCDriver) GetSession() *Session {
} }
func (hd *HDCDriver) Status() (types.DeviceStatus, error) { func (hd *HDCDriver) Status() (types.DeviceStatus, error) {
return types.DeviceStatus{}, errDriverNotImplemented return types.DeviceStatus{}, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) GetDevice() IDevice { func (hd *HDCDriver) GetDevice() IDevice {
@@ -68,15 +69,15 @@ func (hd *HDCDriver) GetDevice() IDevice {
} }
func (hd *HDCDriver) DeviceInfo() (types.DeviceInfo, error) { func (hd *HDCDriver) DeviceInfo() (types.DeviceInfo, error) {
return types.DeviceInfo{}, errDriverNotImplemented return types.DeviceInfo{}, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) Location() (types.Location, error) { func (hd *HDCDriver) Location() (types.Location, error) {
return types.Location{}, errDriverNotImplemented return types.Location{}, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) BatteryInfo() (types.BatteryInfo, error) { func (hd *HDCDriver) BatteryInfo() (types.BatteryInfo, error) {
return types.BatteryInfo{}, errDriverNotImplemented return types.BatteryInfo{}, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) WindowSize() (size types.Size, err error) { func (hd *HDCDriver) WindowSize() (size types.Size, err error) {
@@ -91,7 +92,7 @@ func (hd *HDCDriver) WindowSize() (size types.Size, err error) {
} }
func (hd *HDCDriver) Screen() (ai.Screen, error) { func (hd *HDCDriver) Screen() (ai.Screen, error) {
return ai.Screen{}, errDriverNotImplemented return ai.Screen{}, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) Scale() (float64, error) { func (hd *HDCDriver) Scale() (float64, error) {
@@ -126,7 +127,7 @@ func (hd *HDCDriver) Unlock() (err error) {
func (hd *HDCDriver) AppLaunch(packageName string) error { func (hd *HDCDriver) AppLaunch(packageName string) error {
// Todo // Todo
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) AppTerminate(packageName string) (bool, error) { func (hd *HDCDriver) AppTerminate(packageName string) (bool, error) {
@@ -140,7 +141,7 @@ func (hd *HDCDriver) AppTerminate(packageName string) (bool, error) {
func (hd *HDCDriver) GetForegroundApp() (app types.AppInfo, err error) { func (hd *HDCDriver) GetForegroundApp() (app types.AppInfo, err error) {
// Todo // Todo
return types.AppInfo{}, errDriverNotImplemented return types.AppInfo{}, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) AssertForegroundApp(packageName string, activityType ...string) error { func (hd *HDCDriver) AssertForegroundApp(packageName string, activityType ...string) error {
@@ -149,11 +150,11 @@ func (hd *HDCDriver) AssertForegroundApp(packageName string, activityType ...str
} }
func (hd *HDCDriver) StartCamera() error { func (hd *HDCDriver) StartCamera() error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) StopCamera() error { func (hd *HDCDriver) StopCamera() error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) Orientation() (orientation types.Orientation, err error) { func (hd *HDCDriver) Orientation() (orientation types.Orientation, err error) {
@@ -178,15 +179,15 @@ func (hd *HDCDriver) Tap(x, y float64, opts ...option.ActionOption) error {
} }
func (hd *HDCDriver) DoubleTap(x, y float64, opts ...option.ActionOption) error { func (hd *HDCDriver) DoubleTap(x, y float64, opts ...option.ActionOption) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) TouchAndHold(x, y float64, opts ...option.ActionOption) (err error) { func (hd *HDCDriver) TouchAndHold(x, y float64, opts ...option.ActionOption) (err error) {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error { func (hd *HDCDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
// Swipe works like Drag, but `pressForDuration` value is 0 // Swipe works like Drag, but `pressForDuration` value is 0
@@ -215,15 +216,15 @@ func (hd *HDCDriver) Swipe(fromX, fromY, toX, toY float64, opts ...option.Action
} }
func (hd *HDCDriver) SetPasteboard(contentType types.PasteboardType, content string) error { func (hd *HDCDriver) SetPasteboard(contentType types.PasteboardType, content string) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes.Buffer, err error) { func (hd *HDCDriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes.Buffer, err error) {
return nil, errDriverNotImplemented return nil, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) SetIme(ime string) error { func (hd *HDCDriver) SetIme(ime string) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) SendKeys(text string, opts ...option.ActionOption) error { func (hd *HDCDriver) SendKeys(text string, opts ...option.ActionOption) error {
@@ -235,11 +236,11 @@ func (hd *HDCDriver) Input(text string, opts ...option.ActionOption) error {
} }
func (hd *HDCDriver) Clear(packageName string) error { func (hd *HDCDriver) Clear(packageName string) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) PressButton(devBtn types.DeviceButton) error { func (hd *HDCDriver) PressButton(devBtn types.DeviceButton) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) PressBack(opts ...option.ActionOption) error { func (hd *HDCDriver) PressBack(opts ...option.ActionOption) error {
@@ -251,7 +252,7 @@ func (hd *HDCDriver) Backspace(count int, opts ...option.ActionOption) (err erro
} }
func (hd *HDCDriver) PressKeyCode(keyCode KeyCode) (err error) { func (hd *HDCDriver) PressKeyCode(keyCode KeyCode) (err error) {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) PressHarmonyKeyCode(keyCode ghdc.KeyCode) (err error) { func (hd *HDCDriver) PressHarmonyKeyCode(keyCode ghdc.KeyCode) (err error) {
@@ -282,45 +283,36 @@ func (hd *HDCDriver) Source(srcOpt ...option.SourceOption) (string, error) {
return "", nil return "", nil
} }
func (hd *HDCDriver) LoginNoneUI(packageName, phoneNumber string, captcha, password string) (info AppLoginInfo, err error) {
err = errDriverNotImplemented
return
}
func (hd *HDCDriver) LogoutNoneUI(packageName string) error {
return errDriverNotImplemented
}
func (hd *HDCDriver) TapByText(text string, opts ...option.ActionOption) error { func (hd *HDCDriver) TapByText(text string, opts ...option.ActionOption) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) TapByTexts(actions ...TapTextAction) error { func (hd *HDCDriver) TapByTexts(actions ...TapTextAction) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) AccessibleSource() (string, error) { func (hd *HDCDriver) AccessibleSource() (string, error) {
return "", errDriverNotImplemented return "", types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) HealthCheck() error { func (hd *HDCDriver) HealthCheck() error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) GetAppiumSettings() (map[string]interface{}, error) { func (hd *HDCDriver) GetAppiumSettings() (map[string]interface{}, error) {
return nil, errDriverNotImplemented return nil, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) SetAppiumSettings(settings map[string]interface{}) (map[string]interface{}, error) { func (hd *HDCDriver) SetAppiumSettings(settings map[string]interface{}) (map[string]interface{}, error) {
return nil, errDriverNotImplemented return nil, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) IsHealthy() (bool, error) { func (hd *HDCDriver) IsHealthy() (bool, error) {
return false, errDriverNotImplemented return false, types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) StartCaptureLog(identifier ...string) (err error) { func (hd *HDCDriver) StartCaptureLog(identifier ...string) (err error) {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (hd *HDCDriver) StopCaptureLog() (result interface{}, err error) { func (hd *HDCDriver) StopCaptureLog() (result interface{}, err error) {
@@ -345,11 +337,11 @@ func (hd *HDCDriver) TearDown() error {
} }
func (hd *HDCDriver) Rotation() (rotation types.Rotation, err error) { func (hd *HDCDriver) Rotation() (rotation types.Rotation, err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
func (hd *HDCDriver) SetRotation(rotation types.Rotation) (err error) { func (hd *HDCDriver) SetRotation(rotation types.Rotation) (err error) {
err = errDriverNotImplemented err = types.ErrDriverNotImplemented
return return
} }
+15 -35
View File
@@ -228,35 +228,10 @@ func (dev *IOSDevice) getAppInfo(packageName string) (appInfo types.AppInfo, err
} }
func (dev *IOSDevice) NewDriver() (driverExt IDriverExt, err error) { func (dev *IOSDevice) NewDriver() (driverExt IDriverExt, err error) {
var driver IDriver driver, err := NewWDADriver(dev)
if dev.STUB { if err != nil {
driver, err = NewStubIOSDriver(dev) return nil, errors.Wrap(err, "failed to init WDA driver")
if err != nil {
return nil, errors.Wrap(err, "failed to init Stub driver")
}
} else {
driver, err := NewWDADriver(dev)
if err != nil {
return nil, errors.Wrap(err, "failed to init WDA driver")
}
settings, err := driver.SetAppiumSettings(map[string]interface{}{
"snapshotMaxDepth": dev.SnapshotMaxDepth,
"acceptAlertButtonSelector": dev.AcceptAlertButtonSelector,
})
if err != nil {
return nil, errors.Wrap(err, "failed to set appium WDA settings")
}
log.Info().Interface("appiumWDASettings", settings).Msg("set appium WDA settings")
} }
if dev.ResetHomeOnStartup {
log.Info().Msg("go back to home screen")
if err = driver.Homescreen(); err != nil {
return nil, errors.Wrap(code.MobileUIDriverError,
fmt.Sprintf("go back to home screen failed: %v", err))
}
}
settings, err := driver.SetAppiumSettings(map[string]interface{}{ settings, err := driver.SetAppiumSettings(map[string]interface{}{
"snapshotMaxDepth": dev.SnapshotMaxDepth, "snapshotMaxDepth": dev.SnapshotMaxDepth,
"acceptAlertButtonSelector": dev.AcceptAlertButtonSelector, "acceptAlertButtonSelector": dev.AcceptAlertButtonSelector,
@@ -266,6 +241,13 @@ func (dev *IOSDevice) NewDriver() (driverExt IDriverExt, err error) {
} }
log.Info().Interface("appiumWDASettings", settings).Msg("set appium WDA settings") log.Info().Interface("appiumWDASettings", settings).Msg("set appium WDA settings")
if dev.ResetHomeOnStartup {
log.Info().Msg("go back to home screen")
if err = driver.Homescreen(); err != nil {
return nil, errors.Wrap(code.MobileUIDriverError,
fmt.Sprintf("go back to home screen failed: %v", err))
}
}
if dev.LogOn { if dev.LogOn {
err = driver.StartCaptureLog("hrp_wda_log") err = driver.StartCaptureLog("hrp_wda_log")
if err != nil { if err != nil {
@@ -319,7 +301,7 @@ func (dev *IOSDevice) Uninstall(bundleId string) error {
return nil return nil
} }
func (dev *IOSDevice) forward(localPort, remotePort int) error { func (dev *IOSDevice) Forward(localPort, remotePort int) error {
if dev.listeners[localPort] != nil { if dev.listeners[localPort] != nil {
log.Warn().Msg(fmt.Sprintf("local port :%d is already in use", localPort)) log.Warn().Msg(fmt.Sprintf("local port :%d is already in use", localPort))
_ = dev.listeners[localPort].Close() _ = dev.listeners[localPort].Close()
@@ -521,7 +503,7 @@ func (dev *IOSDevice) NewHTTPDriver(capabilities option.Capabilities) (driver ID
return nil, errors.Wrap(code.DeviceHTTPDriverError, return nil, errors.Wrap(code.DeviceHTTPDriverError,
fmt.Sprintf("get free port failed: %v", err)) fmt.Sprintf("get free port failed: %v", err))
} }
if err = dev.forward(localPort, dev.WDAPort); err != nil { if err = dev.Forward(localPort, dev.WDAPort); err != nil {
return nil, errors.Wrap(code.DeviceHTTPDriverError, return nil, errors.Wrap(code.DeviceHTTPDriverError,
fmt.Sprintf("forward tcp port failed: %v", err)) fmt.Sprintf("forward tcp port failed: %v", err))
} }
@@ -537,7 +519,7 @@ func (dev *IOSDevice) NewHTTPDriver(capabilities option.Capabilities) (driver ID
return nil, errors.Wrap(code.DeviceHTTPDriverError, return nil, errors.Wrap(code.DeviceHTTPDriverError,
fmt.Sprintf("get free port failed: %v", err)) fmt.Sprintf("get free port failed: %v", err))
} }
if err = dev.forward(localMjpegPort, dev.WDAMjpegPort); err != nil { if err = dev.Forward(localMjpegPort, dev.WDAMjpegPort); err != nil {
return nil, errors.Wrap(code.DeviceHTTPDriverError, return nil, errors.Wrap(code.DeviceHTTPDriverError,
fmt.Sprintf("forward tcp port failed: %v", err)) fmt.Sprintf("forward tcp port failed: %v", err))
} }
@@ -563,11 +545,9 @@ func (dev *IOSDevice) NewHTTPDriver(capabilities option.Capabilities) (driver ID
} }
// create new session // create new session
var sessionInfo Session if err = wd.InitSession(capabilities); err != nil {
if sessionInfo, err = wd.NewSession(capabilities); err != nil {
return nil, errors.Wrap(code.DeviceHTTPDriverError, err.Error()) return nil, errors.Wrap(code.DeviceHTTPDriverError, err.Error())
} }
wd.sessionID = sessionInfo.sessionID
if wd.mjpegHTTPConn, err = net.Dial( if wd.mjpegHTTPConn, err = net.Dial(
"tcp", "tcp",
@@ -575,7 +555,7 @@ func (dev *IOSDevice) NewHTTPDriver(capabilities option.Capabilities) (driver ID
); err != nil { ); err != nil {
return nil, errors.Wrap(code.DeviceHTTPDriverError, err.Error()) return nil, errors.Wrap(code.DeviceHTTPDriverError, err.Error())
} }
wd.mjpegClient = convertToHTTPClient(wd.mjpegHTTPConn) wd.mjpegClient = NewHTTPClientWithConnection(wd.mjpegHTTPConn, 30*time.Second)
wd.mjpegUrl = fmt.Sprintf("%s:%d", host, localMjpegPort) wd.mjpegUrl = fmt.Sprintf("%s:%d", host, localMjpegPort)
// init WDA scale // init WDA scale
if wd.scale, err = wd.Scale(); err != nil { if wd.scale, err = wd.Scale(); err != nil {
+90 -96
View File
@@ -34,7 +34,7 @@ func NewWDADriver(device *IOSDevice) (*WDADriver, error) {
IOSDevice: device, IOSDevice: device,
Session: &Session{}, Session: &Session{},
} }
driver.NewSession(nil) driver.InitSession(nil)
return driver, nil return driver, nil
} }
@@ -63,16 +63,16 @@ func (wd *WDADriver) resetSession() error {
if err != nil { if err != nil {
return err return err
} }
sessionInfo, err := rawResp.valueConvertToSessionInfo() sessionInfo, err := rawResp.ValueConvertToSessionInfo()
if err != nil { if err != nil {
return err return err
} }
// update session ID // update session ID
wd.sessionID = sessionInfo.sessionID wd.ID = sessionInfo.ID
return nil return nil
} }
func (wd *WDADriver) httpRequest(method string, rawURL string, rawBody []byte) (rawResp rawResponse, err error) { func (wd *WDADriver) httpRequest(method string, rawURL string, rawBody []byte) (rawResp DriverRawResponse, err error) {
retryInterval := 3 * time.Second retryInterval := 3 * time.Second
for retryCount := 1; retryCount <= 3; retryCount++ { for retryCount := 1; retryCount <= 3; retryCount++ {
rawResp, err = wd.Request(method, rawURL, rawBody) rawResp, err = wd.Request(method, rawURL, rawBody)
@@ -92,25 +92,25 @@ func (wd *WDADriver) httpRequest(method string, rawURL string, rawBody []byte) (
retryInterval = retryInterval * 2 retryInterval = retryInterval * 2
time.Sleep(retryInterval) time.Sleep(retryInterval)
oldSessionID := wd.sessionID oldSessionID := wd.ID
if err2 := wd.resetSession(); err2 != nil { if err2 := wd.resetSession(); err2 != nil {
log.Err(err2).Msgf("failed to reset wda driver session, retry count: %v", retryCount) log.Err(err2).Msgf("failed to reset wda driver session, retry count: %v", retryCount)
continue continue
} }
log.Debug().Str("new session", wd.sessionID).Str("old session", oldSessionID). log.Debug().Str("new session", wd.ID).Str("old session", oldSessionID).
Msgf("reset wda driver session successfully, retry count: %v", retryCount) Msgf("reset wda driver session successfully, retry count: %v", retryCount)
if oldSessionID != "" { if oldSessionID != "" {
rawURL = strings.Replace(rawURL, oldSessionID, wd.sessionID, 1) rawURL = strings.Replace(rawURL, oldSessionID, wd.ID, 1)
} }
} }
return return
} }
func (wd *WDADriver) httpGET(pathElem ...string) (rawResp rawResponse, err error) { func (wd *WDADriver) httpGET(pathElem ...string) (rawResp DriverRawResponse, err error) {
return wd.httpRequest(http.MethodGet, wd.concatURL(nil, pathElem...), nil) return wd.httpRequest(http.MethodGet, wd.concatURL(nil, pathElem...), nil)
} }
func (wd *WDADriver) httpPOST(data interface{}, pathElem ...string) (rawResp rawResponse, err error) { func (wd *WDADriver) httpPOST(data interface{}, pathElem ...string) (rawResp DriverRawResponse, err error) {
var bsJSON []byte = nil var bsJSON []byte = nil
if data != nil { if data != nil {
if bsJSON, err = json.Marshal(data); err != nil { if bsJSON, err = json.Marshal(data); err != nil {
@@ -120,7 +120,7 @@ func (wd *WDADriver) httpPOST(data interface{}, pathElem ...string) (rawResp raw
return wd.httpRequest(http.MethodPost, wd.concatURL(nil, pathElem...), bsJSON) return wd.httpRequest(http.MethodPost, wd.concatURL(nil, pathElem...), bsJSON)
} }
func (wd *WDADriver) httpDELETE(pathElem ...string) (rawResp rawResponse, err error) { func (wd *WDADriver) httpDELETE(pathElem ...string) (rawResp DriverRawResponse, err error) {
return wd.httpRequest(http.MethodDelete, wd.concatURL(nil, pathElem...), nil) return wd.httpRequest(http.MethodDelete, wd.concatURL(nil, pathElem...), nil)
} }
@@ -128,7 +128,7 @@ func (wd *WDADriver) GetMjpegClient() *http.Client {
return wd.mjpegClient return wd.mjpegClient
} }
func (wd *WDADriver) NewSession(capabilities option.Capabilities) (sessionInfo Session, err error) { func (wd *WDADriver) InitSession(capabilities option.Capabilities) error {
// [[FBRoute POST:@"/session"].withoutSession respondWithTarget:self action:@selector(handleCreateSession:)] // [[FBRoute POST:@"/session"].withoutSession respondWithTarget:self action:@selector(handleCreateSession:)]
data := make(map[string]interface{}) data := make(map[string]interface{})
if len(capabilities) == 0 { if len(capabilities) == 0 {
@@ -139,14 +139,16 @@ func (wd *WDADriver) NewSession(capabilities option.Capabilities) (sessionInfo S
} }
} }
var rawResp rawResponse rawResp, err := wd.httpPOST(data, "/session")
if rawResp, err = wd.httpPOST(data, "/session"); err != nil { if err != nil {
return Session{}, err return err
} }
if sessionInfo, err = rawResp.valueConvertToSessionInfo(); err != nil { sessionInfo, err := rawResp.ValueConvertToSessionInfo()
return Session{}, err if err != nil {
return err
} }
return wd.Session = &sessionInfo
return nil
} }
func (wd *WDADriver) DeleteSession() (err error) { func (wd *WDADriver) DeleteSession() (err error) {
@@ -158,13 +160,13 @@ func (wd *WDADriver) DeleteSession() (err error) {
} }
// [[FBRoute DELETE:@""] respondWithTarget:self action:@selector(handleDeleteSession:)] // [[FBRoute DELETE:@""] respondWithTarget:self action:@selector(handleDeleteSession:)]
_, err = wd.httpDELETE("/session", wd.sessionID) _, err = wd.httpDELETE("/session", wd.ID)
return return
} }
func (wd *WDADriver) Status() (deviceStatus types.DeviceStatus, err error) { func (wd *WDADriver) Status() (deviceStatus types.DeviceStatus, err error) {
// [[FBRoute GET:@"/status"].withoutSession respondWithTarget:self action:@selector(handleGetStatus:)] // [[FBRoute GET:@"/status"].withoutSession respondWithTarget:self action:@selector(handleGetStatus:)]
var rawResp rawResponse var rawResp DriverRawResponse
// Notice: use Driver.GET instead of httpGET to avoid loop calling // Notice: use Driver.GET instead of httpGET to avoid loop calling
if rawResp, err = wd.GET("/status"); err != nil { if rawResp, err = wd.GET("/status"); err != nil {
return types.DeviceStatus{}, err return types.DeviceStatus{}, err
@@ -184,8 +186,8 @@ func (wd *WDADriver) GetDevice() IDevice {
func (wd *WDADriver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) { func (wd *WDADriver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) {
// [[FBRoute GET:@"/wda/device/info"] respondWithTarget:self action:@selector(handleGetDeviceInfo:)] // [[FBRoute GET:@"/wda/device/info"] respondWithTarget:self action:@selector(handleGetDeviceInfo:)]
// [[FBRoute GET:@"/wda/device/info"].withoutSession // [[FBRoute GET:@"/wda/device/info"].withoutSession
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/wda/device/info"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/wda/device/info"); err != nil {
return types.DeviceInfo{}, err return types.DeviceInfo{}, err
} }
reply := new(struct{ Value struct{ types.DeviceInfo } }) reply := new(struct{ Value struct{ types.DeviceInfo } })
@@ -199,8 +201,8 @@ func (wd *WDADriver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) {
func (wd *WDADriver) Location() (location types.Location, err error) { func (wd *WDADriver) Location() (location types.Location, err error) {
// [[FBRoute GET:@"/wda/device/location"] respondWithTarget:self action:@selector(handleGetLocation:)] // [[FBRoute GET:@"/wda/device/location"] respondWithTarget:self action:@selector(handleGetLocation:)]
// [[FBRoute GET:@"/wda/device/location"].withoutSession // [[FBRoute GET:@"/wda/device/location"].withoutSession
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/wda/device/location"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/wda/device/location"); err != nil {
return types.Location{}, err return types.Location{}, err
} }
reply := new(struct{ Value struct{ types.Location } }) reply := new(struct{ Value struct{ types.Location } })
@@ -213,8 +215,8 @@ func (wd *WDADriver) Location() (location types.Location, err error) {
func (wd *WDADriver) BatteryInfo() (batteryInfo types.BatteryInfo, err error) { func (wd *WDADriver) BatteryInfo() (batteryInfo types.BatteryInfo, err error) {
// [[FBRoute GET:@"/wda/batteryInfo"] respondWithTarget:self action:@selector(handleGetBatteryInfo:)] // [[FBRoute GET:@"/wda/batteryInfo"] respondWithTarget:self action:@selector(handleGetBatteryInfo:)]
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/wda/batteryInfo"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/wda/batteryInfo"); err != nil {
return types.BatteryInfo{}, err return types.BatteryInfo{}, err
} }
reply := new(struct{ Value struct{ types.BatteryInfo } }) reply := new(struct{ Value struct{ types.BatteryInfo } })
@@ -232,8 +234,8 @@ func (wd *WDADriver) WindowSize() (size types.Size, err error) {
return wd.windowSize, nil return wd.windowSize, nil
} }
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/window/size"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/window/size"); err != nil {
return types.Size{}, errors.Wrap(err, "get window size failed by WDA request") return types.Size{}, errors.Wrap(err, "get window size failed by WDA request")
} }
reply := new(struct{ Value struct{ types.Size } }) reply := new(struct{ Value struct{ types.Size } })
@@ -254,8 +256,8 @@ func (wd *WDADriver) WindowSize() (size types.Size, err error) {
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 rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/wda/screen"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/wda/screen"); err != nil {
return ai.Screen{}, err return ai.Screen{}, err
} }
reply := new(struct{ Value struct{ ai.Screen } }) reply := new(struct{ Value struct{ ai.Screen } })
@@ -285,8 +287,8 @@ func (wd *WDADriver) toScale(x float64) float64 {
func (wd *WDADriver) ActiveAppInfo() (info types.AppInfo, err error) { func (wd *WDADriver) ActiveAppInfo() (info types.AppInfo, err error) {
// [[FBRoute GET:@"/wda/activeAppInfo"] respondWithTarget:self action:@selector(handleActiveAppInfo:)] // [[FBRoute GET:@"/wda/activeAppInfo"] respondWithTarget:self action:@selector(handleActiveAppInfo:)]
// [[FBRoute GET:@"/wda/activeAppInfo"].withoutSession // [[FBRoute GET:@"/wda/activeAppInfo"].withoutSession
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/wda/activeAppInfo"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/wda/activeAppInfo"); err != nil {
return types.AppInfo{}, err return types.AppInfo{}, err
} }
reply := new(struct{ Value struct{ types.AppInfo } }) reply := new(struct{ Value struct{ types.AppInfo } })
@@ -299,8 +301,8 @@ func (wd *WDADriver) ActiveAppInfo() (info types.AppInfo, err error) {
func (wd *WDADriver) ActiveAppsList() (appsList []types.AppBaseInfo, err error) { func (wd *WDADriver) ActiveAppsList() (appsList []types.AppBaseInfo, err error) {
// [[FBRoute GET:@"/wda/apps/list"] respondWithTarget:self action:@selector(handleGetActiveAppsList:)] // [[FBRoute GET:@"/wda/apps/list"] respondWithTarget:self action:@selector(handleGetActiveAppsList:)]
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/wda/apps/list"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/wda/apps/list"); err != nil {
return nil, err return nil, err
} }
reply := new(struct{ Value []types.AppBaseInfo }) reply := new(struct{ Value []types.AppBaseInfo })
@@ -314,8 +316,8 @@ func (wd *WDADriver) ActiveAppsList() (appsList []types.AppBaseInfo, err error)
func (wd *WDADriver) AppState(bundleId string) (runState types.AppState, err error) { func (wd *WDADriver) AppState(bundleId string) (runState types.AppState, err error) {
// [[FBRoute POST:@"/wda/apps/state"] respondWithTarget:self action:@selector(handleSessionAppState:)] // [[FBRoute POST:@"/wda/apps/state"] respondWithTarget:self action:@selector(handleSessionAppState:)]
data := map[string]interface{}{"bundleId": bundleId} data := map[string]interface{}{"bundleId": bundleId}
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/apps/state"); err != nil { if rawResp, err = wd.httpPOST(data, "/session", wd.ID, "/wda/apps/state"); err != nil {
return 0, err return 0, err
} }
reply := new(struct{ Value types.AppState }) reply := new(struct{ Value types.AppState })
@@ -330,11 +332,11 @@ func (wd *WDADriver) AppState(bundleId string) (runState types.AppState, err err
func (wd *WDADriver) IsLocked() (locked bool, err error) { func (wd *WDADriver) IsLocked() (locked bool, err error) {
// [[FBRoute GET:@"/wda/locked"] respondWithTarget:self action:@selector(handleIsLocked:)] // [[FBRoute GET:@"/wda/locked"] respondWithTarget:self action:@selector(handleIsLocked:)]
// [[FBRoute GET:@"/wda/locked"].withoutSession // [[FBRoute GET:@"/wda/locked"].withoutSession
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/wda/locked"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/wda/locked"); err != nil {
return false, err return false, err
} }
if locked, err = rawResp.valueConvertToBool(); err != nil { if locked, err = rawResp.ValueConvertToBool(); err != nil {
return false, err return false, err
} }
return return
@@ -343,14 +345,14 @@ func (wd *WDADriver) IsLocked() (locked bool, err error) {
func (wd *WDADriver) Unlock() (err error) { func (wd *WDADriver) Unlock() (err error) {
// [[FBRoute POST:@"/wda/unlock"] respondWithTarget:self action:@selector(handleUnlock:)] // [[FBRoute POST:@"/wda/unlock"] respondWithTarget:self action:@selector(handleUnlock:)]
// [[FBRoute POST:@"/wda/unlock"].withoutSession // [[FBRoute POST:@"/wda/unlock"].withoutSession
_, err = wd.httpPOST(nil, "/session", wd.sessionID, "/wda/unlock") _, err = wd.httpPOST(nil, "/session", wd.ID, "/wda/unlock")
return return
} }
func (wd *WDADriver) Lock() (err error) { func (wd *WDADriver) Lock() (err error) {
// [[FBRoute POST:@"/wda/lock"] respondWithTarget:self action:@selector(handleLock:)] // [[FBRoute POST:@"/wda/lock"] respondWithTarget:self action:@selector(handleLock:)]
// [[FBRoute POST:@"/wda/lock"].withoutSession // [[FBRoute POST:@"/wda/lock"].withoutSession
_, err = wd.httpPOST(nil, "/session", wd.sessionID, "/wda/lock") _, err = wd.httpPOST(nil, "/session", wd.ID, "/wda/lock")
return return
} }
@@ -363,11 +365,11 @@ func (wd *WDADriver) Homescreen() (err error) {
func (wd *WDADriver) AlertText() (text string, err error) { func (wd *WDADriver) AlertText() (text string, err error) {
// [[FBRoute GET:@"/alert/text"] respondWithTarget:self action:@selector(handleAlertGetTextCommand:)] // [[FBRoute GET:@"/alert/text"] respondWithTarget:self action:@selector(handleAlertGetTextCommand:)]
// [[FBRoute GET:@"/alert/text"].withoutSession // [[FBRoute GET:@"/alert/text"].withoutSession
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/alert/text"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/alert/text"); err != nil {
return "", err return "", err
} }
if text, err = rawResp.valueConvertToString(); err != nil { if text, err = rawResp.ValueConvertToString(); err != nil {
return "", err return "", err
} }
return return
@@ -375,8 +377,8 @@ func (wd *WDADriver) AlertText() (text string, err error) {
func (wd *WDADriver) AlertButtons() (btnLabels []string, err error) { func (wd *WDADriver) AlertButtons() (btnLabels []string, err error) {
// [[FBRoute GET:@"/wda/alert/buttons"] respondWithTarget:self action:@selector(handleGetAlertButtonsCommand:)] // [[FBRoute GET:@"/wda/alert/buttons"] respondWithTarget:self action:@selector(handleGetAlertButtonsCommand:)]
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/wda/alert/buttons"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/wda/alert/buttons"); err != nil {
return nil, err return nil, err
} }
reply := new(struct{ Value []string }) reply := new(struct{ Value []string })
@@ -412,7 +414,7 @@ func (wd *WDADriver) AlertDismiss(label ...string) (err error) {
func (wd *WDADriver) AlertSendKeys(text string) (err error) { func (wd *WDADriver) AlertSendKeys(text string) (err error) {
// [[FBRoute POST:@"/alert/text"] respondWithTarget:self action:@selector(handleAlertSetTextCommand:)] // [[FBRoute POST:@"/alert/text"] respondWithTarget:self action:@selector(handleAlertSetTextCommand:)]
data := map[string]interface{}{"value": strings.Split(text, "")} data := map[string]interface{}{"value": strings.Split(text, "")}
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/alert/text") _, err = wd.httpPOST(data, "/session", wd.ID, "/alert/text")
return return
} }
@@ -423,7 +425,7 @@ func (wd *WDADriver) AppLaunch(bundleId string) (err error) {
data["environment"] = map[string]interface{}{ data["environment"] = map[string]interface{}{
"SHOW_EXPLORER": "NO", "SHOW_EXPLORER": "NO",
} }
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/apps/launch") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/apps/launch")
if err != nil { if err != nil {
return errors.Wrap(code.MobileUILaunchAppError, return errors.Wrap(code.MobileUILaunchAppError,
fmt.Sprintf("wda launch failed: %v", err)) fmt.Sprintf("wda launch failed: %v", err))
@@ -445,11 +447,11 @@ func (wd *WDADriver) AppLaunchUnattached(bundleId string) (err error) {
func (wd *WDADriver) AppTerminate(bundleId string) (successful bool, err error) { func (wd *WDADriver) AppTerminate(bundleId string) (successful bool, err error) {
// [[FBRoute POST:@"/wda/apps/terminate"] respondWithTarget:self action:@selector(handleSessionAppTerminate:)] // [[FBRoute POST:@"/wda/apps/terminate"] respondWithTarget:self action:@selector(handleSessionAppTerminate:)]
data := map[string]interface{}{"bundleId": bundleId} data := map[string]interface{}{"bundleId": bundleId}
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/apps/terminate"); err != nil { if rawResp, err = wd.httpPOST(data, "/session", wd.ID, "/wda/apps/terminate"); err != nil {
return false, err return false, err
} }
if successful, err = rawResp.valueConvertToBool(); err != nil { if successful, err = rawResp.ValueConvertToBool(); err != nil {
return false, err return false, err
} }
return return
@@ -458,7 +460,7 @@ func (wd *WDADriver) AppTerminate(bundleId string) (successful bool, err error)
func (wd *WDADriver) AppActivate(bundleId string) (err error) { func (wd *WDADriver) AppActivate(bundleId string) (err error) {
// [[FBRoute POST:@"/wda/apps/activate"] respondWithTarget:self action:@selector(handleSessionAppActivate:)] // [[FBRoute POST:@"/wda/apps/activate"] respondWithTarget:self action:@selector(handleSessionAppActivate:)]
data := map[string]interface{}{"bundleId": bundleId} data := map[string]interface{}{"bundleId": bundleId}
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/apps/activate") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/apps/activate")
return return
} }
@@ -468,7 +470,7 @@ func (wd *WDADriver) AppDeactivate(second float64) (err error) {
second = 3.0 second = 3.0
} }
data := map[string]interface{}{"duration": second} data := map[string]interface{}{"duration": second}
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/deactivateApp") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/deactivateApp")
return return
} }
@@ -539,7 +541,7 @@ func (wd *WDADriver) Tap(x, y float64, opts ...option.ActionOption) (err error)
// update data options in post data for extra WDA configurations // update data options in post data for extra WDA configurations
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/tap/0") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/tap/0")
return return
} }
@@ -559,7 +561,7 @@ func (wd *WDADriver) DoubleTap(x, y float64, opts ...option.ActionOption) (err e
"x": x, "x": x,
"y": y, "y": y,
} }
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/doubleTap") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/doubleTap")
return return
} }
@@ -603,7 +605,7 @@ func (wd *WDADriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionO
// update data options in post data for extra WDA configurations // update data options in post data for extra WDA configurations
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
// wda 43 version // wda 43 version
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/dragfromtoforduration") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/dragfromtoforduration")
// _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/drag") // _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/drag")
return return
} }
@@ -618,29 +620,29 @@ func (wd *WDADriver) SetPasteboard(contentType types.PasteboardType, content str
"contentType": contentType, "contentType": contentType,
"content": base64.StdEncoding.EncodeToString([]byte(content)), "content": base64.StdEncoding.EncodeToString([]byte(content)),
} }
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/setPasteboard") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/setPasteboard")
return return
} }
func (wd *WDADriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes.Buffer, err error) { func (wd *WDADriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes.Buffer, err error) {
// [[FBRoute POST:@"/wda/getPasteboard"] respondWithTarget:self action:@selector(handleGetPasteboard:)] // [[FBRoute POST:@"/wda/getPasteboard"] respondWithTarget:self action:@selector(handleGetPasteboard:)]
data := map[string]interface{}{"contentType": contentType} data := map[string]interface{}{"contentType": contentType}
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/getPasteboard"); err != nil { if rawResp, err = wd.httpPOST(data, "/session", wd.ID, "/wda/getPasteboard"); err != nil {
return nil, err return nil, err
} }
if raw, err = rawResp.valueDecodeAsBase64(); err != nil { if raw, err = rawResp.ValueDecodeAsBase64(); err != nil {
return nil, err return nil, err
} }
return return
} }
func (wd *WDADriver) SetIme(ime string) error { func (wd *WDADriver) SetIme(ime string) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (wd *WDADriver) PressKeyCode(keyCode KeyCode) (err error) { func (wd *WDADriver) PressKeyCode(keyCode KeyCode) (err error) {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (wd *WDADriver) SendKeys(text string, opts ...option.ActionOption) (err error) { func (wd *WDADriver) SendKeys(text string, opts ...option.ActionOption) (err error) {
@@ -651,7 +653,7 @@ func (wd *WDADriver) SendKeys(text string, opts ...option.ActionOption) (err err
// new data options in post data for extra WDA configurations // new data options in post data for extra WDA configurations
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/keys") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/keys")
return return
} }
@@ -674,7 +676,7 @@ func (wd *WDADriver) Input(text string, opts ...option.ActionOption) (err error)
} }
func (wd *WDADriver) Clear(packageName string) error { func (wd *WDADriver) Clear(packageName string) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
// PressBack simulates a short press on the BACK button. // PressBack simulates a short press on the BACK button.
@@ -710,25 +712,17 @@ func (wd *WDADriver) PressBack(opts ...option.ActionOption) (err error) {
// update data options in post data for extra WDA configurations // update data options in post data for extra WDA configurations
actionOptions.UpdateData(data) actionOptions.UpdateData(data)
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/dragfromtoforduration") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/dragfromtoforduration")
return return
} }
func (wd *WDADriver) PressButton(devBtn types.DeviceButton) (err error) { func (wd *WDADriver) PressButton(devBtn types.DeviceButton) (err error) {
// [[FBRoute POST:@"/wda/pressButton"] respondWithTarget:self action:@selector(handlePressButtonCommand:)] // [[FBRoute POST:@"/wda/pressButton"] respondWithTarget:self action:@selector(handlePressButtonCommand:)]
data := map[string]interface{}{"name": devBtn} data := map[string]interface{}{"name": devBtn}
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/wda/pressButton") _, err = wd.httpPOST(data, "/session", wd.ID, "/wda/pressButton")
return return
} }
func (wd *WDADriver) LoginNoneUI(packageName, phoneNumber string, captcha, password string) (info AppLoginInfo, err error) {
return info, errDriverNotImplemented
}
func (wd *WDADriver) LogoutNoneUI(packageName string) error {
return errDriverNotImplemented
}
func (wd *WDADriver) StartCamera() (err error) { func (wd *WDADriver) StartCamera() (err error) {
// start camera, alias for app_launch com.apple.camera // start camera, alias for app_launch com.apple.camera
return wd.AppLaunch("com.apple.camera") return wd.AppLaunch("com.apple.camera")
@@ -748,8 +742,8 @@ func (wd *WDADriver) StopCamera() (err error) {
func (wd *WDADriver) Orientation() (orientation types.Orientation, err error) { func (wd *WDADriver) Orientation() (orientation types.Orientation, err error) {
// [[FBRoute GET:@"/orientation"] respondWithTarget:self action:@selector(handleGetOrientation:)] // [[FBRoute GET:@"/orientation"] respondWithTarget:self action:@selector(handleGetOrientation:)]
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/orientation"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/orientation"); err != nil {
return "", err return "", err
} }
reply := new(struct{ Value types.Orientation }) reply := new(struct{ Value types.Orientation })
@@ -763,14 +757,14 @@ func (wd *WDADriver) Orientation() (orientation types.Orientation, err error) {
func (wd *WDADriver) SetOrientation(orientation types.Orientation) (err error) { func (wd *WDADriver) SetOrientation(orientation types.Orientation) (err error) {
// [[FBRoute POST:@"/orientation"] respondWithTarget:self action:@selector(handleSetOrientation:)] // [[FBRoute POST:@"/orientation"] respondWithTarget:self action:@selector(handleSetOrientation:)]
data := map[string]interface{}{"orientation": orientation} data := map[string]interface{}{"orientation": orientation}
_, err = wd.httpPOST(data, "/session", wd.sessionID, "/orientation") _, err = wd.httpPOST(data, "/session", wd.ID, "/orientation")
return return
} }
func (wd *WDADriver) Rotation() (rotation types.Rotation, err error) { func (wd *WDADriver) Rotation() (rotation types.Rotation, err error) {
// [[FBRoute GET:@"/rotation"] respondWithTarget:self action:@selector(handleGetRotation:)] // [[FBRoute GET:@"/rotation"] respondWithTarget:self action:@selector(handleGetRotation:)]
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/rotation"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/rotation"); err != nil {
return types.Rotation{}, err return types.Rotation{}, err
} }
reply := new(struct{ Value types.Rotation }) reply := new(struct{ Value types.Rotation })
@@ -783,20 +777,20 @@ func (wd *WDADriver) Rotation() (rotation types.Rotation, err error) {
func (wd *WDADriver) SetRotation(rotation types.Rotation) (err error) { func (wd *WDADriver) SetRotation(rotation types.Rotation) (err error) {
// [[FBRoute POST:@"/rotation"] respondWithTarget:self action:@selector(handleSetRotation:)] // [[FBRoute POST:@"/rotation"] respondWithTarget:self action:@selector(handleSetRotation:)]
_, err = wd.httpPOST(rotation, "/session", wd.sessionID, "/rotation") _, err = wd.httpPOST(rotation, "/session", wd.ID, "/rotation")
return return
} }
func (wd *WDADriver) Screenshot() (raw *bytes.Buffer, err error) { func (wd *WDADriver) Screenshot() (raw *bytes.Buffer, err error) {
// [[FBRoute GET:@"/screenshot"] respondWithTarget:self action:@selector(handleGetScreenshot:)] // [[FBRoute GET:@"/screenshot"] respondWithTarget:self action:@selector(handleGetScreenshot:)]
// [[FBRoute GET:@"/screenshot"].withoutSession respondWithTarget:self action:@selector(handleGetScreenshot:)] // [[FBRoute GET:@"/screenshot"].withoutSession respondWithTarget:self action:@selector(handleGetScreenshot:)]
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/screenshot"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/screenshot"); err != nil {
return nil, errors.Wrap(code.DeviceScreenShotError, return nil, errors.Wrap(code.DeviceScreenShotError,
fmt.Sprintf("get WDA screenshot data failed: %v", err)) fmt.Sprintf("get WDA screenshot data failed: %v", err))
} }
if raw, err = rawResp.valueDecodeAsBase64(); err != nil { if raw, err = rawResp.ValueDecodeAsBase64(); err != nil {
return nil, errors.Wrap(code.DeviceScreenShotError, return nil, errors.Wrap(code.DeviceScreenShotError,
fmt.Sprintf("decode WDA screenshot data failed: %v", err)) fmt.Sprintf("decode WDA screenshot data failed: %v", err))
} }
@@ -806,7 +800,7 @@ func (wd *WDADriver) Screenshot() (raw *bytes.Buffer, err error) {
func (wd *WDADriver) Source(srcOpt ...option.SourceOption) (source string, err error) { func (wd *WDADriver) Source(srcOpt ...option.SourceOption) (source string, err error) {
// [[FBRoute GET:@"/source"] respondWithTarget:self action:@selector(handleGetSourceCommand:)] // [[FBRoute GET:@"/source"] respondWithTarget:self action:@selector(handleGetSourceCommand:)]
// [[FBRoute GET:@"/source"].withoutSession // [[FBRoute GET:@"/source"].withoutSession
tmp, _ := url.Parse(wd.concatURL(nil, "/session", wd.sessionID)) tmp, _ := url.Parse(wd.concatURL(nil, "/session", wd.ID))
toJsonRaw := false toJsonRaw := false
if len(srcOpt) != 0 { if len(srcOpt) != 0 {
q := tmp.Query() q := tmp.Query()
@@ -820,40 +814,40 @@ func (wd *WDADriver) Source(srcOpt ...option.SourceOption) (source string, err e
tmp.RawQuery = q.Encode() tmp.RawQuery = q.Encode()
} }
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpRequest(http.MethodGet, wd.concatURL(tmp, "/source"), nil); err != nil { if rawResp, err = wd.httpRequest(http.MethodGet, wd.concatURL(tmp, "/source"), nil); err != nil {
return "", nil return "", nil
} }
if toJsonRaw { if toJsonRaw {
var jr builtinJSON.RawMessage var jr builtinJSON.RawMessage
if jr, err = rawResp.valueConvertToJsonRawMessage(); err != nil { if jr, err = rawResp.ValueConvertToJsonRawMessage(); err != nil {
return "", err return "", err
} }
return string(jr), nil return string(jr), nil
} }
if source, err = rawResp.valueConvertToString(); err != nil { if source, err = rawResp.ValueConvertToString(); err != nil {
return "", err return "", err
} }
return return
} }
func (wd *WDADriver) TapByText(text string, opts ...option.ActionOption) error { func (wd *WDADriver) TapByText(text string, opts ...option.ActionOption) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (wd *WDADriver) TapByTexts(actions ...TapTextAction) error { func (wd *WDADriver) TapByTexts(actions ...TapTextAction) error {
return errDriverNotImplemented return types.ErrDriverNotImplemented
} }
func (wd *WDADriver) AccessibleSource() (source string, err error) { func (wd *WDADriver) AccessibleSource() (source string, err error) {
// [[FBRoute GET:@"/wda/accessibleSource"] respondWithTarget:self action:@selector(handleGetAccessibleSourceCommand:)] // [[FBRoute GET:@"/wda/accessibleSource"] respondWithTarget:self action:@selector(handleGetAccessibleSourceCommand:)]
// [[FBRoute GET:@"/wda/accessibleSource"].withoutSession // [[FBRoute GET:@"/wda/accessibleSource"].withoutSession
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/wda/accessibleSource"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/wda/accessibleSource"); err != nil {
return "", err return "", err
} }
var jr builtinJSON.RawMessage var jr builtinJSON.RawMessage
if jr, err = rawResp.valueConvertToJsonRawMessage(); err != nil { if jr, err = rawResp.ValueConvertToJsonRawMessage(); err != nil {
return "", err return "", err
} }
source = string(jr) source = string(jr)
@@ -868,8 +862,8 @@ func (wd *WDADriver) HealthCheck() (err error) {
func (wd *WDADriver) GetAppiumSettings() (settings map[string]interface{}, err error) { func (wd *WDADriver) GetAppiumSettings() (settings map[string]interface{}, err error) {
// [[FBRoute GET:@"/appium/settings"] respondWithTarget:self action:@selector(handleGetSettings:)] // [[FBRoute GET:@"/appium/settings"] respondWithTarget:self action:@selector(handleGetSettings:)]
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/session", wd.sessionID, "/appium/settings"); err != nil { if rawResp, err = wd.httpGET("/session", wd.ID, "/appium/settings"); err != nil {
return nil, err return nil, err
} }
reply := new(struct{ Value map[string]interface{} }) reply := new(struct{ Value map[string]interface{} })
@@ -883,8 +877,8 @@ func (wd *WDADriver) GetAppiumSettings() (settings map[string]interface{}, err e
func (wd *WDADriver) SetAppiumSettings(settings map[string]interface{}) (ret map[string]interface{}, err error) { func (wd *WDADriver) SetAppiumSettings(settings map[string]interface{}) (ret map[string]interface{}, err error) {
// [[FBRoute POST:@"/appium/settings"] respondWithTarget:self action:@selector(handleSetSettings:)] // [[FBRoute POST:@"/appium/settings"] respondWithTarget:self action:@selector(handleSetSettings:)]
data := map[string]interface{}{"settings": settings} data := map[string]interface{}{"settings": settings}
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpPOST(data, "/session", wd.sessionID, "/appium/settings"); err != nil { if rawResp, err = wd.httpPOST(data, "/session", wd.ID, "/appium/settings"); err != nil {
return nil, err return nil, err
} }
reply := new(struct{ Value map[string]interface{} }) reply := new(struct{ Value map[string]interface{} })
@@ -896,7 +890,7 @@ func (wd *WDADriver) SetAppiumSettings(settings map[string]interface{}) (ret map
} }
func (wd *WDADriver) IsHealthy() (healthy bool, err error) { func (wd *WDADriver) IsHealthy() (healthy bool, err error) {
var rawResp rawResponse var rawResp DriverRawResponse
if rawResp, err = wd.httpGET("/health"); err != nil { if rawResp, err = wd.httpGET("/health"); err != nil {
return false, err return false, err
} }
-16
View File
@@ -4,7 +4,6 @@ import "github.com/httprunner/httprunner/v5/pkg/gadb"
type AndroidDeviceOptions struct { type AndroidDeviceOptions struct {
SerialNumber string `json:"serial,omitempty" yaml:"serial,omitempty"` SerialNumber string `json:"serial,omitempty" yaml:"serial,omitempty"`
STUB bool `json:"stub,omitempty" yaml:"stub,omitempty"` // use stub
LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"` LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"`
// adb // adb
@@ -23,9 +22,6 @@ func (dev *AndroidDeviceOptions) Options() (deviceOptions []AndroidDeviceOption)
if dev.SerialNumber != "" { if dev.SerialNumber != "" {
deviceOptions = append(deviceOptions, WithSerialNumber(dev.SerialNumber)) deviceOptions = append(deviceOptions, WithSerialNumber(dev.SerialNumber))
} }
if dev.STUB {
deviceOptions = append(deviceOptions, WithStub(true))
}
if dev.UIA2 { if dev.UIA2 {
deviceOptions = append(deviceOptions, WithUIA2(true)) deviceOptions = append(deviceOptions, WithUIA2(true))
} }
@@ -87,12 +83,6 @@ func NewAndroidDeviceOptions(opts ...AndroidDeviceOption) *AndroidDeviceOptions
type AndroidDeviceOption func(*AndroidDeviceOptions) type AndroidDeviceOption func(*AndroidDeviceOptions)
func WithDriverTypeADB() AndroidDeviceOption {
return func(device *AndroidDeviceOptions) {
device.STUB = false
}
}
func WithSerialNumber(serial string) AndroidDeviceOption { func WithSerialNumber(serial string) AndroidDeviceOption {
return func(device *AndroidDeviceOptions) { return func(device *AndroidDeviceOptions) {
device.SerialNumber = serial device.SerialNumber = serial
@@ -105,12 +95,6 @@ func WithUIA2(uia2On bool) AndroidDeviceOption {
} }
} }
func WithStub(stubOn bool) AndroidDeviceOption {
return func(device *AndroidDeviceOptions) {
device.STUB = stubOn
}
}
func WithUIA2IP(ip string) AndroidDeviceOption { func WithUIA2IP(ip string) AndroidDeviceOption {
return func(device *AndroidDeviceOptions) { return func(device *AndroidDeviceOptions) {
device.UIA2IP = ip device.UIA2IP = ip
-10
View File
@@ -4,7 +4,6 @@ type IOSDeviceOptions struct {
UDID string `json:"udid,omitempty" yaml:"udid,omitempty"` UDID string `json:"udid,omitempty" yaml:"udid,omitempty"`
WDAPort int `json:"port,omitempty" yaml:"port,omitempty"` // WDA remote port WDAPort int `json:"port,omitempty" yaml:"port,omitempty"` // WDA remote port
WDAMjpegPort int `json:"mjpeg_port,omitempty" yaml:"mjpeg_port,omitempty"` // WDA remote MJPEG port WDAMjpegPort int `json:"mjpeg_port,omitempty" yaml:"mjpeg_port,omitempty"` // WDA remote MJPEG port
STUB bool `json:"stub,omitempty" yaml:"stub,omitempty"` // use stub
LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"` LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"`
// switch to iOS springboard before init WDA session // switch to iOS springboard before init WDA session
@@ -26,9 +25,6 @@ func (dev *IOSDeviceOptions) Options() (deviceOptions []IOSDeviceOption) {
if dev.WDAMjpegPort != 0 { if dev.WDAMjpegPort != 0 {
deviceOptions = append(deviceOptions, WithWDAMjpegPort(dev.WDAMjpegPort)) deviceOptions = append(deviceOptions, WithWDAMjpegPort(dev.WDAMjpegPort))
} }
if dev.STUB {
deviceOptions = append(deviceOptions, WithIOSStub(true))
}
if dev.LogOn { if dev.LogOn {
deviceOptions = append(deviceOptions, WithWDALogOn(true)) deviceOptions = append(deviceOptions, WithWDALogOn(true))
} }
@@ -123,12 +119,6 @@ func WithWDALogOn(logOn bool) IOSDeviceOption {
} }
} }
func WithIOSStub(stub bool) IOSDeviceOption {
return func(device *IOSDeviceOptions) {
device.STUB = stub
}
}
func WithResetHomeOnStartup(reset bool) IOSDeviceOption { func WithResetHomeOnStartup(reset bool) IOSDeviceOption {
return func(device *IOSDeviceOptions) { return func(device *IOSDeviceOptions) {
device.ResetHomeOnStartup = reset device.ResetHomeOnStartup = reset
+5
View File
@@ -0,0 +1,5 @@
package types
import "errors"
var ErrDriverNotImplemented = errors.New("driver method not implemented")
+1 -2
View File
@@ -38,8 +38,7 @@ func handleDeviceContext() gin.HandlerFunc {
switch strings.ToLower(platform) { switch strings.ToLower(platform) {
case "android": case "android":
device, err := uixt.NewAndroidDevice( device, err := uixt.NewAndroidDevice(
option.WithSerialNumber(serial), option.WithSerialNumber(serial))
option.WithStub(true))
if err != nil { if err != nil {
log.Error().Err(err).Str("platform", platform).Str("serial", serial). log.Error().Err(err).Str("platform", platform).Str("serial", serial).
Msg("device not found") Msg("device not found")
+4 -4
View File
@@ -32,11 +32,11 @@ func NewServer(port int) error {
// get screen info // get screen info
apiV1PlatformSerial.GET("/screenshot", handleDeviceContext(), screenshotHandler) apiV1PlatformSerial.GET("/screenshot", handleDeviceContext(), screenshotHandler)
apiV1PlatformSerial.POST("/screenresult", handleDeviceContext(), screenResultHandler) apiV1PlatformSerial.POST("/screenresult", handleDeviceContext(), screenResultHandler)
apiV1PlatformSerial.GET("/stub/source", handleDeviceContext(), sourceHandler) apiV1PlatformSerial.GET("/shoots/source", handleDeviceContext(), sourceHandler)
apiV1PlatformSerial.GET("/adb/source", handleDeviceContext(), adbSourceHandler) apiV1PlatformSerial.GET("/adb/source", handleDeviceContext(), adbSourceHandler)
// Stub operations // shoots operations
apiV1PlatformSerial.POST("/stub/login", handleDeviceContext(), loginHandler) apiV1PlatformSerial.POST("/shoots/login", handleDeviceContext(), loginHandler)
apiV1PlatformSerial.POST("/stub/logout", handleDeviceContext(), logoutHandler) apiV1PlatformSerial.POST("/shoots/logout", handleDeviceContext(), logoutHandler)
// run uixt actions // run uixt actions
apiV1PlatformSerial.POST("/uixt/action", handleDeviceContext(), uixtActionHandler) apiV1PlatformSerial.POST("/uixt/action", handleDeviceContext(), uixtActionHandler)