Skip to content

Commit

Permalink
Merge pull request #1 from renuo/chrome_with_downloads
Browse files Browse the repository at this point in the history
Add chrome with Download capabilities
  • Loading branch information
coorasse committed Jun 18, 2020
2 parents 9f55afa + 0f0c27c commit e478608
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 10 deletions.
19 changes: 19 additions & 0 deletions .semaphore/master-deploy.yml
@@ -0,0 +1,19 @@
version: v1.0
name: master-deploy
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804

blocks:
- name: master-deploy
task:
secrets:
- name: rubygems-deploy
jobs:
- name: master-deploy
commands:
- checkout --use-cache
- gem build so_many_devices
- chmod 0600 ~/.gem/credentials
- gem push renuo-cli-*.gem
32 changes: 32 additions & 0 deletions .semaphore/semaphore.yml
@@ -0,0 +1,32 @@
version: "v1.0"
name: so_many_devices
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804
auto_cancel:
running:
when: "true"

blocks:
- name: tests
execution_time_limit:
minutes: 10
dependencies: []
task:
secrets:
- name: so_many_devices
env_vars:
- name: RAILS_ENV
value: test
jobs:
- name: tests
commands:
- checkout --use-cache
- cache restore
- bundle install -j 4 --path vendor/bundle
- cache store
- bundle exec rspec
promotions:
- name: master
pipeline_file: master-deploy.yml
56 changes: 56 additions & 0 deletions Gemfile.lock
@@ -0,0 +1,56 @@
PATH
remote: .
specs:
so_many_devices (0.1.0)
capybara (>= 3.0)

GEM
remote: https://rubygems.org/
specs:
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
capybara (3.32.1)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (~> 1.5)
xpath (~> 3.2)
diff-lcs (1.3)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
public_suffix (4.0.4)
rack (2.2.2)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rake (12.3.3)
regexp_parser (1.7.0)
rspec (3.9.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-core (3.9.2)
rspec-support (~> 3.9.3)
rspec-expectations (3.9.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.3)
xpath (3.2.0)
nokogiri (~> 1.8)

PLATFORMS
ruby

DEPENDENCIES
rake (~> 12.0)
rspec (~> 3.0)
so_many_devices!

BUNDLED WITH
2.1.4
34 changes: 31 additions & 3 deletions README.md
Expand Up @@ -29,23 +29,23 @@ In your `rails_helper.rb` you can configure your preferred device for tests:

```ruby
config.before(:each, type: :system, js: true) do
driven_by :iphone_6_7_8
driven_by :iphone_6_7_8
end
```

You can always use the headless version of each device by appending `_headless` to the device name.

```ruby
config.before(:each, type: :system, js: true) do
driven_by :iphone_6_7_8_headless
driven_by :iphone_6_7_8_headless
end
```

We use it to run our system tests on so many devices! Here is our standard configuration:

```ruby
config.before(:each, type: :system, js: true) do
driven_by ENV['SELENIUM_DRIVER'].to_sym
driven_by ENV['SELENIUM_DRIVER'].to_sym
end
```

Expand All @@ -62,6 +62,34 @@ of course, your tests need to run on so many devices!

Check [the YML file containing all the devices](./lib/so_many_devices.yml). So many!

## Chrome with downloads capabilities

We provide also an instance of Chrome already configured with
Downloads capabilities and a `SoManyDevices::DownloadsHelper` that you can use in your project.

Use the following:

```ruby
config.before(:each, type: :system, js: true) do
driven_by :selenium_chrome_with_download_headless # or non-headless version
end

config.include SoManyDevices::DownloadsHelper, type: :system
```

and in your test (just an example...):

```ruby
it 'can download a file', :js do
visit funny_page_path
click_link 'Download PDF'
wait_for_download
expect(downloads.length).to eq(1)
expect(download).to match(/.*\.pdf/)
end
```


## Development

After checking out the repo, run `bin/setup` to install dependencies.
Expand Down
17 changes: 14 additions & 3 deletions lib/so_many_devices.rb
@@ -1,8 +1,10 @@
require "so_many_devices/version"
require "so_many_devices/downloads_helper"
require 'yaml'
require 'capybara'

module SoManyDevices
class Error < StandardError;
end
class Error < StandardError; end

devices = YAML::load_file(File.join(__dir__, 'so_many_devices.yml'))

Expand All @@ -11,13 +13,22 @@ class Error < StandardError;
headless_args = ['--headless', '--disable-site-isolation-trials']
headless_args << '--disable-gpu' if Gem.win_platform?

[[device_name.to_sym, standard_args], ["#{device_name}_headless".to_sym, headless_args]].each do |device_name, args|
[[device_name, standard_args], ["#{device_name}_headless", headless_args]].each do |device_name, args|
Capybara.register_driver device_name.to_sym do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
'goog:chromeOptions' => { args: args, mobileEmulation: options }
)
Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
end
end

