diff --git a/README.md b/README.md index 1ba2512a..ac240e30 100644 --- a/README.md +++ b/README.md @@ -333,14 +333,15 @@ Roles are ALWAYS defined at the begining of the cases. You have to write always 7. [press](#press) 8. [click_and_hold](#click_and_hold) 9. [swipe_up/swipe_down](#swipe_up/swipe_down) -10. [swipe_elements](#swipe_elements) -11. [swipe_coord](#swipe_coord) -12. [click_coord](#click_coord) -13. [clipboard](#clipboard) -14. [handle_ios_alert](#handle_ios_alert) -15. [notifications](#notifications) -16. [back](#back) -17. [update_settings](#update_settings) +10. [swipe_on_element](#swipe_on_element) +11. [swipe_elements](#swipe_elements) +12. [swipe_coord](#swipe_coord) +13. [click_coord](#click_coord) +14. [clipboard](#clipboard) +15. [handle_ios_alert](#handle_ios_alert) +16. [notifications](#notifications) +17. [back](#back) +18. [update_settings](#update_settings) ## API @@ -762,7 +763,7 @@ It works simillar as click, but it will use Appium Actions of the element intern It works simillar as click, but it holds the pressing. The labels and options that you can use are exactly the same. Refer to `click` for more information. -### swipe_up/swipe_down (Mobile) +### swipe_up/swipe_down - Type: swipe_up/swipe_down Role: role1 (Optional. if not specified will use the first one defined in the case Roles) @@ -770,7 +771,7 @@ It works simillar as click, but it holds the pressing. The labels and options th Id: //some/path (Element from where to start the swipe) NoRaise: false/true (Default - false -> will rise error on fail) -### swipe_elements (Mobile) +### swipe_elements - Type: swipe_elements Role: role1 (Optional. if not specified will use the first one defined in the case Roles) @@ -781,7 +782,34 @@ It works simillar as click, but it holds the pressing. The labels and options th Strategy: id/css/xpath/uiautomator/class_chain/... (Element from where to start the swipe) Id: //some/path (Element from where to start the swipe) -### swipe_coord (Mobile) +### swipe_on_element + +Swipe in an arbitrary direction over a single element. By default, the swipe start and endpoints are at the element midpoint (width * 0.5, height * 0.5), which can be changed using offsets. These can be either absolute (in pixels) or relative (in fractions of the element width/height). The swipe duration can also be configured (default is 1 second). + + - Type: swipe_on_element + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Strategy: id/css/xpath/uiautomator/class_chain/... + Id: //some/path + OffsetStartX: 50 (Translates to (0.5 * width) + 50) + OffsetStartY: -25 (Translates to (0.5 * height) - 25) + OffsetEndX: -150 + OffsetEndY: -50 + SwipeTime: 5 (In seconds - default is 1) + NoRaise: false/true (Default - false -> will raise error on fail) + + - Type: swipe_on_element + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Strategy: id/css/xpath/uiautomator/class_chain/... + Id: //some/path + OffsetStartFractionX: 0.4 (Translates to 0.5 + 0.4 = 0.9 * width) + OffsetStartFractionY: -0.2 (Translates to 0.5 - 0.2 = 0.3 * height) + OffsetEndFractionX: -0.4 + OffsetEndFractionY: -0.3 + NoRaise: false/true (Default - false -> will raise error on fail) + +If only 1-3 offsets need to be changed, the other offsets can be omitted. Additionally, mixing absolute and relative offsets within the same action is allowed, but if both offset types are provided for the same element and axis, the absolute offset takes precedence. + +### swipe_coord - Type: swipe_coord Role: role1 (Optional. if not specified will use the first one defined in the case Roles) @@ -790,7 +818,7 @@ It works simillar as click, but it holds the pressing. The labels and options th EndX: 300 EndY: 400 -### click_coord (Mobile) +### click_coord - Type: click_coord Role: role1 (Optional. if not specified will use the first one defined in the case Roles) diff --git a/lib/core/device.rb b/lib/core/device.rb index 0c8e69d8..330406cd 100644 --- a/lib/core/device.rb +++ b/lib/core/device.rb @@ -708,6 +708,48 @@ def swipe_elements(action) .perform end + # Swipe in an arbitrary direction over an element + # Accepts: + # Strategy + # Id + # OffsetStartFractionX + # OffsetStartFractionY + # OffsetEndFractionX + # OffsetEndFractionY + # OffsetStartX + # OffsetStartY + # OffsetEndX + # OffsetEndY + # SwipeTime + def swipe_on_element(action) + el = wait_for(action) + swipe_time = action.key?("SwipeTime") ? action["SwipeTime"] : 1 + elx_midpoint = el.location.x + el.size.width * 0.5 + ely_midpoint = el.location.y + el.size.height * 0.5 + elx_start_offset = ely_start_offset = elx_end_offset = ely_end_offset = 0 + + elx_start_offset = el.size.width * action["OffsetStartFractionX"] if action.key?("OffsetStartFractionX") + ely_start_offset = el.size.height * action["OffsetStartFractionY"] if action.key?("OffsetStartFractionY") + elx_end_offset = el.size.width * action["OffsetEndFractionX"] if action.key?("OffsetEndFractionX") + ely_end_offset = el.size.height * action["OffsetEndFractionY"] if action.key?("OffsetEndFractionY") + elx_start_offset = action["OffsetStartX"] if action.key?("OffsetStartX") + ely_start_offset = action["OffsetStartY"] if action.key?("OffsetStartY") + elx_end_offset = action["OffsetEndX"] if action.key?("OffsetEndX") + ely_end_offset = action["OffsetEndY"] if action.key?("OffsetEndY") + + elx_start = elx_midpoint + elx_start_offset + ely_start = ely_midpoint + ely_start_offset + elx_end = elx_midpoint + elx_end_offset + ely_end = ely_midpoint + ely_end_offset + + @driver.action + .move_to_location(elx_start, ely_start) + .pointer_down(:left) + .move_to_location(elx_end, ely_end, duration: swipe_time) + .release + .perform + end + # TODO def driver_method(action) log_info("TODO")