refactor: TakeScreenShot saves all screenshots

This commit is contained in:
lilong.129
2023-04-16 22:11:35 +08:00
parent 2644c24fae
commit 0a59ced824
9 changed files with 50 additions and 72 deletions

View File

@@ -150,11 +150,7 @@ func NewWorldCupLive(device uixt.Device, matchName, bundleID string, duration, i
func (wc *WorldCupLive) getCurrentLiveTime(utcTime time.Time) error {
utcTimeStr := utcTime.Format("15:04:05")
fileName := filepath.Join(
wc.resultDir, "screenshot", utcTimeStr)
ocrTexts, err := wc.driver.GetTextsByOCR(
uixt.WithScreenShot(fileName),
)
ocrTexts, err := wc.driver.GetTextsByOCR()
if err != nil {
log.Error().Err(err).Msg("get ocr texts failed")
return err

View File

@@ -3,9 +3,10 @@ package adb
import (
"fmt"
"io/ioutil"
"time"
"github.com/spf13/cobra"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
)
var screencapAndroidDevicesCmd = &cobra.Command{
@@ -22,7 +23,7 @@ var screencapAndroidDevicesCmd = &cobra.Command{
return err
}
filepath := fmt.Sprintf("screencap_%d.png", time.Now().Unix())
filepath := fmt.Sprintf("%s.png", builtin.GenNameWithTimestamp("screencap_"))
if err = ioutil.WriteFile(filepath, res, 0o644); err != nil {
return err
}

View File

@@ -443,3 +443,7 @@ func Sign(ver string, ak string, sk string, body []byte) string {
signResult := sha256HMAC(signKey, body)
return fmt.Sprintf("%v/%v", signKeyInfo, string(signResult))
}
func GenNameWithTimestamp(prefix string) string {
return fmt.Sprintf("%s%d", prefix, time.Now().Unix())
}

View File

@@ -11,6 +11,8 @@ import (
"time"
"github.com/rs/zerolog/log"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
)
type DeviceFileInfo struct {
@@ -538,7 +540,7 @@ func (d *Device) InstallAPK(apk io.ReadSeeker) (string, error) {
return string(raw), err
}
remote := fmt.Sprintf("/data/local/tmp/gadb_remote_%d.apk", time.Now().Unix())
remote := fmt.Sprintf("/data/local/tmp/%s.apk", builtin.GenNameWithTimestamp("gadb_remote_"))
err := d.Push(apk, remote, time.Now())
if err != nil {
return "", fmt.Errorf("error pushing: %v", err)

View File

@@ -217,7 +217,7 @@ type DriverExt struct {
doneMjpegStream chan bool
scale float64
ocrService OCRService // used to get text from image
ScreenShots []string // save screenshots path
screenShots []string // cache screenshot paths
CVArgs
}
@@ -253,7 +253,9 @@ func NewDriverExt(device Device, driver WebDriver) (dExt *DriverExt, err error)
return dExt, nil
}
func (dExt *DriverExt) takeScreenShot() (raw *bytes.Buffer, err error) {
// TakeScreenShot takes screenshot and saves image file to $CWD/screenshots/ folder
// if fileName is empty, it will not save image file and only return raw image data
func (dExt *DriverExt) TakeScreenShot(fileName ...string) (raw *bytes.Buffer, err error) {
// wait for action done
time.Sleep(500 * time.Millisecond)
@@ -263,14 +265,27 @@ func (dExt *DriverExt) takeScreenShot() (raw *bytes.Buffer, err error) {
return dExt.frame, nil
}
if raw, err = dExt.Driver.Screenshot(); err != nil {
log.Error().Err(err).Msg("takeScreenShot failed")
log.Error().Err(err).Msg("capture screenshot data failed")
return nil, err
}
// save screenshot to file
if len(fileName) > 0 && fileName[0] != "" {
path := filepath.Join(env.ScreenShotsPath, fileName[0])
path, err := dExt.saveScreenShot(raw, path)
if err != nil {
log.Error().Err(err).Msg("save screenshot file failed")
return nil, err
}
dExt.screenShots = append(dExt.screenShots, path)
log.Info().Str("path", path).Msg("save screenshot file success")
}
return raw, nil
}
// saveScreenShot saves image file with file name
func saveScreenShot(raw *bytes.Buffer, fileName string) (string, error) {
func (dExt *DriverExt) saveScreenShot(raw *bytes.Buffer, fileName string) (string, error) {
img, format, err := image.Decode(raw)
if err != nil {
return "", errors.Wrap(err, "decode screenshot image failed")
@@ -302,19 +317,11 @@ func saveScreenShot(raw *bytes.Buffer, fileName string) (string, error) {
return screenshotPath, nil
}
// ScreenShot takes screenshot and saves image file to $CWD/screenshots/ folder
func (dExt *DriverExt) ScreenShot(fileName string) (string, error) {
raw, err := dExt.takeScreenShot()
if err != nil {
return "", errors.Wrap(err, "screenshot failed")
}
fileName = filepath.Join(env.ScreenShotsPath, fileName)
path, err := saveScreenShot(raw, fileName)
if err != nil {
return "", errors.Wrap(err, "save screenshot failed")
}
return path, nil
func (dExt *DriverExt) GetScreenShots() []string {
defer func() {
dExt.screenShots = nil
}()
return dExt.screenShots
}
// isPathExists returns true if path exists, whether path is file or dir
@@ -689,15 +696,9 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
}
}
case CtlScreenShot:
// take snapshot
log.Info().Msg("take snapshot for current screen")
screenshotPath, err := dExt.ScreenShot(fmt.Sprintf("screenshot_%d",
time.Now().Unix()))
if err != nil {
return errors.Wrap(err, "take screenshot failed")
}
log.Info().Str("path", screenshotPath).Msg("take screenshot")
dExt.ScreenShots = append(dExt.ScreenShots, screenshotPath)
// take screenshot
log.Info().Msg("take screenshot for current screen")
_, err := dExt.TakeScreenShot(builtin.GenNameWithTimestamp("screenshot_"))
return err
case CtlStartCamera:
return dExt.Driver.StartCamera()

View File

@@ -2,7 +2,6 @@ package uixt
import (
"bytes"
"fmt"
"math"
"strings"
"time"
@@ -437,7 +436,6 @@ type DataOptions struct {
IgnoreNotFoundError bool // ignore error if target element not found
MaxRetryTimes int // max retry times if target element not found
Interval float64 // interval between retries in seconds
ScreenShotFilename string // turn on screenshot and specify file name
}
type DataOption func(data *DataOptions)
@@ -514,16 +512,6 @@ func WithDataWaitTime(sec float64) DataOption {
}
}
func WithScreenShot(fileName ...string) DataOption {
return func(data *DataOptions) {
if len(fileName) > 0 {
data.ScreenShotFilename = fileName[0]
} else {
data.ScreenShotFilename = fmt.Sprintf("screenshot_%d", time.Now().Unix())
}
}
}
func NewDataOptions(options ...DataOption) *DataOptions {
dataOptions := &DataOptions{
Data: make(map[string]interface{}),

View File

@@ -175,14 +175,6 @@ func (s *veDEMOCRService) GetTexts(imageBuf *bytes.Buffer, options ...DataOption
dataOptions := NewDataOptions(options...)
if dataOptions.ScreenShotFilename != "" {
path, err := saveScreenShot(imageBuf, dataOptions.ScreenShotFilename)
if err != nil {
return nil, errors.Wrap(err, "save screenshot failed")
}
log.Debug().Str("path", path).Msg("save screenshot")
}
for _, ocrResult := range ocrResults {
rect := image.Rectangle{
// ocrResult.Points 顺序:左上 -> 右上 -> 右下 -> 左下
@@ -313,8 +305,7 @@ type OCRService interface {
func (dExt *DriverExt) GetTextsByOCR(options ...DataOption) (texts OCRTexts, err error) {
var bufSource *bytes.Buffer
if bufSource, err = dExt.takeScreenShot(); err != nil {
err = fmt.Errorf("takeScreenShot error: %v", err)
if bufSource, err = dExt.TakeScreenShot(builtin.GenNameWithTimestamp("ocr_")); err != nil {
return
}
@@ -329,8 +320,7 @@ func (dExt *DriverExt) GetTextsByOCR(options ...DataOption) (texts OCRTexts, err
func (dExt *DriverExt) FindTextByOCR(ocrText string, options ...DataOption) (x, y, width, height float64, err error) {
var bufSource *bytes.Buffer
if bufSource, err = dExt.takeScreenShot(); err != nil {
err = fmt.Errorf("takeScreenShot error: %v", err)
if bufSource, err = dExt.TakeScreenShot(builtin.GenNameWithTimestamp("ocr_")); err != nil {
return
}
@@ -348,8 +338,7 @@ func (dExt *DriverExt) FindTextByOCR(ocrText string, options ...DataOption) (x,
func (dExt *DriverExt) FindTextsByOCR(ocrTexts []string, options ...DataOption) (points [][]float64, err error) {
var bufSource *bytes.Buffer
if bufSource, err = dExt.takeScreenShot(); err != nil {
err = fmt.Errorf("takeScreenShot error: %v", err)
if bufSource, err = dExt.TakeScreenShot(builtin.GenNameWithTimestamp("ocr_")); err != nil {
return
}

View File

@@ -14,6 +14,8 @@ import (
"github.com/pkg/errors"
"gocv.io/x/gocv"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
)
const (
@@ -101,7 +103,7 @@ func (dExt *DriverExt) FindAllImageRect(search string) (rects []image.Rectangle,
if bufSearch, err = getBufFromDisk(search); err != nil {
return nil, err
}
if bufSource, err = dExt.takeScreenShot(); err != nil {
if bufSource, err = dExt.TakeScreenShot(builtin.GenNameWithTimestamp("cv_")); err != nil {
return nil, err
}
@@ -116,7 +118,7 @@ func (dExt *DriverExt) FindImageRectInUIKit(imagePath string, options ...DataOpt
if bufSearch, err = getBufFromDisk(imagePath); err != nil {
return 0, 0, 0, 0, err
}
if bufSource, err = dExt.takeScreenShot(); err != nil {
if bufSource, err = dExt.TakeScreenShot(builtin.GenNameWithTimestamp("cv_")); err != nil {
return 0, 0, 0, 0, err
}

View File

@@ -2,11 +2,11 @@ package hrp
import (
"fmt"
"time"
"github.com/pkg/errors"
"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/pkg/uixt"
)
@@ -572,7 +572,6 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err
Success: false,
ContentSize: 0,
}
screenshots := make([]string, 0)
// merge step variables with session variables
stepVariables, err := s.ParseStepVariables(step.Variables)
@@ -602,18 +601,14 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err
}
// take screenshot after each step
screenshotPath, err := uiDriver.ScreenShot(
fmt.Sprintf("step_%d", time.Now().Unix()))
_, err := uiDriver.TakeScreenShot(
builtin.GenNameWithTimestamp("step_") + "_" + step.Name)
if err != nil {
log.Error().Err(err).Str("step", step.Name).Msg("take screenshot failed")
} else {
log.Info().Str("path", screenshotPath).Msg("take screenshot on step finished")
screenshots = append(screenshots, screenshotPath)
log.Error().Err(err).Str("step", step.Name).Msg("take screenshot failed on step finished")
}
// save attachments
screenshots = append(screenshots, uiDriver.ScreenShots...)
attachments["screenshots"] = screenshots
attachments["screenshots"] = uiDriver.GetScreenShots()
stepResult.Attachments = attachments
}()