Giter Site home page Giter Site logo

capybara-screenshot's Introduction

capybara-screenshot gem

Build Status Code Climate Gem Version

Capture a screenshot for every test failure automatically!

capybara-screenshot used with Capybara alongside Cucumber, Rspec or Minitest, will capture a screenshot for each failure in your test suite. Associated screenshot and HTML file of the failed page (when using capybara-webkit, Selenium, poltergeist or cuprite) is saved into $APPLICATION_ROOT/tmp/capybara.

Available screenshots for each test failure is incredibly helpful for diagnosing problems quickly in your failing steps. You have the ability to view screenshots (when applicable) and source code at the time of each failure.

Please note that Ruby 1.9+ is required to use this Gem. For Ruby 1.8 support, please see the capybara-screenshot Ruby 1.8 branch

Installation

Step 1: install the gem

Using Bundler, add the following to your Gemfile:

gem 'capybara-screenshot', :group => :test

Alternatively, manually install using Ruby Gems:

gem install capybara-screenshot

Step 2: load capybara-screenshot into your tests

Cucumber

In env.rb or a support file, please add:

require 'capybara-screenshot/cucumber'

RSpec

In rails_helper.rb, spec_helper.rb, or a support file, after the require for 'capybara/rspec', please add:

# remember: you must require 'capybara/rspec' first
require 'capybara-screenshot/rspec'

Note: As of RSpec Rails 3.0, it is recommended that all your Rails environment code is loaded into rails_helper.rb instead of spec_helper.rb, and as such, the capybara-screenshot require should be located in rails_helper.rb. See the RSpec Rails 3.0 upgrade notes for more info.

Minitest

Typically in 'test/test_helper.rb', please add:

require 'capybara-screenshot/minitest'

Also, consider adding include Capybara::Screenshot::MiniTestPlugin to any test classes that fail. For example, to capture screenshots for all failing integration tests in minitest-rails, try something like:

class ActionDispatch::IntegrationTest
  include Capybara::Screenshot::MiniTestPlugin
  # ...
end

Test::Unit

Typically in 'test/test_helper.rb', please add:

require 'capybara-screenshot/testunit'

By default, screenshots will be captured for Test::Unit tests in the path 'test/integration'. You can add additional paths:

Capybara::Screenshot.testunit_paths << 'test/feature'

Manual screenshots

If you require more control, screenshots can be generated on demand rather than on failure. This is useful when screenshots produced at the time of failure are not as useful for debugging a rendering problem. Differentiating between manual and failure screenshots can be improved by disabling the auto-generate on failure feature:

Capybara::Screenshot.autosave_on_failure = false

Anywhere the Capybara DSL methods (visit, click etc.) are available so too are the screenshot methods:

screenshot_and_save_page

Or for screenshot only, which will automatically open the image:

screenshot_and_open_image

These are just calls on the main library methods:

Capybara::Screenshot.screenshot_and_save_page
Capybara::Screenshot.screenshot_and_open_image

Better looking HTML screenshots

By the default, HTML screenshots will not look very good when opened in a browser. This happens because the browser can't correctly resolve relative paths like <link href="/assets/...." />, which stops CSS, images, etc... from being loaded. To get a nicer looking page, configure Capybara with:

Capybara.asset_host = 'http://localhost:3000'

This will cause Capybara to add <base>http://localhost:3000</base> to the HTML file, which gives the browser enough information to resolve relative paths. Next, start a rails server in development mode, on port 3000, to respond to requests for assets:

rails s -p 3000

Now when you open the page, you should have something that looks much better. You can leave this setup in place and use the default HTML pages when you don't care about the presentation, or start the rails server when you need something better looking.

Driver configuration

The gem supports the default rendering method for Capybara to generate the screenshot, which is:

page.driver.render(path)

There are also some specific driver configurations for Selenium, Webkit, and Poltergeist. See the definitions here. The Rack::Test driver, Rails' default, does not allow rendering, so it has a driver definition as a noop.

Capybara-webkit defaults to a screenshot size of 1000px by 10px. To specify a custom size, use the following option:

Capybara::Screenshot.webkit_options = { width: 1024, height: 768 }

If a driver is not found the default rendering will be used. If this doesn't work with your driver, then you can add another driver configuration like so

# The driver name should match the Capybara driver config name.
Capybara::Screenshot.register_driver(:exotic_browser_driver) do |driver, path|
  driver.super_dooper_render(path)
end

If your driver is based on existing browser driver, like Firefox, instead of .super_dooper_render do driver.browser.save_screenshot path.

Custom screenshot filename

If you want to control the screenshot filename for a specific test library, to inject the test name into it for example, you can override how the basename is generated for the file:

Capybara::Screenshot.register_filename_prefix_formatter(:rspec) do |example|
  "screenshot_#{example.description.gsub(' ', '-').gsub(/^.*\/spec\//,'')}"
