Skip to content

Commit 4219f1d

Browse files
authored
feature: support selenium-webdriver3.4.1+ (#627)
* update webdriver3.4.3 * add grid 3.4.0 * fix test specs * add selenium 3.x config * define parameterized test method and use it * fix some test flakiness * arrange a bit
1 parent 6eae1b6 commit 4219f1d

File tree

19 files changed

+153
-106
lines changed

19 files changed

+153
-106
lines changed

android_tests/lib/android/specs/common/command.rb

+41-37
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,50 @@ def before_first
88
before_first
99
end
1010

11+
def parameterized_method_defined_check(array)
12+
array.each { |v| Selenium::WebDriver::Remote::OSS::Bridge.method_defined?(v).must_equal true }
13+
end
14+
1115
t 'check all command no arg' do
12-
Selenium::WebDriver::Remote::Bridge.method_defined?(:shake).must_equal true
13-
Selenium::WebDriver::Remote::Bridge.method_defined?(:launch_app).must_equal true
14-
Selenium::WebDriver::Remote::Bridge.method_defined?(:close_app).must_equal true
15-
Selenium::WebDriver::Remote::Bridge.method_defined?(:reset).must_equal true
16-
Selenium::WebDriver::Remote::Bridge.method_defined?(:device_locked?).must_equal true
17-
Selenium::WebDriver::Remote::Bridge.method_defined?(:open_notifications).must_equal true
18-
Selenium::WebDriver::Remote::Bridge.method_defined?(:toggle_airplane_mode).must_equal true
19-
Selenium::WebDriver::Remote::Bridge.method_defined?(:current_activity).must_equal true
20-
Selenium::WebDriver::Remote::Bridge.method_defined?(:current_package).must_equal true
21-
Selenium::WebDriver::Remote::Bridge.method_defined?(:get_network_connection).must_equal true
22-
Selenium::WebDriver::Remote::Bridge.method_defined?(:get_performance_data_types).must_equal true
23-
Selenium::WebDriver::Remote::Bridge.method_defined?(:get_performance_data).must_equal true
24-
Selenium::WebDriver::Remote::Bridge.method_defined?(:get_system_bars).must_equal true
25-
Selenium::WebDriver::Remote::Bridge.method_defined?(:get_display_density).must_equal true
26-
Selenium::WebDriver::Remote::Bridge.method_defined?(:is_keyboard_shown).must_equal true
16+
parameterized_method_defined_check([:shake,
17+
:launch_app,
18+
:close_app,
19+
:reset,
20+
:device_locked?,
21+
:open_notifications,
22+
:toggle_airplane_mode,
23+
:current_activity,
24+
:current_package,
25+
:get_network_connection,
26+
:get_performance_data_types,
27+
:get_performance_data,
28+
:get_system_bars,
29+
:get_display_density,
30+
:is_keyboard_shown])
2731
end
2832

2933
t 'check all command with arg' do
30-
Selenium::WebDriver::Remote::Bridge.method_defined?(:available_contexts).must_equal true
31-
Selenium::WebDriver::Remote::Bridge.method_defined?(:app_strings).must_equal true
32-
Selenium::WebDriver::Remote::Bridge.method_defined?(:lock).must_equal true
33-
Selenium::WebDriver::Remote::Bridge.method_defined?(:install_app).must_equal true
34-
Selenium::WebDriver::Remote::Bridge.method_defined?(:remove_app).must_equal true
35-
Selenium::WebDriver::Remote::Bridge.method_defined?(:app_installed?).must_equal true
36-
Selenium::WebDriver::Remote::Bridge.method_defined?(:background_app).must_equal true
37-
Selenium::WebDriver::Remote::Bridge.method_defined?(:start_activity).must_equal true
38-
Selenium::WebDriver::Remote::Bridge.method_defined?(:set_context).must_equal true
39-
Selenium::WebDriver::Remote::Bridge.method_defined?(:hide_keyboard).must_equal true
40-
Selenium::WebDriver::Remote::Bridge.method_defined?(:press_keycode).must_equal true
41-
Selenium::WebDriver::Remote::Bridge.method_defined?(:long_press_keycode).must_equal true
42-
Selenium::WebDriver::Remote::Bridge.method_defined?(:set_immediate_value).must_equal true
43-
Selenium::WebDriver::Remote::Bridge.method_defined?(:push_file).must_equal true
44-
Selenium::WebDriver::Remote::Bridge.method_defined?(:pull_file).must_equal true
45-
Selenium::WebDriver::Remote::Bridge.method_defined?(:pull_folder).must_equal true
46-
Selenium::WebDriver::Remote::Bridge.method_defined?(:end_coverage).must_equal true
47-
Selenium::WebDriver::Remote::Bridge.method_defined?(:get_settings).must_equal true
48-
Selenium::WebDriver::Remote::Bridge.method_defined?(:update_settings).must_equal true
49-
Selenium::WebDriver::Remote::Bridge.method_defined?(:set_network_connection).must_equal true
50-
Selenium::WebDriver::Remote::Bridge.method_defined?(:touch_actions).must_equal true
51-
Selenium::WebDriver::Remote::Bridge.method_defined?(:multi_touch).must_equal true
34+
parameterized_method_defined_check([:available_contexts,
35+
:app_strings,
36+
:lock,
37+
:install_app,
38+
:remove_app,
39+
:app_installed?,
40+
:background_app,
41+
:start_activity,
42+
:set_context,
43+
:hide_keyboard,
44+
:press_keycode,
45+
:long_press_keycode,
46+
:set_immediate_value,
47+
:push_file,
48+
:pull_file,
49+
:pull_folder,
50+
:end_coverage,
51+
:get_settings,
52+
:update_settings,
53+
:set_network_connection,
54+
:touch_actions,
55+
:multi_touch])
5256
end
5357
end

android_tests/lib/android/specs/common/patch.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
# Skip:
55
# status # status patches are already tested in driver.rb
6-
# raw_execute # debug output for Pry
6+
# execute # debug output for Pry
77

88
describe 'common/patch' do
99
# Attributes are busted in Android.

android_tests/lib/android/specs/driver.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def sauce?
6161
t 'verify all attributes' do
6262
actual = driver_attributes
6363
caps_app_for_teardown = actual[:caps][:app]
64-
expected_app = File.absolute_path('api.apk')
64+
expected_app = File.absolute_path('../test_apps/api.apk')
6565

6666
expected = { automation_name: nil,
6767
custom_url: false,

appium_lib.gemspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
1313
s.homepage = 'https://github.com/appium/ruby_lib' # published as appium_lib
1414
s.require_paths = ['lib']
1515

16-
s.add_runtime_dependency 'selenium-webdriver', '>= 3.0.4', '<= 3.4'
16+
s.add_runtime_dependency 'selenium-webdriver', '~> 3.4.1'
1717
s.add_runtime_dependency 'awesome_print', '~> 1.7'
1818
s.add_runtime_dependency 'json', '>= 1.8'
1919
s.add_runtime_dependency 'tomlrb', '~> 1.1'

grid/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
$ java -jar selenium-server-standalone-2.53.1.jar -role hub -hubConfig hub_config.json
55
```
66

7+
**note**
8+
Selenium Grid 3.4.0 is failed to establish sessions:
9+
710
# Run Appium
811

912
```bash

grid/hub_config_3.json

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"capabilities":
3+
[
4+
{
5+
"browserName": "iPhone Simulator",
6+
"version":"9.0",
7+
"platform":"MAC",
8+
"maxInstances": 1
9+
}
10+
],
11+
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
12+
"maxSession": 5,
13+
"port": 4444,
14+
"register": true,
15+
"registerCycle": 5000,
16+
"hub": "http://localhost:4444/wd/hub",
17+
"nodeStatusCheckTimeout": 5000,
18+
"nodePolling": 5000,
19+
"role": "hub",
20+
"unregisterIfStillDownAfter": 60000,
21+
"downPollingLimit": 2,
22+
"debug": true,
23+
"servlets" : [],
24+
"withoutServlets": [],
25+
"custom": {}
26+
}

ios_tests/lib/ios/specs/common/command.rb

+32-29
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,41 @@ def before_first
88
before_first
99
end
1010

11+
def parameterized_method_defined_check(array)
12+
array.each { |v| Selenium::WebDriver::Remote::OSS::Bridge.method_defined?(v).must_equal true }
13+
end
14+
1115
t 'check all command no arg' do
12-
Selenium::WebDriver::Remote::Bridge.method_defined?(:shake).must_equal true
13-
Selenium::WebDriver::Remote::Bridge.method_defined?(:launch_app).must_equal true
14-
Selenium::WebDriver::Remote::Bridge.method_defined?(:close_app).must_equal true
15-
Selenium::WebDriver::Remote::Bridge.method_defined?(:reset).must_equal true
16-
Selenium::WebDriver::Remote::Bridge.method_defined?(:device_locked?).must_equal true
17-
Selenium::WebDriver::Remote::Bridge.method_defined?(:device_time).must_equal true
18-
Selenium::WebDriver::Remote::Bridge.method_defined?(:current_context).must_equal true
16+
parameterized_method_defined_check([:shake,
17+
:launch_app,
18+
:close_app,
19+
:reset,
20+
:device_locked?,
21+
:device_time,
22+
:current_context])
1923
end
2024

2125
t 'check all command with arg' do
22-
Selenium::WebDriver::Remote::Bridge.method_defined?(:available_contexts).must_equal true
23-
Selenium::WebDriver::Remote::Bridge.method_defined?(:app_strings).must_equal true
24-
Selenium::WebDriver::Remote::Bridge.method_defined?(:lock).must_equal true
25-
Selenium::WebDriver::Remote::Bridge.method_defined?(:install_app).must_equal true
26-
Selenium::WebDriver::Remote::Bridge.method_defined?(:remove_app).must_equal true
27-
Selenium::WebDriver::Remote::Bridge.method_defined?(:app_installed?).must_equal true
28-
Selenium::WebDriver::Remote::Bridge.method_defined?(:background_app).must_equal true
29-
Selenium::WebDriver::Remote::Bridge.method_defined?(:start_activity).must_equal true
30-
Selenium::WebDriver::Remote::Bridge.method_defined?(:set_context).must_equal true
31-
Selenium::WebDriver::Remote::Bridge.method_defined?(:hide_keyboard).must_equal true
32-
Selenium::WebDriver::Remote::Bridge.method_defined?(:press_keycode).must_equal true
33-
Selenium::WebDriver::Remote::Bridge.method_defined?(:long_press_keycode).must_equal true
34-
Selenium::WebDriver::Remote::Bridge.method_defined?(:set_immediate_value).must_equal true
35-
Selenium::WebDriver::Remote::Bridge.method_defined?(:push_file).must_equal true
36-
Selenium::WebDriver::Remote::Bridge.method_defined?(:pull_file).must_equal true
37-
Selenium::WebDriver::Remote::Bridge.method_defined?(:pull_folder).must_equal true
38-
Selenium::WebDriver::Remote::Bridge.method_defined?(:touch_id).must_equal true
39-
Selenium::WebDriver::Remote::Bridge.method_defined?(:toggle_touch_id_enrollment).must_equal true
40-
Selenium::WebDriver::Remote::Bridge.method_defined?(:get_settings).must_equal true
41-
Selenium::WebDriver::Remote::Bridge.method_defined?(:update_settings).must_equal true
42-
Selenium::WebDriver::Remote::Bridge.method_defined?(:touch_actions).must_equal true
43-
Selenium::WebDriver::Remote::Bridge.method_defined?(:multi_touch).must_equal true
26+
parameterized_method_defined_check([:available_contexts,
27+
:app_strings,
28+
:lock,
29+
:install_app,
30+
:remove_app,
31+
:app_installed?,
32+
:background_app,
33+
:start_activity,
34+
:set_context,
35+
:hide_keyboard,
36+
:press_keycode,
37+
:long_press_keycode,
38+
:set_immediate_value,
39+
:push_file,
40+
:pull_file,
41+
:touch_id,
42+
:toggle_touch_id_enrollment,
43+
:get_settings,
44+
:update_settings,
45+
:touch_actions,
46+
:multi_touch])
4447
end
4548
end

ios_tests/lib/ios/specs/common/patch.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# Skip:
66
# status # status patches are already tested in driver.rb
7-
# raw_execute # debug output for Pry
7+
# execute # debug output for Pry
88
#
99

1010
# rake ios[common/patch]

ios_tests/lib/ios/specs/common/web_context.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22
describe 'the web context' do
33
t 'get_android_inspect' do
44
text('Web').click
5-
set_context 'WEBVIEW'
6-
current_context.must_equal 'WEBVIEW_1'
5+
6+
wait_true { available_contexts.size >= 2 }
7+
web_view_context = available_contexts.find { |c| c.start_with? 'WEBVIEW' } # Get WEBVIEW_59153.1 for example.
8+
9+
set_context web_view_context
10+
current_context.must_equal web_view_context
711
sleep 1 # Give a chance to load
812
page.start_with?("\nhtml\n").must_equal true
913
end

ios_tests/lib/ios/specs/device/device.rb

+10-5
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ def go_back
5555
t 'background_app homescreen' do
5656
background_app(-1) # background_app(nil) should work as same.
5757

58-
screen.must_equal 'UICatalog'
59-
# TODO: Should update this assert.
60-
# screen.must_raise ::Selenium::WebDriver::Error::NoSuchElementError
58+
# The app goes to background and never come back
59+
proc { screen }.must_raise ::Selenium::WebDriver::Error::NoSuchElementError
6160
end
6261

6362
t 'reset' do
@@ -83,8 +82,14 @@ def go_back
8382
end
8483

8584
t 'action_chain' do
86-
Appium::TouchAction.new.press(element: text(app_strings['ButtonsExplain'])).perform
87-
wait { id 'ArrowButton' } # successfully transitioned to buttons page
85+
if automation_name_is_xcuitest?
86+
element = text(app_strings['ButtonsExplain'])
87+
tap(x: 0, y: 0, element: element)
88+
else
89+
Appium::TouchAction.new.press(element: text(app_strings['ButtonsExplain'])).perform
90+
end
91+
92+
wait { text 'Back' } # successfully transitioned to buttons page
8893
go_back
8994
end
9095

ios_tests/lib/ios/specs/driver.rb

-2
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,6 @@ def sauce?
297297
end
298298

299299
t 'update settings' do
300-
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
301-
302300
update_settings cyberdelia: 'open'
303301
get_settings['cyberdelia'].must_equal 'open'
304302
end

ios_tests/lib/ios/specs/ios/helper.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def before_first
2222
end
2323

2424
t 'source_window' do
25-
source_window.length.must_be :>=, 14_000
25+
source_window.length.must_be :>=, 10_000
2626
end
2727

2828
# TODO: t 'page_window' do

ios_tests/lib/ios/specs/ios/mobile_methods.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def before_first
1313
t 'elements with class chain' do
1414
elements = find_elements :class_chain, 'XCUIElementTypeWindow/*/*'
1515

16-
elements.size.must_equal 2
16+
elements.size.must_equal 4
1717
elements[0].name.must_equal catalog
1818
elements[1].name.must_be_nil
1919
end

lib/appium_lib/common/command.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ module Commands
5656
# iOS
5757
touch_id: [:post, 'session/:session_id/appium/simulator/touch_id'.freeze],
5858
toggle_touch_id_enrollment: [:post, 'session/:session_id/appium/simulator/toggle_touch_id_enrollment'.freeze]
59-
}.merge(COMMAND_NO_ARG).merge(::Selenium::WebDriver::Remote::Bridge::COMMANDS).freeze
59+
}.merge(COMMAND_NO_ARG).merge(::Selenium::WebDriver::Remote::OSS::Bridge::COMMANDS).freeze
6060
end
6161
end
6262
end

