Merge branch 'fix/yuhongzheng/forward_error' into 'video-release'

fix: 复用forward端口,修复ui2截图时间过长

See merge request iesqa/httprunner!36
This commit is contained in:
余泓铮
2024-05-29 03:35:16 +00:00
9 changed files with 62 additions and 64 deletions

View File

@@ -49,11 +49,11 @@ var listAppsCmd = &cobra.Command{
applicationType = gidevice.ApplicationTypeAny applicationType = gidevice.ApplicationTypeAny
} }
result, errList := device.InstallationProxyBrowse( result, err := device.InstallationProxyBrowse(
gidevice.WithApplicationType(applicationType), gidevice.WithApplicationType(applicationType),
gidevice.WithReturnAttributes("CFBundleVersion", "CFBundleDisplayName", "CFBundleIdentifier")) gidevice.WithReturnAttributes("CFBundleVersion", "CFBundleDisplayName", "CFBundleIdentifier"))
if errList != nil { if err != nil {
return fmt.Errorf("get app list failed") return fmt.Errorf("get app list failed %v", err)
} }
for _, app := range result { for _, app := range result {

View File

@@ -10,6 +10,7 @@ import (
"fmt" "fmt"
"math" "math"
"math/rand" "math/rand"
"net"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
@@ -484,6 +485,24 @@ func ConvertToStringSlice(val interface{}) ([]string, error) {
return nil, fmt.Errorf("invalid type for conversion to []string") return nil, fmt.Errorf("invalid type for conversion to []string")
} }
func GetFreePort() (int, error) {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
return 0, errors.Wrap(err, "resolve tcp addr failed")
}
l, err := net.ListenTCP("tcp", addr)
if err != nil {
return 0, errors.Wrap(err, "listen tcp addr failed")
}
defer func() {
if err = l.Close(); err != nil {
log.Error().Err(err).Msg(fmt.Sprintf("close addr %s error", l.Addr().String()))
}
}()
return l.Addr().(*net.TCPAddr).Port, nil
}
func GetCurrentDay() string { func GetCurrentDay() string {
now := time.Now() now := time.Now()
// 格式化日期为 yyyyMMdd // 格式化日期为 yyyyMMdd

View File

@@ -1,2 +1 @@
v4.5.1 v4.5.1

View File

@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"strconv"
"strings" "strings"
"time" "time"
@@ -181,10 +182,8 @@ func (d *Device) DevicePath() (string, error) {
return resp, err return resp, err
} }
func (d *Device) Forward(localPort int, remoteInterface interface{}, noRebind ...bool) (err error) { func (d *Device) Forward(remoteInterface interface{}, noRebind ...bool) (port int, err error) {
command := ""
var remote string var remote string
local := fmt.Sprintf("tcp:%d", localPort)
switch r := remoteInterface.(type) { switch r := remoteInterface.(type) {
// for unix sockets // for unix sockets
case string: case string:
@@ -193,14 +192,28 @@ func (d *Device) Forward(localPort int, remoteInterface interface{}, noRebind ..
remote = fmt.Sprintf("tcp:%d", r) remote = fmt.Sprintf("tcp:%d", r)
} }
forwardList, err := d.ForwardList()
if err != nil {
return
}
for _, forwardItem := range forwardList {
if forwardItem.Remote == remote {
return strconv.Atoi(forwardItem.Local[4:])
}
}
localPort, err := builtin.GetFreePort()
if err != nil {
return
}
local := fmt.Sprintf("tcp:%d", localPort)
command := fmt.Sprintf("host-serial:%s:forward:%s;%s", d.serial, local, remote)
if len(noRebind) != 0 && noRebind[0] { if len(noRebind) != 0 && noRebind[0] {
command = fmt.Sprintf("host-serial:%s:forward:norebind:%s;%s", d.serial, local, remote) command = fmt.Sprintf("host-serial:%s:forward:norebind:%s;%s", d.serial, local, remote)
} else {
command = fmt.Sprintf("host-serial:%s:forward:%s;%s", d.serial, local, remote)
} }
_, err = d.adbClient.executeCommand(command, true) _, err = d.adbClient.executeCommand(command, true)
return return localPort, nil
} }
func (d *Device) ForwardList() (deviceForwardList []DeviceForward, err error) { func (d *Device) ForwardList() (deviceForwardList []DeviceForward, err error) {

View File

@@ -124,8 +124,7 @@ func TestDevice_Forward(t *testing.T) {
setupDevices(t) setupDevices(t)
for _, device := range devices { for _, device := range devices {
localPort := 61000 localPort, err := device.Forward(6790)
err := device.Forward(localPort, 6790)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@@ -5,7 +5,6 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"net"
"os/exec" "os/exec"
"strings" "strings"
@@ -198,12 +197,8 @@ func (dev *AndroidDevice) NewDriver(options ...DriverOption) (driverExt *DriverE
// NewUSBDriver creates new client via USB connected device, this will also start a new session. // NewUSBDriver creates new client via USB connected device, this will also start a new session.
func (dev *AndroidDevice) NewUSBDriver(capabilities Capabilities) (driver WebDriver, err error) { func (dev *AndroidDevice) NewUSBDriver(capabilities Capabilities) (driver WebDriver, err error) {
var localPort int localPort, err := dev.d.Forward(UIA2ServerPort)
if localPort, err = getFreePort(); err != nil { if err != nil {
return nil, errors.Wrap(code.AndroidDeviceConnectionError,
fmt.Sprintf("get free port failed: %v", err))
}
if err = dev.d.Forward(localPort, UIA2ServerPort); err != nil {
return nil, errors.Wrap(code.AndroidDeviceConnectionError, return nil, errors.Wrap(code.AndroidDeviceConnectionError,
fmt.Sprintf("forward port %d->%d failed: %v", fmt.Sprintf("forward port %d->%d failed: %v",
localPort, UIA2ServerPort, err)) localPort, UIA2ServerPort, err))
@@ -262,20 +257,6 @@ func (dev *AndroidDevice) StopPcap() string {
return "" return ""
} }
func getFreePort() (int, error) {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
return 0, errors.Wrap(err, "resolve tcp addr failed")
}
l, err := net.ListenTCP("tcp", addr)
if err != nil {
return 0, errors.Wrap(err, "listen tcp addr failed")
}
defer func() { _ = l.Close() }()
return l.Addr().(*net.TCPAddr).Port, nil
}
type LineCallback func(string) type LineCallback func(string)
type AdbLogcat struct { type AdbLogcat struct {
@@ -409,6 +390,7 @@ type ExportPoint struct {
func ConvertPoints(lines []string) (eps []ExportPoint) { func ConvertPoints(lines []string) (eps []ExportPoint) {
log.Info().Msg("ConvertPoints") log.Info().Msg("ConvertPoints")
log.Info().Msg(strings.Join(lines, "\n"))
for _, line := range lines { for _, line := range lines {
if strings.Contains(line, "ext") { if strings.Contains(line, "ext") {
idx := strings.Index(line, "{") idx := strings.Index(line, "{")

View File

@@ -10,6 +10,8 @@ import (
"strings" "strings"
"testing" "testing"
"time" "time"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
) )
var ( var (
@@ -21,6 +23,7 @@ func setupAndroid(t *testing.T) {
device, err := NewAndroidDevice() device, err := NewAndroidDevice()
checkErr(t, err) checkErr(t, err)
device.UIA2 = false device.UIA2 = false
device.LogOn = true
driverExt, err = device.NewDriver() driverExt, err = device.NewDriver()
checkErr(t, err) checkErr(t, err)
} }
@@ -195,22 +198,21 @@ func TestDriver_DeviceInfo(t *testing.T) {
} }
func TestDriver_Tap(t *testing.T) { func TestDriver_Tap(t *testing.T) {
driver, err := NewUIADriver(nil, uiaServerURL) setupAndroid(t)
if err != nil { driverExt.Driver.StartCaptureLog("")
t.Fatal(err) err := driverExt.Driver.Tap(150, 340, WithIdentifier("test"))
}
err = driver.Tap(150, 340)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
time.Sleep(time.Second) time.Sleep(time.Second)
err = driver.TapFloat(60.5, 125.5) err = driverExt.Driver.TapFloat(60.5, 125.5, WithIdentifier("test"))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
time.Sleep(time.Second) time.Sleep(time.Second)
result, _ := driverExt.Driver.StopCaptureLog()
t.Log(result)
} }
func TestDriver_Swipe(t *testing.T) { func TestDriver_Swipe(t *testing.T) {
@@ -333,7 +335,7 @@ func TestUiSelectorHelper_NewUiSelectorHelper(t *testing.T) {
} }
func Test_getFreePort(t *testing.T) { func Test_getFreePort(t *testing.T) {
freePort, err := getFreePort() freePort, err := builtin.GetFreePort()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@@ -16,7 +16,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/httprunner/httprunner/v4/hrp/internal/code"
"github.com/httprunner/httprunner/v4/hrp/pkg/utf7" "github.com/httprunner/httprunner/v4/hrp/pkg/utf7"
) )
@@ -564,25 +563,9 @@ func (ud *uiaDriver) Rotation() (rotation Rotation, err error) {
} }
func (ud *uiaDriver) Screenshot() (raw *bytes.Buffer, err error) { func (ud *uiaDriver) Screenshot() (raw *bytes.Buffer, err error) {
// register(getHandler, new CaptureScreenshot("/wd/hub/session/:sessionId/screenshot")) // https://bytedance.larkoffice.com/docx/C8qEdmSHnoRvMaxZauocMiYpnLh
var rawResp rawResponse // ui2截图受内存影响改为adb截图
if rawResp, err = ud.httpGET("/session", ud.sessionId, "screenshot"); err != nil { return ud.adbDriver.Screenshot()
return nil, errors.Wrap(code.AndroidScreenShotError,
fmt.Sprintf("get UIA screenshot data failed: %v", err))
}
reply := new(struct{ Value string })
if err = json.Unmarshal(rawResp, reply); err != nil {
return nil, err
}
var decodeStr []byte
if decodeStr, err = base64.StdEncoding.DecodeString(reply.Value); err != nil {
return nil, errors.Wrap(code.AndroidScreenShotError,
fmt.Sprintf("decode UIA screenshot data failed: %v", err))
}
raw = bytes.NewBuffer(decodeStr)
return
} }
func (ud *uiaDriver) Source(srcOpt ...SourceOption) (source string, err error) { func (ud *uiaDriver) Source(srcOpt ...SourceOption) (source string, err error) {

View File

@@ -16,6 +16,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
"github.com/httprunner/httprunner/v4/hrp/internal/code" "github.com/httprunner/httprunner/v4/hrp/internal/code"
"github.com/httprunner/httprunner/v4/hrp/internal/env" "github.com/httprunner/httprunner/v4/hrp/internal/env"
"github.com/httprunner/httprunner/v4/hrp/pkg/gidevice" "github.com/httprunner/httprunner/v4/hrp/pkg/gidevice"
@@ -592,7 +593,7 @@ func (dev *IOSDevice) NewHTTPDriver(capabilities Capabilities) (driver WebDriver
var localPort int var localPort int
localPort, err = strconv.Atoi(env.WDA_LOCAL_PORT) localPort, err = strconv.Atoi(env.WDA_LOCAL_PORT)
if err != nil { if err != nil {
localPort, err = getFreePort() localPort, err = builtin.GetFreePort()
if err != nil { if err != nil {
return nil, errors.Wrap(code.IOSDeviceHTTPDriverError, return nil, errors.Wrap(code.IOSDeviceHTTPDriverError,
fmt.Sprintf("get free port failed: %v", err)) fmt.Sprintf("get free port failed: %v", err))
@@ -609,7 +610,7 @@ func (dev *IOSDevice) NewHTTPDriver(capabilities Capabilities) (driver WebDriver
var localMjpegPort int var localMjpegPort int
localMjpegPort, err = strconv.Atoi(env.WDA_LOCAL_MJPEG_PORT) localMjpegPort, err = strconv.Atoi(env.WDA_LOCAL_MJPEG_PORT)
if err != nil { if err != nil {
localMjpegPort, err = getFreePort() localMjpegPort, err = builtin.GetFreePort()
if err != nil { if err != nil {
return nil, errors.Wrap(code.IOSDeviceHTTPDriverError, return nil, errors.Wrap(code.IOSDeviceHTTPDriverError,
fmt.Sprintf("get free port failed: %v", err)) fmt.Sprintf("get free port failed: %v", err))