end

By default capybara-screenshot will append a timestamp to the basename. If you want to disable this behavior, set the following option:

Capybara::Screenshot.append_timestamp = false

Custom screenshot directory

By default, when running under Rails, Sinatra, and Padrino, screenshots are saved into $APPLICATION_ROOT/tmp/capybara. Otherwise, they're saved under Dir.pwd. If you want to customize the location, override the file path:

Capybara.save_path = "/file/path"

Uploading screenshots to S3

You can configure capybara-screenshot to automatically save your screenshots to an AWS S3 bucket.

First, install the aws-sdk-s3 gem or add it to your Gemfile:

gem 'aws-sdk-s3', group: :test
gem 'capybara-screenshot', group: :test

Next, configure capybara-screenshot with your S3 credentials, the bucket to save to, and an optional region (default: us-east-1):

Capybara::Screenshot.s3_configuration = {
  s3_client_credentials: {
    access_key_id: "my_access_key_id",
    secret_access_key: "my_secret_access_key",
    region: "eu-central-1"
  },
  bucket_name: "my_screenshots",
  # Optionally: Specify the host used to access the uploaded screenshots
  bucket_host: "my_screenshots.s3-eu-central-1.amazonaws.com",
}

The access key used for S3 uploads need to have at least the s3:PutObject permission.

Note: If you do not provide the bucket_host configuration option, additionally the s3:GetBucketLocation permission is required on the bucket for uploads to succeed.

It is also possible to specify the object parameters such as acl. Configure the capybara-screenshot with these options in this way:

Capybara::Screenshot.s3_object_configuration = {
  acl: 'public-read'
}

You may optionally specify a :key_prefix when generating the S3 keys, which can be used to create virtual folders in S3, e.g.:

Capybara::Screenshot.s3_configuration = {
  ... # other config here
  key_prefix: "some/folder/"
}

Pruning old screenshots automatically

By default, screenshots are saved indefinitely. If you want them to be automatically pruned on a new failure, then you can specify one of the following prune strategies as follows:

# Keep only the screenshots generated from the last failing test suite
Capybara::Screenshot.prune_strategy = :keep_last_run

# Keep up to the number of screenshots specified in the hash
Capybara::Screenshot.prune_strategy = { keep: 20 }

Callbacks

You can hook your own logic into callbacks after the html/screenshot has been saved:

# after Saver#save_html
Capybara::Screenshot.after_save_html do |path|
  mail = Mail.new do
    delivery_method :sendmail
    from     '[email protected]'
    to       '[email protected]'
    subject  'Capybara Screenshot'
    add_file File.read path
  end
  mail.delivery_method :sendmail
  mail.deliver
end

# after Saver#save_screenshot
Capybara::Screenshot.after_save_screenshot do |path|
  # ...
end

Information about screenshots in RSpec output

By default, capybara-screenshot extend RSpec’s formatters to include a link to the screenshot and/or saved html page for each failed spec. If you want to disable this feature completely (eg. to avoid problems with CI tools), use:

Capybara::Screenshot::RSpec.add_link_to_screenshot_for_failed_examples = false

It’s also possible to directly embed the screenshot image in the output if you’re using RSpec’s HtmlFormatter:

Capybara::Screenshot::RSpec::REPORTERS["RSpec::Core::Formatters::HtmlFormatter"] = Capybara::Screenshot::RSpec::HtmlEmbedReporter

If you want to further customize the information added to RSpec’s output, just implement your own reporter class and customize Capybara::Screenshot::RSpec::REPORTERS accordingly. See rspec.rb for more info.

Common problems

If you have recently upgraded from v0.2, or you find that screen shots are not automatically being generated, then it's most likely you have not included the necessary require statement for your testing framework described above. As of version 0.3, without the explicit require, Capybara-Screenshot will not automatically take screen shots. Please re-read the installation instructions above.

Also make sure that you're not calling Capybara.reset_sessions! before the screenshot hook runs. For RSpec you want to make sure that you're using append_after instead of after, for instance:

config.append_after(:each) do
  Capybara.reset_sessions!
end

Raise an issue on the Capybara-Screenshot issue tracker if you are still having problems.

Repository & Contributing to this Gem

Bugs

Please raise an issue at https://github.com/mattheworiordan/capybara-screenshot/issues and ensure you provide sufficient detail to replicate the problem.

Contributions

Contributions are welcome. Please fork this gem and then submit a pull request. New features must include test coverage and must pass on all versions of the testing frameworks supported. Run appraisal to set up the your Gems. then appraisal "rake travis:ci" locally to test your changes against all versions of testing framework gems supported.

Rubygems

The gem details on RubyGems.org can be found at https://rubygems.org/gems/capybara-screenshot

About

