diff --git a/examples/uitest/harmony_e2e_delay_test.go b/examples/uitest/harmony_e2e_delay_test.go new file mode 100644 index 00000000..7ec4d106 --- /dev/null +++ b/examples/uitest/harmony_e2e_delay_test.go @@ -0,0 +1,59 @@ +package uitest + +import ( + "testing" + + "github.com/httprunner/httprunner/v4/hrp" + "github.com/httprunner/httprunner/v4/hrp/pkg/uixt" +) + +func TestHarmonyDouyinE2E(t *testing.T) { + testCase := &hrp.TestCase{ + Config: hrp.NewConfig("直播_抖音_端到端时延_harmony"). + WithVariables(map[string]interface{}{ + "device": "${ENV(SerialNumber)}", + "ups": "${ENV(LIVEUPLIST)}", + }). + SetHarmony(uixt.WithConnectKey("$device"), uixt.WithLogOn(true)), + TestSteps: []hrp.IStep{ + hrp.NewStep("启动抖音"). + Harmony(). + AppTerminate("com.ss.hm.ugc.aweme"). + SwipeToTapApp("com.ss.hm.ugc.aweme"). + Home(). + SwipeToTapApp( + "抖音", + uixt.WithMaxRetryTimes(5), + uixt.WithTapOffset(0, -50), + ). + Sleep(20). + Validate(). + AssertOCRExists("推荐", "进入抖音失败"), + hrp.NewStep("点击放大镜"). + Harmony(). + TapXY(0.9, 0.08). + Sleep(5), + hrp.NewStep("输入账号名称"). + Harmony(). + Input("$ups"). + Sleep(5), + hrp.NewStep("点击搜索"). + Harmony(). + TapByOCR("搜索"). + Sleep(5), + hrp.NewStep("端到端采集").Loop(5). + Harmony(). + TapByOCR( + "直播中", + uixt.WithIgnoreNotFoundError(true), + uixt.WithIndex(-1), + ). + EndToEndDelay(uixt.WithInterval(5), uixt.WithTimeout(120)). + TapByUITypes(uixt.WithScreenShotUITypes("close")), + }, + } + + if err := testCase.Dump2JSON("harmony_e2e_delay_test.json"); err != nil { + t.Fatal(err) + } +} diff --git a/hrp/config.go b/hrp/config.go index 6857aee1..b5f9cbc7 100644 --- a/hrp/config.go +++ b/hrp/config.go @@ -31,6 +31,7 @@ type TConfig struct { WebSocketSetting *WebSocketConfig `json:"websocket,omitempty" yaml:"websocket,omitempty"` IOS []*uixt.IOSDevice `json:"ios,omitempty" yaml:"ios,omitempty"` Android []*uixt.AndroidDevice `json:"android,omitempty" yaml:"android,omitempty"` + Harmony []*uixt.HarmonyDevice `json:"harmony,omitempty" yaml:"harmony,omitempty"` RequestTimeout float32 `json:"request_timeout,omitempty" yaml:"request_timeout,omitempty"` // request timeout in seconds CaseTimeout float32 `json:"case_timeout,omitempty" yaml:"case_timeout,omitempty"` // testcase timeout in seconds Export []string `json:"export,omitempty" yaml:"export,omitempty"` @@ -129,6 +130,27 @@ func (c *TConfig) SetIOS(options ...uixt.IOSDeviceOption) *TConfig { return c } +func (c *TConfig) SetHarmony(options ...uixt.HarmonyDeviceOption) *TConfig { + harmonyOptions := &uixt.HarmonyDevice{} + for _, option := range options { + option(harmonyOptions) + } + + // each device can have its own settings + if harmonyOptions.ConnectKey != "" { + c.Harmony = append(c.Harmony, harmonyOptions) + return c + } + + // device UDID is not specified, settings will be shared + if len(c.Harmony) == 0 { + c.Harmony = append(c.Harmony, harmonyOptions) + } else { + c.Harmony[0] = harmonyOptions + } + return c +} + func (c *TConfig) SetAndroid(options ...uixt.AndroidDeviceOption) *TConfig { uiaOptions := &uixt.AndroidDevice{} for _, option := range options { diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index 3cf3c031..9ff6a4d6 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v5.0.0-beta-2409212048 \ No newline at end of file +v5.0.0-beta-2409251315 \ No newline at end of file diff --git a/hrp/pkg/uixt/harmony_hdc_driver.go b/hrp/pkg/uixt/harmony_hdc_driver.go index 7aa89d8f..76f8462f 100644 --- a/hrp/pkg/uixt/harmony_hdc_driver.go +++ b/hrp/pkg/uixt/harmony_hdc_driver.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "os" + "regexp" "time" "code.byted.org/iesqa/ghdc" @@ -17,6 +18,13 @@ type hdcDriver struct { uiDriver *ghdc.UIDriver } +type PowerStatus string + +const ( + POWER_STATUS_SUSPEND PowerStatus = "POWER_STATUS_SUSPEND" + POWER_STATUS_ON PowerStatus = "POWER_STATUS_ON" +) + func newHarmonyDriver(device *ghdc.Device) (driver *hdcDriver, err error) { driver = new(hdcDriver) driver.device = device @@ -32,6 +40,7 @@ func newHarmonyDriver(device *ghdc.Device) (driver *hdcDriver, err error) { func (hd *hdcDriver) NewSession(capabilities Capabilities) (SessionInfo, error) { hd.Driver.session.Init() + hd.Unlock() return SessionInfo{}, errDriverNotImplemented } @@ -88,11 +97,23 @@ func (hd *hdcDriver) Homescreen() error { func (hd *hdcDriver) Unlock() (err error) { // Todo 检查是否锁屏 hdc shell hidumper -s RenderService -a screen - err = hd.uiDriver.PressPowerKey() + screenInfo, err := hd.device.RunShellCommand("hidumper", "-s", "RenderService", "-a", "screen") if err != nil { return err } - return hd.Swipe(500, 2000, 500, 500) + re := regexp.MustCompile(`powerstatus=([\w_]+)`) + match := re.FindStringSubmatch(screenInfo) + if len(match) <= 1 { + return fmt.Errorf("failed to unlock; failed to find powerstatus") + } + if match[1] == string(POWER_STATUS_SUSPEND) { + err = hd.uiDriver.PressPowerKey() + if err != nil { + return err + } + } + + return hd.Swipe(500, 1500, 500, 500) } func (hd *hdcDriver) AppLaunch(packageName string) error { diff --git a/hrp/step_request.go b/hrp/step_request.go index 40821733..bd1fe8c1 100644 --- a/hrp/step_request.go +++ b/hrp/step_request.go @@ -762,6 +762,14 @@ func (s *StepRequest) IOS() *StepMobile { } } +// Harmony creates a new harmony action +func (s *StepRequest) Harmony() *StepMobile { + s.step.Harmony = &MobileUI{} + return &StepMobile{ + step: s.step, + } +} + // Shell creates a new shell action func (s *StepRequest) Shell(content string) *StepShell { s.step.Shell = &Shell{