mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-10 17:43:00 +08:00
refactor: TakeScreenShot saves all screenshots
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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{}),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user