Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement search context and UA based on selenium 4.21 #480

Merged
merged 31 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
268f40e
set the deps destination [skip ci]
KazuCocoa Jun 17, 2023
8fc3ce4
Merge branch 'master' into selenium-12141
KazuCocoa Jun 17, 2023
5ac21dd
use github
KazuCocoa Jun 17, 2023
b4533ca
Merge branch 'master' into selenium-12141
KazuCocoa Aug 13, 2023
3499f13
Merge branch 'master' into selenium-12141
KazuCocoa Aug 24, 2023
96cfa03
Merge branch 'master' into selenium-12141
KazuCocoa Sep 4, 2023
0938833
Merge branch 'master' into selenium-12141
KazuCocoa Nov 4, 2023
d69922a
Merge branch 'master' into selenium-12141
KazuCocoa Feb 3, 2024
04677c9
mofidy to use extra finders
KazuCocoa Feb 3, 2024
cf178cf
fix lint
KazuCocoa Feb 3, 2024
b86906c
add ua
KazuCocoa Feb 3, 2024
1c4fa9b
revert unnecessary naming changes
KazuCocoa Feb 3, 2024
1927c6f
add new line
KazuCocoa Feb 3, 2024
5e4aeb6
revert docstring
KazuCocoa Feb 3, 2024
4b85ae0
simplify a bit
KazuCocoa Feb 3, 2024
34afcb9
remove request
KazuCocoa Feb 3, 2024
956fe2c
add example of add_command
KazuCocoa Feb 3, 2024
4392936
chore: update to the latest imple
KazuCocoa Feb 4, 2024
f607d4f
set element with ::Selenium::WebDriver::Remote::Bridge.element_class …
KazuCocoa Feb 4, 2024
5ba3244
fix lint
KazuCocoa Feb 4, 2024
7dfec92
removed unnecessary override
KazuCocoa Feb 4, 2024
0d31ff8
Merge branch 'master' into selenium-12141
KazuCocoa Feb 5, 2024
2a6abdf
Merge branch 'master' into selenium-12141
KazuCocoa May 15, 2024
2f38784
Update Gemfile
KazuCocoa May 15, 2024
adc279d
add bundle exec
KazuCocoa May 15, 2024
ef3e469
Merge branch 'master' into selenium-12141
KazuCocoa May 15, 2024
9749e20
remove completed todo
KazuCocoa May 15, 2024
c3daf5c
Merge branch 'master' into selenium-12141
KazuCocoa May 16, 2024
5dc8c76
use selenium webdriver 4.21
KazuCocoa May 16, 2024
ae74d1f
Merge branch 'master' into selenium-12141
KazuCocoa May 16, 2024
b319a09
update changelog
KazuCocoa May 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Read `release_notes.md` for commit level details.
## [Unreleased]

### Enhancements
- Simplify internal code with Selenium 4.21.0. Now it requires selenium webdriver v4.21.0.

### Bug fixes

Expand Down
2 changes: 1 addition & 1 deletion appium_lib_core.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']

spec.add_runtime_dependency 'selenium-webdriver', '~> 4.2'
spec.add_runtime_dependency 'selenium-webdriver', '~> 4.21'
spec.add_runtime_dependency 'faye-websocket', '~> 0.11.0'

spec.add_development_dependency 'rake', '~> 13.0'
Expand Down
96 changes: 21 additions & 75 deletions lib/appium_lib_core/common/base/bridge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
module Appium
module Core
class Base
class LocatorConverter
def convert(how, what)
[how, what]
end
end # LocatorConverter

class Bridge < ::Selenium::WebDriver::Remote::Bridge
include Device::DeviceLock
include Device::Keyboard
Expand All @@ -31,6 +37,8 @@ class Bridge < ::Selenium::WebDriver::Remote::Bridge
include Device::ExecuteDriver
include Device::Orientation

Bridge.locator_converter = LocatorConverter.new

# Prefix for extra capability defined by W3C
APPIUM_PREFIX = 'appium:'

Expand Down Expand Up @@ -153,6 +161,18 @@ def json_create(value)
public

# command for Appium 2.0.

# Example:
# driver.add_command(name: :available_contexts, method: :get, url: 'session/:session_id/contexts') do
# execute(:available_contexts, {}) || []
# end
# Then,
# driver.available_contexts #=> ["NATIVE_APP"]

# def add_command(method:, url:, name:, &block)
# Bridge.add_command name, method, url, &block
# end
Comment on lines +172 to +174
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: once we move to this bridge.add_command, need to update tests as well. should be another pr


def add_command(method:, url:, name:, &block)
::Appium::Logger.info "Overriding the method '#{name}' for '#{url}'" if @available_commands.key? name

Expand All @@ -162,7 +182,7 @@ def add_command(method:, url:, name:, &block)
end

def commands(command)
@available_commands[command]
@available_commands[command] || Bridge.extra_commands[command]
end

def status
Expand Down Expand Up @@ -216,52 +236,8 @@ def element_attribute(element, name)
end

# For Appium
# override
def active_element
::Appium::Core::Element.new self, element_id_from(execute(:get_active_element))
end
alias switch_to_active_element active_element

# For Appium
# override
def find_element_by(how, what, parent_ref = [])
how, what = convert_locator(how, what)

return execute_atom(:findElements, Support::RelativeLocator.new(what).as_json).first if how == 'relative'

