Что такое Capybara

Фреймворк веб-автоматизации функциональных тестов, эмулирующих взаимодействие пользователя с приложением/сайтом. Представляет собой библиотеку (в терминологии Ruby — гем) для работы с web-based-драйвером. Применяется юзер-френдли DSL-язык (Domain Specific Language) описания действий веб-драйвера. Capybara ищет релевантный элемент в DOM и выполняет действие (клик по кнопке, переход по ссылке и все прочее).
Capybara основывается на идее, что в современном веб-приложении практически все происходит асинхронно.
Верификация наличия элемента или проверка какого-то условия — Capybara по умолчанию ожидает появления контента или перехода условия в состояние true. Таймауты можно настраивать.

Поддерживаемые веб-драйверы:
- rack::test: (дефолтный)
- selenium-webdriver
- capybara-WebKit

Ruby-фреймворки для работы с Capybara
Это:
- В первую очередь Cucumber, Ruby-based инструмент для BDD (здесь подробнее о Cucumber и BDD)
- RSpec, BDD-фреймворк, развитие концепции JBehave
- Minitest — пакет для тестирования на Ruby, набор инструментов для TDD и BDD с моками и бенчмарками
Плюсы Cabybara
- Несложная настройка для Rails и Rack, все работает из коробки
- Интуитивное API
- Быстрое переключение бекенда из headless-режима в реальный браузер без внесения изменений в тесты
- Мощная синхронизация — не нужно задавать вручную ожидание в асинхронных процессах
- Встроенная поддержка Selenium
- А WebKit поддерживается через внешний гем
Подключение других инструментов
Начальная настройка:
brew install ruby brew cask install chromedriver gem install bundler gem install cucumber selenium-webdriver gem install rspec cucumber - init. // Create cucumber based test folder strucuture rspec - init. // Create RPSec based test folder structure bundle init. bundle gem <Project_Name> bundle install // Install dependency mentioned in Gemfile
В данном случае работаем с указанными выше тестовыми фреймворками RSpec и MiniTest. В принципе, можно работать с любым из них. Конфигурация:

(Перед тем как ознакомиться, как работает Capybara, желательно посмотреть ее методы.)
Проект в Capybara
Состоит из следующих компонентов:
env.rb
Здесь конфигурация драйверов:
require "selenium-webdriver"
require "capybara"
require "cucumber"
require "rubygems"
require "capybara/cuprite"
require "allure-cucumber"
require "capybara-screenshot/cucumber"
World(Capybara::DSL)
Capybara.threadsafe = true
Before do |scenario|
Capybara.save_path = "screenshot"
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
if ENV["BROWSER"] == "chrome"
Capybara.default_driver = :chrome
$driver = Capybara::Session.new(:chrome)
Capybara.javascript_driver = :chrome
log("Chrome driver is getting instantiated")
elsif ENV["BROWSER"] == "firefox"
Capybara.default_driver = :firefox
Capybara.register_driver :firefox do |app|
options = {
:js_errors => true,
:timeout => 360,
:debug => false,
:inspector => false,
}
Capybara::Selenium::Driver.new(app, :browser => :firefox)
end
else
Capybara.default_driver = :cuprite
$driver = Capybara::Session.new(:cuprite)
log("Headless chrome driver is getting instantiated is getting instantiated")
end
log(ENV["BROWSER"])
log("Driver instacne has been created for Scenarios")
end
After do |scenario|
if scenario.failed?
timestamp = "#{Time.zone.now.strftime("%Y-%m-%d-%H:%M:%S")}"
end
Capybara.reset_sessions!
end
############ Adding Alure Report #############
# Allure
AllureCucumber.configure do |c|
c.results_directory = "report/allure-results"
c.clean_results_directory = true
c.link_tms_pattern = "https://example.org/tms/{}"
c.link_issue_pattern = "https://example.org/issue/{}"
c.tms_prefix = "TMS_"
c.issue_prefix = "ISSUE_"
end
features-файл
Здесь будут сценарии, в BDD-формате:
#features/githubhome.feature
@regression
@SEVERITY:trivial @ISSUE:YZZ-100 @TMS:9901
Feature: Github homepage
Scenario: Github homepage loads properly
Given I am on github homepage
Then the title of the page should be "GitHub: Where the world builds software · GitHub"
Scenario: Sign in to github page
Given I am on github homepage
When I click on sign in button
Then the title of the page should be "Sign in to GitHub · GitHub"
Scenario: Sign up to github page
Given I am on github homepage
When I click on sign up button
Then the page should have "Create your account"
Scenario: Sign up to github page
Given I am on github homepage
When I click on sign up button
And I Enter details for account creation
Then the page should have "Create your account"
Step definition
DSL-код для выполнения тестов:
require "capybara" require "capybara/dsl" require "rspec" require_relative "../support/page_module" World(Capybara::DSL) include Pages Given(/^I am on github homepage$/) do visit "http://www.github.com" end When(/^I click on sign in button$/) do signin = Pages::SignIn.new signin.signin_github end When(/^I click on sign up button$/) do signup = Pages::SignUp.new signup.click_on_signup end And(/^I Enter details for account creation$/) do signup = Pages::SignUp.new signup.signup_github end Then(/^the title of the page should be "(.*)"$/) do |titleText| expect(@browser.title).to be == titleText end Then(/^the page should have "(.*)"$/) do |pageContent| expect(page).to have_content(pageContent) end
page_module.rb
Инкапсулированные page object и действия.
Можно применять разные гемы типа“page-object” и“prism” для написания тест-кейсов в POM.
(Если возникают трудности с пониманием Page Object Model, здесь большой подробный гайд).
require "capybara/dsl"
World(Capybara::DSL)
module Pages
include Capybara::DSL
class SignIn
def signin_github
find(:xpath, '//a[@class="HeaderMenu-link no-underline mr-3"]').click
end
end
class SignUp
def click_on_signup
find(:xpath, '//a[@class="HeaderMenu-link d-inline-block no-underline border border-gray-dark rounded-1 px-2 py-1"]').click
end
def signup_github
find(:xpath, '//input[@id="user_login"]').set("mk")
find(:xpath, '//input[@id="user_email"]').set("mk@gmail.com")
find(:xpath, '//input[@id="user_password"]').set("mkgmailcom")
end
end
end
Rakefile
Инструмент для управления тасками и автоматизации билда. Здесь прописываются (и группируются) таски (задачи), и описываются зависимости в namespace.
Можно вызвать нужные таски и указать им “<browser name>” как параметр, чтобы запустить только в этом браузере. Также прописывается тег в таске, чтобы запустить только один нужный тест (или набор тестов одного предназначения), например @smoke или @regression.
require "rubygems"
require "cucumber"
require "cucumber/rake/task"
require "rake/clean"
require "rake/testtask"
require "rspec/core/rake_task"
CLEAN.include("*.tmp")
CLOBBER.include("*.tmp", "build/*")
CLEAN.include(".html")
task :default => ["clean"]
task :clean do
rm_rf "screenshot/*"
end
Cucumber::Rake::Task.new(:run_features, "This is my cucumber rake task") do |t, args|
#t.profile = "runCucumberTest"
# comment below line of code to use this line of code.both have same purpose.
t.cucumber_opts = %w{--tags @regression}
end
task :runCucumberTest, [:arg1] do |t, args|
puts "Args were: #{args} of class #{args.class}"
puts "arg1 was: '#{args[:arg1]}' of class #{args[:arg1].class}"
ENV["BROWSER"] = args.arg1
puts "Env browse name, #{args.arg1}"
Rake::Task[:run_features].invoke()
end
task :default => [:runCucumberTest]
########### Running MiniTest task *****************
Rake::TestTask.new(:runMiniTest) do |t|
t.pattern = "test/*.rb"
end
task :runMiniTest do |t|
Rake::TestTask[:minitest].invoke()
end
############ Running RSpec Task ##############
task :runRSpecTest, [:arg1] do |t, args|
puts "Args were: #{args} of class #{args.class}"
puts "arg1 was: '#{args[:arg1]}' of class #{args[:arg1].class}"
ENV["BROWSER"] = args.arg1
puts "Env browse name, #{args.arg1}"
Rake::Task[:runRSpecTest].invoke()
end
RSpec::Core::RakeTask.new(:runRSpecTest) do |t|
t.pattern = "spec/*_spec.rb"
t.rspec_opts = "--tag regression"
end
Запуск таска, командой:
$rake 'runCucumberTest['chrome']
Что такое RSpec
RSpec (официальный сайт) — инструмент тестирования для Ruby, заточенный под BDD-тестирование. Наиболее часто применяемая QA-библиотека для Ruby. Несмотря на широкий набор функций и наличие DSL, достаточно прост для новичка.
Отличия от Cucumber DSL:

RSpec создает папку ‘spec’ с тестами. Кроме ‘env.rb’, есть файт ‘spec_helper.rb’, загружающий все Rails-окружение, многочисленные helper-файлы и параметры конфигурации.
В RSpec применяются два способа создания экземпляра драйвера. Первый: регистрация драйвера в spec_helper, создание экземпляра, и применение во всех spec-файлах. Пример:
require "selenium/webdriver"
require "capybara"
require "capybara/cuprite"
require "capybara-screenshot/rspec"
require "capybara/rspec"
Capybara.configure do |config|
config.default_max_wait_time = 10 # seconds
config.default_driver = :firefox
end
RSpec.configure do |config|
config.include Capybara::DSL
end
include Capybara::DSL
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
if ENV["BROWSER"] == "chrome"
Capybara.default_driver = :chrome
@driver = Capybara::Selenium::Driver.new(:chrome)
elsif ENV["BROWSER"] == "firefox"
Capybara.register_driver :firefox do |app|
Capybara::Selenium::Driver.new(app, :browser => :firefox)
end
Capybara.default_driver = :firefox
@driver = Capybara::Selenium::Driver.new(:firefox)
else
Capybara.default_driver = :cuprite
@driver = Capybara::Session.new(:cuprite)
end
#######githubuser_spec.rb
require 'page_module'
require "spec_helper"
RSpec.describe "Github home page" do
before :each do
visit "http://www.github.com"
end
context "Creating GitHub Page user account" do
it "Github homepage loads properly", smoke: true do
expect(@session.title).to be == "GitHub: Where the world builds software · GitHub"
end
it "Sign in to github page", smoke: true do
signin = Pages::SignIn.new(@session)
signin.signin_github
end
it "Sign up to github page", smoke: true do
signup = Pages::SignUp.new(@session)
signup.click_on_signup
signup.signup_github
end
end
after :each do
@session.reset_session!
end
end
Второй способ: ‘named session’, создающая несколько сессий из одного драйвера. Пример такого кода — внизу в ссылках.
Запуск теста RSpec
Из терминала:
$ bundle exec rspec spec/githubuser_spec.rb
$bundle exec rspec spec/*.rb
Через Rake: указывается, в каком браузере запускать. Также можно в Rakefile указать ‘-tag’.
$rake ‘runRpecTest[‘chrome’]’
Из Test Explorer:
Все RSpec-тесты отображаются в TestExplorer, можно выбрать нужный и запустить:

Minitest
Пакет для тестирования под Ruby, поддерживающий TDD (что это?), BDD, моки и бенчмарки. Небольшой, быстрый, нацеленный на легкую читаемость тестов. Кроме модульных и интеграционных тестов (это его традиционное применение), можно тестировать контроллеры.
Как и в Cucumber и RSpec, здесь есть ‘test_helper.rb’. В примере ниже не включен код инициализации драйвера, только добавлен в файл класса.
require "capybara/minitest"
require "minitest/autorun"
require_relative "test_helper"
class HomeSpec < Minitest::Test
include Capybara::DSL
def setup
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.default_driver = :selenium_chrome
# Capybara.save_path = "test/tmp"
end
def test_mk
assert_equal "1", "2"
end
def test_hello
visit "http://www.github.com"
assert_content "Homepage"
page.must_have_content "Homepage"
end
end
Запуск:
$ruby test/github_minitest.rb

На этом всё. Если нужно подробнее, пишите в коменты или в ТГ.
Ссылки
- https://github.com/teamcapybara/capybara
- https://github.com/mattheworiordan/capybara-screenshot#better-looking-html-screenshots
- https://github.com/allure-framework/allure-ruby
- https://makandracards.com/makandra/14017-useful-methods-to-process-tables-in-cucumber-step-definitions
- https://rdoc.info/gems/kosmas58-cucumber/0.3.102/Cucumber/Ast/Table
- https://www.rubydoc.info/gems/capybara/Capybara
***