This gem was written by Matthew O'Riordan, with contributions from many kind people.

License

Copyright © 2020 Matthew O'Riordan, inc. It is free software, and may be redistributed under the terms specified in the LICENSE file.

capybara-screenshot's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

capybara-screenshot's Issues

Screenshots taken on specs that don't use Capybara

I have a project that has an RSpec unit test suite and an RSpec integration test suite. Capybara is only used in the integration test suite. As per the installation steps in the readme, I added require 'capybara-screenshot/rspec' to spec_helper.rb. Now when I get failures in my unit tests, I get a message with a path to a screenshot in the failure message. I looked at rspec.rb in this gem to see how it decides when to save screenshots and it looks like as long as Capybara.page.respond_to?(:save_page) and Capybara::Screenshot.autosave_on_failure && example.exception are true then a screenshot will be saved. In both of my test suites those are always true. Is there something I'm missing here?

I was able to work around the issue by adding require 'capybara-screenshot/rspec' in my own rake task that I use for running the integration test suite, but it seems like there should be a cleaner solution. What do others do to not run into this issue? Another option I see is to have a integration_spec_helper.rb which could be included instead of spec_helper.rb in integration tests and I'd added the reference to capybara-screenshot only in integration_spec_helper.rb. I might have to go with this approach because even with my workaround, if I want to run a single integration test file using rspec path/to/integration_spec.rb I don't get capybara-screenshot.

I also have another situation where I have tests in my integration suite that don't use Capybara, but just test the integration between certain classes, and in those tests I also don't want capybara-screenshot active. My workaround now is to add the following to the outer describe in those files:

  before(:all) { Capybara::Screenshot.autosave_on_failure = false }
  after(:all) { Capybara::Screenshot.autosave_on_failure = true }

But that seems hacky. Is there a better solution there as well?

Thanks.

screenshot not captured until after block executed

The screenshots in our application appear to no longer be captured until after the after(:each) block has been run. This makes the screenshot inaccurate in cases where the after block navigates from the page (such as logging out)

If I remove the after block, the screenshot is captured at the point of failure.

Not getting an image

Hi,

First of all, thanks for the gem!

I tried it at work where we use RSpec for our integration tests and it worked great. I couple your "screenshot_and_open_image" with Capybara's "save_and_open_page" to get both an HTML page (without any CSS styling) and a nice-looking image (.png file, I think). Great!

I am now trying it at home on a different project which uses cucumber. I have the necessary "require capybara-screenshot/cucumber" statement in my env.rb file. (BTW: cucumber-rails 1.3.0, capybara 2.0.2, capybara-webkit 0.14.0, capybara-screenshot 0.3.3 on Ubuntu 12.04 and Firefox 17.0.1)

The problem is that I am not getting any images. When I put "screenshot_and_save_page" in a step-def, a "screenshot_2013-01-09-xxxx.html" file is being generated in /tmp/capybara, so the plumbing hook-up looks okay. And that HTML file is the same as the HTML file that is produced when I use Capybara's "save_and_open_page" method.

Question 1: Should this HTML file contain a .png file which actually shows an image of the page or should it just show the vanilla HTML (i.e. with no CSS styling) - which makes it identical to Capybara's built-in "save_and_open_page" method?

Question 2 (And this is the more important one): When I also insert a call to "screenshot_and_open_image" -- nothing. Am I missing something or does it just not produce images for Cucumber like it did for RSpec?

Thanks,
Larry

Screenshots for every step and embedded in cuke html reports