parent_type, parent_id = parent_ref
id = case parent_type
when :element
execute :find_child_element, { id: parent_id }, { using: how, value: what.to_s }
when :shadow_root
execute :find_shadow_child_element, { id: parent_id }, { using: how, value: what.to_s }
else
execute :find_element, {}, { using: how, value: what.to_s }
end

::Appium::Core::Element.new self, element_id_from(id)
end

# For Appium
# override
def find_elements_by(how, what, parent_ref = [])
how, what = convert_locator(how, what)

return execute_atom :findElements, Support::RelativeLocator.new(what).as_json if how == 'relative'

parent_type, parent_id = parent_ref
ids = case parent_type
when :element
execute :find_child_elements, { id: parent_id }, { using: how, value: what.to_s }
when :shadow_root
execute :find_shadow_child_elements, { id: parent_id }, { using: how, value: what.to_s }
else
execute :find_elements, {}, { using: how, value: what.to_s }
end

ids.map { |id| ::Appium::Core::Element.new self, element_id_from(id) }
end

# For Appium
# @param [Hash] id The id which can get as a response from server
# @return [::Appium::Core::Element]
Expand Down Expand Up @@ -370,36 +346,6 @@ def unwrap_script_result(arg)
arg
end
end

def element_id_from(id)
id['ELEMENT'] || id['element-6066-11e4-a52e-4f735466cecf']
end

# Don't convert locators for Appium in native context
def convert_locator(how, what)
# case how
# when 'class name'
# how = 'css selector'
# what = ".#{escape_css(what)}"
# when 'id'
# how = 'css selector'
# what = "##{escape_css(what)}"
# when 'name'
# how = 'css selector'
# what = "*[name='#{escape_css(what)}']"
# when 'tag name'
# how = 'css selector'
# end
#
# if what.is_a?(Hash)
# what = what.each_with_object({}) do |(h, w), hash|
# h, w = convert_locator(h.to_s, w)
# hash[h] = w
# end
# end

[how, what]
end
end # class Bridge
end # class Base
end # module Core
Expand Down
8 changes: 5 additions & 3 deletions lib/appium_lib_core/common/base/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ class Driver < ::Selenium::WebDriver::Driver
include ::Selenium::WebDriver::DriverExtensions::HasWebStorage

include ::Appium::Core::Base::Rotatable
include ::Appium::Core::Base::SearchContext
include ::Appium::Core::Base::TakesScreenshot
include ::Appium::Core::Base::HasRemoteStatus
include ::Appium::Core::Base::HasLocation
include ::Appium::Core::Base::HasNetworkConnection

include ::Appium::Core::Waitable

::Selenium::WebDriver::SearchContext.extra_finders = APPIUM_EXTRA_FINDERS

# Private API.
# Do not use this for general use. Used by flutter driver to get bridge for creating a new element
attr_reader :bridge
Expand All @@ -57,6 +58,7 @@ def initialize(bridge: nil, listener: nil, **opts) # rubocop:disable Lint/Missin
@bidi = nil

# in the selenium webdriver as well
::Selenium::WebDriver::Remote::Bridge.element_class = ::Appium::Core::Element
bridge ||= create_bridge(**opts)
add_extensions(bridge.browser)
@bridge = listener ? ::Appium::Support::EventFiringBridge.new(bridge, listener, **original_opts) : bridge
Expand Down Expand Up @@ -1023,8 +1025,8 @@ def execute_driver(script: '', type: 'webdriverio', timeout_ms: nil)
# ele = @driver.convert_to_element(response) #=> ::Appium::Core::Element
# ele.rect #=> Can get the rect of the element
#
def convert_to_element(id)
@bridge.convert_to_element id
def convert_to_element(response_id)
@bridge.convert_to_element response_id
end
end # class Driver
end # class Base
Expand Down
21 changes: 14 additions & 7 deletions lib/appium_lib_core/common/base/http_default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ module RequestHeaders
class Default < ::Selenium::WebDriver::Remote::Http::Default
attr_reader :additional_headers

::Selenium::WebDriver::Remote::Http::Common.user_agent = \
"appium/ruby_lib_core/#{VERSION} (#{::Selenium::WebDriver::Remote::Http::Common.user_agent})"

# override
def initialize(open_timeout: nil, read_timeout: nil)
@open_timeout = open_timeout
Expand All @@ -39,6 +42,17 @@ def initialize(open_timeout: nil, read_timeout: nil)
super
end

def set_additional_header(key, value)
@additional_headers[key] = value
::Selenium::WebDriver::Remote::Http::Common.extra_headers = @additional_headers
end

def delete_additional_header(key)
@additional_headers.delete key
::Selenium::WebDriver::Remote::Http::Common.extra_headers = @additional_headers
@common_headers.delete key if defined? @common_headers
end

# Update <code>server_url</code> provided when ruby_lib _core created a default http client.
# Set <code>@http</code> as nil to re-create http client for the <code>server_url</code>
#
Expand All @@ -59,13 +73,6 @@ def update_sending_request_to(scheme:, host:, port:, path:)
@server_url = URI.parse "#{scheme}://#{host}:#{port}#{path}"
end

def request(verb, url, headers, payload, redirects = 0)
headers['User-Agent'] = "appium/ruby_lib_core/#{VERSION} (#{headers['User-Agent']})"
headers = headers.merge @additional_headers unless @additional_headers.empty?

super(verb, url, headers, payload, redirects)
end

private

def validate_url_param(scheme, host, port, path)
Expand Down
Loading
Loading