lib/appium_lib/common/patch.rb

+10-7
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@ def location_rel
6262
#
6363
# Requires from lib/selenium/webdriver/remote.rb
6464
require 'selenium/webdriver/remote/capabilities'
65-
require 'selenium/webdriver/remote/w3c_capabilities'
65+
require 'selenium/webdriver/remote/w3c/capabilities'
6666
require 'selenium/webdriver/remote/bridge'
67-
require 'selenium/webdriver/remote/w3c_bridge'
67+
require 'selenium/webdriver/remote/oss/bridge'
68+
require 'selenium/webdriver/remote/w3c/bridge'
6869
require 'selenium/webdriver/remote/server_error'
6970
require 'selenium/webdriver/remote/response'
70-
require 'selenium/webdriver/remote/commands'
71-
require 'selenium/webdriver/remote/w3c_commands'
71+
require 'selenium/webdriver/remote/oss/commands'
72+
require 'selenium/webdriver/remote/w3c/commands'
7273
require 'selenium/webdriver/remote/http/common'
7374
require 'selenium/webdriver/remote/http/default'
7475

@@ -79,7 +80,8 @@ def location_rel
7980
def patch_webdriver_bridge
8081
Selenium::WebDriver::Remote::Bridge.class_eval do
8182
# Code from lib/selenium/webdriver/remote/bridge.rb
82-
def raw_execute(command, opts = {}, command_hash = nil)
83+
84+
def execute(command, opts = {}, command_hash = nil)
8385
verb, path = commands(command) || raise(ArgumentError, "unknown command: #{command.inspect}")
8486
path = path.dup
8587