I would like to use this gem to generate screenshots for every step in my cucumber features. Additionally, I would like to embed the screenshots within the html formatted output report when running `cucumber features/* -f html -o output.html

I do not see an easy way to automatically generate screenshots for every step or embed within reports. Also, my pages seem to be wider than the screenshots. Is the screenshot width configurable?

Screenshot path in cucumber

Great tool for spec, but not very usable in cucumber.

Like the "Screenshot path in RSpec metadata" feature there should be a path output that shows which .png file belongs to which test. (no output in 0.3.19)

Silence output?

When I use capybara-screenshot to take a screenshot it outputs something like "Saved file screenshot_2013-09-12-17-03-47.247" in console, is there anyway to disable this? Thanks!

screenshot doesn't play well with spork

Running into an issue where no screenshots are created while running spork. Has anyone else seen this behavior?

I first noticed that it wasn't triggering on failed integration tests. I've tried calling it manually via the following.

Capybara::Screenshot::Saver.screen_shot_and_save_page Capybara, Capybara.body                                                                                                                                                                                         
page.driver.render Rails.root.join("tmp/capybara/#{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}.png")

I do get screenshots when I turn off spork though.

Opens 2 browser instances

I use rspec + capybara (webdriver). I used it today for the first time, it woks great. Just that i saw an extra browser instance being opened.

Update README to cover minitest ActionDispatch requirement

It should be clarified in the README that capybara-screenshot/minitest has a hard dependency on ActionDispatch. This is important for those of us who are using capybara and minitest to integration test non-rails or 3rd party applications and thus aren't making use of Action::Dispatch::IntegrationTest.

visit just disappears when using gem.

I've not time to figure out what is going on but when I use your gem, visit (or actually any normal helper method) just up and takes out. Then when I remove your gem from my rails Gemfile it comes back. I'm using RSpec 2 if that helps any.

Eliminate dependency on cucumber

Is there a reason this gem has to depend on Cucumber?

I use Capybara with RSpec request specs and would rather not have to include cucumber and it's dependencies in my bundle (particularly gherkin, which requires native extensions).

Images being saved for successful tests

Hello,

I'm running capybara-screenshot without Cucumber, just Rspec request specs + capybara-webkit and I noticed that images are being generated for all tests and not only for failing ones. Is there any configuration that I need to make in order to fix this?

Thanks!

Currently only owner can read files, add read rights for all, otherwise you'll get error like this:

/usr/local/lib/ruby/gems/2.0.0/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:in require': cannot load such file -- capybara-screenshot/rspec (LoadError) from /usr/local/lib/ruby/gems/2.0.0/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:inblock in require'
from /usr/local/lib/ruby/gems/2.0.0/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:214:in load_dependency' from /usr/local/lib/ruby/gems/2.0.0/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:229:inrequire'

License missing from gemspec

Some companies will only use gems with a certain license.
The canonical and easy way to check is via the gemspec,

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Even for projects that already specify a license, including a license in your gemspec is a good practice, since it is easily
discoverable there without having to check the readme or for a license file. For example, it is the field that rubygems.org uses to display a gem's license.

For example, there is a License Finder gem to help companies ensure all gems they use
meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough
issue that even Bundler now generates gems with a default 'MIT' license.

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), github has created a license picker tool.

In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :).

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue and let me know. In either case, I'll follow up. Thanks!

p.s. I've written a blog post about this project

undefined method 'World'

I followed the instructions in the ReadMe and got the following error;

/home/gsimpson/.rvm/gems/ree-1.8.7-2011.03@myproject/gems/capybara-1.1.1/lib/capybara/cucumber.rb:6: undefined method `World' for main:Object (NoMethodError)

I'm using Rails 3.1.1 and all my gems are pretty up to date.

Cheers,
Graeme

Please, add support for capybara 2.1

Hello, I am try to use your awesome gem with cucumber+capybara(2.1). It was perfect for capybara(2.0), but now autosave when scenario failed not working. Could you add support for capybara 2.1?
Thank you

Not working in OS X

Does this work on OS X or just in Linux? I'm running on Lion and things are working as they should, except nothing is being saved to the /tmp/capybara folder, whether I run with my own code or the sample app that you created. Any idea what's up?

Screenshot not capturing during Cucumber Outline

Whenever I run a scenario in Cucumber with a Scenario Outline (whether ran with/without the --expand option), the failing scenario does not capture a screenshot. However, if I ran the same scenarios in their own individual Scenario, then the screenshot is saved successfully.

Does capybara-screenshot not support Cucumber's Scenario Outline type?

Internal Server Error - ActiveRecordNotFound

Not sure if this is a capybara-screenshot error, or a Poltergeist error (or my error)...
I am getting this error displayed in all my screenshots after I call click_button.

I don't know why, if I take a screenshot prior to this, they come out as expected.
I am using Poltergeist. I tested this scenario manually and it works...

Here is a test snippet:

describe 'xyz' do
        it ' does ABC' do           
            user = Fabricate(:user)
            visit '/sign_up'

            puts User.count # returns 1

            screenshot_and_open_image # works

            fill_in 'Email', with: user.email
            fill_in 'Password', with: user.password
            fill_in 'Password confirmation', with: user.password

           screenshot_and_open_image # works

            click_button 'Sign Up!'

            screenshot_and_open_image # Shows error

            assert true
        end
    end

Appending failure Screenshot path in rspec html report

I was able to get screenshot on failure using "save_screenshot(path)" as mentioned in one of the comments in the issues.
But, I am still not able to get to append that screenshot path to the spec html report.
According to the readme doc, it works by default but looks like something is missing. Is there any other hidden configuration/command like the one above that will do the trick?
Please help if anyone had the same issue and was able to resolve it.

capybara-screenshot could not detect a screenshot driver for 'rack_test'.

capybara-screenshot could not detect a screenshot driver for 'rack_test'. Saving with default with unknown results.

An error occurred in an after hook
NoMethodError: undefined method render' for #<Capybara::RackTest::Driver:0x0000001156cc30> occurred at /home/prusswan/.rvm/gems/ruby-1.9.3-p194/gems/capybara-screenshot-0.2/lib/capybara-screenshot/saver.rb:34:insave_with_default'

