Class: Applitools::Driver

Inherits:
Object
  • Object
show all
Includes:
Selenium::WebDriver::DriverExtensions::HasInputDevices
Defined in:
lib/eyes_selenium/eyes/driver.rb

Constant Summary collapse

DRIVER_METHODS =
[
  :title, :execute_script, :execute_async_script, :quit, :close, :get,
  :post, :page_source, :window_handles, :window_handle, :switch_to,
  :navigate, :manage, :capabilities, :current_url
]
FINDERS =
{
  :class             => 'class name',
  :class_name        => 'class name',
  :css               => 'css selector',
  :id                => 'id',
  :link              => 'link text',
  :link_text         => 'link text',
  :name              => 'name',
  :partial_link_text => 'partial link text',
  :tag_name          => 'tag name',
  :xpath             => 'xpath',
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(eyes, options) ⇒ Driver

If driver is not provided, Applitools::Driver will raise an EyesError exception.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/eyes_selenium/eyes/driver.rb', line 47

def initialize(eyes, options)
  @driver = options[:driver]
  @is_mobile_device = options.fetch(:is_mobile_device, false)
  @eyes = eyes
  # FIXME fix getting "remote address url" or remove "Screenshot taker" altogether.
  # @remote_server_url = address_of_remote_server
  @remote_server_url = 'MOCK_URL'
  @remote_session_id = remote_session_id
  begin
    #noinspection RubyResolve
    if driver.capabilities.takes_screenshot?
     @screenshot_taker = false
    else
      @screenshot_taker = Applitools::ScreenshotTaker.new(@remote_server_url, @remote_session_id)
    end
  rescue => e
    raise Applitools::EyesError.new "Can't take screenshots (#{e.message})"
  end
end

Instance Attribute Details

#driverObject

Returns the value of attribute driver.



37
38
39
# File 'lib/eyes_selenium/eyes/driver.rb', line 37

def driver
  @driver
end

#eyesObject (readonly)

Returns the value of attribute eyes.



36
37
38
# File 'lib/eyes_selenium/eyes/driver.rb', line 36

def eyes
  @eyes
end

#remote_server_urlObject (readonly)

Returns the value of attribute remote_server_url.



36
37
38
# File 'lib/eyes_selenium/eyes/driver.rb', line 36

def remote_server_url
  @remote_server_url
end

#screenshot_takerObject (readonly)

Returns the value of attribute screenshot_taker.



36
37
38
# File 'lib/eyes_selenium/eyes/driver.rb', line 36

def screenshot_taker
  @screenshot_taker
end

Class Method Details

.normalize_rotation!(driver, image, rotation) ⇒ Object

Rotates the image as necessary. The rotation is either manually forced by passing a value in the rotation parameter, or automatically inferred if the rotation parameter is nil.

driver

Applitools::Driver The driver which produced the screenshot.

image

ChunkyPNG::Canvas The image to normalize.

rotation

Integer|nil The degrees by which to rotate the image: positive values = clockwise rotation,

negative values = counter-clockwise, 0 = force no rotation, +nil+ = rotate
automatically when needed.


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/eyes_selenium/eyes/driver.rb', line 15

def self.normalize_rotation!(driver, image, rotation)
  EyesLogger.debug "#{__method__}()"
  if rotation != 0
    num_quadrants = 0
    if !rotation.nil?
      if rotation % 90 != 0
        raise Applitools::EyesError.new(
          "Currently only quadrant rotations are supported. Current rotation: #{rotation}")
      end
      num_quadrants = (rotation / 90).to_i
    elsif rotation.nil? && driver.mobile_device? && driver.landscape_orientation? && image.height > image.width
      # For Android, we need to rotate images to the right, and for iOS to the left.
      num_quadrants = driver.android? ? 1 : -1
    end
    Applitools::Utils::ImageUtils.quadrant_rotate!(image, num_quadrants)
  end
end

Instance Method Details

#android?Boolean

Returns: true if the driver is an Android driver.

Returns:

  • (Boolean)


88
89
90
# File 'lib/eyes_selenium/eyes/driver.rb', line 88

def android?
  platform_name.to_s.upcase == 'ANDROID'
end

#find_element(*args) ⇒ Object



161
162
163
164
165
166
167
168
169
170
# File 'lib/eyes_selenium/eyes/driver.rb', line 161

def find_element(*args)
  how, what = extract_args(args)

  # Make sure that "how" is a valid locator.
  unless FINDERS[how.to_sym]
    raise ArgumentError, "cannot find element by #{how.inspect}"
  end

  Applitools::Element.new(self, driver.find_element(how, what))
end

#find_elements(*args) ⇒ Object



172
173
174
175
176
177
178
179
180
# File 'lib/eyes_selenium/eyes/driver.rb', line 172

def find_elements(*args)
  how, what = extract_args(args)

  unless FINDERS[how.to_sym]
    raise ArgumentError, "cannot find element by #{how.inspect}"
  end

  driver.find_elements(how, what).map { |el| Applitools::Element.new(self, el) }
end

#firefox?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/eyes_selenium/eyes/driver.rb', line 186

def firefox?
  driver.to_s == 'firefox'
end

#ie?Boolean

Returns:

  • (Boolean)


182
183
184
# File 'lib/eyes_selenium/eyes/driver.rb', line 182

def ie?
  driver.to_s == 'ie'
end

#ios?Boolean

Returns: true if the driver is an iOS driver.

Returns:

  • (Boolean)


94
95
96
# File 'lib/eyes_selenium/eyes/driver.rb', line 94

def ios?
  platform_name.to_s.upcase == 'IOS'
end

#keyboardObject



144
145
146
# File 'lib/eyes_selenium/eyes/driver.rb', line 144

def keyboard
  Applitools::EyesKeyboard.new(self, driver.keyboard)
end

#landscape_orientation?Boolean

Returns: true if the driver orientation is landscape.

Returns:

  • (Boolean)


100
101
102
103
104
105
106
# File 'lib/eyes_selenium/eyes/driver.rb', line 100

def landscape_orientation?
  begin
    driver.orientation.to_s.upcase == 'LANDSCAPE'
  rescue NameError
    EyesLogger.debug 'driver has no "orientation" attribute. Assuming Portrait.'
  end
end

#mobile_device?Boolean

Returns: true if the platform running the test is a mobile platform. false otherwise.

Returns:

  • (Boolean)


110
111
112
113
114
# File 'lib/eyes_selenium/eyes/driver.rb', line 110

def mobile_device?
  # We CAN'T check if the device is an +Appium::Driver+ since it is not a RemoteWebDriver. Because of that we use a
  # flag we got as an option in the constructor.
  @is_mobile_device
end

#mouseObject



140
141
142
# File 'lib/eyes_selenium/eyes/driver.rb', line 140

def mouse
  Applitools::EyesMouse.new(self, driver.mouse)
end

#platform_nameObject

Returns: String The platform name or nil if it is undefined.



75
76
77
# File 'lib/eyes_selenium/eyes/driver.rb', line 75

def platform_name
  driver.capabilities['platformName']
end

#platform_versionObject

Returns: String The platform version or nil if it is undefined.



81
82
83
84
# File 'lib/eyes_selenium/eyes/driver.rb', line 81

def platform_version
  version = driver.capabilities['platformVersion']
  version.nil? ? nil : version.to_s
end

#screenshot_as(output_type, rotation = nil) ⇒ Object

Return a PNG screenshot in the given format as a string

output_type

Symbol The format of the screenshot. Accepted values are :base64 and :png.

rotation

Integer|nil The degrees by which to rotate the image: positive values = clockwise rotation,

negative values = counter-clockwise, 0 = force no rotation, +nil+ = rotate
automatically when needed.

Returns: String A screenshot in the requested format.



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/eyes_selenium/eyes/driver.rb', line 124

def screenshot_as(output_type, rotation=nil)
  # FIXME Check if screenshot_taker is still required
  screenshot = screenshot_taker ? screenshot_taker.screenshot : driver.screenshot_as(:base64)
  screenshot = Applitools::Utils::ImageUtils.png_image_from_base64(screenshot)
  Applitools::Driver.normalize_rotation!(self, screenshot, rotation)
  case output_type
    when :base64
      screenshot = Applitools::Utils::ImageUtils.base64_from_png_image(screenshot)
    when :png
      screenshot = Applitools::Utils::ImageUtils.bytes_from_png_image(screenshot)
    else
      raise Applitools::EyesError.new("Unsupported screenshot output type #{output_type.to_s}")
  end
  screenshot.force_encoding('BINARY')
end

#user_agentObject



190
191
192
193
194
195
# File 'lib/eyes_selenium/eyes/driver.rb', line 190

def user_agent
  execute_script 'return navigator.userAgent'
rescue => e
  EyesLogger.info "getUserAgent(): Failed to obtain user-agent string (#{e.message})"
  return nil
end