2017 refactor

This commit is contained in:
Godwin
2017-04-09 11:37:16 -07:00
parent 3d00b70087
commit d1db46ffaf
302 changed files with 7100 additions and 8082 deletions
+113
View File
@@ -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
+40
View File
@@ -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
+46 -11
View File
@@ -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
+606
View File
@@ -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'
+72
View File
@@ -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
+86
View File
@@ -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'
+22 -11
View File
@@ -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'
+102
View File
@@ -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
+54
View File
@@ -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
+124 -454
View File
@@ -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
+70
View File
@@ -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
+93
View File
@@ -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
+93
View File
@@ -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
+107
View File
@@ -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
View File
@@ -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
+142 -20
View File
@@ -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
+194
View File
@@ -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
+443 -44
View File
@@ -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
View File
@@ -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)
+112
View File
@@ -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
+323
View File
@@ -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