Skip to content

Commit 8a66e12

Browse files
authored
[rb] add support for element screenshots (SeleniumHQ#8533)
Extracts TakesScreenshot from DriverExtensions to apply it to Element too
1 parent 55db83f commit 8a66e12

File tree

14 files changed

+153
-119
lines changed

14 files changed

+153
-119
lines changed

rb/lib/selenium/webdriver/chrome/driver.rb

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class Driver < WebDriver::Driver
3030
include DriverExtensions::HasNetworkConditions
3131
include DriverExtensions::HasWebStorage
3232
include DriverExtensions::HasLocation
33-
include DriverExtensions::TakesScreenshot
3433
include DriverExtensions::DownloadsFiles
3534
include DriverExtensions::HasDevTools
3635
include DriverExtensions::HasAuthentication

rb/lib/selenium/webdriver/common.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
require 'selenium/webdriver/common/html5/shared_web_storage'
5151
require 'selenium/webdriver/common/html5/local_storage'
5252
require 'selenium/webdriver/common/html5/session_storage'
53-
require 'selenium/webdriver/common/driver_extensions/takes_screenshot'
5453
require 'selenium/webdriver/common/driver_extensions/rotatable'
5554
require 'selenium/webdriver/common/driver_extensions/has_web_storage'
5655
require 'selenium/webdriver/common/driver_extensions/downloads_files'
@@ -69,5 +68,6 @@
6968
require 'selenium/webdriver/common/keys'
7069
require 'selenium/webdriver/common/profile_helper'
7170
require 'selenium/webdriver/common/options'
71+
require 'selenium/webdriver/common/takes_screenshot'
7272
require 'selenium/webdriver/common/driver'
7373
require 'selenium/webdriver/common/element'

rb/lib/selenium/webdriver/common/driver.rb

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ module WebDriver
3030

3131
class Driver
3232
include SearchContext
33+
include TakesScreenshot
3334

3435
class << self
3536
#
@@ -360,6 +361,10 @@ def service_url(http://github.com/opts)
360361
@service = service_config.launch
361362
@service.uri
362363
end
364+
365+
def screenshot
366+
bridge.screenshot
367+
end
363368
end # Driver
364369
end # WebDriver
365370
end # Selenium

rb/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb

-65
This file was deleted.

rb/lib/selenium/webdriver/common/element.rb

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Element
2323
ELEMENT_KEY = 'element-6066-11e4-a52e-4f735466cecf'
2424

2525
include SearchContext
26+
include TakesScreenshot
2627

2728
#
2829
# Creates a new Element
@@ -327,6 +328,10 @@ def selectable?
327328

328329
tn == 'option' || (tn == 'input' && %w[radio checkbox].include?(type))
329330
end
331+
332+
def screenshot
333+
bridge.element_screenshot(self)
334+
end
330335
end # Element
331336
end # WebDriver
332337
end # Selenium
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# frozen_string_literal: true
2+
3+
# Licensed to the Software Freedom Conservancy (SFC) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The SFC licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
module Selenium
21+
module WebDriver
22+
#
23+
# @api private
24+
#
25+
module TakesScreenshot
26+
#
27+
# Save a PNG screenshot to the given path
28+
#
29+
# @api public
30+
#
31+
32+
def save_screenshot(png_path)
33+
extension = File.extname(png_path).downcase
34+
if extension != '.png'
35+
WebDriver.logger.warn "name used for saved screenshot does not match file type. "\
36+
"It should end with .png extension",
37+
id: :screenshot
38+
end
39+
File.open(png_path, 'wb') { |f| f << screenshot_as(:png) }
40+
end
41+
42+
#
43+
# Return a PNG screenshot in the given format as a string
44+
#
45+
# @param [:base64, :png] format
46+
# @return String screenshot
47+
#
48+
# @api public
49+
50+
def screenshot_as(format)
51+
case format
52+
when :base64
53+
screenshot
54+
when :png
55+
screenshot.unpack1('m')
56+
else
57+
raise Error::UnsupportedOperationError, "unsupported format: #{format.inspect}"
58+
end
59+
end
60+
61+
end # TakesScreenshot
62+
end # WebDriver
63+
end # Selenium

rb/lib/selenium/webdriver/edge_html/driver.rb

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ module EdgeHtml
2828

2929
class Driver < WebDriver::Driver
3030
include DriverExtensions::HasWebStorage
31-
include DriverExtensions::TakesScreenshot
3231

3332
def browser
3433
:edge_html

rb/lib/selenium/webdriver/firefox/driver.rb

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ module Firefox
2929
class Driver < WebDriver::Driver
3030
include DriverExtensions::HasAddons
3131
include DriverExtensions::HasWebStorage
32-
include DriverExtensions::TakesScreenshot
3332

3433
def browser
3534
:firefox

rb/lib/selenium/webdriver/ie/driver.rb

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ module IE
2929

3030
class Driver < WebDriver::Driver
3131
include DriverExtensions::HasWebStorage
32-
include DriverExtensions::TakesScreenshot
3332

3433
def browser
3534
:internet_explorer

rb/lib/selenium/webdriver/remote/bridge.rb

+4
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ def screenshot
251251
execute :take_screenshot
252252
end
253253

254+
def element_screenshot(element)
255+
execute :take_element_screenshot, id: element.ref
256+
end
257+
254258
#
255259
# HTML 5
256260
#

rb/lib/selenium/webdriver/remote/driver.rb

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ module Remote
2828

2929
class Driver < WebDriver::Driver
3030
include DriverExtensions::UploadsFiles
31-
include DriverExtensions::TakesScreenshot
3231
include DriverExtensions::HasSessionId
3332
include DriverExtensions::Rotatable
3433
include DriverExtensions::HasRemoteStatus

rb/lib/selenium/webdriver/safari/driver.rb

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class Driver < WebDriver::Driver
3030
include DriverExtensions::HasDebugger
3131
include DriverExtensions::HasPermissions
3232
include DriverExtensions::HasWebStorage
33-
include DriverExtensions::TakesScreenshot
3433

3534
def browser
3635
:safari

rb/spec/integration/selenium/webdriver/driver_spec.rb

-47
Original file line numberDiff line numberDiff line change
@@ -60,53 +60,6 @@ module WebDriver
6060
expect(driver.find_element(id: 'dynamo').text).to eq("What's for dinner?")
6161
end
6262

63-
context 'screenshots' do
64-
it 'should save' do
65-
driver.navigate.to url_for('xhtmlTest.html')
66-
path = "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.png"
67-
68-
save_screenshot_and_assert(path)
69-
end
70-
71-
it 'should warn if extension of provided path is not png' do
72-
driver.navigate.to url_for('xhtmlTest.html')
73-
path = "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.jpg"
74-
message = "name used for saved screenshot does not match file type. "\
75-
"It should end with .png extension"
76-
expect(WebDriver.logger).to receive(:warn).with(message, id: :screenshot)
77-
78-
save_screenshot_and_assert(path)
79-
end
80-
81-
it 'should not warn if extension of provided path is png' do
82-
driver.navigate.to url_for('xhtmlTest.html')
83-
path = "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.PNG"
84-
expect(WebDriver.logger).not_to receive(:warn)
85-
86-
save_screenshot_and_assert(path)
87-
end
88-
89-
it 'should return in the specified format' do
90-
driver.navigate.to url_for('xhtmlTest.html')
91-
92-
ss = driver.screenshot_as(:png)
93-
expect(ss).to be_kind_of(String)
94-
expect(ss.size).to be_positive
95-
end
96-
97-
it 'raises an error when given an unknown format' do
98-
expect { driver.screenshot_as(:jpeg) }.to raise_error(WebDriver::Error::UnsupportedOperationError)
99-
end
100-
101-
def save_screenshot_and_assert(path)
102-
driver.save_screenshot path
103-
expect(File.exist?(path)).to be true
104-
expect(File.size(path)).to be_positive
105-
ensure
106-
File.delete(path) if File.exist?(path)
107-
end
108-
end
109-
11063
describe 'one element' do
11164
it 'should find by id' do
11265
driver.navigate.to url_for('xhtmlTest.html')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# frozen_string_literal: true
2+
3+
# Licensed to the Software Freedom Conservancy (SFC) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The SFC licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
require_relative 'spec_helper'
21+
22+
module Selenium
23+
module WebDriver
24+
describe TakesScreenshot do
25+
before do
26+
driver.navigate.to url_for('xhtmlTest.html')
27+
end
28+
29+
let(:element) { driver.find_element(css: '.content') }
30+
let(:path) { "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.png" }
31+
32+
it 'should save' do
33+
save_screenshots_and_assert(path)
34+
end
35+
36+
it 'should warn if extension of provided path is not png' do
37+
jpg_path = "#{Dir.tmpdir}/test#{SecureRandom.urlsafe_base64}.jpg"
38+
message = "name used for saved screenshot does not match file type. "\
39+
"It should end with .png extension"
40+
expect(WebDriver.logger).to receive(:warn).with(message, id: :screenshot).twice
41+
42+
save_screenshots_and_assert(jpg_path)
43+
end
44+
45+
it 'should not warn if extension of provided path is png' do
46+
expect(WebDriver.logger).not_to receive(:warn)
47+
48+
save_screenshots_and_assert(path)
49+
end
50+
51+
it 'should return in the specified format' do
52+
ss = element.screenshot_as(:png)
53+
expect(ss).to be_kind_of(String)
54+
expect(ss.size).to be_positive
55+
end
56+
57+
it 'raises an error when given an unknown format' do
58+
expect { element.screenshot_as(:jpeg) }.to raise_error(WebDriver::Error::UnsupportedOperationError)
59+
end
60+
61+
def save_screenshots_and_assert(path)
62+
save_screenshot_and_assert(driver, path)
63+
save_screenshot_and_assert(element, path)
64+
end
65+
66+
def save_screenshot_and_assert(source, path)
67+
source.save_screenshot path
68+
expect(File.exist?(path)).to be true
69+
expect(File.size(path)).to be_positive
70+
ensure
71+
File.delete(path) if File.exist?(path)
72+
end
73+
end
74+
end
75+
end

0 commit comments

Comments
 (0)