Is this supposed to be normal? Even if it is, is there a way to configure capybara-screenshot not to take screenshots for the default driver?

uninitialized constant RSpec::Version (NameError)

This is what I'm getting:

/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.3/lib/rspec/core.rb:166:in `block in const_missing': uninitialized constant RSpec::Version (NameError)
    from /usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.3/lib/rspec/core.rb:166:in `fetch'
    from /usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.3/lib/rspec/core.rb:166:in `const_missing'
    from /usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/capybara-screenshot-1.0.0/lib/capybara-screenshot/rspec/text_reporter.rb:9:in `<module:TextReporter>'
    from /usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/capybara-screenshot-1.0.0/lib/capybara-screenshot/rspec/text_reporter.rb:6:in `<module:RSpec>'
    from /usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/capybara-screenshot-1.0.0/lib/capybara-screenshot/rspec/text_reporter.rb:5:in `<module:Screenshot>'
    from /usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/capybara-screenshot-1.0.0/lib/capybara-screenshot/rspec/text_reporter.rb:4:in `<module:Capybara>'
    from /usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/capybara-screenshot-1.0.0/lib/capybara-screenshot/rspec/text_reporter.rb:3:in `<top (required)>'
    from /usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/capybara-screenshot-1.0.0/lib/capybara-screenshot/rspec.rb:1:in `<top (required)>'
    from /Users/keithpitt/Development/xxx/spec/support/capybara.rb:5:in `<top (required)>'

I think it should be:

>> RSpec::Core::Version::STRING
=> "3.1.3"

Would be helpful to be able to save the '.png' outside of the current working directory (without monkey patching the code)

Title is relatively explanatory.

A user can specify where they want the '.html' files saved, but for the '.png', if you are not running Rails or Sinatra, seems you are SOL for the time being.

The fix is (most likely) pretty simple. it would be nice if you could add this functionality in the near future...seems to be pretty low-hanging fruit.

Thanks for maintaining such a useful tool,

wokkaflokkaflame

how to emulate save_and_open_page

Great work. How can we not only have it save the HTML on an error, but automatically open it, just like Capybara's save_and_open_page method?

Ruby 2.1.0 support

I had a suite of tests always returning exit code 0 regardless of passing or failing scenarios when the project was updated to Ruby 2.1.0. What I thought was a Cucumber issue was actually caused by capybara-screenshot returning an exit code 0 every time. After removing capybara-screenshot it started returning the correct exit code (0 for passing suite, 1 for failing).

If you could give capybara-screenshot 2.1.0 support then it'd be great!

Referenced issue here:
cucumber/common#635

location of require moved with rspec 3.1.4

Hi, great gem, but as of rspec 3.1.(4 ?),

require 'capybara-screenshot'
require 'capybara-screenshot/rspec'

should be added to the top of rails_helper.rb, not spec_helper.rb in order for the gem to be be called.