[[:selenium_chrome_with_download, standard_args], [:selenium_chrome_with_download_headless, headless_args]].each do |device_name, args|
Capybara.register_driver device_name do | app |
browser_options = ::Selenium::WebDriver::Chrome::Options.new(args: args)
browser_options.add_preference(:download, prompt_for_download: false, default_directory: SoManyDevices::DownloadsHelper::PATH.to_s)
browser_options.add_preference(:browser, set_download_behavior: { behavior: 'allow' })
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end
end
end
end
37 changes: 37 additions & 0 deletions lib/so_many_devices/downloads_helper.rb
@@ -0,0 +1,37 @@
module SoManyDevices
module DownloadsHelper
TIMEOUT = 10
PATH = "#{Dir.pwd}/tmp/downloads/"

def downloads
Dir["#{PATH}/*"]
end

def download
downloads.first
end

def download_content
wait_for_download
File.read(download)
end

def wait_for_download
Timeout.timeout(TIMEOUT) do
sleep 0.1 until downloaded?
end
end

def downloaded?
!downloading? && downloads.any?
end

def downloading?
downloads.grep(/\.crdownload$/).any?
end

def clear_downloads
FileUtils.rm_f(downloads)
end
end
end
2 changes: 1 addition & 1 deletion lib/so_many_devices/version.rb
@@ -1,3 +1,3 @@
module SoManyDevices
VERSION = "0.1.0"
VERSION = "0.2.0"
end
2 changes: 2 additions & 0 deletions so_many_devices.gemspec
Expand Up @@ -24,4 +24,6 @@ Gem::Specification.new do |spec|
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

spec.add_dependency 'capybara', '>= 3.0'
end
11 changes: 11 additions & 0 deletions spec/downloads_helper_spec.rb
@@ -0,0 +1,11 @@
RSpec.describe SoManyDevices::DownloadsHelper do
include SoManyDevices::DownloadsHelper

it 'points to a tmp path' do
FileUtils.mkdir_p(described_class::PATH)
expect(described_class::PATH).to end_with('tmp/downloads')
expect(downloads).to eq([])
FileUtils.touch("#{described_class::PATH}/example.txt")
expect(downloads).to eq(['example.txt'])
end
end
11 changes: 8 additions & 3 deletions spec/so_many_devices_spec.rb
@@ -1,9 +1,14 @@
RSpec.describe SoManyDevices do
it "has a version number" do
it 'has a version number' do
expect(SoManyDevices::VERSION).not_to be nil
end

it "does something useful" do
expect(false).to eq(true)
it 'defines a list of devices' do
devices = YAML::load_file(File.join(__dir__, '../lib/so_many_devices.yml'))
already_available_devices = 5
chrome_with_download_devices = 2
expect(Capybara.drivers.length).to eq((devices.keys.length * 2) +
already_available_devices +
chrome_with_download_devices)
end
end

0 comments on commit e478608

Please sign in to comment.