mirror of
https://github.com/httprunner/httprunner.git
synced 2026-06-28 19:11:28 +08:00
Merge branch 'fix/yuhongzheng/forward_error' into 'video-release'
fix: 复用forward端口,修复ui2截图时间过长 See merge request iesqa/httprunner!36
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
v4.5.1
|
v4.5.1
|
||||||
|
|
||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, "{")
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user