undefined method `add_teardown_hook' for ActionDispatch::IntegrationTest:Class

After updating to 0.1.5, I get this error on initialisation, from lib/capybara-screenshot/minitest.rb:4.

I'm using Rails 3.1.3 and Ruby 1.9.2, but the project was created with --skip-active-record --skip-test-unit, in case that makes a difference.

Perhaps it would be safer to check that ActionDispatch::IntegrationTest is not only defined, but also responds to #add_teardown_hook.

PNG data stream used as file name

Saved file /home/jenkins/workspace/Cucumber-Tests/tmp/capybara/screenshot_2014-01-31-18-11-27.068.html
Given an unsubscribed male user "MrMangione" # features/step_definitions/user_steps.rb:263
File name too long @ rb_sysopen - data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+gAAAdHCAYAAABRplPMAAAgAElEQVR4nOyd
55sUxf72f3/AeY4CuzupZ6Zz98xsJGOARYKSJJrASBBQzOmYc87p6DEQRDJI
....
....
oAMAAAAAYIAf6+//A0mHKM/RBj9BAAAAAElFTkSuQmCC
(Errno::ENAMETOOLONG)
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/formatter/gherkin_formatter_adapter.rb:86:in initialize' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/formatter/gherkin_formatter_adapter.rb:86:inopen'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/formatter/gherkin_formatter_adapter.rb:86:in embed' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:181:inblock in send_to_all'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:179:in each' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:179:insend_to_all'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:173:in broadcast' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:160:inembed'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime/user_interface.rb:54:in embed' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/rb_support/rb_world.rb:117:inAfter'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/core_ext/instance_exec.rb:36:in cucumber_instance_exec' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/rb_support/rb_hook.rb:14:ininvoke'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:114:in invoke' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:108:inblock in execute_after'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:107:in reverse_each' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:107:inexecute_after'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:19:in after' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime/support_code.rb:112:inblock in fire_hook'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime/support_code.rb:111:in each' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime/support_code.rb:111:infire_hook'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime.rb:113:in after' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime.rb:100:inbefore_and_after'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime.rb:82:in block in with_hooks' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime/support_code.rb:120:incall'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime/support_code.rb:120:in block (3 levels) in around' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:9:inblock in around'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:94:in call' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:94:inblock (3 levels) in execute_around'
/home/jenkins/workspace/Dating-Cucumber-Tests/features/support/env.rb:81:in call' /home/jenkins/workspace/Dating-Cucumber-Tests/features/support/env.rb:81:inblock in <top (required)>'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/core_ext/instance_exec.rb:48:in instance_exec' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/core_ext/instance_exec.rb:48:inblock in cucumber_instance_exec'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/core_ext/instance_exec.rb:69:in cucumber_run_with_backtrace_filtering' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/core_ext/instance_exec.rb:36:incucumber_instance_exec'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/rb_support/rb_hook.rb:14:in invoke' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:114:ininvoke'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:93:in block (2 levels) in execute_around' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:97:incall'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:97:in execute_around' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/language_support/language_methods.rb:8:inaround'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime/support_code.rb:119:in block (2 levels) in around' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime/support_code.rb:123:incall'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime/support_code.rb:123:in around' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime.rb:94:inaround'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime.rb:81:in with_hooks' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:13:inexecute'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/scenario.rb:32:in block in accept' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/scenario.rb:79:inwith_visitor'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/scenario.rb:31:in accept' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:58:inblock in visit_feature_element'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:170:in broadcast' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:57:invisit_feature_element'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/feature.rb:38:in block in accept' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/feature.rb:37:ineach'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/feature.rb:37:in accept' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:27:inblock in visit_feature'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:170:in broadcast' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:26:invisit_feature'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/features.rb:28:in block in accept' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/features.rb:17:ineach'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/features.rb:17:in each' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/features.rb:27:inaccept'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:21:in block in visit_features' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:170:inbroadcast'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/ast/tree_walker.rb:20:in visit_features' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/runtime.rb:49:inrun!'
/home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/lib/cucumber/cli/main.rb:47:in execute!' /home/jenkins/.gems/ruby/2.1.0/gems/cucumber-1.3.10/bin/cucumber:13:in<top (required)>'
/home/jenkins/.gems/ruby/2.1.0/bin/cucumber:23:in load' /home/jenkins/.gems/ruby/2.1.0/bin/cucumber:23:in

'

Screenshots don't seem to be capturing "modal" dialogs.

We have a rails app that we are testing with capybara-screenshot. Our application is built with Backbone.js, and we are using the capybara-webkit driver and cucumber for testing. When we write a test that views a page that has a "modal dialog"... which we create from the bootstrap CSS library (e.g. twitter's css framework), our modal dialogs are not appearing as part of the screen shot.

I noticed that the poltergeist driver https://github.com/jonleighton/poltergeist has an option to save the entire page.

"...By default, only the viewport will be rendered (the part of the page that is in view). To render the entire page, use

page.driver.render('/path/to/file.png', :full => true).

..."

(That said, we'd rather use the webkit driver.)

Here is an example of a modal dialog with Bootstrap from twitter:

http://twitter.github.com/bootstrap/javascript.html#modals

(Click the Launch modal demo button.) We have tried to put a delay in our tests to allow the modal to load, but that has not helped either.

I am a bit out of my depth here and apologize if this is short on technical details. Being able to save the modal dialogs that are begin generated by the Bootstrap framework from twitter would be huge for us.

Thanks for any help you can provide, and thanks for a great tool!

Miles.

Change description to indicate framework support

It's currently:

Automatically save screen shots when a Cucumber Capybara scenario fails

Since capybara-screenshot supports quite a few frameworks by now, I think you could brag a bit more about that ;)

"Feature" request: consider removing colorize dependency

4247c42 pulls in the GPL-licensed colorize gem as a dependency. Some people working for companies with strict license policies may not be able to use capybara-screenshot at work as a result. Thought I'd mention it in case it's something you hadn't considered.

Method not found

I have to call the full method, ala:

Capybara::Screenshot.screenshot_and_open_image

For whatever reason, just calling screenshot_and_open_image by itself is not found in the Capybara DSL. Just a small annoyance, probably something I'm missing.

0.2.4 failing with 'undefined method `configure' for RSpec:Module'

