_ruby
Example
First let's include our dependent libraries (e.g., selenium-webdriver
to control the browser, rspec/expectations
and RSpec::Matchers
for assertions, and gmail
to access a Gmail account headless) and create some
simple setup
, teardown
, and run
methods to handle our test configuration.
# filename: forgot_password.rb
require 'selenium-webdriver'
require 'rspec-expectations'
include RSpec::Matchers
require 'gmail'
def setup
@driver = Selenium::WebDriver.for :firefox
end
def teardown
@driver.quit
end
def run
setup
yield
teardown
end
Once triggered, the forgot password e-mail should be received quickly. But since we're dealing with a third-party provider we'll want to build in some resiliency. So let's create a simple mechanism to retry our email lookup a configurable number of times and make it wait a handful of seconds in-between each attempt.
def try(number_of_times)
count = 0 ; item_of_interest = nil
until item_of_interest != nil || count == number_of_times
item_of_interest = yield
sleep 10
count += 1
end
end
When calling this method, we will need to specify an integer for the number of times that we'd like to retry an
action. And we'll specify the action by passing it to the method through the use of yield
(which enables us to
pass a block of code into the method just like we're doing for the run
method). Between each attempt, the
method will wait for 10
seconds.
Now let's wire up our test.
run do
@driver.get 'https://the-internet.herokuapp.com/forgot_password'
@driver.find_element(id: 'email').send_keys(ENV['EMAIL_USERNAME'])
@driver.find_element(id: 'form_submit').click
gmail = Gmail.new(ENV['EMAIL_USERNAME'], ENV['EMAIL_PASSWORD'])
try(6) { @email = gmail.inbox.emails(:unread, from: 'no-reply@the-internet.herokuapp.com').last }
message_body = @email.message.body.raw_source
url = message_body.scan(/https?:\/\/[\S]+/).last
username = message_body.scan(/username: (.*)$/)[0][0].strip
password = message_body.scan(/password: (.*)$/)[0][0].strip
@driver.get url
@driver.find_element(id: 'username').send_keys username
@driver.find_element(id: 'password').send_keys password
@driver.find_element(id: 'login').submit
expect(@driver.current_url.include?('/secure')).to eql true
end
We initiate the forgot password workflow by loading the page with the forgot password form, providing an email address, and submitting the form. We then access the Gmail account headless. Notice that the username and password credentials are specified with environment variables, but you could just as easily hard-code your credentials here.
After connecting we attempt to retrieve the message body. Here is where we employ our try
method (retrying the
lookup action up to 6
times). If the inbox lookup doesn't find what it's looking for, it will return nil
,
which will trigger the try
loop to run again after waiting 10
seconds. If it finds what we're looking for,
then the loop will stop running and the test will proceed.
Once the forgot password email is found we parse it's body with regular expressions to find the URL & user credentials in it. We then put these values to use with our browser session (which is still active) by visiting the URL and logging in. Once done we assert that login was successful by checking to see if we gained access to a secure part of the site.
Expected Behavior
If you save this file and run it (e.g., ruby forgot_password.rb
from the command-line) here is what will happen:
- Open the browser
- Visit the page and initiate the forgot password workflow
- Headless access Gmail and retrieve the email message body
- Parse the message body for user credentials
- Visit the site and login with the user credentials
- Check that login was successful
- Close the browser
NOTE: When running this script you can pass in the Gmail account username and password at runtime
(e.g., EMAIL_USERNAME=youremail@gmail.com EMAIL_PASSWORD=yourpassword ruby forgot_password.rb
).
Summary
Your forgot password workflow might be different, so adapt as needed. And if you have other things in an e-mail message body that you need to parse for and aren't sure of the regular expressions you need -- give Rubular a try.
Happy Testing!