mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 07:26:55 +08:00
feat: cache screenshot ocr texts
This commit is contained in:
@@ -97,7 +97,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"method": "sleep",
|
"method": "sleep",
|
||||||
"params": 10
|
"params": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"method": "screenshot"
|
"method": "screenshot"
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"method": "sleep",
|
"method": "sleep",
|
||||||
"params": 10
|
"params": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"method": "screenshot"
|
"method": "screenshot"
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ func TestAndroidLiveSwipeTest(t *testing.T) {
|
|||||||
SleepRandom(0, 5, 0.6, 5, 10, 0.4),
|
SleepRandom(0, 5, 0.6, 5, 10, 0.4),
|
||||||
hrp.NewStep("向上滑动,等待 10s").
|
hrp.NewStep("向上滑动,等待 10s").
|
||||||
Android().
|
Android().
|
||||||
SwipeUp(uixt.WithIdentifier("第一次上划")).Sleep(10).ScreenShot(). // 上划 1 次,等待 10s,截图保存
|
SwipeUp(uixt.WithIdentifier("第一次上划")).Sleep(5).ScreenShot(). // 上划 1 次,等待 5s,截图保存
|
||||||
SwipeUp(uixt.WithIdentifier("第二次上划")).Sleep(10).ScreenShot(), // 再上划 1 次,等待 10s,截图保存
|
SwipeUp(uixt.WithIdentifier("第二次上划")).Sleep(5).ScreenShot(), // 再上划 1 次,等待 5s,截图保存
|
||||||
hrp.NewStep("exit").
|
hrp.NewStep("exit").
|
||||||
Android().
|
Android().
|
||||||
AppTerminate("com.ss.android.ugc.aweme").
|
AppTerminate("com.ss.android.ugc.aweme").
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
case ACTION_ScreenShot:
|
case ACTION_ScreenShot:
|
||||||
// take screenshot
|
// take screenshot
|
||||||
log.Info().Msg("take screenshot for current screen")
|
log.Info().Msg("take screenshot for current screen")
|
||||||
_, err := dExt.TakeScreenShot(builtin.GenNameWithTimestamp("%d_screenshot"))
|
_, _, err := dExt.TakeScreenShot(builtin.GenNameWithTimestamp("%d_screenshot"))
|
||||||
return err
|
return err
|
||||||
case ACTION_StartCamera:
|
case ACTION_StartCamera:
|
||||||
return dExt.Driver.StartCamera()
|
return dExt.Driver.StartCamera()
|
||||||
|
|||||||
+22
-13
@@ -51,8 +51,8 @@ type DriverExt struct {
|
|||||||
windowSize Size
|
windowSize Size
|
||||||
frame *bytes.Buffer
|
frame *bytes.Buffer
|
||||||
doneMjpegStream chan bool
|
doneMjpegStream chan bool
|
||||||
OCRService IOCRService // used to get text from image
|
OCRService IOCRService // used to get texts from image
|
||||||
screenShots []string // cache screenshot paths
|
stepScreenShots map[string]OCRTexts // cache screenshot ocr results, key is image path
|
||||||
|
|
||||||
CVArgs
|
CVArgs
|
||||||
}
|
}
|
||||||
@@ -61,6 +61,7 @@ func NewDriverExt(device Device, driver WebDriver) (dExt *DriverExt, err error)
|
|||||||
dExt = &DriverExt{
|
dExt = &DriverExt{
|
||||||
Device: device,
|
Device: device,
|
||||||
Driver: driver,
|
Driver: driver,
|
||||||
|
stepScreenShots: make(map[string]OCRTexts),
|
||||||
}
|
}
|
||||||
dExt.doneMjpegStream = make(chan bool, 1)
|
dExt.doneMjpegStream = make(chan bool, 1)
|
||||||
|
|
||||||
@@ -86,22 +87,22 @@ func NewDriverExt(device Device, driver WebDriver) (dExt *DriverExt, err error)
|
|||||||
|
|
||||||
// TakeScreenShot takes screenshot and saves image file to $CWD/screenshots/ folder
|
// 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
|
// 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) {
|
func (dExt *DriverExt) TakeScreenShot(fileName ...string) (raw *bytes.Buffer, path string, err error) {
|
||||||
// iOS 优先使用 MJPEG 流进行截图,性能最优
|
// iOS 优先使用 MJPEG 流进行截图,性能最优
|
||||||
// 如果 MJPEG 流未开启,则使用 WebDriver 的截图接口
|
// 如果 MJPEG 流未开启,则使用 WebDriver 的截图接口
|
||||||
if dExt.frame != nil {
|
if dExt.frame != nil {
|
||||||
return dExt.frame, nil
|
return dExt.frame, "", nil
|
||||||
}
|
}
|
||||||
if raw, err = dExt.Driver.Screenshot(); err != nil {
|
if raw, err = dExt.Driver.Screenshot(); err != nil {
|
||||||
log.Error().Err(err).Msg("capture screenshot data failed")
|
log.Error().Err(err).Msg("capture screenshot data failed")
|
||||||
return nil, err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// compress image data
|
// compress image data
|
||||||
compressed, err := compressImageBuffer(raw)
|
compressed, err := compressImageBuffer(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("compress screenshot data failed")
|
log.Error().Err(err).Msg("compress screenshot data failed")
|
||||||
return nil, err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// save screenshot to file
|
// save screenshot to file
|
||||||
@@ -110,13 +111,12 @@ func (dExt *DriverExt) TakeScreenShot(fileName ...string) (raw *bytes.Buffer, er
|
|||||||
path, err := dExt.saveScreenShot(compressed, path)
|
path, err := dExt.saveScreenShot(compressed, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("save screenshot file failed")
|
log.Error().Err(err).Msg("save screenshot file failed")
|
||||||
return nil, err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
dExt.screenShots = append(dExt.screenShots, path)
|
return compressed, path, nil
|
||||||
log.Info().Str("path", path).Msg("save screenshot file success")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return compressed, nil
|
return compressed, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compressImageBuffer(raw *bytes.Buffer) (compressed *bytes.Buffer, err error) {
|
func compressImageBuffer(raw *bytes.Buffer) (compressed *bytes.Buffer, err error) {
|
||||||
@@ -160,14 +160,23 @@ func (dExt *DriverExt) saveScreenShot(raw *bytes.Buffer, fileName string) (strin
|
|||||||
return "", errors.Wrap(err, "encode screenshot image failed")
|
return "", errors.Wrap(err, "encode screenshot image failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dExt.stepScreenShots[screenshotPath] = nil
|
||||||
|
log.Info().Str("path", screenshotPath).Msg("save screenshot file success")
|
||||||
return screenshotPath, nil
|
return screenshotPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dExt *DriverExt) GetScreenShots() []string {
|
func (dExt *DriverExt) GetScreenShots() map[string]OCRTexts {
|
||||||
defer func() {
|
defer func() {
|
||||||
dExt.screenShots = nil
|
for key := range dExt.stepScreenShots {
|
||||||
|
delete(dExt.stepScreenShots, key)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
return dExt.screenShots
|
|
||||||
|
copied := make(map[string]OCRTexts)
|
||||||
|
for key, value := range dExt.stepScreenShots {
|
||||||
|
copied[key] = value
|
||||||
|
}
|
||||||
|
return copied
|
||||||
}
|
}
|
||||||
|
|
||||||
// isPathExists returns true if path exists, whether path is file or dir
|
// isPathExists returns true if path exists, whether path is file or dir
|
||||||
|
|||||||
@@ -279,7 +279,8 @@ type IOCRService interface {
|
|||||||
|
|
||||||
func (dExt *DriverExt) GetScreenTextsByOCR() (texts OCRTexts, err error) {
|
func (dExt *DriverExt) GetScreenTextsByOCR() (texts OCRTexts, err error) {
|
||||||
var bufSource *bytes.Buffer
|
var bufSource *bytes.Buffer
|
||||||
if bufSource, err = dExt.TakeScreenShot(
|
var imagePath string
|
||||||
|
if bufSource, imagePath, err = dExt.TakeScreenShot(
|
||||||
builtin.GenNameWithTimestamp("%d_ocr")); err != nil {
|
builtin.GenNameWithTimestamp("%d_ocr")); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -290,6 +291,7 @@ func (dExt *DriverExt) GetScreenTextsByOCR() (texts OCRTexts, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dExt.stepScreenShots[imagePath] = ocrTexts
|
||||||
return ocrTexts, nil
|
return ocrTexts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ func (dExt *DriverExt) FindAllImageRect(search string) (rects []image.Rectangle,
|
|||||||
if bufSearch, err = getBufFromDisk(search); err != nil {
|
if bufSearch, err = getBufFromDisk(search); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if bufSource, err = dExt.TakeScreenShot(builtin.GenNameWithTimestamp("%d_cv")); err != nil {
|
if bufSource, _, err = dExt.TakeScreenShot(builtin.GenNameWithTimestamp("%d_cv")); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,15 +25,21 @@ func (dExt *DriverExt) VideoCrawler(configs *VideoCrawlerConfigs) (err error) {
|
|||||||
// loop until target count achieved
|
// loop until target count achieved
|
||||||
for {
|
for {
|
||||||
// take screenshot and get screen texts by OCR
|
// take screenshot and get screen texts by OCR
|
||||||
_, err := dExt.GetScreenTextsByOCR()
|
texts, err := dExt.GetScreenTextsByOCR()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("OCR GetTexts failed")
|
log.Error().Err(err).Msg("OCR GetTexts failed")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check if text popup exists
|
// check if text popup exists
|
||||||
|
if isTextPopup(texts) {
|
||||||
|
log.Info().Msg("text popup found")
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: check if live video
|
// check if live video
|
||||||
|
if isLiveVideo(texts) {
|
||||||
|
log.Info().Msg("live video found")
|
||||||
|
}
|
||||||
|
|
||||||
// assert feed video type
|
// assert feed video type
|
||||||
|
|
||||||
@@ -48,3 +54,13 @@ func (dExt *DriverExt) VideoCrawler(configs *VideoCrawlerConfigs) (err error) {
|
|||||||
|
|
||||||
// return nil
|
// return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isTextPopup(texts OCRTexts) bool {
|
||||||
|
texts.FindTexts([]string{"确定", "取消"})
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isLiveVideo(texts OCRTexts) bool {
|
||||||
|
_, err := texts.FindTexts([]string{"点击进入直播间", "直播中"})
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,18 +5,12 @@ package uixt
|
|||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestVideoCrawler(t *testing.T) {
|
func TestVideoCrawler(t *testing.T) {
|
||||||
device, err := NewAndroidDevice()
|
setupAndroid(t)
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
driver, err := device.NewDriver(nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
configs := &VideoCrawlerConfigs{
|
configs := &VideoCrawlerConfigs{
|
||||||
AppPackageName: "com.ss.android.ugc.aweme",
|
AppPackageName: "com.ss.android.ugc.aweme",
|
||||||
}
|
}
|
||||||
err = driver.VideoCrawler(configs)
|
err := driverExt.VideoCrawler(configs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -609,7 +609,7 @@ func runStepMobileUI(s *SessionRunner, step *TStep) (stepResult *StepResult, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// take screenshot after each step
|
// take screenshot after each step
|
||||||
_, err := uiDriver.TakeScreenShot(
|
_, _, err := uiDriver.TakeScreenShot(
|
||||||
builtin.GenNameWithTimestamp("%d_step_") + step.Name)
|
builtin.GenNameWithTimestamp("%d_step_") + step.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Str("step", step.Name).Msg("take screenshot failed on step finished")
|
log.Error().Err(err).Str("step", step.Name).Msg("take screenshot failed on step finished")
|
||||||
|
|||||||
Reference in New Issue
Block a user