Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TEST] Pcaston add tests for recaptcha service #599 #593

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions features/event_management.feature
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ Scenario: Company registration request in PETS
Then I should see "Signed in successfully."
Then I am in User's browser
Given I am on the home page
And I click the "Register as an Employer" button
And I wait 1 second
And I click the "Register as an Employer" link
Then I should see "Request Company Registration"
And I fill in the fields:
| Company Name | Widgets, Inc. |
Expand Down
18 changes: 9 additions & 9 deletions features/job_skills.feature
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ Background: adding job to database
| Skill3 | Long haul driver with Class C license |

Given the following jobs exist:
| title | description | company | creator | shift | skills | city |
| Job1 | About job1. | Widgets Inc. | [email protected] | Day | Skill1, Skill2 | city1 |
| Job2 | About job2. | Widgets Inc. | [email protected] | Day | Skill3 | city2 |
| title | description | company | creator | shift | skills | city |
| Job1 | About job1. | Widgets Inc. | [email protected] | Day | Skill1 | city1 |
| Job2 | About job2. | Widgets Inc. | [email protected] | Day | Skill3 | city2 |


@javascript
Expand Down Expand Up @@ -63,16 +63,16 @@ Scenario: Edit job and change associated skills
And I am logged in as "[email protected]" with password "qwerty123"
And I click the "Jobs" link
Then I click the "Job1" link
And I wait 1 second
And I should see "Skill1"
And I should see "Skill2"
Then I click the "Edit Job" link
And I wait 1 second
And I click the second "remove job skill" link
And I click the first "remove job skill" link
And I click the "Add Job Skill" link
And I select "Skill3" in second select list "Name:"
And I select "Skill3" in first select list "Name:"
And I click the "Add Job Skill" link
And I select "Skill2" in second select list "Name:"
And I press "Update"
Then I should see "Job1 has been updated successfully."
And I should see "Skill1"
And I should see "Skill2"
And I should see "Skill3"
And I should not see "Skill2"
And I should not see "Skill1"
15 changes: 15 additions & 0 deletions features/pages.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Feature: a user clicking contact is verified by a recaptcha

As prospective user of PETS
I want to make contact and send a message

@selenium_browser
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to switch this test to use Selenium, driving a Chrome browser in "visible" mode (both poltergeist, and headless Chrome, failed to work).

I also have to use special recaptcha keys - these were added to the application.yml file - will DM you on slack with that updated file.

See: https://developers.google.com/recaptcha/docs/faq (section on automated tests)

Copy link
Contributor Author

@patmbolger patmbolger Jul 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I forgot to mention that one of the problems you were having with using poltergeist was that phantomjs support for ES2015 (aka ES6) is still a work-in-progress. (ariya/phantomjs#14506).

(Poltergeist uses phantomjs to support js code).

@arun1595 is using ES6 in some of his code (e.g. promise). Poltergeist silently fails when ES6 is encountered, so there is no indication of what caused the test to fail. Going to Chrome as the Selenium browser fixed this issue (but, for these tests, only when I used Chrome in visible (non-headless) mode.)

Scenario: click the contact link
Given I am on the home page
And I click the first "Contact" link
And I fill in "Full Name" with "Charlie Bucket"
And I fill in "Email" with "[email protected]"
And I fill in "Message" with "Hi Metplus"
And I click the recaptcha
And I click the "Send Message" button
Then I should see "Your message was sent successfully!"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest also adding a "sad" path - that is, the user fills out the info but fails to check the "not a robot" box.

32 changes: 25 additions & 7 deletions features/step_definitions/users_steps.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
include ServiceStubHelpers::RecaptchaValidator
Given(/^I have the following Job Seekers$/) do |table|
# table is a table.hashes.keys # => [:email, :password]
table.hashes.each do |seeker|
Expand All @@ -11,14 +12,15 @@
end

When(/^I visit profile for "(\w+)"$/) do |first_name|
user = User.find_by_first_name!(first_name)
visit "/users/edit.#{user.id}"
user = User.find_by_first_name!(first_name)
visit "/users/edit.#{user.id}"
end

Then(/^I should verify the change of first_name "(.*?)", last_name "(.*?)" and phone "(.*?)"$/) do |first_name, last_name, phone|
user = User.find_by_first_name(first_name)
expect(user.last_name).to eql last_name
expect(user.phone).to eql phone
Then(/^I\sshould\sverify\sthe\schange\sof\sfirst_name\s"(.*?)",\s
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is OK but I don't think it is necessary and it makes the regex harder to read.

The pattern /text1 text2/ is treated exactly the same as /text1\stext2/, so the addition of \s is not needed.

last_name\s"(.*?)"\sand\sphone\s"(.*?)"$/x) do |first_name, last_name, phone|
user = User.find_by_first_name(first_name)
expect(user.last_name).to eql last_name
expect(user.phone).to eql phone
end

Then(/^I should( not)? be remembered$/) do |not_remembered|
Expand All @@ -33,10 +35,26 @@
expect(person_type.expires).to be_future
end
end
j

Then(/^I should be logged out$/) do
cookies = page.driver.cookies
expect(cookies['person_type']).to be nil
expect(cookies['user_id']).to be nil
end

Given(/^I click the recaptcha$/) do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra empty line detected at block body beginning.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra empty line detected at block body beginning.

# Override server-side verification of recaptcha response:
# (the recaptcha widget is being served as a separate document within
# an iframe. There does not seem to be a way to simulate user entry
# (checking a box) for the "I'm not a robot" prompt. This is by design
# since the intent is to prevent automated entry that simulates a human.
# Thus, 1) we won't attempt to "check the box", and 2) we will override
# server-side verification to just return true (== verified by Google).

class RecaptchaService
def self.verify(_, _)
true
end
end
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment above explains where I ended up with this step, after trying to simulate a user action (checking the box). The stub method did not work, but simply overriding the verify method does the job.

1 change: 1 addition & 0 deletions features/step_definitions/web_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def search_text(text)
end

And(/^show me the page$/) do
save_and_open_page

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove debugger entry point save_and_open_page.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove debugger entry point save_and_open_page.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to have been dropped in a prior PR. Adding it back ....

end

When(/^(?:I|they) click and accept the "([^"]*)" button$/) do |button_text|
Expand Down
47 changes: 14 additions & 33 deletions features/support/env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
require 'email_spec/cucumber'
require 'capybara/cucumber'
require 'capybara/poltergeist'
require 'webmock/cucumber'
require 'cucumber/rspec/doubles'
require './spec/support/service_stub_helpers'