Backtrace snippet:
undefined method configure' for RSpec:Module /Users/agranov/.rvm/gems/ruby-1.9.2-p320@dotBusy32/gems/capybara-screenshot-0.2.4/lib/capybara-screenshot/rspec.rb:1:in<top (required)>'
/Users/agranov/.rvm/gems/ruby-1.9.2-p320@dotBusy32/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:in require' /Users/agranov/.rvm/gems/ruby-1.9.2-p320@dotBusy32/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:inblock in require'
/Users/agranov/.rvm/gems/ruby-1.9.2-p320@dotBusy32/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:236:in load_dependency' /Users/agranov/.rvm/gems/ruby-1.9.2-p320@dotBusy32/gems/activesupport-3.2.3/lib/active_support/dependencies.rb:251:inrequire'
/Users/agranov/.rvm/gems/ruby-1.9.2-p320@dotBusy32/gems/capybara-screenshot-0.2.4/lib/capybara-screenshot.rb:104:in `<top (required)>'

I've made sure that it's being loaded last in Gemfile.

Reverting back to 0.2.2 fixes the issue.

Not getting a link to screenshot in RSpec output

I am using capybara-screenshot 0.3.21, capybara 2.4.1 and rspec 3.1.0 and when I run a failing spec I don't see a link to the produced png/html. I haven't set Capybara::Screenshot::RSpec.add_link_to_screenshot_for_failed_examples = false. Is this a known issue?

specs fail if no `context' container is present

Not to give you the double-whammy, but I just found this problem even on 0.2.2.

With the same Gemfile as I included in my other logged issue, the following spec,

require 'spec_helper'

describe "UserActivations" do
  it "sends a user activation email when user is created" do
    visit login_path
    click_link "Register"
    <...snip...>
  end
end

will fail with the following message:

  1) UserActivations sends a user activation email when user is created
     Screenshot: /Volumes/.../tmp/capybara/screenshot-2012-10-26-15-27-09.png
     Failure/Error: visit login_path
     NoMethodError:
       undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x00000103359158>
     # ./spec/requests/user_activation_spec.rb:6:in `block (2 levels) in <top (required)>'

If I add a context wrapper around the test,

require 'spec_helper'

describe "UserActivations" do
  context "when activating a user" do
    it "sends a user activation email when user is created" do
      visit login_path
      click_link "Register"
      <...snip...>
    end
  end
end

everything works as expected:

UserActivations
  when activating a user
    sends a user activation email when user is created

Finished in 3.42 seconds
1 example, 0 failures

Keep only last screenshots

Is there possible to have only 10 | 50 | 100 last screenshots?

My tmp/ folder quickly turns into a mess when I deal with failing tests.

Not getting any image on error although path specfied

On rspec errors, I get a message

Screenshot: [some file path]

However, there's no file.

I've got the following gem versions:

capybara (2.1.0)
  mime-types (>= 1.16)
  nokogiri (>= 1.3.3)
  rack (>= 1.0.0)
  rack-test (>= 0.5.4)
  xpath (~> 2.0)
capybara-screenshot (0.3.14)
  capybara (>= 1.0, < 3)
  launchy

undefined method `render' for #<Capybara::Selenium::Driver:0xbe790b8>

Hello.

Is there a way to solve this?

My spec_helper.rb has this:
...
require 'capybara/rspec'
require 'capybara/rails'
...
require 'capybara-screenshot/rspec'
...
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end

Capybara.javascript_driver = :chrome
Capybara.default_driver = :chrome

Error occurs whenever test fails or I try to create screenshot manually.

An error occurred in an after hook
NoMethodError: undefined method render' for #<Capybara::Selenium::Driver:0xbe790b8> occurred at C:/VirVit/Ruby200/lib/ruby/gems/2.0.0/gems/capybara-screenshot-0.3.19/lib/capybara-screenshot.rb:73:inblock (2 levels) in <top (required)>'

gemfile.lock is:
capybara (2.2.1)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (> 2.0)
capybara-email (2.3.0)
capybara (
> 2.2.0)
mail
capybara-screenshot (0.3.19)
capybara (>= 1.0, < 3)
launchy

Thank you in advance! :)

Can't work without rails

Failure/Error: prepare_merchant_for_testing!
     NoMethodError:
       undefined method `root' for Rails:Module
     # /Users/pavel/.rvm/gems/ruby-1.9.3-p327/gems/capybara-screenshot-0.3.17/lib/capybara-screenshot.rb:49:in `capybara_root'
     # /Users/pavel/.rvm/gems/ruby-1.9.3-p327/gems/capybara-screenshot-0.3.17/lib/capybara-screenshot/saver.rb:50:in `screenshot_path'
     # /Users/pavel/.rvm/gems/ruby-1.9.3-p327/gems/capybara-screenshot-0.3.17/lib/capybara-screenshot/saver.rb:35:in `save_screenshot'
     # /Users/pavel/.rvm/gems/ruby-1.9.3-p327/gems/capybara-screenshot-0.3.17/lib/capybara-screenshot/saver.rb:19:in `save'
     # /Users/pavel/.rvm/gems/ruby-1.9.3-p327/gems/capybara-screenshot-0.3.17/lib/capybara-screenshot.rb:27:in `screenshot_and_open_image'
     # /Users/pavel/.rvm/gems/ruby-1.9.3-p327/gems/capybara-screenshot-0.3.17/lib/capybara-screenshot/capybara.rb:11:in `screenshot_and_open_image'

