2017 refactor
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
Feature: Conferences
|
||||
Scenario: Multiple conferences can be displayed on the list page
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And an upcoming regional conference in 'Yellowknife'
|
||||
And a past conference in 'New Orleans'
|
||||
And I am on the conferences page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
And see 'Yellowknife'
|
||||
And see 'New Orleans'
|
||||
|
||||
Scenario: Only public conferences are displayed on the conference list page
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And an upcoming regional conference in 'Yellowknife'
|
||||
And a past conference in 'New Orleans'
|
||||
But it is not public
|
||||
And I am on the conferences page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
And see 'Yellowknife'
|
||||
But I should not see 'New Orleans'
|
||||
|
||||
Scenario: Non-public conferences can be seen by hosts
|
||||
Given there is an upcoming regional conference in 'Yellowknife'
|
||||
And a past conference in 'New Orleans'
|
||||
And an upcoming conference in 'Brooklyn NY'
|
||||
But the conference is not public
|
||||
And the conference is not featured
|
||||
And I am logged in
|
||||
And I am a conference host
|
||||
And I am on the conferences page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
And see 'Yellowknife'
|
||||
And see 'New Orleans'
|
||||
|
||||
Scenario: Site administrators should be able to create and edit conferences
|
||||
Given there is an upcoming regional conference in 'Yellowknife'
|
||||
And a past conference in 'New Orleans'
|
||||
And an upcoming conference in 'Brooklyn NY'
|
||||
And I am logged in
|
||||
And I am an admin
|
||||
|
||||
But the conference is not public
|
||||
And the conference is not featured
|
||||
And I am on the conferences page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
And see 'Yellowknife'
|
||||
And see 'New Orleans'
|
||||
And see a 'Create' link
|
||||
And see an 'Edit' link
|
||||
|
||||
Scenario: Conference info page shows conference details
|
||||
Given there is an upcoming regional conference in 'Yellowknife'
|
||||
And a past conference in 'New Orleans'
|
||||
And an upcoming conference in 'Brooklyn NY'
|
||||
And I am on the conference page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
But I should not see 'Yellowknife'
|
||||
And not see 'New Orleans'
|
||||
And not see 'More info'
|
||||
And not see a 'Register' link
|
||||
And I should not see an 'Administrate' link
|
||||
And I should not see an 'Edit' link
|
||||
|
||||
Scenario: Conference info page shows a register link
|
||||
Given there is an upcoming regional conference in 'Yellowknife'
|
||||
And a past conference in 'New Orleans'
|
||||
And an upcoming conference in 'Brooklyn NY'
|
||||
And registration is open
|
||||
And I am on the conference page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
But I should not see 'Yellowknife'
|
||||
And not see 'New Orleans'
|
||||
And not see 'More info'
|
||||
But I should see a 'Register' link
|
||||
And I should not see an 'Administrate' link
|
||||
And I should not see an 'Edit' link
|
||||
|
||||
Scenario: Conferences that are not public cannot be viewed
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
But it is not public
|
||||
And I am logged in
|
||||
And I am on the conference page
|
||||
|
||||
Then I should not see 'Brooklyn'
|
||||
But I should see 'Access Denied'
|
||||
And I should not see an 'Edit' link
|
||||
|
||||
Scenario: Conferences that are not public can be viewed by hosts
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am logged in
|
||||
And I am a conference host
|
||||
And I am on the conference page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
But I should not see 'Access Denied'
|
||||
And I see an 'Administrate' link
|
||||
And I should not see an 'Edit' link
|
||||
|
||||
Scenario: Site administrators should be able to view and edit conferences
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am logged in
|
||||
And I am an admin
|
||||
And I am on the conference page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
But I should not see 'Access Denied'
|
||||
And I see an 'Administrate' link
|
||||
And I should not see an 'Edit' link
|
||||
@@ -0,0 +1,40 @@
|
||||
Feature: Contact Us
|
||||
Scenario: Contact the site administrator
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Contact Us' link
|
||||
|
||||
When I click the 'Contact Us' link
|
||||
|
||||
Then I should see 'What are you contacting us about?'
|
||||
Then I should see 'Email address'
|
||||
And I enter my email
|
||||
And select 'Something about the website'
|
||||
And enter a subject as 'My Contact Subject'
|
||||
And enter a message as 'My contact message'
|
||||
And press 'send'
|
||||
|
||||
Then I should be on the contact_sent page
|
||||
And I should see 'Thank you for contacting us'
|
||||
|
||||
And the site administrator should get two 'My contact subject' emails
|
||||
And the site administrator should get a 'Details for' email
|
||||
|
||||
Scenario: Contact the site administrator from the contact page
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am logged in
|
||||
And I am on the contact page
|
||||
|
||||
Then I should see 'What are you contacting us about?'
|
||||
And I should not see 'Email address'
|
||||
And select 'Something about the website'
|
||||
And enter a subject as 'My Contact Subject'
|
||||
And enter a message as 'My contact message'
|
||||
And press 'send'
|
||||
|
||||
Then I should be on the contact_sent page
|
||||
And I should see 'Thank you for contacting us'
|
||||
|
||||
And the site administrator should get two 'My contact subject' emails
|
||||
And the site administrator should get a 'Details for' email
|
||||
@@ -1,14 +1,49 @@
|
||||
Feature: Landing Page
|
||||
In order to learn about Bike!Bike!
|
||||
As a visitor
|
||||
In order to learn about Bike!Bike!
|
||||
As a visitor
|
||||
|
||||
Scenario: See a more info link
|
||||
Given There is an upcoming conference in Halifax NS
|
||||
And I am on the landing page
|
||||
Then I see the Bike!Bike! logo
|
||||
Scenario: A more info link is displayed before registration is open
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'More info' link
|
||||
|
||||
Scenario: A registration link is displayed when registration is open
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And Registration is open
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'More info' link
|
||||
And see a 'Register' link
|
||||
And see 'Brooklyn'
|
||||
|
||||
Scenario: Multiple conferences can be displayed on the front page
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And There is an upcoming regional conference in 'Yellowknife'
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
And see 'Yellowknife'
|
||||
And see 'Northwest Territories'
|
||||
|
||||
Scenario: Conferneces don't require a poster or date
|
||||
Given there is an upcoming conference in 'Drumheller AB'
|
||||
But the conference has no poster
|
||||
And it has no date
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see 'Drumheller'
|
||||
And see 'Alberta'
|
||||
|
||||
Scenario: Only public and featured conferences are displayed on the front page
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And there is an upcoming regional conference in 'Portland OR'
|
||||
But it is not featured
|
||||
And there is an upcoming regional conference in 'Prince Rupert BC'
|
||||
But it is not public
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see 'Brooklyn'
|
||||
But I should not see 'Portland'
|
||||
And I should not see 'Prince Rupert'
|
||||
|
||||
Scenario: See a register link
|
||||
Given There is an upcoming conference in Sackville NB
|
||||
And Registration is open
|
||||
And I am on the landing page
|
||||
And I see a Register link
|
||||
|
||||
@@ -0,0 +1,606 @@
|
||||
Feature: Registration
|
||||
Scenario: Registration can really happen
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And registration is open
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Register' link
|
||||
|
||||
When I click the 'Register' link
|
||||
Then I should be on the register page
|
||||
And I should see 'Registration is now open'
|
||||
|
||||
When I enter my email address
|
||||
And press confirm email
|
||||
Then I should see 'Confirm Email'
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should see 'Safer Space Agreement'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Donation'
|
||||
And I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
But I should not see the 'Contact Info' link
|
||||
And I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I click on the 'I Agree' button
|
||||
Then I should see 'What is your name?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Donation'
|
||||
And I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
But I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I enter my name
|
||||
And fill in my location with 'Seattle'
|
||||
And click the 'Next' button
|
||||
Then I should see 'Do you need a place to stay?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Donation'
|
||||
And I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Your Visit' link
|
||||
But I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
And I should see 'Your location was corrected from "Seattle" to "Seattle, Washington, United States"'
|
||||
|
||||
When I check 'Indoor Location'
|
||||
And I check 'Yes'
|
||||
And I check 'Omnivore'
|
||||
And click the 'Register' button
|
||||
Then I should see 'Propose a Workshop'
|
||||
And I should get a 'Thank you for registering for Bike!Bike! 2025' email
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Donation'
|
||||
|
||||
And I should not see 'Hosting'
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Your Visit' link
|
||||
And I should see the 'Workshops' link
|
||||
But I should not see the 'Donation' link
|
||||
|
||||
Scenario: Housing providers can register
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And registration is open
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Register' link
|
||||
|
||||
When I click the 'Register' link
|
||||
Then I should be on the register page
|
||||
And I should see 'Registration is now open'
|
||||
|
||||
When I enter my email address
|
||||
And press confirm email
|
||||
Then I should see 'Confirm Email'
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should see 'Safer Space Agreement'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Donation'
|
||||
And I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
But I should not see the 'Contact Info' link
|
||||
And I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I click on the 'I Agree' button
|
||||
Then I should see 'What is your name?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Donation'
|
||||
And I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
But I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I enter my name
|
||||
And fill in my location with 'Brooklyn'
|
||||
And click the 'Next' button
|
||||
Then I should see 'Can you provide housing to attendees visiting the city?'
|
||||
And I should not see 'Do you need a place to stay?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Hosting'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Your Visit'
|
||||
And I should not see 'Donation'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Hosting' link
|
||||
But I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
And I should see 'Your location was corrected from "Brooklyn" to "Brooklyn, New York, United States"'
|
||||
And I should see 'I can provide housing'
|
||||
But I should not see 'Your address and phone number will be shared with your guests and conference organizers'
|
||||
|
||||
When I check 'I can provide housing'
|
||||
Then I should see 'Your address and phone number will be shared with your guests and conference organizers'
|
||||
|
||||
When I enter my address
|
||||
And enter my phone
|
||||
And enter my bed space as '2'
|
||||
When I press the 'Next' button
|
||||
Then I should get a 'Thank you for registering for Bike!Bike! 2025' email
|
||||
And I should see 'Propose a Workshop'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Hosting' link
|
||||
And I should see the 'Workshops' link
|
||||
But I should not see the 'Donation' link
|
||||
|
||||
Scenario: Housing providers who are not intending to register can register
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And registration is open
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Register' link
|
||||
|
||||
When I click the 'Register' link
|
||||
Then I should be on the register page
|
||||
And I should see 'Registration is now open'
|
||||
|
||||
When I enter my email address
|
||||
And press confirm email
|
||||
Then I should see 'Confirm Email'
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should see 'Safer Space Agreement'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Donation'
|
||||
And I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
But I should not see the 'Contact Info' link
|
||||
And I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I click on the 'I Agree' button
|
||||
Then I should see 'What is your name?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Donation'
|
||||
And I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
But I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I enter my name
|
||||
And fill in my location with 'Brooklyn'
|
||||
And click the 'Next' button
|
||||
Then I should see 'Can you provide housing to attendees visiting the city?'
|
||||
And I should not see 'Do you need a place to stay?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Hosting'
|
||||
And see 'Workshops'
|
||||
But I should not see 'Your Visit'
|
||||
And I should not see 'Donation'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Hosting' link
|
||||
But I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
And I should see 'Your location was corrected from "Brooklyn" to "Brooklyn, New York, United States"'
|
||||
And I should see 'I can provide housing'
|
||||
But I should not see 'Your address and phone number will be shared with your guests and conference organizers'
|
||||
|
||||
When I check 'I can provide housing'
|
||||
Then I should see 'Your address and phone number will be shared with your guests and conference organizers'
|
||||
|
||||
When I enter my address
|
||||
And enter my phone
|
||||
And enter my bed space as '2'
|
||||
And check 'I will not be attending the conference'
|
||||
When I press the 'Next' button
|
||||
Then I should get a 'Thank you for registering for Bike!Bike! 2025' email
|
||||
And I should not see 'Propose a Workshop'
|
||||
But I should see 'Can you provide housing to attendees visiting the city?'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Hosting' link
|
||||
And I should not see the 'Workshops' link
|
||||
But I should not see the 'Donation' link
|
||||
|
||||
Scenario: Users who live in neighbouring towns cannot be hosts by default
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And registration is open
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Register' link
|
||||
|
||||
When I click the 'Register' link
|
||||
Then I should be on the register page
|
||||
|
||||
When I enter my email address
|
||||
And press confirm email
|
||||
Then I should see 'Confirm Email'
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should see 'Safer Space Agreement'
|
||||
|
||||
When I click on the 'I Agree' button
|
||||
Then I should see 'What is your name?'
|
||||
|
||||
When I enter my name
|
||||
And fill in my location with 'Newark NJ'
|
||||
And click the 'Next' button
|
||||
Then I should not see 'Can you provide housing to attendees visiting the city?'
|
||||
|
||||
Scenario: Users who live in neighbouring towns can be housing providers if a radius is entered
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And the conference accepts housing providers that live within 100km
|
||||
And registration is open
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Register' link
|
||||
|
||||
When I click the 'Register' link
|
||||
Then I should be on the register page
|
||||
And I should see 'Registration is now open'
|
||||
|
||||
When I enter my email address
|
||||
And press confirm email
|
||||
Then I should see 'Confirm Email'
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should see 'Safer Space Agreement'
|
||||
|
||||
When I click on the 'I Agree' button
|
||||
Then I should see 'What is your name?'
|
||||
|
||||
When I enter my name
|
||||
And fill in my location with 'Newark'
|
||||
And click the 'Next' button
|
||||
Then I should see 'Can you provide housing to attendees visiting the city?'
|
||||
|
||||
Scenario: Users can pay for registration
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And the conference accepts paypal
|
||||
And registration is open
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Register' link
|
||||
|
||||
When I click the 'Register' link
|
||||
Then I should be on the register page
|
||||
And I should see 'Registration is now open'
|
||||
|
||||
When I enter my email address
|
||||
And press confirm email
|
||||
Then I should see 'Confirm Email'
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should see 'Safer Space Agreement'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
But I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
But I should not see the 'Contact Info' link
|
||||
And I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I click on the 'I Agree' button
|
||||
Then I should see 'What is your name?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
But I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
But I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I enter my name
|
||||
And fill in my location with 'Seattle'
|
||||
And click the 'Next' button
|
||||
Then I should see 'Do you need a place to stay?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
But I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Your Visit' link
|
||||
But I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
And I should see 'Your location was corrected from "Seattle" to "Seattle, Washington, United States"'
|
||||
|
||||
When I check 'Indoor Location'
|
||||
And I check 'Yes'
|
||||
And I check 'Omnivore'
|
||||
And click the 'Register' button
|
||||
Then I should see 'Registration Fees'
|
||||
And I should get a 'Thank you for registering for Bike!Bike! 2025' email
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
|
||||
And I should not see 'Hosting'
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Your Visit' link
|
||||
And I should see the 'Donation' link
|
||||
But I should not see the 'Workshops' link
|
||||
|
||||
And I should see '$25.00'
|
||||
And I should see '$50.00'
|
||||
And I should see '$100.00'
|
||||
And I should see 'Custom amount'
|
||||
And I should see 'Skip'
|
||||
|
||||
When I click the '$50.00' button
|
||||
And finish with paypal
|
||||
Then I should see 'Please confirm your payment'
|
||||
And see 'You are about to confirm your payment of $50.00 for registration'
|
||||
|
||||
When I click the 'Confirm' button
|
||||
Then I should see 'You have made a payment of $50.00'
|
||||
And see 'Thank you!'
|
||||
|
||||
When I click the 'Skip' button
|
||||
Then I should see 'Propose a Workshop'
|
||||
|
||||
Scenario: Users can fail to pay for registration
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And the conference accepts paypal
|
||||
And registration is open
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Register' link
|
||||
|
||||
When I click the 'Register' link
|
||||
Then I should be on the register page
|
||||
And I should see 'Registration is now open'
|
||||
|
||||
When I enter my email address
|
||||
And press confirm email
|
||||
Then I should see 'Confirm Email'
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should see 'Safer Space Agreement'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
But I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
But I should not see the 'Contact Info' link
|
||||
And I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I click on the 'I Agree' button
|
||||
Then I should see 'What is your name?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
But I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
But I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I enter my name
|
||||
And fill in my location with 'Seattle'
|
||||
And click the 'Next' button
|
||||
Then I should see 'Do you need a place to stay?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
But I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Your Visit' link
|
||||
But I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
And I should see 'Your location was corrected from "Seattle" to "Seattle, Washington, United States"'
|
||||
|
||||
When I check 'Indoor Location'
|
||||
And I check 'Yes'
|
||||
And I check 'Omnivore'
|
||||
And click the 'Register' button
|
||||
Then I should see 'Registration Fees'
|
||||
And I should get a 'Thank you for registering for Bike!Bike! 2025' email
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
|
||||
And I should not see 'Hosting'
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Your Visit' link
|
||||
And I should see the 'Donation' link
|
||||
But I should not see the 'Workshops' link
|
||||
|
||||
And I should see '$25.00'
|
||||
And I should see '$50.00'
|
||||
And I should see '$100.00'
|
||||
And I should see 'Custom amount'
|
||||
And I should see 'Skip'
|
||||
|
||||
When I click the '$50.00' button
|
||||
But I don't finish with paypal
|
||||
Then I should see 'Please confirm your payment'
|
||||
Then I should see 'Registration Fees'
|
||||
And see 'You are about to confirm your payment of $50.00 for registration'
|
||||
|
||||
When I click the 'Confirm' button
|
||||
Then I should not see 'You have made a payment of $50.00'
|
||||
But I should see 'Your payment was not completed'
|
||||
|
||||
Scenario: Users can decide not to pay for registration
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And the conference accepts paypal
|
||||
And registration is open
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Register' link
|
||||
|
||||
When I click the 'Register' link
|
||||
Then I should be on the register page
|
||||
And I should see 'Registration is now open'
|
||||
|
||||
When I enter my email address
|
||||
And press confirm email
|
||||
Then I should see 'Confirm Email'
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should see 'Safer Space Agreement'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
But I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
But I should not see the 'Contact Info' link
|
||||
And I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I click on the 'I Agree' button
|
||||
Then I should see 'What is your name?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
But I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
But I should not see the 'Your Visit' link
|
||||
And I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
When I enter my name
|
||||
And fill in my location with 'Seattle'
|
||||
And click the 'Next' button
|
||||
Then I should see 'Do you need a place to stay?'
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
But I should not see 'Hosting'
|
||||
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Your Visit' link
|
||||
But I should not see the 'Donation' link
|
||||
And I should not see the 'Workshops' link
|
||||
|
||||
And I should see 'Your location was corrected from "Seattle" to "Seattle, Washington, United States"'
|
||||
|
||||
When I check 'Indoor Location'
|
||||
And I check 'Yes'
|
||||
And I check 'Omnivore'
|
||||
And click the 'Register' button
|
||||
Then I should see 'Registration Fees'
|
||||
And I should get a 'Thank you for registering for Bike!Bike! 2025' email
|
||||
And I should see 'Policy'
|
||||
And see 'Contact Info'
|
||||
And see 'Your Visit'
|
||||
And see 'Workshops'
|
||||
And see 'Donation'
|
||||
|
||||
And I should not see 'Hosting'
|
||||
And I should see the 'Policy' link
|
||||
And I should see the 'Contact Info' link
|
||||
And I should see the 'Your Visit' link
|
||||
And I should see the 'Donation' link
|
||||
But I should not see the 'Workshops' link
|
||||
|
||||
And I should see '$25.00'
|
||||
And I should see '$50.00'
|
||||
And I should see '$100.00'
|
||||
And I should see 'Custom amount'
|
||||
And I should see 'Skip'
|
||||
|
||||
When I click the 'Skip' button
|
||||
Then I should see 'Propose a Workshop'
|
||||
@@ -0,0 +1,72 @@
|
||||
Feature: Conference Schedule
|
||||
|
||||
Scenario: View published schedule
|
||||
Given that there is an upcoming conference
|
||||
And registration is open
|
||||
And I am logged in
|
||||
And registered
|
||||
|
||||
And the event locations are:
|
||||
| Title | Address |
|
||||
| The Shop | 1027 Flatbush Ave |
|
||||
| The Co-op | 1415 Cortelyou Rd |
|
||||
|
||||
And the workshop times are:
|
||||
| Time | Length | Days |
|
||||
| 9:00 | 1 hour 30 minutes | Tuesday, Wednesday |
|
||||
| 10:30 | 1 hour 30 minutes | Tuesday, Wednesday |
|
||||
| 1:30 | 1 hour 30 minutes | Tuesday, Wednesday |
|
||||
| 3:00 | 1 hour | Tuesday, Wednesday |
|
||||
|
||||
And the schedule on Tuesday is:
|
||||
| The Shop | The Co-op |
|
||||
| How to teach “hands off” | Volunteer Retention and Burnout |
|
||||
| Reaching New Immigrants | Winter Riding Skill-share |
|
||||
| Recycled Bike Art! | Yoga for Cyclists |
|
||||
| Vanquishing the Storage Monster | Battlefield: Consensus! |
|
||||
|
||||
And the schedule on Wednesday is:
|
||||
| The Shop | The Co-op |
|
||||
| Bike Advocacy/Working with the City | Confronting car culture |
|
||||
| Bike Book Club! | Mobile Repair Clinic |
|
||||
| Bike Sharing! | Recycled bike art |
|
||||
| Classes, Workshops, Space | Software developers exchange |
|
||||
|
||||
And the workshop schedule is not published
|
||||
And I am on the conference page
|
||||
|
||||
Then I should see 'Bike!Bike! 2025'
|
||||
And see 'Proposed Workshops'
|
||||
And see 'Bike Sharing!'
|
||||
But I should not see 'Schedule'
|
||||
And not see 'Tuesday'
|
||||
And I should see 16 workshops under 'Proposed Workshops'
|
||||
|
||||
When the workshop schedule is published
|
||||
And I refresh the page
|
||||
Then I should see 'Schedule'
|
||||
And see 'Tuesday'
|
||||
And see 'Wednesday'
|
||||
And see 'Bike Sharing!'
|
||||
And I should see 16 workshops under 'Schedule'
|
||||
But I should not see 'Proposed Workshops'
|
||||
And not see 'Monday'
|
||||
And not see 'Thursday'
|
||||
And not see 'Flatbush Ave'
|
||||
|
||||
When I click on 'Reaching New Immigrants' link
|
||||
Then I should see 'The Shop'
|
||||
And see '1027 Flatbush Ave'
|
||||
And see 'More info'
|
||||
And see 'Close'
|
||||
|
||||
When I click on the 'Close' button
|
||||
Then I should not see 'Flatbush Ave'
|
||||
But I should see 'Battlefield: Consensus!'
|
||||
|
||||
When I click on 'Battlefield: Consensus!'
|
||||
Then I should see 'The Co-op'
|
||||
And see '1415 Cortelyou Rd'
|
||||
|
||||
When I click on the '1415 Cortelyou Rd' link
|
||||
Then I should be on a google maps page
|
||||
@@ -0,0 +1,86 @@
|
||||
Feature: Sign In
|
||||
Scenario: Sign in from the footer using email
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am on the landing page
|
||||
|
||||
Then I should see a 'Sign In' link
|
||||
|
||||
When I click the 'Sign In' link
|
||||
|
||||
Then I should see 'Email address'
|
||||
And I enter my email
|
||||
And press confirm_email
|
||||
|
||||
Then I should be on the do_confirm page
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should be on the settings page
|
||||
Then I should not see a 'My registration' link
|
||||
|
||||
Scenario: Sign in from the settings page
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am on the settings page
|
||||
|
||||
Then I should see 'Email address'
|
||||
And I enter my email
|
||||
And press confirm_email
|
||||
|
||||
Then I should be on the do_confirm page
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should be on the settings page
|
||||
|
||||
Scenario: Users can sign in in different sessions
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am on the settings page
|
||||
|
||||
Then I should see 'Email address'
|
||||
And I enter my email
|
||||
And press confirm_email
|
||||
|
||||
|
||||
Then I should be on the do_confirm page
|
||||
And I should get a 'confirmation' email
|
||||
|
||||
Then in a new session
|
||||
When I click on the 'Confirm' link in the email
|
||||
Then I should be on the confirmation page
|
||||
And I enter my email
|
||||
And click the 'Sign In' button
|
||||
|
||||
Then I should be on the settings page
|
||||
|
||||
Scenario: A registration link should be accessible for registered users
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am logged in
|
||||
And I am registered for the conference
|
||||
And I am on the settings page
|
||||
|
||||
Then I should see a 'My registration' link
|
||||
|
||||
Scenario: Conference hosts should see links to their conference
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I am logged in
|
||||
And I am a conference host
|
||||
And I am on the settings page
|
||||
|
||||
Then I should see 'Your Conferences'
|
||||
And I should see a 'Bike!Bike! 2015' link
|
||||
|
||||
Scenario: New accounts created with Facebook are forced to add an email address
|
||||
Given there is an upcoming conference in 'Brooklyn NY'
|
||||
And I have a facebook account
|
||||
And my name is 'Mark Zuckerberg'
|
||||
But my facebook account has no email address
|
||||
|
||||
When I log in with facebook
|
||||
Then I should be on the oauth_update page
|
||||
And I should see 'Before proceeding, you must provide us an email address'
|
||||
|
||||
When I enter my email address
|
||||
And press save
|
||||
Then I should be on the home page
|
||||
And I should see 'Mark Zuckerberg'
|
||||
And I should see 'Sign out'
|
||||
@@ -1,15 +1,26 @@
|
||||
Feature: Static Pages
|
||||
In order to learn about Bike!Bike!
|
||||
As a visitor
|
||||
|
||||
Scenario: Read the about page
|
||||
Given There is an upcoming conference in Halifax NS
|
||||
And I am on the about page
|
||||
Scenario: Read the about page
|
||||
Given There is an upcoming conference in 'Portland OR'
|
||||
And I am on the about page
|
||||
Then I should see 'What is Bike!Bike!?'
|
||||
|
||||
Scenario: Read the policy page
|
||||
Given There is an upcoming conference in Halifax NS
|
||||
And I am on the policy page
|
||||
Scenario: Read the policy page
|
||||
Given There is an upcoming conference in 'Regina, SK'
|
||||
And I am on the policy page
|
||||
Then I should see 'Safer Space Agreement'
|
||||
|
||||
Scenario: See a 404 page
|
||||
Given There is an upcoming conference in Halifax NS
|
||||
And I am on a 404 error page
|
||||
Scenario: See a 404 page
|
||||
Given There is an upcoming conference in 'Edmundston, NB'
|
||||
And I am on a 404 error page
|
||||
Then I should see 'The page you are looking for could not be found'
|
||||
|
||||
Scenario: See a 500 page
|
||||
Given There is an upcoming conference in 'Souris, MB'
|
||||
And I am on a 500 error page
|
||||
Then I should see 'An error has occurred'
|
||||
|
||||
Scenario: See a locale not available page
|
||||
Given There is an upcoming conference in 'Eldorado, MX'
|
||||
And I am on a locale not available error page
|
||||
Then I should see 'Klingon Translations Missing'
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
|
||||
Given /^(?:(?:that )?there is )?an? (upcoming|past)( regional)? conference(?: in '(.+)')?$/i do |when_, is_regional, location|
|
||||
location ||= 'Brooklyn NY' # this will set up our mocks to use a valid poster
|
||||
TestState.last_conference = FactoryGirl.build("#{when_}#{is_regional ? '_regional' : ''}_conference".to_sym)
|
||||
TestState.last_conference.city = City.search(location)
|
||||
TestState.last_organization = create_org(nil, location)
|
||||
TestState.last_conference.organizations << TestState.last_organization
|
||||
|
||||
# generate the slug
|
||||
TestState.last_conference.save!
|
||||
|
||||
# set the poster
|
||||
poster = File.join(Rails.root, 'features', 'support', 'assets', 'images',
|
||||
'posters', "#{TestState.last_conference.slug}.png")
|
||||
TestState.last_conference.poster = Rack::Test::UploadedFile.new(poster) if File.exist?(poster)
|
||||
TestState.last_conference.save!
|
||||
end
|
||||
|
||||
Given /^(?:the conference |it )has no (poster|date)$/i do |field|
|
||||
if field == 'date'
|
||||
TestState.last_conference.start_date = nil
|
||||
TestState.last_conference.end_date = nil
|
||||
else
|
||||
TestState.last_conference.send("#{field}=".to_sym, nil)
|
||||
end
|
||||
|
||||
TestState.last_conference.save!
|
||||
end
|
||||
|
||||
Given /^(?:the conference |it )?is not (featured|public)$/i do |field|
|
||||
TestState.last_conference.send("is_#{field}=".to_sym, false)
|
||||
TestState.last_conference.save!
|
||||
end
|
||||
|
||||
Given /^the conference accepts housing providers that live within (\d+)(mi|km)$/i do |number, unit|
|
||||
TestState.last_conference.provider_conditions = {'distance' => {'number' => number.to_i, 'unit' => unit}}
|
||||
TestState.last_conference.save!
|
||||
end
|
||||
|
||||
Given /^the conference accepts paypal$/i do
|
||||
TestState.last_conference.paypal_email_address = Forgery(:internet).email_address
|
||||
TestState.last_conference.paypal_username = Forgery(:internet).user_name
|
||||
TestState.last_conference.paypal_password = Forgery(:basic).password
|
||||
TestState.last_conference.paypal_signature = Forgery(:basic).password
|
||||
TestState.last_conference.save!
|
||||
end
|
||||
|
||||
Then /^I am( not)? a member of (.+)$/i do |state, org_name|
|
||||
user = nil
|
||||
should_be = !(state =~ / not/)
|
||||
org = Organization.find_by(:name => org_name)
|
||||
if should_be
|
||||
org.should be
|
||||
org.users.should be
|
||||
elsif org.nil? || org.users.nil?
|
||||
return
|
||||
end
|
||||
org.users.each { |u|
|
||||
if u.email == TestState.last_email_entered
|
||||
user = u
|
||||
end
|
||||
}
|
||||
user.send(should_be ? 'should' : 'should_not', be)
|
||||
end
|
||||
|
||||
Given /^the event locations are:$/i do |table|
|
||||
table.hashes.each do |location|
|
||||
create_location(headers_to_attributes(location))
|
||||
end
|
||||
end
|
||||
|
||||
Given /^the workshop times are:$/i do |table|
|
||||
blocks = []
|
||||
wday = TestState.last_conference.start_date.wday
|
||||
table.hashes.each do |block|
|
||||
blocks << {
|
||||
'time' => string_to_time(block['Time']).to_s,
|
||||
'length' => string_to_time_length(block['Length']).to_s,
|
||||
'days' => block['Days'].split(/\s*,\s*/).map { |day| str_to_wday(day).to_s }
|
||||
}
|
||||
end
|
||||
TestState.last_conference.workshop_blocks = blocks
|
||||
TestState.last_conference.save!
|
||||
end
|
||||
|
||||
Given /^the schedule on (.+) is:$/i do |day, table|
|
||||
@locations = {}
|
||||
conference_day = str_to_wday(day)
|
||||
|
||||
table.hashes.each_with_index do |slot, block|
|
||||
slot.each do |location_title, workshop_title|
|
||||
location = (@locations[location_title] ||= EventLocation.find_by_title(location_title))
|
||||
workshop = create_workshop(workshop_title)
|
||||
workshop.block = {
|
||||
'day' => conference_day,
|
||||
'block' => block
|
||||
}
|
||||
workshop.event_location_id = location.id
|
||||
workshop.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
Then /^(?:I )?should not get an email$/i do
|
||||
ActionMailer::Base.deliveries.size.should eq 0
|
||||
end
|
||||
|
||||
Then /^(.*) should get (.+) '(.+)' emails?$/i do |to, amount, subject|
|
||||
address = email_address(to)
|
||||
emails = emails_to(address, subject)
|
||||
|
||||
unless emails.length == (str_to_num(amount))
|
||||
email_log = []
|
||||
ActionMailer::Base.deliveries.each do |mail|
|
||||
email_log << "\t#{mail.to.join(', ')}: #{mail.subject}"
|
||||
end
|
||||
total_emails = ActionMailer::Base.deliveries.length
|
||||
fail "Failed to find #{amount} email#{amount == 1 ? '' : 's'} to #{address} with #{subject} in the subject amoung #{total_emails} total email#{total_emails == 1 ? '' : 's'}:\n#{email_log.join("\n")}"
|
||||
end
|
||||
|
||||
TestState.last_email = emails.first
|
||||
end
|
||||
|
||||
Then /^th(?:e|at) email should contain (.+)$/i do |value|
|
||||
TestState.last_email = ActionMailer::Base.deliveries.last
|
||||
|
||||
if TestState.last_email.parts && TestState.last_email.parts.first
|
||||
TestState.last_email.parts.first.body.raw_source.should include(value)
|
||||
TestState.last_email.parts.last.body.raw_source.should include(value)
|
||||
else
|
||||
TestState.last_email.body.raw_source.should include(value)
|
||||
end
|
||||
end
|
||||
|
||||
Then /^in th(?:e|at) email I should see (.+)$/i do |value|
|
||||
TestState.last_email = ActionMailer::Base.deliveries.last
|
||||
|
||||
if /(an?|the|my) (.+) link/ =~ value
|
||||
value = path_to Regexp.last_match(2)
|
||||
end
|
||||
|
||||
if TestState.last_email.parts
|
||||
TestState.last_email.parts.first.body.raw_source.should include(value)
|
||||
TestState.last_email.parts.last.body.raw_source.should include(value)
|
||||
else
|
||||
TestState.last_email.body.raw_source.should include(value)
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:I )?click (?:on )?(?:the )?(?:a )?'(.+?)' link in the email?$/i do | text |
|
||||
href = find_in_last_email("a:contains('#{text}')", :href)
|
||||
|
||||
attempt_to do
|
||||
visit href
|
||||
sleep 1
|
||||
end
|
||||
end
|
||||
@@ -1,487 +1,157 @@
|
||||
require 'forgery'
|
||||
|
||||
Given(/^(I )?(am on |visit )the (.+) page$/) do |a, b, page_name|
|
||||
visit path_to(page_name)
|
||||
Then /^(?:I )?(?:should )?(not )?see (?:the |an? )?'(.+)' link$/i do |no, item|
|
||||
attempt_to do
|
||||
if no.present?
|
||||
expect(page).not_to have_link item
|
||||
else
|
||||
TestState.it = first('a', text: item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Given(/^I am on a (.+) error page$/) do |page_name|
|
||||
case page_name
|
||||
when '404'
|
||||
path = '/error_404'
|
||||
else
|
||||
raise "Unknown error page #{page_name}"
|
||||
end
|
||||
visit path
|
||||
Then /^(?:I )?(?:should )?(?:still )?(not )?see '(.+)'$/i do |negate, item|
|
||||
attempt_to do
|
||||
expect(page).send(negate ? :not_to : :to, have_text(item))
|
||||
end
|
||||
end
|
||||
|
||||
Given(/^I am on the (.+) site$/) do |language|
|
||||
ApplicationController::set_host (get_language_code(language) + '.bikebike.org')
|
||||
Then /^(?:I )?(?:should )?(?:still )?(not )?see (?:my |the )([^']+)$/i do |negate, item|
|
||||
attempt_to do
|
||||
expect(page).send(negate ? :not_to : :to, have_text(TestState::Values[get_field(item)]))
|
||||
end
|
||||
end
|
||||
|
||||
Given(/^I am in (.+)$/) do |location|
|
||||
ApplicationController::set_location (location)
|
||||
Then /^(?:I )?click (?:on )?(?:the )?(a )?'(.+?)'( button| link)?(?: beside '(.+?)')?(?: again)?$/i do |first, item, type, beside|
|
||||
attempt_to do
|
||||
begin
|
||||
root_item = beside.present? ? element_with_text(/#{Regexp.escape(beside)}.*?#{Regexp.escape(item)}/) : page
|
||||
if type.present?
|
||||
type.strip!
|
||||
selector = {button: 'button, a.button', link: 'a'}[type.to_sym]
|
||||
element = root_item.first(selector, text: item) || root_item.first(selector, text: item, visible: false) || root_item.find(selector, text: item)
|
||||
else
|
||||
element = element_with_text(item, root_item)
|
||||
end
|
||||
element.click
|
||||
rescue Exception => e
|
||||
puts text
|
||||
raise e
|
||||
end
|
||||
sleep(1) # let any aimations or page loads to complete
|
||||
end
|
||||
end
|
||||
|
||||
When(/^I go to the (.+) page$/) do |page_name|
|
||||
visit path_to(page_name)
|
||||
Then /^(?:I )?press (.+)$/i do |item|
|
||||
attempt_to do
|
||||
text = (item =~ /'(.*)'/ ? $1 : page.find('button[value$="' + item.gsub(/\s+/, '_') + '"]').text)
|
||||
click_link_or_button(text)
|
||||
sleep(1) # let any aimations or page loads to complete
|
||||
end
|
||||
end
|
||||
|
||||
When(/^(I )?(finish|cancel) ((with )?(paypal|the payment))$/) do |a, action, b, c, d|
|
||||
if action != 'cancel'
|
||||
@my_registration = ConferenceRegistration.find(@my_registration.id)
|
||||
@my_registration.payment_confirmation_token = 'token'
|
||||
@my_registration.save!
|
||||
url = register_paypal_confirm_path(@last_conference.slug, :paypal_confirm, 'token')
|
||||
visit url
|
||||
end
|
||||
Then /^(?:I )?(un)?check '(.+)'$/i do |uncheck, text|
|
||||
begin
|
||||
find('.check-box-field label', text: text).click
|
||||
rescue Exception => e
|
||||
# if we didn't find a label with the text, look for an 'Other' option
|
||||
begin
|
||||
find(".check-box-field input[placeholder*='#{text}']").click
|
||||
rescue
|
||||
# if we failed to find that too, raise the original exception
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^(I )?pay \$?([\d\.]+)$/) do | a, amount |
|
||||
button = nil
|
||||
|
||||
paypal_info = YAML.load(File.read(Rails.root.join("config/paypal.yml")))['test'].symbolize_keys
|
||||
@last_conference.paypal_username = paypal_info[:username]
|
||||
@last_conference.paypal_password = paypal_info[:password]
|
||||
@last_conference.paypal_signature = paypal_info[:signature]
|
||||
@last_conference.save!
|
||||
|
||||
@my_registration.payment_info = {:payer_id => '1234', :token => '5678', :amount => amount.to_f, :status => 'Completed'}.to_yaml
|
||||
@my_registration.save!
|
||||
|
||||
control = page.all("[value^=\"#{amount}\"]")
|
||||
|
||||
@last_payment_amount = amount
|
||||
|
||||
if control.length > 0
|
||||
control.first.trigger('click')
|
||||
else
|
||||
fill_in(locate('amount'), :with => amount)
|
||||
click_link_or_button(locate('payment'))
|
||||
end
|
||||
Then /^(?:my )?'(.+)' should (not )?be checked$/i do |text, negate|
|
||||
label = find('.check-box-field label', text: text)
|
||||
find("##{label[:for]}", visible: false).send(negate ? :should_not : :should, be_checked)
|
||||
end
|
||||
|
||||
Then(/^(I )?(don't )?have enough funds$/) do | a, status |
|
||||
if status.blank?
|
||||
info = YAML.load(@my_registration.payment_info)
|
||||
info[:status] = 'Completed'
|
||||
@my_registration.payment_info = info.to_yaml
|
||||
@my_registration.save!
|
||||
end
|
||||
Then /^(?:I )?(?:select|choose|want) (?:an? |the )?'(.+?)'$/i do |value|
|
||||
option = first('option', text: value)
|
||||
option.first(:xpath, './/..').set(option.value)
|
||||
end
|
||||
|
||||
Given(/^There is an upcoming conference( in .+)?$/) do |location|
|
||||
@last_conference = FactoryGirl.create(:upcoming_conference)
|
||||
if location
|
||||
@org = create_org(nil, location)
|
||||
@last_conference.organizations << @org
|
||||
@last_conference.save!
|
||||
end
|
||||
Then /^(?:I )?fill in (.+?) with '(.+)'$/i do |field, value|
|
||||
field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2')
|
||||
find(selector_for(field)).set value
|
||||
|
||||
if /email/ =~ field && !(/organization/ =~ field)
|
||||
TestState.last_email_entered = value
|
||||
end
|
||||
end
|
||||
|
||||
Given(/^an organization( named .+)? exists in (.+)?$/) do |name, location|
|
||||
if location =~ /every country/i
|
||||
Carmen::World.instance.subregions.each { |country|
|
||||
if country.subregions?
|
||||
country.subregions.each { |region|
|
||||
org = Organization.new(name: rand(36**16).to_s(36), slug: rand(36**16).to_s(36))
|
||||
org.locations << Location.new(city: 'City', country: country.code, territory: region.code)
|
||||
org.save!
|
||||
}
|
||||
else
|
||||
org = Organization.new(name: rand(36**16).to_s(36), slug: rand(36**16).to_s(36))
|
||||
org.locations << Location.new(city: 'City', country: country.code)
|
||||
org.save!
|
||||
end
|
||||
}
|
||||
else
|
||||
create_org(name ? name.gsub(/^\s*named\s+(.*?)\s*$/, '\1') : nil, location)
|
||||
end
|
||||
Then /^(?:I )?enter (?:my |an? |some |the )?(.+?)(?: as '(.+)')?$/i do |field, value|
|
||||
field = get_field(field)
|
||||
|
||||
sel = selector_for(field)
|
||||
element = first(sel, visible: true) || first(sel, visible: false)
|
||||
|
||||
unless value.present?
|
||||
value = case field
|
||||
when /email(_address)?/
|
||||
TestState.last_email_entered || Forgery(:internet).email_address
|
||||
when 'name'
|
||||
Forgery(field).full_name
|
||||
when 'city', 'country', 'phone', 'province', 'state' ,'street_address', 'address'
|
||||
aliases = {'address' => 'street_address'}
|
||||
Forgery('address').send((aliases[field] || field).to_sym)
|
||||
when 'subject', 'title'
|
||||
Forgery::LoremIpsum.sentence(random: true).gsub(/\.$/, '').titlecase
|
||||
when /(comment|reply)/
|
||||
Forgery::LoremIpsum.paragraphs(2, sentences: 6, random: true)
|
||||
when 'message'
|
||||
Forgery::LoremIpsum.paragraphs(2, sentences: 6, random: true)
|
||||
when 'info'
|
||||
Forgery::LoremIpsum.paragraphs(rand(1..4), sentences: rand(3..8), random: true)
|
||||
else
|
||||
fail "Unknown selector '#{field}'"
|
||||
end
|
||||
end
|
||||
|
||||
(TestState::Values[field] = value)
|
||||
|
||||
element.set value
|
||||
|
||||
if /email/ =~ field && !(/organization/ =~ field)
|
||||
TestState.last_email_entered = value
|
||||
end
|
||||
end
|
||||
|
||||
Given(/^a workshop( titled .+)? exists?$/) do |title|
|
||||
workshop = Workshop.new
|
||||
workshop.conference_id = @last_conference.id
|
||||
workshop.title = title ? title.gsub(/^\s*titled\s*(.*?)\s*$/, '\1') : Forgery::LoremIpsum.sentence({:random => true}).gsub(/\.$/, '').titlecase
|
||||
workshop.info = Forgery::LoremIpsum.paragraph({:random => true})
|
||||
workshop.locale = :en
|
||||
workshop.save
|
||||
username = Forgery::LoremIpsum.word({:random => true})
|
||||
user = User.create(firstname: username, email: "#{username}@bikebike.org")
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: workshop.id, role: :creator)
|
||||
@last_workshop = workshop
|
||||
Then /^(?:my )?(.+)? should (not )?be set to (.+)$/i do |field, should, value|
|
||||
field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2')
|
||||
page.find('[id$="' + field.gsub(/\s+/, '_') + '"]').value.send(should.nil? ? 'should' : 'should_not', eq(value))
|
||||
end
|
||||
|
||||
Given(/^the workshop is scheduled for day (\d+) at (\d\d?):(\d\d) at (.+)$/) do |day, hour, minute, location|
|
||||
@last_workshop.start_time = @last_conference.start_date.change({hour: hour.to_i, min: minute.to_i}) + (day.to_i - 1).days
|
||||
@last_workshop.end_time = @last_workshop.start_time + 1.5.hours
|
||||
#puts " === [#{location}] === "
|
||||
#puts EventLocation.all.to_yaml.to_s
|
||||
@last_workshop.event_location_id = EventLocation.find_by_title(location).id
|
||||
@last_workshop.save
|
||||
Then /^(?:I )?set (.+?) to (.+)$/i do |field, value|
|
||||
field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2')
|
||||
page.find('[id$="' + field.gsub(/\s+/, '_') + '"]', :visible => false).set value
|
||||
end
|
||||
|
||||
Given(/^the workshop schedule is (not )?published$/) do |is_not_published|
|
||||
@last_conference.workshop_schedule_published = is_not_published ? false : true
|
||||
@last_conference.save
|
||||
Then /^(?:I )?wait for (.+?) to appear$/i do |field|
|
||||
count = 0
|
||||
element = nil
|
||||
while element.nil? && count < 120
|
||||
begin element = page.find('[id$="' + field.gsub(/\s+/, '_') + '"]'); rescue; end
|
||||
begin element ||= page.find('[id$="' + field.gsub(/\s+/, '_') + '"]', :visible => false); rescue; end
|
||||
sleep(1)
|
||||
count += 1
|
||||
end
|
||||
end
|
||||
|
||||
Given(/^a location( named .+)? exists?$/) do |title|
|
||||
location = EventLocation.new
|
||||
location.conference_id = @last_conference.id
|
||||
location.title = title ? title.gsub(/^\s*named\s*(.*?)\s*$/, '\1') : Forgery::LoremIpsum.sentence({:random => true}).gsub(/\.$/, '').titlecase
|
||||
#location.info = Forgery::LoremIpsum.paragraph({:random => true})
|
||||
#location.locale = :en
|
||||
location.save
|
||||
@last_location = location
|
||||
Then /^(?:I )?select (.+?) from (.+)$/i do |value, field|
|
||||
select(value, :from => locate(field))
|
||||
end
|
||||
|
||||
Given(/^(I )have created a workshop titled (.+)( with (\d+) facilitators)?$/) do |a, title, b, facilitator_count|
|
||||
workshop = Workshop.new
|
||||
workshop.conference_id = @last_conference.id
|
||||
workshop.title = title ? title.gsub(/^\s*titled\s*(.*?)\s*$/, '\1') : Forgery::LoremIpsum.sentence({:random => true}).gsub(/\.$/, '').titlecase
|
||||
workshop.info = Forgery::LoremIpsum.paragraph({:random => true})
|
||||
workshop.locale = :en
|
||||
workshop.save
|
||||
WorkshopFacilitator.create(user_id: @my_account.id, workshop_id: workshop.id, role: :creator)
|
||||
(1..(facilitator_count || '0').to_i).each do |i|
|
||||
username = Forgery::LoremIpsum.word({:random => true})
|
||||
user = User.create(firstname: username, email: "#{username}@bikebike.org")
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: workshop.id, role: :collaborator)
|
||||
end
|
||||
@last_workshop = workshop
|
||||
Then /^in a new session$/i do
|
||||
Capybara.reset_sessions!
|
||||
end
|
||||
|
||||
Given(/^(\d+) (person is|people are) interested in the workshop$/) do |interested,a|
|
||||
(1..interested.to_i).each do |i|
|
||||
WorkshopInterest.create(workshop_id: @last_workshop.id, user_id: (@my_account ? @my_account.id + 1 : 1000) + i)
|
||||
end
|
||||
end
|
||||
|
||||
Given(/^(\d+) (person has|people have) requested to facilitate (the|my) workshop$/) do |request_count,a,b|
|
||||
(1..(request_count || '0').to_i).each do |i|
|
||||
username = Forgery::LoremIpsum.word({:random => true})
|
||||
user = User.create(firstname: username, email: "#{username}@bikebike.org")
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: @last_workshop.id, role: :requested)
|
||||
end
|
||||
end
|
||||
|
||||
Given(/^(.+) has requested to facilitate (the|my) workshop$/) do |username,a|
|
||||
user = User.create(firstname: username, email: "#{username.gsub(/\s+/, '.').downcase}@bikebike.org")
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: @last_workshop.id, role: :requested)
|
||||
end
|
||||
|
||||
Given(/^(.+) is (also )?facilitating (the|my) workshop$/) do |username,a,b|
|
||||
user = User.create(firstname: username, email: "#{username.gsub(/\s+/, '.')}@bikebike.org")
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: @last_workshop.id, role: :collaborator)
|
||||
end
|
||||
|
||||
Given(/^a user named (.+?)( with the email (.+))? exists$/) do |username,a,email|
|
||||
user = User.create(firstname: username, email: email || "#{username.gsub(/\s+/, '.')}@bikebike.org")
|
||||
end
|
||||
|
||||
Then(/^(I )(approve|deny) the facilitator request from (.+)$/) do |a,action,username|
|
||||
user = User.find_by_firstname(username)
|
||||
visit "/conferences/#{@last_conference.slug}/workshops/#{@last_workshop.id}/facilitate_request/#{user.id}/#{action}/"
|
||||
end
|
||||
|
||||
Given(/^Registration is (open|closed)$/) do |status|
|
||||
@last_conference.registration_open = (status == 'open')
|
||||
@last_conference.save!
|
||||
end
|
||||
|
||||
Then(/^(I )?(should )?(not )?see (.+)$/) do | a, b, no, item |
|
||||
if /(the )?Bike!Bike! logo$/ =~ item
|
||||
if no.present?
|
||||
expect(page).not_to have_selector('.bb-icon-logo')
|
||||
else
|
||||
expect(page).to have_selector('.bb-icon-logo')
|
||||
end
|
||||
elsif /(the|a)?\s?(.+) menu item$/ =~ item
|
||||
within('#main-nav') {
|
||||
if no.present?
|
||||
expect(page).not_to have_link Regexp.last_match(2)
|
||||
else
|
||||
expect(page).to have_link Regexp.last_match(2)
|
||||
end
|
||||
}
|
||||
elsif /(the|a)?\s?(.+) image$/ =~ item
|
||||
if no.present?
|
||||
expect(page).not_to have_selector("##{Regexp.last_match(2)} img")
|
||||
else
|
||||
expect(page).to have_selector("##{Regexp.last_match(2)} img")
|
||||
end
|
||||
elsif /(the|a)?\s?(.+) link$/ =~ item
|
||||
if no.present?
|
||||
expect(page).not_to have_link Regexp.last_match(2)
|
||||
else
|
||||
expect(page).to have_link Regexp.last_match(2)
|
||||
end
|
||||
else
|
||||
if no.present?
|
||||
expect(page).not_to have_text item
|
||||
else
|
||||
expect(page).to have_text item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^(I )?wait (\d+) seconds$/) do | a, time |
|
||||
sleep time.to_i
|
||||
end
|
||||
|
||||
## ======= Forms ======= ##
|
||||
|
||||
Then(/^(I )?click (on )?(the first )?(.+?)( button| link| which is hidden)?$/) do | a, b, first, item, type |
|
||||
item = item.gsub(/^\s*(a|the)\s*(.*)$/, '\2')
|
||||
if type && type.strip == 'button'
|
||||
click_button(item)
|
||||
elsif type && type.strip == 'link'
|
||||
#print page.html
|
||||
click_link(item)
|
||||
elsif type && type =~ /hidden/
|
||||
find('[id$="' + item.gsub(/\s+/, '_') + '"]', :visible => false).click
|
||||
else
|
||||
if first.present?
|
||||
page.first(:link, item).trigger('click')
|
||||
else
|
||||
page.find_link(item).trigger('click')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^(I )?press (.+)$/) do | a, item |
|
||||
click_link_or_button(page.find('button[value$="' + item.gsub(/\s+/, '_') + '"]').text)#locate(item))
|
||||
end
|
||||
|
||||
Then(/^(I )?(un)?check (.+)$/) do | a, state, item |
|
||||
if state == 'un'
|
||||
uncheck(locate(item))
|
||||
else
|
||||
check(locate(item))
|
||||
end
|
||||
end
|
||||
|
||||
# (a ) (b ) (c ) (value)(d ) (group)
|
||||
Then(/^(I )?(select|choose|want) (an? |the )?(.+?)( as my| as the| as an?| for)? (.+)$/) do | a, b, c, value, d, group |
|
||||
if (control = page.all("[name=\"#{group.pluralize}[#{value}]\"]".gsub(/^\s+$/, '_'))).length > 0
|
||||
method = check(control.first[:id])
|
||||
elsif (control = page.all("[name=\"#{group}\"][value=\"#{value}\"]".gsub(/^\s+$/, '_'))).length > 0
|
||||
control.first.trigger('click')
|
||||
else
|
||||
raise "Could not find control to select"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Then(/^(I )?fill in (.+?) with (.+)$/) do | a, field, value |
|
||||
field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2')
|
||||
fill_in(locate(field), :with => value)
|
||||
|
||||
if /email/ =~ field && !(/organization/ =~ field)
|
||||
@last_email_entered = value
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^(I )?enter (.+?) (as my |as the |in the|as an? )(.+)$/) do | a, value, b, field |
|
||||
field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2')
|
||||
fill_in(locate(field), :with => value)
|
||||
|
||||
if /email/ =~ field && !(/organization/ =~ field)
|
||||
@last_email_entered = value
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^(my )?(.+)? should (not )?be set to (.+)$/) do | a, field, should, value |
|
||||
field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2')
|
||||
page.find('[id$="' + field.gsub(/\s+/, '_') + '"]').value.send(should.nil? ? 'should' : 'should_not', eq(value))
|
||||
end
|
||||
|
||||
Then(/^(my )?(.+)? should (not )?be checked$/) do | a, field, should |
|
||||
field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2')
|
||||
page.find('[id$="' + field.gsub(/\s+/, '_') + '"]').send(should.nil? ? 'should' : 'should_not', be_checked)
|
||||
end
|
||||
|
||||
Then(/^I set (.+?) to (.+)$/) do | field, value |
|
||||
field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2')
|
||||
page.find('[id$="' + field.gsub(/\s+/, '_') + '"]', :visible => false).set value
|
||||
end
|
||||
|
||||
Then(/^(I )wait for (.+?) to appear$/) do | a, field |
|
||||
count = 0
|
||||
element = nil
|
||||
while element.nil? && count < 120
|
||||
begin element = page.find('[id$="' + field.gsub(/\s+/, '_') + '"]'); rescue; end
|
||||
begin element ||= page.find('[id$="' + field.gsub(/\s+/, '_') + '"]', :visible => false); rescue; end
|
||||
sleep(1)
|
||||
count += 1
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^(I )?show the (page|url)$/) do | a, item |
|
||||
if item == 'url'
|
||||
print current_url
|
||||
else
|
||||
print page.html
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^I select (.+?) from (.+)$/) do | value, field |
|
||||
select(value, :from => locate(field))
|
||||
end
|
||||
|
||||
## ======= Emails ======= ##
|
||||
|
||||
Then(/^I should not get an email$/) do
|
||||
ActionMailer::Base.deliveries.size.should eq 0
|
||||
end
|
||||
|
||||
Then (/^I should get an? (.+) email$/) do |subject|
|
||||
@last_email = ActionMailer::Base.deliveries.last
|
||||
if @last_email_entered
|
||||
@last_email.to.should include @last_email_entered
|
||||
end
|
||||
@last_email.subject.should include(subject)
|
||||
end
|
||||
|
||||
Then (/^th(e|at) email should contain (.+)$/) do |a, value|
|
||||
@last_email = ActionMailer::Base.deliveries.last
|
||||
|
||||
if @last_email.parts && @last_email.parts.first
|
||||
@last_email.parts.first.body.raw_source.should include(value)
|
||||
@last_email.parts.last.body.raw_source.should include(value)
|
||||
else
|
||||
@last_email.body.raw_source.should include(value)
|
||||
end
|
||||
end
|
||||
|
||||
Then (/^in th(e|at) email I should see (.+)$/) do |a, value|
|
||||
@last_email = ActionMailer::Base.deliveries.last
|
||||
|
||||
if /(an?|the|my) (.+) link/ =~ value
|
||||
value = path_to Regexp.last_match(2)
|
||||
end
|
||||
|
||||
if @last_email.parts
|
||||
@last_email.parts.first.body.raw_source.should include(value)
|
||||
@last_email.parts.last.body.raw_source.should include(value)
|
||||
else
|
||||
@last_email.body.raw_source.should include(value)
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^(I )?confirm my account$/) do | a |
|
||||
@my_account = User.find_user(@last_email_entered)
|
||||
@confirmation = EmailConfirmation.where(["user_id = ?", @my_account.id]).order("created_at DESC").first
|
||||
visit "/confirm/#{@confirmation.token}"
|
||||
end
|
||||
|
||||
Then (/^I should (not )?be registered for the conference$/) do |state|
|
||||
@my_account = User.find_by(:email => @last_email_entered)
|
||||
@my_registration = ConferenceRegistration.find_by(:user_id => @my_account.id, :conference_id => @last_conference.id)
|
||||
if state && state.strip == 'not'
|
||||
@my_registration.should be_nil
|
||||
else
|
||||
@my_registration.should_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
Given (/^(I )?am logged in as (.+)$/) do |a, email|
|
||||
#include Sorcery::TestHelpers::Rails
|
||||
@my_account = User.create(:email => email)
|
||||
EmailConfirmation.create(:token => 'test', :user_id => @my_account.id)
|
||||
visit "/confirm/test"
|
||||
fill_in(locate('email'), :with => email)
|
||||
click_link_or_button(page.find('button[type="submit"]').text)
|
||||
end
|
||||
|
||||
Given (/^My name is (.+)$/) do |name|
|
||||
@my_account.firstname = name
|
||||
@my_account.save
|
||||
end
|
||||
|
||||
Given (/^(I am|(.+) is) registered for the conference$/) do |a,username|
|
||||
user = username ? User.find_by_firstname(username) : @my_account
|
||||
|
||||
registration = ConferenceRegistration.create(
|
||||
:user_id => user.id,
|
||||
:conference_id => @last_conference.id,
|
||||
:is_attending => true,
|
||||
:is_confirmed => true,
|
||||
:is_participant => true,
|
||||
:city => 'Somewhere',
|
||||
:arrival => '2015-09-28 00:00:00',
|
||||
:departure => '2015-09-28 00:00:00',
|
||||
:housing => 'house',
|
||||
:bike => 'medium',
|
||||
:other => '',
|
||||
:allergies => '',
|
||||
:languages => '["en"]',
|
||||
:food => 'meat'
|
||||
)
|
||||
if username
|
||||
@last_registration = registration
|
||||
else
|
||||
@my_registration = registration
|
||||
end
|
||||
end
|
||||
|
||||
Given (/^(I )?have paid( \$?\d+|\$?\d+\.\d+)? for registration$/) do |a, amount|
|
||||
@my_registration.registration_fees_paid = amount ? amount.to_f : 50.0
|
||||
@my_registration.save
|
||||
end
|
||||
|
||||
Given (/^(I )?am a conference host$/) do |a|
|
||||
org = @last_conference.organizations.first
|
||||
org.users ||= Array.new
|
||||
org.users << @my_account
|
||||
org.save
|
||||
end
|
||||
|
||||
Then (/^(I )?save (my |the )workshop$/) do |a, b|
|
||||
title = find('[name=title]').value
|
||||
click_button('save')
|
||||
@last_workshop = Workshop.order('created_at DESC').first
|
||||
end
|
||||
|
||||
Then (/^(I )?(view|edit|delete) (my |the )workshop$/) do |a, action, b|
|
||||
if action == 'view'
|
||||
visit "/conferences/#{@last_conference.slug}/workshops/#{@last_workshop.id}"
|
||||
else
|
||||
visit "/conferences/#{@last_conference.slug}/workshops/#{@last_workshop.id}/#{action}"
|
||||
end
|
||||
end
|
||||
|
||||
Then (/^my registration (should( not)? be|is( not)?) (confirmed|completed?|paid)$/) do |state, x, y, field|
|
||||
ConferenceRegistration.find_by!(:email => @last_email_entered).
|
||||
send(field == 'confirmed' ? 'is_confirmed' : (field == 'paid' ? 'registration_fees_paid' : field)).
|
||||
send(state =~ / not/ ? 'should_not' : 'should', be)
|
||||
end
|
||||
|
||||
Then (/^I am( not)? a user$/) do |state|
|
||||
User.find_user(@last_email_entered).
|
||||
send(state =~ / not/ ? 'should_not' : 'should', be)
|
||||
end
|
||||
|
||||
Then (/^I am( not)? a member of (.+)$/) do |state, org_name|
|
||||
user = nil
|
||||
should_be = !(state =~ / not/)
|
||||
org = Organization.find_by(:name => org_name)
|
||||
if should_be
|
||||
org.should be
|
||||
org.users.should be
|
||||
elsif org.nil? || org.users.nil?
|
||||
return
|
||||
end
|
||||
org.users.each { |u|
|
||||
if u.email == @last_email_entered
|
||||
user = u
|
||||
end
|
||||
}
|
||||
user.send(should_be ? 'should' : 'should_not', be)
|
||||
end
|
||||
|
||||
Then (/^My (.+) should(not )? be (.+)$/) do |field, state, value|
|
||||
User.find_user(@last_email_entered).
|
||||
send(field.gsub(/\s/, '_')).
|
||||
send(state =~ / not/ ? 'should_not' : 'should', eq(value))
|
||||
Then /^(?:my |the )([A-Z][a-z]+ )?(workshop|conference|user|conference registration) (.+?) should (not )?be '(.+?)'$/i do |locale, type, attribute, negate, value|
|
||||
object = TestState.send("last_#{type.gsub(' ', '_')}")
|
||||
attribute = attribute.gsub(' ', '_').downcase
|
||||
actual_value = locale ? object.get_column_for_locale!(attribute, get_locale(locale)) : object.send(attribute)
|
||||
expect(actual_value).send(negate ? :not_to : :to, (be == value))
|
||||
end
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
Given /^(?:I )?(?:(?:am )?on |visit )(?:the |my )(.+) page$/i do |page_name|
|
||||
attempt_to do
|
||||
visit path_to(page_name)
|
||||
end
|
||||
end
|
||||
|
||||
Given /^(?:(?:I )?am )?on an? (.+) error page$/i do |page_name|
|
||||
case page_name
|
||||
when '404', '500'
|
||||
path = "/error_#{page_name}"
|
||||
when 'locale not available'
|
||||
path = 'locale_not_available_error/tlh'
|
||||
else
|
||||
raise "Unknown error page #{page_name}"
|
||||
end
|
||||
|
||||
attempt_to do
|
||||
visit path
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:I )?should be on (?:the |an? | my)?(.+) page$/i do |page_name|
|
||||
attempt_to do
|
||||
path = path_to(page_name)
|
||||
path = /(https?\/\/:[^\/]+)?#{Regexp.escape(path)}\/?(\?|#|$)/ unless path.is_a?(Regexp)
|
||||
current_url.should match path
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I am on the (.+) site$/i do |language|
|
||||
ApplicationController::set_host (get_language_code(language) + '.bikebike.org')
|
||||
end
|
||||
|
||||
Given /^I am in (.+)$/i do |location|
|
||||
ApplicationController::set_location (location)
|
||||
end
|
||||
|
||||
When /^I go to the (.+) page$/i do |page_name|
|
||||
visit path_to(page_name)
|
||||
end
|
||||
|
||||
Given /^a location( named .+)? exists?$/i do |title|
|
||||
location = EventLocation.new
|
||||
location.conference_id = TestState.last_conference.id
|
||||
location.title = title ? title.gsub(/^\s*named\s*(.*?)\s*$/, '\1') : Forgery::LoremIpsum.sentence({:random => true}).gsub(/\.$/, '').titlecase
|
||||
location.save
|
||||
TestState.last_location = location
|
||||
end
|
||||
|
||||
Then /^(?:I )?show the (page|url)$/i do |item|
|
||||
if item == 'url'
|
||||
print current_url
|
||||
else
|
||||
print page.html
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:I )?wait (\d+(?:\.\d+)?) seconds?$/i do |time|
|
||||
sleep time.to_i
|
||||
end
|
||||
|
||||
Then /^take a screenshot?$/i do
|
||||
page.save_screenshot(File.expand_path('./test.png'), full: true)
|
||||
end
|
||||
|
||||
When /^(?:I )?re(?:fresh|load) the page$/i do
|
||||
attempt_to do
|
||||
visit current_url
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,93 @@
|
||||
|
||||
Given /^(?:I am |'(.+)' is )?registered(?: for the conference)?$/i do |username|
|
||||
create_registration(username.present? ? get_user(username) : TestState.my_account)
|
||||
end
|
||||
|
||||
Given /^(?:I )?have paid( \$?\d+|\$?\d+\.\d+)? for registration$/i do |amount|
|
||||
TestState.my_registration.registration_fees_paid = amount ? amount.to_f : 50.0
|
||||
TestState.my_registration.save!
|
||||
end
|
||||
|
||||
Then /^my registration should( not)? be (confirmed|completed?|paid)$/i do |state, field|
|
||||
ConferenceRegistration.find_by!(email: TestState.last_email_entered).
|
||||
send(field == 'confirmed' ? 'is_confirmed' : (field == 'paid' ? 'registration_fees_paid' : field)).
|
||||
send(state =~ / not/ ? 'should_not' : 'should', be)
|
||||
end
|
||||
|
||||
Then /^I should (not )?be registered for the conference$/i do |state|
|
||||
if state && state.strip == 'not'
|
||||
TestState.my_registration.should be_nil
|
||||
else
|
||||
TestState.my_registration.should_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
When /^(?:I )?(finish|cancel|don't finish) (?:(?:with )?(?:paypal|the payment))$/i do |action|
|
||||
TestState.my_registration ||= ConferenceRegistration.find_by(user_id: TestState.my_account.id, conference_id: TestState.last_conference.id)
|
||||
TestState.my_registration.payment_confirmation_token = 'token'
|
||||
|
||||
unless action == 'cancel'
|
||||
info = YAML.load(TestState.my_registration.payment_info) || {}
|
||||
info[:status] = action == 'finish' ? 'Completed' : 'Incomplete'
|
||||
TestState.my_registration.payment_info = info.to_yaml
|
||||
end
|
||||
|
||||
TestState.my_registration.save!
|
||||
visit send("register_paypal_#{action == 'cancel' ? 'cancel' : 'confirm'}_path".to_sym, TestState.last_conference.slug, :paypal_confirm, 'token', amount: YAML.load(TestState.my_registration.payment_info)[:amount])
|
||||
end
|
||||
|
||||
# Then /^(?:I )?pay \$?([\d\.]+)$/i do |amount|
|
||||
# button = nil
|
||||
|
||||
# paypal_info = YAML.load(File.read(Rails.root.join("config/paypal.yml")))['test'].symbolize_keys
|
||||
# TestState.last_conference.paypal_username = paypal_info[:username]
|
||||
# TestState.last_conference.paypal_password = paypal_info[:password]
|
||||
# TestState.last_conference.paypal_signature = paypal_info[:signature]
|
||||
# TestState.last_conference.save!
|
||||
|
||||
# TestState.my_registration.payment_info = {
|
||||
# payer_id: '1234',
|
||||
# token: '5678',
|
||||
# amount: amount.to_f,
|
||||
# status: 'Completed'
|
||||
# }.to_yaml
|
||||
# TestState.my_registration.save!
|
||||
|
||||
# control = page.all("[value^=\"#{amount}\"]")
|
||||
|
||||
# TestState.last_payment_amount = amount
|
||||
|
||||
# if control.length > 0
|
||||
# control.first.trigger('click')
|
||||
# else
|
||||
# fill_in(locate('amount'), with: amount)
|
||||
# click_link_or_button(locate('payment'))
|
||||
# end
|
||||
# end
|
||||
|
||||
# Then /^(?:I )?(don't )?have enough funds$/i do |status|
|
||||
# if status.blank?
|
||||
# info = YAML.load(TestState.my_registration.payment_info)
|
||||
# info[:status] = 'Completed'
|
||||
# TestState.my_registration.payment_info = info.to_yaml
|
||||
# TestState.my_registration.save!
|
||||
# end
|
||||
# end
|
||||
|
||||
Given /^a workshop( titled .+)? exists?$/i do |title|
|
||||
workshop = Workshop.new
|
||||
workshop.conference_id = TestState.last_conference.id
|
||||
workshop.title = title ? title.gsub(/^\s*titled\s*(.*?)\s*$/, '\1') : Forgery::LoremIpsum.sentence({random: true}).gsub(/\.$/, '').titlecase
|
||||
workshop.info = Forgery::LoremIpsum.paragraph({random: true})
|
||||
workshop.locale = :en
|
||||
workshop.save
|
||||
username = Forgery::LoremIpsum.word({random: true})
|
||||
user = User.create(firstname: username, email: "#{username}@bikebike.org")
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: workshop.id, role: :creator)
|
||||
TestState.last_workshop = workshop
|
||||
end
|
||||
|
||||
Given /^registration is (open|closed)$/i do |status|
|
||||
TestState.last_conference.registration_status = status
|
||||
TestState.last_conference.save!
|
||||
end
|
||||
@@ -0,0 +1,93 @@
|
||||
Then /^I am( not)? a user$/i do |state|
|
||||
TestState.my_account.send(state =~ / not/ ? 'should_not' : 'should', be)
|
||||
end
|
||||
|
||||
Given /^(?:I )?(?:am logged|log) in(?: as '(.+)')?$/i do |email|
|
||||
TestState.my_account = get_user(email)
|
||||
TestState.last_token = 'test'
|
||||
|
||||
attempt_to do
|
||||
EmailConfirmation.create(token: TestState.last_token, user_id: TestState.my_account.id)
|
||||
|
||||
attempt_to do
|
||||
visit path_to(:confirm)
|
||||
end
|
||||
|
||||
first(selector_for('email')).set(TestState.my_account.email)
|
||||
first('#token + button[type="submit"]').click
|
||||
|
||||
begin
|
||||
expect(page).to have_link TestState.my_account.name
|
||||
rescue
|
||||
fail "Error logging in"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Given /^(?:I )?(only )?speak (.+)$/i do |only, language|
|
||||
TestState.my_account.languages ||= ['en']
|
||||
if only
|
||||
TestState.my_account.languages = [get_locale(language)]
|
||||
else
|
||||
TestState.my_account.languages << get_locale(language)
|
||||
end
|
||||
TestState.my_account.save!
|
||||
end
|
||||
|
||||
Then /^(?:I )?should (not )?be (?:logged|signed) in$/ do |negate|
|
||||
expect(logged_in?).to_be !negate
|
||||
end
|
||||
|
||||
When /^(?:I )?log in with facebook$/i do
|
||||
visit oauth_callback_path(
|
||||
name: TestState.my_account.firstname,
|
||||
email: TestState.my_account.email,
|
||||
fb_id: TestState.my_account.fb_id
|
||||
)
|
||||
end
|
||||
|
||||
Given /^(?:I )?have a facebook account$/i do
|
||||
TestState.my_account = FactoryGirl.build(:user)
|
||||
TestState.my_account.fb_id = '1'
|
||||
end
|
||||
|
||||
Given /^(?:I )?am a registered user$/i do
|
||||
TestState.my_account.save!
|
||||
end
|
||||
|
||||
Given /^my facebook account has no email address$/ do
|
||||
TestState.my_account.email = nil
|
||||
TestState.my_account.save! if TestState.my_account.id.present?
|
||||
end
|
||||
|
||||
Given /^my name is '(.+)'$/i do |name|
|
||||
TestState.my_account.firstname = name
|
||||
TestState.my_account.save! if TestState.my_account.id.present?
|
||||
end
|
||||
|
||||
Given /^(?:I )?am an? (.+)$/i do |role|
|
||||
if role == 'conference host'
|
||||
org = TestState.last_conference.organizations.first
|
||||
org.users ||= Array.new
|
||||
org.users << TestState.my_account
|
||||
org.save
|
||||
else
|
||||
case role
|
||||
when /(site )?admin(istrator)?/
|
||||
role = 'administrator'
|
||||
end
|
||||
|
||||
TestState.my_account.role = role
|
||||
TestState.my_account.save!
|
||||
end
|
||||
end
|
||||
|
||||
Then /^(?:I )?confirm my account$/i do
|
||||
TestState.my_account = User.find_user(TestState.last_email_entered)
|
||||
TestState.confirmation = EmailConfirmation.where(["user_id = ?", TestState.my_account.id]).order("created_at DESC").first
|
||||
visit "/confirm/#{TestState.confirmation.token}"
|
||||
end
|
||||
|
||||
Given /^a user named (.+?)(?: with the email (.+))? exists$/i do |username, email|
|
||||
user = User.create(firstname: username, email: email || "#{username.gsub(/\s+/, '.')}@bikebike.org")
|
||||
end
|
||||
@@ -0,0 +1,107 @@
|
||||
Given /^((?:I )?have|there is) a workshop (?:named |titled )?'(.+?)'$/ do |owner, title|
|
||||
if owner =~ /^there is$/
|
||||
owner = create_user
|
||||
create_registration(owner)
|
||||
else
|
||||
owner = TestState.my_account
|
||||
end
|
||||
create_workshop(title, owner)
|
||||
end
|
||||
|
||||
Given /^(?:it|'(.+?)') is (not )?looking for facilitators$/ do |title, negate|
|
||||
workshop = title.present? ? TestState.last_workshop : Workshop.find_by_title(title)
|
||||
workshop.needs_facilitators = !negate
|
||||
workshop.save!
|
||||
end
|
||||
|
||||
Given /^(?:I am|'(.+)' is) facilitating(?: '(.+?)')?$/ do |user, title|
|
||||
workshop = title.present? ? Workshop.find_by_title(title) : TestState.last_workshop
|
||||
user = user.present? ? get_user(user) : TestState.my_account
|
||||
WorkshopFacilitator.create(
|
||||
user_id: user.id,
|
||||
workshop_id: workshop.id,
|
||||
role: :collaborator
|
||||
)
|
||||
end
|
||||
|
||||
Then /^(?:I )?save (?:my |the )workshop$/i do
|
||||
title = find('[name=title]').value
|
||||
click_button('save')
|
||||
TestState.last_workshop = Workshop.order('created_at DESC').first
|
||||
end
|
||||
|
||||
Then /^(?:I )?(view|edit|delete) (?:my |the )workshop$/i do |action|
|
||||
if action == 'view'
|
||||
visit "/conferences/#{TestState.last_conference.slug}/workshops/#{TestState.last_workshop.id}"
|
||||
else
|
||||
visit "/conferences/#{TestState.last_conference.slug}/workshops/#{TestState.last_workshop.id}/#{action}"
|
||||
end
|
||||
end
|
||||
|
||||
Given /^the workshop is scheduled for day (\d+) at (\d\d?):(\d\d) at (.+)$/i do |day, hour, minute, location|
|
||||
TestState.last_workshop.start_time = TestState.last_conference.start_date.change({hour: hour.to_i, min: minute.to_i}) + (day.to_i - 1).days
|
||||
TestState.last_workshop.end_time = TestState.last_workshop.start_time + 1.5.hours
|
||||
TestState.last_workshop.event_location_id = EventLocation.find_by_title(location).id
|
||||
TestState.last_workshop.save!
|
||||
end
|
||||
|
||||
Given /^the workshop schedule is (not )?published$/i do |is_not_published|
|
||||
TestState.last_conference.workshop_schedule_published = is_not_published ? false : true
|
||||
TestState.last_conference.save!
|
||||
end
|
||||
|
||||
Given /^(?:I )?have created a workshop titled (.+)(?: with (\d+) facilitators)?$/i do |title, facilitator_count|
|
||||
workshop = Workshop.new
|
||||
workshop.conference_id = TestState.last_conference.id
|
||||
workshop.title = title ? title.gsub(/^\s*titled\s*(.*?)\s*$/, '\1') : Forgery::LoremIpsum.sentence({:random => true}).gsub(/\.$/, '').titlecase
|
||||
workshop.info = Forgery::LoremIpsum.paragraph({:random => true})
|
||||
workshop.locale = :en
|
||||
workshop.save
|
||||
WorkshopFacilitator.create(user_id: TestState.my_account.id, workshop_id: workshop.id, role: :creator)
|
||||
(1..(facilitator_count || '0').to_i).each do |i|
|
||||
username = Forgery::LoremIpsum.word({:random => true})
|
||||
user = User.create(firstname: username, email: "#{username}@bikebike.org")
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: workshop.id, role: :collaborator)
|
||||
end
|
||||
TestState.last_workshop = workshop
|
||||
end
|
||||
|
||||
Given /^(.+?) (?:person is |people are )?interested(?: in '(.+?)')?$/i do |interested, title|
|
||||
workshop = title.present? ? Workshop.find_by_title(title) : TestState.last_workshop
|
||||
str_to_num(interested).times do
|
||||
user = create_user
|
||||
WorkshopInterest.create(workshop_id: workshop.id, user_id: user.id)
|
||||
end
|
||||
end
|
||||
|
||||
Given /^(\d+) (?:person has |people have )?requested to facilitate (?:the |my )?workshop$/i do |request_count|
|
||||
(1..(request_count || '0').to_i).each do |i|
|
||||
username = Forgery::LoremIpsum.word({:random => true})
|
||||
user = User.create(firstname: username, email: "#{username}@bikebike.org")
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: TestState.last_workshop.id, role: :requested)
|
||||
end
|
||||
end
|
||||
|
||||
Given /^'(.+)' has requested to facilitate (?:the |my )?workshop$/i do |username|
|
||||
user = get_user(username)
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: TestState.last_workshop.id, role: :requested)
|
||||
end
|
||||
|
||||
Given /^(.+) is (?:also )?facilitating (?:the |my )?workshop$/i do |username|
|
||||
user = User.create(firstname: username, email: "#{username.gsub(/\s+/, '.')}@bikebike.org")
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: TestState.last_workshop.id, role: :collaborator)
|
||||
end
|
||||
|
||||
Then /^(?:I )?(approve|deny) the facilitator request from (.+)$/i do |action, username|
|
||||
user = User.find_by_firstname(username)
|
||||
visit "/conferences/#{TestState.last_conference.slug}/workshops/#{TestState.last_workshop.id}/facilitate_request/#{user.id}/#{action}/"
|
||||
end
|
||||
|
||||
Then /^(?:I )?(?:should )?(not )?see (.+) workshops?(?: in total)?(?: under '(.+?)')?$/i do |negate, number, heading|
|
||||
if heading
|
||||
parent = parent_element(element_with_text(heading))
|
||||
else
|
||||
parent = page
|
||||
end
|
||||
compare(number, parent.all('.workshop-list > li, #schedule-preview .workshop').size, negate)
|
||||
end
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 130 KiB |
+56
-129
@@ -1,157 +1,84 @@
|
||||
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
|
||||
# It is recommended to regenerate this file in the future when you upgrade to a
|
||||
# newer version of cucumber-rails. Consider adding your own code to a new file
|
||||
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
|
||||
# files.
|
||||
|
||||
require 'cucumber/rails'
|
||||
require 'capybara/poltergeist'
|
||||
require 'lingua_franca/capybara'
|
||||
require 'mocha/mini_test'
|
||||
require 'fileutils'
|
||||
require 'marmara'
|
||||
|
||||
# Capybara defaults to CSS3 selectors rather than XPath.
|
||||
# If you'd prefer to use XPath, just uncomment this line and adjust any
|
||||
# selectors in your step definitions to use the XPath syntax.
|
||||
# Capybara.default_selector = :xpath
|
||||
|
||||
# By default, any exception happening in your Rails application will bubble up
|
||||
# to Cucumber so that your scenario will fail. This is a different from how
|
||||
# your application behaves in the production environment, where an error page will
|
||||
# be rendered instead.
|
||||
#
|
||||
# Sometimes we want to override this default behaviour and allow Rails to rescue
|
||||
# exceptions and display an error page (just like when the app is running in production).
|
||||
# Typical scenarios where you want to do this is when you test your error pages.
|
||||
# There are two ways to allow Rails to rescue exceptions:
|
||||
#
|
||||
# 1) Tag your scenario (or feature) with @allow-rescue
|
||||
#
|
||||
# 2) Set the value below to true. Beware that doing this globally is not
|
||||
# recommended as it will mask a lot of errors for you!
|
||||
#
|
||||
ActionController::Base.allow_rescue = false
|
||||
|
||||
# Remove/comment out the lines below if your app doesn't have a database.
|
||||
# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
|
||||
begin
|
||||
DatabaseCleaner.strategy = :truncation
|
||||
#DatabaseCleaner.clean_with(:truncation)
|
||||
rescue NameError
|
||||
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
|
||||
DatabaseCleaner.strategy = :truncation, { except: %w[cities city_cache] }
|
||||
|
||||
Capybara.register_driver :bb_poltergeist do |app|
|
||||
if ENV['CSS_TEST']
|
||||
Marmara.options = {
|
||||
ignore: [/paypal\./],
|
||||
rewrite: {
|
||||
from: /^.*\/(.*?)\/.*?\.css$/,
|
||||
to: '\1.css'
|
||||
},
|
||||
minimum: {
|
||||
declarations: 30
|
||||
}
|
||||
}
|
||||
Marmara.start_recording
|
||||
end
|
||||
|
||||
opts = {
|
||||
timeout: 10,
|
||||
window_size: [1200, 800]
|
||||
}
|
||||
Capybara::Poltergeist::Driver.new(app, opts)
|
||||
end
|
||||
|
||||
Before('@javascript') do
|
||||
ActiveRecord::Base.shared_connection = nil
|
||||
ActiveRecord::Base.descendants.each do |model|
|
||||
model.shared_connection = nil
|
||||
end
|
||||
ActiveRecord::Base.shared_connection = nil
|
||||
ActiveRecord::Base.descendants.each do |model|
|
||||
model.shared_connection = nil
|
||||
end
|
||||
end
|
||||
|
||||
Before do
|
||||
# user_agent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
|
||||
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A"
|
||||
#request.stub!(:user_agent).and_return()
|
||||
#controller.request.stub!(:user_agent).and_return(user_agent)
|
||||
ActionDispatch::Request.any_instance.stubs(:user_agent).returns(user_agent)
|
||||
#page.driver.browser.header('User-Agent', user_agent)
|
||||
#page.driver.headers = { "User-Agent" => "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2403.157 Safari/537.36" }
|
||||
TestState.reset!
|
||||
safari5 = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
|
||||
chrome55 = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"
|
||||
ActionDispatch::Request.any_instance.stubs(:user_agent).returns(safari5)
|
||||
LinguaFranca.test_driver = page.driver
|
||||
host = "http://#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}"
|
||||
LinguaFranca.host = host
|
||||
Mail::TestMailer.deliveries.clear
|
||||
end
|
||||
|
||||
After do |scenario|
|
||||
#save_and_open_page if scenario.failed?
|
||||
puts " = PAGE START = \n#{page.html}\n = PAGE END = " if scenario.failed?
|
||||
#puts page.find('#main')['innerHTML'] if scenario.failed?
|
||||
sleep 1
|
||||
log_result scenario
|
||||
LinguaFranca.screenshot_mail
|
||||
|
||||
if scenario.failed?
|
||||
if @exception
|
||||
puts @exception.to_s
|
||||
puts @exception.backtrace.join("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
After do
|
||||
DatabaseCleaner.clean
|
||||
DatabaseCleaner.clean
|
||||
end
|
||||
|
||||
#After('suite') do
|
||||
# puts " ============ #{After all} ============ "
|
||||
#end
|
||||
AfterStep do
|
||||
# capture used selectors to generate css coverage
|
||||
Marmara.record(page) if Marmara.recording?
|
||||
|
||||
# You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios.
|
||||
# See the DatabaseCleaner documentation for details. Example:
|
||||
#
|
||||
# Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do
|
||||
# # { :except => [:widgets] } may not do what you expect here
|
||||
# # as Cucumber::Rails::Database.javascript_strategy overrides
|
||||
# # this setting.
|
||||
# DatabaseCleaner.strategy = :truncation
|
||||
# end
|
||||
#
|
||||
# Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do
|
||||
# DatabaseCleaner.strategy = :transaction
|
||||
# end
|
||||
#
|
||||
|
||||
# Possible values are :truncation and :transaction
|
||||
# The :transaction strategy is faster, but might give you threading problems.
|
||||
# See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature
|
||||
Capybara.register_driver :bb_poltergeist do |app|
|
||||
I18n.backend.start_recording_html(Capybara::LinguaFrancaPoltergeist::Driver.new(app, :inspector => true, :timeout => 120))
|
||||
# take some extra time between steps if we're recording
|
||||
sleep(0.5) if LinguaFranca.recording?
|
||||
end
|
||||
|
||||
Cucumber::Rails::Database.javascript_strategy = :transaction
|
||||
Capybara.default_driver = :bb_poltergeist
|
||||
Capybara.javascript_driver = :bb_poltergeist
|
||||
Geocoder.configure(:timeout => 60)
|
||||
Geocoder.configure(timeout: 60)
|
||||
|
||||
def locate(id)
|
||||
id = id.gsub(/\s+/, '_')
|
||||
e = page.all("[name=\"#{id}\"], [id=\"#{id}\"]")
|
||||
if e.length
|
||||
return e.first[:id]
|
||||
end
|
||||
page.all("[name$=\"#{id}\"], [id$=\"#{id}\"]").first[:id]
|
||||
end
|
||||
|
||||
def create_org(name = nil, location = nil)
|
||||
org = FactoryGirl.create(:org)
|
||||
found_location = nil
|
||||
if location.present?
|
||||
cache_file = File.join(File.dirname(__FILE__), 'location_cache.yml')
|
||||
cache = {}
|
||||
if File.exists?(cache_file)
|
||||
begin
|
||||
cache = YAML.load_file(cache_file)
|
||||
rescue
|
||||
# get rid of the cache if there's an error
|
||||
end
|
||||
end
|
||||
l = cache[location]
|
||||
if l.nil?
|
||||
l = Geocoder.search(location).first
|
||||
cache[location] = l
|
||||
File.open(cache_file, 'w') { |f| f.write cache.to_yaml }
|
||||
end
|
||||
begin
|
||||
found_location = Location.new(city: l.city, territory: l.province_code, country: l.country_code, latitude: l.latitude, longitude: l.longitude)
|
||||
rescue; end
|
||||
if found_location.nil?
|
||||
# let it though, we might be offline
|
||||
org.save!
|
||||
return org
|
||||
end
|
||||
end
|
||||
if name.present?
|
||||
org.name = name
|
||||
org.slug = org.generate_slug(name, found_location)
|
||||
end
|
||||
if found_location.present?
|
||||
org.locations << found_location
|
||||
end
|
||||
org.save!
|
||||
org
|
||||
end
|
||||
|
||||
def get_language_code(language)
|
||||
languages = {
|
||||
'english' => 'en',
|
||||
'french' => 'fr',
|
||||
'spanish' => 'es',
|
||||
'german' => 'de'
|
||||
}
|
||||
languages[language.downcase]
|
||||
at_exit do
|
||||
Marmara.stop_recording if Marmara.recording?
|
||||
# LinguaFranca.capture_translations if LinguaFranca.recording?
|
||||
end
|
||||
|
||||
@@ -1,24 +1,146 @@
|
||||
FactoryGirl.define do
|
||||
factory :upcoming_conference, :class => 'Conference' do
|
||||
title 'My Bike!Bike!'
|
||||
slug 'MyBikeBike'
|
||||
info 'Curabitur non nulla sit amet nisl tempus convallis quis ac lectus.'
|
||||
poster 'poster.jpg'
|
||||
cover 'cover.jpg'
|
||||
registration_open false
|
||||
start_date Date.today - 30.days
|
||||
end_date Date.today - 26.days
|
||||
conference_type_id (ConferenceType.find_by(:slug => 'bikebike') || ConferenceType.create(:slug => 'bikebike')).id
|
||||
paypal_username 'joe'
|
||||
locale 'en'
|
||||
end
|
||||
factory :upcoming_conference, class: :Conference do
|
||||
info Forgery::LoremIpsum.paragraphs(2, sentences: 6, html: true, random: true)
|
||||
start_date Date.new(2025, 9, 1)
|
||||
end_date Date.new(2025, 9, 4)
|
||||
conferencetype :annual
|
||||
year 2025
|
||||
paypal_username 'joe'
|
||||
locale 'en'
|
||||
is_public true
|
||||
is_featured true
|
||||
|
||||
factory :org, :class => 'Organization' do
|
||||
name 'My Organization'
|
||||
info 'Curabitur non nulla sit amet nisl tempus convallis quis ac lectus.'
|
||||
avatar 'avatar.jpg'
|
||||
cover 'cover.jpg'
|
||||
end
|
||||
factory :upcoming_regional_conference, class: :Conference do
|
||||
start_date Date.new(2025, 2, 14)
|
||||
end_date Date.new(2025, 2, 16)
|
||||
conferencetype :nw
|
||||
end
|
||||
|
||||
factory :past_conference, class: :Conference do
|
||||
start_date Date.new(2013, 10, 3)
|
||||
end_date Date.new(2013, 10, 6)
|
||||
year 2013
|
||||
is_featured false
|
||||
end
|
||||
end
|
||||
|
||||
factory :registration, class: :ConferenceRegistration do
|
||||
conference_id nil
|
||||
user_id nil
|
||||
is_attending 'y'
|
||||
registration_fees_paid [25, 50, 100, Random.rand(10...150)].sample
|
||||
arrival nil
|
||||
departure nil
|
||||
other Forgery::LoremIpsum.paragraph(random: true)
|
||||
allergies Forgery::LoremIpsum.paragraph(random: true)
|
||||
steps_completed [:policy, :contact_info, :questions, :hosting, :payment]
|
||||
can_provide_housing false
|
||||
housing_data {}
|
||||
city_id 2
|
||||
end
|
||||
|
||||
factory :org, class: :Organization do
|
||||
name 'My Organization'
|
||||
info 'Curabitur non nulla sit amet nisl tempus convallis quis ac lectus.'
|
||||
end
|
||||
|
||||
factory :user, class: :User do
|
||||
email Forgery::Internet.email_address
|
||||
firstname Forgery::Name.full_name
|
||||
end
|
||||
|
||||
factory :workshop, class: :Workshop do
|
||||
conference_id nil
|
||||
languages ['en'].to_json
|
||||
end
|
||||
end
|
||||
|
||||
World(FactoryGirl::Syntax::Methods)
|
||||
World(FactoryGirl::Syntax::Methods)
|
||||
|
||||
def create_user(options = {})
|
||||
options[:firstname] ||= Forgery(:name).full_name
|
||||
options[:email] ||= Forgery(:internet).email_address
|
||||
options[:languages] ||= ['en'].to_json
|
||||
options[:languages] = options[:languages].to_json if options[:languages].is_a?(Array)
|
||||
User.create(options)
|
||||
end
|
||||
|
||||
def create_workshop(title, user = TestState.my_account)
|
||||
workshop = FactoryGirl.build(:workshop)
|
||||
workshop.conference_id = TestState.last_conference.id
|
||||
workshop.title = title || Forgery::LoremIpsum.sentence(random: true).gsub(/\.$/, '').titlecase
|
||||
workshop.theme = TestState::Sample[:workshop].all_themes
|
||||
workshop.space = TestState::Sample[:workshop].all_spaces
|
||||
workshop.needs = [TestState::Sample[:workshop].all_needs].to_json
|
||||
workshop.info = Forgery::LoremIpsum.paragraphs(Random.rand(1..4), sentences: Random.rand(3..8), random: true)
|
||||
workshop.save!
|
||||
WorkshopFacilitator.create(user_id: user.id, workshop_id: workshop.id, role: :creator)
|
||||
TestState.last_workshop = workshop
|
||||
return workshop
|
||||
end
|
||||
|
||||
def create_location(options)
|
||||
location = EventLocation.new(options)
|
||||
location.conference_id = TestState.last_conference.id
|
||||
location.save!
|
||||
return location
|
||||
end
|
||||
|
||||
def create_registration(user = TestState.my_account)
|
||||
registration = FactoryGirl.build(:registration)
|
||||
registration.conference_id = TestState.last_conference.id
|
||||
registration.user_id = user.id
|
||||
registration.arrival = TestState.last_conference.start_date
|
||||
registration.departure = TestState.last_conference.end_date
|
||||
registration.housing = TestState::Sample[:conference_registration].all_housing_options
|
||||
registration.bike = TestState::Sample[:conference_registration].all_bike_options
|
||||
registration.food = TestState::Sample[:conference_registration].all_food_options
|
||||
registration.save!
|
||||
|
||||
if user == TestState.my_account
|
||||
TestState.my_registration = registration
|
||||
else
|
||||
TestState.last_registration = registration
|
||||
end
|
||||
|
||||
return registration
|
||||
end
|
||||
|
||||
def create_org(name = nil, location = nil)
|
||||
org = FactoryGirl.create(:org)
|
||||
found_location = nil
|
||||
if location.present?
|
||||
cache_file = File.join(File.dirname(__FILE__), 'location_cache.yml')
|
||||
cache = {}
|
||||
if File.exists?(cache_file)
|
||||
begin
|
||||
cache = YAML.load_file(cache_file)
|
||||
rescue
|
||||
# get rid of the cache if there's an error
|
||||
end
|
||||
end
|
||||
l = cache[location]
|
||||
if l.nil?
|
||||
l = Geocoder.search(location).first
|
||||
cache[location] = l
|
||||
File.open(cache_file, 'w') { |f| f.write cache.to_yaml }
|
||||
end
|
||||
begin
|
||||
found_location = Location.new(city: l.city, territory: l.province_code, country: l.country_code, latitude: l.latitude, longitude: l.longitude)
|
||||
rescue; end
|
||||
if found_location.nil?
|
||||
# let it though, we might be offline
|
||||
org.save!
|
||||
return org
|
||||
end
|
||||
end
|
||||
if name.present?
|
||||
org.name = name
|
||||
org.slug = org.generate_slug(name, found_location)
|
||||
end
|
||||
if found_location.present?
|
||||
org.locations << found_location
|
||||
end
|
||||
org.save!
|
||||
org
|
||||
end
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
include Sorcery::TestHelpers::Rails
|
||||
|
||||
def locate(id)
|
||||
id = id.gsub(/\s+/, '_')
|
||||
e = page.all("[name=\"#{id}\"], [id=\"#{id}\"], [id^=\"#{id}--\"]")
|
||||
return e.first[:id]
|
||||
end
|
||||
|
||||
def selector_for(id)
|
||||
prefixes = ['body.has-overlay .dlg.open ', 'body #primary-content ']
|
||||
selectors = ['[name="{id}"]', '[id="{id}"]', '[id^="{id}--"]']
|
||||
|
||||
selector = []
|
||||
prefixes.each do | pre |
|
||||
selectors.each do | sel |
|
||||
selector << "#{pre}#{sel}".gsub(/\{id\}/, id)
|
||||
end
|
||||
end
|
||||
|
||||
selector.join(',')
|
||||
end
|
||||
|
||||
def get_language_code(language)
|
||||
languages = {
|
||||
'english' => 'en',
|
||||
'french' => 'fr',
|
||||
'spanish' => 'es',
|
||||
'german' => 'de'
|
||||
}
|
||||
languages[language.downcase]
|
||||
end
|
||||
|
||||
def to_filename(filename)
|
||||
filename.gsub(/[^\w\s_-]+/, '')
|
||||
.gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
|
||||
.gsub(/\s+/, '_')
|
||||
end
|
||||
|
||||
def log_result(scenario)
|
||||
if Capybara.current_session.server.present?
|
||||
dir = "log/test-results/#{to_filename(scenario.feature.name)}"
|
||||
FileUtils::mkdir_p dir
|
||||
filename = "#{to_filename(scenario.name)}.html"
|
||||
File.write("#{dir}/#{filename}", capture_html)
|
||||
end
|
||||
end
|
||||
|
||||
def capture_html(distance_from_root = 3)
|
||||
html = page.html
|
||||
host = "http://#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}"
|
||||
public_dir = "#{'../' * distance_from_root}public/"
|
||||
|
||||
html.gsub(/(=\"|\(['"]?)(?:#{host})?\/(assets|uploads)/, "\\1#{public_dir}\\2")
|
||||
end
|
||||
|
||||
def attempt_to(&block)
|
||||
begin
|
||||
retries ||= 0
|
||||
timeout ||= 0
|
||||
timeout += 1
|
||||
yield
|
||||
rescue Exception => e
|
||||
raise e unless (retries += 1) <= 4
|
||||
# puts "Failed: #{e}"
|
||||
# puts "Retry ##{retries}"
|
||||
sleep(timeout * timeout)
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
def last_email_html
|
||||
if TestState.last_email.parts
|
||||
TestState.last_email.parts.last.body.raw_source
|
||||
else
|
||||
TestState.last_email.body.raw_source
|
||||
end
|
||||
end
|
||||
|
||||
def find_in_last_email(selector, attribute = nil)
|
||||
html = last_email_html.gsub(/^.*?(<table .*<\/table>).*$/m, '\1').gsub(/\n/, ' ').gsub(/\'/, '\\\'')
|
||||
Nokogiri::HTML(html).at(selector).attr(attribute)
|
||||
end
|
||||
|
||||
def emails_to(email_address, subject = nil)
|
||||
ActionMailer::Base.deliveries.select do |mail|
|
||||
mail.to.include?(email_address) &&
|
||||
(subject.nil? || mail.subject.downcase =~ /#{Regexp.escape(subject.downcase)}/)
|
||||
end
|
||||
end
|
||||
|
||||
def str_to_num(num)
|
||||
nums = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
|
||||
return nums.find_index(num) if nums.include?(num)
|
||||
|
||||
case num
|
||||
when 'no', 'none'
|
||||
return 0
|
||||
when 'a', 'an'
|
||||
return 1
|
||||
when 'two', 'couple', 'a couple', 'couple of', 'a couple of'
|
||||
return 2
|
||||
end
|
||||
|
||||
return num.to_i if num =~ /\d+/
|
||||
|
||||
fail "Could not interpret '#{num}' as a number"
|
||||
end
|
||||
|
||||
def compare(expected, actual, negate = false)
|
||||
case expected
|
||||
when /any|some/
|
||||
expectation = (be >= 1)
|
||||
else
|
||||
expectation = (be == str_to_num(expected))
|
||||
end
|
||||
expect(actual).send(negate ? :not_to : :to, expectation)
|
||||
end
|
||||
|
||||
def email_address(user)
|
||||
case user
|
||||
when /(I|me)/
|
||||
TestState.last_email_entered || TestState.my_account.email
|
||||
when /^(?:the )?site administrator$/i
|
||||
'goodgodwin@hotmail.com'
|
||||
when /^'(.+)'$/
|
||||
get_user($1).email
|
||||
else
|
||||
user
|
||||
end
|
||||
end
|
||||
|
||||
def get_locale(language)
|
||||
return ({
|
||||
spanish: :es,
|
||||
english: :en,
|
||||
french: :fr,
|
||||
german: :de,
|
||||
klingon: :tlh
|
||||
}[language.strip.downcase.to_sym] or fail "Unable to convert '#{language.trim}' into a locale")
|
||||
end
|
||||
|
||||
def get_field(field)
|
||||
field = field.gsub(/^\s*(my|the)\s*(.+)$/, '\2').gsub(/\s/, '_')
|
||||
aliases = {'phone_number' => 'phone', 'email_address' => 'email'}
|
||||
return aliases[field] || field
|
||||
end
|
||||
|
||||
def get_user(username)
|
||||
return create_user unless username.present?
|
||||
|
||||
TestState::Users[username] = create_user({
|
||||
(username =~ /^[^\s]+@[^\s]+\.[^\s]+$/ ? :email : :firstname) => username
|
||||
}) unless TestState::Users[username].present?
|
||||
|
||||
return TestState::Users[username]
|
||||
end
|
||||
|
||||
def element_with_text(text, parent = page)
|
||||
smallest = nil
|
||||
parent.all('*', text: text).each do |node|
|
||||
smallest = node if smallest.nil? || smallest.native['outerHTML'].length > node.native['outerHTML'].length
|
||||
end
|
||||
return smallest
|
||||
end
|
||||
|
||||
def parent_element(node)
|
||||
node.first(:xpath, './/..')
|
||||
end
|
||||
|
||||
def headers_to_attributes(object)
|
||||
new_object = {}
|
||||
object.each do |key, value|
|
||||
new_object[key.underscore] = value
|
||||
end
|
||||
|
||||
return new_object
|
||||
end
|
||||
|
||||
def string_to_time(str)
|
||||
h, m = str.split(':')
|
||||
h = h.to_i
|
||||
m = m.to_i
|
||||
h += 12 if h < 6
|
||||
return h + (m > 0 ? 0.5 : 0)
|
||||
end
|
||||
|
||||
def string_to_time_length(str)
|
||||
parts = str.match(/^(?:(\d+) hour)?\s*(?:(\d+) minutes)?$/)
|
||||
return (parts[1] || '0').to_i + ((parts[2] || '0').to_i > 0 ? 0.5 : 0)
|
||||
end
|
||||
|
||||
def str_to_wday(str)
|
||||
return [:sun, :mon, :tue, :wed, :thu, :fri, :sat].index(str[0...3].downcase.to_sym)
|
||||
end
|
||||
@@ -1,24 +1,74 @@
|
||||
---
|
||||
" in Halifax NS": !ruby/object:Geocoder::Result::Google
|
||||
Brooklyn NY: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Halifax
|
||||
short_name: Halifax
|
||||
- long_name: Brooklyn
|
||||
short_name: Brooklyn
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Halifax
|
||||
short_name: Halifax
|
||||
types:
|
||||
- administrative_area_level_3
|
||||
- political
|
||||
- long_name: Halifax Regional Municipality
|
||||
short_name: Halifax Regional Municipality
|
||||
- sublocality
|
||||
- sublocality_level_1
|
||||
- long_name: Kings County
|
||||
short_name: Kings County
|
||||
types:
|
||||
- administrative_area_level_2
|
||||
- political
|
||||
- long_name: Nova Scotia
|
||||
short_name: NS
|
||||
- long_name: New York
|
||||
short_name: NY
|
||||
types:
|
||||
- administrative_area_level_1
|
||||
- political
|
||||
- long_name: United States
|
||||
short_name: US
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
formatted_address: Brooklyn, NY, USA
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 40.739446
|
||||
lng: -73.8333651
|
||||
southwest:
|
||||
lat: 40.551042
|
||||
lng: -74.05663
|
||||
location:
|
||||
lat: 40.6781784
|
||||
lng: -73.9441579
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 40.739446
|
||||
lng: -73.8333651
|
||||
southwest:
|
||||
lat: 40.551042
|
||||
lng: -74.05663
|
||||
place_id: ChIJCSF8lBZEwokRhngABHRcdoI
|
||||
types:
|
||||
- political
|
||||
- sublocality
|
||||
- sublocality_level_1
|
||||
cache_hit:
|
||||
Yellowknife: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Yellowknife
|
||||
short_name: Yellowknife
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Fort Smith, Unorganized
|
||||
short_name: Fort Smith, Unorganized
|
||||
types:
|
||||
- administrative_area_level_3
|
||||
- political
|
||||
- long_name: Fort Smith Region
|
||||
short_name: Fort Smith Region
|
||||
types:
|
||||
- administrative_area_level_2
|
||||
- political
|
||||
- long_name: Northwest Territories
|
||||
short_name: NT
|
||||
types:
|
||||
- administrative_area_level_1
|
||||
- political
|
||||
@@ -27,42 +77,291 @@
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
formatted_address: Halifax, NS, Canada
|
||||
- long_name: X0E
|
||||
short_name: X0E
|
||||
types:
|
||||
- postal_code
|
||||
- postal_code_prefix
|
||||
formatted_address: Yellowknife, NT X0E, Canada
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 44.7035313
|
||||
lng: -63.5576784
|
||||
lat: 62.5412576
|
||||
lng: -114.299678
|
||||
southwest:
|
||||
lat: 44.5949302
|
||||
lng: -63.68627009999999
|
||||
lat: 62.4084661
|
||||
lng: -114.518312
|
||||
location:
|
||||
lat: 44.6488625
|
||||
lng: -63.5753196
|
||||
lat: 62.4539717
|
||||
lng: -114.3717886
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 44.7035313
|
||||
lng: -63.5576784
|
||||
lat: 62.5412577
|
||||
lng: -114.299678
|
||||
southwest:
|
||||
lat: 44.5949302
|
||||
lng: -63.68627009999999
|
||||
partial_match: true
|
||||
place_id: ChIJwfrbBxQhWksR3C2LQ6bja2Y
|
||||
lat: 62.4084945
|
||||
lng: -114.518312
|
||||
place_id: ChIJyYJGoyzx0VMRge9xQyQ3wbQ
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
cache_hit:
|
||||
" in Sackville NB": !ruby/object:Geocoder::Result::Google
|
||||
New Orleans: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Sackville
|
||||
short_name: Sackville
|
||||
- long_name: New Orleans
|
||||
short_name: New Orleans
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Westmorland County
|
||||
short_name: Westmorland County
|
||||
- long_name: Orleans Parish
|
||||
short_name: Orleans Parish
|
||||
types:
|
||||
- administrative_area_level_2
|
||||
- political
|
||||
- long_name: Louisiana
|
||||
short_name: LA
|
||||
types:
|
||||
- administrative_area_level_1
|
||||
- political
|
||||
- long_name: United States
|
||||
short_name: US
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
formatted_address: New Orleans, LA, USA
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 30.199332
|
||||
lng: -89.625053
|
||||
southwest:
|
||||
lat: 29.8666609
|
||||
lng: -90.14007389999999
|
||||
location:
|
||||
lat: 29.95106579999999
|
||||
lng: -90.0715323
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 30.1748625
|
||||
lng: -89.6269311
|
||||
southwest:
|
||||
lat: 29.86842459999999
|
||||
lng: -90.1380099
|
||||
place_id: ChIJZYIRslSkIIYRtNMiXuhbBts
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
cache_hit:
|
||||
Drumheller AB: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Drumheller
|
||||
short_name: Drumheller
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Division No. 5
|
||||
short_name: Division No. 5
|
||||
types:
|
||||
- administrative_area_level_2
|
||||
- political
|
||||
- long_name: Alberta
|
||||
short_name: AB
|
||||
types:
|
||||
- administrative_area_level_1
|
||||
- political
|
||||
- long_name: Canada
|
||||
short_name: CA
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
formatted_address: Drumheller, AB, Canada
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 51.488701
|
||||
lng: -112.4530051
|
||||
southwest:
|
||||
lat: 51.3208389
|
||||
lng: -112.806076
|
||||
location:
|
||||
lat: 51.4651847
|
||||
lng: -112.7105343
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 51.488701
|
||||
lng: -112.4530051
|
||||
southwest:
|
||||
lat: 51.3208389
|
||||
lng: -112.806076
|
||||
place_id: ChIJHx_0B4ANc1MRWZCRwItZUUw
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
cache_hit:
|
||||
Portland OR: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Portland
|
||||
short_name: Portland
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Multnomah County
|
||||
short_name: Multnomah County
|
||||
types:
|
||||
- administrative_area_level_2
|
||||
- political
|
||||
- long_name: Oregon
|
||||
short_name: OR
|
||||
types:
|
||||
- administrative_area_level_1
|
||||
- political
|
||||
- long_name: United States
|
||||
short_name: US
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
formatted_address: Portland, OR, USA
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 45.654424
|
||||
lng: -122.4718489
|
||||
southwest:
|
||||
lat: 45.432393
|
||||
lng: -122.8369952
|
||||
location:
|
||||
lat: 45.5230622
|
||||
lng: -122.6764816
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 45.6524799
|
||||
lng: -122.4718489
|
||||
southwest:
|
||||
lat: 45.432393
|
||||
lng: -122.8369952
|
||||
place_id: ChIJJ3SpfQsLlVQRkYXR9ua5Nhw
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
cache_hit:
|
||||
Prince Rupert BC: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Prince Rupert
|
||||
short_name: Prince Rupert
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Skeena-Queen Charlotte
|
||||
short_name: Skeena-Queen Charlotte
|
||||
types:
|
||||
- administrative_area_level_2
|
||||
- political
|
||||
- long_name: British Columbia
|
||||
short_name: BC
|
||||
types:
|
||||
- administrative_area_level_1
|
||||
- political
|
||||
- long_name: Canada
|
||||
short_name: CA
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
formatted_address: Prince Rupert, BC, Canada
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 54.338083
|
||||
lng: -130.2437961
|
||||
southwest:
|
||||
lat: 54.19392
|
||||
lng: -130.3634291
|
||||
location:
|
||||
lat: 54.3150367
|
||||
lng: -130.3208187
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 54.3343706
|
||||
lng: -130.2478032
|
||||
southwest:
|
||||
lat: 54.202669
|
||||
lng: -130.3608029
|
||||
place_id: ChIJaUV_axPVclQRElbZTQ_jB3E
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
cache_hit:
|
||||
Regina, SK: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Regina
|
||||
short_name: Regina
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Sherwood No. 159
|
||||
short_name: Sherwood No. 159
|
||||
types:
|
||||
- administrative_area_level_3
|
||||
- political
|
||||
- long_name: Division No. 6
|
||||
short_name: Division No. 6
|
||||
types:
|
||||
- administrative_area_level_2
|
||||
- political
|
||||
- long_name: Saskatchewan
|
||||
short_name: SK
|
||||
types:
|
||||
- administrative_area_level_1
|
||||
- political
|
||||
- long_name: Canada
|
||||
short_name: CA
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
formatted_address: Regina, SK, Canada
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 50.5207396
|
||||
lng: -104.4924259
|
||||
southwest:
|
||||
lat: 50.3964489
|
||||
lng: -104.7783923
|
||||
location:
|
||||
lat: 50.4452112
|
||||
lng: -104.6188944
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 50.5207396
|
||||
lng: -104.4924259
|
||||
southwest:
|
||||
lat: 50.3964489
|
||||
lng: -104.7783923
|
||||
place_id: ChIJ6z2l-0AeHFMRsVR7t5YySjU
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
cache_hit:
|
||||
Edmundston, NB: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Edmundston
|
||||
short_name: Edmundston
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Madawaska County
|
||||
short_name: Madawaska County
|
||||
types:
|
||||
- administrative_area_level_2
|
||||
- political
|
||||
@@ -76,28 +375,128 @@
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
formatted_address: Sackville, NB, Canada
|
||||
formatted_address: Edmundston, NB, Canada
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 45.96934
|
||||
lng: -64.31372929999999
|
||||
lat: 47.456634
|
||||
lng: -68.14554509999999
|
||||
southwest:
|
||||
lat: 45.86707
|
||||
lng: -64.4562439
|
||||
lat: 47.3177789
|
||||
lng: -68.44122399999999
|
||||
location:
|
||||
lat: 45.897903
|
||||
lng: -64.3682803
|
||||
lat: 47.3690127
|
||||
lng: -68.32667409999999
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 45.96934
|
||||
lng: -64.31372929999999
|
||||
lat: 47.456634
|
||||
lng: -68.14554509999999
|
||||
southwest:
|
||||
lat: 45.86707
|
||||
lng: -64.4562439
|
||||
partial_match: true
|
||||
place_id: ChIJA-OnietQX0sR3kWeYPsw4gs
|
||||
lat: 47.3183866
|
||||
lng: -68.44122399999999
|
||||
place_id: ChIJuQPKxpipvUwRtNjzmeech34
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
cache_hit:
|
||||
Souris, MB: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Souris
|
||||
short_name: Souris
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Glenwood
|
||||
short_name: Glenwood
|
||||
types:
|
||||
- administrative_area_level_3
|
||||
- political
|
||||
- long_name: Division No. 7
|
||||
short_name: Division No. 7
|
||||
types:
|
||||
- administrative_area_level_2
|
||||
- political
|
||||
- long_name: Manitoba
|
||||
short_name: MB
|
||||
types:
|
||||
- administrative_area_level_1
|
||||
- political
|
||||
- long_name: Canada
|
||||
short_name: CA
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
- long_name: R0K
|
||||
short_name: R0K
|
||||
types:
|
||||
- postal_code
|
||||
- postal_code_prefix
|
||||
formatted_address: Souris, MB R0K, Canada
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 49.6272052
|
||||
lng: -100.2464522
|
||||
southwest:
|
||||
lat: 49.6061908
|
||||
lng: -100.2774639
|
||||
location:
|
||||
lat: 49.6207985
|
||||
lng: -100.2583026
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 49.6272052
|
||||
lng: -100.2464522
|
||||
southwest:
|
||||
lat: 49.6061908
|
||||
lng: -100.2774639
|
||||
place_id: ChIJjVrTVVh851IRLuGKzGdiUj8
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
cache_hit:
|
||||
Eldorado, MX: !ruby/object:Geocoder::Result::Google
|
||||
data:
|
||||
address_components:
|
||||
- long_name: Eldorado
|
||||
short_name: Eldorado
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
- long_name: Sinaloa
|
||||
short_name: Sin.
|
||||
types:
|
||||
- administrative_area_level_1
|
||||
- political
|
||||
- long_name: Mexico
|
||||
short_name: MX
|
||||
types:
|
||||
- country
|
||||
- political
|
||||
formatted_address: Eldorado, Sin., Mexico
|
||||
geometry:
|
||||
bounds:
|
||||
northeast:
|
||||
lat: 24.3379838
|
||||
lng: -107.3476352
|
||||
southwest:
|
||||
lat: 24.3108689
|
||||
lng: -107.3831387
|
||||
location:
|
||||
lat: 24.3240714
|
||||
lng: -107.3584174
|
||||
location_type: APPROXIMATE
|
||||
viewport:
|
||||
northeast:
|
||||
lat: 24.3379838
|
||||
lng: -107.3476352
|
||||
southwest:
|
||||
lat: 24.3108689
|
||||
lng: -107.3831387
|
||||
place_id: ChIJv33Pqm0ho4YRUQ45wKAluZ4
|
||||
types:
|
||||
- locality
|
||||
- political
|
||||
|
||||
+27
-26
@@ -1,34 +1,35 @@
|
||||
module NavigationHelpers
|
||||
def path_to(path)
|
||||
path = path.to_sym
|
||||
def path_to(path)
|
||||
path = path.to_sym
|
||||
args = []
|
||||
|
||||
case path
|
||||
when /^landing$/i
|
||||
path = :home
|
||||
when /^registration$/i
|
||||
path = "/conferences/#{@last_conference.slug}/register/"
|
||||
when /^edit conference$/i
|
||||
path = "/conferences/#{@last_conference.slug}/edit/"
|
||||
when /^(workshops|stats|broadcast)$/i
|
||||
path = "/conferences/#{@last_conference.slug}/#{path}/"
|
||||
when /^(stats.xls)$/i
|
||||
path = "/conferences/#{@last_conference.slug}/stats.xls"
|
||||
end
|
||||
case path
|
||||
when /^landing$/i
|
||||
path = :home
|
||||
when /^(my )?workshop$/i
|
||||
path = :view_workshop
|
||||
args << TestState.last_conference.slug
|
||||
args << TestState.last_workshop.id
|
||||
when /^registration$/i
|
||||
path = :register
|
||||
args << TestState.last_conference.slug
|
||||
when /^(conference|register|workshops)$/i
|
||||
args << TestState.last_conference.slug
|
||||
when /^confirm(ation)?$/
|
||||
path = :confirm
|
||||
args << TestState.last_token
|
||||
when /^google maps$/
|
||||
path = /^https:\/\/www\.google\.com\/maps\/place\/.*/
|
||||
end
|
||||
|
||||
if path.is_a?(Symbol)
|
||||
begin
|
||||
path = Rails.application.routes.url_helpers.send("#{path}_path".to_sym)
|
||||
rescue Object => e
|
||||
raise "Can't find mapping from \"#{path}\" to a path."
|
||||
end
|
||||
end
|
||||
if path.is_a?(Symbol)
|
||||
path = Rails.application.routes.url_helpers.send("#{path}_path".to_sym, *args)
|
||||
end
|
||||
|
||||
if path.blank?
|
||||
raise "Can't find mapping from \"#{page_name}\" to a path."
|
||||
end
|
||||
raise "Can't find mapping from \"#{path}\" to a path." unless path.present?
|
||||
|
||||
return path
|
||||
end
|
||||
return path
|
||||
end
|
||||
end
|
||||
|
||||
World(NavigationHelpers)
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
module TestState
|
||||
class Store
|
||||
attr_accessor :last_email_entered
|
||||
attr_accessor :last_conference
|
||||
attr_accessor :last_registration
|
||||
attr_accessor :last_organization
|
||||
attr_accessor :last_email
|
||||
attr_accessor :it
|
||||
|
||||
def my_account=(user)
|
||||
@my_account = user
|
||||
end
|
||||
|
||||
def my_account
|
||||
@my_account ||= User.find_by(email: last_email_entered)
|
||||
end
|
||||
|
||||
def my_registration=(reg)
|
||||
@my_registration = reg
|
||||
end
|
||||
|
||||
def my_registration
|
||||
@my_registration ||= ConferenceRegistration.find_by(user_id: my_account.id)
|
||||
end
|
||||
|
||||
def last_token=(token)
|
||||
@last_token = token
|
||||
end
|
||||
|
||||
def last_token
|
||||
@last_token ||= EmailConfirmation.where(user_id: my_account.id).last.token
|
||||
end
|
||||
|
||||
def last_workshop=(workshop)
|
||||
@last_workshop = workshop
|
||||
end
|
||||
|
||||
def last_workshop
|
||||
@last_workshop ||= Workshop.all.last
|
||||
end
|
||||
end
|
||||
|
||||
module Values
|
||||
class << self
|
||||
def []=(key, value)
|
||||
@my_values ||= {}
|
||||
@my_values[key.to_sym] = value
|
||||
end
|
||||
|
||||
def [](key)
|
||||
@my_values ||= {}
|
||||
return @my_values[key.to_sym]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Users
|
||||
class << self
|
||||
def []=(username, user)
|
||||
@users ||= {}
|
||||
@users[username.to_s] = user
|
||||
end
|
||||
|
||||
def [](username)
|
||||
@users ||= {}
|
||||
return @users[username.to_s]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Sample
|
||||
def self.[](type)
|
||||
@types ||= {}
|
||||
@types[type.to_sym] ||= Sample.new(type)
|
||||
return @types[type.to_sym]
|
||||
end
|
||||
|
||||
def method_missing(method_sym, *arguments, &block)
|
||||
@arrays ||= {}
|
||||
unless @arrays[method_sym].present?
|
||||
@arrays[method_sym] = {
|
||||
array: Object.const_get(@type.to_s.camelize).send(method_sym, *arguments, &block)
|
||||
}
|
||||
end
|
||||
|
||||
if @arrays[method_sym][:last].present?
|
||||
@arrays[method_sym][:last] += 1
|
||||
@arrays[method_sym][:last] = 0 if @arrays[method_sym][:last] >= @arrays[method_sym][:array].length
|
||||
else
|
||||
@arrays[method_sym][:last] = 0
|
||||
end
|
||||
|
||||
return @arrays[method_sym][:array][@arrays[method_sym][:last]]
|
||||
end
|
||||
|
||||
private
|
||||
def initialize(type)
|
||||
@type = type
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
def reset!
|
||||
@store = nil
|
||||
end
|
||||
|
||||
def method_missing(method_sym, *arguments, &block)
|
||||
@store ||= Store.new
|
||||
@store.send(method_sym, *arguments, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,323 @@
|
||||
Feature: Workshops
|
||||
Scenario: Registered users can create, edit, delete workshops
|
||||
Given there is an upcoming conference
|
||||
And registration is open
|
||||
And I am logged in
|
||||
And registered for the conference
|
||||
And on the registration page
|
||||
|
||||
Then I should see 'Propose a Workshop'
|
||||
But I should not see any workshops
|
||||
|
||||
When I click on 'Propose a Workshop'
|
||||
Then I should see 'Create a Workshop'
|
||||
And see 'Describe your workshop in detail'
|
||||
|
||||
When I enter a title
|
||||
And enter some info
|
||||
And I check 'Spanish'
|
||||
And check 'Projector'
|
||||
And check 'Funding'
|
||||
And check 'Meeting Room'
|
||||
And click the 'Save' button
|
||||
|
||||
Then I should be on my workshop page
|
||||
And I should see 'Funding'
|
||||
And should see 'Projector'
|
||||
And see my title
|
||||
And see my info
|
||||
|
||||
When I click on 'Edit'
|
||||
Then I should see 'Edit Workshop'
|
||||
And see 'Describe your workshop in detail'
|
||||
And 'English' should be checked
|
||||
And 'Spanish' should be checked
|
||||
And 'Projector' should be checked
|
||||
And 'Funding' should be checked
|
||||
And 'Meeting Room' should be checked
|
||||
|
||||
When I check 'Tools'
|
||||
And check 'Other'
|
||||
And enter the other theme as 'Education'
|
||||
And click the 'Save' button
|
||||
|
||||
Then I should be on my workshop page
|
||||
And I should see 'Tools'
|
||||
And should see 'Education'
|
||||
|
||||
When I click the 'Workshops' link
|
||||
Then I should see a workshop
|
||||
|
||||
When I click on the 'More info' link
|
||||
Then I should see 'Tools'
|
||||
And should see 'Education'
|
||||
|
||||
When I click the 'Delete Workshop' link
|
||||
Then I should see 'Deleting a workshop cannot be undone'
|
||||
|
||||
When I click on the 'Cancel' button
|
||||
Then I should see 'Tools'
|
||||
And should see 'Education'
|
||||
|
||||
When I click the 'Delete Workshop' link
|
||||
And click the 'Confirm' button
|
||||
Then I should see 'Propose a Workshop'
|
||||
But I should not see any workshops
|
||||
|
||||
Scenario: Users can comment on an translate their own workshops
|
||||
Given that there is an upcoming conference
|
||||
And registration is open
|
||||
And I am logged in
|
||||
And registered
|
||||
And I have a workshop titled 'Bridges to Bicycles'
|
||||
And I am on my workshop page
|
||||
|
||||
Then I should see 'Bridges to Bicycles'
|
||||
When I click 'Translate into Spanish'
|
||||
Then I should see 'Translation of Bridges to Bicycles'
|
||||
|
||||
When I enter my title as 'Puentes a las bicicletas'
|
||||
And enter some info
|
||||
And click the 'Save' button
|
||||
Then my workshop title should be 'Bridges to Bicycles'
|
||||
And my Spanish workshop title should be 'Puentes a las bicicletas'
|
||||
And I should see 'Bridges to Bicycles'
|
||||
|
||||
When I enter a comment
|
||||
And I click the 'Add Comment' button
|
||||
Then I should see 'less than a minute ago'
|
||||
And I should see my comment
|
||||
|
||||
When I click the 'Reply' button
|
||||
And enter a reply
|
||||
And click the 'Reply' button
|
||||
Then I should see my comment
|
||||
And see my reply
|
||||
|
||||
Scenario: Users can add facilitators to their workshops
|
||||
Given that there is an upcoming conference
|
||||
And registration is open
|
||||
And I am logged in
|
||||
And registered
|
||||
And I have a workshop titled 'Applying for 501c3 status'
|
||||
And I am on my workshop page
|
||||
|
||||
Then I should see 'Applying for 501c3 status'
|
||||
When I enter an email address as 'new-facilitator@bikebike.org'
|
||||
And click the '+' button
|
||||
|
||||
Then I should be on my workshop page
|
||||
And I should see 'new-facilitator@bikebike.org Unregistered'
|
||||
And new-facilitator@bikebike.org should get a 'Confirmation' email
|
||||
And new-facilitator@bikebike.org should get a 'You have been added as a facilitator' email
|
||||
|
||||
When I click the 'Remove' link
|
||||
Then I should see 'Please Confirm'
|
||||
And see 'Are you sure you would like to remove new-facilitator@bikebike.org as a facilitator of this workshop?'
|
||||
|
||||
When I click the 'No' button
|
||||
Then I should not see 'Please Confirm'
|
||||
But I should see 'new-facilitator@bikebike.org Unregistered'
|
||||
|
||||
When I click the 'Remove' link again
|
||||
Then I should see 'Please Confirm'
|
||||
And I should see 'Yes'
|
||||
And click the 'Yes' button
|
||||
Then I should not see 'Please Confirm'
|
||||
And I should not see 'new-facilitator@bikebike.org Unregistered'
|
||||
But I should see 'Applying for 501c3 status'
|
||||
|
||||
Scenario: Users can approve and deny facilitation requests on their workshops
|
||||
Given that there is an upcoming conference
|
||||
And registration is open
|
||||
And I am logged in
|
||||
And registered
|
||||
And I have a workshop titled 'Sturmey Archer Hub Repair'
|
||||
|
||||
And 'Spartacus' has requested to facilitate my workshop
|
||||
And 'Saladin' has requested to facilitate my workshop
|
||||
And 'Hadrian' has requested to facilitate my workshop
|
||||
|
||||
And 'Spartacus' is registered for the conference
|
||||
And 'Saladin' is registered for the conference
|
||||
And 'Hadrian' is registered for the conference
|
||||
|
||||
And I am on my workshop page
|
||||
|
||||
Then I should see 'Sturmey Archer Hub Repair'
|
||||
And I should see 'Spartacus Requested'
|
||||
And I should see 'Saladin Requested'
|
||||
And I should see 'Hadrian Requested'
|
||||
|
||||
When I click the 'Deny' button beside 'Spartacus'
|
||||
Then I should be on my workshop page
|
||||
And I should see 'Saladin'
|
||||
And I should see 'Hadrian'
|
||||
But I should not see 'Spartacus'
|
||||
And 'Spartacus' should get a 'Your request to facilitate ‘Sturmey Archer Hub Repair’ has been denied' email
|
||||
|
||||
When I click the 'Approve' button beside 'Saladin'
|
||||
Then I should be on my workshop page
|
||||
And I should see 'Saladin Collaborator'
|
||||
And 'Saladin' should get a 'You have been added as a facilitator of ‘Sturmey Archer Hub Repair’' email
|
||||
|
||||
When I click the 'Approve' button beside 'Hadrian'
|
||||
Then I should be on my workshop page
|
||||
And I should see 'Hadrian Collaborator'
|
||||
And 'Hadrian' should get a 'You have been added as a facilitator of ‘Sturmey Archer Hub Repair’' email
|
||||
|
||||
When I click the 'Remove' button beside 'Hadrian'
|
||||
Then I should see 'Please Confirm'
|
||||
And see 'Are you sure you would like to remove Hadrian as a facilitator of this workshop?'
|
||||
|
||||
When I click on the 'No' button
|
||||
Then I should see 'Hadrian'
|
||||
|
||||
When I click the 'Remove' button beside 'Hadrian' again
|
||||
Then I should see 'Please Confirm'
|
||||
And see 'Are you sure you would like to remove Hadrian as a facilitator of this workshop?'
|
||||
|
||||
When I click on the 'Yes' button
|
||||
Then I should not see 'Hadrian'
|
||||
|
||||
When I click the 'Transfer Ownership' button beside 'Saladin'
|
||||
Then I should see 'Please Confirm'
|
||||
And see 'Are you sure you want to transfer ownership to Saladin?'
|
||||
|
||||
When I click the 'No' button
|
||||
Then I should see 'Saladin Collaborator'
|
||||
|
||||
When I click the 'Transfer Ownership' button beside 'Saladin' again
|
||||
Then I should see 'Please Confirm'
|
||||
And see 'Are you sure you want to transfer ownership to Saladin?'
|
||||
|
||||
When I click the 'Yes' button
|
||||
Then I should not see 'Saladin Collaborator'
|
||||
But I should see 'Saladin Owner'
|
||||
|
||||
When I click the 'Leave' button
|
||||
Then I should see 'Please Confirm'
|
||||
And see 'Are you sure you would like to remove yourself as a facilitator of this workshop?'
|
||||
|
||||
When I click the 'No' button
|
||||
Then I should see 'Leave'
|
||||
|
||||
When I click the 'Leave' button again
|
||||
Then I should see 'Please Confirm'
|
||||
And see 'Are you sure you would like to remove yourself as a facilitator of this workshop?'
|
||||
|
||||
When I click the 'Yes' button
|
||||
Then I should not see 'Leave'
|
||||
But I should see 'Make a facilitation request'
|
||||
|
||||
When I click the 'Make a facilitation request' button
|
||||
Then I should see 'Request to Facilitate ‘Sturmey Archer Hub Repair’'
|
||||
|
||||
When I enter a message
|
||||
And click the 'Send' button
|
||||
|
||||
Then 'Saladin' should get a 'Request to facilitate ‘Sturmey Archer Hub Repair’' email
|
||||
And I should see 'Your request has been sent'
|
||||
|
||||
When I click the 'View this workshop' button
|
||||
Then I should see 'Cancel Request'
|
||||
|
||||
When I click the 'Cancel Request' button
|
||||
Then I should see 'Please Confirm'
|
||||
And I should see 'Are you sure you would like to cancel your request to become a facilitator of this workshop?'
|
||||
|
||||
When I click the 'No' button
|
||||
Then I should still see 'Cancel Request'
|
||||
When I click the 'Cancel Request' button again
|
||||
And click the 'Yes' button
|
||||
Then I should not see 'Cancel Request'
|
||||
But I should see 'Make a facilitation request'
|
||||
|
||||
Scenario: Users can add interest to workshops
|
||||
Given that there is an upcoming conference
|
||||
And registration is open
|
||||
And I am logged in
|
||||
And registered
|
||||
And I have a workshop titled 'Bridges to Bicycles'
|
||||
And there is a workshop titled '3-Speed Hubs and the trouble with Sexism'
|
||||
And there is a workshop titled 'Bike Polo! Mallet making and game'
|
||||
And there is a workshop titled 'Cooperating with for-profit bike shops'
|
||||
And there is a workshop titled 'The future of Bike! Bike!'
|
||||
|
||||
And '3-Speed Hubs and the trouble with Sexism' is looking for facilitators
|
||||
And I am facilitating 'Bike Polo! Mallet making and game'
|
||||
And one person is interested in 'Cooperating with for-profit bike shops'
|
||||
And ten people are interested in 'The future of Bike! Bike!'
|
||||
And five people are interested in 'Bike Polo! Mallet making and game'
|
||||
|
||||
And I am on the workshops page
|
||||
|
||||
Then I should see seven workshops
|
||||
And I should see two workshops under 'Your Workshops'
|
||||
And see five workshops under 'All Other Workshops'
|
||||
And I should see '3-Speed Hubs and the trouble with Sexism No one is interested in this workshop yet'
|
||||
And see 'Bike Polo! Mallet making and game 5 people are interested in this workshop'
|
||||
And see 'The future of Bike! Bike! 10 people are interested in this workshop'
|
||||
And see 'Cooperating with for-profit bike shops One person is interested in this workshop'
|
||||
|
||||
When I click the '+1' button beside '3-Speed Hubs and the trouble with Sexism'
|
||||
Then I should see '3-Speed Hubs and the trouble with Sexism You are interested in this workshop'
|
||||
|
||||
When I click the '+1' button beside 'The future of Bike! Bike!'
|
||||
Then I should see 'The future of Bike! Bike! You and 10 others are interested in this workshop'
|
||||
|
||||
When I click the '-1' button beside '3-Speed Hubs and the trouble with Sexism'
|
||||
Then I should see '3-Speed Hubs and the trouble with Sexism No one is interested in this workshop yet'
|
||||
|
||||
When I click the '-1' button beside 'The future of Bike! Bike!'
|
||||
Then I should see 'The future of Bike! Bike! 10 people are interested in this workshop'
|
||||
|
||||
Scenario: Translators can translate workshops
|
||||
Given that there is an upcoming conference
|
||||
And registration is open
|
||||
And I am logged in
|
||||
And registered
|
||||
And I speak Spanish
|
||||
And there is a workshop titled 'Women and Transgender shop hours'
|
||||
And 'Macbeth' is facilitating
|
||||
And I am on the workshop page
|
||||
|
||||
Then I should see 'Women and Transgender shop hours'
|
||||
When I click 'Translate into Spanish'
|
||||
Then I should see 'Translation of Women and Transgender shop hours'
|
||||
|
||||
When I enter my title as 'Horas de las mujeres y de los transexuales'
|
||||
And enter some info
|
||||
And click the 'Save' button
|
||||
|
||||
Then the Spanish workshop title should be 'Horas de las mujeres y de los transexuales'
|
||||
And I should see 'Women and Transgender shop hours'
|
||||
And 'Macbeth' should get a 'The translation for ‘Women and Transgender shop hours’ has been modified' email
|
||||
|
||||
Scenario: Users can comment on workshops
|
||||
Given that there is an upcoming conference
|
||||
And registration is open
|
||||
And I am logged in as 'Brunhilda'
|
||||
And registered
|
||||
And 'Geronimo' is registered
|
||||
And I have a workshop titled 'Grant writing and Government Contracts'
|
||||
And I am on the workshop page
|
||||
|
||||
When in a new session
|
||||
Then I log in as 'Geronimo'
|
||||
And I visit the workshop page
|
||||
And enter a comment as 'Will you be covering Canadian contracts?'
|
||||
And click the 'Add Comment' button
|
||||
|
||||
Then I should see 'Will you be covering Canadian contracts?'
|
||||
And 'Brunhilda' should get a 'commented' email
|
||||
|
||||
When in a new session
|
||||
Then I log in as 'Brunhilda'
|
||||
And I visit the workshop page
|
||||
And click the 'Reply' button
|
||||
And enter a reply as 'If we can find a Canadian facilitator'
|
||||
And click the 'Reply' button
|
||||
|
||||
Then I should see 'If we can find a Canadian facilitator'
|
||||
And 'Geronimo' should get a 'replied' email
|
||||
Reference in New Issue
Block a user