testa_appium_driver 0.1.11 → 0.1.12

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -15
  3. data/.idea/deployment.xml +21 -21
  4. data/.idea/inspectionProfiles/Project_Default.xml +8 -8
  5. data/.idea/misc.xml +5 -5
  6. data/.idea/modules.xml +7 -7
  7. data/.idea/runConfigurations/Android_Test.xml +41 -41
  8. data/.idea/runConfigurations.xml +9 -9
  9. data/.idea/sshConfigs.xml +12 -12
  10. data/.idea/vcs.xml +5 -5
  11. data/.idea/webServers.xml +20 -20
  12. data/.rspec +3 -3
  13. data/.rubocop.yml +13 -13
  14. data/CHANGELOG.md +5 -5
  15. data/CODE_OF_CONDUCT.md +102 -102
  16. data/Gemfile +12 -12
  17. data/LICENSE.txt +21 -21
  18. data/README.md +378 -378
  19. data/Rakefile +12 -12
  20. data/bin/console +17 -17
  21. data/bin/setup +8 -8
  22. data/lib/testa_appium_driver/android/class_selectors.rb +437 -437
  23. data/lib/testa_appium_driver/android/driver.rb +69 -69
  24. data/lib/testa_appium_driver/android/locator/attributes.rb +113 -113
  25. data/lib/testa_appium_driver/android/locator.rb +141 -141
  26. data/lib/testa_appium_driver/android/scroll_actions/uiautomator_scroll_actions.rb +61 -61
  27. data/lib/testa_appium_driver/android/selenium_element.rb +7 -7
  28. data/lib/testa_appium_driver/common/bounds.rb +149 -149
  29. data/lib/testa_appium_driver/common/constants.rb +36 -36
  30. data/lib/testa_appium_driver/common/exceptions/strategy_mix_exception.rb +11 -11
  31. data/lib/testa_appium_driver/common/helpers.rb +270 -270
  32. data/lib/testa_appium_driver/common/locator/scroll_actions.rb +397 -397
  33. data/lib/testa_appium_driver/common/locator.rb +610 -610
  34. data/lib/testa_appium_driver/common/scroll_actions/json_wire_scroll_actions.rb +3 -3
  35. data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +237 -237
  36. data/lib/testa_appium_driver/common/scroll_actions.rb +246 -246
  37. data/lib/testa_appium_driver/common/selenium_element.rb +19 -19
  38. data/lib/testa_appium_driver/driver.rb +312 -312
  39. data/lib/testa_appium_driver/ios/driver.rb +48 -48
  40. data/lib/testa_appium_driver/ios/locator/attributes.rb +80 -80
  41. data/lib/testa_appium_driver/ios/locator.rb +70 -70
  42. data/lib/testa_appium_driver/ios/selenium_element.rb +6 -6
  43. data/lib/testa_appium_driver/ios/type_selectors.rb +187 -187
  44. data/lib/testa_appium_driver/version.rb +5 -5
  45. data/lib/testa_appium_driver.rb +6 -6
  46. data/testa_appium_driver.gemspec +41 -41
  47. data/testa_appium_driver.iml +27 -78
  48. metadata +3 -3
