feat: validate UI exists

This commit is contained in:
debugtalk
2022-07-27 21:13:53 +08:00
parent b3887d5364
commit 087743bd9c
3 changed files with 164 additions and 28 deletions

View File

@@ -172,11 +172,11 @@ type StepAndroidValidation struct {
step *TStep
}
func (s *StepAndroidValidation) AssertTextExists(expectedText string, msg string) *StepAndroidValidation {
func (s *StepAndroidValidation) AssertXpathExists(expectedXpath string, msg string) *StepAndroidValidation {
v := Validator{
Check: "android_ui",
Assert: "text_exists",
Expect: expectedText,
Check: "UI",
Assert: "xpath_exists",
Expect: expectedXpath,
Message: msg,
}
s.step.Validators = append(s.step.Validators, v)

View File

@@ -2,6 +2,7 @@ package hrp
import (
"fmt"
"strings"
"github.com/electricbubble/gwda"
"github.com/pkg/errors"
@@ -140,11 +141,44 @@ type StepIOSValidation struct {
step *TStep
}
func (s *StepIOSValidation) AssertTextExists(expectedText string, msg string) *StepIOSValidation {
func (s *StepIOSValidation) AssertNameExists(expectedName string, msg string) *StepIOSValidation {
v := Validator{
Check: "ios_ui",
Assert: "text_exists",
Expect: expectedText,
Check: "UI",
Assert: "name_exists",
Expect: expectedName,
Message: msg,
}
s.step.Validators = append(s.step.Validators, v)
return s
}
func (s *StepIOSValidation) AssertNameNotExists(expectedName string, msg string) *StepIOSValidation {
v := Validator{
Check: "UI",
Assert: "name_not_exists",
Expect: expectedName,
Message: msg,
}
s.step.Validators = append(s.step.Validators, v)
return s
}
func (s *StepIOSValidation) AssertXpathExists(expectedXpath string, msg string) *StepIOSValidation {
v := Validator{
Check: "UI",
Assert: "xpath_exists",
Expect: expectedXpath,
Message: msg,
}
s.step.Validators = append(s.step.Validators, v)
return s
}
func (s *StepIOSValidation) AssertXpathNotExists(expectedXpath string, msg string) *StepIOSValidation {
v := Validator{
Check: "UI",
Assert: "xpath_not_exists",
Expect: expectedXpath,
Message: msg,
}
s.step.Validators = append(s.step.Validators, v)
@@ -282,9 +316,14 @@ func runStepIOS(r *SessionRunner, step *TStep) (stepResult *StepResult, err erro
}
}
// do validation
// step.Validators
// validate
validateResults, err := wdaClient.doValidation(step.Validators)
if err != nil {
return
}
sessionData := newSessionData()
sessionData.Validators = validateResults
stepResult.Data = sessionData
stepResult.Success = true
return stepResult, nil
}
@@ -314,11 +353,21 @@ func (w *wdaClient) doAction(action MobileAction) error {
}
return w.Driver.Tap(location[0], location[1])
}
// click on xpath
if xpath, ok := action.Params.(string); ok {
selector := gwda.BySelector{
XPath: xpath,
// click on name or xpath
if param, ok := action.Params.(string); ok {
var selector gwda.BySelector
if strings.HasPrefix(param, "/") {
// xpath
selector = gwda.BySelector{
XPath: param,
}
} else {
// name
selector = gwda.BySelector{
Name: param,
}
}
ele, err := w.Driver.FindElement(selector)
if err != nil {
return errors.Wrap(err, "failed to find element")
@@ -340,9 +389,9 @@ func (w *wdaClient) doAction(action MobileAction) error {
if direction, ok := action.Params.(string); ok {
switch direction {
case "up":
fromX, fromY, toX, toY = width/2, height*1/4, width/2, height*3/4
case "down":
fromX, fromY, toX, toY = width/2, height*3/4, width/2, height*1/4
case "down":
fromX, fromY, toX, toY = width/2, height*1/4, width/2, height*3/4
case "left":
fromX, fromY, toX, toY = width*3/4, height/2, width*1/4, height/2
case "right":
@@ -367,7 +416,74 @@ func (w *wdaClient) doAction(action MobileAction) error {
return nil
}
func (w *wdaClient) doValidation() error {
// TODO
return errActionNotImplemented
func (w *wdaClient) doValidation(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 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")
}
var result bool
switch validator.Assert {
case "xpath_exists":
result = w.assertXpath(expected, true)
case "xpath_not_exists":
result = w.assertXpath(expected, false)
case "name_exists":
result = w.assertName(expected, true)
case "name_not_exists":
result = w.assertName(expected, false)
}
if result {
log.Info().
Str("assert", validator.Assert).
Str("expect", expected).
Msg("validate UI success")
validataResult.CheckResult = "pass"
validateResults = append(validateResults, validataResult)
} else {
log.Error().
Str("assert", validator.Assert).
Str("expect", expected).
Str("msg", validator.Message).
Msg("validate UI failed")
validateResults = append(validateResults, validataResult)
err = errors.New("step validation failed")
}
}
return
}
func (w *wdaClient) assertName(name string, exists bool) bool {
selector := gwda.BySelector{
Name: name,
}
_, err := w.Driver.FindElement(selector)
return exists == (err == nil)
}
func (w *wdaClient) assertXpath(xpath string, exists bool) bool {
selector := gwda.BySelector{
XPath: xpath,
}
_, err := w.Driver.FindElement(selector)
return exists == (err == nil)
}

View File

@@ -12,8 +12,8 @@ func TestAndroidAction(t *testing.T) {
NewStep("launch douyin").
Android().Serial("xxx").Click("抖音").
Validate().
AssertTextExists("首页", "首页 tab 不存在").
AssertTextExists("消息", "消息 tab 不存在"),
AssertXpathExists("首页", "首页 tab 不存在").
AssertXpathExists("消息", "消息 tab 不存在"),
NewStep("swipe up and down").
Android().Serial("xxx").SwipeUp().SwipeUp().SwipeDown(),
},
@@ -27,15 +27,35 @@ func TestAndroidAction(t *testing.T) {
}
}
func TestIOSAction(t *testing.T) {
func TestIOSSettingsAction(t *testing.T) {
testCase := &TestCase{
Config: NewConfig("ios ui action"),
Config: NewConfig("ios ui action on Settings"),
TestSteps: []IStep{
NewStep("launch douyin").
IOS().Click("//*[@label='抖音']").
NewStep("launch Settings").
IOS().Click("//*[@label='设置']").
Validate().
AssertTextExists("首页", "首页 tab 不存在").
AssertTextExists("消息", "消息 tab 不存在"),
AssertNameExists("飞行模式", "「飞行模式」不存在").
AssertNameNotExists("飞行模式2", "「飞行模式2」不存在"),
NewStep("swipe up and down").
IOS().SwipeUp().SwipeUp().SwipeDown(),
},
}
err := NewRunner(t).Run(testCase)
if err != nil {
t.Fatal(err)
}
}
func TestIOSDouyinAction(t *testing.T) {
testCase := &TestCase{
Config: NewConfig("ios ui action on 抖音"),
TestSteps: []IStep{
NewStep("launch douyin").
IOS().Click("//*[@label='抖音']").
Validate().
AssertNameExists("首页", "首页 tab 不存在").
AssertNameExists("消息", "消息 tab 不存在"),
NewStep("swipe up and down").
IOS().SwipeUp().SwipeUp().SwipeDown(),
},