@@ -130,7 +132,7 @@ def raw_execute(command, opts = {}, command_hash = nil)
130132
delay = $driver.global_webdriver_http_sleep
131133
sleep delay if !delay.nil? && delay > 0
132134
# Appium::Logger.info "verb: #{verb}, path #{path}, command_hash #{command_hash.to_json}"
133-
http.call verb, path, command_hash
135+
http.call(verb, path, command_hash)
134136
end # def
135137
end # class
136138
end
@@ -146,6 +148,7 @@ def error_message
146148
case val
147149
when Hash
148150
msg = val['origValue'] || val['message'] or return 'unknown error'
151+
msg << ": #{val['alert']['text'].inspect}" if val['alert'].is_a?(Hash) && val['alert']['text']
149152
msg << " (#{val['class']})" if val['class']
150153
when String
151154
msg = val
@@ -163,7 +166,7 @@ class Selenium::WebDriver::Remote::Http::Common # rubocop:disable Style/ClassAnd
163166
end
164167

165168
def patch_remote_driver_commands
166-
Selenium::WebDriver::Remote::Bridge.class_eval do
169+
Selenium::WebDriver::Remote::OSS::Bridge.class_eval do
167170
def commands(command)
168171
::Appium::Driver::Commands::COMMAND[command]
169172
end

lib/appium_lib/device/device.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ def delegate_from_appium_driver(method, delegation_target = :driver)
437437

438438
# @private
439439
def create_bridge_command(method)
440-
Selenium::WebDriver::Remote::Bridge.class_eval do
440+
Selenium::WebDriver::Remote::OSS::Bridge.class_eval do
441441
block_given? ? class_eval(&Proc.new) : define_method(method) { execute method }
442442
end
443443
end

0 commit comments

Comments
 (0)