# Capybara defaults to CSS3 selectors rather than XPath.
# If you'd prefer to use XPath, just uncomment this line and adjust any
Expand Down Expand Up @@ -68,40 +71,18 @@
Cucumber::Rails::Database.javascript_strategy = :truncation

Capybara.default_max_wait_time = 10
# see http://blog.pixarea.com/2013/02/locking-the-firefox-version-when-testing-rails-with-capybara-and-selenium/ for
# details on how to set this up
Capybara.register_driver :selenium do |app|
require 'selenium/webdriver'
# FIREFOX_BINARY_PATH (if used) needs to be the path to the FF executable
Selenium::WebDriver::Firefox::Binary.path =
ENV['FIREFOX_BINARY_PATH'] || Selenium::WebDriver::Firefox::Binary.path
Capybara::Selenium::Driver.new(app, browser: :firefox)
end

Before '@selenium' do
Capybara.current_session.current_window.resize_to(1024, 768)
Capybara.register_driver :selenium_browser do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome
)
end

if ENV['IN_BROWSER']
# On demand: non-headless tests via Selenium/WebDriver
# To run the scenarios in browser (default: Firefox), use the following command line:
# IN_BROWSER=true bundle exec cucumber
# or (to have a pause of 1 second between each step):
# IN_BROWSER=true PAUSE=1 bundle exec cucumber
Capybara.default_driver = :selenium
AfterStep do
sleep(ENV['PAUSE'] || 0).to_i
end
else
# DEFAULT: headless tests with poltergeist/PhantomJS
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(
app,
window_size: [1280, 1024],
js_errors: false,
timeout: 10
# debug: true
)
end
Capybara.javascript_driver = :poltergeist
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
args: ['headless']
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some restructuring to simplify, and also add Chrome as browser option for the Selenium web driver.

end
19 changes: 11 additions & 8 deletions features/support/hooks.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
Before('@javascript') do
# Currently, poltergeist is preferred for headless tests
Capybara.current_driver = :poltergeist
end

Before('@selenium') do
# Note that poltergeist is the preferred web driver for tests that
# require javascript support
Capybara.javascript_driver = :selenium
Before('@selenium_browser') do
# Use this hook for running tests with visible browser ("non-headless")
Capybara.current_driver = :selenium_browser
end

After('@selenium') do
Capybara.reset_sessions!
Capybara.javascript_driver = :poltergeist
Before('@selenium') do
# Use this hook for running headless tests using Chrome
Capybara.current_driver = :selenium
end

After('@javascript') do
After('@javascript, @selenium_browser, @selenium') do
Capybara.reset_sessions!
# force Chrome to quit after each scenario:
page.driver.quit if Capybara.current_driver == :selenium ||
Capybara.current_driver == :selenium_browser
Capybara.current_driver = :rack_test
end
19 changes: 19 additions & 0 deletions spec/services/recaptcha_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'rails_helper'

