From eb9e3efe6cf363bad84cfd8f53ac793f95fa29e1 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Thu, 29 Sep 2022 23:10:46 +0800 Subject: [PATCH] fix: trigger wda logs with usbmux --- hrp/internal/uixt/android_driver.go | 12 ++++- hrp/internal/uixt/ext.go | 1 - hrp/internal/uixt/interface.go | 4 ++ hrp/internal/uixt/ios_device.go | 70 +---------------------------- hrp/internal/uixt/ios_driver.go | 41 +++++++++++++++++ hrp/internal/version/VERSION | 2 +- hrp/session.go | 16 +++---- hrp/summary.go | 2 +- httprunner/__init__.py | 2 +- pyproject.toml | 2 +- 10 files changed, 69 insertions(+), 83 deletions(-) diff --git a/hrp/internal/uixt/android_driver.go b/hrp/internal/uixt/android_driver.go index 77501047..858cb2d7 100644 --- a/hrp/internal/uixt/android_driver.go +++ b/hrp/internal/uixt/android_driver.go @@ -138,7 +138,7 @@ func (ud *uiaDriver) SessionDetails() (scrollData map[string]interface{}, err er if rawResp, err = ud.httpGET("/session", ud.sessionId); err != nil { return nil, err } - var reply = new(struct{ Value map[string]interface{} }) + reply := new(struct{ Value map[string]interface{} }) if err = json.Unmarshal(rawResp, reply); err != nil { return nil, err } @@ -944,3 +944,13 @@ func (ud *uiaDriver) WaitWithTimeout(condition Condition, timeout time.Duration) func (ud *uiaDriver) Wait(condition Condition) error { return ud.WaitWithTimeoutAndInterval(condition, DefaultWaitTimeout, DefaultWaitInterval) } + +func (ud *uiaDriver) StartCaptureLog(identifier ...string) (err error) { + // TODO + return +} + +func (ud *uiaDriver) StopCaptureLog() (result interface{}, err error) { + // TODO + return +} diff --git a/hrp/internal/uixt/ext.go b/hrp/internal/uixt/ext.go index 927b08c1..93155a76 100644 --- a/hrp/internal/uixt/ext.go +++ b/hrp/internal/uixt/ext.go @@ -131,7 +131,6 @@ type DriverExt struct { frame *bytes.Buffer doneMjpegStream chan bool scale float64 - host string StartTime time.Time // used to associate screenshots name ScreenShots []string // save screenshots path diff --git a/hrp/internal/uixt/interface.go b/hrp/internal/uixt/interface.go index 346233f4..cbc7c668 100644 --- a/hrp/internal/uixt/interface.go +++ b/hrp/internal/uixt/interface.go @@ -989,6 +989,10 @@ type WebDriver interface { // Close inner connections properly Close() error + + // triggers the log capture and returns the log entries + StartCaptureLog(identifier ...string) (err error) + StopCaptureLog() (result interface{}, err error) } // WebElement defines method supported by web elements. diff --git a/hrp/internal/uixt/ios_device.go b/hrp/internal/uixt/ios_device.go index b5f37268..48a4e54e 100644 --- a/hrp/internal/uixt/ios_device.go +++ b/hrp/internal/uixt/ios_device.go @@ -5,7 +5,6 @@ import ( "encoding/base64" builtinJSON "encoding/json" "fmt" - "io/ioutil" "mime" "mime/multipart" "net" @@ -111,9 +110,8 @@ func InitWDAClient(device *IOSDevice) (*DriverExt, error) { } log.Info().Interface("appiumWDASettings", settings).Msg("set appium WDA settings") - driverExt.host = fmt.Sprintf("http://127.0.0.1:%d", iosDevice.Port) if device.LogOn { - err = driverExt.StartLogRecording("hrp_wda_log") + err = driverExt.Driver.StartCaptureLog("hrp_wda_log") if err != nil { return nil, err } @@ -198,6 +196,7 @@ func (dev *IOSDevice) UUID() string { // NewHTTPDriver creates new remote HTTP client, this will also start a new session. func (dev *IOSDevice) NewHTTPDriver(capabilities Capabilities) (driver WebDriver, err error) { wd := new(wdaDriver) + wd.client = http.DefaultClient urlPrefix := fmt.Sprintf("http://127.0.0.1:%d", dev.Port) if wd.urlPrefix, err = url.Parse(urlPrefix); err != nil { @@ -208,7 +207,6 @@ func (dev *IOSDevice) NewHTTPDriver(capabilities Capabilities) (driver WebDriver return nil, err } wd.sessionId = sessionInfo.SessionId - wd.client = http.DefaultClient if wd.mjpegHTTPConn, err = net.Dial( "tcp", @@ -246,70 +244,6 @@ func (dev *IOSDevice) NewUSBDriver(capabilities Capabilities) (driver WebDriver, return wd, err } -type wdaResponse struct { - Value interface{} `json:"value"` - SessionID string `json:"sessionId"` -} - -func (dExt *DriverExt) StartLogRecording(identifier string) error { - log.Info().Msg("start WDA log recording") - data := map[string]interface{}{"action": "start", "type": 2, "identifier": identifier} - _, err := dExt.triggerWDALog(data) - if err != nil { - return errors.Wrap(err, "failed to start WDA log recording") - } - - return nil -} - -func (dExt *DriverExt) GetLogs() (interface{}, error) { - log.Info().Msg("stop log recording") - if _, ok := dExt.Driver.(*wdaDriver); ok { - data := map[string]interface{}{"action": "stop"} - reply, err := dExt.triggerWDALog(data) - if err != nil { - log.Error().Err(err).Interface("reply", reply).Msg("failed to get WDA logs") - return "", errors.Wrap(err, "failed to get WDA logs") - } - return reply.Value, nil - } else { - // TODO: Android log recording - } - return "", nil -} - -func (dExt *DriverExt) triggerWDALog(data map[string]interface{}) (*wdaResponse, error) { - // [[FBRoute POST:@"/gtf/automation/log"].withoutSession respondWithTarget:self action:@selector(handleAutomationLog:)] - postJSON, err := json.Marshal(data) - if err != nil { - return nil, err - } - - url := fmt.Sprintf("%s/gtf/automation/log", dExt.host) - log.Info().Str("url", url).Interface("data", data).Msg("trigger WDA log") - resp, err := http.DefaultClient.Post(url, "application/json", bytes.NewBuffer(postJSON)) - if err != nil { - return nil, err - } - - if resp.StatusCode != http.StatusOK { - return nil, errors.Errorf("failed to trigger wda log, response status code: %d", resp.StatusCode) - } - - rawResp, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - reply := new(wdaResponse) - if err = json.Unmarshal(rawResp, reply); err != nil { - return reply, err - } - log.Info().Interface("value", reply.Value).Msg("get WDA log response") - - return reply, nil -} - func (dExt *DriverExt) ConnectMjpegStream(httpClient *http.Client) (err error) { if httpClient == nil { return errors.New(`'httpClient' can't be nil`) diff --git a/hrp/internal/uixt/ios_driver.go b/hrp/internal/uixt/ios_driver.go index 771d7d36..ac4159f0 100644 --- a/hrp/internal/uixt/ios_driver.go +++ b/hrp/internal/uixt/ios_driver.go @@ -861,3 +861,44 @@ func (wd *wdaDriver) WaitWithTimeout(condition Condition, timeout time.Duration) func (wd *wdaDriver) Wait(condition Condition) error { return wd.WaitWithTimeoutAndInterval(condition, DefaultWaitTimeout, DefaultWaitInterval) } + +func (wd *wdaDriver) triggerWDALog(data map[string]interface{}) (rawResp []byte, err error) { + // [[FBRoute POST:@"/gtf/automation/log"].withoutSession respondWithTarget:self action:@selector(handleAutomationLog:)] + return wd.httpPOST(data, "/gtf/automation/log") +} + +func (wd *wdaDriver) StartCaptureLog(identifier ...string) error { + log.Info().Msg("start WDA log recording") + if identifier == nil { + identifier = []string{""} + } + data := map[string]interface{}{"action": "start", "type": 2, "identifier": identifier[0]} + _, err := wd.triggerWDALog(data) + if err != nil { + return errors.Wrap(err, "failed to start WDA log recording") + } + + return nil +} + +type wdaResponse struct { + Value interface{} `json:"value"` + SessionID string `json:"sessionId"` +} + +func (wd *wdaDriver) StopCaptureLog() (result interface{}, err error) { + log.Info().Msg("stop log recording") + data := map[string]interface{}{"action": "stop"} + rawResp, err := wd.triggerWDALog(data) + if err != nil { + log.Error().Err(err).Bytes("rawResp", rawResp).Msg("failed to get WDA logs") + return "", errors.Wrap(err, "failed to get WDA logs") + } + reply := new(wdaResponse) + if err = json.Unmarshal(rawResp, reply); err != nil { + log.Error().Err(err).Bytes("rawResp", rawResp).Msg("failed to json.Unmarshal WDA logs") + return reply, err + } + log.Info().Interface("value", reply.Value).Msg("get WDA log response") + return reply.Value, nil +} diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index 710e0281..0dbff02d 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v4.3.0-beta-09292020 \ No newline at end of file +v4.3.0-beta-09292312 \ No newline at end of file diff --git a/hrp/session.go b/hrp/session.go index 83c0429b..d04f5a9e 100644 --- a/hrp/session.go +++ b/hrp/session.go @@ -8,8 +8,6 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog/log" - - "github.com/httprunner/httprunner/v4/hrp/internal/json" ) // SessionRunner is used to run testcase and its steps. @@ -165,17 +163,17 @@ func (r *SessionRunner) GetSummary() (*TestCaseSummary, error) { caseSummary.InOut.ConfigVars = r.parsedConfig.Variables // add WDA/UIA logs to summary - logs := make(map[string]interface{}) - for udid, client := range r.hrpRunner.uiClients { - log, err := client.GetLogs() + for uuid, client := range r.hrpRunner.uiClients { + log, err := client.Driver.StopCaptureLog() if err != nil { return caseSummary, err } - logs[udid] = log + logs := map[string]interface{}{ + "uuid": uuid, + "content": log, + } + caseSummary.Logs = append(caseSummary.Logs, logs) } - logsBytes, _ := json.Marshal(logs) - caseSummary.Logs = string(logsBytes) - return caseSummary, nil } diff --git a/hrp/summary.go b/hrp/summary.go index 841f7fc5..0883a3d8 100644 --- a/hrp/summary.go +++ b/hrp/summary.go @@ -151,7 +151,7 @@ type TestCaseSummary struct { Stat *TestStepStat `json:"stat" yaml:"stat"` Time *TestCaseTime `json:"time" yaml:"time"` InOut *TestCaseInOut `json:"in_out" yaml:"in_out"` - Logs string `json:"logs,omitempty" yaml:"logs,omitempty"` + Logs []interface{} `json:"logs,omitempty" yaml:"logs,omitempty"` Records []*StepResult `json:"records" yaml:"records"` RootDir string `json:"root_dir" yaml:"root_dir"` } diff --git a/httprunner/__init__.py b/httprunner/__init__.py index 415278d7..fe307b9d 100644 --- a/httprunner/__init__.py +++ b/httprunner/__init__.py @@ -1,4 +1,4 @@ -__version__ = "v4.3.0-beta-09292020" +__version__ = "v4.3.0-beta-09292312" __description__ = "One-stop solution for HTTP(S) testing." diff --git a/pyproject.toml b/pyproject.toml index adbe2bde..b1f1f680 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "httprunner" -version = "v4.3.0-beta-09292020" +version = "v4.3.0-beta-09292312" description = "One-stop solution for HTTP(S) testing." license = "Apache-2.0" readme = "README.md"