mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-10 17:43:00 +08:00
refactor: XTDriver
This commit is contained in:
@@ -41,13 +41,13 @@ var installCmd = &cobra.Command{
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
driverExt, err := device.NewDriver()
|
||||
driver, err := device.NewDriver()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = driverExt.GetDriver().GetDevice().Install(args[0],
|
||||
err = driver.GetDevice().Install(args[0],
|
||||
option.WithReinstall(replace),
|
||||
option.WithDowngrade(downgrade),
|
||||
option.WithGrantPermission(grant),
|
||||
|
||||
@@ -28,46 +28,48 @@ func init() {
|
||||
fmt.Printf("=== start running cases, serial=%s, runTimes=%d ===\n", serial, runTimes)
|
||||
}
|
||||
|
||||
func launchAppDriver(pkgName string) (driver uixt.IDriverExt, err error) {
|
||||
func launchAppDriver(pkgName string) (driverExt *uixt.XTDriver, err error) {
|
||||
device, _ := uixt.NewAndroidDevice(option.WithSerialNumber(serial))
|
||||
driver, err = device.NewDriver()
|
||||
driver, err := device.NewDriver()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = driver.GetDriver().AppTerminate(pkgName)
|
||||
_, err = driver.AppTerminate(pkgName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = driver.GetDriver().Homescreen()
|
||||
err = driver.Homescreen()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = driver.GetDriver().AppLaunch(pkgName)
|
||||
err = driver.AppLaunch(pkgName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
time.Sleep(15 * time.Second)
|
||||
|
||||
driverExt = uixt.NewXTDriver(driver)
|
||||
|
||||
// 处理弹窗
|
||||
err = driver.ClosePopupsHandler()
|
||||
err = driverExt.ClosePopupsHandler()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 进入推荐页
|
||||
err = driver.TapByOCR("推荐", option.WithScope(0, 0, 1, 0.3))
|
||||
err = driverExt.TapByOCR("推荐", option.WithScope(0, 0, 1, 0.3))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return driver, nil
|
||||
return driverExt, nil
|
||||
}
|
||||
|
||||
func watchVideo(driver uixt.IDriverExt) (err error) {
|
||||
func watchVideo(driver *uixt.XTDriver) (err error) {
|
||||
time.Sleep(3 * time.Second)
|
||||
err = driver.SwipeRelative(0.7, 0.7, 0.7, 0.2)
|
||||
if err != nil {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||
)
|
||||
|
||||
@@ -28,9 +29,9 @@ func init() {
|
||||
fmt.Printf("=== start running cases, serial=%s, runTimes=%d ===\n", serial, runTimes)
|
||||
}
|
||||
|
||||
func launchAppDriver(pkgName string) (driver uixt.IDriverExt, err error) {
|
||||
func launchAppDriver(pkgName string) (driverExt *uixt.XTDriver, err error) {
|
||||
device, _ := uixt.NewIOSDevice(option.WithUDID(serial))
|
||||
driver, err = device.NewDriver()
|
||||
driver, err := device.NewDriver()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -52,22 +53,25 @@ func launchAppDriver(pkgName string) (driver uixt.IDriverExt, err error) {
|
||||
|
||||
time.Sleep(15 * time.Second)
|
||||
|
||||
driverExt = uixt.NewXTDriver(driver,
|
||||
ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
|
||||
// 处理弹窗
|
||||
err = driver.ClosePopupsHandler()
|
||||
err = driverExt.ClosePopupsHandler()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 进入推荐页
|
||||
err = driver.TapByOCR("推荐", option.WithScope(0, 0, 1, 0.3))
|
||||
err = driverExt.TapByOCR("推荐", option.WithScope(0, 0, 1, 0.3))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return driver, nil
|
||||
return driverExt, nil
|
||||
}
|
||||
|
||||
func watchVideo(driver uixt.IDriverExt) (err error) {
|
||||
func watchVideo(driver *uixt.XTDriver) (err error) {
|
||||
time.Sleep(3 * time.Second)
|
||||
err = driver.SwipeRelative(0.7, 0.7, 0.7, 0.2)
|
||||
if err != nil {
|
||||
|
||||
@@ -39,12 +39,9 @@ var rootCmd = &cobra.Command{
|
||||
return errors.New("android or ios app bundldID is required")
|
||||
}
|
||||
|
||||
driverExt, err := uixt.NewDriverExt(driver,
|
||||
driverExt := uixt.NewXTDriver(driver,
|
||||
ai.WithCVService(ai.CVServiceTypeVEDEM),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wc := NewWorldCupLive(driverExt, matchName, bundleID, duration, interval)
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ func convertTimeToSeconds(timeStr string) (int, error) {
|
||||
return seconds, nil
|
||||
}
|
||||
|
||||
func initIOSDriver(uuid string) uixt.IDriverExt {
|
||||
func initIOSDriver(uuid string) *uixt.XTDriver {
|
||||
device, err := uixt.NewIOSDevice(
|
||||
option.WithUDID(uuid),
|
||||
option.WithWDAPort(8700), option.WithWDAMjpegPort(8800),
|
||||
@@ -48,16 +48,18 @@ func initIOSDriver(uuid string) uixt.IDriverExt {
|
||||
log.Fatal().Err(err).Msg("failed to init ios device")
|
||||
}
|
||||
driver, _ := device.NewDriver()
|
||||
return driver
|
||||
driverExt := uixt.NewXTDriver(driver)
|
||||
return driverExt
|
||||
}
|
||||
|
||||
func initAndroidDriver(uuid string) uixt.IDriverExt {
|
||||
func initAndroidDriver(uuid string) *uixt.XTDriver {
|
||||
device, err := uixt.NewAndroidDevice(option.WithSerialNumber(uuid))
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("failed to init android device")
|
||||
}
|
||||
driver, _ := device.NewDriver()
|
||||
return driver
|
||||
driverExt := uixt.NewXTDriver(driver)
|
||||
return driverExt
|
||||
}
|
||||
|
||||
type timeLog struct {
|
||||
@@ -68,7 +70,7 @@ type timeLog struct {
|
||||
}
|
||||
|
||||
type WorldCupLive struct {
|
||||
driver uixt.IDriverExt
|
||||
driver *uixt.XTDriver
|
||||
file *os.File
|
||||
resultDir string
|
||||
MatchName string `json:"matchName"`
|
||||
@@ -81,7 +83,7 @@ type WorldCupLive struct {
|
||||
PerfFile string `json:"perf"`
|
||||
}
|
||||
|
||||
func NewWorldCupLive(driver uixt.IDriverExt, matchName, bundleID string, duration, interval int) *WorldCupLive {
|
||||
func NewWorldCupLive(driver *uixt.XTDriver, matchName, bundleID string, duration, interval int) *WorldCupLive {
|
||||
if matchName == "" {
|
||||
matchName = "unknown-match"
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
v5.0.0+2502102239
|
||||
v5.0.0+2502111148
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
"github.com/httprunner/httprunner/v5/internal/config"
|
||||
"github.com/httprunner/httprunner/v5/internal/json"
|
||||
"github.com/httprunner/httprunner/v5/pkg/gadb"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/types"
|
||||
)
|
||||
@@ -149,8 +148,7 @@ func (dev *AndroidDevice) LogEnabled() bool {
|
||||
return dev.Options.LogOn
|
||||
}
|
||||
|
||||
func (dev *AndroidDevice) NewDriver() (driverExt IDriverExt, err error) {
|
||||
var driver IDriver
|
||||
func (dev *AndroidDevice) NewDriver() (driver IDriver, err error) {
|
||||
if dev.Options.UIA2 || dev.Options.LogOn {
|
||||
driver, err = NewUIA2Driver(dev)
|
||||
} else {
|
||||
@@ -166,16 +164,11 @@ func (dev *AndroidDevice) NewDriver() (driverExt IDriverExt, err error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
driverExt, err = NewDriverExt(driver, ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init android driver ext failed")
|
||||
}
|
||||
// setup driver
|
||||
if err := driverExt.GetDriver().Setup(); err != nil {
|
||||
if err := driver.Setup(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return driverExt, nil
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
func (dev *AndroidDevice) StartPerf() error {
|
||||
|
||||
@@ -9,19 +9,22 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/httprunner/httprunner/v5/internal/builtin"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/types"
|
||||
)
|
||||
|
||||
var driverExt IDriverExt
|
||||
var driverExt *XTDriver
|
||||
|
||||
func setupAndroidAdbDriver(t *testing.T) {
|
||||
device, err := NewAndroidDevice()
|
||||
checkErr(t, err)
|
||||
device.Options.UIA2 = false
|
||||
device.Options.LogOn = false
|
||||
driverExt, err = device.NewDriver()
|
||||
driver, err = device.NewDriver()
|
||||
checkErr(t, err)
|
||||
driverExt = NewXTDriver(driver,
|
||||
ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
}
|
||||
|
||||
func setupAndroidUIA2Driver(t *testing.T) {
|
||||
@@ -29,8 +32,10 @@ func setupAndroidUIA2Driver(t *testing.T) {
|
||||
checkErr(t, err)
|
||||
device.Options.UIA2 = true
|
||||
device.Options.LogOn = false
|
||||
driverExt, err = device.NewDriver()
|
||||
driver, err = device.NewDriver()
|
||||
checkErr(t, err)
|
||||
driverExt = NewXTDriver(driver,
|
||||
ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
}
|
||||
|
||||
func TestAndroidDevice_GetPackageInfo(t *testing.T) {
|
||||
@@ -252,12 +257,12 @@ func TestDriver_AppLaunch(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = driver.GetDriver().AppLaunch("com.android.settings")
|
||||
err = driver.AppLaunch("com.android.settings")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
raw, err := driver.GetDriver().Screenshot()
|
||||
raw, err := driver.Screenshot()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -305,19 +310,19 @@ func TestDriver_KeepAlive(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = driver.GetDriver().AppLaunch("com.android.settings")
|
||||
err = driver.AppLaunch("com.android.settings")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = driver.GetDriver().Screenshot()
|
||||
_, err = driver.Screenshot()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
time.Sleep(60 * time.Second)
|
||||
|
||||
_, err = driver.GetDriver().Screenshot()
|
||||
_, err = driver.Screenshot()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -330,7 +335,7 @@ func TestDriver_AppTerminate(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = driver.GetDriver().AppTerminate("tv.danmaku.bili")
|
||||
_, err = driver.AppTerminate("tv.danmaku.bili")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||
)
|
||||
|
||||
@@ -22,10 +23,13 @@ func TestIOSDemo(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
driverExt, err := device.NewDriver()
|
||||
driver, err := device.NewDriver()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
driverExt := uixt.NewXTDriver(driver,
|
||||
ai.WithCVService(ai.CVServiceTypeVEDEM),
|
||||
)
|
||||
|
||||
// release session
|
||||
defer func() {
|
||||
|
||||
@@ -147,6 +147,37 @@ type IDriver interface {
|
||||
TearDown() error
|
||||
}
|
||||
|
||||
func NewXTDriver(driver IDriver, opts ...ai.AIServiceOption) *XTDriver {
|
||||
services := ai.NewAIService(opts...)
|
||||
driverExt := &XTDriver{
|
||||
Driver: driver,
|
||||
CVService: services.ICVService,
|
||||
LLMService: services.ILLMService,
|
||||
}
|
||||
return driverExt
|
||||
}
|
||||
|
||||
func NewDriverExt(driver IDriver, opts ...ai.AIServiceOption) (*XTDriver, error) {
|
||||
services := ai.NewAIService(opts...)
|
||||
driverExt := &XTDriver{
|
||||
Driver: driver,
|
||||
CVService: services.ICVService,
|
||||
LLMService: services.ILLMService,
|
||||
}
|
||||
// create results directory
|
||||
// TODO: move to setup
|
||||
if err := builtin.EnsureFolderExists(config.ResultsPath); err != nil {
|
||||
return nil, errors.Wrap(err, "create results directory failed")
|
||||
}
|
||||
if err := builtin.EnsureFolderExists(config.ScreenShotsPath); err != nil {
|
||||
return nil, errors.Wrap(err, "create screenshots directory failed")
|
||||
}
|
||||
return driverExt, nil
|
||||
}
|
||||
|
||||
var _ IDriverExt = (*XTDriver)(nil)
|
||||
|
||||
// XTDriver = IDriver + AI
|
||||
type IDriverExt interface {
|
||||
GetDriver() IDriver // get original driver
|
||||
|
||||
@@ -176,35 +207,17 @@ type IDriverExt interface {
|
||||
DoValidation(check, assert, expected string, message ...string) (err error)
|
||||
}
|
||||
|
||||
func NewDriverExt(driver IDriver, opts ...ai.AIServiceOption) (IDriverExt, error) {
|
||||
services := ai.NewAIService(opts...)
|
||||
driverExt := &DriverExt{
|
||||
Driver: driver,
|
||||
CVService: services.ICVService,
|
||||
LLMService: services.ILLMService,
|
||||
}
|
||||
// create results directory
|
||||
// TODO: move to setup
|
||||
if err := builtin.EnsureFolderExists(config.ResultsPath); err != nil {
|
||||
return nil, errors.Wrap(err, "create results directory failed")
|
||||
}
|
||||
if err := builtin.EnsureFolderExists(config.ScreenShotsPath); err != nil {
|
||||
return nil, errors.Wrap(err, "create screenshots directory failed")
|
||||
}
|
||||
return driverExt, nil
|
||||
}
|
||||
|
||||
type DriverExt struct {
|
||||
type XTDriver struct {
|
||||
Driver IDriver
|
||||
CVService ai.ICVService // OCR/CV
|
||||
LLMService ai.ILLMService // LLM
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) GetDriver() IDriver {
|
||||
func (dExt *XTDriver) GetDriver() IDriver {
|
||||
return dExt.Driver
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) Setup() error {
|
||||
func (dExt *XTDriver) Setup() error {
|
||||
// unlock device screen
|
||||
err := dExt.Driver.Unlock()
|
||||
if err != nil {
|
||||
@@ -215,7 +228,7 @@ func (dExt *DriverExt) Setup() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) assertOCR(text, assert string) error {
|
||||
func (dExt *XTDriver) assertOCR(text, assert string) error {
|
||||
var opts []option.ActionOption
|
||||
opts = append(opts, option.WithScreenShotFileName(fmt.Sprintf("assert_ocr_%s", text)))
|
||||
|
||||
@@ -248,7 +261,7 @@ func (dExt *DriverExt) assertOCR(text, assert string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) assertForegroundApp(appName, assert string) (err error) {
|
||||
func (dExt *XTDriver) assertForegroundApp(appName, assert string) (err error) {
|
||||
err = dExt.Driver.AssertForegroundApp(appName)
|
||||
switch assert {
|
||||
case AssertionEqual:
|
||||
@@ -265,7 +278,7 @@ func (dExt *DriverExt) assertForegroundApp(appName, assert string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) DoValidation(check, assert, expected string, message ...string) (err error) {
|
||||
func (dExt *XTDriver) DoValidation(check, assert, expected string, message ...string) (err error) {
|
||||
switch check {
|
||||
case SelectorOCR:
|
||||
err = dExt.assertOCR(expected, assert)
|
||||
|
||||
@@ -103,7 +103,7 @@ type TapTextAction struct {
|
||||
Options []option.ActionOption
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) ParseActionOptions(opts ...option.ActionOption) []option.ActionOption {
|
||||
func (dExt *XTDriver) ParseActionOptions(opts ...option.ActionOption) []option.ActionOption {
|
||||
actionOptions := option.NewActionOptions(opts...)
|
||||
|
||||
// convert relative scope to absolute scope
|
||||
@@ -116,7 +116,7 @@ func (dExt *DriverExt) ParseActionOptions(opts ...option.ActionOption) []option.
|
||||
return actionOptions.Options()
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) GenAbsScope(x1, y1, x2, y2 float64) option.AbsScope {
|
||||
func (dExt *XTDriver) GenAbsScope(x1, y1, x2, y2 float64) option.AbsScope {
|
||||
// convert relative scope to absolute scope
|
||||
windowSize, _ := dExt.Driver.WindowSize()
|
||||
absX1 := int(x1 * float64(windowSize.Width))
|
||||
@@ -126,7 +126,7 @@ func (dExt *DriverExt) GenAbsScope(x1, y1, x2, y2 float64) option.AbsScope {
|
||||
return option.AbsScope{absX1, absY1, absX2, absY2}
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) DoAction(action MobileAction) (err error) {
|
||||
func (dExt *XTDriver) DoAction(action MobileAction) (err error) {
|
||||
actionStartTime := time.Now()
|
||||
defer func() {
|
||||
var logger *zerolog.Event
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (dExt *DriverExt) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) (err error) {
|
||||
func (dExt *XTDriver) Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) (err error) {
|
||||
windowSize, err := dExt.Driver.WindowSize()
|
||||
if err != nil {
|
||||
return errors.Wrap(code.DeviceGetInfoError, err.Error())
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/httprunner/httprunner/v5/code"
|
||||
)
|
||||
|
||||
func (dExt *DriverExt) Input(text string) (err error) {
|
||||
func (dExt *XTDriver) Input(text string) (err error) {
|
||||
err = dExt.Driver.Input(text)
|
||||
if err != nil {
|
||||
return errors.Wrap(code.MobileUIInputError, err.Error())
|
||||
|
||||
@@ -18,7 +18,7 @@ type InstallResult struct {
|
||||
ErrorMsg string `json:"errorMsg"`
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) InstallByUrl(url string, opts ...option.InstallOption) error {
|
||||
func (dExt *XTDriver) InstallByUrl(url string, opts ...option.InstallOption) error {
|
||||
// 获取当前目录
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
@@ -41,7 +41,7 @@ func (dExt *DriverExt) InstallByUrl(url string, opts ...option.InstallOption) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) Install(filePath string, opts ...option.InstallOption) error {
|
||||
func (dExt *XTDriver) Install(filePath string, opts ...option.InstallOption) error {
|
||||
if _, ok := dExt.Driver.GetDevice().(*AndroidDevice); ok {
|
||||
stopChan := make(chan struct{})
|
||||
go func() {
|
||||
@@ -90,7 +90,7 @@ func (dExt *DriverExt) Install(filePath string, opts ...option.InstallOption) er
|
||||
return dExt.Driver.GetDevice().Install(filePath, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) Uninstall(packageName string, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) Uninstall(packageName string, opts ...option.ActionOption) error {
|
||||
actionOptions := option.NewActionOptions(opts...)
|
||||
err := dExt.Driver.GetDevice().Uninstall(packageName)
|
||||
if err != nil {
|
||||
|
||||
@@ -43,7 +43,7 @@ func findTextPopup(screenTexts ai.OCRTexts) (closePoint *ai.OCRText) {
|
||||
return
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) handleTextPopup(screenTexts ai.OCRTexts) error {
|
||||
func (dExt *XTDriver) handleTextPopup(screenTexts ai.OCRTexts) error {
|
||||
closePoint := findTextPopup(screenTexts)
|
||||
if closePoint == nil {
|
||||
// no popup found
|
||||
@@ -60,7 +60,7 @@ func (dExt *DriverExt) handleTextPopup(screenTexts ai.OCRTexts) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) AutoPopupHandler() error {
|
||||
func (dExt *XTDriver) AutoPopupHandler() error {
|
||||
// TODO: check popup by activity type
|
||||
|
||||
// check popup by screenshot
|
||||
@@ -98,7 +98,7 @@ func (p *PopupInfo) ClosePoint() *ai.PointF {
|
||||
return &closePoint
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) CheckPopup() (popup *PopupInfo, err error) {
|
||||
func (dExt *XTDriver) CheckPopup() (popup *PopupInfo, err error) {
|
||||
screenResult, err := dExt.GetScreenResult(
|
||||
option.WithScreenShotUpload(true),
|
||||
option.WithScreenShotClosePopups(true), // get popup area and close area
|
||||
@@ -122,7 +122,7 @@ func (dExt *DriverExt) CheckPopup() (popup *PopupInfo, err error) {
|
||||
return popup, nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) ClosePopupsHandler() (err error) {
|
||||
func (dExt *XTDriver) ClosePopupsHandler() (err error) {
|
||||
log.Info().Msg("try to find and close popups")
|
||||
|
||||
popup, err := dExt.CheckPopup()
|
||||
|
||||
@@ -46,7 +46,7 @@ func (s *ScreenResult) FilterTextsByScope(x1, y1, x2, y2 float64) ai.OCRTexts {
|
||||
}
|
||||
|
||||
// GetScreenResult takes a screenshot, returns the image recognition result
|
||||
func (dExt *DriverExt) GetScreenResult(opts ...option.ActionOption) (screenResult *ScreenResult, err error) {
|
||||
func (dExt *XTDriver) GetScreenResult(opts ...option.ActionOption) (screenResult *ScreenResult, err error) {
|
||||
screenshotOptions := option.NewActionOptions(opts...)
|
||||
|
||||
var fileName string
|
||||
@@ -129,7 +129,7 @@ func (dExt *DriverExt) GetScreenResult(opts ...option.ActionOption) (screenResul
|
||||
return screenResult, nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) GetScreenTexts(opts ...option.ActionOption) (ocrTexts ai.OCRTexts, err error) {
|
||||
func (dExt *XTDriver) GetScreenTexts(opts ...option.ActionOption) (ocrTexts ai.OCRTexts, err error) {
|
||||
options := option.NewActionOptions(opts...)
|
||||
if options.ScreenShotFileName == "" {
|
||||
opts = append(opts, option.WithScreenShotFileName("get_screen_texts"))
|
||||
@@ -142,7 +142,7 @@ func (dExt *DriverExt) GetScreenTexts(opts ...option.ActionOption) (ocrTexts ai.
|
||||
return screenResult.Texts, nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) FindUIRectInUIKit(search string, opts ...option.ActionOption) (point ai.PointF, err error) {
|
||||
func (dExt *XTDriver) FindUIRectInUIKit(search string, opts ...option.ActionOption) (point ai.PointF, err error) {
|
||||
// find text using OCR
|
||||
if !builtin.IsPathExists(search) {
|
||||
return dExt.FindScreenText(search, opts...)
|
||||
@@ -152,7 +152,7 @@ func (dExt *DriverExt) FindUIRectInUIKit(search string, opts ...option.ActionOpt
|
||||
return
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) FindScreenText(text string, opts ...option.ActionOption) (point ai.PointF, err error) {
|
||||
func (dExt *XTDriver) FindScreenText(text string, opts ...option.ActionOption) (point ai.PointF, err error) {
|
||||
options := option.NewActionOptions(opts...)
|
||||
if options.ScreenShotFileName == "" {
|
||||
opts = append(opts, option.WithScreenShotFileName(fmt.Sprintf("find_screen_text_%s", text)))
|
||||
@@ -174,7 +174,7 @@ func (dExt *DriverExt) FindScreenText(text string, opts ...option.ActionOption)
|
||||
return
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) FindUIResult(opts ...option.ActionOption) (point ai.PointF, err error) {
|
||||
func (dExt *XTDriver) FindUIResult(opts ...option.ActionOption) (point ai.PointF, err error) {
|
||||
options := option.NewActionOptions(opts...)
|
||||
if options.ScreenShotFileName == "" {
|
||||
opts = append(opts, option.WithScreenShotFileName(
|
||||
@@ -199,7 +199,7 @@ func (dExt *DriverExt) FindUIResult(opts ...option.ActionOption) (point ai.Point
|
||||
}
|
||||
|
||||
// GetScreenShot takes screenshot and saves image file to $CWD/screenshots/ folder
|
||||
func (dExt *DriverExt) GetScreenShot(fileName string) (raw *bytes.Buffer, path string, err error) {
|
||||
func (dExt *XTDriver) GetScreenShot(fileName string) (raw *bytes.Buffer, path string, err error) {
|
||||
if raw, err = dExt.Driver.Screenshot(); err != nil {
|
||||
log.Error().Err(err).Msg("capture screenshot data failed")
|
||||
return nil, "", errors.Wrap(code.DeviceScreenShotError, err.Error())
|
||||
|
||||
@@ -19,7 +19,7 @@ func assertRelative(p float64) bool {
|
||||
}
|
||||
|
||||
// SwipeRelative swipe from relative position [fromX, fromY] to relative position [toX, toY]
|
||||
func (dExt *DriverExt) SwipeRelative(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) SwipeRelative(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
|
||||
if !assertRelative(fromX) || !assertRelative(fromY) ||
|
||||
!assertRelative(toX) || !assertRelative(toY) {
|
||||
return errors.Wrap(code.InvalidCaseError,
|
||||
@@ -45,25 +45,25 @@ func (dExt *DriverExt) SwipeRelative(fromX, fromY, toX, toY float64, opts ...opt
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) SwipeUp(opts ...option.ActionOption) (err error) {
|
||||
func (dExt *XTDriver) SwipeUp(opts ...option.ActionOption) (err error) {
|
||||
return dExt.SwipeRelative(0.5, 0.5, 0.5, 0.1, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) SwipeDown(opts ...option.ActionOption) (err error) {
|
||||
func (dExt *XTDriver) SwipeDown(opts ...option.ActionOption) (err error) {
|
||||
return dExt.SwipeRelative(0.5, 0.5, 0.5, 0.9, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) SwipeLeft(opts ...option.ActionOption) (err error) {
|
||||
func (dExt *XTDriver) SwipeLeft(opts ...option.ActionOption) (err error) {
|
||||
return dExt.SwipeRelative(0.5, 0.5, 0.1, 0.5, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) SwipeRight(opts ...option.ActionOption) (err error) {
|
||||
func (dExt *XTDriver) SwipeRight(opts ...option.ActionOption) (err error) {
|
||||
return dExt.SwipeRelative(0.5, 0.5, 0.9, 0.5, opts...)
|
||||
}
|
||||
|
||||
type Action func(driver *DriverExt) error
|
||||
type Action func(driver *XTDriver) error
|
||||
|
||||
func (dExt *DriverExt) LoopUntil(findAction, findCondition, foundAction Action, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) LoopUntil(findAction, findCondition, foundAction Action, opts ...option.ActionOption) error {
|
||||
actionOptions := option.NewActionOptions(opts...)
|
||||
maxRetryTimes := actionOptions.MaxRetryTimes
|
||||
interval := actionOptions.Interval
|
||||
@@ -86,7 +86,7 @@ func (dExt *DriverExt) LoopUntil(findAction, findCondition, foundAction Action,
|
||||
fmt.Sprintf("loop %d times, match find condition failed", maxRetryTimes))
|
||||
}
|
||||
|
||||
func prepareSwipeAction(dExt *DriverExt, params interface{}, opts ...option.ActionOption) func(d *DriverExt) error {
|
||||
func prepareSwipeAction(dExt *XTDriver, params interface{}, opts ...option.ActionOption) func(d *XTDriver) error {
|
||||
actionOptions := option.NewActionOptions(opts...)
|
||||
|
||||
var swipeDirection interface{}
|
||||
@@ -103,7 +103,7 @@ func prepareSwipeAction(dExt *DriverExt, params interface{}, opts ...option.Acti
|
||||
actionOptions.Steps = 10
|
||||
}
|
||||
|
||||
return func(d *DriverExt) error {
|
||||
return func(d *XTDriver) error {
|
||||
defer func() {
|
||||
// wait for swipe action to completed and content to load completely
|
||||
time.Sleep(time.Duration(1000*actionOptions.Interval) * time.Millisecond)
|
||||
@@ -138,7 +138,7 @@ func prepareSwipeAction(dExt *DriverExt, params interface{}, opts ...option.Acti
|
||||
}
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) swipeToTapTexts(texts []string, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) swipeToTapTexts(texts []string, opts ...option.ActionOption) error {
|
||||
if len(texts) == 0 {
|
||||
return errors.New("no text to tap")
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func (dExt *DriverExt) swipeToTapTexts(texts []string, opts ...option.ActionOpti
|
||||
actionOptions.Identifier = ""
|
||||
optionsWithoutIdentifier := actionOptions.Options()
|
||||
var point ai.PointF
|
||||
findTexts := func(d *DriverExt) error {
|
||||
findTexts := func(d *XTDriver) error {
|
||||
var err error
|
||||
screenResult, err := d.GetScreenResult(
|
||||
option.WithScreenShotOCR(true),
|
||||
@@ -172,7 +172,7 @@ func (dExt *DriverExt) swipeToTapTexts(texts []string, opts ...option.ActionOpti
|
||||
point = points[0].Center() // FIXME
|
||||
return nil
|
||||
}
|
||||
foundTextAction := func(d *DriverExt) error {
|
||||
foundTextAction := func(d *XTDriver) error {
|
||||
// tap text
|
||||
return d.TapAbsXY(point.X, point.Y, opts...)
|
||||
}
|
||||
@@ -181,7 +181,7 @@ func (dExt *DriverExt) swipeToTapTexts(texts []string, opts ...option.ActionOpti
|
||||
return dExt.LoopUntil(findAction, findTexts, foundTextAction, optionsWithoutIdentifier...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) SwipeToTapApp(appName string, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) SwipeToTapApp(appName string, opts ...option.ActionOption) error {
|
||||
// go to home screen
|
||||
if err := dExt.Driver.Homescreen(); err != nil {
|
||||
return errors.Wrap(err, "go to home screen failed")
|
||||
|
||||
@@ -11,13 +11,12 @@ import (
|
||||
func TestAndroidSwipeAction(t *testing.T) {
|
||||
setupAndroidAdbDriver(t)
|
||||
|
||||
dExt := driverExt.(*DriverExt)
|
||||
swipeAction := prepareSwipeAction(dExt, "up", option.WithDirection("down"))
|
||||
err := swipeAction(dExt)
|
||||
swipeAction := prepareSwipeAction(driverExt, "up", option.WithDirection("down"))
|
||||
err := swipeAction(driverExt)
|
||||
checkErr(t, err)
|
||||
|
||||
swipeAction = prepareSwipeAction(dExt, "up", option.WithCustomDirection(0.5, 0.5, 0.5, 0.9))
|
||||
err = swipeAction(dExt)
|
||||
swipeAction = prepareSwipeAction(driverExt, "up", option.WithCustomDirection(0.5, 0.5, 0.5, 0.9))
|
||||
err = swipeAction(driverExt)
|
||||
checkErr(t, err)
|
||||
}
|
||||
|
||||
@@ -34,7 +33,6 @@ func TestAndroidSwipeToTapTexts(t *testing.T) {
|
||||
err := driverExt.GetDriver().AppLaunch("com.ss.android.ugc.aweme")
|
||||
checkErr(t, err)
|
||||
|
||||
dExt := driverExt.(*DriverExt)
|
||||
err = dExt.swipeToTapTexts([]string{"点击进入直播间", "直播中"}, option.WithDirection("up"))
|
||||
err = driverExt.swipeToTapTexts([]string{"点击进入直播间", "直播中"}, option.WithDirection("up"))
|
||||
checkErr(t, err)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||
)
|
||||
|
||||
func (dExt *DriverExt) TapAbsXY(x, y float64, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) TapAbsXY(x, y float64, opts ...option.ActionOption) error {
|
||||
// tap on absolute coordinate [x, y]
|
||||
err := dExt.Driver.Tap(x, y, opts...)
|
||||
if err != nil {
|
||||
@@ -18,7 +18,7 @@ func (dExt *DriverExt) TapAbsXY(x, y float64, opts ...option.ActionOption) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) TapXY(x, y float64, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) TapXY(x, y float64, opts ...option.ActionOption) error {
|
||||
// tap on [x, y] percent of window size
|
||||
if x > 1 || y > 1 {
|
||||
return fmt.Errorf("x, y percentage should be <= 1, got x=%v, y=%v", x, y)
|
||||
@@ -33,7 +33,7 @@ func (dExt *DriverExt) TapXY(x, y float64, opts ...option.ActionOption) error {
|
||||
return dExt.TapAbsXY(x, y, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) TapByOCR(ocrText string, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) TapByOCR(ocrText string, opts ...option.ActionOption) error {
|
||||
actionOptions := option.NewActionOptions(opts...)
|
||||
if actionOptions.ScreenShotFileName == "" {
|
||||
opts = append(opts, option.WithScreenShotFileName(fmt.Sprintf("tap_by_ocr_%s", ocrText)))
|
||||
@@ -50,7 +50,7 @@ func (dExt *DriverExt) TapByOCR(ocrText string, opts ...option.ActionOption) err
|
||||
return dExt.TapAbsXY(point.X, point.Y, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) TapByUIDetection(opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) TapByUIDetection(opts ...option.ActionOption) error {
|
||||
options := option.NewActionOptions(opts...)
|
||||
|
||||
point, err := dExt.FindUIResult(opts...)
|
||||
@@ -64,11 +64,11 @@ func (dExt *DriverExt) TapByUIDetection(opts ...option.ActionOption) error {
|
||||
return dExt.TapAbsXY(point.X, point.Y, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) Tap(param string, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) Tap(param string, opts ...option.ActionOption) error {
|
||||
return dExt.TapOffset(param, 0, 0, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) TapOffset(param string, xOffset, yOffset float64, opts ...option.ActionOption) (err error) {
|
||||
func (dExt *XTDriver) TapOffset(param string, xOffset, yOffset float64, opts ...option.ActionOption) (err error) {
|
||||
options := option.NewActionOptions(opts...)
|
||||
|
||||
point, err := dExt.FindUIRectInUIKit(param, opts...)
|
||||
@@ -82,7 +82,7 @@ func (dExt *DriverExt) TapOffset(param string, xOffset, yOffset float64, opts ..
|
||||
return dExt.TapAbsXY(point.X+xOffset, point.Y+yOffset, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) DoubleTapXY(x, y float64, opts ...option.ActionOption) error {
|
||||
func (dExt *XTDriver) DoubleTapXY(x, y float64, opts ...option.ActionOption) error {
|
||||
// double tap on coordinate: [x, y] should be relative
|
||||
if x > 1 || y > 1 {
|
||||
return fmt.Errorf("x, y percentage should be < 1, got x=%v, y=%v", x, y)
|
||||
@@ -101,11 +101,11 @@ func (dExt *DriverExt) DoubleTapXY(x, y float64, opts ...option.ActionOption) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) DoubleTap(param string, opts ...option.ActionOption) (err error) {
|
||||
func (dExt *XTDriver) DoubleTap(param string, opts ...option.ActionOption) (err error) {
|
||||
return dExt.DoubleTapOffset(param, 0, 0, opts...)
|
||||
}
|
||||
|
||||
func (dExt *DriverExt) DoubleTapOffset(param string, xOffset, yOffset float64, opts ...option.ActionOption) (err error) {
|
||||
func (dExt *XTDriver) DoubleTapOffset(param string, xOffset, yOffset float64, opts ...option.ActionOption) (err error) {
|
||||
point, err := dExt.FindUIRectInUIKit(param)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,35 +4,34 @@ package uixt
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
)
|
||||
|
||||
var iosDevice *IOSDevice
|
||||
var (
|
||||
iosDevice *IOSDevice
|
||||
iosDriverExt *XTDriver
|
||||
)
|
||||
|
||||
func init() {
|
||||
iosDevice, _ = NewIOSDevice()
|
||||
driver, _ := iosDevice.NewDriver()
|
||||
iosDriverExt = NewXTDriver(driver,
|
||||
ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
}
|
||||
|
||||
func TestDriverExt_TapXY(t *testing.T) {
|
||||
driverExt, err := iosDevice.NewDriver()
|
||||
checkErr(t, err)
|
||||
|
||||
err = driverExt.TapXY(0.4, 0.5)
|
||||
err := iosDriverExt.TapXY(0.4, 0.5)
|
||||
checkErr(t, err)
|
||||
}
|
||||
|
||||
func TestDriverExt_TapAbsXY(t *testing.T) {
|
||||
driverExt, err := iosDevice.NewDriver()
|
||||
checkErr(t, err)
|
||||
|
||||
err = driverExt.TapAbsXY(100, 300)
|
||||
err := iosDriverExt.TapAbsXY(100, 300)
|
||||
checkErr(t, err)
|
||||
}
|
||||
|
||||
func TestDriverExt_TapWithOCR(t *testing.T) {
|
||||
driverExt, err := iosDevice.NewDriver()
|
||||
checkErr(t, err)
|
||||
|
||||
// 需要点击文字上方的图标
|
||||
err = driverExt.TapOffset("抖音", 0, -20)
|
||||
err := iosDriverExt.TapOffset("抖音", 0, -20)
|
||||
checkErr(t, err)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func TestNewDriverExt(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
driverExt, _ := NewDriverExt(driver,
|
||||
driverExt := NewXTDriver(driver,
|
||||
ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
|
||||
texts, _ := driverExt.GetScreenTexts()
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/httprunner/v5/code"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/types"
|
||||
)
|
||||
@@ -94,21 +93,15 @@ func (dev *HarmonyDevice) GetPackageInfo(packageName string) (types.AppInfo, err
|
||||
return types.AppInfo{}, nil
|
||||
}
|
||||
|
||||
func (dev *HarmonyDevice) NewDriver() (IDriverExt, error) {
|
||||
func (dev *HarmonyDevice) NewDriver() (IDriver, error) {
|
||||
// init harmony driver
|
||||
driver, err := NewHDCDriver(dev)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init harmony driver failed")
|
||||
}
|
||||
driverExt, err := NewDriverExt(driver, ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init harmony driver ext failed")
|
||||
}
|
||||
|
||||
// setup driver
|
||||
if err := driverExt.GetDriver().Setup(); err != nil {
|
||||
if err := driver.Setup(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return driverExt, nil
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
@@ -5,9 +5,14 @@ package uixt
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
)
|
||||
|
||||
var hdcDriver *HDCDriver
|
||||
var (
|
||||
hdcDriver *HDCDriver
|
||||
hdcDriverExt *XTDriver
|
||||
)
|
||||
|
||||
func setupHarmonyDevice(t *testing.T) {
|
||||
device, err := NewHarmonyDevice()
|
||||
@@ -18,6 +23,8 @@ func setupHarmonyDevice(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hdcDriverExt = NewXTDriver(hdcDriver,
|
||||
ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
}
|
||||
|
||||
func TestWindowSize(t *testing.T) {
|
||||
@@ -31,7 +38,7 @@ func TestWindowSize(t *testing.T) {
|
||||
|
||||
func TestHarmonyTap(t *testing.T) {
|
||||
setupHarmonyDevice(t)
|
||||
err := hdcDriver.TapAbsXY(200, 2000)
|
||||
err := hdcDriverExt.TapAbsXY(200, 2000)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -39,7 +46,7 @@ func TestHarmonyTap(t *testing.T) {
|
||||
|
||||
func TestHarmonySwipe(t *testing.T) {
|
||||
setupHarmonyDevice(t)
|
||||
err := hdcDriver.SwipeLeft()
|
||||
err := hdcDriverExt.SwipeLeft()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import (
|
||||
|
||||
"github.com/httprunner/httprunner/v5/code"
|
||||
"github.com/httprunner/httprunner/v5/internal/builtin"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/types"
|
||||
)
|
||||
@@ -203,8 +202,8 @@ func (dev *IOSDevice) getAppInfo(packageName string) (appInfo types.AppInfo, err
|
||||
return types.AppInfo{}, fmt.Errorf("not found App by bundle id: %s", packageName)
|
||||
}
|
||||
|
||||
func (dev *IOSDevice) NewDriver() (driverExt IDriverExt, err error) {
|
||||
driver, err := NewWDADriver(dev)
|
||||
func (dev *IOSDevice) NewDriver() (driver IDriver, err error) {
|
||||
driver, err = NewWDADriver(dev)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to init WDA driver")
|
||||
}
|
||||
@@ -230,18 +229,11 @@ func (dev *IOSDevice) NewDriver() (driverExt IDriverExt, err error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
driverExt, err = NewDriverExt(driver, ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init ios driver ext failed")
|
||||
}
|
||||
|
||||
// setup driver
|
||||
if err := driverExt.GetDriver().Setup(); err != nil {
|
||||
if err := driver.Setup(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return driverExt, nil
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
func (dev *IOSDevice) Install(appPath string, opts ...option.InstallOption) (err error) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/types"
|
||||
)
|
||||
@@ -17,7 +18,7 @@ import (
|
||||
var (
|
||||
bundleId = "com.apple.Preferences"
|
||||
driver IDriver
|
||||
iOSDriverExt IDriverExt
|
||||
iOSDriverExt *XTDriver
|
||||
)
|
||||
|
||||
func setup(t *testing.T) {
|
||||
@@ -30,10 +31,11 @@ func setup(t *testing.T) {
|
||||
}
|
||||
capabilities := option.NewCapabilities()
|
||||
capabilities.WithDefaultAlertAction(option.AlertActionAccept)
|
||||
iOSDriverExt, err = device.NewDriver()
|
||||
driver, err = device.NewDriver()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
iOSDriverExt = NewXTDriver(driver, ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
}
|
||||
|
||||
func TestViaUSB(t *testing.T) {
|
||||
|
||||
@@ -22,7 +22,7 @@ type timeLog struct {
|
||||
}
|
||||
|
||||
type EndToEndDelay struct {
|
||||
driver *DriverExt
|
||||
driver *XTDriver
|
||||
StartTime string `json:"startTime"`
|
||||
EndTime string `json:"endTime"`
|
||||
Interval int `json:"interval"` // seconds
|
||||
@@ -30,7 +30,7 @@ type EndToEndDelay struct {
|
||||
Timelines []timeLog `json:"timelines"`
|
||||
}
|
||||
|
||||
func CollectEndToEndDelay(dExt *DriverExt, opts ...option.ActionOption) {
|
||||
func CollectEndToEndDelay(dExt *XTDriver, opts ...option.ActionOption) {
|
||||
dataOptions := option.NewActionOptions(opts...)
|
||||
startTime := time.Now()
|
||||
|
||||
|
||||
16
runner.go
16
runner.go
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/httprunner/httprunner/v5/internal/sdk"
|
||||
"github.com/httprunner/httprunner/v5/internal/version"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
)
|
||||
|
||||
// Run starts to run testcase with default configs.
|
||||
@@ -281,7 +282,7 @@ func (r *HRPRunner) NewCaseRunner(testcase TestCase) (*CaseRunner, error) {
|
||||
TestCase: testcase,
|
||||
hrpRunner: r,
|
||||
parser: newParser(),
|
||||
uixtDrivers: make(map[string]uixt.IDriverExt),
|
||||
uixtDrivers: make(map[string]*uixt.XTDriver),
|
||||
}
|
||||
config := testcase.Config.Get()
|
||||
|
||||
@@ -336,7 +337,7 @@ type CaseRunner struct {
|
||||
parametersIterator *ParametersIterator
|
||||
|
||||
// UI automation clients for iOS and Android, key is udid/serial
|
||||
uixtDrivers map[string]uixt.IDriverExt
|
||||
uixtDrivers map[string]*uixt.XTDriver
|
||||
}
|
||||
|
||||
func (r *CaseRunner) GetParametersIterator() *ParametersIterator {
|
||||
@@ -430,11 +431,12 @@ func (r *CaseRunner) parseConfig() (parsedConfig *TConfig, err error) {
|
||||
if err := device.Setup(); err != nil {
|
||||
return nil, errors.Wrap(err, "setup android device failed")
|
||||
}
|
||||
driverExt, err := device.NewDriver()
|
||||
driver, err := device.NewDriver()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init android driver failed")
|
||||
}
|
||||
|
||||
driverExt := uixt.NewXTDriver(driver, ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
r.uixtDrivers[androidDevice.Options.SerialNumber] = driverExt
|
||||
}
|
||||
// parse iOS devices config
|
||||
@@ -452,11 +454,12 @@ func (r *CaseRunner) parseConfig() (parsedConfig *TConfig, err error) {
|
||||
if err := device.Setup(); err != nil {
|
||||
return nil, errors.Wrap(err, "setup ios device failed")
|
||||
}
|
||||
driverExt, err := device.NewDriver()
|
||||
driver, err := device.NewDriver()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init ios driver failed")
|
||||
}
|
||||
|
||||
driverExt := uixt.NewXTDriver(driver, ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
r.uixtDrivers[iosDevice.Options.UDID] = driverExt
|
||||
}
|
||||
// parse harmony devices config
|
||||
@@ -474,11 +477,12 @@ func (r *CaseRunner) parseConfig() (parsedConfig *TConfig, err error) {
|
||||
if err := device.Setup(); err != nil {
|
||||
return nil, errors.Wrap(err, "setup harmony device failed")
|
||||
}
|
||||
driverExt, err := device.NewDriver()
|
||||
driver, err := device.NewDriver()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init harmony driver failed")
|
||||
}
|
||||
|
||||
driverExt := uixt.NewXTDriver(driver, ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
r.uixtDrivers[harmonyDevice.Options.ConnectKey] = driverExt
|
||||
}
|
||||
|
||||
@@ -521,7 +525,7 @@ func (r *CaseRunner) parseDeviceConfig(device interface{}, configVariables map[s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *CaseRunner) GetUIXTDriver(serial string) (driver uixt.IDriverExt, err error) {
|
||||
func (r *CaseRunner) GetUIXTDriver(serial string) (driver *uixt.XTDriver, err error) {
|
||||
for key, driver := range r.uixtDrivers {
|
||||
// return the driver with the same serial
|
||||
if key == serial {
|
||||
|
||||
@@ -10,10 +10,11 @@ import (
|
||||
|
||||
"github.com/httprunner/httprunner/v5/code"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||
)
|
||||
|
||||
var uiClients = make(map[string]uixt.IDriverExt) // UI automation clients for iOS and Android, key is udid/serial
|
||||
var uiClients = make(map[string]*uixt.XTDriver) // UI automation clients for iOS and Android, key is udid/serial
|
||||
|
||||
func (r *Router) HandleDeviceContext() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
@@ -66,9 +67,13 @@ func (r *Router) HandleDeviceContext() gin.HandlerFunc {
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Set("driver", driver)
|
||||
|
||||
driverExt := uixt.NewXTDriver(driver,
|
||||
ai.WithCVService(ai.CVServiceTypeVEDEM))
|
||||
|
||||
c.Set("driver", driverExt)
|
||||
// cache driver
|
||||
uiClients[serial] = driver
|
||||
uiClients[serial] = driverExt
|
||||
default:
|
||||
c.JSON(http.StatusBadRequest, HttpResponse{
|
||||
Code: code.GetErrorCode(code.InvalidParamError),
|
||||
@@ -81,13 +86,13 @@ func (r *Router) HandleDeviceContext() gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func GetContextDriver(c *gin.Context) (uixt.IDriverExt, error) {
|
||||
func GetContextDriver(c *gin.Context) (*uixt.XTDriver, error) {
|
||||
driverObj, exists := c.Get("driver")
|
||||
if !exists {
|
||||
handlerInitDeviceDriverFailedContext(c)
|
||||
return nil, fmt.Errorf("driver not found")
|
||||
}
|
||||
dExt := driverObj.(*uixt.DriverExt)
|
||||
dExt := driverObj.(*uixt.XTDriver)
|
||||
return dExt, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -780,7 +780,7 @@ func runStepMobileUI(s *SessionRunner, step IStep) (stepResult *StepResult, err
|
||||
return stepResult, nil
|
||||
}
|
||||
|
||||
func validateUI(ud uixt.IDriverExt, iValidators []interface{}) (validateResults []*ValidationResult, err error) {
|
||||
func validateUI(ud *uixt.XTDriver, iValidators []interface{}) (validateResults []*ValidationResult, err error) {
|
||||
for _, iValidator := range iValidators {
|
||||
validator, ok := iValidator.(Validator)
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user