refactor: move android options to pkg/uixt/options

This commit is contained in:
lilong.129
2025-02-06 15:34:36 +08:00
parent 14c81ea142
commit 8a78ba6477
14 changed files with 124 additions and 98 deletions
+2 -1
View File
@@ -9,6 +9,7 @@ import (
"github.com/httprunner/httprunner/v5/internal/sdk" "github.com/httprunner/httprunner/v5/internal/sdk"
"github.com/httprunner/httprunner/v5/pkg/uixt" "github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/options"
) )
var ( var (
@@ -35,7 +36,7 @@ var installCmd = &cobra.Command{
return err return err
} }
device, err := uixt.NewAndroidDevice(uixt.WithSerialNumber(serial)) device, err := uixt.NewAndroidDevice(options.WithSerialNumber(serial))
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return err return err
+7 -7
View File
@@ -160,23 +160,23 @@ func (c *TConfig) SetHarmony(options ...uixt.HarmonyDeviceOption) *TConfig {
return c return c
} }
func (c *TConfig) SetAndroid(options ...uixt.AndroidDeviceOption) *TConfig { func (c *TConfig) SetAndroid(opts ...options.AndroidDeviceOption) *TConfig {
uiaOptions := &uixt.AndroidDevice{} uiaOptions := options.NewAndroidDeviceConfig(opts...)
for _, option := range options { device := &uixt.AndroidDevice{
option(uiaOptions) AndroidDeviceConfig: uiaOptions,
} }
// each device can have its own settings // each device can have its own settings
if uiaOptions.SerialNumber != "" { if uiaOptions.SerialNumber != "" {
c.Android = append(c.Android, uiaOptions) c.Android = append(c.Android, device)
return c return c
} }
// device UDID is not specified, settings will be shared // device UDID is not specified, settings will be shared
if len(c.Android) == 0 { if len(c.Android) == 0 {
c.Android = append(c.Android, uiaOptions) c.Android = append(c.Android, device)
} else { } else {
c.Android[0] = uiaOptions c.Android[0] = device
} }
return c return c
} }
+4 -1
View File
@@ -5,6 +5,7 @@ import (
hrp "github.com/httprunner/httprunner/v5" hrp "github.com/httprunner/httprunner/v5"
"github.com/httprunner/httprunner/v5/pkg/uixt" "github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/options"
) )
func TestAndroidDouyinE2E(t *testing.T) { func TestAndroidDouyinE2E(t *testing.T) {
@@ -14,7 +15,9 @@ func TestAndroidDouyinE2E(t *testing.T) {
"device": "${ENV(SerialNumber)}", "device": "${ENV(SerialNumber)}",
"ups": "${ENV(LIVEUPLIST)}", "ups": "${ENV(LIVEUPLIST)}",
}). }).
SetAndroid(uixt.WithSerialNumber("$device"), uixt.WithAdbLogOn(true)), SetAndroid(
options.WithSerialNumber("$device"),
options.WithAdbLogOn(true)),
TestSteps: []hrp.IStep{ TestSteps: []hrp.IStep{
hrp.NewStep("启动抖音"). hrp.NewStep("启动抖音").
Android(). Android().
+2 -1
View File
@@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/httprunner/httprunner/v5/pkg/uixt" "github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/options"
) )
var ( var (
@@ -28,7 +29,7 @@ func init() {
} }
func launchAppDriver(pkgName string) (driver *uixt.DriverExt, err error) { func launchAppDriver(pkgName string) (driver *uixt.DriverExt, err error) {
device, _ := uixt.NewAndroidDevice(uixt.WithSerialNumber(serial)) device, _ := uixt.NewAndroidDevice(options.WithSerialNumber(serial))
driver, err = device.NewDriver() driver, err = device.NewDriver()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -7,6 +7,7 @@ import (
hrp "github.com/httprunner/httprunner/v5" hrp "github.com/httprunner/httprunner/v5"
"github.com/httprunner/httprunner/v5/pkg/uixt" "github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/options"
) )
func TestAndroidDouyinFeedTest(t *testing.T) { func TestAndroidDouyinFeedTest(t *testing.T) {
@@ -15,7 +16,7 @@ func TestAndroidDouyinFeedTest(t *testing.T) {
WithVariables(map[string]interface{}{ WithVariables(map[string]interface{}{
"device": "${ENV(SerialNumber)}", "device": "${ENV(SerialNumber)}",
}). }).
SetAndroid(uixt.WithSerialNumber("$device")), SetAndroid(options.WithSerialNumber("$device")),
TestSteps: []hrp.IStep{ TestSteps: []hrp.IStep{
hrp.NewStep("启动抖音"). hrp.NewStep("启动抖音").
Android(). Android().
@@ -7,6 +7,7 @@ import (
hrp "github.com/httprunner/httprunner/v5" hrp "github.com/httprunner/httprunner/v5"
"github.com/httprunner/httprunner/v5/pkg/uixt" "github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/options"
) )
func TestAndroidLiveSwipeTest(t *testing.T) { func TestAndroidLiveSwipeTest(t *testing.T) {
@@ -15,7 +16,7 @@ func TestAndroidLiveSwipeTest(t *testing.T) {
WithVariables(map[string]interface{}{ WithVariables(map[string]interface{}{
"device": "${ENV(SerialNumber)}", "device": "${ENV(SerialNumber)}",
}). }).
SetAndroid(uixt.WithSerialNumber("$device")), SetAndroid(options.WithSerialNumber("$device")),
TestSteps: []hrp.IStep{ TestSteps: []hrp.IStep{
hrp.NewStep("启动抖音"). hrp.NewStep("启动抖音").
Android(). Android().
+2 -2
View File
@@ -6,7 +6,7 @@ import (
"testing" "testing"
hrp "github.com/httprunner/httprunner/v5" hrp "github.com/httprunner/httprunner/v5"
"github.com/httprunner/httprunner/v5/pkg/uixt" "github.com/httprunner/httprunner/v5/pkg/uixt/options"
) )
func TestHamonyDouyinFeedTest(t *testing.T) { func TestHamonyDouyinFeedTest(t *testing.T) {
@@ -16,7 +16,7 @@ func TestHamonyDouyinFeedTest(t *testing.T) {
"device": "a38c2c5c", "device": "a38c2c5c",
"query": "${ENV(query)}", "query": "${ENV(query)}",
}). }).
SetAndroid(uixt.WithSerialNumber("$device")), SetAndroid(options.WithSerialNumber("$device")),
TestSteps: []hrp.IStep{ TestSteps: []hrp.IStep{
hrp.NewStep("启动抖音"). hrp.NewStep("启动抖音").
Android(). Android().
+3 -3
View File
@@ -18,9 +18,9 @@ func TestAndroidExpertTest(t *testing.T) {
"app_name": "抖音", "app_name": "抖音",
}). }).
SetAndroid( SetAndroid(
uixt.WithSerialNumber("$device"), options.WithSerialNumber("$device"),
uixt.WithAdbLogOn(true), options.WithAdbLogOn(true),
uixt.WithUIA2(true), options.WithUIA2(true),
), ),
TestSteps: []hrp.IStep{ TestSteps: []hrp.IStep{
// 温启动 // 温启动
+1 -1
View File
@@ -51,7 +51,7 @@ func initIOSDevice(uuid string) uixt.IDevice {
} }
func initAndroidDevice(uuid string) uixt.IDevice { func initAndroidDevice(uuid string) uixt.IDevice {
device, err := uixt.NewAndroidDevice(uixt.WithSerialNumber(uuid)) device, err := uixt.NewAndroidDevice(options.WithSerialNumber(uuid))
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("failed to init android device") log.Fatal().Err(err).Msg("failed to init android device")
} }
+3 -1
View File
@@ -7,6 +7,8 @@ import (
"fmt" "fmt"
"os" "os"
"testing" "testing"
"github.com/httprunner/httprunner/v5/pkg/uixt/options"
) )
func checkOCR(buff *bytes.Buffer) error { func checkOCR(buff *bytes.Buffer) error {
@@ -53,7 +55,7 @@ func TestOCRWithLocalFile(t *testing.T) {
func TestTapUIWithScreenshot(t *testing.T) { func TestTapUIWithScreenshot(t *testing.T) {
serialNumber := os.Getenv("SERIAL_NUMBER") serialNumber := os.Getenv("SERIAL_NUMBER")
device, _ := NewAndroidDevice(WithSerialNumber(serialNumber)) device, _ := NewAndroidDevice(options.WithSerialNumber(serialNumber))
driver, err := device.NewDriver() driver, err := device.NewDriver()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
+16 -73
View File
@@ -24,6 +24,7 @@ import (
"github.com/httprunner/httprunner/v5/internal/config" "github.com/httprunner/httprunner/v5/internal/config"
"github.com/httprunner/httprunner/v5/internal/json" "github.com/httprunner/httprunner/v5/internal/json"
"github.com/httprunner/httprunner/v5/pkg/gadb" "github.com/httprunner/httprunner/v5/pkg/gadb"
"github.com/httprunner/httprunner/v5/pkg/uixt/options"
) )
var ( var (
@@ -48,58 +49,20 @@ var evalite embed.FS
const forwardToPrefix = "forward-to-" const forwardToPrefix = "forward-to-"
type AndroidDeviceOption func(*AndroidDevice) func NewAndroidDevice(opts ...options.AndroidDeviceOption) (device *AndroidDevice, err error) {
androidOptions := &options.AndroidDeviceConfig{
func WithSerialNumber(serial string) AndroidDeviceOption {
return func(device *AndroidDevice) {
device.SerialNumber = serial
}
}
func WithUIA2(uia2On bool) AndroidDeviceOption {
return func(device *AndroidDevice) {
device.UIA2 = uia2On
}
}
func WithStub(stubOn bool) AndroidDeviceOption {
return func(device *AndroidDevice) {
device.STUB = stubOn
}
}
func WithUIA2IP(ip string) AndroidDeviceOption {
return func(device *AndroidDevice) {
device.UIA2IP = ip
}
}
func WithUIA2Port(port int) AndroidDeviceOption {
return func(device *AndroidDevice) {
device.UIA2Port = port
}
}
func WithAdbLogOn(logOn bool) AndroidDeviceOption {
return func(device *AndroidDevice) {
device.LogOn = logOn
}
}
func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, err error) {
device = &AndroidDevice{
UIA2IP: UIA2ServerHost, UIA2IP: UIA2ServerHost,
UIA2Port: UIA2ServerPort, UIA2Port: UIA2ServerPort,
} }
for _, option := range options { for _, option := range opts {
option(device) option(androidOptions)
} }
deviceList, err := GetAndroidDevices(device.SerialNumber) deviceList, err := GetAndroidDevices(androidOptions.SerialNumber)
if err != nil { if err != nil {
return nil, errors.Wrap(code.DeviceConnectionError, err.Error()) return nil, errors.Wrap(code.DeviceConnectionError, err.Error())
} }
if device.SerialNumber == "" && len(deviceList) > 1 { if androidOptions.SerialNumber == "" && len(deviceList) > 1 {
return nil, errors.Wrap(code.DeviceConnectionError, "more than one device connected, please specify the serial") return nil, errors.Wrap(code.DeviceConnectionError, "more than one device connected, please specify the serial")
} }
@@ -113,8 +76,12 @@ func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, er
Msg("android SerialNumber is not specified, select the first one") Msg("android SerialNumber is not specified, select the first one")
} }
device.d = dev device = &AndroidDevice{
device.logcat = NewAdbLogcat(device.SerialNumber) AndroidDeviceConfig: androidOptions,
d: dev,
logcat: NewAdbLogcat(device.SerialNumber),
}
evalToolRaw, err := evalite.ReadFile("evalite") evalToolRaw, err := evalite.ReadFile("evalite")
if err != nil { if err != nil {
return nil, errors.Wrap(code.LoadFileError, err.Error()) return nil, errors.Wrap(code.LoadFileError, err.Error())
@@ -161,33 +128,9 @@ func GetAndroidDevices(serial ...string) (devices []*gadb.Device, err error) {
} }
type AndroidDevice struct { type AndroidDevice struct {
d *gadb.Device *options.AndroidDeviceConfig
logcat *AdbLogcat d *gadb.Device
SerialNumber string `json:"serial,omitempty" yaml:"serial,omitempty"` logcat *AdbLogcat
STUB bool `json:"stub,omitempty" yaml:"stub,omitempty"` // use stub
UIA2 bool `json:"uia2,omitempty" yaml:"uia2,omitempty"` // use uiautomator2
UIA2IP string `json:"uia2_ip,omitempty" yaml:"uia2_ip,omitempty"` // uiautomator2 server ip
UIA2Port int `json:"uia2_port,omitempty" yaml:"uia2_port,omitempty"` // uiautomator2 server port
LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"`
}
func (dev *AndroidDevice) Options() (deviceOptions []AndroidDeviceOption) {
if dev.SerialNumber != "" {
deviceOptions = append(deviceOptions, WithSerialNumber(dev.SerialNumber))
}
if dev.UIA2 {
deviceOptions = append(deviceOptions, WithUIA2(true))
}
if dev.UIA2IP != "" {
deviceOptions = append(deviceOptions, WithUIA2IP(dev.UIA2IP))
}
if dev.UIA2Port != 0 {
deviceOptions = append(deviceOptions, WithUIA2Port(dev.UIA2Port))
}
if dev.LogOn {
deviceOptions = append(deviceOptions, WithAdbLogOn(true))
}
return
} }
func (dev *AndroidDevice) Init() error { func (dev *AndroidDevice) Init() error {
+74
View File
@@ -1 +1,75 @@
package options package options
type AndroidDeviceConfig struct {
SerialNumber string `json:"serial,omitempty" yaml:"serial,omitempty"`
STUB bool `json:"stub,omitempty" yaml:"stub,omitempty"` // use stub
UIA2 bool `json:"uia2,omitempty" yaml:"uia2,omitempty"` // use uiautomator2
UIA2IP string `json:"uia2_ip,omitempty" yaml:"uia2_ip,omitempty"` // uiautomator2 server ip
UIA2Port int `json:"uia2_port,omitempty" yaml:"uia2_port,omitempty"` // uiautomator2 server port
LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"`
}
func (dev *AndroidDeviceConfig) Options() (deviceOptions []AndroidDeviceOption) {
if dev.SerialNumber != "" {
deviceOptions = append(deviceOptions, WithSerialNumber(dev.SerialNumber))
}
if dev.UIA2 {
deviceOptions = append(deviceOptions, WithUIA2(true))
}
if dev.UIA2IP != "" {
deviceOptions = append(deviceOptions, WithUIA2IP(dev.UIA2IP))
}
if dev.UIA2Port != 0 {
deviceOptions = append(deviceOptions, WithUIA2Port(dev.UIA2Port))
}
if dev.LogOn {
deviceOptions = append(deviceOptions, WithAdbLogOn(true))
}
return
}
func NewAndroidDeviceConfig(opts ...AndroidDeviceOption) *AndroidDeviceConfig {
config := &AndroidDeviceConfig{}
for _, opt := range opts {
opt(config)
}
return config
}
type AndroidDeviceOption func(*AndroidDeviceConfig)
func WithSerialNumber(serial string) AndroidDeviceOption {
return func(device *AndroidDeviceConfig) {
device.SerialNumber = serial
}
}
func WithUIA2(uia2On bool) AndroidDeviceOption {
return func(device *AndroidDeviceConfig) {
device.UIA2 = uia2On
}
}
func WithStub(stubOn bool) AndroidDeviceOption {
return func(device *AndroidDeviceConfig) {
device.STUB = stubOn
}
}
func WithUIA2IP(ip string) AndroidDeviceOption {
return func(device *AndroidDeviceConfig) {
device.UIA2IP = ip
}
}
func WithUIA2Port(port int) AndroidDeviceOption {
return func(device *AndroidDeviceConfig) {
device.UIA2Port = port
}
}
func WithAdbLogOn(logOn bool) AndroidDeviceOption {
return func(device *AndroidDeviceConfig) {
device.LogOn = logOn
}
}
+4 -1
View File
@@ -8,6 +8,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/httprunner/httprunner/v5/code" "github.com/httprunner/httprunner/v5/code"
"github.com/httprunner/httprunner/v5/pkg/uixt" "github.com/httprunner/httprunner/v5/pkg/uixt"
"github.com/httprunner/httprunner/v5/pkg/uixt/options"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
@@ -35,7 +36,9 @@ func handleDeviceContext() gin.HandlerFunc {
switch strings.ToLower(platform) { switch strings.ToLower(platform) {
case "android": case "android":
device, err := uixt.NewAndroidDevice(uixt.WithSerialNumber(serial), uixt.WithStub(true)) device, err := uixt.NewAndroidDevice(
options.WithSerialNumber(serial),
options.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")
+2 -5
View File
@@ -760,11 +760,8 @@ func (s *StepRequest) MobileUI() *StepMobile {
} }
// Android creates a new android step session // Android creates a new android step session
func (s *StepRequest) Android(options ...uixt.AndroidDeviceOption) *StepMobile { func (s *StepRequest) Android(opts ...options.AndroidDeviceOption) *StepMobile {
androidOptions := &uixt.AndroidDevice{} androidOptions := options.NewAndroidDeviceConfig(opts...)
for _, option := range options {
option(androidOptions)
}
return &StepMobile{ return &StepMobile{
StepConfig: s.StepConfig, StepConfig: s.StepConfig,
Android: &MobileUI{ Android: &MobileUI{