@@ -1,62 +1,62 @@
1
- module TestaAppiumDriver
2
- #noinspection RubyInstanceMethodNamingConvention
3
- class ScrollActions
4
- private
5
-
6
- def uiautomator_scroll_to_start_or_end(type)
7
-
8
- scrollable_selector = @scrollable.ui_selector(false)
9
- orientation = @scrollable.scroll_orientation == :vertical ? ".setAsVerticalList()" : ".setAsHorizontalList()"
10
- scroll_command = type == :start ? ".scrollToBeginning(#{DEFAULT_UIAUTOMATOR_MAX_SWIPES})" : ".scrollToEnd(#{DEFAULT_UIAUTOMATOR_MAX_SWIPES})"
11
- cmd = "new UiScrollable(#{scrollable_selector})#{orientation}#{scroll_command};"
12
- begin
13
- puts "Scroll execute[uiautomator_#{type}]: #{cmd}"
14
- @driver.find_element(uiautomator: cmd)
15
- rescue
16
- # Ignored
17
- end
18
-
19
-
20
- end
21
-
22
-
23
- def uiautomator_scroll_to
24
- raise "UiAutomator scroll cannot work with specified direction" unless @direction.nil?
25
-
26
- scrollable_selector = @scrollable.ui_selector(false)
27
- element_selector = @locator.ui_selector(false)
28
- orientation_command = @scrollable.scroll_orientation == :vertical ? ".setAsVerticalList()" : ".setAsHorizontalList()"
29
- cmd = "new UiScrollable(#{scrollable_selector})#{orientation_command}.scrollIntoView(#{element_selector});"
30
- begin
31
- puts "Scroll execute[uiautomator_scroll_to]: #{cmd}"
32
- @driver.find_element(uiautomator: cmd)
33
- rescue
34
- # Ignored
35
- ensure
36
- end
37
- end
38
-
39
-
40
- def uiautomator_page_or_fling(type, direction)
41
- scrollable_selector = @scrollable.ui_selector(false)
42
- orientation = direction == :up || direction == :down ? ".setAsVerticalList()" : ".setAsHorizontalList()"
43
- if type == SCROLL_ACTION_TYPE_SCROLL
44
- direction_command = direction == :down || direction == :right ? ".scrollForward()" : ".scrollBackward()"
45
- elsif type == SCROLL_ACTION_TYPE_FLING
46
- direction_command = direction == :down || direction == :right ? ".flingForward()" : ".flingBackward()"
47
- else
48
- raise "Unknown scroll action type #{type}"
49
- end
50
- cmd = "new UiScrollable(#{scrollable_selector})#{orientation}#{direction_command};"
51
- begin
52
- puts "Scroll execute[uiautomator_#{type}]: #{cmd}"
53
- @driver.find_element(uiautomator: cmd)
54
- rescue
55
- # Ignored
56
- end
57
- end
58
-
59
-
60
- end
61
-
1
+ module TestaAppiumDriver
2
+ #noinspection RubyInstanceMethodNamingConvention
3
+ class ScrollActions
4
+ private
5
+
6
+ def uiautomator_scroll_to_start_or_end(type)
7
+
8
+ scrollable_selector = @scrollable.ui_selector(false)
9
+ orientation = @scrollable.scroll_orientation == :vertical ? ".setAsVerticalList()" : ".setAsHorizontalList()"
10
+ scroll_command = type == :start ? ".scrollToBeginning(#{DEFAULT_UIAUTOMATOR_MAX_SWIPES})" : ".scrollToEnd(#{DEFAULT_UIAUTOMATOR_MAX_SWIPES})"
11
+ cmd = "new UiScrollable(#{scrollable_selector})#{orientation}#{scroll_command};"
12
+ begin
13
+ puts "Scroll execute[uiautomator_#{type}]: #{cmd}"
14
+ @driver.find_element(uiautomator: cmd)
15
+ rescue
16
+ # Ignored
17
+ end
18
+
19
+
20
+ end
21
+
22
+
23
+ def uiautomator_scroll_to
24
+ raise "UiAutomator scroll cannot work with specified direction" unless @direction.nil?
25
+
26
+ scrollable_selector = @scrollable.ui_selector(false)
27
+ element_selector = @locator.ui_selector(false)
28
+ orientation_command = @scrollable.scroll_orientation == :vertical ? ".setAsVerticalList()" : ".setAsHorizontalList()"
29
+ cmd = "new UiScrollable(#{scrollable_selector})#{orientation_command}.scrollIntoView(#{element_selector});"
30
+ begin
31
+ puts "Scroll execute[uiautomator_scroll_to]: #{cmd}"
32
+ @driver.find_element(uiautomator: cmd)
33
+ rescue
34
+ # Ignored
35
+ ensure
36
+ end
37
+ end
38
+
39
+
40
+ def uiautomator_page_or_fling(type, direction)
41
+ scrollable_selector = @scrollable.ui_selector(false)
42
+ orientation = direction == :up || direction == :down ? ".setAsVerticalList()" : ".setAsHorizontalList()"
43
+ if type == SCROLL_ACTION_TYPE_SCROLL
44
+ direction_command = direction == :down || direction == :right ? ".scrollForward()" : ".scrollBackward()"
45
+ elsif type == SCROLL_ACTION_TYPE_FLING
46
+ direction_command = direction == :down || direction == :right ? ".flingForward()" : ".flingBackward()"
47
+ else
48
+ raise "Unknown scroll action type #{type}"
49
+ end
50
+ cmd = "new UiScrollable(#{scrollable_selector})#{orientation}#{direction_command};"
51
+ begin
52
+ puts "Scroll execute[uiautomator_#{type}]: #{cmd}"
53
+ @driver.find_element(uiautomator: cmd)
54
+ rescue
55
+ # Ignored
56
+ end
57
+ end
58
+
59
+
60
+ end
61
+
62
62
  end
