mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 23:51:25 +08:00
refactor: driver ScreenShot
This commit is contained in:
@@ -1 +1 @@
|
|||||||
v5.0.0+2502111749
|
v5.0.0+2502111813
|
||||||
|
|||||||
@@ -520,13 +520,26 @@ func (ad *ADBDriver) SetRotation(rotation types.Rotation) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) ScreenShot() (raw *bytes.Buffer, err error) {
|
func (ad *ADBDriver) ScreenShot(opts ...option.ActionOption) (raw *bytes.Buffer, err error) {
|
||||||
resp, err := ad.runShellCommand("screencap", "-p")
|
resp, err := ad.runShellCommand("screencap", "-p")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "adb screencap failed")
|
return nil, errors.Wrapf(code.DeviceScreenShotError,
|
||||||
|
"adb screencap failed %v", err)
|
||||||
|
}
|
||||||
|
raw = bytes.NewBuffer([]byte(resp))
|
||||||
|
|
||||||
|
actionOptions := option.NewActionOptions(opts...)
|
||||||
|
if actionOptions.ScreenShotFileName != "" {
|
||||||
|
// save screenshot to file
|
||||||
|
path, err := saveScreenShot(raw, actionOptions.ScreenShotFileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(code.DeviceScreenShotError,
|
||||||
|
"save screenshot file failed %v", err)
|
||||||
|
}
|
||||||
|
log.Info().Str("path", path).Msg("screenshot saved")
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes.NewBuffer([]byte(resp)), nil
|
return raw, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ad *ADBDriver) Source(srcOpt ...option.SourceOption) (source string, err error) {
|
func (ad *ADBDriver) Source(srcOpt ...option.SourceOption) (source string, err error) {
|
||||||
|
|||||||
@@ -533,10 +533,10 @@ func (ud *UIA2Driver) Rotation() (rotation types.Rotation, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ud *UIA2Driver) ScreenShot() (raw *bytes.Buffer, err error) {
|
func (ud *UIA2Driver) ScreenShot(opts ...option.ActionOption) (raw *bytes.Buffer, err error) {
|
||||||
// https://bytedance.larkoffice.com/docx/C8qEdmSHnoRvMaxZauocMiYpnLh
|
// https://bytedance.larkoffice.com/docx/C8qEdmSHnoRvMaxZauocMiYpnLh
|
||||||
// ui2截图受内存影响,改为adb截图
|
// ui2截图受内存影响,改为adb截图
|
||||||
return ud.ADBDriver.ScreenShot()
|
return ud.ADBDriver.ScreenShot(opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ud *UIA2Driver) Source(srcOpt ...option.SourceOption) (source string, err error) {
|
func (ud *UIA2Driver) Source(srcOpt ...option.SourceOption) (source string, err error) {
|
||||||
|
|||||||
+2
-3
@@ -43,7 +43,7 @@ type IDriver interface {
|
|||||||
BatteryInfo() (types.BatteryInfo, error)
|
BatteryInfo() (types.BatteryInfo, error)
|
||||||
ForegroundInfo() (app types.AppInfo, err error)
|
ForegroundInfo() (app types.AppInfo, err error)
|
||||||
WindowSize() (types.Size, error)
|
WindowSize() (types.Size, error)
|
||||||
ScreenShot() (*bytes.Buffer, error)
|
ScreenShot(opts ...option.ActionOption) (*bytes.Buffer, error)
|
||||||
ScreenRecord(duration time.Duration) (videoPath string, err error)
|
ScreenRecord(duration time.Duration) (videoPath string, err error)
|
||||||
Source(srcOpt ...option.SourceOption) (string, error)
|
Source(srcOpt ...option.SourceOption) (string, error)
|
||||||
Orientation() (orientation types.Orientation, err error)
|
Orientation() (orientation types.Orientation, err error)
|
||||||
@@ -97,11 +97,10 @@ var _ IDriverExt = (*XTDriver)(nil)
|
|||||||
type IDriverExt interface {
|
type IDriverExt interface {
|
||||||
GetScreenResult(opts ...option.ActionOption) (screenResult *ScreenResult, err error)
|
GetScreenResult(opts ...option.ActionOption) (screenResult *ScreenResult, err error)
|
||||||
GetScreenTexts(opts ...option.ActionOption) (ocrTexts ai.OCRTexts, err error)
|
GetScreenTexts(opts ...option.ActionOption) (ocrTexts ai.OCRTexts, err error)
|
||||||
GetScreenShot(fileName string) (raw *bytes.Buffer, path string, err error)
|
|
||||||
|
|
||||||
// tap with AI
|
// tap with AI
|
||||||
TapByOCR(text string, opts ...option.ActionOption) error
|
TapByOCR(text string, opts ...option.ActionOption) error
|
||||||
TapByCV(opts ...option.ActionOption) error
|
TapByCV(opts ...option.ActionOption) error // TODO: refactor
|
||||||
|
|
||||||
// swipe
|
// swipe
|
||||||
SwipeRelative(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
|
SwipeRelative(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ func (dExt *XTDriver) GetScreenResult(opts ...option.ActionOption) (screenResult
|
|||||||
|
|
||||||
// get screenshot info with retry
|
// get screenshot info with retry
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
bufSource, imagePath, err = dExt.GetScreenShot(fileName)
|
imagePath = filepath.Join(config.ScreenShotsPath, fileName)
|
||||||
|
bufSource, err = dExt.IDriver.ScreenShot(option.WithScreenShotFileName(imagePath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lastErr = err
|
lastErr = err
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 1)
|
||||||
@@ -188,24 +189,6 @@ func (dExt *XTDriver) FindUIResult(opts ...option.ActionOption) (point ai.PointF
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScreenShot takes screenshot and saves image file to $CWD/screenshots/ folder
|
|
||||||
func (dExt *XTDriver) GetScreenShot(fileName string) (raw *bytes.Buffer, path string, err error) {
|
|
||||||
if raw, err = dExt.ScreenShot(); err != nil {
|
|
||||||
log.Error().Err(err).Msg("capture screenshot data failed")
|
|
||||||
return nil, "", errors.Wrap(code.DeviceScreenShotError, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// save screenshot to file
|
|
||||||
path = filepath.Join(config.ScreenShotsPath, fileName)
|
|
||||||
path, err = saveScreenShot(raw, path)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("save screenshot file failed")
|
|
||||||
return nil, "", errors.Wrap(code.DeviceScreenShotError,
|
|
||||||
fmt.Sprintf("save screenshot file failed: %s", err.Error()))
|
|
||||||
}
|
|
||||||
return raw, path, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// saveScreenShot saves compressed image file with file name
|
// saveScreenShot saves compressed image file with file name
|
||||||
func saveScreenShot(raw *bytes.Buffer, fileName string) (string, error) {
|
func saveScreenShot(raw *bytes.Buffer, fileName string) (string, error) {
|
||||||
// notice: screenshot data is a stream, so we need to copy it to a new buffer
|
// notice: screenshot data is a stream, so we need to copy it to a new buffer
|
||||||
|
|||||||
@@ -3,21 +3,21 @@
|
|||||||
package uixt
|
package uixt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/httprunner/httprunner/v5/internal/config"
|
||||||
|
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetScreenShot(t *testing.T) {
|
func TestGetScreenShot(t *testing.T) {
|
||||||
setupAndroidAdbDriver(t)
|
setupAndroidAdbDriver(t)
|
||||||
|
|
||||||
fileName := "test_screenshot"
|
imagePath := filepath.Join(config.ScreenShotsPath, "test_screenshot")
|
||||||
_, path, err := driverExt.GetScreenShot(fileName)
|
_, err := driverExt.IDriver.ScreenShot(option.WithScreenShotFileName(imagePath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("GetScreenShot failed: %v", err)
|
t.Fatalf("GetScreenShot failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if path == "" {
|
t.Logf("screenshot saved at: %s", imagePath)
|
||||||
t.Fatal("screenshot path is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Logf("screenshot saved at: %s", path)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.byted.org/iesqa/ghdc"
|
"code.byted.org/iesqa/ghdc"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
|
"github.com/httprunner/httprunner/v5/code"
|
||||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||||
"github.com/httprunner/httprunner/v5/pkg/uixt/types"
|
"github.com/httprunner/httprunner/v5/pkg/uixt/types"
|
||||||
)
|
)
|
||||||
@@ -217,13 +219,13 @@ func (hd *HDCDriver) PressHarmonyKeyCode(keyCode ghdc.KeyCode) (err error) {
|
|||||||
return hd.uiDriver.PressKey(keyCode)
|
return hd.uiDriver.PressKey(keyCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hd *HDCDriver) ScreenShot() (*bytes.Buffer, error) {
|
func (hd *HDCDriver) ScreenShot(opts ...option.ActionOption) (*bytes.Buffer, error) {
|
||||||
tempDir := os.TempDir()
|
tempDir := os.TempDir()
|
||||||
screenshotPath := fmt.Sprintf("%s/screenshot_%d.png", tempDir, time.Now().Unix())
|
screenshotPath := fmt.Sprintf("%s/screenshot_%d.png", tempDir, time.Now().Unix())
|
||||||
err := hd.uiDriver.Screenshot(screenshotPath)
|
err := hd.uiDriver.Screenshot(screenshotPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("failed to screenshot")
|
return nil, errors.Wrapf(code.DeviceScreenShotError,
|
||||||
return nil, err
|
"hdc screencap failed %v", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = os.Remove(screenshotPath)
|
_ = os.Remove(screenshotPath)
|
||||||
@@ -234,7 +236,20 @@ func (hd *HDCDriver) ScreenShot() (*bytes.Buffer, error) {
|
|||||||
log.Error().Err(err).Msg("failed to screenshot")
|
log.Error().Err(err).Msg("failed to screenshot")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return bytes.NewBuffer(raw), nil
|
rawBuffer := bytes.NewBuffer(raw)
|
||||||
|
|
||||||
|
actionOptions := option.NewActionOptions(opts...)
|
||||||
|
if actionOptions.ScreenShotFileName != "" {
|
||||||
|
// save screenshot to file
|
||||||
|
path, err := saveScreenShot(rawBuffer, actionOptions.ScreenShotFileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(code.DeviceScreenShotError,
|
||||||
|
"save screenshot file failed %v", err)
|
||||||
|
}
|
||||||
|
log.Info().Str("path", path).Msg("screenshot saved")
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawBuffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hd *HDCDriver) Source(srcOpt ...option.SourceOption) (string, error) {
|
func (hd *HDCDriver) Source(srcOpt ...option.SourceOption) (string, error) {
|
||||||
|
|||||||
@@ -280,19 +280,31 @@ func (wd *WDADriver) Screen() (screen ai.Screen, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *WDADriver) ScreenShot() (raw *bytes.Buffer, err error) {
|
func (wd *WDADriver) ScreenShot(opts ...option.ActionOption) (raw *bytes.Buffer, err error) {
|
||||||
// [[FBRoute GET:@"/screenshot"] respondWithTarget:self action:@selector(handleGetScreenshot:)]
|
// [[FBRoute GET:@"/screenshot"] respondWithTarget:self action:@selector(handleGetScreenshot:)]
|
||||||
// [[FBRoute GET:@"/screenshot"].withoutSession respondWithTarget:self action:@selector(handleGetScreenshot:)]
|
// [[FBRoute GET:@"/screenshot"].withoutSession respondWithTarget:self action:@selector(handleGetScreenshot:)]
|
||||||
var rawResp DriverRawResponse
|
rawResp, err := wd.httpGET("/session", wd.Session.ID, "/screenshot")
|
||||||
if rawResp, err = wd.httpGET("/session", wd.Session.ID, "/screenshot"); err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(code.DeviceScreenShotError,
|
return nil, errors.Wrap(code.DeviceScreenShotError,
|
||||||
fmt.Sprintf("get WDA screenshot data failed: %v", err))
|
fmt.Sprintf("WDA screenshot failed %v", err))
|
||||||
}
|
}
|
||||||
|
raw, err = rawResp.ValueDecodeAsBase64()
|
||||||
if raw, err = rawResp.ValueDecodeAsBase64(); err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(code.DeviceScreenShotError,
|
return nil, errors.Wrap(code.DeviceScreenShotError,
|
||||||
fmt.Sprintf("decode WDA screenshot data failed: %v", err))
|
fmt.Sprintf("decode WDA screenshot data failed: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actionOptions := option.NewActionOptions(opts...)
|
||||||
|
if actionOptions.ScreenShotFileName != "" {
|
||||||
|
// save screenshot to file
|
||||||
|
path, err := saveScreenShot(raw, actionOptions.ScreenShotFileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(code.DeviceScreenShotError,
|
||||||
|
"save screenshot file failed %v", err)
|
||||||
|
}
|
||||||
|
log.Info().Str("path", path).Msg("screenshot saved")
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user