Usamos bastante o Capybara para fazer testes de integração. Aqui você vê um cheatsheet com as principais funções dessa gem
Visitando páginas
# visitando uma url
visit 'https://campuscode.com.br'
# visitando um caminho relativo
visit '/conteudos'
# também podemos usar os prefixos das rotas
visit root_path
Interação com elementos
# clicar num link, botão ou input submit
click_on 'Criar artigo'
# clicar somente em links
click_link 'Criar artigo'
# clicar somente em botões
click_button 'Criar artigo'
# É sempre bom lembrar que o click_on é um alias para click_link_or_button
Interação com formulários
# preenchendo uma caixa de texto
fill_in 'Nome', with: 'Fulano'
# Selecionando uma opção de select box
select 'Brasil', from: 'Países'
# Marcando e desmarcando checkboxes
check 'Sou maior de 18 anos'
uncheck 'Sou maior de 18 anos'
# Selecionando uma opção de radio buttons
choose 'Um radio button'
# Incluindo um arquivo como attachment
attach_file 'Image', Rails.root.join('/caminho/da/imagem.png')
Limitando a interação
# busca dentro de elementos
#exemplo mais comum
within('div#uma-div') do
fill_in 'Nome', with: 'Fulano'
end
# outro exemplo comum usando um elemento
within('form') do
fill_in 'Nome', with: 'Fulano'
end
# exemplos específicos
within(:xpath, './/div[@id="uma-div"]') do
fill_in 'Nome', with: 'Fulano'
end
within(:css, 'form') do
fill_in 'Nome', with: 'Fulano'
end
within_fieldset('um-fieldset') do
fill_in 'Nome', with: 'Fulano'
end
within_table('uma tabela') do
click_on 'Editar'
end
# executa um iframe e interage com o resultado
within_frame('#iframe') do
click_on 'Editar'
end
# usando find
find('form').fill_in('Nome', with: 'Fulano')
find('div.btn-primary').click
find('input[name="title"]').trigger('focus')
# usando all
# retorna todas as aparições do elemento
all('div.btn')
Asserção
O Capybara tem diversos matchers como page.has_content?('um texto')
ou page.has_css?('div', text: 'Uma div legal')
.
Vamos apresentar os exemplos usando RSpec.
Para mais detalhes recomendamos a documentação do Capybara
# encontra o texto em qualquer elemento da página
expect(page).to have_content('Criar')
# Vale lembrar que todos os seletores tem sua negação
expect(page).to_not have_content('Criar')
# encontra o seletor específico
expect(page).to have_css('div#um-form')
expect(page).to have_css('div#um-form', text: 'Um texto')
# encontrando botões e links
expect(page).to have_link('Criar')
expect(page).to have_button('Criar')
# match de regex na página
expect(page).to have_xpath("//a", href: "campuscode.com.br")
# mais genérico
expect(page).to have_selector(:css, "div#um-form")
expect(page).to have_selector(:xpath, "//a/h3")
# opções para campos
expect(page).to have_checked_field('#um-campo')
expect(page).to have_unchecked_field('#um-campo')
expect(page).to have_field('#um-campo')
expect(page).to have_table('#um-campo')
# caminho da execução
expect(current_path).to eq(root_path)
expect(current_url).to eq(root_url)
Opções comuns
# wait - espera um elemento na tela
fill_in 'Nome', with: 'Fulano', wait: 10
# visible - visibilidade de elementos
click_on 'Editar', visible: false
click_on 'Editar', visible: :both
# count - conta quantidade de elementos
expect(page).to have_link('Apagar', count: 4)
# between, minimum, maximum
expect(page).to have_link('Apagar', between: 4..10)
expect(page).to have_link('Apagar', minimum: 4)
expect(page).to have_link('Apagar', maximum: 4)
Aplicando um script
page.execute_script("$('#um-id').text('CampusCode')")
Outros métodos que podem ser úteis
evaluate_script
using_wait_time
save_page
save_and_open_page
save_screenshot
save_and_open_screenshot
drag_to