RSpec.describe RecaptchaService, type: :model do
context 'User login with captcha' do
describe 'verify recaptcha response' do
let!(:captcha_response) { 'XX' }
let!(:ip_address) { '168.140.181.4' }
before :each do
stub_recaptcha_verify
end
it 'should login with correct recaptcha' do
expect(RecaptchaService.verify(captcha_response, ip_address)).to be true
end
it 'is disallowed when no recaptcha' do
expect(RecaptchaService.verify(nil, ip_address)).to be false
end
end
end
end
106 changes: 53 additions & 53 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# This file was generated by the `rails generate rspec:install` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# This file was generated by the `rails generate rspec:install` command.
# Conventionally, allspecs live under a `spec` directory, which RSpec adds to
# the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause
# this file to always be loaded, without a need to explicitly require it in any
# files.
Expand All @@ -25,6 +26,7 @@

Dir['./spec/support/**/*.rb'].each { |f| require f }
include ServiceStubHelpers::EmailValidator
include ServiceStubHelpers::RecaptchaValidator
# WebMock config

# Uncomment to disable Webmock and access external services during test:
Expand Down Expand Up @@ -63,56 +65,54 @@
mocks.verify_partial_doubles = true
end

# The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content.
=begin
# These two settings work together to allow you to limit a spec run
# to individual examples or groups you care about by tagging them with
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
# get run.
config.filter_run :focus
config.run_all_when_everything_filtered = true

# Allows RSpec to persist some state between runs in order to support
# the `--only-failures` and `--next-failure` CLI options. We recommend
# you configure your source control system to ignore this file.
config.example_status_persistence_file_path = "spec/examples.txt"

# Limits the available syntax to the non-monkey patched syntax that is
# recommended. For more details, see:
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
config.disable_monkey_patching!

# Many RSpec users commonly either run the entire suite or an individual
# file, and it's useful to allow more verbose output when running an
# individual spec file.
if config.files_to_run.one?
# Use the documentation formatter for detailed output,
# unless a formatter has already been configured
# (e.g. via a command-line flag).
config.default_formatter = 'doc'
end

# Print the 10 slowest examples and example groups at the
# end of the spec run, to help surface which specs are running
# particularly slow.
config.profile_examples = 10

# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = :random

# Seed global randomization in this process using the `--seed` CLI option.
# Setting this allows you to use `--seed` to deterministically reproduce
# test failures related to randomization by passing the same `--seed` value
# as the one that triggered the failure.
Kernel.srand config.seed
=end
config.example_status_persistence_file_path = "spec/examples.txt"
# The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content.
# # These two settings work together to allow you to limit a spec run
# # to individual examples or groups you care about by tagging them with
# # `:focus` metadata. When nothing is tagged with `:focus`, all examples
# # get run.
# config.filter_run :focus
# config.run_all_when_everything_filtered = true
#
# # Allows RSpec to persist some state between runs in order to support
# # the `--only-failures` and `--next-failure` CLI options. We recommend
# # you configure your source control system to ignore this file.
# config.example_status_persistence_file_path = "spec/examples.txt"
#
# # Limits the available syntax to the non-monkey patched syntax that is
# # recommended. For more details, see:
# # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
# # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
# # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
# config.disable_monkey_patching!
#
# # Many RSpec users commonly either run the entire suite or an individual
# # file, and it's useful to allow more verbose output when running an
# # individual spec file.
# if config.files_to_run.one?
# # Use the documentation formatter for detailed output,
# # unless a formatter has already been configured
# # (e.g. via a command-line flag).
# config.default_formatter = 'doc'
# end
#
# # Print the 10 slowest examples and example groups at the
# # end of the spec run, to help surface which specs are running
# # particularly slow.
# config.profile_examples = 10
#
# # Run specs in random order to surface order dependencies. If you find an
# # order dependency and want to debug it, you can fix the order by providing
# # the seed, which is printed after each run.
# # --seed 1234
# config.order = :random
#
# # Seed global randomization in this process using the `--seed` CLI option.
# # Setting this allows you to use `--seed` to deterministically reproduce
# # test failures related to randomization by passing the same `--seed` value
# # as the one that triggered the failure.
# Kernel.srand config.seed
config.example_status_persistence_file_path = 'spec/examples.txt'
config.include FactoryGirl::Syntax::Methods

config.before(:suite) do
Expand Down Expand Up @@ -146,5 +146,5 @@
config.include(EmailSpec::Helpers)
config.include(EmailSpec::Matchers)

config.pattern = "**/*_spec.rb"
config.pattern = '**/*_spec.rb'
end
Loading