testa_appium_driver 0.1.1 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.idea/inspectionProfiles/Project_Default.xml +8 -8
- data/.idea/runConfigurations/Android_Test.xml +41 -41
- data/.rspec +3 -3
- data/.rubocop.yml +13 -13
- data/CHANGELOG.md +5 -5
- data/CODE_OF_CONDUCT.md +102 -102
- data/Gemfile +12 -12
- data/LICENSE.txt +21 -21
- data/Rakefile +12 -12
- data/bin/console +17 -17
- data/bin/setup +8 -8
- data/lib/testa_appium_driver/android/class_selectors.rb +50 -0
- data/lib/testa_appium_driver/android/driver.rb +2 -1
- data/lib/testa_appium_driver/android/locator/attributes.rb +2 -2
- data/lib/testa_appium_driver/android/locator.rb +1 -1
- data/lib/testa_appium_driver/android/selenium_element.rb +1 -1
- data/lib/testa_appium_driver/common/locator/scroll_actions.rb +136 -58
- data/lib/testa_appium_driver/common/locator.rb +14 -7
- data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +12 -4
- data/lib/testa_appium_driver/common/scroll_actions.rb +30 -8
- data/lib/testa_appium_driver/common/selenium_element.rb +2 -2
- data/lib/testa_appium_driver/driver.rb +35 -12
- data/lib/testa_appium_driver/ios/driver.rb +1 -0
- data/lib/testa_appium_driver/ios/locator/attributes.rb +5 -3
- data/lib/testa_appium_driver/ios/locator.rb +3 -2
- data/lib/testa_appium_driver/version.rb +5 -5
- data/testa_appium_driver.gemspec +3 -2
- data/testa_appium_driver.iml +1 -1
- metadata +10 -8
@@ -3,7 +3,7 @@ module TestaAppiumDriver
|
|
3
3
|
|
4
4
|
private
|
5
5
|
# @return [Array]
|
6
|
-
def w3c_each(
|
6
|
+
def w3c_each(direction, &block)
|
7
7
|
elements = []
|
8
8
|
begin
|
9
9
|
@driver.disable_wait_for_idle
|
@@ -13,7 +13,14 @@ module TestaAppiumDriver
|
|
13
13
|
iterations = 0
|
14
14
|
|
15
15
|
|
16
|
-
|
16
|
+
if direction.nil?
|
17
|
+
scroll_to_start
|
18
|
+
if @scrollable.scroll_orientation == :vertical
|
19
|
+
direction = :down
|
20
|
+
else
|
21
|
+
direction = :right
|
22
|
+
end
|
23
|
+
end
|
17
24
|
|
18
25
|
until is_end_of_scroll?
|
19
26
|
matches = @locator.execute(skip_cache: true)
|
@@ -27,6 +34,7 @@ module TestaAppiumDriver
|
|
27
34
|
end
|
28
35
|
iterations += 1
|
29
36
|
break if !@max_scrolls.nil? && iterations == @max_scrolls
|
37
|
+
self.send("page_#{direction}")
|
30
38
|
end
|
31
39
|
rescue => e
|
32
40
|
raise e
|
@@ -37,13 +45,13 @@ module TestaAppiumDriver
|
|
37
45
|
elements
|
38
46
|
end
|
39
47
|
|
40
|
-
def w3c_align(with)
|
48
|
+
def w3c_align(with, scroll_to_find)
|
41
49
|
@driver.disable_wait_for_idle
|
42
50
|
default_deadzone!
|
43
51
|
|
44
52
|
|
45
53
|
|
46
|
-
@locator.scroll_to
|
54
|
+
@locator.scroll_to if scroll_to_find
|
47
55
|
|
48
56
|
element = @locator.execute
|
49
57
|
@driver.disable_implicit_wait
|
@@ -3,19 +3,24 @@ require_relative 'scroll_actions/w3c_scroll_actions'
|
|
3
3
|
|
4
4
|
|
5
5
|
module TestaAppiumDriver
|
6
|
-
#noinspection RubyResolve,RubyTooManyInstanceVariablesInspection
|
7
|
-
class ScrollActions
|
8
6
|
|
7
|
+
# Class for handling scroll actions
|
8
|
+
class ScrollActions
|
9
|
+
# @param [TestaAppiumDriver::Locator, nil] scrollable container that will be used to determine the bounds for scrolling
|
10
|
+
# @param [Hash] params
|
11
|
+
# acceptable params
|
12
|
+
# - locator - element that should be found with scrolling actions
|
13
|
+
# - deadzone - [Hash] that stores top, bottom, left and right deadzone values. If deadzone[:top] is 200 then 200px from top of the scrollable container will not be used for scrolling
|
14
|
+
# - max_scrolls - [Integer] maximum number of scrolls before exception is thrown
|
15
|
+
# - default_scroll_strategy - defines which scroll strategy will be used if a scroll action is valid for multiple strategies
|
9
16
|
def initialize(scrollable, params = {})
|
10
17
|
@scrollable = scrollable
|
11
18
|
@locator = params[:locator]
|
12
19
|
@deadzone = params[:deadzone]
|
13
|
-
@direction = params[:direction]
|
14
20
|
@max_scrolls = params[:max_scrolls]
|
15
21
|
@default_scroll_strategy = params[:default_scroll_strategy]
|
16
22
|
@driver = @locator.driver
|
17
23
|
|
18
|
-
@raise = params[:raise]
|
19
24
|
|
20
25
|
if @scrollable.nil?
|
21
26
|
# if we dont have a scrollable element or if we do have it, but it is not compatible with uiautomator
|
@@ -35,16 +40,33 @@ module TestaAppiumDriver
|
|
35
40
|
end
|
36
41
|
|
37
42
|
|
38
|
-
def align(with)
|
39
|
-
w3c_align(with)
|
43
|
+
def align(with, scroll_to_find)
|
44
|
+
w3c_align(with, scroll_to_find)
|
40
45
|
@locator
|
41
46
|
end
|
42
47
|
|
43
48
|
# @return [Array]
|
44
|
-
def each(
|
45
|
-
w3c_each(
|
49
|
+
def each(&block)
|
50
|
+
w3c_each(nil, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def each_down(&block)
|
54
|
+
w3c_each(:down, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def each_up(&block)
|
58
|
+
w3c_each(:up, &block)
|
46
59
|
end
|
47
60
|
|
61
|
+
def each_right(&block)
|
62
|
+
w3c_each(:right, &block)
|
63
|
+
end
|
64
|
+
|
65
|
+
def each_left(&block)
|
66
|
+
w3c_each(:left, &block)
|
67
|
+
end
|
68
|
+
|
69
|
+
|
48
70
|
def resolve_strategy
|
49
71
|
if @strategy.nil?
|
50
72
|
@default_scroll_strategy
|
@@ -1,19 +1,19 @@
|
|
1
1
|
module Selenium
|
2
2
|
module WebDriver
|
3
|
-
#noinspection RubyClassVariableUsageInspection
|
4
3
|
class Element
|
4
|
+
# sets the testa appium driver instance for the current phone
|
5
5
|
def self.set_driver(driver, udid)
|
6
6
|
udid = "unknown" if udid.nil?
|
7
7
|
@@drivers ||= {}
|
8
8
|
@@drivers[udid] = driver
|
9
9
|
end
|
10
10
|
|
11
|
+
# @return [TestaAppiumDriver::Driver] testa appium driver instance for the current phone
|
11
12
|
def get_driver
|
12
13
|
udid = @bridge.capabilities.instance_variable_get(:@capabilities)["udid"]
|
13
14
|
udid = "unknown" if udid.nil?
|
14
15
|
@@drivers[udid]
|
15
16
|
end
|
16
|
-
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'em/pure_ruby'
|
4
|
+
require 'appium_lib_core'
|
5
|
+
|
3
6
|
require_relative 'common/bounds'
|
4
7
|
require_relative 'common/exceptions/strategy_mix_exception'
|
5
8
|
require_relative 'common/helpers'
|
@@ -10,18 +13,24 @@ require_relative 'common/selenium_element'
|
|
10
13
|
module TestaAppiumDriver
|
11
14
|
class Driver
|
12
15
|
include Helpers
|
16
|
+
|
17
|
+
# @return [::Appium::Core::Base::Driver] the ruby_lib_core appium driver
|
13
18
|
attr_accessor :driver
|
19
|
+
|
20
|
+
# @return [String] iOS or Android
|
14
21
|
attr_reader :device
|
22
|
+
|
23
|
+
# @return [String] driver automation name (uiautomator2 or xcuitest)
|
15
24
|
attr_reader :automation_name
|
16
25
|
|
17
26
|
# custom options
|
18
|
-
# -
|
27
|
+
# - default_find_strategy: default strategy to be used for finding elements. Available strategies :uiautomator or :xpath
|
28
|
+
# - default_scroll_strategy: default strategy to be used for scrolling. Available strategies: :uiautomator(android only), :w3c
|
19
29
|
def initialize(opts = {})
|
20
30
|
@testa_opts = opts[:testa_appium_driver] || {}
|
21
31
|
|
22
32
|
|
23
|
-
|
24
|
-
core = ::Appium::Core.for(opts)
|
33
|
+
core = Appium::Core.for(opts)
|
25
34
|
extend_for(core.device, core.automation_name)
|
26
35
|
@device = core.device
|
27
36
|
@automation_name = core.automation_name
|
@@ -29,14 +38,15 @@ module TestaAppiumDriver
|
|
29
38
|
handle_testa_opts
|
30
39
|
|
31
40
|
@driver = core.start_driver
|
32
|
-
invalidate_cache
|
41
|
+
invalidate_cache
|
33
42
|
|
34
43
|
|
35
|
-
|
44
|
+
Selenium::WebDriver::Element.set_driver(self, opts[:caps][:udid])
|
36
45
|
end
|
37
46
|
|
38
47
|
|
39
|
-
|
48
|
+
# invalidates current find_element cache
|
49
|
+
def invalidate_cache
|
40
50
|
@cache = {
|
41
51
|
strategy: nil,
|
42
52
|
selector: nil,
|
@@ -49,11 +59,13 @@ module TestaAppiumDriver
|
|
49
59
|
|
50
60
|
|
51
61
|
|
52
|
-
#
|
62
|
+
# Executes the find_element with the resolved locator strategy and selector. Find_element might be skipped if cache is hit.
|
63
|
+
# Cache stores last executed find_element with given selector, strategy and from_element. If given values are the same within
|
64
|
+
# last 5 seconds element is retrieved from cache.
|
53
65
|
# @param [TestaAppiumDriver::Locator, TestaAppiumDriver::Driver] from_element element from which start the search
|
54
|
-
# @param [String] selector resolved string of a [TestaAppiumDriver::Locator] selector xpath for xpath strategy, java UiSelectors for uiautomator
|
66
|
+
# @param [String] selector resolved string of a [TestaAppiumDriver::Locator] selector xpath for xpath strategy, java UiSelectors for uiautomator or id for ID strategy
|
55
67
|
# @param [Boolean] single fetch single or multiple results
|
56
|
-
# @param [Symbol, nil] strategy [TestaAppiumDriver
|
68
|
+
# @param [Symbol, nil] strategy [TestaAppiumDriver::FIND_STRATEGY_UIAUTOMATOR], [TestaAppiumDriver::FIND_STRATEGY_XPATH] or [TestaAppiumDriver::FIND_STRATEGY_ID]
|
57
69
|
# @param [Symbol] default_strategy if strategy is not enforced, default can be used
|
58
70
|
# @param [Boolean] skip_cache to skip checking and storing cache
|
59
71
|
# @return [Selenium::WebDriver::Element, Array] element is returned if single is true, array otherwise
|
@@ -107,21 +119,27 @@ module TestaAppiumDriver
|
|
107
119
|
|
108
120
|
|
109
121
|
# method missing is used to forward methods to the actual appium driver
|
122
|
+
# after the method is executed, find element cache is invalidated
|
110
123
|
def method_missing(method, *args, &block)
|
111
|
-
@driver.send(method, *args, &block)
|
124
|
+
r = @driver.send(method, *args, &block)
|
125
|
+
invalidate_cache
|
126
|
+
r
|
112
127
|
end
|
113
128
|
|
129
|
+
# disables implicit wait
|
114
130
|
def disable_implicit_wait
|
115
131
|
@implicit_wait_ms = @driver.get_timeouts["implicit"]
|
116
132
|
@driver.manage.timeouts.implicit_wait = 0
|
117
133
|
end
|
118
134
|
|
135
|
+
# enables implicit wait, can be called only after disabling implicit wait
|
119
136
|
def enable_implicit_wait
|
120
137
|
raise "Implicit wait is not disabled" if @implicit_wait_ms.nil?
|
121
138
|
# get_timeouts always returns in milliseconds, but we should set in seconds
|
122
139
|
@driver.manage.timeouts.implicit_wait = @implicit_wait_ms / 1000
|
123
140
|
end
|
124
141
|
|
142
|
+
# disables wait for idle, only executed for android devices
|
125
143
|
def disable_wait_for_idle
|
126
144
|
if @device == :android
|
127
145
|
@wait_for_idle_timeout = @driver.settings.get["waitForIdleTimeout"]
|
@@ -129,6 +147,7 @@ module TestaAppiumDriver
|
|
129
147
|
end
|
130
148
|
end
|
131
149
|
|
150
|
+
# enables wait for idle, only executed for android devices
|
132
151
|
def enable_wait_for_idle
|
133
152
|
if @device == :android
|
134
153
|
raise "Wait for idle is not disabled" if @wait_for_idle_timeout.nil?
|
@@ -136,12 +155,15 @@ module TestaAppiumDriver
|
|
136
155
|
end
|
137
156
|
end
|
138
157
|
|
158
|
+
|
159
|
+
# @@return [String] current package under test
|
139
160
|
def current_package
|
140
161
|
@driver.current_package
|
141
162
|
end
|
142
163
|
|
143
|
-
|
144
|
-
|
164
|
+
|
165
|
+
def window_size
|
166
|
+
@driver.window_size
|
145
167
|
end
|
146
168
|
|
147
169
|
def back
|
@@ -166,6 +188,7 @@ module TestaAppiumDriver
|
|
166
188
|
end
|
167
189
|
|
168
190
|
|
191
|
+
# @return [Array<Selenium::WebDriver::Element] array of 2 elements, the first element without children and the last element without children in the current page
|
169
192
|
def first_and_last_leaf(from_element = @driver)
|
170
193
|
disable_wait_for_idle
|
171
194
|
disable_implicit_wait
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module TestaAppiumDriver
|
2
|
-
|
3
|
-
class Locator
|
4
|
-
|
2
|
+
module Attributes
|
5
3
|
|
6
4
|
#noinspection RubyNilAnalysis
|
7
5
|
def attribute(name, *args)
|
@@ -76,4 +74,8 @@ module TestaAppiumDriver
|
|
76
74
|
alias_method :bounds, :rect
|
77
75
|
alias_method :text, :label
|
78
76
|
end
|
77
|
+
#noinspection RubyYardReturnMatch
|
78
|
+
class Locator
|
79
|
+
include TestaAppiumDriver::Attributes
|
80
|
+
end
|
79
81
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative 'locator/attributes'
|
2
2
|
|
3
3
|
module TestaAppiumDriver
|
4
|
-
#noinspection RubyTooManyInstanceVariablesInspection
|
5
4
|
class Locator
|
6
5
|
include TypeSelectors
|
7
6
|
|
@@ -24,6 +23,7 @@ module TestaAppiumDriver
|
|
24
23
|
end
|
25
24
|
|
26
25
|
|
26
|
+
# @return [Array] returns 2 elements. The first is the resolved find element strategy and the second is the resolved selector
|
27
27
|
def strategy_and_selector
|
28
28
|
if @can_use_id_strategy
|
29
29
|
return FIND_STRATEGY_NAME, @can_use_id_strategy
|
@@ -32,7 +32,8 @@ module TestaAppiumDriver
|
|
32
32
|
end
|
33
33
|
|
34
34
|
|
35
|
-
|
35
|
+
|
36
|
+
# @return [Locator] new child locator element
|
36
37
|
def add_child_selector(params)
|
37
38
|
params, selectors = extract_selectors_from_params(params)
|
38
39
|
single = params[:single]
|
@@ -1,5 +1,5 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module TestaAppiumDriver
|
4
|
-
VERSION = "0.1.
|
5
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TestaAppiumDriver
|
4
|
+
VERSION = "0.1.5"
|
5
|
+
end
|
data/testa_appium_driver.gemspec
CHANGED
@@ -9,13 +9,14 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.email = ["karlo.razumovic@gmail.com"]
|
10
10
|
|
11
11
|
spec.summary = "Appium made easy"
|
12
|
-
spec.description = "Testa appium driver is a wrapper around ruby_lib_core. It significantly reduces the amount of code
|
12
|
+
spec.description = "Testa appium driver is a wrapper around ruby_lib_core. It leverages all driver features and makes them simple and easy to use, significantly reduces the amount of code needed and enables you to define locators that can be reused"
|
13
13
|
spec.homepage = "https://github.com/Karazum/testa_appium_driver"
|
14
14
|
spec.license = "MIT"
|
15
15
|
spec.required_ruby_version = ">= 2.4.0"
|
16
16
|
|
17
17
|
#spec.metadata["allowed_push_host"] = "Set to 'https://mygemserver.com'"
|
18
18
|
|
19
|
+
spec.metadata["documentation_uri"] = "https://www.rubydoc.info/gems/testa_appium_driver"
|
19
20
|
spec.metadata["homepage_uri"] = spec.homepage
|
20
21
|
spec.metadata["source_code_uri"] = "https://github.com/Karazum/testa_appium_driver"
|
21
22
|
spec.metadata["changelog_uri"] = "https://github.com/Karazum/testa_appium_driver"
|
@@ -30,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
30
31
|
spec.require_paths = ["lib"]
|
31
32
|
|
32
33
|
spec.add_runtime_dependency "appium_lib_core", ["= 4.7.0"]
|
33
|
-
spec.add_runtime_dependency "json", ["
|
34
|
+
spec.add_runtime_dependency "json", ["~> 2.3"]
|
34
35
|
|
35
36
|
spec.add_development_dependency "rubocop", ["= 1.19.0"]
|
36
37
|
spec.add_development_dependency "rake", ["~> 13.0"]
|
data/testa_appium_driver.iml
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
<orderEntry type="sourceFolder" forTests="false" />
|
12
12
|
<orderEntry type="library" scope="PROVIDED" name="appium_lib_core (v4.7.0, ruby-2.6.5-p114) [gem]" level="application" />
|
13
13
|
<orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, ruby-2.6.5-p114) [gem]" level="application" />
|
14
|
-
<orderEntry type="library" scope="PROVIDED" name="bundler (v2.
|
14
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v2.1.4, ruby-2.6.5-p114) [gem]" level="application" />
|
15
15
|
<orderEntry type="library" scope="PROVIDED" name="childprocess (v3.0.0, ruby-2.6.5-p114) [gem]" level="application" />
|
16
16
|
<orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.4.4, ruby-2.6.5-p114) [gem]" level="application" />
|
17
17
|
<orderEntry type="library" scope="PROVIDED" name="eventmachine (v1.2.7, ruby-2.6.5-p114) [gem]" level="application" />
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testa_appium_driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- karlo.razumovic
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-08-
|
11
|
+
date: 2021-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appium_lib_core
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.3
|
33
|
+
version: '2.3'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.3
|
40
|
+
version: '2.3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rubocop
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,8 +66,9 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '13.0'
|
69
|
-
description: Testa appium driver is a wrapper around ruby_lib_core. It
|
70
|
-
|
69
|
+
description: Testa appium driver is a wrapper around ruby_lib_core. It leverages all
|
70
|
+
driver features and makes them simple and easy to use, significantly reduces the
|
71
|
+
amount of code needed and enables you to define locators that can be reused
|
71
72
|
email:
|
72
73
|
- karlo.razumovic@gmail.com
|
73
74
|
executables: []
|
@@ -123,6 +124,7 @@ homepage: https://github.com/Karazum/testa_appium_driver
|
|
123
124
|
licenses:
|
124
125
|
- MIT
|
125
126
|
metadata:
|
127
|
+
documentation_uri: https://www.rubydoc.info/gems/testa_appium_driver
|
126
128
|
homepage_uri: https://github.com/Karazum/testa_appium_driver
|
127
129
|
source_code_uri: https://github.com/Karazum/testa_appium_driver
|
128
130
|
changelog_uri: https://github.com/Karazum/testa_appium_driver
|