Open tansaku opened 8 years ago
He he, nice idea, feel free to do a PR if you can make it happen :)
using the headless gem, you can achieve this :)
@aclima93 fancy trying?
I'll see what I can cook up :)
Just curious if anyone ever found a solution for this?
Apologies for never returning to this thread with my results but maybe it can still serve as a starting point to someone. Here's a bunch of snippets which i worked on back in 2018-2019, I ended up using the headless gem and capybara to capture both screenshots and videos of our app during tests.
(Disclaimer: I haven't actively used this tech-stack for over 4 years, so probably won't be of much help in troubleshooting)
/app/controllers/concerns/recording_videos_concern.rb
require 'headless'
module RecordingVideosConcern
extend ActiveSupport::Concern
def recording_filename
"TODO.mov" # TODO:
end
def screenshot_filename(counter)
"TODO.png" # TODO:
end
def setup_recording
@image_counter = 0
@headless = Headless.new(video: { provider: :ffmpeg, log_file_path: STDERR })
@headless.start
end
def start_recording
@headless.video.start_capture
end
def stop_recording
# headless stores a local copy of the recording
@headless.video.stop_and_save recording_filename
upload_local_recording if File.exist? recording_filename
end
def upload_local_recording
# TODO:
end
def take_screenshot
@session.save_screenshot screenshot_filename(@image_counter)
@image_counter += 1
end
def save_screenshots
return unless @image_counter.positive?
# capybara session stores a local copy of the recording
filenames = (0..@image_counter - 1).map do |number|
screenshot_filename number
end
filenames = filenames.select do |filename|
File.exist? filename
end
upload_local_screenshots filenames
end
def upload_local_screenshots(filenames)
# TODO:
end
end
/app/controllers/concerns/capybara_videos_concern.rb
module CapybaraVideosConcern
extend ActiveSupport::Concern
def setup_capybara_session
configure_chrome_driver
configure_capybara_with_chrome_driver
Capybara::Session.new(:headless_chrome)
end
def configure_chrome_driver
# define our chrome browser's driver
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
chromeOptions: { args: %w[headless disable-gpu] }
)
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--disable-infobars')
Capybara.register_driver :headless_chrome do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
options: options,
desired_capabilities: capabilities
)
end
end
def configure_capybara_with_chrome_driver
Capybara.configure do |config|
# load assets
config.asset_host = ENV.fetch('RAILS_HOST')
# don't auto-fill a port into requests
config.always_include_port = false
config.run_server = false
config.app_host = ENV.fetch('RAILS_HOST')
config.default_driver = :headless_chrome
config.javascript_driver = :headless_chrome
end
end
end
/spec/spec_helper.rb
require 'capybara/rspec'
require 'capybara/dsl'
require 'capybara-screenshot/rspec'
require 'capybara_extensions'
require 'headless'
RSpec.configure do |config|
config.include Capybara::DSL
end
# Customized webdriver for Capybara
# https://drivy.engineering/running-capybara-headless-chrome/
# https://peter.sh/experiments/chromium-command-line-switches/
Capybara.register_driver :custom_chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
loggingPrefs:{
browser: 'ALL'
}
)
# remove the `headless` option to watch the specs in action
options = Selenium::WebDriver::Chrome::Options.new(
args: %w[
disable-dev-shm-usage
disable-gpu
disable-logging
disable-notifications
headless
disable-web-security
incognito
lang=en-us
log-level=3
no-sandbox
silent
start-maximized
window-size=1920,1080
]
)
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
options: options,
desired_capabilities: capabilities
)
end
# Capybara configurations
Capybara.configure do |config|
config.always_include_port = false
server_port = # TODO:
Capybara.server_port = server_port
Ngrok::Rspec.tunnel = {
port: server_port
}
config.javascript_driver = :custom_chrome
config.default_driver = :custom_chrome
config.default_max_wait_time = 10 # seconds
end
# use this to disable screenshot uploading
Capybara::Screenshot.autosave_on_failure = true
# Capybara screenshots
save_path = 'capybara/failures/'
Capybara::Screenshot.register_driver(:custom_chrome) do |driver, path|
driver.browser.save_screenshot(path)
end
Capybara.save_path = save_path
Capybara::Screenshot::RSpec::REPORTERS["RSpec::Core::Formatters::HtmlFormatter"] = Capybara::Screenshot::RSpec::HtmlEmbedReporter
usage
# setup
@session = setup_capybara_session
setup_recording
start_recording
# TODO: navigate through the app / perform actions
# cleanup
stop_recording
I can take multiple screenshots, but I wonder would it be possible to do something like tagging a cucumber scenario so that a complete video of the operation in the browser would be produced on error or possibly on completion?