appom 1.4.0 → 2.0.0
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/README.md +170 -42
- data/lib/appom/configuration.rb +490 -0
- data/lib/appom/element_cache.rb +372 -0
- data/lib/appom/element_container.rb +257 -244
- data/lib/appom/element_finder.rb +142 -138
- data/lib/appom/element_state.rb +458 -0
- data/lib/appom/element_validation.rb +138 -0
- data/lib/appom/exceptions.rb +130 -0
- data/lib/appom/helpers.rb +328 -0
- data/lib/appom/logging.rb +106 -0
- data/lib/appom/page.rb +19 -10
- data/lib/appom/performance.rb +394 -0
- data/lib/appom/retry.rb +178 -0
- data/lib/appom/screenshot.rb +371 -0
- data/lib/appom/section.rb +24 -21
- data/lib/appom/smart_wait.rb +455 -0
- data/lib/appom/version.rb +4 -1
- data/lib/appom/visual.rb +600 -0
- data/lib/appom/wait.rb +96 -35
- data/lib/appom.rb +191 -20
- metadata +35 -19
data/lib/appom/wait.rb
CHANGED
|
@@ -1,42 +1,103 @@
|
|
|
1
|
-
|
|
2
|
-
class Wait
|
|
3
|
-
DEFAULT_TIMEOUT = 5
|
|
4
|
-
DEFAULT_INTERVAL = 0.25
|
|
5
|
-
|
|
6
|
-
##
|
|
7
|
-
# Create a new Wait instance
|
|
8
|
-
#
|
|
9
|
-
# @param [Hash] opts Options for this instance
|
|
10
|
-
# @option opts [Numeric] :timeout (5) Seconds to wait before timing out.
|
|
11
|
-
# @option opts [Numeric] :interval (0.25) Seconds to sleep between polls.
|
|
12
|
-
#
|
|
13
|
-
def initialize(opts = {})
|
|
14
|
-
@timeout = opts.fetch(:timeout, DEFAULT_TIMEOUT)
|
|
15
|
-
@interval = opts.fetch(:interval, DEFAULT_INTERVAL)
|
|
16
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
17
2
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
3
|
+
# Provides wait functionality with configurable timeout and retry interval.
|
|
4
|
+
#
|
|
5
|
+
# The Wait class is used throughout Appom to wait for conditions to become true,
|
|
6
|
+
# such as waiting for elements to appear or disappear, or for elements to reach
|
|
7
|
+
# a certain state.
|
|
8
|
+
#
|
|
9
|
+
# @example Basic wait usage
|
|
10
|
+
# wait = Appom::Wait.new(timeout: 10, interval: 0.5)
|
|
11
|
+
# result = wait.until { some_condition }
|
|
12
|
+
#
|
|
13
|
+
# @example Wait for element to be displayed
|
|
14
|
+
# wait = Appom::Wait.new(timeout: 5)
|
|
15
|
+
# wait.until { element.displayed? }
|
|
16
|
+
#
|
|
17
|
+
# @since 0.1.0
|
|
18
|
+
# @author Harry.Tran
|
|
19
|
+
class Appom::Wait
|
|
20
|
+
include Appom::Logging
|
|
21
|
+
|
|
22
|
+
# Default timeout in seconds
|
|
23
|
+
DEFAULT_TIMEOUT = 5
|
|
24
|
+
# Default retry interval in seconds
|
|
25
|
+
DEFAULT_INTERVAL = 0.25
|
|
26
|
+
|
|
27
|
+
# @!attribute [r] timeout
|
|
28
|
+
# @return [Numeric] The timeout value in seconds
|
|
29
|
+
# @!attribute [r] interval
|
|
30
|
+
# @return [Numeric] The interval between retries in seconds
|
|
31
|
+
attr_reader :timeout, :interval
|
|
32
|
+
|
|
33
|
+
# Create a new Wait instance
|
|
34
|
+
#
|
|
35
|
+
# @param opts [Hash] Options for this instance
|
|
36
|
+
# @option opts [Numeric] :timeout (5) Seconds to wait before timing out
|
|
37
|
+
# @option opts [Numeric] :interval (0.25) Seconds to sleep between polls
|
|
38
|
+
# @return [Wait] A new Wait instance
|
|
39
|
+
#
|
|
40
|
+
# @example Create wait with custom timeout
|
|
41
|
+
# wait = Appom::Wait.new(timeout: 10, interval: 1.0)
|
|
42
|
+
def initialize(opts = {})
|
|
43
|
+
@timeout = opts.fetch(:timeout, DEFAULT_TIMEOUT)
|
|
44
|
+
@interval = opts.fetch(:interval, DEFAULT_INTERVAL)
|
|
45
|
+
end
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
# Wait until the given block returns a truthy value
|
|
48
|
+
#
|
|
49
|
+
# @yield [] Block to execute repeatedly until it returns true
|
|
50
|
+
# @return [Object] The result of the block when it returns truthy
|
|
51
|
+
# @raise [WaitError] If the timeout is reached before condition is met
|
|
52
|
+
# @raise [AppomError] Re-raises any Appom-specific errors from the block
|
|
53
|
+
#
|
|
54
|
+
# @example Wait for element to appear
|
|
55
|
+
# wait.until { page.find_element(:id, 'button') }
|
|
56
|
+
#
|
|
57
|
+
# @example Wait with exception handling
|
|
58
|
+
# wait.until do
|
|
59
|
+
# element = page.find_element(:id, 'button')
|
|
60
|
+
# element.displayed? && element.enabled?
|
|
61
|
+
# end
|
|
62
|
+
def until(&)
|
|
63
|
+
end_time = Time.now + @timeout
|
|
64
|
+
error_message = ''
|
|
65
|
+
last_error = nil
|
|
66
|
+
start_time = Time.now
|
|
67
|
+
|
|
68
|
+
log_wait_start('custom condition', @timeout)
|
|
69
|
+
|
|
70
|
+
until Time.now > end_time
|
|
71
|
+
begin
|
|
72
|
+
result = yield
|
|
73
|
+
if result
|
|
74
|
+
duration = Time.now - start_time
|
|
75
|
+
log_wait_end('custom condition', duration.round(3), success: true)
|
|
76
|
+
return result
|
|
77
|
+
end
|
|
78
|
+
rescue StandardError => e
|
|
79
|
+
last_error = e
|
|
80
|
+
error_message = e.message
|
|
37
81
|
end
|
|
38
82
|
|
|
39
|
-
|
|
83
|
+
sleep @interval
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
duration = Time.now - start_time
|
|
87
|
+
log_wait_end('custom condition', duration.round(3), success: false)
|
|
88
|
+
|
|
89
|
+
# Handle exceptions differently based on type
|
|
90
|
+
if last_error.is_a?(StandardError) && last_error.instance_of?(StandardError)
|
|
91
|
+
# Wrap StandardError in WaitError with message included
|
|
92
|
+
condition = "condition (last error: #{error_message})"
|
|
93
|
+
raise Appom::WaitError.new(condition, @timeout)
|
|
94
|
+
elsif last_error
|
|
95
|
+
# Raise specific exceptions directly (ArgumentError, RuntimeError, etc.)
|
|
96
|
+
raise last_error
|
|
97
|
+
else
|
|
98
|
+
# No exceptions, just condition never became true
|
|
99
|
+
condition = error_message.empty? ? 'condition' : error_message
|
|
100
|
+
raise Appom::WaitError.new(condition, @timeout)
|
|
40
101
|
end
|
|
41
102
|
end
|
|
42
103
|
end
|
data/lib/appom.rb
CHANGED
|
@@ -2,57 +2,228 @@
|
|
|
2
2
|
|
|
3
3
|
require 'appom/version'
|
|
4
4
|
require 'appium_lib'
|
|
5
|
-
require 'appom/
|
|
5
|
+
require 'appom/exceptions'
|
|
6
|
+
require 'appom/logging'
|
|
7
|
+
require 'appom/element_validation'
|
|
8
|
+
require 'appom/retry'
|
|
9
|
+
require 'appom/wait'
|
|
10
|
+
require 'appom/smart_wait'
|
|
11
|
+
require 'appom/element_cache'
|
|
12
|
+
require 'appom/screenshot'
|
|
13
|
+
require 'appom/configuration'
|
|
6
14
|
|
|
15
|
+
# The main Appom module provides a comprehensive Page Object Model framework for Appium.
|
|
16
|
+
#
|
|
17
|
+
# Appom gives you a simple, clean and semantic DSL for describing mobile applications.
|
|
18
|
+
# It implements the Page Object Model pattern on top of Appium with enhanced error
|
|
19
|
+
# handling, logging, performance monitoring, visual testing, and element state tracking.
|
|
20
|
+
#
|
|
21
|
+
# @example Basic usage
|
|
22
|
+
# # Register Appium driver
|
|
23
|
+
# Appom.register_driver do
|
|
24
|
+
# Appium::Driver.new(options, false)
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# # Configure global settings
|
|
28
|
+
# Appom.configure do |config|
|
|
29
|
+
# config.max_wait_time = 30
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# # Define page objects with enhanced features
|
|
33
|
+
# class LoginPage < Appom::Page
|
|
34
|
+
# element :email, :id, 'email_field'
|
|
35
|
+
# element :password, :id, 'password_field'
|
|
36
|
+
# element :submit, :accessibility_id, 'submit_button'
|
|
37
|
+
#
|
|
38
|
+
# def login_with_monitoring(email, password)
|
|
39
|
+
# Appom::Performance.time_operation('login_process') do
|
|
40
|
+
# self.email.set email
|
|
41
|
+
# self.password.set password
|
|
42
|
+
# self.submit.click
|
|
43
|
+
# end
|
|
44
|
+
# end
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# @example Visual testing
|
|
48
|
+
# # Perform visual regression test
|
|
49
|
+
# Appom::Visual.regression_test('login_screen')
|
|
50
|
+
#
|
|
51
|
+
# @example Performance monitoring
|
|
52
|
+
# # Get performance statistics
|
|
53
|
+
# stats = Appom::Performance.summary
|
|
54
|
+
# puts "Average operation time: #{stats[:average_operation_time]}s"
|
|
55
|
+
#
|
|
56
|
+
# @see https://github.com/hoangtaiki/appom
|
|
57
|
+
# @author Harry.Tran
|
|
7
58
|
module Appom
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# A block was passed to the method, which it cannot interpreter.
|
|
11
|
-
class UnsupportedBlockError < StandardError; end
|
|
59
|
+
include Appom::Logging
|
|
60
|
+
extend Appom::Logging
|
|
12
61
|
|
|
13
62
|
autoload :ElementContainer, 'appom/element_container'
|
|
14
63
|
autoload :Page, 'appom/page'
|
|
15
64
|
autoload :Wait, 'appom/wait'
|
|
16
65
|
autoload :Section, 'appom/section'
|
|
17
66
|
autoload :ElementFinder, 'appom/element_finder'
|
|
67
|
+
autoload :Helpers, 'appom/helpers'
|
|
68
|
+
autoload :Retry, 'appom/retry'
|
|
69
|
+
autoload :SmartWait, 'appom/smart_wait'
|
|
70
|
+
autoload :ElementCache, 'appom/element_cache'
|
|
71
|
+
autoload :Screenshot, 'appom/screenshot'
|
|
72
|
+
autoload :Configuration, 'appom/configuration'
|
|
73
|
+
autoload :Performance, 'appom/performance'
|
|
74
|
+
autoload :ElementState, 'appom/element_state'
|
|
75
|
+
autoload :Visual, 'appom/visual'
|
|
18
76
|
|
|
19
77
|
class << self
|
|
20
|
-
attr_accessor :driver
|
|
21
|
-
attr_accessor :max_wait_time
|
|
78
|
+
attr_accessor :driver, :max_wait_time
|
|
22
79
|
|
|
23
|
-
# Configure appom
|
|
80
|
+
# Configure appom global settings
|
|
81
|
+
#
|
|
82
|
+
# @yieldparam [self] config The Appom module for configuration
|
|
83
|
+
# @example Configure wait time
|
|
84
|
+
# Appom.configure do |config|
|
|
85
|
+
# config.max_wait_time = 30
|
|
86
|
+
# end
|
|
24
87
|
def configure
|
|
25
88
|
yield self
|
|
26
89
|
end
|
|
27
90
|
|
|
28
|
-
# Register a new
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
|
|
91
|
+
# Register a new Appium driver for Appom
|
|
92
|
+
#
|
|
93
|
+
# @yield [] Block that returns an Appium::Driver instance
|
|
94
|
+
# @return [Appium::Driver] The registered driver instance
|
|
95
|
+
# @raise [DriverError] If driver registration fails
|
|
96
|
+
#
|
|
97
|
+
# @example Register iOS driver
|
|
98
|
+
# Appom.register_driver do
|
|
99
|
+
# options = {
|
|
100
|
+
# appium_lib: { server_url: 'http://localhost:4723' },
|
|
101
|
+
# caps: { platformName: 'iOS', deviceName: 'iPhone 13' }
|
|
102
|
+
# }
|
|
103
|
+
# Appium::Driver.new(options, false)
|
|
104
|
+
# end
|
|
105
|
+
def register_driver(&)
|
|
106
|
+
log_info('Registering Appium driver')
|
|
107
|
+
|
|
108
|
+
# Register driver with performance monitoring
|
|
109
|
+
@driver = Performance.time_operation('driver_registration', &)
|
|
110
|
+
|
|
32
111
|
setup_exit_handler
|
|
112
|
+
|
|
113
|
+
# Initialize element state tracking if enabled
|
|
114
|
+
if Configuration.get('element_state.tracking_enabled', false)
|
|
115
|
+
ElementState.tracker
|
|
116
|
+
log_info('Element state tracking initialized')
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
log_info('Appium driver registered successfully')
|
|
120
|
+
@driver
|
|
121
|
+
rescue StandardError => e
|
|
122
|
+
log_error('Failed to register driver', { error: e.message })
|
|
123
|
+
raise DriverError, "Failed to register driver: #{e.message}"
|
|
33
124
|
end
|
|
34
125
|
|
|
35
|
-
#
|
|
126
|
+
# Start the registered Appium driver
|
|
127
|
+
#
|
|
128
|
+
# @raise [DriverNotInitializedError] If no driver has been registered
|
|
129
|
+
# @raise [DriverOperationError] If driver start fails
|
|
36
130
|
def start_driver
|
|
37
|
-
@driver
|
|
131
|
+
raise DriverNotInitializedError unless @driver
|
|
132
|
+
|
|
133
|
+
log_info('Starting Appium driver')
|
|
134
|
+
|
|
135
|
+
# Start driver with performance monitoring
|
|
136
|
+
Performance.time_operation('driver_start') do
|
|
137
|
+
@driver.start_driver
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
log_info('Appium driver started successfully')
|
|
141
|
+
rescue DriverNotInitializedError
|
|
142
|
+
raise
|
|
143
|
+
rescue StandardError => e
|
|
144
|
+
log_error('Failed to start driver', { error: e.message })
|
|
145
|
+
raise DriverOperationError.new('start_driver', e.message)
|
|
38
146
|
end
|
|
39
147
|
|
|
40
|
-
# Reset the device, relaunching the application
|
|
148
|
+
# Reset the device, relaunching the application
|
|
149
|
+
#
|
|
150
|
+
# @raise [DriverNotInitializedError] If no driver has been registered
|
|
151
|
+
# @raise [DriverOperationError] If driver reset fails
|
|
41
152
|
def reset_driver
|
|
42
|
-
@driver
|
|
153
|
+
raise DriverNotInitializedError unless @driver
|
|
154
|
+
|
|
155
|
+
log_info('Resetting Appium driver')
|
|
156
|
+
|
|
157
|
+
# Reset driver with performance monitoring
|
|
158
|
+
Performance.time_operation('driver_reset') do
|
|
159
|
+
@driver.reset
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
log_info('Appium driver reset successfully')
|
|
163
|
+
rescue DriverNotInitializedError
|
|
164
|
+
raise
|
|
165
|
+
rescue StandardError => e
|
|
166
|
+
log_error('Failed to reset driver', { error: e.message })
|
|
167
|
+
raise DriverOperationError.new('reset', e.message)
|
|
43
168
|
end
|
|
44
169
|
|
|
45
170
|
# After run all scenario and exit we will quit driver to close application under test
|
|
46
171
|
def setup_exit_handler
|
|
47
172
|
main = Process.pid
|
|
48
173
|
at_exit do
|
|
49
|
-
|
|
174
|
+
cleanup_on_exit(main)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
private
|
|
179
|
+
|
|
180
|
+
# Extracted method to enable testing
|
|
181
|
+
def cleanup_on_exit(main_pid)
|
|
182
|
+
return unless Process.pid == main_pid
|
|
183
|
+
|
|
184
|
+
begin
|
|
185
|
+
# Export performance metrics before quitting
|
|
186
|
+
if defined?(Performance) && Performance.monitor.metrics.any?
|
|
187
|
+
Performance.export_metrics(format: :json)
|
|
188
|
+
log_info('Performance metrics exported on exit')
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
@driver&.driver_quit
|
|
192
|
+
rescue StandardError => e
|
|
193
|
+
# Log error but don't raise during exit
|
|
194
|
+
warn "Warning: Failed to quit driver during exit: #{e.message}"
|
|
50
195
|
end
|
|
51
196
|
end
|
|
197
|
+
|
|
198
|
+
public
|
|
199
|
+
|
|
200
|
+
# Performance monitoring convenience methods
|
|
201
|
+
def performance_stats
|
|
202
|
+
Performance.summary
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def export_performance_metrics(**)
|
|
206
|
+
Performance.export_metrics(**)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Visual testing convenience methods
|
|
210
|
+
def visual_regression_test(name, **)
|
|
211
|
+
Visual.regression_test(name, **)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def generate_visual_report(**)
|
|
215
|
+
Visual.generate_report(**)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Element state tracking convenience methods
|
|
219
|
+
def element_tracking_summary
|
|
220
|
+
ElementState.tracking_summary
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def export_element_tracking(**)
|
|
224
|
+
ElementState.export_data(**)
|
|
225
|
+
end
|
|
52
226
|
end
|
|
53
227
|
|
|
54
228
|
@max_wait_time = 20
|
|
55
229
|
end
|
|
56
|
-
|
|
57
|
-
World(Appom)
|
|
58
|
-
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: appom
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Harry.Tran
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-02-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: appium_lib
|
|
@@ -16,46 +16,48 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '16.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '16.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: cucumber
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
31
|
+
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '9.0'
|
|
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: '
|
|
40
|
+
version: '9.0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: selenium-webdriver
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0
|
|
48
|
-
type: :
|
|
47
|
+
version: '4.0'
|
|
48
|
+
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0
|
|
55
|
-
description: Appom
|
|
56
|
-
|
|
54
|
+
version: '4.0'
|
|
55
|
+
description: Appom provides a clean, semantic DSL for mobile application testing.
|
|
56
|
+
Built on Appium, it includes performance monitoring, visual regression testing,
|
|
57
|
+
element state tracking, smart waiting, and intelligent caching for enterprise-grade
|
|
58
|
+
test automation.
|
|
57
59
|
email:
|
|
58
|
-
-
|
|
60
|
+
- duchoang.vp@gmail.com
|
|
59
61
|
executables: []
|
|
60
62
|
extensions: []
|
|
61
63
|
extra_rdoc_files: []
|
|
@@ -63,17 +65,30 @@ files:
|
|
|
63
65
|
- LICENSE.txt
|
|
64
66
|
- README.md
|
|
65
67
|
- lib/appom.rb
|
|
68
|
+
- lib/appom/configuration.rb
|
|
66
69
|
- lib/appom/cucumber.rb
|
|
70
|
+
- lib/appom/element_cache.rb
|
|
67
71
|
- lib/appom/element_container.rb
|
|
68
72
|
- lib/appom/element_finder.rb
|
|
73
|
+
- lib/appom/element_state.rb
|
|
74
|
+
- lib/appom/element_validation.rb
|
|
75
|
+
- lib/appom/exceptions.rb
|
|
76
|
+
- lib/appom/helpers.rb
|
|
77
|
+
- lib/appom/logging.rb
|
|
69
78
|
- lib/appom/page.rb
|
|
79
|
+
- lib/appom/performance.rb
|
|
80
|
+
- lib/appom/retry.rb
|
|
81
|
+
- lib/appom/screenshot.rb
|
|
70
82
|
- lib/appom/section.rb
|
|
83
|
+
- lib/appom/smart_wait.rb
|
|
71
84
|
- lib/appom/version.rb
|
|
85
|
+
- lib/appom/visual.rb
|
|
72
86
|
- lib/appom/wait.rb
|
|
73
87
|
homepage: https://github.com/hoangtaiki/appom
|
|
74
88
|
licenses:
|
|
75
89
|
- MIT
|
|
76
|
-
metadata:
|
|
90
|
+
metadata:
|
|
91
|
+
rubygems_mfa_required: 'true'
|
|
77
92
|
post_install_message:
|
|
78
93
|
rdoc_options: []
|
|
79
94
|
require_paths:
|
|
@@ -82,15 +97,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
82
97
|
requirements:
|
|
83
98
|
- - ">="
|
|
84
99
|
- !ruby/object:Gem::Version
|
|
85
|
-
version: 2.2
|
|
100
|
+
version: 3.2.2
|
|
86
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
102
|
requirements:
|
|
88
103
|
- - ">="
|
|
89
104
|
- !ruby/object:Gem::Version
|
|
90
105
|
version: '0'
|
|
91
106
|
requirements: []
|
|
92
|
-
rubygems_version: 3.
|
|
107
|
+
rubygems_version: 3.4.10
|
|
93
108
|
signing_key:
|
|
94
109
|
specification_version: 4
|
|
95
|
-
summary: A Page Object Model for Appium
|
|
110
|
+
summary: A comprehensive Page Object Model framework for Appium with advanced testing
|
|
111
|
+
capabilities
|
|
96
112
|
test_files: []
|