mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 23:51:25 +08:00
refactor: move shoots driver to driver_ext
This commit is contained in:
@@ -1 +1 @@
|
|||||||
v5.0.0+2502091051
|
v5.0.0+2502101335
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -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
@@ -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
@@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var ErrDriverNotImplemented = errors.New("driver method not implemented")
|
||||||
+1
-2
@@ -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
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user