I'd like to use Cucumber with Capybara to test my Rails application's Facebook registration procedure by executing the following scenario:
@javascript
Scenario: Connect account
When I go to the home page
And I press "Connect your Facebook account"
And I fill in "test@address" for "Email"
And I fill in "test" for "Password"
And I press "Login"
And I press "Allow"
Then I should be on the dashboard page
How do folks approach the problem of integration testing browser-based Facebook integration? A web search turns up only a couple of blog posts that predate the graph API, and they only seem to discuss implementing a precondition that sets up an environment representing a user already logged in to Facebook.
Some specific issues to address:
How does one simulate clicking the <fb:login-button>
element? The best thing I've come up with (but have yet to test) is to manually fire a click event on the element.
Once the Facebook dialog comes up, does Capybara have access to it? How? This seems required in order to enter the email address and password of a test Facebook account and to install the Facebook app for the test account.
For that matter, how does one manage test accounts? http://developers.facebook.com/docs/test_users/ indicates that test users can be created and deleted with the Graph API, but the API doesn't look to to provide access to an email address or password for a test account, which seems to make them useless for testing this particular flow.
I'm sure I'm overlooking other important issues as well. I sure am curious how other folks have attacked this problem!
I've managed to get this working in rspec acceptance specs with the following code:
https://gist.github.com/1084767
This uses mogli to create and destroy test users and capybara to orchestrate the browser test. I believe you could get it working with Cucumber by removing the shared_context block and using Cucumber before/after hooks, like:
Before '@fb_test_user' do
@fb_user = create_test_user(installed: false)
end
After '@fb_test_user' do
@fb_user.destroy
end
World(FacebookIntegrationHelpers)
i'm currently using the omniauth gem to handle this type of authentication. FBML is deprecated, so I suggest moving to the JS SDK for client side FB interaction. Anyways, if you're using omniauth, you can stub out the response relatively easily by specifying some Before tags in your env folder like so:
Config Success case:
Before('@omniauth_test_success') do
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:facebook] = {
"provider" => "facebook",
"uid" => '12345',
"user_info" => {
"email" => "email@email.com",
"first_name" => "John",
"last_name" => "Doe",
"name" => "John Doe"
# any other attributes you want to stub out for testing
}
}
end
Config Failure Case
Before('@omniauth_test_failure') do
OmniAuth.config.test_mode = true
[:default, :facebook, :twitter].each do |service|
OmniAuth.config.mock_auth[service] = :invalid_credentials
# or whatever status code you want to stub
end
end
Cukes Feature
Scenario: A user unsuccessfully signs in with their email/password
Given I am on the homepage
When I follow "Login"
And I "unsuccessfully" sign in with email and pass
Then I should see "Failed."
@omniauth_test_success
Scenario: A user successfully signs in with Facebook
Given I am on the homepage
And I follow "Login"
When I follow "facebook"
Then I should see "Login successful."
@omniauth_test_failure
Scenario: A user unsuccessfully signs in with Facebook
Given I am on the homepage
And I follow "Login"
When I follow "facebook"
Then I should see "Failed."