@@ -1,8 +1,8 @@
1
- module Selenium
2
- module WebDriver
3
- class Element
4
- include TestaAppiumDriver::ClassSelectors
5
- include TestaAppiumDriver::Attributes
6
- end
7
- end
1
+ module Selenium
2
+ module WebDriver
3
+ class Element
4
+ include TestaAppiumDriver::ClassSelectors
5
+ include TestaAppiumDriver::Attributes
6
+ end
7
+ end
8
8
  end
@@ -1,150 +1,150 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
- module TestaAppiumDriver
5
- class Bounds
6
-
7
- attr_reader :width
8
- attr_reader :height
9
- attr_reader :offset
10
-
11
-
12
- # @param top_left [Coordinates]
13
- # @param bottom_right [Coordinates]
14
- # @param window_width [Integer]
15
- # @param window_height [Integer]
16
- def initialize(top_left, bottom_right, window_width, window_height)
17
- @top_left = top_left
18
- @bottom_right = bottom_right
19
- @width = bottom_right.x - top_left.x
20
- @height = bottom_right.y - top_left.y
21
- @offset = Offset.new(self, window_width, window_height)
22
- @center = TestaAppiumDriver::Coordinates.new(@top_left.x + @width/2, @top_left.y + @height / 2)
23
- end
24
-
25
- def as_json
26
- {
27
- width: @width,
28
- height: @height,
29
- top_left: @top_left.as_json,
30
- bottom_right: @bottom_right.as_json,
31
- offset: @offset.as_json
32
- }
33
- end
34
-
35
- # @return [TestaAppiumDriver::Offset]
36
- def offset
37
- @offset
38
- end
39
-
40
- # @return [TestaAppiumDriver::Coordinates]
41
- def top_left
42
- @top_left
43
- end
44
- # @return [TestaAppiumDriver::Coordinates]
45
- def bottom_right
46
- @bottom_right
47
- end
48
-
49
- # @return [TestaAppiumDriver::Coordinates]
50
- def center
51
- @center
52
- end
53
-
54
- def to_s
55
- JSON.dump(as_json)
56
- end
57
-
58
- # @param bounds [String] bounds that driver.attribute("bounds") return
59
- # @param driver [TestaAppiumDriver::Driver]
60
- def self.from_android(bounds, driver)
61
- matches = bounds.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/)
62
- raise "Unexpected bounds: #{bounds}" unless matches
63
-
64
- captures = matches.captures
65
- top_left = Coordinates.new(captures[0], captures[1])
66
- bottom_right = Coordinates.new(captures[2], captures[3])
67
- ws = driver.window_size
68
- window_width = ws.width.to_i
69
- window_height = ws.height.to_i
70
- Bounds.new(top_left, bottom_right, window_width, window_height)
71
- end
72
-
73
- def self.from_ios(rect, driver)
74
- rect = JSON.parse(rect)
75
- top_left = Coordinates.new(rect["x"], rect["y"])
76
- bottom_right = Coordinates.new(top_left.x + rect["width"].to_i, top_left.y + rect["height"].to_i)
77
- ws = driver.window_size
78
- window_width = ws.width.to_i
79
- window_height = ws.height.to_i
80
- Bounds.new(top_left, bottom_right, window_width, window_height)
81
- end
82
- end
83
-
84
- #noinspection ALL
85
- class Coordinates
86
- def initialize(x, y)
87
- @x = x.to_i
88
- @y = y.to_i
89
- end
90
-
91
- def as_json
92
- {
93
- x: @x,
94
- y: @y
95
- }
96
- end
97
-
98
-
99
- # @return [Integer]
100
- def x
101
- @x
102
- end
103
-
104
- # @return [Integer]
105
- def y
106
- @y
107
- end
108
- end
109
-
110
-
111
- class Offset
112
- def initialize(bounds, window_width, window_height)
113
- @top = bounds.top_left.y
114
- @right = window_width - bounds.bottom_right.x
115
- @bottom = window_height - bounds.bottom_right.y
116
- @left = bounds.top_left.x
117
- end
118
-
119
- def as_json
120
- {
121
- top: @top,
122
- right: @right,
123
- bottom: @bottom,
124
- left: @left
125
- }
126
- end
127
-
128
-
129
- # @return [Integer]
130
- def top
131
- @top
132
- end
133
-
134
- # @return [Integer]
135
- def right
136
- @right
137
- end
138
-
139
- # @return [Integer]
140
- def bottom
141
- @bottom
142
- end
143
-
144
- # @return [Integer]
145
- def left
146
- @left
147
- end
148
-
149
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ module TestaAppiumDriver
5
+ class Bounds
6
+
7
+ attr_reader :width
8
+ attr_reader :height
9
+ attr_reader :offset
10
+
11
+
12
+ # @param top_left [Coordinates]
13
+ # @param bottom_right [Coordinates]
14
+ # @param window_width [Integer]
15
+ # @param window_height [Integer]
16
+ def initialize(top_left, bottom_right, window_width, window_height)
17
+ @top_left = top_left
18
+ @bottom_right = bottom_right
19
+ @width = bottom_right.x - top_left.x
20
+ @height = bottom_right.y - top_left.y
21
+ @offset = Offset.new(self, window_width, window_height)
22
+ @center = TestaAppiumDriver::Coordinates.new(@top_left.x + @width/2, @top_left.y + @height / 2)
23
+ end
24
+
25
+ def as_json
26
+ {
27
+ width: @width,
28
+ height: @height,
29
+ top_left: @top_left.as_json,
30
+ bottom_right: @bottom_right.as_json,
31
+ offset: @offset.as_json
32
+ }
33
+ end
34
+
35
+ # @return [TestaAppiumDriver::Offset]
36
+ def offset
37
+ @offset
38
+ end
39
+
40
+ # @return [TestaAppiumDriver::Coordinates]
41
+ def top_left
42
+ @top_left
43
+ end
44
+ # @return [TestaAppiumDriver::Coordinates]
45
+ def bottom_right
46
+ @bottom_right
47
+ end
48
+
49
+ # @return [TestaAppiumDriver::Coordinates]
50
+ def center
51
+ @center
52
+ end
53
+
54
+ def to_s
55
+ JSON.dump(as_json)
56
+ end
57
+
58
+ # @param bounds [String] bounds that driver.attribute("bounds") return
59
+ # @param driver [TestaAppiumDriver::Driver]
60
+ def self.from_android(bounds, driver)
61
+ matches = bounds.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/)
62
+ raise "Unexpected bounds: #{bounds}" unless matches
63
+
64
+ captures = matches.captures
65
+ top_left = Coordinates.new(captures[0], captures[1])
66
+ bottom_right = Coordinates.new(captures[2], captures[3])
67
+ ws = driver.window_size
68
+ window_width = ws.width.to_i
69
+ window_height = ws.height.to_i
70
+ Bounds.new(top_left, bottom_right, window_width, window_height)
71
+ end
72
+
73
+ def self.from_ios(rect, driver)
74
+ rect = JSON.parse(rect)
75
+ top_left = Coordinates.new(rect["x"], rect["y"])
76
+ bottom_right = Coordinates.new(top_left.x + rect["width"].to_i, top_left.y + rect["height"].to_i)
77
+ ws = driver.window_size
78
+ window_width = ws.width.to_i
79
+ window_height = ws.height.to_i
80
+ Bounds.new(top_left, bottom_right, window_width, window_height)
81
+ end
82
+ end
83
+
84
+ #noinspection ALL
85
+ class Coordinates
86
+ def initialize(x, y)
87
+ @x = x.to_i
88
+ @y = y.to_i
89
+ end
90
+
91
+ def as_json
92
+ {
93
+ x: @x,
94
+ y: @y
95
+ }
96
+ end
97
+
98
+
99
+ # @return [Integer]
100
+ def x
101
+ @x
102
+ end
103
+
104
+ # @return [Integer]
105
+ def y
106
+ @y
107
+ end
108
+ end
109
+
110
+
111
+ class Offset
112
+ def initialize(bounds, window_width, window_height)
113
+ @top = bounds.top_left.y
114
+ @right = window_width - bounds.bottom_right.x
115
+ @bottom = window_height - bounds.bottom_right.y
116
+ @left = bounds.top_left.x
117
+ end
118
+
119
+ def as_json
120
+ {
121
+ top: @top,
122
+ right: @right,
123
+ bottom: @bottom,
124
+ left: @left
125
+ }
126
+ end
127
+
128
+
129
+ # @return [Integer]
130
+ def top
131
+ @top
132
+ end
133
+
134
+ # @return [Integer]
135
+ def right
136
+ @right
137
+ end
138
+
139
+ # @return [Integer]
140
+ def bottom
141
+ @bottom
142
+ end
143
+
144
+ # @return [Integer]
145
+ def left
146
+ @left
147
+ end
148
+
149
+ end
150
150
  end
