diff --git a/hrp/server.go b/hrp/boomer_server.go similarity index 100% rename from hrp/server.go rename to hrp/boomer_server.go diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index 0270bcab..4f6687d5 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v5.0.0+2411092158 +v5.0.0+2411092254 diff --git a/hrp/models.go b/hrp/models.go deleted file mode 100644 index 15191bc8..00000000 --- a/hrp/models.go +++ /dev/null @@ -1,70 +0,0 @@ -package hrp - -// define struct for testcase -type TestCaseDef struct { - Config *TConfig `json:"config" yaml:"config"` - Steps []*TStep `json:"teststeps" yaml:"teststeps"` -} - -type StepConfig struct { - StepName string `json:"name" yaml:"name"` // required - Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"` - SetupHooks []string `json:"setup_hooks,omitempty" yaml:"setup_hooks,omitempty"` - TeardownHooks []string `json:"teardown_hooks,omitempty" yaml:"teardown_hooks,omitempty"` - Extract map[string]string `json:"extract,omitempty" yaml:"extract,omitempty"` - Validators []interface{} `json:"validate,omitempty" yaml:"validate,omitempty"` - StepExport []string `json:"export,omitempty" yaml:"export,omitempty"` - Loops int `json:"loops,omitempty" yaml:"loops,omitempty"` - IgnorePopup bool `json:"ignore_popup,omitempty" yaml:"ignore_popup,omitempty"` -} - -// define struct for teststep -type TStep struct { - StepConfig `json:",inline" yaml:",inline"` - Request *Request `json:"request,omitempty" yaml:"request,omitempty"` - API interface{} `json:"api,omitempty" yaml:"api,omitempty"` // *APIPath or *API - TestCase interface{} `json:"testcase,omitempty" yaml:"testcase,omitempty"` // *TestCasePath or *TestCase - Transaction *Transaction `json:"transaction,omitempty" yaml:"transaction,omitempty"` - Rendezvous *Rendezvous `json:"rendezvous,omitempty" yaml:"rendezvous,omitempty"` - ThinkTime *ThinkTime `json:"think_time,omitempty" yaml:"think_time,omitempty"` - WebSocket *WebSocketAction `json:"websocket,omitempty" yaml:"websocket,omitempty"` - Android *MobileUI `json:"android,omitempty" yaml:"android,omitempty"` - Harmony *MobileUI `json:"harmony,omitempty" yaml:"harmony,omitempty"` - IOS *MobileUI `json:"ios,omitempty" yaml:"ios,omitempty"` - Shell *Shell `json:"shell,omitempty" yaml:"shell,omitempty"` -} - -// one step contains one or multiple actions -type ActionResult struct { - Name string `json:"name"` // action name - StartTime int64 `json:"start_time"` // action start time - Elapsed int64 `json:"elapsed_ms"` // action elapsed time(ms) - Error error `json:"error"` // action execution result -} - -// one testcase contains one or multiple steps -type StepResult struct { - Name string `json:"name" yaml:"name"` // step name - Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"` // step identifier - StartTime int64 `json:"start_time" yaml:"time"` // step start time - StepType StepType `json:"step_type" yaml:"step_type"` // step type, testcase/request/transaction/rendezvous - Success bool `json:"success" yaml:"success"` // step execution result - Elapsed int64 `json:"elapsed_ms" yaml:"elapsed_ms"` // step execution time in millisecond(ms) - HttpStat map[string]int64 `json:"httpstat,omitempty" yaml:"httpstat,omitempty"` // httpstat in millisecond(ms) - Data interface{} `json:"data,omitempty" yaml:"data,omitempty"` // step data - ContentSize int64 `json:"content_size" yaml:"content_size"` // response body length - ExportVars map[string]interface{} `json:"export_vars,omitempty" yaml:"export_vars,omitempty"` // extract variables - Actions []*ActionResult `json:"actions,omitempty" yaml:"actions,omitempty"` // store action execution info - Attachments interface{} `json:"attachments,omitempty" yaml:"attachments,omitempty"` // store extra step information, such as error message or screenshots -} - -// IStep represents interface for all types for teststeps, includes: -// StepRequest, StepRequestWithOptionalArgs, StepRequestValidation, StepRequestExtraction, -// StepTestCaseWithOptionalArgs, -// StepTransaction, StepRendezvous, StepWebSocket. -type IStep interface { - Name() string - Type() StepType - Config() *StepConfig - Run(*SessionRunner) (*StepResult, error) -} diff --git a/hrp/step.go b/hrp/step.go index 958d2c7c..b3c39e0b 100644 --- a/hrp/step.go +++ b/hrp/step.go @@ -18,3 +18,66 @@ const ( stepTypeSuffixExtraction StepType = "_extraction" stepTypeSuffixValidation StepType = "_validation" ) + +type StepConfig struct { + StepName string `json:"name" yaml:"name"` // required + Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"` + SetupHooks []string `json:"setup_hooks,omitempty" yaml:"setup_hooks,omitempty"` + TeardownHooks []string `json:"teardown_hooks,omitempty" yaml:"teardown_hooks,omitempty"` + Extract map[string]string `json:"extract,omitempty" yaml:"extract,omitempty"` + Validators []interface{} `json:"validate,omitempty" yaml:"validate,omitempty"` + StepExport []string `json:"export,omitempty" yaml:"export,omitempty"` + Loops int `json:"loops,omitempty" yaml:"loops,omitempty"` + IgnorePopup bool `json:"ignore_popup,omitempty" yaml:"ignore_popup,omitempty"` +} + +// define struct for teststep +type TStep struct { + StepConfig `json:",inline" yaml:",inline"` + Request *Request `json:"request,omitempty" yaml:"request,omitempty"` + API interface{} `json:"api,omitempty" yaml:"api,omitempty"` // *APIPath or *API + TestCase interface{} `json:"testcase,omitempty" yaml:"testcase,omitempty"` // *TestCasePath or *TestCase + Transaction *Transaction `json:"transaction,omitempty" yaml:"transaction,omitempty"` + Rendezvous *Rendezvous `json:"rendezvous,omitempty" yaml:"rendezvous,omitempty"` + ThinkTime *ThinkTime `json:"think_time,omitempty" yaml:"think_time,omitempty"` + WebSocket *WebSocketAction `json:"websocket,omitempty" yaml:"websocket,omitempty"` + Android *MobileUI `json:"android,omitempty" yaml:"android,omitempty"` + Harmony *MobileUI `json:"harmony,omitempty" yaml:"harmony,omitempty"` + IOS *MobileUI `json:"ios,omitempty" yaml:"ios,omitempty"` + Shell *Shell `json:"shell,omitempty" yaml:"shell,omitempty"` +} + +// one step contains one or multiple actions +type ActionResult struct { + Name string `json:"name"` // action name + StartTime int64 `json:"start_time"` // action start time + Elapsed int64 `json:"elapsed_ms"` // action elapsed time(ms) + Error error `json:"error"` // action execution result +} + +// one testcase contains one or multiple steps +type StepResult struct { + Name string `json:"name" yaml:"name"` // step name + Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"` // step identifier + StartTime int64 `json:"start_time" yaml:"time"` // step start time + StepType StepType `json:"step_type" yaml:"step_type"` // step type, testcase/request/transaction/rendezvous + Success bool `json:"success" yaml:"success"` // step execution result + Elapsed int64 `json:"elapsed_ms" yaml:"elapsed_ms"` // step execution time in millisecond(ms) + HttpStat map[string]int64 `json:"httpstat,omitempty" yaml:"httpstat,omitempty"` // httpstat in millisecond(ms) + Data interface{} `json:"data,omitempty" yaml:"data,omitempty"` // step data + ContentSize int64 `json:"content_size" yaml:"content_size"` // response body length + ExportVars map[string]interface{} `json:"export_vars,omitempty" yaml:"export_vars,omitempty"` // extract variables + Actions []*ActionResult `json:"actions,omitempty" yaml:"actions,omitempty"` // store action execution info + Attachments interface{} `json:"attachments,omitempty" yaml:"attachments,omitempty"` // store extra step information, such as error message or screenshots +} + +// IStep represents interface for all types for teststeps, includes: +// StepRequest, StepRequestWithOptionalArgs, StepRequestValidation, StepRequestExtraction, +// StepTestCaseWithOptionalArgs, +// StepTransaction, StepRendezvous, StepWebSocket. +type IStep interface { + Name() string + Type() StepType + Config() *StepConfig + Run(*SessionRunner) (*StepResult, error) +} diff --git a/hrp/step_mobile_ui.go b/hrp/step_mobile_ui.go index 31e47a40..24401ec6 100644 --- a/hrp/step_mobile_ui.go +++ b/hrp/step_mobile_ui.go @@ -2,6 +2,7 @@ package hrp import ( "fmt" + "strings" "github.com/pkg/errors" "github.com/rs/zerolog/log" @@ -737,3 +738,38 @@ func runStepMobileUI(s *SessionRunner, step IStep) (stepResult *StepResult, err stepResult.Success = true return stepResult, nil } + +func validateUI(ud *uixt.DriverExt, iValidators []interface{}) (validateResults []*ValidationResult, err error) { + for _, iValidator := range iValidators { + validator, ok := iValidator.(Validator) + if !ok { + return nil, errors.New("validator type error") + } + + validataResult := &ValidationResult{ + Validator: validator, + CheckResult: "fail", + } + + // parse check value + if !strings.HasPrefix(validator.Check, "ui_") { + validataResult.CheckResult = "skip" + log.Warn().Interface("validator", validator).Msg("skip validator") + validateResults = append(validateResults, validataResult) + continue + } + + expected, ok := validator.Expect.(string) + if !ok { + return nil, errors.New("validator expect should be string") + } + + if !ud.DoValidation(validator.Check, validator.Assert, expected, validator.Message) { + return validateResults, errors.New("step validation failed") + } + + validataResult.CheckResult = "pass" + validateResults = append(validateResults, validataResult) + } + return validateResults, nil +} diff --git a/hrp/step_request.go b/hrp/step_request.go index 9de8f472..074038e8 100644 --- a/hrp/step_request.go +++ b/hrp/step_request.go @@ -259,11 +259,11 @@ func initUpload(step *StepRequestWithOptionalArgs) { step.Request.Body = "$m_encoder" } -func prepareUpload(parser *Parser, step *StepRequestWithOptionalArgs, stepVariables map[string]interface{}) (err error) { - if len(step.Request.Upload) == 0 { +func prepareUpload(parser *Parser, stepRequest *StepRequest, stepVariables map[string]interface{}) (err error) { + if len(stepRequest.Request.Upload) == 0 { return } - uploadMap, err := parser.Parse(step.Request.Upload, stepVariables) + uploadMap, err := parser.Parse(stepRequest.Request.Upload, stepVariables) if err != nil { return } @@ -292,7 +292,7 @@ func runStepRequest(r *SessionRunner, step IStep) (stepResult *StepResult, err e } }() - err = prepareUpload(r.caseRunner.parser, stepRequest, stepRequest.Variables) + err = prepareUpload(r.caseRunner.parser, stepRequest.StepRequest, stepRequest.Variables) if err != nil { return } @@ -908,11 +908,7 @@ func (s *StepRequestExtraction) WithJmesPath(jmesPath string, varName string) *S // Validate switches to step validation. func (s *StepRequestExtraction) Validate() *StepRequestValidation { return &StepRequestValidation{ - StepRequestWithOptionalArgs: &StepRequestWithOptionalArgs{ - StepRequest: &StepRequest{ - StepConfig: s.StepConfig, - }, - }, + StepRequestWithOptionalArgs: s.StepRequestWithOptionalArgs, } } diff --git a/hrp/step_request_response.go b/hrp/step_request_response.go index 5f28b269..42c7e9e1 100644 --- a/hrp/step_request_response.go +++ b/hrp/step_request_response.go @@ -16,7 +16,6 @@ import ( "github.com/httprunner/httprunner/v4/hrp/internal/builtin" "github.com/httprunner/httprunner/v4/hrp/internal/json" - "github.com/httprunner/httprunner/v4/hrp/pkg/uixt" ) var fieldTags = []string{"proto", "status_code", "headers", "cookies", "body", textExtractorSubRegexp} @@ -273,38 +272,3 @@ func (v *responseObject) searchRegexp(expr string) interface{} { log.Error().Str("expr", expr).Msg("search regexp failed") return expr } - -func validateUI(ud *uixt.DriverExt, iValidators []interface{}) (validateResults []*ValidationResult, err error) { - for _, iValidator := range iValidators { - validator, ok := iValidator.(Validator) - if !ok { - return nil, errors.New("validator type error") - } - - validataResult := &ValidationResult{ - Validator: validator, - CheckResult: "fail", - } - - // parse check value - if !strings.HasPrefix(validator.Check, "ui_") { - validataResult.CheckResult = "skip" - log.Warn().Interface("validator", validator).Msg("skip validator") - validateResults = append(validateResults, validataResult) - continue - } - - expected, ok := validator.Expect.(string) - if !ok { - return nil, errors.New("validator expect should be string") - } - - if !ud.DoValidation(validator.Check, validator.Assert, expected, validator.Message) { - return validateResults, errors.New("step validation failed") - } - - validataResult.CheckResult = "pass" - validateResults = append(validateResults, validataResult) - } - return validateResults, nil -} diff --git a/hrp/convert.go b/hrp/step_request_response_test.go similarity index 100% rename from hrp/convert.go rename to hrp/step_request_response_test.go diff --git a/hrp/testcase.go b/hrp/testcase.go index 8fc5649b..5f00ca58 100644 --- a/hrp/testcase.go +++ b/hrp/testcase.go @@ -14,6 +14,12 @@ import ( "github.com/httprunner/httprunner/v4/hrp/pkg/uixt" ) +// define struct for testcase +type TestCaseDef struct { + Config *TConfig `json:"config" yaml:"config"` + Steps []*TStep `json:"teststeps" yaml:"teststeps"` +} + // ITestCase represents interface for testcases, // includes TestCase and TestCasePath. type ITestCase interface {