Skip to content

Commit

Permalink
[rb] add support for element screenshots (#8533)
Browse files Browse the repository at this point in the history
Extracts TakesScreenshot from DriverExtensions to apply it to Element too
  • Loading branch information
johndouthat authored Oct 28, 2020
1 parent 55db83f commit 8a66e12
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 119 deletions.
1 change: 0 additions & 1 deletion rb/lib/selenium/webdriver/chrome/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ class Driver < WebDriver::Driver
include DriverExtensions::HasNetworkConditions
include DriverExtensions::HasWebStorage
include DriverExtensions::HasLocation
include DriverExtensions::TakesScreenshot
include DriverExtensions::DownloadsFiles
include DriverExtensions::HasDevTools
include DriverExtensions::HasAuthentication
Expand Down
2 changes: 1 addition & 1 deletion rb/lib/selenium/webdriver/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
require 'selenium/webdriver/common/html5/shared_web_storage'
require 'selenium/webdriver/common/html5/local_storage'
require 'selenium/webdriver/common/html5/session_storage'
require 'selenium/webdriver/common/driver_extensions/takes_screenshot'
require 'selenium/webdriver/common/driver_extensions/rotatable'
require 'selenium/webdriver/common/driver_extensions/has_web_storage'
require 'selenium/webdriver/common/driver_extensions/downloads_files'
Expand All @@ -69,5 +68,6 @@
require 'selenium/webdriver/common/keys'
require 'selenium/webdriver/common/profile_helper'
require 'selenium/webdriver/common/options'
require 'selenium/webdriver/common/takes_screenshot'
require 'selenium/webdriver/common/driver'
require 'selenium/webdriver/common/element'
5 changes: 5 additions & 0 deletions rb/lib/selenium/webdriver/common/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module WebDriver

class Driver
include SearchContext
include TakesScreenshot

class << self
#
Expand Down Expand Up @@ -360,6 +361,10 @@ def service_url(opts)
@service = service_config.launch
@service.uri
end

def screenshot
bridge.screenshot
end
end # Driver
end # WebDriver
end # Selenium

This file was deleted.

5 changes: 5 additions & 0 deletions rb/lib/selenium/webdriver/common/element.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Element
ELEMENT_KEY = 'element-6066-11e4-a52e-4f735466cecf'

include SearchContext
include TakesScreenshot

#
# Creates a new Element
Expand Down Expand Up @@ -327,6 +328,10 @@ def selectable?

tn == 'option' || (tn == 'input' && %w[radio checkbox].include?(type))
end

def screenshot
bridge.element_screenshot(self)
end
end # Element
end # WebDriver
end # Selenium
63 changes: 63 additions & 0 deletions rb/lib/selenium/webdriver/common/takes_screenshot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

module Selenium
module WebDriver
#
# @api private
#
module TakesScreenshot
#
# Save a PNG screenshot to the given path
#
# @api public
#

def save_screenshot(png_path)
extension = File.extname(png_path).downcase
if extension != '.png'
WebDriver.logger.warn "name used for saved screenshot does not match file type. "\
"It should end with .png extension",
id: :screenshot
end
File.open(png_path, 'wb') { |f| f << screenshot_as(:png) }
end

#
# Return a PNG screenshot in the given format as a string
#
# @param [:base64, :png] format
# @return String screenshot
#
# @api public

def screenshot_as(format)
case format
when :base64
screenshot
when :png
screenshot.unpack1('m')
else
raise Error::UnsupportedOperationError, "unsupported format: #{format.inspect}"
end
end

end # TakesScreenshot
end # WebDriver
end # Selenium
1 change: 0 additions & 1 deletion rb/lib/selenium/webdriver/edge_html/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ module EdgeHtml

class Driver < WebDriver::Driver
include DriverExtensions::HasWebStorage
include DriverExtensions::TakesScreenshot

def browser
:edge_html
Expand Down
1 change: 0 additions & 1 deletion rb/lib/selenium/webdriver/firefox/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ module Firefox
class Driver < WebDriver::Driver
include DriverExtensions::HasAddons
include DriverExtensions::HasWebStorage
include DriverExtensions::TakesScreenshot

def browser
:firefox
Expand Down
1 change: 0 additions & 1 deletion rb/lib/selenium/webdriver/ie/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ module IE

class Driver < WebDriver::Driver
include DriverExtensions::HasWebStorage
include DriverExtensions::TakesScreenshot

def browser
:internet_explorer
Expand Down
4 changes: 4 additions & 0 deletions rb/lib/selenium/webdriver/remote/bridge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ def screenshot
execute :take_screenshot
end

def element_screenshot(element)
execute :take_element_screenshot, id: element.ref
end

#
# HTML 5
#
Expand Down
1 change: 0 additions & 1 deletion rb/lib/selenium/webdriver/remote/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ module Remote

class Driver < WebDriver::Driver
include DriverExtensions::UploadsFiles
include DriverExtensions::TakesScreenshot
include DriverExtensions::HasSessionId
include DriverExtensions::Rotatable
include DriverExtensions::HasRemoteStatus
Expand Down
1 change: 0 additions & 1 deletion rb/lib/selenium/webdriver/safari/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ class Driver < WebDriver::Driver
include DriverExtensions::HasDebugger
include DriverExtensions::HasPermissions
include DriverExtensions::HasWebStorage
include DriverExtensions::TakesScreenshot

def browser
:safari
Expand Down
47 changes: 0 additions & 47 deletions rb/spec/integration/selenium/webdriver/driver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,53 +60,6 @@ module WebDriver
expect(driver.find_element(id: 'dynamo').text).to eq("What's for dinner?")
end

context 'screenshots' do
it 'should save' do
driver.navigate.to url_for('xhtmlTest.html')
path = "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.png"

save_screenshot_and_assert(path)
end

it 'should warn if extension of provided path is not png' do
driver.navigate.to url_for('xhtmlTest.html')
path = "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.jpg"
message = "name used for saved screenshot does not match file type. "\
"It should end with .png extension"
expect(WebDriver.logger).to receive(:warn).with(message, id: :screenshot)

save_screenshot_and_assert(path)
end

it 'should not warn if extension of provided path is png' do
driver.navigate.to url_for('xhtmlTest.html')
path = "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.PNG"
expect(WebDriver.logger).not_to receive(:warn)

save_screenshot_and_assert(path)
end

it 'should return in the specified format' do
driver.navigate.to url_for('xhtmlTest.html')

ss = driver.screenshot_as(:png)
expect(ss).to be_kind_of(String)
expect(ss.size).to be_positive
end

it 'raises an error when given an unknown format' do
expect { driver.screenshot_as(:jpeg) }.to raise_error(WebDriver::Error::UnsupportedOperationError)
end

def save_screenshot_and_assert(path)
driver.save_screenshot path
expect(File.exist?(path)).to be true
expect(File.size(path)).to be_positive
ensure
File.delete(path) if File.exist?(path)
end
end

describe 'one element' do
it 'should find by id' do
driver.navigate.to url_for('xhtmlTest.html')
Expand Down
75 changes: 75 additions & 0 deletions rb/spec/integration/selenium/webdriver/takes_screenshot_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# frozen_string_literal: true

# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

require_relative 'spec_helper'

module Selenium
module WebDriver
describe TakesScreenshot do
before do
driver.navigate.to url_for('xhtmlTest.html')
end

let(:element) { driver.find_element(css: '.content') }
let(:path) { "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.png" }

it 'should save' do
save_screenshots_and_assert(path)
end

it 'should warn if extension of provided path is not png' do
jpg_path = "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.jpg"
message = "name used for saved screenshot does not match file type. "\
"It should end with .png extension"
expect(WebDriver.logger).to receive(:warn).with(message, id: :screenshot).twice

save_screenshots_and_assert(jpg_path)
end

it 'should not warn if extension of provided path is png' do
expect(WebDriver.logger).not_to receive(:warn)

save_screenshots_and_assert(path)
end

it 'should return in the specified format' do
ss = element.screenshot_as(:png)
expect(ss).to be_kind_of(String)
expect(ss.size).to be_positive
end

it 'raises an error when given an unknown format' do
expect { element.screenshot_as(:jpeg) }.to raise_error(WebDriver::Error::UnsupportedOperationError)
end

def save_screenshots_and_assert(path)
save_screenshot_and_assert(driver, path)
save_screenshot_and_assert(element, path)
end

def save_screenshot_and_assert(source, path)
source.save_screenshot path
expect(File.exist?(path)).to be true
expect(File.size(path)).to be_positive
ensure
File.delete(path) if File.exist?(path)
end
end
end
end

0 comments on commit 8a66e12

Please sign in to comment.