Skip to content

Commit a0a3cfc

Browse files
authored
feat: add speed option (#318)
* add speed option * tweak docstring * use android sdk 29 to make the sumulator stable * add note
1 parent 16b4f09 commit a0a3cfc

File tree

8 files changed

+107
-22
lines changed

8 files changed

+107
-22
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Read `release_notes.md` for commit level details.
55
## [Unreleased]
66

77
### Enhancements
8+
- Add `speed` argument for `ppium::Core::Base::Driver#set_location`
89
- Add `multiple` and `match_neighbour_threshold` arguments for `Appium::Core::Base::Driver#find_image_occurrence`
910

1011
### Bug fixes

ci-jobs/functional_test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ parameters:
44
vmImageForIOS: 'macOS-10.15' # Not sure the reason, but macOS 10.14 instance raises no info.plist error
55
xcodeForIOS: 12.2
66
xcodeForTVOS: 12.2
7-
androidSDK: 30
7+
androidSDK: 29 # API Level 30 emulators are more unstable than 29
88
appiumVersion: 'beta'
99
ignoreVersionSkip: true
1010
CI: true

lib/appium_lib_core/common/base/bridge/mjsonwp.rb

+6
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ def send_actions(_data)
7878
def convert_to_element(id)
7979
::Selenium::WebDriver::Element.new self, element_id_from(id)
8080
end
81+
82+
def set_location(lat, lon, alt = 0.0, speed: nil)
83+
loc = { latitude: lat, longitude: lon, altitude: alt }
84+
loc[:speed] = speed unless speed.nil?
85+
execute :set_location, {}, { location: loc }
86+
end
8187
end # class MJSONWP
8288
end # class Bridge
8389
end # class Base

lib/appium_lib_core/common/base/bridge/w3c.rb

+2-11
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,9 @@ def location
170170

171171
# For Appium
172172
# No implementation for W3C webdriver module
173-
# called in +extend DriverExtensions::HasLocation+
174-
# It has below code as well. We should consider the same context in Selenium 4 as backward compatibility.
175-
#
176-
# def location=(loc)
177-
# # note: Location = Struct.new(:latitude, :longitude, :altitude)
178-
# raise TypeError, "expected #{Location}, got #{loc.inspect}:#{loc.class}" unless loc.is_a?(Location)
179-
#
180-
# @bridge.set_location loc.latitude, loc.longitude, loc.altitude
181-
# end
182-
#
183-
def set_location(lat, lon, alt = 0.0)
173+
def set_location(lat, lon, alt = 0.0, speed: nil)
184174
loc = { latitude: lat, longitude: lon, altitude: alt }
175+
loc[:speed] = speed unless speed.nil?
185176
execute :set_location, {}, { location: loc }
186177
end
187178

lib/appium_lib_core/common/base/driver.rb

+4-10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
require_relative 'screenshot'
1818
require_relative 'rotable'
1919
require_relative 'remote_status'
20+
require_relative 'has_location'
2021

2122
module Appium
2223
module Core
@@ -26,11 +27,14 @@ class Driver < ::Selenium::WebDriver::Driver
2627
include ::Selenium::WebDriver::DriverExtensions::HasSessionId
2728
include ::Selenium::WebDriver::DriverExtensions::HasRemoteStatus
2829
include ::Selenium::WebDriver::DriverExtensions::HasWebStorage
30+
include ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
31+
include ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
2932

3033
include ::Appium::Core::Base::Rotatable
3134
include ::Appium::Core::Base::SearchContext
3235
include ::Appium::Core::Base::TakesScreenshot
3336
include ::Appium::Core::Base::HasRemoteStatus
37+
include ::Appium::Core::Base::HasLocation
3438

3539
# Private API.
3640
# Do not use this for general use. Used by flutter driver to get bridge for creating a new element
@@ -39,16 +43,6 @@ class Driver < ::Selenium::WebDriver::Driver
3943
def initialize(opts = {})
4044
listener = opts.delete(:listener)
4145
@bridge = ::Appium::Core::Base::Bridge.handshake(**opts)
42-
if @bridge.dialect == :oss # MJSONWP
43-
extend ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
44-
extend ::Selenium::WebDriver::DriverExtensions::HasLocation
45-
extend ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
46-
elsif @bridge.dialect == :w3c
47-
# TODO: Only for Appium. Ideally, we'd like to remove the below like selenium-webdriver
48-
extend ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
49-
extend ::Selenium::WebDriver::DriverExtensions::HasLocation
50-
extend ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
51-
end
5246
super(@bridge, listener: listener)
5347
end
5448

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# frozen_string_literal: true
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
module Appium
16+
module Core
17+
class Base
18+
#
19+
# @api private
20+
#
21+
module HasLocation
22+
# Get the location of the device.
23+
#
24+
# @return [::Selenium::WebDriver::Location]
25+
#
26+
# @example
27+
#
28+
# driver.location #=> ::Selenium::WebDriver::Location.new(10, 10, 10)
29+
#
30+
def location
31+
@bridge.location
32+
end
33+
34+
# Set the location of the device.
35+
#
36+
# @param [::Selenium::WebDriver::Location] location Set the location.
37+
#
38+
# @example
39+
#
40+
# driver.location = ::Selenium::WebDriver::Location.new(10, 10, 10)
41+
#
42+
def location=(location)
43+
unless location.is_a?(::Selenium::WebDriver::Location)
44+
raise TypeError, "expected #{::Selenium::WebDriver::Location}, got #{location.inspect}:#{location.class}"
45+
end
46+
47+
@bridge.set_location location.latitude, location.longitude, location.altitude
48+
end
49+
50+
# Set the location of the device.
51+
#
52+
# @param [String, Number] latitude Set the latitude.
53+
# @param [String, Number] longitude Set the longitude.
54+
# @param [String, Number] altitude Set the altitude.
55+
# @param [String, Number] speed Set the speed to apply the location on Android real devices @since Appium 1.21.0.
56+
# @param [::Selenium::WebDriver::Location]
57+
#
58+
# @example
59+
#
60+
# driver.location = ::Selenium::WebDriver::Location.new(10, 10, 10)
61+
#
62+
def set_location(latitude, longitude, altitude, speed: nil)
63+
if speed.nil?
64+
self.location = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
65+
else
66+
loc = ::Selenium::WebDriver::Location.new(Float(latitude), Float(longitude), Float(altitude))
67+
@bridge.set_location loc.latitude, loc.longitude, loc.altitude, speed: Float(speed)
68+
end
69+
end
70+
end
71+
end
72+
end
73+
end

test/unit/android/webdriver/mjsonwp/commands_test.rb

+10
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ def test_set_location
102102
assert_requested(:post, "#{SESSION}/location", times: 2)
103103
end
104104

105+
def test_set_location_speed
106+
stub_request(:post, "#{SESSION}/location")
107+
.with(body: { location: { latitude: 1.0, longitude: 1.0, altitude: 1.0, speed: 1.0 } }.to_json)
108+
.to_return(headers: HEADER, status: 200, body: { value: nil }.to_json)
109+
110+
@driver.set_location 1, 1, 1, speed: 1
111+
112+
assert_requested(:post, "#{SESSION}/location", times: 1)
113+
end
114+
105115
def test_rotate
106116
stub_request(:post, "#{SESSION}/orientation")
107117
.to_return(headers: HEADER, status: 200, body: { value: 'xxxx' }.to_json)

test/unit/android/webdriver/w3c/commands_test.rb

+10
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ def test_set_location
9696
assert_requested(:post, "#{SESSION}/location", times: 2)
9797
end
9898

99+
def test_set_location_speed
100+
stub_request(:post, "#{SESSION}/location")
101+
.with(body: { location: { latitude: 1.0, longitude: 1.0, altitude: 1.0, speed: 1.0 } }.to_json)
102+
.to_return(headers: HEADER, status: 200, body: { value: nil }.to_json)
103+
104+
@driver.set_location 1, 1, 1, speed: 1
105+
106+
assert_requested(:post, "#{SESSION}/location", times: 1)
107+
end
108+
99109
def test_rotate
100110
stub_request(:post, "#{SESSION}/orientation")
101111
.to_return(headers: HEADER, status: 200, body: { value: 'xxxx' }.to_json)

0 commit comments

Comments
 (0)