diff --git a/internal/version/VERSION b/internal/version/VERSION index be2916ae..14788e68 100644 --- a/internal/version/VERSION +++ b/internal/version/VERSION @@ -1 +1 @@ -v5.0.0+2502191654 +v5.0.0+2502191738 diff --git a/pkg/uixt/android_driver_uia2.go b/pkg/uixt/android_driver_uia2.go index c095801c..e58e12a0 100644 --- a/pkg/uixt/android_driver_uia2.go +++ b/pkg/uixt/android_driver_uia2.go @@ -121,7 +121,8 @@ func (ud *UIA2Driver) DeleteSession() (err error) { if ud.Session.ID == "" { return nil } - if _, err = ud.Session.DELETE("/session", ud.Session.ID); err == nil { + urlStr := fmt.Sprintf("/session/%s", ud.Session.ID) + if _, err = ud.Session.DELETE(urlStr); err == nil { ud.Session.ID = "" } @@ -150,7 +151,8 @@ func (ud *UIA2Driver) Status() (deviceStatus types.DeviceStatus, err error) { func (ud *UIA2Driver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) { // register(getHandler, new GetDeviceInfo("/wd/hub/session/:sessionId/appium/device/info")) var rawResp DriverRawResponse - if rawResp, err = ud.Session.GET("/session", ud.Session.ID, "appium/device/info"); err != nil { + urlStr := fmt.Sprintf("/session/%s/appium/device/info", ud.Session.ID) + if rawResp, err = ud.Session.GET(urlStr); err != nil { return types.DeviceInfo{}, err } reply := new(struct{ Value struct{ types.DeviceInfo } }) @@ -164,7 +166,8 @@ func (ud *UIA2Driver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) { func (ud *UIA2Driver) BatteryInfo() (batteryInfo types.BatteryInfo, err error) { // register(getHandler, new GetBatteryInfo("/wd/hub/session/:sessionId/appium/device/battery_info")) var rawResp DriverRawResponse - if rawResp, err = ud.Session.GET("/session", ud.Session.ID, "appium/device/battery_info"); err != nil { + urlStr := fmt.Sprintf("/session/%s/appium/device/battery_info", ud.Session.ID) + if rawResp, err = ud.Session.GET(urlStr); err != nil { return types.BatteryInfo{}, err } reply := new(struct{ Value struct{ types.BatteryInfo } }) @@ -186,7 +189,8 @@ func (ud *UIA2Driver) WindowSize() (size types.Size, err error) { } var rawResp DriverRawResponse - if rawResp, err = ud.Session.GET("/session", ud.Session.ID, "window/:windowHandle/size"); err != nil { + urlStr := fmt.Sprintf("/session/%s/window/:windowHandle/size", ud.Session.ID) + if rawResp, err = ud.Session.GET(urlStr); err != nil { return types.Size{}, errors.Wrap(err, "get window size failed by UIA2 request") } reply := new(struct{ Value struct{ types.Size } }) @@ -212,7 +216,8 @@ func (ud *UIA2Driver) WindowSize() (size types.Size, err error) { // Back simulates a short press on the BACK button. func (ud *UIA2Driver) Back() (err error) { // register(postHandler, new PressBack("/wd/hub/session/:sessionId/back")) - _, err = ud.Session.POST(nil, "/session", ud.Session.ID, "back") + urlStr := fmt.Sprintf("/session/%s/back", ud.Session.ID) + _, err = ud.Session.POST(nil, urlStr) return } @@ -227,14 +232,16 @@ func (ud *UIA2Driver) PressKeyCodes(keyCode KeyCode, metaState KeyMeta, flags .. if len(flags) != 0 { data["flags"] = flags[0] } - _, err = ud.Session.POST(data, "/session", ud.Session.ID, "appium/device/press_keycode") + urlStr := fmt.Sprintf("/session/%s/appium/device/press_keycode", ud.Session.ID) + _, err = ud.Session.POST(data, urlStr) return } func (ud *UIA2Driver) Orientation() (orientation types.Orientation, err error) { // [[FBRoute GET:@"/orientation"] respondWithTarget:self action:@selector(handleGetOrientation:)] var rawResp DriverRawResponse - if rawResp, err = ud.Session.GET("/session", ud.Session.ID, "/orientation"); err != nil { + urlStr := fmt.Sprintf("/session/%s/orientation", ud.Session.ID) + if rawResp, err = ud.Session.GET(urlStr); err != nil { return "", err } reply := new(struct{ Value types.Orientation }) @@ -270,7 +277,8 @@ func (ud *UIA2Driver) DoubleTapXY(x, y float64, opts ...option.ActionOption) err }, } - _, err = ud.Session.POST(data, "/session", ud.Session.ID, "actions/tap") + urlStr := fmt.Sprintf("/session/%s/actions/tap", ud.Session.ID) + _, err = ud.Session.POST(data, urlStr) return err } @@ -309,7 +317,8 @@ func (ud *UIA2Driver) TapAbsXY(x, y float64, opts ...option.ActionOption) error } option.MergeOptions(data, opts...) - _, err := ud.Session.POST(data, "/session", ud.Session.ID, "actions/tap") + urlStr := fmt.Sprintf("/session/%s/actions/tap", ud.Session.ID) + _, err := ud.Session.POST(data, urlStr) return err } @@ -328,7 +337,8 @@ func (ud *UIA2Driver) TouchAndHold(x, y float64, opts ...option.ActionOption) (e "duration": int(duration * 1000), }, } - _, err = ud.Session.POST(data, "/session", ud.Session.ID, "touch/longclick") + urlStr := fmt.Sprintf("/session/%s/touch/longclick", ud.Session.ID) + _, err = ud.Session.POST(data, urlStr) return } @@ -354,7 +364,8 @@ func (ud *UIA2Driver) Drag(fromX, fromY, toX, toY float64, opts ...option.Action option.MergeOptions(data, opts...) // register(postHandler, new Drag("/wd/hub/session/:sessionId/touch/drag")) - _, err = ud.Session.POST(data, "/session", ud.Session.ID, "touch/drag") + urlStr := fmt.Sprintf("/session/%s/touch/drag", ud.Session.ID) + _, err = ud.Session.POST(data, urlStr) return err } @@ -395,7 +406,8 @@ func (ud *UIA2Driver) Swipe(fromX, fromY, toX, toY float64, opts ...option.Actio } option.MergeOptions(data, opts...) - _, err = ud.Session.POST(data, "/session", ud.Session.ID, "actions/swipe") + urlStr := fmt.Sprintf("/session/%s/actions/swipe", ud.Session.ID) + _, err = ud.Session.POST(data, urlStr) return err } @@ -413,7 +425,8 @@ func (ud *UIA2Driver) SetPasteboard(contentType types.PasteboardType, content st "content": base64.StdEncoding.EncodeToString([]byte(content)), } // register(postHandler, new SetClipboard("/wd/hub/session/:sessionId/appium/device/set_clipboard")) - _, err = ud.Session.POST(data, "/session", ud.Session.ID, "appium/device/set_clipboard") + urlStr := fmt.Sprintf("/session/%s/appium/device/set_clipboard", ud.Session.ID) + _, err = ud.Session.POST(data, urlStr) return } @@ -426,7 +439,8 @@ func (ud *UIA2Driver) GetPasteboard(contentType types.PasteboardType) (raw *byte "contentType": contentType[0], } var rawResp DriverRawResponse - if rawResp, err = ud.Session.POST(data, "/session", ud.Session.ID, "appium/device/get_clipboard"); err != nil { + urlStr := fmt.Sprintf("/session/%s/appium/device/get_clipboard", ud.Session.ID) + if rawResp, err = ud.Session.POST(data, urlStr); err != nil { return } reply := new(struct{ Value string }) @@ -455,7 +469,8 @@ func (ud *UIA2Driver) Input(text string, opts ...option.ActionOption) (err error "text": text, } option.MergeOptions(data, opts...) - _, err = ud.Session.POST(data, "/session", ud.Session.ID, "/keys") + urlStr := fmt.Sprintf("/session/%s/keys", ud.Session.ID) + _, err = ud.Session.POST(data, urlStr) return } @@ -510,14 +525,16 @@ func (ud *UIA2Driver) SendActionKey(text string, opts ...option.ActionOption) (e } option.MergeOptions(data, opts...) - _, err = ud.Session.POST(data, "/session", ud.Session.ID, "/actions/keys") + urlStr := fmt.Sprintf("/session/%s/actions/keys", ud.Session.ID) + _, err = ud.Session.POST(data, urlStr) return } func (ud *UIA2Driver) Rotation() (rotation types.Rotation, err error) { // register(getHandler, new GetRotation("/wd/hub/session/:sessionId/rotation")) var rawResp DriverRawResponse - if rawResp, err = ud.Session.GET("/session", ud.Session.ID, "rotation"); err != nil { + urlStr := fmt.Sprintf("/session/%s/rotation", ud.Session.ID) + if rawResp, err = ud.Session.GET(urlStr); err != nil { return types.Rotation{}, err } reply := new(struct{ Value types.Rotation }) @@ -538,7 +555,8 @@ func (ud *UIA2Driver) ScreenShot(opts ...option.ActionOption) (raw *bytes.Buffer func (ud *UIA2Driver) Source(srcOpt ...option.SourceOption) (source string, err error) { // register(getHandler, new Source("/wd/hub/session/:sessionId/source")) var rawResp DriverRawResponse - if rawResp, err = ud.Session.GET("/session", ud.Session.ID, "source"); err != nil { + urlStr := fmt.Sprintf("/session/%s/source", ud.Session.ID) + if rawResp, err = ud.Session.GET(urlStr); err != nil { return "", err } reply := new(struct{ Value string }) diff --git a/pkg/uixt/driver_session.go b/pkg/uixt/driver_session.go index 031f3727..195b7833 100644 --- a/pkg/uixt/driver_session.go +++ b/pkg/uixt/driver_session.go @@ -87,8 +87,8 @@ func (s *DriverSession) History() []*DriverRequests { return s.requests } -func (s *DriverSession) concatURL(elem ...string) (string, error) { - if len(elem) == 0 { +func (s *DriverSession) concatURL(urlStr string) (string, error) { + if urlStr == "" || urlStr == "/" { if s.baseUrl == "" { return "", fmt.Errorf("base URL is empty") } @@ -96,14 +96,11 @@ func (s *DriverSession) concatURL(elem ...string) (string, error) { } // 处理完整 URL - if strings.HasPrefix(elem[0], "http://") || strings.HasPrefix(elem[0], "https://") { - u, err := url.Parse(elem[0]) + if strings.HasPrefix(urlStr, "http://") || strings.HasPrefix(urlStr, "https://") { + u, err := url.Parse(urlStr) if err != nil { return "", fmt.Errorf("failed to parse URL: %w", err) } - if len(elem) > 1 { - u.Path = path.Join(u.Path, path.Join(elem[1:]...)) - } return u.String(), nil } @@ -116,55 +113,25 @@ func (s *DriverSession) concatURL(elem ...string) (string, error) { return "", fmt.Errorf("failed to parse base URL: %w", err) } - // 保存原始查询参数 - baseQuery := u.Query() - // 处理路径和查询参数 - var paths []string - for i, e := range elem { - if i == len(elem)-1 { - // 处理最后一个元素的查询参数 - parts := strings.SplitN(e, "?", 2) - paths = append(paths, parts[0]) - if len(parts) > 1 { - newQuery, err := url.ParseQuery(parts[1]) - if err != nil { - return "", fmt.Errorf("failed to parse query params: %w", err) - } - // 合并查询参数 - for k, v := range newQuery { - baseQuery[k] = v - } - } - } else { - paths = append(paths, e) + parts := strings.SplitN(urlStr, "?", 2) + u.Path = path.Join(u.Path, parts[0]) + if len(parts) > 1 { + query, err := url.ParseQuery(parts[1]) + if err != nil { + return "", fmt.Errorf("failed to parse query params: %w", err) } - } - - // 合并路径 - u.Path = path.Join(append([]string{u.Path}, paths...)...) - - // 设置合并后的查询参数 - if len(baseQuery) > 0 { - u.RawQuery = baseQuery.Encode() + u.RawQuery = query.Encode() } return u.String(), nil } -func (s *DriverSession) GET(pathElem ...string) (rawResp DriverRawResponse, err error) { - urlStr, err := s.concatURL(pathElem...) - if err != nil { - return nil, err - } +func (s *DriverSession) GET(urlStr string) (rawResp DriverRawResponse, err error) { return s.RequestWithRetry(http.MethodGet, urlStr, nil) } -func (s *DriverSession) POST(data interface{}, pathElem ...string) (rawResp DriverRawResponse, err error) { - urlStr, err := s.concatURL(pathElem...) - if err != nil { - return nil, err - } +func (s *DriverSession) POST(data interface{}, urlStr string) (rawResp DriverRawResponse, err error) { var bsJSON []byte = nil if data != nil { if bsJSON, err = json.Marshal(data); err != nil { @@ -174,18 +141,14 @@ func (s *DriverSession) POST(data interface{}, pathElem ...string) (rawResp Driv return s.RequestWithRetry(http.MethodPost, urlStr, bsJSON) } -func (s *DriverSession) DELETE(pathElem ...string) (rawResp DriverRawResponse, err error) { - urlStr, err := s.concatURL(pathElem...) - if err != nil { - return nil, err - } +func (s *DriverSession) DELETE(urlStr string) (rawResp DriverRawResponse, err error) { return s.RequestWithRetry(http.MethodDelete, urlStr, nil) } -func (s *DriverSession) RequestWithRetry(method string, rawURL string, rawBody []byte) ( +func (s *DriverSession) RequestWithRetry(method string, urlStr string, rawBody []byte) ( rawResp DriverRawResponse, err error) { for count := 1; count <= s.maxRetry; count++ { - rawResp, err = s.Request(method, rawURL, rawBody) + rawResp, err = s.Request(method, urlStr, rawBody) if err == nil { return } @@ -205,8 +168,15 @@ func (s *DriverSession) RequestWithRetry(method string, rawURL string, rawBody [ return } -func (s *DriverSession) Request(method string, rawURL string, rawBody []byte) ( +func (s *DriverSession) Request(method string, urlStr string, rawBody []byte) ( rawResp DriverRawResponse, err error) { + + // concat url with base url + rawURL, err := s.concatURL(urlStr) + if err != nil { + return nil, err + } + driverResult := &DriverRequests{ RequestMethod: method, RequestUrl: rawURL, diff --git a/pkg/uixt/driver_session_test.go b/pkg/uixt/driver_session_test.go index a846cb6d..b64708c3 100644 --- a/pkg/uixt/driver_session_test.go +++ b/pkg/uixt/driver_session_test.go @@ -10,82 +10,101 @@ func TestDriverSession_concatURL(t *testing.T) { tests := []struct { name string baseUrl string - elem []string + urlStr string want string wantErr bool errMsg string }{ { - name: "empty elements with empty base url", + name: "empty url with empty base url", baseUrl: "", - elem: []string{}, + urlStr: "", wantErr: true, errMsg: "base URL is empty", }, { - name: "empty elements with valid base url", + name: "empty url with valid base url", baseUrl: "http://localhost:8080", - elem: []string{}, + urlStr: "", want: "http://localhost:8080", }, { - name: "absolute url in first element", + name: "root path with empty base url", + baseUrl: "", + urlStr: "/", + wantErr: true, + errMsg: "base URL is empty", + }, + { + name: "root path with valid base url", baseUrl: "http://localhost:8080", - elem: []string{"https://example.com/api", "users"}, - want: "https://example.com/api/users", + urlStr: "/", + want: "http://localhost:8080", + }, + { + name: "absolute http url", + baseUrl: "http://localhost:8080", + urlStr: "http://example.com/api", + want: "http://example.com/api", + }, + { + name: "absolute https url", + baseUrl: "http://localhost:8080", + urlStr: "https://example.com/api", + want: "https://example.com/api", }, { name: "invalid absolute url", baseUrl: "http://localhost:8080", - elem: []string{"http://[invalid-url", "users"}, + urlStr: "http://[invalid-url", wantErr: true, errMsg: "failed to parse URL", }, { name: "relative path with empty base url", baseUrl: "", - elem: []string{"api", "users"}, + urlStr: "api/users", wantErr: true, errMsg: "base URL is empty", }, { name: "relative path with invalid base url", baseUrl: "http://[invalid-url", - elem: []string{"api", "users"}, + urlStr: "api/users", wantErr: true, errMsg: "failed to parse base URL", }, + { + name: "relative path with valid base url", + baseUrl: "http://localhost:8080", + urlStr: "api/users", + want: "http://localhost:8080/api/users", + }, { name: "relative path with query params", baseUrl: "http://localhost:8080", - elem: []string{"api", "users?id=1&name=test"}, + urlStr: "api/users?id=1&name=test", want: "http://localhost:8080/api/users?id=1&name=test", }, { name: "base url with query params", baseUrl: "http://localhost:8080?token=123", - elem: []string{"api", "users?id=1"}, - want: "http://localhost:8080/api/users?id=1&token=123", + urlStr: "api/users?id=1", + want: "http://localhost:8080/api/users?id=1", }, { name: "invalid query params", baseUrl: "http://localhost:8080", - elem: []string{"api", "users?id=%invalid"}, + urlStr: "api/users?id=%invalid", wantErr: true, errMsg: "failed to parse query params", }, - { - name: "multiple path segments", - baseUrl: "http://localhost:8080", - elem: []string{"api", "v1", "users", "profile"}, - want: "http://localhost:8080/api/v1/users/profile", - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { s := &DriverSession{baseUrl: tt.baseUrl} - got, err := s.concatURL(tt.elem...) + got, err := s.concatURL(tt.urlStr) if tt.wantErr { assert.Error(t, err) diff --git a/pkg/uixt/ios_driver_wda.go b/pkg/uixt/ios_driver_wda.go index 9ad387f2..9391cf17 100644 --- a/pkg/uixt/ios_driver_wda.go +++ b/pkg/uixt/ios_driver_wda.go @@ -187,7 +187,8 @@ func (wd *WDADriver) DeleteSession() (err error) { } // [[FBRoute DELETE:@""] respondWithTarget:self action:@selector(handleDeleteSession:)] - _, err = wd.Session.DELETE("/session", wd.Session.ID) + urlStr := fmt.Sprintf("/session/%s", wd.Session.ID) + _, err = wd.Session.DELETE(urlStr) wd.Session.ID = "" wd.Session.client.CloseIdleConnections() return @@ -216,7 +217,8 @@ func (wd *WDADriver) DeviceInfo() (deviceInfo types.DeviceInfo, err error) { // [[FBRoute GET:@"/wda/device/info"] respondWithTarget:self action:@selector(handleGetDeviceInfo:)] // [[FBRoute GET:@"/wda/device/info"].withoutSession var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/wda/device/info"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/device/info", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return types.DeviceInfo{}, err } reply := new(struct{ Value struct{ types.DeviceInfo } }) @@ -231,7 +233,8 @@ func (wd *WDADriver) Location() (location types.Location, err error) { // [[FBRoute GET:@"/wda/device/location"] respondWithTarget:self action:@selector(handleGetLocation:)] // [[FBRoute GET:@"/wda/device/location"].withoutSession var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/wda/device/location"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/device/location", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return types.Location{}, err } reply := new(struct{ Value struct{ types.Location } }) @@ -245,7 +248,8 @@ func (wd *WDADriver) Location() (location types.Location, err error) { func (wd *WDADriver) BatteryInfo() (batteryInfo types.BatteryInfo, err error) { // [[FBRoute GET:@"/wda/batteryInfo"] respondWithTarget:self action:@selector(handleGetBatteryInfo:)] var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/wda/batteryInfo"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/batteryInfo", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return types.BatteryInfo{}, err } reply := new(struct{ Value struct{ types.BatteryInfo } }) @@ -264,7 +268,8 @@ func (wd *WDADriver) WindowSize() (size types.Size, err error) { } var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/window/size"); err != nil { + urlStr := fmt.Sprintf("/session/%s/window/size", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return types.Size{}, errors.Wrap(err, "get window size failed by WDA request") } reply := new(struct{ Value struct{ types.Size } }) @@ -303,7 +308,8 @@ type Screen struct { func (wd *WDADriver) Screen() (screen Screen, err error) { // [[FBRoute GET:@"/wda/screen"] respondWithTarget:self action:@selector(handleGetScreen:)] var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/wda/screen"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/screen", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return Screen{}, err } reply := new(struct{ Value struct{ Screen } }) @@ -317,7 +323,8 @@ func (wd *WDADriver) Screen() (screen Screen, err error) { func (wd *WDADriver) ScreenShot(opts ...option.ActionOption) (raw *bytes.Buffer, err error) { // [[FBRoute GET:@"/screenshot"] respondWithTarget:self action:@selector(handleGetScreenshot:)] // [[FBRoute GET:@"/screenshot"].withoutSession respondWithTarget:self action:@selector(handleGetScreenshot:)] - rawResp, err := wd.Session.GET("/session", wd.Session.ID, "/screenshot") + urlStr := fmt.Sprintf("/session/%s/screenshot", wd.Session.ID) + rawResp, err := wd.Session.GET(urlStr) if err != nil { return nil, errors.Wrap(code.DeviceScreenShotError, fmt.Sprintf("WDA screenshot failed %v", err)) @@ -350,7 +357,8 @@ func (wd *WDADriver) ActiveAppInfo() (info types.AppInfo, err error) { // [[FBRoute GET:@"/wda/activeAppInfo"] respondWithTarget:self action:@selector(handleActiveAppInfo:)] // [[FBRoute GET:@"/wda/activeAppInfo"].withoutSession var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/wda/activeAppInfo"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/activeAppInfo", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return types.AppInfo{}, err } reply := new(struct{ Value struct{ types.AppInfo } }) @@ -364,7 +372,8 @@ func (wd *WDADriver) ActiveAppInfo() (info types.AppInfo, err error) { func (wd *WDADriver) ActiveAppsList() (appsList []types.AppBaseInfo, err error) { // [[FBRoute GET:@"/wda/apps/list"] respondWithTarget:self action:@selector(handleGetActiveAppsList:)] var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/wda/apps/list"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/apps/list", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return nil, err } reply := new(struct{ Value []types.AppBaseInfo }) @@ -379,7 +388,8 @@ func (wd *WDADriver) AppState(bundleId string) (runState types.AppState, err err // [[FBRoute POST:@"/wda/apps/state"] respondWithTarget:self action:@selector(handleSessionAppState:)] data := map[string]interface{}{"bundleId": bundleId} var rawResp DriverRawResponse - if rawResp, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/apps/state"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/apps/state", wd.Session.ID) + if rawResp, err = wd.Session.POST(data, urlStr); err != nil { return 0, err } reply := new(struct{ Value types.AppState }) @@ -395,7 +405,8 @@ func (wd *WDADriver) IsLocked() (locked bool, err error) { // [[FBRoute GET:@"/wda/locked"] respondWithTarget:self action:@selector(handleIsLocked:)] // [[FBRoute GET:@"/wda/locked"].withoutSession var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/wda/locked"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/locked", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return false, err } if locked, err = rawResp.ValueConvertToBool(); err != nil { @@ -407,14 +418,16 @@ func (wd *WDADriver) IsLocked() (locked bool, err error) { func (wd *WDADriver) Unlock() (err error) { // [[FBRoute POST:@"/wda/unlock"] respondWithTarget:self action:@selector(handleUnlock:)] // [[FBRoute POST:@"/wda/unlock"].withoutSession - _, err = wd.Session.POST(nil, "/session", wd.Session.ID, "/wda/unlock") + urlStr := fmt.Sprintf("/session/%s/wda/unlock", wd.Session.ID) + _, err = wd.Session.POST(nil, urlStr) return } func (wd *WDADriver) Lock() (err error) { // [[FBRoute POST:@"/wda/lock"] respondWithTarget:self action:@selector(handleLock:)] // [[FBRoute POST:@"/wda/lock"].withoutSession - _, err = wd.Session.POST(nil, "/session", wd.Session.ID, "/wda/lock") + urlStr := fmt.Sprintf("/session/%s/wda/lock", wd.Session.ID) + _, err = wd.Session.POST(nil, urlStr) return } @@ -428,7 +441,8 @@ func (wd *WDADriver) AlertText() (text string, err error) { // [[FBRoute GET:@"/alert/text"] respondWithTarget:self action:@selector(handleAlertGetTextCommand:)] // [[FBRoute GET:@"/alert/text"].withoutSession var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/alert/text"); err != nil { + urlStr := fmt.Sprintf("/session/%s/alert/text", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return "", err } if text, err = rawResp.ValueConvertToString(); err != nil { @@ -440,7 +454,8 @@ func (wd *WDADriver) AlertText() (text string, err error) { func (wd *WDADriver) AlertButtons() (btnLabels []string, err error) { // [[FBRoute GET:@"/wda/alert/buttons"] respondWithTarget:self action:@selector(handleGetAlertButtonsCommand:)] var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/wda/alert/buttons"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/alert/buttons", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return nil, err } reply := new(struct{ Value []string }) @@ -476,7 +491,8 @@ func (wd *WDADriver) AlertDismiss(label ...string) (err error) { func (wd *WDADriver) AlertSendKeys(text string) (err error) { // [[FBRoute POST:@"/alert/text"] respondWithTarget:self action:@selector(handleAlertSetTextCommand:)] data := map[string]interface{}{"value": strings.Split(text, "")} - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/alert/text") + urlStr := fmt.Sprintf("/session/%s/alert/text", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) return } @@ -487,7 +503,8 @@ func (wd *WDADriver) AppLaunch(bundleId string) (err error) { data["environment"] = map[string]interface{}{ "SHOW_EXPLORER": "NO", } - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/apps/launch") + urlStr := fmt.Sprintf("/session/%s/wda/apps/launch", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) if err != nil { return errors.Wrap(code.MobileUILaunchAppError, fmt.Sprintf("wda launch failed: %v", err)) @@ -510,7 +527,8 @@ func (wd *WDADriver) AppTerminate(bundleId string) (successful bool, err error) // [[FBRoute POST:@"/wda/apps/terminate"] respondWithTarget:self action:@selector(handleSessionAppTerminate:)] data := map[string]interface{}{"bundleId": bundleId} var rawResp DriverRawResponse - if rawResp, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/apps/terminate"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/apps/terminate", wd.Session.ID) + if rawResp, err = wd.Session.POST(data, urlStr); err != nil { return false, err } if successful, err = rawResp.ValueConvertToBool(); err != nil { @@ -522,7 +540,8 @@ func (wd *WDADriver) AppTerminate(bundleId string) (successful bool, err error) func (wd *WDADriver) AppActivate(bundleId string) (err error) { // [[FBRoute POST:@"/wda/apps/activate"] respondWithTarget:self action:@selector(handleSessionAppActivate:)] data := map[string]interface{}{"bundleId": bundleId} - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/apps/activate") + urlStr := fmt.Sprintf("/session/%s/wda/apps/activate", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) return } @@ -532,7 +551,8 @@ func (wd *WDADriver) AppDeactivate(second float64) (err error) { second = 3.0 } data := map[string]interface{}{"duration": second} - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/deactivateApp") + urlStr := fmt.Sprintf("/session/%s/wda/deactivateApp", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) return } @@ -579,7 +599,8 @@ func (wd *WDADriver) TapAbsXY(x, y float64, opts ...option.ActionOption) error { } option.MergeOptions(data, opts...) - _, err := wd.Session.POST(data, "/session", wd.Session.ID, "/wda/tap/0") + urlStr := fmt.Sprintf("/session/%s/wda/tap/0", wd.Session.ID) + _, err := wd.Session.POST(data, urlStr) return err } @@ -598,7 +619,8 @@ func (wd *WDADriver) DoubleTapXY(x, y float64, opts ...option.ActionOption) erro "x": x, "y": y, } - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/doubleTap") + urlStr := fmt.Sprintf("/session/%s/wda/doubleTap", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) return err } @@ -634,7 +656,8 @@ func (wd *WDADriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionO } option.MergeOptions(data, opts...) // wda 43 version - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/dragfromtoforduration") + urlStr := fmt.Sprintf("/session/%s/wda/dragfromtoforduration", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) // _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/drag") return err } @@ -649,7 +672,8 @@ func (wd *WDADriver) SetPasteboard(contentType types.PasteboardType, content str "contentType": contentType, "content": base64.StdEncoding.EncodeToString([]byte(content)), } - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/setPasteboard") + urlStr := fmt.Sprintf("/session/%s/wda/setPasteboard", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) return } @@ -657,7 +681,8 @@ func (wd *WDADriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes // [[FBRoute POST:@"/wda/getPasteboard"] respondWithTarget:self action:@selector(handleGetPasteboard:)] data := map[string]interface{}{"contentType": contentType} var rawResp DriverRawResponse - if rawResp, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/getPasteboard"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/getPasteboard", wd.Session.ID) + if rawResp, err = wd.Session.POST(data, urlStr); err != nil { return nil, err } if raw, err = rawResp.ValueDecodeAsBase64(); err != nil { @@ -674,7 +699,8 @@ func (wd *WDADriver) Input(text string, opts ...option.ActionOption) (err error) // [[FBRoute POST:@"/wda/keys"] respondWithTarget:self action:@selector(handleKeys:)] data := map[string]interface{}{"value": strings.Split(text, "")} option.MergeOptions(data, opts...) - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/keys") + urlStr := fmt.Sprintf("/session/%s/wda/keys", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) return } @@ -694,37 +720,22 @@ func (wd *WDADriver) AppClear(packageName string) error { // Back simulates a short press on the BACK button. func (wd *WDADriver) Back() (err error) { - windowSize, err := wd.WindowSize() - if err != nil { - return - } - fromX := wd.toScale(float64(windowSize.Width) * 0) - fromY := wd.toScale(float64(windowSize.Height) * 0.5) - toX := wd.toScale(float64(windowSize.Width) * 0.6) - toY := wd.toScale(float64(windowSize.Height) * 0.5) - - data := map[string]interface{}{ - "fromX": fromX, - "fromY": fromY, - "toX": toX, - "toY": toY, - } - - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/dragfromtoforduration") - return + return wd.Swipe(0, 0.5, 0.6, 0.5) } func (wd *WDADriver) PressButton(devBtn types.DeviceButton) (err error) { // [[FBRoute POST:@"/wda/pressButton"] respondWithTarget:self action:@selector(handlePressButtonCommand:)] data := map[string]interface{}{"name": devBtn} - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/wda/pressButton") + urlStr := fmt.Sprintf("/session/%s/wda/pressButton", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) return } func (wd *WDADriver) Orientation() (orientation types.Orientation, err error) { // [[FBRoute GET:@"/orientation"] respondWithTarget:self action:@selector(handleGetOrientation:)] var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/orientation"); err != nil { + urlStr := fmt.Sprintf("/session/%s/orientation", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return "", err } reply := new(struct{ Value types.Orientation }) @@ -738,14 +749,16 @@ func (wd *WDADriver) Orientation() (orientation types.Orientation, err error) { func (wd *WDADriver) SetOrientation(orientation types.Orientation) (err error) { // [[FBRoute POST:@"/orientation"] respondWithTarget:self action:@selector(handleSetOrientation:)] data := map[string]interface{}{"orientation": orientation} - _, err = wd.Session.POST(data, "/session", wd.Session.ID, "/orientation") + urlStr := fmt.Sprintf("/session/%s/orientation", wd.Session.ID) + _, err = wd.Session.POST(data, urlStr) return } func (wd *WDADriver) Rotation() (rotation types.Rotation, err error) { // [[FBRoute GET:@"/rotation"] respondWithTarget:self action:@selector(handleGetRotation:)] var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/rotation"); err != nil { + urlStr := fmt.Sprintf("/session/%s/rotation", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return types.Rotation{}, err } reply := new(struct{ Value types.Rotation }) @@ -758,7 +771,8 @@ func (wd *WDADriver) Rotation() (rotation types.Rotation, err error) { func (wd *WDADriver) SetRotation(rotation types.Rotation) (err error) { // [[FBRoute POST:@"/rotation"] respondWithTarget:self action:@selector(handleSetRotation:)] - _, err = wd.Session.POST(rotation, "/session", wd.Session.ID, "/rotation") + urlStr := fmt.Sprintf("/session/%s/rotation", wd.Session.ID) + _, err = wd.Session.POST(rotation, urlStr) return } @@ -798,7 +812,8 @@ func (wd *WDADriver) AccessibleSource() (source string, err error) { // [[FBRoute GET:@"/wda/accessibleSource"] respondWithTarget:self action:@selector(handleGetAccessibleSourceCommand:)] // [[FBRoute GET:@"/wda/accessibleSource"].withoutSession var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/wda/accessibleSource"); err != nil { + urlStr := fmt.Sprintf("/session/%s/wda/accessibleSource", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return "", err } var jr builtinJSON.RawMessage @@ -829,7 +844,8 @@ func (wd *WDADriver) IsHealthy() (healthy bool, err error) { func (wd *WDADriver) GetAppiumSettings() (settings map[string]interface{}, err error) { // [[FBRoute GET:@"/appium/settings"] respondWithTarget:self action:@selector(handleGetSettings:)] var rawResp DriverRawResponse - if rawResp, err = wd.Session.GET("/session", wd.Session.ID, "/appium/settings"); err != nil { + urlStr := fmt.Sprintf("/session/%s/appium/settings", wd.Session.ID) + if rawResp, err = wd.Session.GET(urlStr); err != nil { return nil, err } reply := new(struct{ Value map[string]interface{} }) @@ -844,7 +860,8 @@ func (wd *WDADriver) SetAppiumSettings(settings map[string]interface{}) (ret map // [[FBRoute POST:@"/appium/settings"] respondWithTarget:self action:@selector(handleSetSettings:)] data := map[string]interface{}{"settings": settings} var rawResp DriverRawResponse - if rawResp, err = wd.Session.POST(data, "/session", wd.Session.ID, "/appium/settings"); err != nil { + urlStr := fmt.Sprintf("/session/%s/appium/settings", wd.Session.ID) + if rawResp, err = wd.Session.POST(data, urlStr); err != nil { return nil, err } reply := new(struct{ Value map[string]interface{} })