Skip to content

Commit 9dd9c83

Browse files
authored
add adding appium-prefix for W3C format (#34)
* add adding appium-prefix * add tests for add_appium_prefix * add the fixing into changelog * add docs
1 parent cb94184 commit 9dd9c83

File tree

4 files changed

+121
-3
lines changed

4 files changed

+121
-3
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
33

44
## [Unreleased]
55
### Enhancements
6+
- Append `appium:` prefix for capabilities automatically due to W3C format.
67

78
### Bug fixes
89

appium_lib_core.gemspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
2222
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
2323
spec.require_paths = ['lib']
2424

25-
spec.add_runtime_dependency 'selenium-webdriver', '~> 3.4', '>= 3.4.1'
25+
spec.add_runtime_dependency 'selenium-webdriver', '~> 3.5'
2626
spec.add_runtime_dependency 'json', '>= 1.8'
2727

2828
spec.add_development_dependency 'bundler', '~> 1.14'

lib/appium_lib_core/common/base/bridge.rb

+47-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@ module Appium
22
module Core
33
class Base
44
class Bridge < ::Selenium::WebDriver::Remote::Bridge
5+
# Almost same as self.handshake in ::Selenium::WebDriver::Remote::Bridge
6+
#
7+
# Implements protocol handshake which:
8+
#
9+
# 1. Creates session with driver.
10+
# 2. Sniffs response.
11+
# 3. Based on the response, understands which dialect we should use.
12+
#
13+
# @return [CoreBridgeMJSONWP, CoreBridgeW3C]
14+
#
515
def self.handshake(**opts)
616
desired_capabilities = opts.delete(:desired_capabilities)
717

@@ -25,15 +35,50 @@ def self.handshake(**opts)
2535
end
2636
end
2737

38+
# Append `appium:` prefix for Appium following W3C spec
39+
# https://www.w3.org/TR/webdriver/#dfn-validate-capabilities
40+
#
41+
# @param [::Selenium::WebDriver::Remote::W3C::Capabilities, Hash] capabilities A capability
42+
# @return [::Selenium::WebDriver::Remote::W3C::Capabilities]
43+
def add_appium_prefix(capabilities)
44+
w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.new
45+
46+
capabilities = capabilities.__send__(:capabilities) unless capabilities.is_a?(Hash)
47+
capabilities.each do |name, value|
48+
next if value.nil?
49+
next if value.is_a?(String) && value.empty?
50+
51+
capability_name = name.to_s
52+
w3c_name = appium_prefix?(capability_name, w3c_capabilities) ? name : "appium:#{capability_name}"
53+
54+
w3c_capabilities[w3c_name] = value
55+
end
56+
57+
w3c_capabilities
58+
end
59+
2860
private
2961

62+
APPIUM_PREFIX = 'appium:'.freeze
63+
def appium_prefix?(capability_name, w3c_capabilities)
64+
snake_cased_capability_names = ::Selenium::WebDriver::Remote::W3C::Capabilities::KNOWN.map(&:to_s)
65+
camel_cased_capability_names = snake_cased_capability_names.map(&w3c_capabilities.method(:camel_case))
66+
67+
snake_cased_capability_names.include?(capability_name) ||
68+
camel_cased_capability_names.include?(capability_name) ||
69+
capability_name.start_with?(APPIUM_PREFIX)
70+
end
71+
3072
# Use capabilities directory because Appium's capability is based on W3C one.
31-
# Called in bridge.create_session(desired_capabilities)
73+
# Called in bridge.create_session(desired_capabilities) from Parent class
3274
def merged_capabilities(desired_capabilities)
75+
new_caps = add_appium_prefix(desired_capabilities)
76+
w3c_capabilities = ::Selenium::WebDriver::Remote::W3C::Capabilities.from_oss(new_caps)
77+
3378
{
3479
desiredCapabilities: desired_capabilities,
3580
capabilities: {
36-
firstMatch: [desired_capabilities]
81+
firstMatch: [w3c_capabilities]
3782
}
3883
}
3984
end

test/unit/common_test.rb

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
require 'test_helper'
2+
3+
# $ rake test:unit TEST=test/unit/common_test.rb
4+
class AppiumLibCoreTest
5+
class Common
6+
class AppiumCoreBaseBridgeTest < Minitest::Test
7+
def setup
8+
@bridge = Appium::Core::Base::Bridge.new
9+
end
10+
11+
def test_add_appium_prefix_compatible_with_oss
12+
cap = {
13+
platformName: :ios,
14+
automationName: 'XCUITest',
15+
app: 'test/functional/app/UICatalog.app',
16+
platformVersion: '10.3',
17+
deviceName: 'iPhone Simulator',
18+
useNewWDA: true,
19+
some_capability: 'some_capability'
20+
}
21+
base_caps = Appium::Core::Base::Capabilities.create_capabilities(cap)
22+
23+
expected = {
24+
proxy: nil,
25+
platformName: :ios,
26+
'appium:automationName' => 'XCUITest',
27+
'appium:app' => 'test/functional/app/UICatalog.app',
28+
'appium:platformVersion' => '10.3',
29+
'appium:deviceName' => 'iPhone Simulator',
30+
'appium:useNewWDA' => true,
31+
'appium:some_capability' => 'some_capability'
32+
}
33+
34+
assert_equal expected, @bridge.add_appium_prefix(base_caps).__send__(:capabilities)
35+
end
36+
37+
def test_add_appium_prefix_already_have_appium_prefix
38+
cap = {
39+
platformName: :ios,
40+
automationName: 'XCUITest',
41+
'appium:app' => 'test/functional/app/UICatalog.app',
42+
platformVersion: '10.3',
43+
deviceName: 'iPhone Simulator',
44+
useNewWDA: true,
45+
some_capability: 'some_capability'
46+
}
47+
base_caps = Appium::Core::Base::Capabilities.create_capabilities(cap)
48+
49+
expected = {
50+
proxy: nil,
51+
platformName: :ios,
52+
'appium:automationName' => 'XCUITest',
53+
'appium:app' => 'test/functional/app/UICatalog.app',
54+
'appium:platformVersion' => '10.3',
55+
'appium:deviceName' => 'iPhone Simulator',
56+
'appium:useNewWDA' => true,
57+
'appium:some_capability' => 'some_capability'
58+
}
59+
60+
assert_equal expected, @bridge.add_appium_prefix(base_caps).__send__(:capabilities)
61+
end
62+
63+
def test_add_appium_prefix_has_no_parameter
64+
cap = {}
65+
base_caps = Appium::Core::Base::Capabilities.create_capabilities(cap)
66+
expected = { proxy: nil }
67+
68+
assert_equal expected, @bridge.add_appium_prefix(base_caps).__send__(:capabilities)
69+
end
70+
end
71+
end
72+
end

0 commit comments

Comments
 (0)