Original article: https://hackernoon.com/how-to-integrate-selenium-with-capybara-iq2n30dg
Sometimes you want to know how your capybara
test cases interact with your site, sometimes viewing log on console to find out why test cases are not working is not enough, that’s why you Want to make it show the steps in the browser in real time. You can do this really easily with Selenium, which provides us with the functionality needed to interact with the interface of all popular browsers.
Let’s start by looking at what we will use in this article, you can use your own versions but it is better if they are:
1 2 3 4 5 6 7 | $ lsb_release -a Ubuntu 18.04.4 LTS $ rails -v Rails 6.0.3.1 $ ruby --version ruby 2.6.5p114 (2019–10–01 revision 67812) [x86_64-linux] |
Ok, now we can start creating new projects:
1 2 | $ rails new myApp -T |
We use the -T flag to not initialize the project and test files because we will create these files manually. After the command has finished running, we need to go into the project folder:
1 2 | $ cd myApp |
I always check if the server can run or not to make sure everything works correctly, if any error should be present on the console then I can tell.
1 2 | $ rails s |
If all goes well, we can continue.
To comply with TDD, we first need to create test cases with RSpec and Capybara, so let’s start by adding the required Gem in the development group and testing in Gemfile:
1 2 3 4 5 6 7 8 9 | group <span class="token symbol">:development</span> <span class="token punctuation">,</span> <span class="token symbol">:test</span> <span class="token keyword">do</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> gem <span class="token string">'rspec-rails'</span> <span class="token punctuation">,</span> <span class="token string">'~> 4.0'</span> <span class="token punctuation">,</span> <span class="token string">'>= 4.0.1'</span> gem <span class="token string">'capybara'</span> <span class="token punctuation">,</span> <span class="token string">'~> 3.32'</span> <span class="token punctuation">,</span> <span class="token string">'>= 3.32.2'</span> gem <span class="token string">'selenium-chúng tabdriver'</span> <span class="token punctuation">,</span> <span class="token string">'~> 3.142'</span> <span class="token punctuation">,</span> <span class="token string">'>= 3.142.7'</span> <span class="token keyword">end</span> |
Note, the 3 dots above are meant to indicate the gems already available in your project. Now we can install the gems above (you can also use the bundle install
command, the two commands are the same):
1 2 | $ bundle |
If everything has installed successfully, we need to install, and set up for the gem above, To install RSpec, we just need to run the following command:
1 2 | rails g rspec:install |
Our small rodent friend, Capybara will need a bit more work. First, we need to put the following code in the first line of /spec/rspec_helper.rb
file:
1 2 | <span class="token keyword">require</span> <span class="token string">'capybara/rspec'</span> |
In the file /spec/rails_helper.rb
:
1 2 3 4 5 6 | <span class="token constant">Capybara</span> <span class="token punctuation">.</span> register_driver <span class="token symbol">:selenium_chrome</span> <span class="token keyword">do</span> <span class="token operator">|</span> app <span class="token operator">|</span> <span class="token constant">Capybara</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Selenium</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Driver</span> <span class="token punctuation">.</span> <span class="token keyword">new</span> <span class="token punctuation">(</span> app <span class="token punctuation">,</span> browser <span class="token punctuation">:</span> <span class="token symbol">:chrome</span> <span class="token punctuation">)</span> <span class="token keyword">end</span> <span class="token constant">Capybara</span> <span class="token punctuation">.</span> javascript_driver <span class="token operator">=</span> <span class="token symbol">:selenium_chrome</span> |
We also need to change the use_transactional_fixtures
parameter to false
:
1 2 | config <span class="token punctuation">.</span> use_transactional_fixtures <span class="token operator">=</span> <span class="token boolean">false</span> |
This is the code that shows what the rails_helper.rb
file will look like after all the changes, and delete the comments:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <span class="token keyword">require</span> <span class="token string">'spec_helper'</span> <span class="token constant">ENV</span> <span class="token punctuation">[</span> <span class="token string">'RAILS_ENV'</span> <span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token operator">=</span> <span class="token string">'test'</span> <span class="token keyword">require</span> <span class="token builtin">File</span> <span class="token punctuation">.</span> expand_path <span class="token punctuation">(</span> <span class="token string">'../config/environment'</span> <span class="token punctuation">,</span> __dir__ <span class="token punctuation">)</span> abort <span class="token punctuation">(</span> <span class="token string">'The Rails environment is running in production mode!'</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token constant">Rails</span> <span class="token punctuation">.</span> env <span class="token punctuation">.</span> production <span class="token operator">?</span> <span class="token keyword">require</span> <span class="token string">'rspec/rails'</span> <span class="token keyword">require</span> <span class="token string">'./spec/support/factory_bot'</span> <span class="token keyword">begin</span> <span class="token constant">ActiveRecord</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Migration</span> <span class="token punctuation">.</span> maintain_test_schema <span class="token operator">!</span> <span class="token keyword">rescue</span> <span class="token constant">ActiveRecord</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">PendingMigrationError</span> <span class="token operator">=</span> <span class="token operator">></span> e puts e <span class="token punctuation">.</span> to_s <span class="token punctuation">.</span> strip exit <span class="token number">1</span> <span class="token keyword">end</span> <span class="token constant">Capybara</span> <span class="token punctuation">.</span> register_driver <span class="token symbol">:selenium_chrome</span> <span class="token keyword">do</span> <span class="token operator">|</span> app <span class="token operator">|</span> <span class="token constant">Capybara</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Selenium</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Driver</span> <span class="token punctuation">.</span> <span class="token keyword">new</span> <span class="token punctuation">(</span> app <span class="token punctuation">,</span> browser <span class="token punctuation">:</span> <span class="token symbol">:chrome</span> <span class="token punctuation">)</span> <span class="token keyword">end</span> <span class="token constant">Capybara</span> <span class="token punctuation">.</span> javascript_driver <span class="token operator">=</span> <span class="token symbol">:selenium_chrome</span> <span class="token constant">RSpec</span> <span class="token punctuation">.</span> configure <span class="token keyword">do</span> <span class="token operator">|</span> config <span class="token operator">|</span> config <span class="token punctuation">.</span> fixture_path <span class="token operator">=</span> <span class="token string">" <span class="token interpolation"><span class="token delimiter tag">#{</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Rails</span> <span class="token punctuation">.</span> root <span class="token delimiter tag">}</span></span> /spec/fixtures"</span> config <span class="token punctuation">.</span> use_transactional_fixtures <span class="token operator">=</span> <span class="token boolean">false</span> config <span class="token punctuation">.</span> infer_spec_type_from_file_location <span class="token operator">!</span> config <span class="token punctuation">.</span> filter_rails_from_backtrace <span class="token operator">!</span> <span class="token keyword">end</span> |
In addition, we also need to install chromium chrome driver, If you have not already installed it. For Ubuntu, you just need to run the following command:
1 2 3 | sudo apt-get update sudo apt-get install chromium-chromedriver |
If you use another operating system, you can visit the chromedriver homepage and follow the instructions https://chromedriver.chromium.org/downloads .
Okay, since we have done so many things that we haven’t even written a test case, we can finally write it. We need to create a folder called features
inside the /spec
directory, and inside it, we create the posts_spec.rb
file including our test case.
/spec/features/posts_spec.rb
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">require</span> <span class="token string">'rails_helper'</span> <span class="token constant">RSpec</span> <span class="token punctuation">.</span> describe <span class="token constant">Post</span> <span class="token punctuation">,</span> driver <span class="token punctuation">:</span> <span class="token symbol">:selenium_chrome</span> <span class="token punctuation">,</span> js <span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token keyword">do</span> describe <span class="token string">'the create posts process'</span> <span class="token keyword">do</span> it <span class="token string">'should create a post'</span> <span class="token keyword">do</span> visit new_post_path fill_in <span class="token string">'Title'</span> <span class="token punctuation">,</span> with <span class="token punctuation">:</span> <span class="token string">'Post title'</span> fill_in <span class="token string">'Content'</span> <span class="token punctuation">,</span> with <span class="token punctuation">:</span> <span class="token string">'Post content'</span> click_button <span class="token string">'Create Post'</span> expect <span class="token punctuation">(</span> page <span class="token punctuation">)</span> <span class="token punctuation">.</span> to have_content <span class="token string">'Post was successfully created.'</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
The first line requires the rails_helper
file and loads the code in it, then, as described in the RSpec documentation, we use RSpec.describe
to encapsulate your code according to the test case, it is important that Indicates which specific driver use, in this case, is :selenium_chrome
driver. In addition, we need to enable JavaScript with js: true
because selenium sometimes has problems without it.
And our test case is complete!
However, it will fail, as expected.
Because we still haven’t implemented this feature in our project. But don’t worry, we will do it now. To be able to achieve our goals directly, I will ignore the usual constructs, for example, regarding posts will be a user. In our application, a post will be created anonymously, that is, it is not owned by any user. And to save time, I will use the scaffold
to create a simple CRUD module, just use the following command:
1 2 | $ rails g scaffold Post title content:text |
Then run the migrate database:
1 2 | $ rails db:migrate |
For now, we can access the localhost:3000/posts
in the browser, which lists all the posts created in my application. We still have no posts yet, but we can proceed to create one with the capybara test
, just run the following command:
1 2 | $ rspec spec/features/posts_spec.rb |
Your browser will automatically open and fill out the form.
Now we can celebrate because the test case has been a success!
One final note: make sure this works only with your ruby on rails application, otherwise, not Capybara
running on your site. And that’s all for this article. I hope it will be helpful to you.