mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-04 23:16:57 +08:00
change: update DataOptions
This commit is contained in:
@@ -491,12 +491,11 @@ func (ud *uiaDriver) TapFloat(x, y float64, options ...DataOption) (err error) {
|
|||||||
"x": x,
|
"x": x,
|
||||||
"y": y,
|
"y": y,
|
||||||
}
|
}
|
||||||
// append options in post data for extra uiautomator configurations
|
// new data options in post data for extra uiautomator configurations
|
||||||
for _, option := range options {
|
d := NewData(options...)
|
||||||
option(data)
|
d.MergeData(data)
|
||||||
}
|
|
||||||
|
|
||||||
_, err = ud.httpPOST(data, "/session", ud.sessionId, "appium/tap")
|
_, err = ud.httpPOST(d.Data, "/session", ud.sessionId, "appium/tap")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,16 +550,11 @@ func (ud *uiaDriver) DragFloat(fromX, fromY, toX, toY float64, options ...DataOp
|
|||||||
"endY": toY,
|
"endY": toY,
|
||||||
}
|
}
|
||||||
|
|
||||||
// append options in post data for extra uiautomator configurations
|
// new data options in post data for extra uiautomator configurations
|
||||||
for _, option := range options {
|
d := NewData(options...)
|
||||||
option(data)
|
d.MergeData(data)
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := data["steps"]; !ok {
|
return ud._drag(d.Data)
|
||||||
data["steps"] = 12 // default steps
|
|
||||||
}
|
|
||||||
|
|
||||||
return ud._drag(data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ud *uiaDriver) _swipe(startX, startY, endX, endY interface{}, options ...DataOption) (err error) {
|
func (ud *uiaDriver) _swipe(startX, startY, endX, endY interface{}, options ...DataOption) (err error) {
|
||||||
@@ -572,16 +566,11 @@ func (ud *uiaDriver) _swipe(startX, startY, endX, endY interface{}, options ...D
|
|||||||
"endY": endY,
|
"endY": endY,
|
||||||
}
|
}
|
||||||
|
|
||||||
// append options in post data for extra uiautomator configurations
|
// new data options in post data for extra uiautomator configurations
|
||||||
// e.g. use WithPressDurationOption to set pressForDuration
|
d := NewData(options...)
|
||||||
for _, option := range options {
|
d.MergeData(data)
|
||||||
option(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := data["steps"]; !ok {
|
_, err = ud.httpPOST(d.Data, "/session", ud.sessionId, "touch/perform")
|
||||||
data["steps"] = 12 // default steps
|
|
||||||
}
|
|
||||||
_, err = ud.httpPOST(data, "/session", ud.sessionId, "touch/perform")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,7 +579,7 @@ func (ud *uiaDriver) _swipe(startX, startY, endX, endY interface{}, options ...D
|
|||||||
// per step. So for a 100 steps, the swipe will take about 1/2 second to complete.
|
// per step. So for a 100 steps, the swipe will take about 1/2 second to complete.
|
||||||
// `steps` is the number of move steps sent to the system
|
// `steps` is the number of move steps sent to the system
|
||||||
func (ud *uiaDriver) Swipe(fromX, fromY, toX, toY int, options ...DataOption) error {
|
func (ud *uiaDriver) Swipe(fromX, fromY, toX, toY int, options ...DataOption) error {
|
||||||
options = append(options, WithStepsOption(12))
|
options = append(options, WithDataSteps(12))
|
||||||
return ud.SwipeFloat(float64(fromX), float64(fromY), float64(toX), float64(toY), options...)
|
return ud.SwipeFloat(float64(fromX), float64(fromY), float64(toX), float64(toY), options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,16 +659,11 @@ func (ud *uiaDriver) SendKeys(text string, options ...DataOption) (err error) {
|
|||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"text": text,
|
"text": text,
|
||||||
}
|
}
|
||||||
// append options in post data for extra uiautomator configurations
|
// new data options in post data for extra uiautomator configurations
|
||||||
for _, option := range options {
|
d := NewData(options...)
|
||||||
option(data)
|
d.MergeData(data)
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := data["isReplace"]; !ok {
|
_, err = ud.httpPOST(d.Data, "/session", ud.sessionId, "keys")
|
||||||
data["isReplace"] = true // default true
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = ud.httpPOST(data, "/session", ud.sessionId, "keys")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,17 +671,16 @@ func (ud *uiaDriver) Input(text string, options ...DataOption) (err error) {
|
|||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"view": text,
|
"view": text,
|
||||||
}
|
}
|
||||||
// append options in post data for extra uiautomator configurations
|
// new data options in post data for extra uiautomator configurations
|
||||||
for _, option := range options {
|
d := NewData(options...)
|
||||||
option(data)
|
d.MergeData(data)
|
||||||
}
|
|
||||||
|
|
||||||
var element WebElement
|
var element WebElement
|
||||||
if valuetext, ok := data["textview"]; ok {
|
if valuetext, ok := d.Data["textview"]; ok {
|
||||||
element, err = ud.FindElement(BySelector{UiAutomator: NewUiSelectorHelper().TextContains(fmt.Sprintf("%v", valuetext)).String()})
|
element, err = ud.FindElement(BySelector{UiAutomator: NewUiSelectorHelper().TextContains(fmt.Sprintf("%v", valuetext)).String()})
|
||||||
} else if valueid, ok := data["id"]; ok {
|
} else if valueid, ok := d.Data["id"]; ok {
|
||||||
element, err = ud.FindElement(BySelector{ResourceIdID: fmt.Sprintf("%v", valueid)})
|
element, err = ud.FindElement(BySelector{ResourceIdID: fmt.Sprintf("%v", valueid)})
|
||||||
} else if valuedesc, ok := data["description"]; ok {
|
} else if valuedesc, ok := d.Data["description"]; ok {
|
||||||
element, err = ud.FindElement(BySelector{UiAutomator: NewUiSelectorHelper().Description(fmt.Sprintf("%v", valuedesc)).String()})
|
element, err = ud.FindElement(BySelector{UiAutomator: NewUiSelectorHelper().Description(fmt.Sprintf("%v", valuedesc)).String()})
|
||||||
} else {
|
} else {
|
||||||
element, err = ud.FindElement(BySelector{ClassName: ElementType{EditText: true}})
|
element, err = ud.FindElement(BySelector{ClassName: ElementType{EditText: true}})
|
||||||
|
|||||||
@@ -29,16 +29,11 @@ func (ue uiaElement) SendKeys(text string, options ...DataOption) (err error) {
|
|||||||
"text": text,
|
"text": text,
|
||||||
}
|
}
|
||||||
|
|
||||||
// append options in post data for extra uiautomator configurations
|
// new data options in post data for extra uiautomator configurations
|
||||||
for _, option := range options {
|
d := NewData(options...)
|
||||||
option(data)
|
d.MergeData(data)
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := data["isReplace"]; !ok {
|
_, err = ue.parent.httpPOST(d.Data, "/session", ue.parent.sessionId, "/element", ue.id, "/value")
|
||||||
data["isReplace"] = true // default true
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = ue.parent.httpPOST(data, "/session", ue.parent.sessionId, "/element", ue.id, "/value")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +108,7 @@ func (ue uiaElement) Swipe(fromX, fromY, toX, toY int) error {
|
|||||||
|
|
||||||
func (ue uiaElement) SwipeFloat(fromX, fromY, toX, toY float64) error {
|
func (ue uiaElement) SwipeFloat(fromX, fromY, toX, toY float64) error {
|
||||||
options := []DataOption{
|
options := []DataOption{
|
||||||
WithStepsOption(12),
|
WithDataSteps(12),
|
||||||
WithCustomOption("elementId", ue.id),
|
WithCustomOption("elementId", ue.id),
|
||||||
}
|
}
|
||||||
return ue.parent._swipe(fromX, fromY, toX, toY, options...)
|
return ue.parent._swipe(fromX, fromY, toX, toY, options...)
|
||||||
|
|||||||
@@ -26,5 +26,5 @@ func (dExt *DriverExt) DragOffsetFloat(pathname string, toX, toY, xOffset, yOffs
|
|||||||
fromY := y + height*yOffset
|
fromY := y + height*yOffset
|
||||||
|
|
||||||
return dExt.Driver.DragFloat(fromX, fromY, toX, toY,
|
return dExt.Driver.DragFloat(fromX, fromY, toX, toY,
|
||||||
WithPressDurationOption(pressForDuration[0]))
|
WithDataPressDuration(pressForDuration[0]))
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-18
@@ -383,9 +383,9 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
action.Scope = []float64{0, 0, 1, 1}
|
action.Scope = []float64{0, 0, 1, 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
identifierOption := WithIdentifierOption(action.Identifier)
|
identifierOption := WithDataIdentifier(action.Identifier)
|
||||||
indexOption := WithIndexOption(action.Index)
|
indexOption := WithDataIndex(action.Index)
|
||||||
scopeOption := WithScopeOption(dExt.GetAbsScope(action.Scope[0], action.Scope[1], action.Scope[2], action.Scope[3]))
|
scopeOption := WithDataScope(dExt.GetAbsScope(action.Scope[0], action.Scope[1], action.Scope[2], action.Scope[3]))
|
||||||
|
|
||||||
var point PointF
|
var point PointF
|
||||||
findApp := func(d *DriverExt) error {
|
findApp := func(d *DriverExt) error {
|
||||||
@@ -423,9 +423,9 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
action.Scope = []float64{0, 0, 1, 1}
|
action.Scope = []float64{0, 0, 1, 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
identifierOption := WithIdentifierOption(action.Identifier)
|
identifierOption := WithDataIdentifier(action.Identifier)
|
||||||
indexOption := WithIndexOption(action.Index)
|
indexOption := WithDataIndex(action.Index)
|
||||||
scopeOption := WithScopeOption(dExt.GetAbsScope(action.Scope[0], action.Scope[1], action.Scope[2], action.Scope[3]))
|
scopeOption := WithDataScope(dExt.GetAbsScope(action.Scope[0], action.Scope[1], action.Scope[2], action.Scope[3]))
|
||||||
|
|
||||||
var point PointF
|
var point PointF
|
||||||
findText := func(d *DriverExt) error {
|
findText := func(d *DriverExt) error {
|
||||||
@@ -464,7 +464,7 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
action.Scope = []float64{0, 0, 1, 1}
|
action.Scope = []float64{0, 0, 1, 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
scopeOption := WithScopeOption(dExt.GetAbsScope(action.Scope[0], action.Scope[1], action.Scope[2], action.Scope[3]))
|
scopeOption := WithDataScope(dExt.GetAbsScope(action.Scope[0], action.Scope[1], action.Scope[2], action.Scope[3]))
|
||||||
|
|
||||||
var point PointF
|
var point PointF
|
||||||
findText := func(d *DriverExt) error {
|
findText := func(d *DriverExt) error {
|
||||||
@@ -482,7 +482,7 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
}
|
}
|
||||||
foundTextAction := func(d *DriverExt) error {
|
foundTextAction := func(d *DriverExt) error {
|
||||||
// tap text
|
// tap text
|
||||||
return d.TapAbsXY(point.X, point.Y, WithIdentifierOption(action.Identifier))
|
return d.TapAbsXY(point.X, point.Y, WithDataIdentifier(action.Identifier))
|
||||||
}
|
}
|
||||||
|
|
||||||
// default to retry 10 times
|
// default to retry 10 times
|
||||||
@@ -520,7 +520,7 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
}
|
}
|
||||||
x, _ := location[0].(float64)
|
x, _ := location[0].(float64)
|
||||||
y, _ := location[1].(float64)
|
y, _ := location[1].(float64)
|
||||||
return dExt.TapXY(x, y, WithIdentifierOption(action.Identifier))
|
return dExt.TapXY(x, y, WithDataIdentifier(action.Identifier))
|
||||||
}
|
}
|
||||||
return fmt.Errorf("invalid %s params: %v", ACTION_TapXY, action.Params)
|
return fmt.Errorf("invalid %s params: %v", ACTION_TapXY, action.Params)
|
||||||
case ACTION_TapAbsXY:
|
case ACTION_TapAbsXY:
|
||||||
@@ -531,12 +531,12 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
}
|
}
|
||||||
x, _ := location[0].(float64)
|
x, _ := location[0].(float64)
|
||||||
y, _ := location[1].(float64)
|
y, _ := location[1].(float64)
|
||||||
return dExt.TapAbsXY(x, y, WithIdentifierOption(action.Identifier))
|
return dExt.TapAbsXY(x, y, WithDataIdentifier(action.Identifier))
|
||||||
}
|
}
|
||||||
return fmt.Errorf("invalid %s params: %v", ACTION_TapAbsXY, action.Params)
|
return fmt.Errorf("invalid %s params: %v", ACTION_TapAbsXY, action.Params)
|
||||||
case ACTION_Tap:
|
case ACTION_Tap:
|
||||||
if param, ok := action.Params.(string); ok {
|
if param, ok := action.Params.(string); ok {
|
||||||
return dExt.Tap(param, WithIdentifierOption(action.Identifier), WithIgnoreNotFoundErrorOption(true), WithIndexOption(action.Index))
|
return dExt.Tap(param, WithDataIdentifier(action.Identifier), WithDataIgnoreNotFoundError(true), WithDataIndex(action.Index))
|
||||||
}
|
}
|
||||||
return fmt.Errorf("invalid %s params: %v", ACTION_Tap, action.Params)
|
return fmt.Errorf("invalid %s params: %v", ACTION_Tap, action.Params)
|
||||||
case ACTION_TapByOCR:
|
case ACTION_TapByOCR:
|
||||||
@@ -545,16 +545,16 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
action.Scope = []float64{0, 0, 1, 1}
|
action.Scope = []float64{0, 0, 1, 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
indexOption := WithIndexOption(action.Index)
|
indexOption := WithDataIndex(action.Index)
|
||||||
scopeOption := WithScopeOption(dExt.GetAbsScope(action.Scope[0], action.Scope[1], action.Scope[2], action.Scope[3]))
|
scopeOption := WithDataScope(dExt.GetAbsScope(action.Scope[0], action.Scope[1], action.Scope[2], action.Scope[3]))
|
||||||
identifierOption := WithIdentifierOption(action.Identifier)
|
identifierOption := WithDataIdentifier(action.Identifier)
|
||||||
IgnoreNotFoundErrorOption := WithIgnoreNotFoundErrorOption(action.IgnoreNotFoundError)
|
IgnoreNotFoundErrorOption := WithDataIgnoreNotFoundError(action.IgnoreNotFoundError)
|
||||||
return dExt.TapByOCR(ocrText, identifierOption, IgnoreNotFoundErrorOption, indexOption, scopeOption)
|
return dExt.TapByOCR(ocrText, identifierOption, IgnoreNotFoundErrorOption, indexOption, scopeOption)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("invalid %s params: %v", ACTION_TapByOCR, action.Params)
|
return fmt.Errorf("invalid %s params: %v", ACTION_TapByOCR, action.Params)
|
||||||
case ACTION_TapByCV:
|
case ACTION_TapByCV:
|
||||||
if imagePath, ok := action.Params.(string); ok {
|
if imagePath, ok := action.Params.(string); ok {
|
||||||
return dExt.TapByCV(imagePath, WithIdentifierOption(action.Identifier), WithIgnoreNotFoundErrorOption(true), WithIndexOption(action.Index))
|
return dExt.TapByCV(imagePath, WithDataIdentifier(action.Identifier), WithDataIgnoreNotFoundError(true), WithDataIndex(action.Index))
|
||||||
}
|
}
|
||||||
return fmt.Errorf("invalid %s params: %v", ACTION_TapByCV, action.Params)
|
return fmt.Errorf("invalid %s params: %v", ACTION_TapByCV, action.Params)
|
||||||
case ACTION_DoubleTapXY:
|
case ACTION_DoubleTapXY:
|
||||||
@@ -574,7 +574,7 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
}
|
}
|
||||||
return fmt.Errorf("invalid %s params: %v", ACTION_DoubleTap, action.Params)
|
return fmt.Errorf("invalid %s params: %v", ACTION_DoubleTap, action.Params)
|
||||||
case ACTION_Swipe:
|
case ACTION_Swipe:
|
||||||
identifierOption := WithIdentifierOption(action.Identifier)
|
identifierOption := WithDataIdentifier(action.Identifier)
|
||||||
if positions, ok := action.Params.([]interface{}); ok {
|
if positions, ok := action.Params.([]interface{}); ok {
|
||||||
// relative fromX, fromY, toX, toY of window size: [0.5, 0.9, 0.5, 0.1]
|
// relative fromX, fromY, toX, toY of window size: [0.5, 0.9, 0.5, 0.1]
|
||||||
if len(positions) != 4 {
|
if len(positions) != 4 {
|
||||||
@@ -606,7 +606,7 @@ func (dExt *DriverExt) DoAction(action MobileAction) error {
|
|||||||
options = append(options, WithCustomOption("description", action.Description))
|
options = append(options, WithCustomOption("description", action.Description))
|
||||||
}
|
}
|
||||||
if action.Identifier != "" {
|
if action.Identifier != "" {
|
||||||
options = append(options, WithIdentifierOption(action.Identifier))
|
options = append(options, WithDataIdentifier(action.Identifier))
|
||||||
}
|
}
|
||||||
return dExt.Driver.Input(param, options...)
|
return dExt.Driver.Input(param, options...)
|
||||||
case CtlSleep:
|
case CtlSleep:
|
||||||
|
|||||||
+74
-25
@@ -3,6 +3,7 @@ package uixt
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -773,62 +774,110 @@ type Rect struct {
|
|||||||
Size
|
Size
|
||||||
}
|
}
|
||||||
|
|
||||||
type DataOption func(data map[string]interface{})
|
type DataOption func(data *DataOptions)
|
||||||
|
|
||||||
func WithCustomOption(key string, value interface{}) DataOption {
|
func WithCustomOption(key string, value interface{}) DataOption {
|
||||||
return func(data map[string]interface{}) {
|
return func(data *DataOptions) {
|
||||||
data[key] = value
|
data.Data[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithPressDurationOption(duraion float64) DataOption {
|
func WithDataPressDuration(duration float64) DataOption {
|
||||||
return func(data map[string]interface{}) {
|
return func(data *DataOptions) {
|
||||||
data["duration"] = duraion
|
data.Data["duration"] = duration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithStepsOption(steps int) DataOption {
|
func WithDataSteps(steps int) DataOption {
|
||||||
return func(data map[string]interface{}) {
|
return func(data *DataOptions) {
|
||||||
data["steps"] = steps
|
data.Data["steps"] = steps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithFrequencyOption(frequency int) DataOption {
|
func WithDataFrequency(frequency int) DataOption {
|
||||||
return func(data map[string]interface{}) {
|
return func(data *DataOptions) {
|
||||||
data["frequency"] = frequency
|
data.Data["frequency"] = frequency
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithIndexOption(index int) DataOption {
|
func WithDataIndex(index int) DataOption {
|
||||||
return func(data map[string]interface{}) {
|
return func(data *DataOptions) {
|
||||||
data["index"] = index
|
data.Index = index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithScopeOption(x1, x2, y1, y2 int) DataOption {
|
func WithDataScope(x1, x2, y1, y2 int) DataOption {
|
||||||
return func(data map[string]interface{}) {
|
return func(data *DataOptions) {
|
||||||
data["scope"] = []int{x1, x2, y1, y2}
|
data.Scope = []int{x1, x2, y1, y2}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithIdentifierOption(identifier string) DataOption {
|
func WithDataIdentifier(identifier string) DataOption {
|
||||||
if identifier == "" {
|
if identifier == "" {
|
||||||
return func(data map[string]interface{}) {}
|
return func(data *DataOptions) {}
|
||||||
}
|
}
|
||||||
return func(data map[string]interface{}) {
|
return func(data *DataOptions) {
|
||||||
data["log"] = map[string]interface{}{
|
data.Data["log"] = map[string]interface{}{
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"data": identifier,
|
"data": identifier,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithIgnoreNotFoundErrorOption(ignoreError bool) DataOption {
|
func WithDataIgnoreNotFoundError(ignoreError bool) DataOption {
|
||||||
return func(data map[string]interface{}) {
|
return func(data *DataOptions) {
|
||||||
data["ignoreNotFoundError"] = ignoreError
|
data.IgnoreNotFoundError = ignoreError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DataOptions struct {
|
||||||
|
Data map[string]interface{} // configurations used by ios/android driver
|
||||||
|
Scope []int // used by ocr to get text position in the scope
|
||||||
|
Index int // index of the target element, should start from 1
|
||||||
|
IgnoreNotFoundError bool // ignore error if target element not found
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewData(options ...DataOption) *DataOptions {
|
||||||
|
data := &DataOptions{
|
||||||
|
Data: map[string]interface{}{},
|
||||||
|
}
|
||||||
|
for _, option := range options {
|
||||||
|
option(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data.Scope) == 0 {
|
||||||
|
data.Scope = []int{0, 0, math.MaxInt64, math.MaxInt64} // default scope
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := data.Data["steps"]; !ok {
|
||||||
|
data.Data["steps"] = 12 // default steps
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := data.Data["duration"]; !ok {
|
||||||
|
data.Data["duration"] = 1.0 // default duration
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := data.Data["frequency"]; !ok {
|
||||||
|
data.Data["frequency"] = 60 // default frequency
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := data.Data["isReplace"]; !ok {
|
||||||
|
data.Data["isReplace"] = true // default true
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataOptions) MergeData(data map[string]interface{}) {
|
||||||
|
for key, value := range data {
|
||||||
|
d.Data[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataOptions) AddData(key string, value interface{}) {
|
||||||
|
d.Data[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
// current implemeted device: IOSDevice, AndroidDevice
|
// current implemeted device: IOSDevice, AndroidDevice
|
||||||
type Device interface {
|
type Device interface {
|
||||||
UUID() string
|
UUID() string
|
||||||
|
|||||||
+15
-26
@@ -379,12 +379,11 @@ func (wd *wdaDriver) TapFloat(x, y float64, options ...DataOption) (err error) {
|
|||||||
"x": x,
|
"x": x,
|
||||||
"y": y,
|
"y": y,
|
||||||
}
|
}
|
||||||
// append options in post data for extra WDA configurations
|
// new data options in post data for extra WDA configurations
|
||||||
// e.g. add identifier in tap event logs
|
d := NewData(options...)
|
||||||
for _, option := range options {
|
d.MergeData(data)
|
||||||
option(data)
|
|
||||||
}
|
_, err = wd.httpPOST(d.Data, "/session", wd.sessionId, "/wda/tap/0")
|
||||||
_, err = wd.httpPOST(data, "/session", wd.sessionId, "/wda/tap/0")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,26 +432,21 @@ func (wd *wdaDriver) DragFloat(fromX, fromY, toX, toY float64, options ...DataOp
|
|||||||
"toY": toY,
|
"toY": toY,
|
||||||
}
|
}
|
||||||
|
|
||||||
// append options in post data for extra WDA configurations
|
// new data options in post data for extra WDA configurations
|
||||||
// e.g. use WithPressDurationOption to set pressForDuration
|
d := NewData(options...)
|
||||||
for _, option := range options {
|
d.MergeData(data)
|
||||||
option(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := data["duration"]; !ok {
|
_, err = wd.httpPOST(d.Data, "/session", wd.sessionId, "/wda/dragfromtoforduration")
|
||||||
data["duration"] = 1.0 // default duration
|
|
||||||
}
|
|
||||||
_, err = wd.httpPOST(data, "/session", wd.sessionId, "/wda/dragfromtoforduration")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *wdaDriver) Swipe(fromX, fromY, toX, toY int, options ...DataOption) error {
|
func (wd *wdaDriver) Swipe(fromX, fromY, toX, toY int, options ...DataOption) error {
|
||||||
options = append(options, WithPressDurationOption(0))
|
options = append(options, WithDataPressDuration(0))
|
||||||
return wd.SwipeFloat(float64(fromX), float64(fromY), float64(toX), float64(toY), options...)
|
return wd.SwipeFloat(float64(fromX), float64(fromY), float64(toX), float64(toY), options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *wdaDriver) SwipeFloat(fromX, fromY, toX, toY float64, options ...DataOption) error {
|
func (wd *wdaDriver) SwipeFloat(fromX, fromY, toX, toY float64, options ...DataOption) error {
|
||||||
options = append(options, WithPressDurationOption(0))
|
options = append(options, WithDataPressDuration(0))
|
||||||
return wd.DragFloat(fromX, fromY, toX, toY, options...)
|
return wd.DragFloat(fromX, fromY, toX, toY, options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,16 +508,11 @@ func (wd *wdaDriver) SendKeys(text string, options ...DataOption) (err error) {
|
|||||||
// [[FBRoute POST:@"/wda/keys"] respondWithTarget:self action:@selector(handleKeys:)]
|
// [[FBRoute POST:@"/wda/keys"] respondWithTarget:self action:@selector(handleKeys:)]
|
||||||
data := map[string]interface{}{"value": strings.Split(text, "")}
|
data := map[string]interface{}{"value": strings.Split(text, "")}
|
||||||
|
|
||||||
// append options in post data for extra WDA configurations
|
// new data options in post data for extra WDA configurations
|
||||||
// e.g. use WithFrequency to set frequency of typing
|
d := NewData(options...)
|
||||||
for _, option := range options {
|
d.MergeData(data)
|
||||||
option(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := data["frequency"]; !ok {
|
_, err = wd.httpPOST(d.Data, "/session", wd.sessionId, "/wda/keys")
|
||||||
data["frequency"] = 60 // default frequency
|
|
||||||
}
|
|
||||||
_, err = wd.httpPOST(data, "/session", wd.sessionId, "/wda/keys")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,16 +30,11 @@ func (we wdaElement) SendKeys(text string, options ...DataOption) (err error) {
|
|||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"value": strings.Split(text, ""),
|
"value": strings.Split(text, ""),
|
||||||
}
|
}
|
||||||
// append options in post data for extra uiautomator configurations
|
// new data options in post data for extra uiautomator configurations
|
||||||
for _, option := range options {
|
d := NewData(options...)
|
||||||
option(data)
|
d.MergeData(data)
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := data["frequency"]; !ok {
|
_, err = we.parent.httpPOST(d.Data, "/session", we.parent.sessionId, "/element", we.id, "/value")
|
||||||
data["frequency"] = 60
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = we.parent.httpPOST(data, "/session", we.parent.sessionId, "/element", we.id, "/value")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -443,7 +443,7 @@ func Test_remoteWD_TouchAndHold(t *testing.T) {
|
|||||||
func Test_remoteWD_Drag(t *testing.T) {
|
func Test_remoteWD_Drag(t *testing.T) {
|
||||||
setup(t)
|
setup(t)
|
||||||
|
|
||||||
// err := driver.Drag(200, 300, 200, 500, WithPressDurationOption(0.5))
|
// err := driver.Drag(200, 300, 200, 500, WithDataPressDuration(0.5))
|
||||||
err := driver.Swipe(200, 300, 200, 500)
|
err := driver.Swipe(200, 300, 200, 500)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math"
|
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -111,20 +110,7 @@ func getLogID(header http.Header) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *veDEMOCRService) FindText(text string, imageBuf []byte, options ...DataOption) (rect image.Rectangle, err error) {
|
func (s *veDEMOCRService) FindText(text string, imageBuf []byte, options ...DataOption) (rect image.Rectangle, err error) {
|
||||||
data := map[string]interface{}{}
|
data := NewData(options...)
|
||||||
for _, option := range options {
|
|
||||||
option(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := data["index"]; !ok {
|
|
||||||
data["index"] = 0 // index not specified
|
|
||||||
}
|
|
||||||
index, _ := data["index"].(int)
|
|
||||||
|
|
||||||
if _, ok := data["scope"]; !ok {
|
|
||||||
data["scope"] = []int{0, 0, math.MaxInt64, math.MaxInt64} // scope not specified
|
|
||||||
}
|
|
||||||
scope, _ := data["scope"].([]int)
|
|
||||||
|
|
||||||
ocrResults, err := s.getOCRResult(imageBuf)
|
ocrResults, err := s.getOCRResult(imageBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -146,7 +132,7 @@ func (s *veDEMOCRService) FindText(text string, imageBuf []byte, options ...Data
|
|||||||
Y: int(ocrResult.Points[2].Y),
|
Y: int(ocrResult.Points[2].Y),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if rect.Min.X > scope[0] && rect.Max.X < scope[2] && rect.Min.Y > scope[1] && rect.Max.Y < scope[3] {
|
if rect.Min.X > data.Scope[0] && rect.Max.X < data.Scope[2] && rect.Min.Y > data.Scope[1] && rect.Max.Y < data.Scope[3] {
|
||||||
ocrTexts = append(ocrTexts, ocrResult.Text)
|
ocrTexts = append(ocrTexts, ocrResult.Text)
|
||||||
|
|
||||||
// not contains text
|
// not contains text
|
||||||
@@ -163,7 +149,7 @@ func (s *veDEMOCRService) FindText(text string, imageBuf []byte, options ...Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
// match exactly, and not specify index, return the first one
|
// match exactly, and not specify index, return the first one
|
||||||
if index == 0 {
|
if data.Index == 0 {
|
||||||
return rect, nil
|
return rect, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,7 +160,7 @@ func (s *veDEMOCRService) FindText(text string, imageBuf []byte, options ...Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get index
|
// get index
|
||||||
idx := index
|
idx := data.Index
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
// NOTICE: index start from 1
|
// NOTICE: index start from 1
|
||||||
idx = idx - 1
|
idx = idx - 1
|
||||||
@@ -198,20 +184,11 @@ func (s *veDEMOCRService) FindTexts(texts []string, imageBuf []byte, options ...
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data := map[string]interface{}{}
|
data := NewData(options...)
|
||||||
for _, option := range options {
|
ocrTexts := map[string]bool{}
|
||||||
option(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := data["scope"]; !ok {
|
|
||||||
data["scope"] = []int{0, 0, math.MaxInt64, math.MaxInt64} // scope not specified
|
|
||||||
}
|
|
||||||
scope, _ := data["scope"].([]int)
|
|
||||||
|
|
||||||
var success bool
|
var success bool
|
||||||
var rect image.Rectangle
|
var rect image.Rectangle
|
||||||
ocrTexts := map[string]bool{}
|
|
||||||
|
|
||||||
for _, text := range texts {
|
for _, text := range texts {
|
||||||
var found bool
|
var found bool
|
||||||
for _, ocrResult := range ocrResults {
|
for _, ocrResult := range ocrResults {
|
||||||
@@ -227,7 +204,7 @@ func (s *veDEMOCRService) FindTexts(texts []string, imageBuf []byte, options ...
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if rect.Min.X >= scope[0] && rect.Max.X <= scope[2] && rect.Min.Y >= scope[1] && rect.Max.Y <= scope[3] {
|
if rect.Min.X >= data.Scope[0] && rect.Max.X <= data.Scope[2] && rect.Min.Y >= data.Scope[1] && rect.Max.Y <= data.Scope[3] {
|
||||||
ocrTexts[ocrResult.Text] = true
|
ocrTexts[ocrResult.Text] = true
|
||||||
|
|
||||||
// not contains text
|
// not contains text
|
||||||
|
|||||||
+11
-24
@@ -65,16 +65,12 @@ func (dExt *DriverExt) GetImageXY(imagePath string, options ...DataOption) (poin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (dExt *DriverExt) TapByOCR(ocrText string, options ...DataOption) error {
|
func (dExt *DriverExt) TapByOCR(ocrText string, options ...DataOption) error {
|
||||||
data := map[string]interface{}{}
|
data := NewData(options...)
|
||||||
for _, option := range options {
|
|
||||||
option(data)
|
|
||||||
}
|
|
||||||
point, err := dExt.GetTextXY(ocrText, options...)
|
point, err := dExt.GetTextXY(ocrText, options...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if d, ok := data["ignoreNotFoundError"]; ok {
|
if data.IgnoreNotFoundError {
|
||||||
if b, ok := d.(bool); b && ok {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -83,16 +79,12 @@ func (dExt *DriverExt) TapByOCR(ocrText string, options ...DataOption) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (dExt *DriverExt) TapByCV(imagePath string, options ...DataOption) error {
|
func (dExt *DriverExt) TapByCV(imagePath string, options ...DataOption) error {
|
||||||
data := map[string]interface{}{}
|
data := NewData(options...)
|
||||||
for _, option := range options {
|
|
||||||
option(data)
|
|
||||||
}
|
|
||||||
point, err := dExt.GetImageXY(imagePath, options...)
|
point, err := dExt.GetImageXY(imagePath, options...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if d, ok := data["ignoreNotFoundError"]; ok {
|
if data.IgnoreNotFoundError {
|
||||||
if b, ok := d.(bool); b && ok {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -111,17 +103,12 @@ func (dExt *DriverExt) TapOffset(param string, xOffset, yOffset float64, options
|
|||||||
return ele.Click()
|
return ele.Click()
|
||||||
}
|
}
|
||||||
|
|
||||||
data := map[string]interface{}{}
|
data := NewData(options...)
|
||||||
for _, option := range options {
|
|
||||||
option(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
x, y, width, height, err := dExt.FindUIRectInUIKit(param, options...)
|
x, y, width, height, err := dExt.FindUIRectInUIKit(param, options...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if d, ok := data["ignoreNotFoundError"]; ok {
|
if data.IgnoreNotFoundError {
|
||||||
if b, ok := d.(bool); b && ok {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user