percy-appium-app 0.0.1 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba54dc346521591705be68354e98b25018a98a1af988b9d05c7b3e6d6120b92f
4
- data.tar.gz: 5fe4abc08f138a09c1f5c95f327f9bebb8c9d4f7899cd0ffbe233d2d95cb5e86
3
+ metadata.gz: 3a9d215b1a1e9daf04d5672a65a909db34bf2f9118e7551a72a83ba742e3dcbf
4
+ data.tar.gz: d5bd4454dbb19e0f649025ebb21692a847b1e6f14a4bf85f67c16749ff462349
5
5
  SHA512:
6
- metadata.gz: 5434a1ce14329a48bf5411050de8c466ec40e77f3545fa159d566d077d28d88ce027a7ed87ea3a3cf0cc6a851350376a7218d93e6250de93cc165e5ba6179196
7
- data.tar.gz: 2a8f9febe81d0490ed25d4f8bca3a2b24851a62d5c51ea33527629e72e810de9a4e0e94593f88727ffe42c25237c43aab785529d1e7bb4d24b5fd81488fedd8e
6
+ metadata.gz: 10f4a8d07bdc08deb1068025032f05cedacd3959244a1fbd5465ce9ed2eac0a502ab629abeb3087849ad62d9edf874dc298b49a8e14c9c2e36b2b4da71d9f1f6
7
+ data.tar.gz: ef3897862dacf57e5b64b8026a0272415b7ea47a09cdd80e83bc8bcc51d7be02dc4243b4b3e99f268a841934b0131112d37610abef8c5801b21e0e208eb17c8d
data/README.md CHANGED
@@ -1 +1,191 @@
1
- # percy-appium-ruby
1
+ # percy-appium-ruby
2
+
3
+ [Percy](https://percy.io) visual testing for Ruby Appium.
4
+
5
+ ## Installation
6
+
7
+ npm install `@percy/cli`:
8
+
9
+ ```sh-session
10
+ $ npm install --save-dev @percy/cli
11
+ ```
12
+
13
+ gem install Percy appium package:
14
+
15
+ ```ssh-session
16
+ $ gem install percy-appium-app
17
+ ```
18
+
19
+
20
+ ## Usage
21
+
22
+ This is an example test using the `percy_screenshot` function.
23
+
24
+ ``` ruby
25
+ require 'appium_lib'
26
+ require 'percy-appium-app'
27
+
28
+ username = '<BROWSERSTACK_USERNAME>'
29
+ access_key = '<ACCESS_KEY>'
30
+
31
+ capabilities = {
32
+ 'platformName' => 'android',
33
+ 'platformVersion' => '13.0',
34
+ 'deviceName' => 'Google Pixel 7',
35
+ 'bstack:options' => {
36
+ 'appiumVersion' => '2.0.1'
37
+ },
38
+ 'app' => '<APP LINK>',
39
+ 'appium:percyOptions' => {
40
+ # enabled is default True. This can be used to disable visual testing for certain capabilities
41
+ 'enabled' => true
42
+ }
43
+ }
44
+
45
+ appium_driver = Appium::Driver.new(
46
+ {
47
+ 'caps' => capabilities,
48
+ 'appium_lib' => {
49
+ server_url: "https://#{username}:#{access_key}@hub-cloud.browserstack.com/wd/hub"
50
+ }
51
+ }, true
52
+ )
53
+ driver = appium_driver.start_driver
54
+
55
+ # take a screenshot
56
+ percy_screenshot(driver, 'here is some name')
57
+ ```
58
+
59
+ Running the test above normally will result in the following log:
60
+
61
+ ```sh-session
62
+ [percy] Percy is not running, disabling screenshots
63
+ ```
64
+
65
+ When running with [`percy
66
+ app:exec`](https://github.com/percy/cli/tree/master/packages/cli-exec#app-exec), and your project's
67
+ `PERCY_TOKEN`, a new Percy build will be created and screenshots will be uploaded to your project.
68
+
69
+ ```sh-session
70
+ $ export PERCY_TOKEN=[your-project-token]
71
+ $ percy app:exec -- [ruby test command]
72
+ [percy] Percy has started!
73
+ [percy] Created build #1: https://percy.io/[your-project]
74
+ [percy] Screenshot taken "Ruby example"
75
+ [percy] Stopping percy...
76
+ [percy] Finalized build #1: https://percy.io/[your-project]
77
+ [percy] Done!
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ `percy_screenshot(driver, name[, **kwargs])`
83
+
84
+ - `driver` (**required**) - A appium driver instance
85
+ - `name` (**required**) - The screenshot name; must be unique to each screenshot
86
+ - `device_name` (**optional**) - The device name used for capturing screenshot
87
+ - `orientation` (**optional**) - Orientation of device while capturing screeenshot; Allowed values [`portrait` | `landscape`]
88
+ - `status_bar_height` (**optional**) - Height of status bar; int
89
+ - `nav_bar_height` (**optional**) - Height of navigation bar; int
90
+ - `fullpage` (**optional**) - [Alpha] Only supported on App Automate driver sessions [ needs @percy/cli 1.20.2+ ]; boolean
91
+ - `screen_lengths` (**optional**) - [Alpha] Max screen lengths for fullPage; int
92
+ - In case scrollview is overlapping with other app elements. Offsets can be provided to reduce the area which needs to be considered for scrolling:
93
+ - `top_scrollview_offset`: (**optional**) - [Alpha] Offset from top of scrollview; int
94
+ - `bottom_scrollview_offset` (**optional**) - [Alpha] Offset from bottom of scrollview; int
95
+ - `full_screen` (**optional**) - Indicate whether app is full screen; boolean [ needs @percy/cli 1.20.2+ ];
96
+ - `scrollable_xpath` (**optional**) - [Alpha] Scrollable element xpath for fullpage [ needs @percy/cli 1.20.2+ ]; string
97
+ - `scrollable_id` (**optional**) - [Alpha] Scrollable element accessibility id for fullpage [ needs @percy/cli 1.20.2+ ]; string
98
+ - `ignore_regions_xpaths` (**optional**) - Elements xpaths that user want to ignore in visual diff [ needs @percy/cli 1.23.0+ ]; list of string
99
+ - `ignore_region_accessibility_ids` (**optional**) - Elements accessibility_ids that user want to ignore in visual diff [ needs @percy/cli 1.23.0+ ]; list of string
100
+ - `ignore_region_appium_elements` (**optional**) - Appium elements that user want to ignore in visual diff [ needs @percy/cli 1.23.0+ ]; list of appium element object
101
+ - `custom_ignore_regions` (**optional**) - Custom locations that user want to ignore in visual diff [ needs @percy/cli 1.23.0+ ]; list of ignore_region object
102
+ - IgnoreRegion:-
103
+ - Description: This class represents a rectangular area on a screen that needs to be ignored for visual diff.
104
+ - Constructor:
105
+ ```
106
+ init(self, top, bottom, left, right)
107
+ ```
108
+ - Parameters:
109
+ - `top` (int): Top coordinate of the ignore region.
110
+ - `bottom` (int): Bottom coordinate of the ignore region.
111
+ - `left` (int): Left coordinate of the ignore region.
112
+ - `right` (int): Right coordinate of the ignore region.
113
+
114
+ ## Running with Hybrid Apps
115
+
116
+ For a hybrid app, we need to switch to native context before taking screenshot.
117
+
118
+ - Add a helper method similar to following for say flutter based hybrid app:
119
+ ```ruby
120
+ def percy_screenshot_flutter(driver, name: str, **kwargs):
121
+ driver.switch_to.context('NATIVE_APP')
122
+ percy_screenshot(driver, name, **kwargs)
123
+ driver.switch_to.context('FLUTTER')
124
+ end
125
+ ```
126
+
127
+ - Call PercyScreenshotFlutter helper function when you want to take screenshot.
128
+ ```ruby
129
+ percy_screenshot_flutter(driver, name, **kwargs)
130
+ ```
131
+
132
+ > Note:
133
+ >
134
+ > For other hybrid apps the `driver.switch_to.context('FLUTTER')` would change to context that it uses like say WEBVIEW etc.
135
+ >
136
+
137
+ ## Running Percy on Automate
138
+ `percy_screenshot(driver, name, options)` [ needs @percy/cli 1.27.0-beta.0+ ];
139
+ - `driver` (**required**) - A appium driver instance
140
+ - `name` (**required**) - The screenshot name; must be unique to each screenshot
141
+ - `options` (**optional**) - There are various options supported by percy_screenshot to server further functionality.
142
+ - `freeze_animated_image` - Boolean value by default it falls back to `false`, you can pass `true` and percy will freeze image based animations.
143
+ - `freeze_image_by_selectors` -List of selectors. Images will be freezed which are passed using selectors. For this to work `freeze_animated_image` must be set to true.
144
+ - `freeze_image_by_xpaths` - List of xpaths. Images will be freezed which are passed using xpaths. For this to work `freeze_animated_image` must be set to true.
145
+ - `percy_css` - Custom CSS to be added to DOM before the screenshot being taken. Note: This gets removed once the screenshot is taken.
146
+ - `ignore_region_xpaths` - List of xpaths. elements in the DOM can be ignored using xpath
147
+ - `ignore_region_selectors` - List of selectors. elements in the DOM can be ignored using selectors.
148
+ - `ignore_region_appium_elements` - List of appium web-element. elements can be ignored using appium_elements.
149
+ - `custom_ignore_regions` - List of custom objects. elements can be ignored using custom boundaries. Just passing a simple object for it like below.
150
+ - example: ```{"top": 10, "right": 10, "bottom": 120, "left": 10}```
151
+ - In above example it will draw rectangle of ignore region as per given coordinates.
152
+ - `top` (int): Top coordinate of the ignore region.
153
+ - `bottom` (int): Bottom coordinate of the ignore region.
154
+ - `left` (int): Left coordinate of the ignore region.
155
+ - `right` (int): Right coordinate of the ignore region.
156
+ - `consider_region_xpaths` - List of xpaths. elements in the DOM can be considered for diffing and will be ignored by Intelli Ignore using xpaths.
157
+ - `consider_region_selectors` - List of selectors. elements in the DOM can be considered for diffing and will be ignored by Intelli Ignore using selectors.
158
+ - `consider_region_appium_elements` - List of appium web-element. elements can be considered for diffing and will be ignored by Intelli Ignore using appium_elements.
159
+ - `custom_consider_regions` - List of custom objects. elements can be considered for diffing and will be ignored by Intelli Ignore using custom boundaries
160
+ - example:```{"top": 10, "right": 10, "bottom": 120, "left": 10}```
161
+ - In above example it will draw rectangle of consider region will be drawn.
162
+ - Parameters:
163
+ - `top` (int): Top coordinate of the consider region.
164
+ - `bottom` (int): Bottom coordinate of the consider region.
165
+ - `left` (int): Left coordinate of the consider region.
166
+ - `right` (int): Right coordinate of the consider region.
167
+
168
+ ### Creating Percy on automate build
169
+ Note: Automate Percy Token starts with `auto` keyword. The command can be triggered using `exec` keyword.
170
+
171
+ ```sh-session
172
+ $ export PERCY_TOKEN=[your-project-token]
173
+ $ percy exec -- [ruby test command]
174
+ [percy] Percy has started!
175
+ [percy] [Ruby example] : Starting automate screenshot ...
176
+ [percy] Screenshot taken "Ruby example"
177
+ [percy] Stopping percy...
178
+ [percy] Finalized build #1: https://percy.io/[your-project]
179
+ [percy] Done!
180
+ ```
181
+
182
+ Refer to docs here: [Percy on Automate](https://docs.percy.io/docs/integrate-functional-testing-with-visual-testing)
183
+
184
+ ### Migrating Config
185
+
186
+ If you have a previous Percy configuration file, migrate it to the newest version with the
187
+ [`config:migrate`](https://github.com/percy/cli/tree/master/packages/cli-config#percy-configmigrate-filepath-output) command:
188
+
189
+ ```sh-session
190
+ $ percy config:migrate
191
+ ```
data/percy/environment.rb CHANGED
@@ -4,22 +4,24 @@ require 'appium_lib'
4
4
  require 'appium_lib/version'
5
5
  require_relative 'version'
6
6
 
7
- class Environment
8
- @percy_build_id = nil
9
- @percy_build_url = nil
10
- @session_type = nil
7
+ module Percy
8
+ class Percy::Environment
9
+ @percy_build_id = nil
10
+ @percy_build_url = nil
11
+ @session_type = nil
11
12
 
12
- class << self
13
- attr_accessor :percy_build_id, :percy_build_url, :session_type
13
+ class << self
14
+ attr_accessor :percy_build_id, :percy_build_url, :session_type
14
15
 
15
- def get_client_info(flag = false)
16
- sdk_version = SDK_VERSION
17
- flag ? "percy-appium-app-ruby/#{sdk_version}" : "percy-appium-app/#{sdk_version}"
18
- end
16
+ def get_client_info(flag = false)
17
+ sdk_version = Percy::VERSION
18
+ flag ? "percy-appium-app-ruby/#{sdk_version}" : "percy-appium-app/#{sdk_version}"
19
+ end
19
20
 
20
- def get_env_info
21
- appium_version = Appium::VERSION # This assumes the 'appium_lib' gem provides a VERSION constant.
22
- ["appium/#{appium_version}", "ruby/#{RUBY_VERSION}"]
21
+ def get_env_info
22
+ appium_version = Appium::VERSION # This assumes the 'appium_lib' gem provides a VERSION constant.
23
+ ["appium/#{appium_version}", "ruby/#{RUBY_VERSION}"]
24
+ end
23
25
  end
24
26
  end
25
27
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  class BaseException < StandardError; end
4
2
 
5
3
  class UnsupportedDevice < BaseException; end
@@ -6,50 +6,52 @@ require_relative 'percy_options'
6
6
  require_relative '../providers/provider_resolver'
7
7
  require_relative '../metadata/metadata_resolver'
8
8
 
9
- class AppPercy
10
- attr_accessor :metadata, :provider
9
+ module Percy
10
+ class AppPercy
11
+ attr_accessor :metadata, :provider
11
12
 
12
- def initialize(driver)
13
- raise DriverNotSupported unless driver.is_a?(Appium::Core::Base::Driver)
13
+ def initialize(driver)
14
+ raise DriverNotSupported unless driver.is_a?(Appium::Core::Base::Driver)
14
15
 
15
- @driver = driver
16
- @metadata = MetadataResolver.resolve(@driver)
17
- @provider = ProviderResolver.resolve(@driver)
18
- @percy_options = PercyOptions.new(@metadata.capabilities)
19
- end
16
+ @driver = driver
17
+ @metadata = Percy::MetadataResolver.resolve(@driver)
18
+ @provider = Percy::ProviderResolver.resolve(@driver)
19
+ @percy_options = Percy::PercyOptions.new(@metadata.capabilities)
20
+ end
20
21
 
21
- def screenshot(name, **kwargs)
22
- return nil unless @percy_options.enabled
22
+ def screenshot(name, **kwargs)
23
+ return nil unless @percy_options.enabled
23
24
 
24
- raise TypeError, 'Argument name should be a String' unless name.is_a?(String)
25
+ raise TypeError, 'Argument name should be a String' unless name.is_a?(String)
25
26
 
26
- device_name = kwargs[:device_name]
27
- raise TypeError, 'Argument device_name should be a String' if device_name && !device_name.is_a?(String)
27
+ device_name = kwargs[:device_name]
28
+ raise TypeError, 'Argument device_name should be a String' if device_name && !device_name.is_a?(String)
28
29
 
29
- fullscreen = kwargs[:full_screen]
30
- if fullscreen && !fullscreen.is_a?(TrueClass) && !fullscreen.is_a?(FalseClass)
31
- raise TypeError,
32
- 'Argument fullscreen should be a Boolean'
33
- end
30
+ fullscreen = kwargs[:full_screen]
31
+ if fullscreen && !fullscreen.is_a?(TrueClass) && !fullscreen.is_a?(FalseClass)
32
+ raise TypeError,
33
+ 'Argument fullscreen should be a Boolean'
34
+ end
34
35
 
35
- status_bar_height = kwargs[:status_bar_height]
36
- if status_bar_height && !status_bar_height.is_a?(Integer)
37
- raise TypeError,
38
- 'Argument status_bar_height should be an Integer'
39
- end
36
+ status_bar_height = kwargs[:status_bar_height]
37
+ if status_bar_height && !status_bar_height.is_a?(Integer)
38
+ raise TypeError,
39
+ 'Argument status_bar_height should be an Integer'
40
+ end
41
+
42
+ nav_bar_height = kwargs[:nav_bar_height]
43
+ raise TypeError, 'Argument nav_bar_height should be an Integer' if nav_bar_height && !nav_bar_height.is_a?(Integer)
40
44
 
41
- nav_bar_height = kwargs[:nav_bar_height]
42
- raise TypeError, 'Argument nav_bar_height should be an Integer' if nav_bar_height && !nav_bar_height.is_a?(Integer)
45
+ orientation = kwargs[:orientation]
46
+ if orientation && !orientation.is_a?(String)
47
+ raise TypeError,
48
+ 'Argument orientation should be a String and portrait/landscape'
49
+ end
43
50
 
44
- orientation = kwargs[:orientation]
45
- if orientation && !orientation.is_a?(String)
46
- raise TypeError,
47
- 'Argument orientation should be a String and portrait/landscape'
51
+ @provider.screenshot(name, **kwargs)
52
+ nil
48
53
  end
49
54
 
50
- @provider.screenshot(name, **kwargs)
51
- nil
55
+ attr_reader :percy_options
52
56
  end
53
-
54
- attr_reader :percy_options
55
57
  end
data/percy/lib/cache.rb CHANGED
@@ -1,53 +1,54 @@
1
1
  # frozen_string_literal: true
2
+ module Percy
3
+ class Cache
4
+ attr_reader :cache
5
+
6
+ @@cache = {}
7
+ CACHE_TIMEOUT = 5 * 60 # 5 * 60 seconds
8
+ TIMEOUT_KEY = 'last_access_time'
9
+
10
+ SESSION_DETAILS = 'session_details'
11
+ SYSTEM_BARS = 'system_bars'
12
+ WINDOW_SIZE = 'window_size'
13
+ VIEWPORT = 'viewport'
14
+ SESSION_CAPABILITIES = 'session_capabilities'
15
+ CAPABILITIES = 'capabilities'
16
+ COMMAND_EXECUTOR_URL = 'command_executor_url'
17
+
18
+ def cache
19
+ @@cache
20
+ end
2
21
 
3
- class Cache
4
- attr_reader :cache
5
-
6
- @@cache = {}
7
- CACHE_TIMEOUT = 5 * 60 # 5 * 60 seconds
8
- TIMEOUT_KEY = 'last_access_time'
9
-
10
- SESSION_DETAILS = 'session_details'
11
- SYSTEM_BARS = 'system_bars'
12
- WINDOW_SIZE = 'window_size'
13
- VIEWPORT = 'viewport'
14
- SESSION_CAPABILITIES = 'session_capabilities'
15
- CAPABILITIES = 'capabilities'
16
- COMMAND_EXECUTOR_URL = 'command_executor_url'
17
-
18
- def cache
19
- @@cache
20
- end
22
+ def self.set_cache(session_id, property, value)
23
+ raise TypeError, 'Argument session_id should be a String' unless session_id.is_a?(String)
24
+ raise TypeError, 'Argument property should be a String' unless property.is_a?(String)
21
25
 
22
- def self.set_cache(session_id, property, value)
23
- raise TypeError, 'Argument session_id should be a String' unless session_id.is_a?(String)
24
- raise TypeError, 'Argument property should be a String' unless property.is_a?(String)
26
+ session = @@cache.fetch(session_id, {})
27
+ session[TIMEOUT_KEY] = Time.now.to_i
28
+ session[property] = value
29
+ @@cache[session_id] = session
30
+ end
25
31
 
26
- session = @@cache.fetch(session_id, {})
27
- session[TIMEOUT_KEY] = Time.now.to_i
28
- session[property] = value
29
- @@cache[session_id] = session
30
- end
32
+ def self.get_cache(session_id, property)
33
+ cleanup_cache
31
34
 
32
- def self.get_cache(session_id, property)
33
- cleanup_cache
35
+ raise TypeError, 'Argument session_id should be a String' unless session_id.is_a?(String)
36
+ raise TypeError, 'Argument property should be a String' unless property.is_a?(String)
34
37
 
35
- raise TypeError, 'Argument session_id should be a String' unless session_id.is_a?(String)
36
- raise TypeError, 'Argument property should be a String' unless property.is_a?(String)
38
+ session = @@cache.fetch(session_id, {})
39
+ session.fetch(property, nil)
40
+ end
37
41
 
38
- session = @@cache.fetch(session_id, {})
39
- session.fetch(property, nil)
40
- end
42
+ def self.cleanup_cache
43
+ now = Time.now.to_i
44
+ session_ids = []
41
45
 
42
- def self.cleanup_cache
43
- now = Time.now.to_i
44
- session_ids = []
46
+ @@cache.each do |session_id, session|
47
+ timestamp = session[TIMEOUT_KEY]
48
+ session_ids << session_id if now - timestamp >= CACHE_TIMEOUT
49
+ end
45
50
 
46
- @@cache.each do |session_id, session|
47
- timestamp = session[TIMEOUT_KEY]
48
- session_ids << session_id if now - timestamp >= CACHE_TIMEOUT
51
+ session_ids.each { |session_id| @@cache.delete(session_id) }
49
52
  end
50
-
51
- session_ids.each { |session_id| @@cache.delete(session_id) }
52
53
  end
53
54
  end
@@ -9,124 +9,126 @@ require_relative '../exceptions/exceptions'
9
9
  require_relative '../version'
10
10
  require_relative '../environment'
11
11
 
12
- CLIENT_INFO = "percy-appium-app/#{SDK_VERSION}"
13
- ENV_INFO = ["appium/#{Appium::VERSION}", "ruby/#{RUBY_VERSION}"].freeze
12
+ module Percy
13
+ CLIENT_INFO = "percy-appium-app/#{VERSION}"
14
+ ENV_INFO = ["appium/#{Appium::VERSION}", "ruby/#{RUBY_VERSION}"].freeze
14
15
 
15
- PERCY_CLI_API = ENV['PERCY_CLI_API'] || 'http://localhost:5338'
16
+ PERCY_CLI_API = ENV['PERCY_CLI_API'] || 'http://localhost:5338'
16
17
 
17
- class CLIWrapper
18
- def initialize; end
18
+ class CLIWrapper
19
+ def initialize; end
19
20
 
20
- def self.percy_enabled?
21
- @percy_enabled ||= begin
22
- uri = URI("#{PERCY_CLI_API}/percy/healthcheck")
23
- response = Net::HTTP.get_response(uri)
21
+ def self.percy_enabled?
22
+ @percy_enabled ||= begin
23
+ uri = URI("#{PERCY_CLI_API}/percy/healthcheck")
24
+ response = Net::HTTP.get_response(uri)
24
25
 
25
- raise CLIException, response.body unless response.is_a?(Net::HTTPSuccess)
26
+ raise CLIException, response.body unless response.is_a?(Net::HTTPSuccess)
26
27
 
27
- data = JSON.parse(response.body)
28
- raise CLIException, data['error'] unless data['success']
28
+ data = JSON.parse(response.body)
29
+ raise CLIException, data['error'] unless data['success']
30
+
31
+ Percy::Environment.percy_build_id = data['build']['id']
32
+ Percy::Environment.percy_build_url = data['build']['url']
33
+ Percy::Environment.session_type = data.fetch('type', nil)
29
34
 
30
- Environment.percy_build_id = data['build']['id']
31
- Environment.percy_build_url = data['build']['url']
32
- Environment.session_type = data.fetch('type', nil)
35
+ version = response['x-percy-core-version']
36
+ if version.split('.')[0] != '1'
37
+ log("Unsupported Percy CLI version, #{version}")
38
+ return false
39
+ end
40
+ return true unless version.split('.')[1].to_i < 27
33
41
 
34
- version = response['x-percy-core-version']
35
- if version.split('.')[0] != '1'
36
- log("Unsupported Percy CLI version, #{version}")
42
+ log('Please upgrade to the latest CLI version for using this SDK. Minimum compatible version is 1.27.0-beta.0')
43
+ return false
44
+ rescue StandardError => e
45
+ log('Percy is not running, disabling screenshots')
46
+ log(e, on_debug: true)
37
47
  return false
38
48
  end
39
- return true unless version.split('.')[1].to_i < 27
40
-
41
- log('Please upgrade to the latest CLI version for using this SDK. Minimum compatible version is 1.27.0-beta.0')
42
- return false
43
- rescue StandardError => e
44
- log('Percy is not running, disabling screenshots')
45
- log(e, on_debug: true)
46
- return false
47
49
  end
48
- end
49
50
 
50
- def post_screenshots(name, tag, tiles, external_debug_url = nil, ignored_elements_data = nil,
51
- considered_elements_data = nil)
52
- body = request_body(name, tag, tiles, external_debug_url, ignored_elements_data, considered_elements_data)
53
- body['client_info'] = Environment.get_client_info
54
- body['environment_info'] = Environment.get_env_info
51
+ def post_screenshots(name, tag, tiles, external_debug_url = nil, ignored_elements_data = nil,
52
+ considered_elements_data = nil)
53
+ body = request_body(name, tag, tiles, external_debug_url, ignored_elements_data, considered_elements_data)
54
+ body['client_info'] = Percy::Environment.get_client_info
55
+ body['environment_info'] = Percy::Environment.get_env_info
55
56
 
56
- uri = URI("#{PERCY_CLI_API}/percy/comparison")
57
- http = Net::HTTP.new(uri.host, uri.port)
58
- request = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
59
- request.body = body.to_json
57
+ uri = URI("#{PERCY_CLI_API}/percy/comparison")
58
+ http = Net::HTTP.new(uri.host, uri.port)
59
+ request = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
60
+ request.body = body.to_json
60
61
 
61
- response = http.request(request)
62
- data = JSON.parse(response.body)
62
+ response = http.request(request)
63
+ data = JSON.parse(response.body)
63
64
 
64
- raise CLIException, data.fetch('error', 'UnknownException') if response.code != '200'
65
+ raise CLIException, data.fetch('error', 'UnknownException') if response.code != '200'
65
66
 
66
- data
67
- end
68
-
69
- def self.post_failed_event(error)
70
- body = {
71
- 'clientInfo' => Environment.get_client_info(true),
72
- 'message' => error,
73
- 'errorKind' => 'sdk'
74
- }
67
+ data
68
+ end
75
69
 
76
- uri = URI("#{PERCY_CLI_API}/percy/events")
77
- response = Net::HTTP.post(uri, body.to_json, 'Content-Type' => 'application/json')
70
+ def self.post_failed_event(error)
71
+ body = {
72
+ 'clientInfo' => Percy::Environment.get_client_info(true),
73
+ 'message' => error,
74
+ 'errorKind' => 'sdk'
75
+ }
76
+
77
+ uri = URI("#{PERCY_CLI_API}/percy/events")
78
+ response = Net::HTTP.post(uri, body.to_json, 'Content-Type' => 'application/json')
79
+
80
+ # Handle errors
81
+ if response.code.to_i != 200
82
+ data = JSON.parse(response.body)
83
+ error_message = data.fetch('error', 'UnknownException')
84
+ raise CLIException, error_message
85
+ end
78
86
 
79
- # Handle errors
80
- if response.code.to_i != 200
81
- data = JSON.parse(response.body)
82
- error_message = data.fetch('error', 'UnknownException')
83
- raise CLIException, error_message
87
+ JSON.parse(response.body)
88
+ rescue StandardError => e
89
+ log(e.message, on_debug: true)
90
+ nil
84
91
  end
85
92
 
86
- JSON.parse(response.body)
87
- rescue StandardError => e
88
- log(e.message, on_debug: true)
89
- nil
90
- end
93
+ def post_poa_screenshots(name, session_id, command_executor_url, capabilities, desired_capabilities, options = nil)
94
+ body = {
95
+ 'sessionId' => session_id,
96
+ 'commandExecutorUrl' => command_executor_url,
97
+ 'capabilities' => capabilities.dup, # In Ruby, you can duplicate the hash with `dup`
98
+ 'sessionCapabilities' => desired_capabilities.dup,
99
+ 'snapshotName' => name,
100
+ 'options' => options
101
+ }
91
102
 
92
- def post_poa_screenshots(name, session_id, command_executor_url, capabilities, desired_capabilities, options = nil)
93
- body = {
94
- 'sessionId' => session_id,
95
- 'commandExecutorUrl' => command_executor_url,
96
- 'capabilities' => capabilities.dup, # In Ruby, you can duplicate the hash with `dup`
97
- 'sessionCapabilities' => desired_capabilities.dup,
98
- 'snapshotName' => name,
99
- 'options' => options
100
- }
103
+ body['client_info'] = Percy::Environment.get_client_info # Using class method without the underscore
104
+ body['environment_info'] = Percy::Environment.get_env_info
101
105
 
102
- body['client_info'] = Environment.get_client_info # Using class method without the underscore
103
- body['environment_info'] = Environment.get_env_info
106
+ uri = URI("#{PERCY_CLI_API}/percy/automateScreenshot")
107
+ response = Net::HTTP.post(uri, body.to_json, 'Content-Type' => 'application/json')
104
108
 
105
- uri = URI("#{PERCY_CLI_API}/percy/automateScreenshot")
106
- response = Net::HTTP.post(uri, body.to_json, 'Content-Type' => 'application/json')
109
+ # Handle errors
110
+ raise CLIException, "Error: #{response.message}" unless response.is_a?(Net::HTTPSuccess)
107
111
 
108
- # Handle errors
109
- raise CLIException, "Error: #{response.message}" unless response.is_a?(Net::HTTPSuccess)
112
+ data = JSON.parse(response.body)
110
113
 
111
- data = JSON.parse(response.body)
114
+ if response.code != '200'
115
+ error_message = data.fetch('error', 'UnknownException')
116
+ raise CLIException, error_message
117
+ end
112
118
 
113
- if response.code != '200'
114
- error_message = data.fetch('error', 'UnknownException')
115
- raise CLIException, error_message
119
+ data
116
120
  end
117
121
 
118
- data
119
- end
120
-
121
- def request_body(name, tag, tiles, external_debug_url, ignored_elements_data, considered_elements_data)
122
- tiles = tiles.map(&:to_h)
123
- {
124
- 'name' => name,
125
- 'tag' => tag,
126
- 'tiles' => tiles,
127
- 'ignored_elements_data' => ignored_elements_data,
128
- 'external_debug_url' => external_debug_url,
129
- 'considered_elements_data' => considered_elements_data
130
- }
122
+ def request_body(name, tag, tiles, external_debug_url, ignored_elements_data, considered_elements_data)
123
+ tiles = tiles.map(&:to_h)
124
+ {
125
+ 'name' => name,
126
+ 'tag' => tag,
127
+ 'tiles' => tiles,
128
+ 'ignored_elements_data' => ignored_elements_data,
129
+ 'external_debug_url' => external_debug_url,
130
+ 'considered_elements_data' => considered_elements_data
131
+ }
132
+ end
131
133
  end
132
134
  end