Screenshots not taken for selenium drivers not named ':selenium'

We register a selenium Firefox driver named ':firefox'. Screenshots don't get taken for this driver, because saver.rb explicitly checks for a driver named ':selenium'.

Capybara.register_driver :firefox do |app|
  Capybara::Selenium::Driver.new(app, :browser => :firefox)
end

From saver.rb:

case capybara.current_driver
  ...
  when :selenium
    capybara.page.driver.browser.save_screenshot(screenshot_path)
  else
    #Uh-oh!  Our selenium driver named ':firefox' falls through to here and doesn't get handled

Pretty easy to fix by checking responds_to?(:save_screenshot) instead of looking at the driver name -- I'll try to send a pull request.

Screenshot in Rspec breaks model/controller tests when used with webmock

Screenshot seems to run on all examples, regardless of type. Normally this isn't an issue, as it doesn't produce a screenshot if Capybara isn't running. But in a model spec, it still tries, which causes Capybara to fire a request to the test server. Webmock will block this by default, as the request has not been stubbed for the example, causing the test to fail as in the example below.

Real HTTP connections are disabled. 
Unregistered request: GET http://127.0.0.1:7777/__identify__ with headers 
{'Accept'=>'*/*', 'Accept-
Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}

Setting Capybara::Screenshot.autosave_on_failure = false in config.before(:each) does not help since it is checked after if Capybara.page.respond_to?(:save_page), which I assume is what fires off the identify request.

Am I missing a config option here? If none already exists, I think the lowest impact way to fix this would be to add a configuration that allows you to completely disable screenshot for certain test types, or move the Capybara::Screenshot.autosave_on_failure check above the Capybara.page.respond_to?(:save_page) check so that it never launches Capybara unless it needs to.

Let me know if I'm missing something obvious. Otherwise happy to create a pull request.

cucumber require not working correctly in Sinatra app

I am testing a Sinatra app. I followed the docs and used require 'capybara-screenshot/cucumber' in my Cucumber env.rb file. When I ran my test, I got a name error because Capybara::Screenshot was not loaded. I then used require 'capybara-screenshot' (no /cucumber) and it complained about launchy missing. After installing the launchy gem all worked fine. So either the docs are wrong or the code is wrong :-)

Screenshots not being saved on failure, or saved or opened on explicit call

I'm sure this is my own configuration issue, but this used to work and I'm not sure what else to try. If you would prefer this be an issue on SO, just let me know -- I'm trying to follow your instruction in the README by posting here :).

  • capybara 2.1.0
  • capybara-webkit 1.0.0
  • capybara-screenshot 0.3.6
  • qt stable 4.8.4 (bottled)
  • OS X 10.8.3

My, somewhat intense, spec_helper.rb (e.g. I'm making the explicit require call).

A sample spec results in:

Run options: include {:only=>true}

All examples were filtered out; ignoring {:only=>true}

Showroom
  without being logged in
    adding a vehicle from a search result vehicle card
webkit
2013-06-05 10:42:10.556 webkit_server[82805:707] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead.
      drops open the showroom (FAILED - 1)

Failures:

  1) Showroom without being logged in adding a vehicle from a search result vehicle card drops open the showroom
     Screenshot: <project>/tmp/capybara/screenshot_2013-06-05-10-42-16.585.png
     Failure/Error: find("#showroom").should be_visible
     Capybara::ElementNotFound:
       Unable to find css "#showroom"
     # ./spec/features/web/showroom_spec.rb:18:in `block (4 levels) in <top (required)>'

Finished in 6.76 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/features/web/showroom_spec.rb:15 # Showroom without being logged in adding a vehicle from a search result vehicle card drops open the showroom
     Screenshot: <project>/tmp/capybara/screenshot_2013-06-05-10-42-16.585.png

Randomized with seed 3046

But my tmp/capybara directory is empty.

The QT warning is apparently not an issue.

I've tried combinations for passing/failing explicit save/open calls that I can think of, and I always get no image opened, and no images saved, or an error like this (which is probably just because there is no file to open?):

Failure in opening <project>/tmp/capybara/screenshot_2013-06-05-10-40-34.236.png with options {}: No application found to handle '<project>/tmp/capybara/screenshot_2013-06-05-10-40-34.236.png'

Any thoughts? Any help is greatly appreciated!

open the screenshot upon failure

When there is a failure and the screenshot is generated, I'd like to have the screenshot opened immediately in a viewer. Something like open filename would work on Mac. Where would I hook in to do this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.