@@ -1,37 +1,37 @@
1
- # frozen_string_literal: true
2
-
3
- #noinspection ALL
4
- module TestaAppiumDriver
5
- FIND_STRATEGY_UIAUTOMATOR = :uiautomator
6
- FIND_STRATEGY_XPATH = :xpath
7
- FIND_STRATEGY_ID = :id
8
- FIND_STRATEGY_NAME = :name
9
- FIND_STRATEGY_IMAGE = :image
10
- FIND_STRATEGY_CLASS_CHAIN = :class_chain
11
-
12
- SCROLL_STRATEGY_UIAUTOMATOR = :uiautomator
13
- SCROLL_STRATEGY_W3C = :w3c
14
-
15
-
16
- SCROLL_CORRECTION_W3C = 30
17
- SCROLL_ALIGNMENT_THRESHOLD = 25
18
-
19
- SCROLL_ACTION_TYPE_SCROLL = :scroll
20
- SCROLL_ACTION_TYPE_FLING = :fling
21
- SCROLL_ACTION_TYPE_DRAG = :drag
22
-
23
-
24
- DEFAULT_UIAUTOMATOR_MAX_SWIPES = 20
25
-
26
- DEFAULT_ANDROID_FIND_STRATEGY = FIND_STRATEGY_UIAUTOMATOR
27
- DEFAULT_ANDROID_SCROLL_STRATEGY = SCROLL_STRATEGY_UIAUTOMATOR
28
-
29
-
30
- DEFAULT_IOS_FIND_STRATEGY = FIND_STRATEGY_XPATH
31
- DEFAULT_IOS_SCROLL_STRATEGY = SCROLL_STRATEGY_W3C
32
-
33
- DEFAULT_W3C_MAX_SCROLLS = 7
34
-
35
- EXISTS_WAIT = 0.5
36
- LONG_TAP_DURATION = 1.5
1
+ # frozen_string_literal: true
2
+
3
+ #noinspection ALL
4
+ module TestaAppiumDriver
5
+ FIND_STRATEGY_UIAUTOMATOR = :uiautomator
6
+ FIND_STRATEGY_XPATH = :xpath
7
+ FIND_STRATEGY_ID = :id
8
+ FIND_STRATEGY_NAME = :name
9
+ FIND_STRATEGY_IMAGE = :image
10
+ FIND_STRATEGY_CLASS_CHAIN = :class_chain
11
+
12
+ SCROLL_STRATEGY_UIAUTOMATOR = :uiautomator
13
+ SCROLL_STRATEGY_W3C = :w3c
14
+
15
+
16
+ SCROLL_CORRECTION_W3C = 30
17
+ SCROLL_ALIGNMENT_THRESHOLD = 25
18
+
19
+ SCROLL_ACTION_TYPE_SCROLL = :scroll
20
+ SCROLL_ACTION_TYPE_FLING = :fling
21
+ SCROLL_ACTION_TYPE_DRAG = :drag
22
+
23
+
24
+ DEFAULT_UIAUTOMATOR_MAX_SWIPES = 20
25
+
26
+ DEFAULT_ANDROID_FIND_STRATEGY = FIND_STRATEGY_UIAUTOMATOR
27
+ DEFAULT_ANDROID_SCROLL_STRATEGY = SCROLL_STRATEGY_UIAUTOMATOR
28
+
29
+
30
+ DEFAULT_IOS_FIND_STRATEGY = FIND_STRATEGY_XPATH
31
+ DEFAULT_IOS_SCROLL_STRATEGY = SCROLL_STRATEGY_W3C
32
+
33
+ DEFAULT_W3C_MAX_SCROLLS = 7
34
+
35
+ EXISTS_WAIT = 0.5
36
+ LONG_TAP_DURATION = 1.5
37
37
  end
@@ -1,12 +1,12 @@
1
- # frozen_string_literal: true
2
-
3
- module TestaAppiumDriver
4
- class StrategyMixException < Exception
5
- def initialize(strategy, strategy_reason, mixed_strategy, mixed_reason)
6
-
7
- # example: parent is only available in xpath strategy and cannot be used with from_element which is only available in uiautomator strategy
8
- msg = "strategy mix exception: '#{strategy_reason}' is only available in #{strategy} strategy and cannot be used with '#{mixed_reason}' which is only available in #{mixed_strategy} strategy"
9
- super(msg)
10
- end
11
- end
1
+ # frozen_string_literal: true
2
+
3
+ module TestaAppiumDriver
4
+ class StrategyMixException < Exception
5
+ def initialize(strategy, strategy_reason, mixed_strategy, mixed_reason)
6
+
7
+ # example: parent is only available in xpath strategy and cannot be used with from_element which is only available in uiautomator strategy
8
+ msg = "strategy mix exception: '#{strategy_reason}' is only available in #{strategy} strategy and cannot be used with '#{mixed_reason}' which is only available in #{mixed_strategy} strategy"
9
+ super(msg)
10
+ end
11
+ end
12
12
  end