eyes_core 3.14.0 → 3.14.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/applitools/calabash/calabash_element.rb +62 -0
- data/lib/applitools/calabash/calabash_screenshot_provider.rb +81 -0
- data/lib/applitools/calabash/environment_detector.rb +23 -0
- data/lib/applitools/calabash/eyes.rb +182 -0
- data/lib/applitools/calabash/eyes_calabash_android_screenshot.rb +56 -0
- data/lib/applitools/calabash/eyes_calabash_ios_screenshot.rb +28 -0
- data/lib/applitools/calabash/eyes_calabash_screenshot.rb +78 -0
- data/lib/applitools/calabash/eyes_hooks.rb +51 -0
- data/lib/applitools/calabash/eyes_settings.rb +43 -0
- data/lib/applitools/calabash/full_page_capture_algorithm.rb +24 -0
- data/lib/applitools/calabash/full_page_capture_algorithm/android_scroll_view.rb +85 -0
- data/lib/applitools/calabash/full_page_capture_algorithm/base.rb +49 -0
- data/lib/applitools/calabash/full_page_capture_algorithm/ios_ui_table_view.rb +148 -0
- data/lib/applitools/calabash/os_versions.rb +23 -0
- data/lib/applitools/calabash/rspec_matchers.rb +22 -0
- data/lib/applitools/calabash/steps/android_eyes_session.rb +35 -0
- data/lib/applitools/calabash/steps/android_matchers.rb +34 -0
- data/lib/applitools/calabash/steps/eyes_session.rb +40 -0
- data/lib/applitools/calabash/steps/eyes_settings.rb +57 -0
- data/lib/applitools/calabash/steps/ios_eyes_session.rb +13 -0
- data/lib/applitools/calabash/steps/ios_matchers.rb +15 -0
- data/lib/applitools/calabash/steps/matchers.rb +69 -0
- data/lib/applitools/calabash/target.rb +67 -0
- data/lib/applitools/calabash/utils.rb +72 -0
- data/lib/applitools/calabash_steps.rb +14 -0
- data/lib/applitools/chunky_png_patch.rb +1 -0
- data/lib/applitools/connectivity/server_connector.rb +5 -4
- data/lib/applitools/core/abstract_region.rb +16 -0
- data/lib/applitools/core/class_name.rb +7 -0
- data/lib/applitools/core/eyes_base.rb +2 -0
- data/lib/applitools/core/floating_region.rb +17 -4
- data/lib/applitools/core/fluent_interface.rb +8 -0
- data/lib/applitools/core/location.rb +7 -0
- data/lib/applitools/core/match_window_data.rb +1 -1
- data/lib/applitools/core/rectangle_size.rb +8 -2
- data/lib/applitools/core/region.rb +9 -1
- data/lib/applitools/rspec/target_matcher.rb +23 -0
- data/lib/applitools/utils/eyes_selenium_utils.rb +0 -2
- data/lib/applitools/version.rb +1 -1
- metadata +30 -2
@@ -0,0 +1,23 @@
|
|
1
|
+
module Applitools
|
2
|
+
module Calabash
|
3
|
+
module OsVersions
|
4
|
+
module Android
|
5
|
+
extend self
|
6
|
+
API_TO_NAME = {
|
7
|
+
4 => 'Android 1',
|
8
|
+
10 => 'Android 2',
|
9
|
+
13 => 'Android 3',
|
10
|
+
20 => 'Android 4',
|
11
|
+
22 => 'Android 5',
|
12
|
+
23 => 'Android 6',
|
13
|
+
25 => 'Android 7',
|
14
|
+
27 => 'Android 8'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
def os_version(api_level)
|
18
|
+
API_TO_NAME[API_TO_NAME.keys.select { |v| api_level.to_i >= v }.last] || 'Android'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rspec/expectations'
|
2
|
+
|
3
|
+
RSpec::Matchers.define :match_baseline do |expected|
|
4
|
+
match do |actual|
|
5
|
+
result = Applitools::Calabash::EyesSettings.instance.eyes.check(expected, actual)
|
6
|
+
result.as_expected?
|
7
|
+
end
|
8
|
+
|
9
|
+
failure_message do |_actual|
|
10
|
+
"expected #{expected} to match a baseline"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec::Matchers.define :be_success do
|
15
|
+
match do |actual|
|
16
|
+
actual.as_expected? == true
|
17
|
+
end
|
18
|
+
|
19
|
+
failure_message do |actual|
|
20
|
+
"Expected eyes session to be successful, but mismatches occur. \n#{actual}"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Then(/^set OS$/) do
|
2
|
+
sdk_version = begin
|
3
|
+
perform_action('android_sdk_version')
|
4
|
+
rescue HTTPClient::KeepAliveDisconnected
|
5
|
+
reinstall_apps
|
6
|
+
start_test_server_in_background
|
7
|
+
perform_action('android_sdk_version')
|
8
|
+
end
|
9
|
+
if sdk_version['success']
|
10
|
+
Applitools::Calabash::EyesSettings.instance.eyes.host_os = Applitools::Calabash::OsVersions::Android.os_version(
|
11
|
+
sdk_version['message']
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Then(/^set device pixel ratio$/) do
|
17
|
+
display_info = `#{default_device.adb_command} shell dumpsys display`
|
18
|
+
# size_match = /deviceWidth=(?<width>\d+), deviceHeight=(?<height>\d+)/.match(display_info)
|
19
|
+
density_match = /DisplayDeviceInfo.*density (?<density>\d+)/.match(display_info)
|
20
|
+
Applitools::Calabash::EyesSettings.instance.eyes.device_pixel_ratio = density_match[:density].to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
Then(/^set device physical size$/) do
|
24
|
+
result = /mDefaultViewport=.*deviceWidth=(?<width>\d+).*deviceHeight=(?<height>\d+).*\n/.match(
|
25
|
+
`#{default_device.adb_command} shell dumpsys display |grep mDefaultViewport`
|
26
|
+
)
|
27
|
+
step %(eyes viewport size is "#{result[:width].to_i}x#{result[:height].to_i}")
|
28
|
+
end
|
29
|
+
|
30
|
+
Then(/^set device size$/) do
|
31
|
+
result = /^.*app=(?<width>\d+)x(?<height>\d+)/.match(
|
32
|
+
`#{default_device.adb_command} shell dumpsys window displays |grep cur | tr -d ' '`
|
33
|
+
)
|
34
|
+
step %(eyes viewport size is "#{result[:width].to_i}x#{result[:height].to_i}")
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Then(/^ignore status bar$/) do
|
2
|
+
raise Applitools::EyesError, '@target is not set' unless @target
|
3
|
+
step %(query element "view id:'statusBarBackground'")
|
4
|
+
@target.ignore @current_element if @current_element
|
5
|
+
end
|
6
|
+
|
7
|
+
Then(/^remove status bar$/) do
|
8
|
+
raise Applitools::EyesError, '@target is not set' unless @target
|
9
|
+
step %(query element "view id:'statusBarBackground'")
|
10
|
+
if @current_element
|
11
|
+
viewport_size = Applitools::RectangleSize.from_any_argument(
|
12
|
+
Applitools::Calabash::EyesSettings.instance.viewport_size
|
13
|
+
)
|
14
|
+
region_location = Applitools::Location.new(0, @current_element.size.height)
|
15
|
+
@target.region(Applitools::Region.from_location_size(region_location, viewport_size))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Then(/^the whole screen should match a baseline/) do
|
20
|
+
step %(create target)
|
21
|
+
step %(remove status bar)
|
22
|
+
step %(target should match a baseline)
|
23
|
+
end
|
24
|
+
|
25
|
+
Then(/^query element "([^"]*)" and take (\d+)$/) do |query, index|
|
26
|
+
@current_element = nil
|
27
|
+
@current_element = Applitools::Calabash::Utils.get_android_element(self, query, index)
|
28
|
+
end
|
29
|
+
|
30
|
+
Then(/^check for scrollable$/) do
|
31
|
+
unless query('ScrollView').empty?
|
32
|
+
@present_scrollable = Applitools::Calabash::Utils.get_android_element(self, 'ScrollView', 0)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Then(/^create eyes$/) do
|
2
|
+
eyes_settings = Applitools::Calabash::EyesSettings.instance
|
3
|
+
eyes_settings.eyes ||= Applitools::Calabash::Eyes.new.tap do |eyes|
|
4
|
+
eyes.api_key = eyes_settings.applitools_api_key
|
5
|
+
log_file_path = File.join(eyes_settings.log_prefix, eyes_settings.log_file)
|
6
|
+
eyes.log_handler = Logger.new(File.new(log_file_path, 'w+'))
|
7
|
+
end
|
8
|
+
|
9
|
+
unless eyes_settings.eyes.open?
|
10
|
+
step %(set batch "#{@before_hook_scenario.feature.name}")
|
11
|
+
step %(set OS)
|
12
|
+
step %(set device pixel ratio)
|
13
|
+
step %(set device size)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Then(/^open eyes$/) do
|
18
|
+
eyes_settings = Applitools::Calabash::EyesSettings.instance
|
19
|
+
eyes_settings.eyes.open eyes_settings.options_for_open unless eyes_settings.eyes.open?
|
20
|
+
end
|
21
|
+
|
22
|
+
When(/^I close eyes session$/) do
|
23
|
+
@test_result = Applitools::Calabash::EyesSettings.instance.eyes.close(false)
|
24
|
+
end
|
25
|
+
|
26
|
+
Then(/^test result should be positive$/) do
|
27
|
+
raise Applitools::EyesError, 'Test result are not present!' unless @test_result
|
28
|
+
expect(@test_result).to be_success
|
29
|
+
end
|
30
|
+
|
31
|
+
Then(/^applitools link should be reported$/) do
|
32
|
+
puts @test_result
|
33
|
+
end
|
34
|
+
|
35
|
+
Then(/^terminate eyes session$/) do
|
36
|
+
step %(I close eyes session)
|
37
|
+
step %(test result should be positive)
|
38
|
+
step %(applitools link should be reported)
|
39
|
+
@test_results = nil
|
40
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
Given(/^eyes application name is "([^"]*)"$/) do |name|
|
2
|
+
Applitools::Calabash::EyesSettings.instance.app_name = name
|
3
|
+
end
|
4
|
+
|
5
|
+
Given(/^eyes test name is "([^"]*)"$/) do |name|
|
6
|
+
Applitools::Calabash::EyesSettings.instance.test_name = name
|
7
|
+
end
|
8
|
+
|
9
|
+
Given(/^eyes viewport size is "([^"]*)"$/) do |size|
|
10
|
+
Applitools::Calabash::EyesSettings.instance.viewport_size = Applitools::RectangleSize.from_any_argument(size).to_h
|
11
|
+
end
|
12
|
+
|
13
|
+
Given(/^eyes API key "([^"]*)"$/) do |key|
|
14
|
+
Applitools::Calabash::EyesSettings.instance.applitools_api_key = key
|
15
|
+
end
|
16
|
+
|
17
|
+
Given(/^eyes tag is "([^"]*)"$/) do |tag|
|
18
|
+
@tag = tag
|
19
|
+
end
|
20
|
+
|
21
|
+
Given(/^set batch "([^"]*)"/) do |name|
|
22
|
+
@current_batch ||= Applitools::Calabash::EyesSettings.instance.eyes.batch.tap do |batch|
|
23
|
+
batch.name = name
|
24
|
+
end
|
25
|
+
|
26
|
+
Applitools::Calabash::EyesSettings.instance.eyes.batch = @current_batch
|
27
|
+
end
|
28
|
+
|
29
|
+
Given(/^calabash screenshot dir is "([^"]*)"$/) do |path|
|
30
|
+
Applitools::Calabash::EyesSettings.instance.screenshot_dir = path
|
31
|
+
end
|
32
|
+
|
33
|
+
Given(/^calabash temp dir is "([^"]*)"$/) do |path|
|
34
|
+
Applitools::Calabash::EyesSettings.instance.tmp_dir = path
|
35
|
+
end
|
36
|
+
|
37
|
+
Given(/^calabash log path is "([^"]*)"$/) do |path|
|
38
|
+
Applitools::Calabash::EyesSettings.instance.log_dir = path
|
39
|
+
end
|
40
|
+
|
41
|
+
Given(/^eyes logfile is "([^"]*)"$/) do |logfile_path|
|
42
|
+
Applitools::Calabash::EyesSettings.instance.log_file = logfile_path
|
43
|
+
end
|
44
|
+
|
45
|
+
Given(/^clear directories$/) do
|
46
|
+
Applitools::Calabash::Utils.clear_directories(Applitools::Calabash::EyesSettings.instance)
|
47
|
+
end
|
48
|
+
|
49
|
+
Given(/^create directories$/) do
|
50
|
+
Applitools::Calabash::Utils.create_directories(Applitools::Calabash::EyesSettings.instance)
|
51
|
+
end
|
52
|
+
|
53
|
+
Given(/^set it up$/) do
|
54
|
+
step %(clear directories)
|
55
|
+
step %(create directories)
|
56
|
+
Applitools::Calabash::EyesSettings.instance.needs_setting_up = false
|
57
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Then(/^set OS$/) do
|
2
|
+
Applitools::Calabash::EyesSettings.instance.eyes.host_os = "iOS #{default_device.ios_major_version}"
|
3
|
+
end
|
4
|
+
|
5
|
+
Then(/^set device pixel ratio$/) do
|
6
|
+
dimensions = default_device.screen_dimensions
|
7
|
+
Applitools::Calabash::EyesSettings.instance.eyes.device_pixel_ratio = dimensions[:scale] #:native_scale?
|
8
|
+
end
|
9
|
+
|
10
|
+
Then(/^set device size$/) do
|
11
|
+
dimensions = default_device.screen_dimensions
|
12
|
+
step %(eyes viewport size is "#{dimensions[:width].to_i}x#{dimensions[:height].to_i}")
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Then(/^the whole screen should match a baseline/) do
|
2
|
+
step %(create target)
|
3
|
+
step %(target should match a baseline)
|
4
|
+
end
|
5
|
+
|
6
|
+
Then(/^query element "([^"]*)" and take (\d+)$/) do |query, index|
|
7
|
+
@current_element = nil
|
8
|
+
@current_element = Applitools::Calabash::Utils.get_ios_element(self, query, index)
|
9
|
+
end
|
10
|
+
|
11
|
+
Then(/^check for scrollable$/) do
|
12
|
+
unless query('UIScrollView').empty?
|
13
|
+
@present_scrollable = Applitools::Calabash::Utils.get_ios_element(self, 'UIScrollView', 0)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
Then(/^create target$/) do
|
2
|
+
@target = nil
|
3
|
+
@target = Applitools::Calabash::Target.new
|
4
|
+
end
|
5
|
+
|
6
|
+
Then(/^target should match a baseline$/) do
|
7
|
+
raise Applitools::EyesError, '@target is not set' unless @target
|
8
|
+
@tag ||= ''
|
9
|
+
expect(@target).to match_baseline(@tag)
|
10
|
+
end
|
11
|
+
|
12
|
+
Then(/^the element "([^"]*)" should match a baseline$/) do |query|
|
13
|
+
step %(create target)
|
14
|
+
step %(query element "#{query}")
|
15
|
+
@target.region(@current_element) if @current_element
|
16
|
+
step %(target should match a baseline)
|
17
|
+
end
|
18
|
+
|
19
|
+
Then(/^the entire element "([^"]*)" should match a baseline$/) do |query|
|
20
|
+
step %(create target)
|
21
|
+
step %(query element "#{query}")
|
22
|
+
@target.region(@current_element).fully if @current_element
|
23
|
+
step %(target should match a baseline)
|
24
|
+
end
|
25
|
+
|
26
|
+
Then(/^query element "([^"]*)"$/) do |query|
|
27
|
+
step %(query element "#{query}" and take 0)
|
28
|
+
end
|
29
|
+
|
30
|
+
Then(/^I check viewport window$/) do
|
31
|
+
step %(the whole screen should match a baseline)
|
32
|
+
end
|
33
|
+
|
34
|
+
Then(/^I check viewport window with description "([^"]*)"$/) do |description|
|
35
|
+
step %(eyes tag is "#{description}")
|
36
|
+
step %(I check viewport window)
|
37
|
+
end
|
38
|
+
|
39
|
+
Then(/^I check window$/) do
|
40
|
+
step %(check for scrollable)
|
41
|
+
if @present_scrollable
|
42
|
+
step %(the entire element "#{@present_scrollable.element_query}" should match a baseline)
|
43
|
+
else
|
44
|
+
step %(I check viewport window)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Then(/^I check window with description "([^"]*)"$/) do |description|
|
49
|
+
step %(eyes tag is "#{description}")
|
50
|
+
step %(I check window)
|
51
|
+
end
|
52
|
+
|
53
|
+
Then(/^I check viewport element "([^"]*)"$/) do |selector|
|
54
|
+
step %(the element "#{selector}" should match a baseline)
|
55
|
+
end
|
56
|
+
|
57
|
+
Then(/^I check viewport element "([^"]*)" with description "([^"]*)"$/) do |selector, description|
|
58
|
+
step %(eyes tag is "#{description}")
|
59
|
+
step %(I check viewport element "#{selector}")
|
60
|
+
end
|
61
|
+
|
62
|
+
Then(/^I check element "([^"]*)"$/) do |selector|
|
63
|
+
step %(the entire element "#{selector}" should match a baseline)
|
64
|
+
end
|
65
|
+
|
66
|
+
Then(/^I check element "([^"]*)" with description "([^"]*)"$/) do |selector, description|
|
67
|
+
step %(eyes tag is "#{description}")
|
68
|
+
step %(I check element "#{selector}")
|
69
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Applitools
|
2
|
+
module Calabash
|
3
|
+
class Target
|
4
|
+
include Applitools::FluentInterface
|
5
|
+
|
6
|
+
attr_accessor :options, :ignored_regions, :region_to_check, :floating_regions
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
self.ignored_regions = []
|
10
|
+
self.floating_regions = []
|
11
|
+
self.options = {
|
12
|
+
trim: false
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def fully
|
17
|
+
options[:stitch_content] = true
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def ignore(region = nil)
|
22
|
+
if region
|
23
|
+
Applitools::ArgumentGuard.is_a? region, 'region', Applitools::Calabash::CalabashElement
|
24
|
+
ignored_regions << region.region
|
25
|
+
else
|
26
|
+
self.ignored_regions = []
|
27
|
+
end
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def region(region = nil)
|
32
|
+
if region
|
33
|
+
case region
|
34
|
+
when Applitools::Calabash::CalabashElement, Applitools::Region
|
35
|
+
self.region_to_check = region
|
36
|
+
else
|
37
|
+
self.region_to_check = nil
|
38
|
+
raise(
|
39
|
+
Applitools::EyesIllegalArgument,
|
40
|
+
'Expected region to be instance of Applitools::Calabash::CalabashElement or Applitools::Region'
|
41
|
+
)
|
42
|
+
end
|
43
|
+
else
|
44
|
+
self.region_to_check = nil
|
45
|
+
end
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
# def floating(*args)
|
50
|
+
# value = case args.first
|
51
|
+
# when Applitools::FloatingRegion
|
52
|
+
# proc { args.first.scale_it!(scale_factor) }
|
53
|
+
# when Applitools::Region
|
54
|
+
# proc do
|
55
|
+
# region = args.shift
|
56
|
+
# region.scale_it!(scale_factor)
|
57
|
+
# Applitools::FloatingRegion.new region.left, region.top, region.width, region.height, *args
|
58
|
+
# end
|
59
|
+
# else
|
60
|
+
# self.floating_regions = []
|
61
|
+
# end
|
62
|
+
# floating_regions << value
|
63
|
+
# self
|
64
|
+
# end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Applitools
|
2
|
+
module Calabash
|
3
|
+
module Utils
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def create_directories(eyes_settings)
|
7
|
+
FileUtils.mkpath(
|
8
|
+
File.join(Dir.getwd, eyes_settings.tmp_dir, eyes_settings.screenshot_dir)
|
9
|
+
)
|
10
|
+
FileUtils.mkpath(
|
11
|
+
File.join(Dir.getwd, eyes_settings.log_dir)
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def clear_directories(eyes_settings)
|
16
|
+
tmp_dir = File.join Dir.getwd, eyes_settings.tmp_dir
|
17
|
+
log_dir = File.join Dir.getwd, eyes_settings.log_dir
|
18
|
+
|
19
|
+
FileUtils.remove_dir(tmp_dir) if File.exist?(tmp_dir)
|
20
|
+
FileUtils.remove_dir(log_dir) if File.exist?(log_dir)
|
21
|
+
end
|
22
|
+
|
23
|
+
def using_screenshot(context)
|
24
|
+
return unless block_given?
|
25
|
+
screenshot_options = Applitools::Calabash::EyesSettings.instance.screenshot_names.next
|
26
|
+
yield context.screenshot(screenshot_options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def region_from_element(element)
|
30
|
+
region = Applitools::Region.new(
|
31
|
+
element['rect']['x'],
|
32
|
+
element['rect']['y'],
|
33
|
+
element['rect']['width'],
|
34
|
+
element['rect']['height']
|
35
|
+
)
|
36
|
+
return region if Applitools::Calabash::EnvironmentDetector.android?
|
37
|
+
region.scale_it!(Applitools::Calabash::EyesSettings.instance.eyes.density)
|
38
|
+
end
|
39
|
+
|
40
|
+
def request_element(context, element, method)
|
41
|
+
Applitools::ArgumentGuard.is_a?(element, 'element', Applitools::Calabash::CalabashElement)
|
42
|
+
context.query(element.element_query, method)
|
43
|
+
end
|
44
|
+
|
45
|
+
def grub_android_class_name(context, element)
|
46
|
+
request_element(context, element, :class)
|
47
|
+
end
|
48
|
+
|
49
|
+
def grub_ios_class_name(context, element)
|
50
|
+
request_element(context, element, :className)
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_android_element(context, query, index)
|
54
|
+
element_query = if (id = context.query(query, :getId)[index.to_i]) && id > 0
|
55
|
+
"* id:#{id}"
|
56
|
+
else
|
57
|
+
query + " index:#{index.to_i}"
|
58
|
+
end
|
59
|
+
element = context.query(element_query).first
|
60
|
+
Applitools::Calabash::CalabashElement.new(element, element_query)
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_ios_element(context, query, index)
|
64
|
+
hash = context.query(query, :hash)[index.to_i]
|
65
|
+
return unless hash
|
66
|
+
element_query = "* hash:#{hash}"
|
67
|
+
element = context.query(element_query).first
|
68
|
+
Applitools::Calabash::CalabashElement.new(element, element_query)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|