mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-10 23:12:41 +08:00
change: remove live e2e
This commit is contained in:
@@ -4,6 +4,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
|
"github.com/httprunner/httprunner/v5/internal/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -35,4 +39,12 @@ func init() {
|
|||||||
ScreenShotsPath = filepath.Join(ResultsPath, ScreenshotsDirName)
|
ScreenShotsPath = filepath.Join(ResultsPath, ScreenshotsDirName)
|
||||||
ActionLogFilePath = filepath.Join(ResultsDir, ActionLogDireName)
|
ActionLogFilePath = filepath.Join(ResultsDir, ActionLogDireName)
|
||||||
DeviceActionLogFilePath = "/sdcard/Android/data/io.appium.uiautomator2.server/files/hodor"
|
DeviceActionLogFilePath = "/sdcard/Android/data/io.appium.uiautomator2.server/files/hodor"
|
||||||
|
|
||||||
|
// create results directory
|
||||||
|
if err := builtin.EnsureFolderExists(ResultsPath); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("create results directory failed")
|
||||||
|
}
|
||||||
|
if err := builtin.EnsureFolderExists(ScreenShotsPath); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("create screenshots directory failed")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v5.0.0+2502111148
|
v5.0.0+2502111217
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
// current implemeted device: IOSDevice, AndroidDevice, HarmonyDevice
|
// current implemeted device: IOSDevice, AndroidDevice, HarmonyDevice
|
||||||
type IDevice interface {
|
type IDevice interface {
|
||||||
UUID() string // ios udid or android serial
|
UUID() string // ios udid or android serial
|
||||||
|
NewDriver() (driver IDriver, err error)
|
||||||
|
|
||||||
Setup() error
|
Setup() error
|
||||||
Teardown() error
|
Teardown() error
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"github.com/httprunner/httprunner/v5/internal/builtin"
|
|
||||||
"github.com/httprunner/httprunner/v5/internal/config"
|
|
||||||
"github.com/httprunner/httprunner/v5/internal/json"
|
"github.com/httprunner/httprunner/v5/internal/json"
|
||||||
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
"github.com/httprunner/httprunner/v5/pkg/uixt/ai"
|
||||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
||||||
@@ -157,24 +155,6 @@ func NewXTDriver(driver IDriver, opts ...ai.AIServiceOption) *XTDriver {
|
|||||||
return driverExt
|
return driverExt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDriverExt(driver IDriver, opts ...ai.AIServiceOption) (*XTDriver, error) {
|
|
||||||
services := ai.NewAIService(opts...)
|
|
||||||
driverExt := &XTDriver{
|
|
||||||
Driver: driver,
|
|
||||||
CVService: services.ICVService,
|
|
||||||
LLMService: services.ILLMService,
|
|
||||||
}
|
|
||||||
// create results directory
|
|
||||||
// TODO: move to setup
|
|
||||||
if err := builtin.EnsureFolderExists(config.ResultsPath); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "create results directory failed")
|
|
||||||
}
|
|
||||||
if err := builtin.EnsureFolderExists(config.ScreenShotsPath); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "create screenshots directory failed")
|
|
||||||
}
|
|
||||||
return driverExt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ IDriverExt = (*XTDriver)(nil)
|
var _ IDriverExt = (*XTDriver)(nil)
|
||||||
|
|
||||||
// XTDriver = IDriver + AI
|
// XTDriver = IDriver + AI
|
||||||
@@ -185,6 +165,7 @@ type IDriverExt interface {
|
|||||||
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)
|
GetScreenShot(fileName string) (raw *bytes.Buffer, path string, err error)
|
||||||
|
|
||||||
|
// tap
|
||||||
TapByOCR(ocrText string, opts ...option.ActionOption) error
|
TapByOCR(ocrText string, opts ...option.ActionOption) error
|
||||||
TapXY(x, y float64, opts ...option.ActionOption) error
|
TapXY(x, y float64, opts ...option.ActionOption) error
|
||||||
TapAbsXY(x, y float64, opts ...option.ActionOption) error
|
TapAbsXY(x, y float64, opts ...option.ActionOption) error
|
||||||
|
|||||||
@@ -337,9 +337,6 @@ func (dExt *XTDriver) DoAction(action MobileAction) (err error) {
|
|||||||
return dExt.Driver.StopCamera()
|
return dExt.Driver.StopCamera()
|
||||||
case ACTION_ClosePopups:
|
case ACTION_ClosePopups:
|
||||||
return dExt.ClosePopupsHandler()
|
return dExt.ClosePopupsHandler()
|
||||||
case ACTION_EndToEndDelay:
|
|
||||||
CollectEndToEndDelay(dExt, action.GetOptions()...)
|
|
||||||
return nil
|
|
||||||
case ACTION_CallFunction:
|
case ACTION_CallFunction:
|
||||||
fn := action.Fn
|
fn := action.Fn
|
||||||
fn()
|
fn()
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
// ctx context.Context
|
|
||||||
ID string
|
ID string
|
||||||
baseURL *url.URL
|
baseURL *url.URL
|
||||||
client *http.Client
|
client *http.Client
|
||||||
@@ -32,8 +31,6 @@ type Session struct {
|
|||||||
requests []*DriverRequests
|
requests []*DriverRequests
|
||||||
// cache screenshot ocr results
|
// cache screenshot ocr results
|
||||||
screenResults []*ScreenResult
|
screenResults []*ScreenResult
|
||||||
// cache e2e delay
|
|
||||||
e2eDelay []timeLog
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Session) addScreenResult(screenResult *ScreenResult) {
|
func (d *Session) addScreenResult(screenResult *ScreenResult) {
|
||||||
@@ -53,7 +50,6 @@ func (d *Session) Init(baseUrl string) error {
|
|||||||
func (d *Session) Reset() {
|
func (d *Session) Reset() {
|
||||||
d.screenResults = make([]*ScreenResult, 0)
|
d.screenResults = make([]*ScreenResult, 0)
|
||||||
d.requests = make([]*DriverRequests, 0)
|
d.requests = make([]*DriverRequests, 0)
|
||||||
d.e2eDelay = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Session) GetData(withReset bool) Attachments {
|
func (d *Session) GetData(withReset bool) Attachments {
|
||||||
@@ -63,9 +59,6 @@ func (d *Session) GetData(withReset bool) Attachments {
|
|||||||
if len(d.requests) != 0 {
|
if len(d.requests) != 0 {
|
||||||
data["requests"] = d.requests
|
data["requests"] = d.requests
|
||||||
}
|
}
|
||||||
if d.e2eDelay != nil {
|
|
||||||
data["e2e_results"] = d.e2eDelay
|
|
||||||
}
|
|
||||||
if withReset {
|
if withReset {
|
||||||
d.Reset()
|
d.Reset()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,138 +0,0 @@
|
|||||||
package uixt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
|
|
||||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
|
||||||
)
|
|
||||||
|
|
||||||
type timeLog struct {
|
|
||||||
UTCTimeStr string `json:"utc_time_str"`
|
|
||||||
UTCTime int64 `json:"utc_time"`
|
|
||||||
LiveTimeStr string `json:"live_time_str"`
|
|
||||||
LiveTime int64 `json:"live_time"`
|
|
||||||
Delay float64 `json:"delay"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type EndToEndDelay struct {
|
|
||||||
driver *XTDriver
|
|
||||||
StartTime string `json:"startTime"`
|
|
||||||
EndTime string `json:"endTime"`
|
|
||||||
Interval int `json:"interval"` // seconds
|
|
||||||
Duration int `json:"duration"` // seconds
|
|
||||||
Timelines []timeLog `json:"timelines"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func CollectEndToEndDelay(dExt *XTDriver, opts ...option.ActionOption) {
|
|
||||||
dataOptions := option.NewActionOptions(opts...)
|
|
||||||
startTime := time.Now()
|
|
||||||
|
|
||||||
if dataOptions.Interval == 0 {
|
|
||||||
dataOptions.Interval = 5
|
|
||||||
}
|
|
||||||
if dataOptions.Timeout == 0 {
|
|
||||||
dataOptions.Timeout = 60
|
|
||||||
}
|
|
||||||
|
|
||||||
endToEndDelay := &EndToEndDelay{
|
|
||||||
driver: dExt,
|
|
||||||
Duration: int(dataOptions.Timeout),
|
|
||||||
Interval: int(dataOptions.Interval),
|
|
||||||
StartTime: startTime.Format("2006-01-02 15:04:05"),
|
|
||||||
}
|
|
||||||
|
|
||||||
endToEndDelay.Start()
|
|
||||||
|
|
||||||
// TODO: remove
|
|
||||||
dExt.Driver.GetSession().e2eDelay = endToEndDelay.Timelines
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ete *EndToEndDelay) getCurrentLiveTime(utcTime time.Time) error {
|
|
||||||
utcTimeStr := utcTime.Format("2006-01-02 15:04:05")
|
|
||||||
ocrTexts, err := ete.driver.GetScreenTexts()
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("get ocr texts failed")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter ocr texts with time format
|
|
||||||
var liveTimeTexts []string
|
|
||||||
for _, ocrText := range ocrTexts {
|
|
||||||
if len(ocrText.Text) < 13 || strings.Contains(ocrText.Text, ":") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// exclude digit(s) recognized as letter(s)
|
|
||||||
_, errParseInt := strconv.ParseInt(ocrText.Text[:13], 10, 64)
|
|
||||||
if errParseInt != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
liveTimeTexts = append(liveTimeTexts, ocrText.Text)
|
|
||||||
}
|
|
||||||
|
|
||||||
var liveTimeText string
|
|
||||||
if len(liveTimeTexts) != 0 {
|
|
||||||
liveTimeText = liveTimeTexts[0]
|
|
||||||
} else {
|
|
||||||
log.Warn().Msg("no time text found")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
liveTimeInt, err := strconv.Atoi(liveTimeText)
|
|
||||||
if err != nil {
|
|
||||||
liveTimeInt = 0
|
|
||||||
}
|
|
||||||
liveTimeSInt, err := strconv.Atoi(liveTimeText[:10])
|
|
||||||
if err != nil {
|
|
||||||
liveTimeSInt = 0
|
|
||||||
}
|
|
||||||
liveTimeNSInt, err := strconv.Atoi(liveTimeText[10:13])
|
|
||||||
if err != nil {
|
|
||||||
liveTimeNSInt = 0
|
|
||||||
}
|
|
||||||
liveTimeStr := time.Unix(int64(liveTimeSInt), int64(liveTimeNSInt*1000*1000)).Format("2006-01-02 15:04:05")
|
|
||||||
log.Info().
|
|
||||||
Str("utcTime", utcTimeStr).
|
|
||||||
Int64("utcTimeInt", utcTime.UnixMilli()).
|
|
||||||
Str("liveTime", liveTimeStr).
|
|
||||||
Int64("liveTimeInt", int64(liveTimeInt)).
|
|
||||||
Float64("delay", float64(utcTime.UnixMilli()-int64(liveTimeInt))/1000).
|
|
||||||
Msg("log live time")
|
|
||||||
ete.Timelines = append(ete.Timelines, timeLog{
|
|
||||||
UTCTimeStr: utcTimeStr,
|
|
||||||
UTCTime: utcTime.UnixMilli(),
|
|
||||||
LiveTimeStr: liveTimeStr,
|
|
||||||
LiveTime: int64(liveTimeInt),
|
|
||||||
Delay: float64(utcTime.UnixMilli()-int64(liveTimeInt)) / 1000,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ete *EndToEndDelay) Start() {
|
|
||||||
c := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(c, syscall.SIGTERM, syscall.SIGINT)
|
|
||||||
timer := time.NewTimer(time.Duration(ete.Duration) * time.Second)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-timer.C:
|
|
||||||
ete.EndTime = time.Now().Format("2006-01-02 15:04:05")
|
|
||||||
return
|
|
||||||
case <-c:
|
|
||||||
ete.EndTime = time.Now().Format("2006-01-02 15:04:05")
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
utcTime := time.Now()
|
|
||||||
if utcTime.Unix()%int64(ete.Interval) == 0 {
|
|
||||||
_ = ete.getCurrentLiveTime(utcTime)
|
|
||||||
} else {
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user