Fix regressions and refactorings

This commit is contained in:
Reinier Balt 2012-03-19 14:05:54 +01:00
parent 41ebd2ec9b
commit ca7d81d75a
21 changed files with 259 additions and 397 deletions

16
Gemfile
View file

@ -14,8 +14,12 @@ gem "aasm", "~>2.2.0"
gem "rubyjedi-actionwebservice", :require => "actionwebservice"
gem "rubycas-client", "~>2.2.1"
gem "ruby-openid", :require => "openid"
# you may comment out the database driver you will not be using.
# This will prevent a native build of the driver. Building native drivers is not always possible on all hosters
gem "sqlite3"
gem "mysql"
gem 'bcrypt-ruby', '~> 2.1.4'
gem 'htmlentities', '~> 4.3.0'
gem "mail"
@ -47,10 +51,14 @@ group :test do
gem "thoughtbot-factory_girl"
gem 'memory_test_fix', '~>0.1.3'
gem "capybara", ">=0.3.5"
gem "selenium-webdriver", "2.14.0" # is locked to 2.14.0 for https://code.google.com/p/selenium/issues/detail?id=3075
gem "capybara-webkit"
gem "capybara-screenshot"
gem "launchy"
gem "selenium-webdriver" # Note that > 2.14 has problems: https://code.google.com/p/selenium/issues/detail?id=3075
gem "database_cleaner", ">=0.5.0"
gem "cucumber-rails", "~>0.3.2"
# uncomment to use the webkit option. This depends on Qt to be installed
#gem "capybara-webkit"
# uncomment to be able to make screenshots from scenarios
#gem "capybara-screenshot"
#gem "launchy"
end

View file

@ -16,7 +16,6 @@ GEM
activesupport (= 2.3.14)
activesupport (2.3.14)
acts_as_list (0.1.4)
addressable (2.2.6)
bcrypt-ruby (2.1.4)
builder (3.0.0)
capybara (1.1.2)
@ -26,11 +25,6 @@ GEM
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
capybara-screenshot (0.1.10)
capybara (>= 1.0)
capybara-webkit (0.9.0)
capybara (>= 1.0.0, < 1.2)
json
cgi_multipart_eof_fix (2.5.0)
childprocess (0.3.1)
ffi (~> 1.0.6)
@ -62,8 +56,6 @@ GEM
httpclient (2.2.4)
i18n (0.6.0)
json (1.6.5)
launchy (2.0.5)
addressable (~> 2.2.6)
linecache (0.46)
rbx-require-relative (> 0.0.4)
mail (2.4.1)
@ -77,7 +69,7 @@ GEM
daemons (>= 1.0.3)
fastthread (>= 1.0.1)
gem_plugin (>= 0.2.3)
multi_json (1.0.4)
multi_json (1.1.0)
mysql (2.8.1)
nokogiri (1.4.7)
polyglot (0.3.3)
@ -112,10 +104,10 @@ GEM
rubyzip (0.9.6.1)
sanitize (1.2.1)
nokogiri (~> 1.4.1)
selenium-webdriver (2.14.0)
childprocess (>= 0.2.1)
ffi (~> 1.0.9)
multi_json (~> 1.0.4)
selenium-webdriver (2.20.0)
childprocess (>= 0.2.5)
ffi (~> 1.0)
multi_json (~> 1.0)
rubyzip
soap4r (1.5.8)
httpclient (>= 2.1.1)
@ -142,8 +134,6 @@ DEPENDENCIES
acts_as_list (~> 0.1.4)
bcrypt-ruby (~> 2.1.4)
capybara (>= 0.3.5)
capybara-screenshot
capybara-webkit
cucumber-rails (~> 0.3.2)
database_cleaner (>= 0.5.0)
flexmock
@ -152,7 +142,6 @@ DEPENDENCIES
hoe
hpricot
htmlentities (~> 4.3.0)
launchy
mail
memory_test_fix (~> 0.1.3)
mongrel
@ -166,7 +155,7 @@ DEPENDENCIES
rubycas-client (~> 2.2.1)
rubyjedi-actionwebservice
sanitize (~> 1.2.1)
selenium-webdriver (= 2.14.0)
selenium-webdriver
soap4r (~> 1.5.8)
sqlite3
test-unit (= 1.2.3)

View file

@ -9,7 +9,7 @@ Feature: dependencies
| testuser | secret | false |
And I have logged in as "testuser" with password "secret"
@javascript @webkit_only
@javascript
Scenario: Adding dependency to dependency by drag and drop
Given I have a project "dependencies" with 3 todos
And "todo 2" depends on "todo 1"
@ -73,9 +73,9 @@ Feature: dependencies
Then I should see "test 1" in the completed container
And I should see "test 2" in the action container
And I should not see "test 2" in the deferred container
And I should see the empty message in the deferred container
And I should see empty message for deferred todos of project
@javascript @selenium_only
@javascript
Scenario: Deleting a predecessor will activate successors
Given I have a context called "@pc"
And I have a project "dependencies" that has the following todos
@ -90,9 +90,9 @@ Feature: dependencies
When I delete the action "test 1"
Then I should see "test 2" in the action container
And I should not see "test 2" in the deferred container
And I should see the empty message in the deferred container
And I should see empty message for deferred todos of project
@javascript @selenium_only
@javascript
Scenario: Deleting a successor will update predecessor
Given I have a context called "@pc"
And I have a project "dependencies" that has the following todos
@ -111,7 +111,7 @@ Feature: dependencies
Then I should see "test 3" within the dependencies of "test 1"
And I should not see "test 2"
@javascript @webkit_only
@javascript
Scenario: Dragging an action to a completed action will not add it as a dependency
Given I have a context called "@pc"
And I have a project "dependencies" that has the following todos
@ -124,7 +124,7 @@ Feature: dependencies
Then I should see an error flash message saying "Cannot add this action as a dependency to a completed action!"
And I should see "test 1" in project container for "dependencies"
@javascript @webkit_only
@javascript
Scenario Outline: Marking a successor as complete will update predecessor
Given I have a context called "@pc"
And I have a project "dependencies" that has the following todos
@ -146,7 +146,7 @@ Feature: dependencies
| "dependencies" project |
| tag page for "bla" |
@javascript @webkit_only
@javascript
Scenario Outline: Marking a successor as active will update predecessor
Given I have a context called "@pc"
And I have a project "dependencies" that has the following todos

View file

@ -109,7 +109,7 @@ Feature: Edit a next action from every page
| tag page for "starred" | tag |
| "visible project" project | project |
@javascript @wip
@javascript
Scenario Outline: I can mark a completed todo active and it will update empty messages and context containers
Given I have a completed todo with description "visible todo" in project "visible project" with tags "starred" in the context "visible context"
When I go to the <page>
@ -209,8 +209,10 @@ Feature: Edit a next action from every page
When I go to the tickler page
Then I should see "start later"
@javascript
@javascript @wip
Scenario: I can defer a todo
# this script fails on https://code.google.com/p/selenium/issues/detail?id=3075 for selenium-webdriver > 2.14.
# and selenium-webdriver < 2.20 fails on firefox 11 :-( So @wip for now. This will work on webkit though
When I go to the home page
And I submit a new action with description "start later" in the context "@pc"
And I defer "start later" for 1 day
@ -218,8 +220,10 @@ Feature: Edit a next action from every page
When I go to the tickler page
Then I should see "start later"
@javascript
@javascript @wip
Scenario: I can make a project from a todo
# this script fails on https://code.google.com/p/selenium/issues/detail?id=3075 for selenium-webdriver > 2.14.
# and selenium-webdriver < 2.20 fails on firefox 11 :-( So @wip for now. This will work on webkit though
When I go to the home page
And I submit a new action with description "buy mediacenter" in the context "@pc"
And I make a project of "buy mediacenter"

View file

@ -33,8 +33,7 @@ Feature: View, add, remove notes
Given I have a project "Pass Final Exam" with 2 notes
When I go to the notes page
And I delete the first note
Then the first note should disappear
And the badge should show 1
Then the badge should show 1
@javascript
Scenario: Edit a note

View file

@ -16,14 +16,14 @@ Feature: Edit a project
When I click on the first note icon
Then I should go to that note page
@selenium
@javascript
Scenario: I can describe the project using markup
When I go to the "manage me" project
And I edit the project description to "_successfull outcome_: project is *done*"
Then I should see the italic text "successfull outcome" in the project description
And I should see the bold text "done" in the project description
@selenium
@javascript
Scenario: I can edit the project name in place
Given I have a project "release tracks 1.8" with 1 todos
When I go to the "release tracks 1.8" project
@ -33,7 +33,7 @@ Feature: Edit a project
Then I should see that a project named "release tracks 1.8" is not present
And I should see that a project named "release tracks 2.0" is present
@selenium
@javascript
Scenario: I cannot edit the project name in two places at once
Given I have a project "release tracks 1.8" with 1 todos
When I go to the "release tracks 1.8" project
@ -43,14 +43,14 @@ Feature: Edit a project
Then I should not be able to change the project name in place
# Ticket #1041
@selenium
@javascript
Scenario: I can change the name of the project using the Edit Project Settings form
Given I have a project "bananas" with 1 todos
When I go to the "bananas" project
And I edit the project name to "cherries"
Then the project title should be "cherries"
@selenium
@javascript
Scenario: I can change the name of the project and it should update the new todo form
Given I have a project "bananas" with 1 todos
When I go to the "bananas" project
@ -58,7 +58,7 @@ Feature: Edit a project
Then the project title should be "cherries"
And the project field of the new todo form should contain "cherries"
@selenium
@javascript
Scenario: I can change the default context of the project and it should update the new todo form
Given I have a project "bananas" with 1 todos
When I go to the "bananas" project
@ -69,7 +69,7 @@ Feature: Edit a project
Then the default context of the new todo form should be "@pc"
# Ticket #1042
@selenium
@javascript
Scenario: I cannot change the name of a project in the project view to the name of another existing project
Given I have a project "test" with 1 todos
When I go to the projects page
@ -79,7 +79,7 @@ Feature: Edit a project
Then I should see "Name already exists"
# Ticket #1042
@selenium
@javascript
Scenario: I cannot change the name of a project in the project list view to the name of another existing project
Given I have a project "test" with 1 todos
When I go to the projects page
@ -87,29 +87,29 @@ Feature: Edit a project
When I try to edit the project name of "manage me" to "test"
Then I should see "Name already exists"
@selenium
@javascript
Scenario: I can add a note to the project
Given I have a project called "test"
When I go to the "test" project
And I add a note "hello I'm testing" to the project
Then I should see one note in the project
@selenium
@javascript
Scenario: Cancelling adding a note to the project will remove form
Given I have a project called "test"
When I go to the "test" project
And I cancel adding a note to the project
Then the form for adding a note should not be visible
@selenium
@javascript @wip
Scenario: Long notes in a project are shown cut off
Given I have a project called "test"
When I go to the "test" project
And I add a note "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890TOO LONG" to the project
Then I should not see "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890TOO LONG"
And I should see "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456"
Then I should not see the note "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890TOO LONG"
And I should see the note "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456"
@selenium
@javascript
Scenario: Cancelling editing a project will restore project settings
Given I have a project called "test"
When I go to the "test" project
@ -119,7 +119,7 @@ Feature: Edit a project
When I cancel the project edit form
Then I should see the default project settings
@selenium
@javascript
Scenario: Moving the todo to the tickler will move todo to tickler container and update empty messages
Given I have a project "test" with 1 todos
When I go to the "test" project
@ -132,34 +132,34 @@ Feature: Edit a project
And I should see empty message for completed todos of project
And I should see empty message for todos of project
@selenium
@javascript
Scenario: Moving the todo out of the tickler will move todo to active container and update empty messages
Given I have a project "test" with 1 deferred todos
When I go to the "test" project
Then I should see "todo 1" in the deferred container
Then I should see "deferred todo 1" in the deferred container
And I should see empty message for todos of project
And I should not see empty message for deferred todos of project
When I clear the show from date of "todo 1"
Then I should see "todo 1" in the action container
When I clear the show from date of "deferred todo 1"
Then I should see "deferred todo 1" in the action container
And I should see empty message for deferred todos of project
And I should not see empty message for todos of project
@selenium
@javascript
Scenario: Making all todos inactive will show empty message
Given I have a project "test" with 1 todos
When I go to the "test" project
And I mark "todo 1" as complete
Then I should see empty message for todos of project
@selenium
@javascript
Scenario: Making all deferred todos inactive will show empty message
Given I have a project "test" with 1 deferred todos
When I go to the "test" project
And I mark "todo 1" as complete
And I mark "deferred todo 1" as complete
Then I should see empty message for todos of project
# Ticket #1043
@selenium
@javascript
Scenario: I can move a todo out of the current project
Given I have a project "foo" with 2 todos
And I have a project called "bar"

View file

@ -155,14 +155,14 @@ end
####### Repeat patterns #######
Then /^I should see "([^"]*)" in the active recurring todos container$/ do |repeat_pattern|
Then /^I should (see|not see) "([^"]*)" in the active recurring todos container$/ do |visibility, repeat_pattern|
repeat = @current_user.recurring_todos.find_by_description(repeat_pattern)
unless repeat.nil?
xpath = "//div[@id='active_recurring_todos_container']//div[@id='recurring_todo_#{repeat.id}']"
page.should have_xpath(xpath, :visible => true)
page.send(visibility == "see" ? "should" : "should_not", have_xpath(xpath, :visible => true))
else
step "I should see \"#{repeat_pattern}\""
step "I should #{visibility} \"#{repeat_pattern}\""
end
end

View file

@ -7,25 +7,19 @@ When /^I delete the context "([^\"]*)"$/ do |context_name|
end
get_confirm_text.should == "Are you sure that you want to delete the context '#{context_name}'? Be aware that this will also delete all (repeating) actions in this context!"
wait_until do
!page.has_css?("a#delete_context_#{context.id}")
end
# wait until the context is removed
page.should_not have_css("a#delete_context_#{context.id}")
end
When /^I edit the context to rename it to "([^\"]*)"$/ do |new_name|
find("a#link_edit_context_#{@context.id}").click
wait_until do
page.has_css?("button#submit_context_#{@context.id}")
end
page.should have_css("button#submit_context_#{@context.id}", :visible=>true)
fill_in "context_name", :with => new_name
click_button "submit_context_#{@context.id}"
wait_until do
!page.has_css?("button#submit_context_#{@context.id}", :visible=>true)
end
# wait for the form to go away
page.should have_css("a#link_edit_context_#{@context.id}", :visible=> true)
end
When /^I add a new context "([^"]*)"$/ do |context_name|
@ -64,11 +58,11 @@ Then /^I should see that a context named "([^"]*)" is not present$/ do |context_
end
Then /^I should see that the context container for (.*) contexts is not present$/ do |state|
page.has_css?("div#list-#{state}-contexts-container", :visible => true).should be_false
page.should_not have_css("div#list-#{state}-contexts-container", :visible => true)
end
Then /^I should see that the context container for (.*) contexts is present$/ do |state|
find("div#list-#{state}-contexts-container", :visible => true).should_not be_nil
page.should have_css("div#list-#{state}-contexts-container", :visible => true)
end
Then /^I should see the context "([^"]*)" under "([^"]*)"$/ do |context_name, state|

View file

@ -72,17 +72,17 @@ Then /^he should see that a context named "([^\"]*)" is not present$/ do |contex
end
Then /^I should not see empty message for todos of context/ do
find("div#c#{@context.id}empty-nd").should_not be_visible
page.should_not have_css("div#c#{@context.id}empty-nd", :visible=>true)
end
Then /^I should see empty message for todos of context/ do
find("div#c#{@context.id}empty-nd").should be_visible
page.should have_css("div#c#{@context.id}empty-nd", :visible => true)
end
Then /^I should not see empty message for completed todos of context$/ do
find("div#empty-d").should_not be_visible
page.should_not have_css("div#empty-d", :visible=>true)
end
When /^I should see empty message for completed todos of context$/ do
find("div#empty-d").should be_visible
page.should have_css("div#empty-d", :visible=>true)
end

View file

@ -11,7 +11,7 @@ When /^I drag "(.*)" to "(.*)"$/ do |dragged, target|
drag_id = Todo.find_by_description(dragged).id
drop_id = Todo.find_by_description(target).id
drag_elem = page.find(:xpath, "//div[@id='line_todo_#{drag_id}']//img[@class='grip']")
drop_elem = page.find(:xpath, "//div[@id='line_todo_#{drop_id}']//div[@class='description']")
drop_elem = page.find(:xpath, "//div[@id='line_todo_#{drop_id}']")
drag_elem.drag_to(drop_elem)
end
@ -35,7 +35,6 @@ When /^I edit the dependency of "([^"]*)" to add "([^"]*)" as predecessor$/ do |
open_edit_form_for(todo)
form_css = "form#form_todo_#{todo.id}"
within form_css do
fill_in 'predecessor_input', :with => predecessor_description
end
@ -86,8 +85,12 @@ Then /^the successors of "(.*)" should include "(.*)"$/ do |parent_name, child_n
parent = @current_user.todos.find_by_description(parent_name)
parent.should_not be_nil
child = parent.pending_successors.find_by_description(child_name)
child.should_not be_nil
# wait until the successor is added. TODO: make this not loop indefinitly
wait_until do
found = !parent.pending_successors.find_by_description(child_name).nil?
sleep 0.2 unless found
found
end
end
Then /^I should see "([^\"]*)" within the dependencies of "([^\"]*)"$/ do |successor_description, todo_description|

View file

@ -1,21 +1,3 @@
Given /^I have one project "([^\"]*)" with no notes$/ do |project_name|
@current_user.projects.create!(:name => project_name)
end
Given /^I have two projects with one note each$/ do
project_a = @current_user.projects.create!(:name => 'project A')
project_a.notes.create!(:user_id => @current_user.id, :body => 'note for project A')
project_b = @current_user.projects.create!(:name => 'project B')
project_b.notes.create!(:user_id => @current_user.id, :body => 'note for project B')
end
Given /^I have a project "([^\"]*)" with (.*) notes?$/ do |project_name, num|
project = @current_user.projects.create!(:name => project_name)
1.upto num.to_i do |i|
project.notes.create!(:user_id => @current_user.id, :body => "A note #{i}. This is the very long body of note #{i} where you should not see the last part of the note after 50 characters")
end
end
When /^I add note "([^\"]*)" from the "([^\"]*)" project page$/ do |note, project|
project = Project.find_by_name(project)
project.notes.create!(:user_id => @current_user.id, :body => note)
@ -29,6 +11,8 @@ When /^I delete the first note$/ do
click_link "delete_note_#{id}"
end
get_confirm_text.should == "Are you sure that you want to delete the note '#{id}'?"
page.should_not have_css("a#delete_note_#{id}")
end
When /^I click the icon next to the note$/ do
@ -49,7 +33,6 @@ When /^I toggle the note of "([^"]*)"$/ do |todo_description|
todo.should_not be_nil
xpath = "//div[@id='line_todo_#{todo.id}']/div/a/img"
page.find(:xpath, xpath).click
end
@ -84,9 +67,7 @@ Then /^the first note should disappear$/ do
id = title.split(' ').last
note = "div#note_#{id}"
wait_until do
!page.has_selector?(note)
end
page.should_not have_css(note, :visible=>true)
end
Then /^I should see the note text$/ do
@ -95,11 +76,10 @@ end
Then /^I should not see the note "([^"]*)"$/ do |note_content|
if page.has_selector?("div", :text => note_content)
page.find("div", :text => note_content).visible?.should be_false
page.find("div", :text => note_content).should_not be_visible
end
end
Then /^I should see the note "([^"]*)"$/ do |note_content|
page.find("div", :text => note_content).visible?.should be_true
page.find("div", :text => note_content).should be_visible
end

View file

@ -1,31 +1,3 @@
Given /^I have a project "([^"]*)" with (\d+) active todos$/ do |name, count|
@context = @current_user.contexts.find_or_create_by_name("Context A")
@project = @current_user.projects.find_or_create_by_name(name)
@todos=[]
1.upto count.to_i do |i|
todo = @current_user.todos.create!(
:project_id => @project.id,
:context_id => @context.id,
:description => "todo #{i}")
@todos << todo
end
end
Given /^I have a project "([^"]*)" with (\d+) deferred actions$/ do |name, deferred|
step "I have a project \"#{name}\" with #{deferred} active todos"
@todos.each do |t|
t.show_from = Time.zone.now + 1.week
t.description = "deferred " + t.description
t.save!
end
end
Given /^I have a project "([^"]*)" with (\d+) active actions and (\d+) deferred actions$/ do |name, active_count, deferred_count|
step "I have a project \"#{name}\" with #{active_count} active todos"
step "I have a project \"#{name}\" with #{deferred_count} deferred actions"
end
When /^I delete project "([^"]*)"$/ do |project_name|
project = @current_user.projects.find_by_name(project_name)
project.should_not be_nil
@ -134,7 +106,7 @@ Then /^the new project form should be visible$/ do
end
Then /^the new project form should not be visible$/ do
page.has_css?("div#project_new", :visible => true).should be_false
page.should_not have_css("div#project_new", :visible => true)
end
Then /^the project "([^"]*)" should have (\d+) actions listed$/ do |name, count|

View file

@ -1,3 +1,7 @@
Given /^I have no projects$/ do
Project.delete_all
end
Given /^I have an outdated project "([^"]*)" with (\d+) todos$/ do |project_name, num_todos|
step "I have a project \"#{project_name}\" with #{num_todos} todos"
@project = @current_user.projects.find_by_name(project_name)
@ -5,9 +9,18 @@ Given /^I have an outdated project "([^"]*)" with (\d+) todos$/ do |project_name
@project.save
end
Given /^I have a project "([^\"]*)" with ([0-9]+) todos$/ do |project_name, num_todos|
Given /^I have a project "([^"]*)" with (\d+) deferred actions$/ do |name, deferred|
step "I have a project \"#{name}\" with #{deferred} deferred todos"
end
Given /^I have a project "([^"]*)" with (\d+) active actions and (\d+) deferred actions$/ do |name, active_count, deferred_count|
step "I have a project \"#{name}\" with #{active_count} active todos"
step "I have a project \"#{name}\" with #{deferred_count} deferred todos"
end
Given /^I have a project "([^\"]*)" with ([0-9]+) (todo|active todo|deferred todo)s$/ do |project_name, num_todos, state|
@context = @current_user.contexts.find_or_create_by_name("Context A")
@project = @current_user.projects.create!(:name => project_name)
@project = @current_user.projects.find_or_create_by_name(project_name)
# acts_as_list adds at top by default, but that is counter-intuitive when reading scenario's, so reverse this
@project.move_to_bottom
@ -16,20 +29,14 @@ Given /^I have a project "([^\"]*)" with ([0-9]+) todos$/ do |project_name, num_
todo = @current_user.todos.create!(
:project_id => @project.id,
:context_id => @context.id,
:description => "todo #{i}")
:description => "#{state} #{i}")
todo.show_from = Time.zone.now + 1.week if state=="deferred todo"
todo.save!
@todos << todo
end
end
Given /^I have a project "([^\"]*)" with ([0-9]+) deferred todos$/ do |project_name, num_todos|
step "I have a project \"#{project_name}\" with #{num_todos} todos"
@todos.each do |todo|
todo.show_from = Time.zone.now + 1.week
todo.save!
end
end
Given /^there exists a project "([^\"]*)" for user "([^\"]*)"$/ do |project_name, user_name|
Given /^there exists a project (?:|called )"([^"]*)" for user "([^"]*)"$/ do |project_name, user_name|
user = User.find_by_login(user_name)
user.should_not be_nil
@project = user.projects.create!(:name => project_name)
@ -37,17 +44,12 @@ Given /^there exists a project "([^\"]*)" for user "([^\"]*)"$/ do |project_name
@project.move_to_bottom
end
Given /^there exists a project called "([^"]*)" for user "([^"]*)"$/ do |project_name, login|
# TODO: regexp change to integrate this with the previous since only 'called' is different
step "there exists a project \"#{project_name}\" for user \"#{login}\""
end
Given /^I have a project called "([^"]*)"$/ do |project_name|
step "there exists a project \"#{project_name}\" for user \"#{@current_user.login}\""
Given /^I have a project (?:|called )"([^"]*)"$/ do |project_name|
@project = @current_user.projects.create!(:name => project_name)
end
Given /^I have a project "([^"]*)" with a default context of "([^"]*)"$/ do |project_name, context_name|
step "there exists a project \"#{project_name}\" for user \"#{@current_user.login}\""
step "I have a project \"#{project_name}\""
context = @current_user.contexts.create!(:name => context_name)
@project.default_context = context
@project.save!
@ -55,7 +57,7 @@ end
Given /^I have the following projects:$/ do |table|
table.hashes.each do |project|
step 'I have a project called "'+project[:project_name]+'"'
step "I have a project called \"#{project[:project_name]}\""
# acts_as_list puts the last added project at the top, but we want it
# at the bottom to be consistent with the table in the scenario
@project.move_to_bottom
@ -63,11 +65,11 @@ Given /^I have the following projects:$/ do |table|
end
end
Given /^I have a completed project called "([^"]*)"$/ do |project_name|
Given /^I have a (completed|hidden) project called "([^"]*)"$/ do |state, project_name|
step "I have a project called \"#{project_name}\""
@project.complete!
@project.send(state=="completed" ? "complete!" : "hide!")
@project.reload
assert @project.completed?
assert @project.send(state=="completed" ? "completed?" : "hidden?")
end
Given /^I have (\d+) completed projects$/ do |number_of_projects|
@ -76,13 +78,22 @@ Given /^I have (\d+) completed projects$/ do |number_of_projects|
end
end
Given /^I have no projects$/ do
Project.delete_all
Given /^I have one project "([^\"]*)" with no notes$/ do |project_name|
step "I have a project called \"#{project_name}\""
end
Given /^I have a hidden project called "([^"]*)"$/ do |project_name|
@project = @current_user.projects.create!(:name => project_name)
@project.hide!
Given /^I have two projects with one note each$/ do
step "I have a project \"project A\""
@project.notes.create!(:user_id => @current_user.id, :body => 'note for project A')
step "I have a project \"project B\""
@project.notes.create!(:user_id => @current_user.id, :body => 'note for project B')
end
Given /^I have a project "([^\"]*)" with (.*) notes?$/ do |project_name, num|
project = @current_user.projects.create!(:name => project_name)
1.upto num.to_i do |i|
project.notes.create!(:user_id => @current_user.id, :body => "A note #{i}. This is the very long body of note #{i} where you should not see the last part of the note after 50 characters")
end
end
When /^I open the project edit form$/ do
@ -92,10 +103,7 @@ end
When /^I cancel the project edit form$/ do
click_link "cancel_project_#{@project.id}"
wait_until do
!page.has_css?("submit_project_#{@project.id}")
end
page.should_not have_css("submit_project_#{@project.id}")
end
When /^I edit the project description to "([^\"]*)"$/ do |new_description|
@ -135,8 +143,8 @@ Then /^I should (see|not see) empty message for (todos|deferred todos|completed
end
elem = find(css)
elem.nil?.should be_false
elem.visible?.should(visible=="see" ? be_true : be_false)
elem.should_not be_nil
elem.send(visible=="see" ? "should" : "should_not", be_visible)
end
Then /^I edit the default tags to "([^"]*)"$/ do |default_tags|
@ -169,9 +177,7 @@ end
Then /^I should be able to change the project name in place$/ do
#Note that this is not changing the project name
wait_until do
page.has_css? "div#project_name>form>input"
end
page.should have_css("div#project_name>form>input")
page.find("div#project_name > form > button[type=cancel]").click
end
@ -179,12 +185,12 @@ When /^I edit the project settings$/ do
@project.should_not be_nil
click_link "link_edit_project_#{@project.id}"
page.has_xpath?("//div[@id='edit_project_#{@project.id}']/form//button[@id='submit_project_#{@project.id}']").should be_true
page.should have_xpath("//div[@id='edit_project_#{@project.id}']/form//button[@id='submit_project_#{@project.id}']")
end
Then /^I should not be able to change the project name in place$/ do
step "I click to edit the project name in place"
page.has_xpath?("//div[@id='project_name']/form/input").should be_false
page.should_not have_xpath("//div[@id='project_name']/form/input")
end
When /^I close the project settings$/ do
@ -194,7 +200,6 @@ When /^I close the project settings$/ do
wait_for_animations_to_end
end
When /^I edit the project state of "([^"]*)" to "([^"]*)"$/ do |project_name, state_name|
project = @current_user.projects.find_by_name(project_name)
project.should_not be_nil
@ -243,7 +248,6 @@ Then /^I should see the bold text "([^\"]*)" in the project description$/ do |te
page.should have_xpath(xpath)
bold_text = page.find(:xpath, xpath).text
bold_text.should =~ /#{text_in_bold}/
end
@ -252,7 +256,6 @@ Then /^I should see the italic text "([^\"]*)" in the project description$/ do |
page.should have_xpath(xpath)
italic_text = page.find(:xpath, xpath).text
italic_text.should =~ /#{text_in_italic}/
end
@ -268,12 +271,12 @@ end
Then /^I should (see|not see) the default project settings$/ do |visible|
default_settings = "This project is active with no default context and with no default tags"
if visible == "see"
elem = page.find("div.project_settings")
elem.visible?.should be_true
if visible == "see"
elem.should be_visible
elem.text.should =~ /#{default_settings}/
else
elem = page.find("div.project_settings")
elem.visible?.should be_false
elem.should_not be_visible
end
end

View file

@ -68,17 +68,10 @@ When /^I delete the pattern "([^"]*)"$/ do |pattern_name|
page.should_not have_css("#delete_icon_#{pattern.id}")
end
When /^I mark the pattern "([^"]*)" as complete$/ do |pattern_name|
When /^I mark the pattern "([^"]*)" as (complete|active)$/ do |pattern_name, state|
pattern = @current_user.recurring_todos.find_by_description(pattern_name)
pattern.should_not be_nil
pattern.completed?.should be_false
page.find("#check_#{pattern.id}").click
end
When /^I mark the pattern "([^"]*)" as active$/ do |pattern_name|
pattern = @current_user.recurring_todos.find_by_description(pattern_name)
pattern.should_not be_nil
pattern.completed?.should be_true
pattern.completed?.should(state=="complete" ? be_false : be_true)
page.find("#check_#{pattern.id}").click
end

View file

@ -160,7 +160,7 @@ end
####### PROJECT WITH TODOS ######
Given /^I have a project "([^"]*)" that has the following todos$/ do |project_name, todos|
Given /^I have a project "([^"]*)" that has the following (todos|deferred todos)$/ do |project_name, kind_of_todo, todos|
step "I have a project called \"#{project_name}\""
@project.should_not be_nil
todos.hashes.each do |todo|
@ -171,26 +171,7 @@ Given /^I have a project "([^"]*)" that has the following todos$/ do |project_na
:context_id => context.id,
:project_id=>@project.id,
:notes => todo[:notes])
unless todo[:tags].nil?
new_todo.tag_with(todo[:tags])
end
unless todo[:completed].nil?
new_todo.complete! if todo[:completed] == 'yes'
end
end
end
Given /^I have a project "([^"]*)" that has the following deferred todos$/ do |project_name, todos|
step "I have a project called \"#{project_name}\""
@project.should_not be_nil
todos.hashes.each do |todo|
context = @current_user.contexts.find_by_name(todo[:context])
context.should_not be_nil
new_todo = @current_user.todos.create!(
:description => todo[:description],
:context_id => context.id,
:project_id=>@project.id,
:show_from=>Time.zone.now+1.week)
new_todo.show_from = Time.zone.now+1.week if kind_of_todo=="deferred todos"
unless todo[:tags].nil?
new_todo.tag_with(todo[:tags])
end
@ -213,9 +194,6 @@ When /^I submit a new action with description "([^"]*)" with a dependency on "([
fill_in "todo[description]", :with => todo_description
fill_in "predecessor_input", :with => predecessor_description
# input = "xpath=//form[@id='todo-form-new-action']//input[@id='predecessor_input']"
# selenium.focus(input)
# selenium.type_keys input, predecessor_description
# wait for auto complete
autocomplete = "//a[@id='ui-active-menuitem']"

View file

@ -81,6 +81,7 @@ end
When /^I edit the description of "([^"]*)" to "([^"]*)"$/ do |action_description, new_description|
todo = @current_user.todos.find_by_description(action_description)
todo.should_not be_nil
open_edit_form_for(todo)
fill_in "todo_description", :with => new_description
submit_edit_todo_form(todo)
@ -89,6 +90,7 @@ end
When /^I try to edit the description of "([^"]*)" to "([^"]*)"$/ do |action_description, new_description|
todo = @current_user.todos.find_by_description(action_description)
todo.should_not be_nil
open_edit_form_for(todo)
fill_in "todo_description", :with => new_description
submit_button_xpath = "//div[@id='edit_todo_#{todo.id}']//button[@id='submit_todo_#{todo.id}']"
@ -119,6 +121,7 @@ end
When /^I clear the due date of "([^"]*)"$/ do |action_description|
todo = @current_user.todos.find_by_description(action_description)
todo.should_not be_nil
open_edit_form_for(todo)
within "div#edit_todo_#{todo.id}" do
find("a#due_x_todo_#{todo.id}").click
@ -132,6 +135,7 @@ end
When /^I edit the show from date of "([^"]*)" to next month$/ do |action_description|
todo = @current_user.todos.find_by_description(action_description)
todo.should_not be_nil
open_edit_form_for(todo)
fill_in "show_from_todo_#{todo.id}", :with => format_date(todo.created_at + 1.month)
submit_edit_todo_form(todo)
@ -143,7 +147,6 @@ When /^I remove the show from date from "([^"]*)"$/ do |action_description|
open_edit_form_for(todo)
page.find(:xpath, "//div[@id='edit_todo_#{todo.id}']//a[@id='show_from_x_todo_#{todo.id}']/img").click
submit_edit_todo_form(todo)
end
@ -156,6 +159,7 @@ When /^I defer "([^"]*)" for 1 day$/ do |action_description|
todo.should_not be_nil
open_submenu_for(todo)
page.should have_css("a#defer_1_todo_#{todo.id}", :visible=>true)
click_link "defer_1_todo_#{todo.id}"
wait_for_ajax
@ -176,6 +180,7 @@ When /^I make a project of "([^"]*)"$/ do |action_description|
todo.should_not be_nil
open_submenu_for(todo)
page.should have_css("a#to_project_todo_#{todo.id}", :visible=>true)
click_link "to_project_todo_#{todo.id}"
page.should have_no_css("div#line_todo_#{todo.id}")
@ -187,5 +192,5 @@ end
Then /^I should see an error message$/ do
error_block = "//form/div[@id='edit_error_status']"
page.find(:xpath, error_block).should_not be_nil
page.should have_xpath(error_block)
end

View file

@ -26,9 +26,7 @@ When /^I open the notes of "([^"]*)"$/ do |action_description|
page.find(:xpath, "//div[@id='line_todo_#{todo.id}']/div/a/img").click
wait_until do
page.find(:xpath, "//div[@id='notes_todo_#{todo.id}']").visible?
end
page.should have_xpath("//div[@id='notes_todo_#{todo.id}']", :visible=>true)
end
####### THEN #######
@ -38,7 +36,6 @@ Then /^I should see a starred "([^"]*)"$/ do |action_description|
todo.should_not be_nil
xpath_starred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star starred']"
page.should have_xpath(xpath_starred)
end
@ -55,13 +52,6 @@ Then /^I should see ([0-9]+) todos$/ do |count|
total.should == count.to_i
end
Then /^there should not be an error$/ do
# form should be gone and thus no errors visible
wait_for :timeout => 5 do
!selenium.is_visible("edit_todo_#{@dep_todo.id}")
end
end
Then /^I should see the todo "([^\"]*)"$/ do |todo_description|
page.should have_xpath("//span[.=\"#{todo_description}\"]", :visible => true)
end
@ -76,14 +66,7 @@ Then /^I should see a completed todo "([^"]*)"$/ do |todo_description|
# only completed todos have a grey span with the completed_at date
xpath = "//div[@id='line_todo_#{todo.id}']/div/span[@class='grey']"
unless selenium.is_element_present(xpath)
wait_for :timeout => 5 do
selenium.is_element_present(xpath)
end
end
selenium.is_visible(xpath).should be_true
page.should have_xpath(xpath, :visible=>true)
end
Then /^I should see an active todo "([^"]*)"$/ do |todo_description|
@ -105,9 +88,6 @@ end
Then /^the selected project should be "([^"]*)"$/ do |content|
# Works for mobile. TODO: make it work for both mobile and non-mobile
if content.blank?
if page.has_css?("select#todo_project_id option[selected='selected']")
puts "text=#{page.find("select#todo_project_id option[selected='selected']").text}"
end
page.has_css?("select#todo_project_id option[selected='selected']").should be_false
else
page.find("select#todo_project_id option[selected='selected']").text.should =~ /#{content}/
@ -117,10 +97,6 @@ end
Then /^the selected context should be "([^"]*)"$/ do |content|
# Works for mobile. TODO: make it work for both mobile and non-mobile
if content.blank?
if page.has_css?("select#todo_context_id option[selected='selected']")
puts "text=#{page.find("select#todo_context_id option[selected='selected']").text}"
save_and_open_page
end
page.has_css?("select#todo_context_id option[selected='selected']").should be_false
else
page.find("select#todo_context_id option[selected='selected']").text.should =~ /#{content}/
@ -132,9 +108,7 @@ Then /^I should see the page selector$/ do
end
Then /^the page should be "([^"]*)"$/ do |page_number|
page_number_found = -1
page_number_xpath = ".//span[@class='current']"
page.find(:xpath, page_number_xpath).text.should == page_number
page.find(:xpath, ".//span[@class='current']").text.should == page_number
end
Then /^the project field of the new todo form should contain "([^"]*)"$/ do |project_name|
@ -172,41 +146,19 @@ Then /^I should see "([^"]*)" in the completed section of the mobile site$/ do |
page.should have_xpath(xpath)
end
Then /^I should not see empty message for todos of home/ do
find("div#no_todos_in_view").should_not be_visible
end
Then /^I should see empty message for todos of home/ do
find("div#no_todos_in_view").should be_visible
end
Then /^I should not see empty message for completed todos of home$/ do
find("div#empty-d").should_not be_visible
end
Then /^I should see empty message for completed todos of home$/ do
find("div#empty-d").should be_visible
Then /^I should (see|not see) empty message for (completed todos|todos) of home/ do |visible, kind_of_todo|
elem = find(kind_of_todo=="todos" ? "div#no_todos_in_view" : "div#empty-d")
elem.send(visible=="see" ? "should" : "should_not", be_visible)
end
Then /^I should (see|not see) the empty tickler message$/ do |see|
elem = find("div#tickler-empty-nd")
if see=="see"
elem.should be_visible
else
elem.should_not be_visible
end
elem.send(see=="see" ? "should" : "should_not", be_visible)
end
Then /^I should not see the notes of "([^"]*)"$/ do |todo_description|
Then /^I should (see|not see) the notes of "([^"]*)"$/ do |visible, todo_description|
todo = @current_user.todos.find_by_description(todo_description)
todo.should_not be_nil
page.find("div#notes_todo_#{todo.id}").should_not be_visible
end
Then /^I should see the notes of "([^"]*)"$/ do |todo_description|
todo = @current_user.todos.find_by_description(todo_description)
todo.should_not be_nil
page.find("div#notes_todo_#{todo.id}").should be_visible
page.find("div#notes_todo_#{todo.id}").send(visible=="see" ? "should" : "should_not", be_visible)
end

View file

@ -36,7 +36,8 @@ end
When /^I change my password to "([^"]*)"$/ do |password|
step 'I should be on the change password page'
%w{password password_confirmation}.each { |name| fill_in "user[#{name}]", :with => password }
fill_in "user[password]", :with => password
fill_in "user[password_confirmation]", :with => password
click_button "Change password"
end
@ -55,9 +56,7 @@ When /^I delete the user "([^\"]*)"$/ do |username|
end
get_confirm_text.should == "Warning: this will delete user '#{user.login}', all their actions, contexts, project and notes. Are you sure that you want to continue?"
wait_until do
!page.has_css?("tr#user-#{user.id}")
end
page.should_not have_css("tr#user-#{user.id}")
end
Then /^I should see that a user named "([^\"]*)" is not present$/ do |username|

View file

@ -1,128 +1,46 @@
module TracksStepHelper
def submit_multiple_next_action_form
xpath = "//form[@id='todo-form-multi-new-action']//button[@id='todo_multi_new_action_submit']"
handle_js_confirm do
within("form#todo-form-multi-new-action") do
click_button("todo_multi_new_action_submit")
end
wait_for_ajax
wait_for_animations_to_end
end
end
def submit_next_action_form
handle_js_confirm do
within("#todo-form-new-action") do
click_button("todo_new_action_submit")
end
wait_for_ajax
wait_for_animations_to_end
end
end
def submit_new_context_form
within "form#context-form" do
find("button#context_new_submit").click
end
wait_for_ajax
wait_for_animations_to_end
end
def submit_new_project_form
within "form#project_form" do
click_button "project_new_project_submit"
end
wait_for_ajax
wait_for_animations_to_end
end
def wait_for_form_to_go_away(todo)
page.should_not have_content("button#submit_todo_#{todo.id}")
end
def submit_edit_todo_form (todo)
within "div#edit_todo_#{todo.id}" do
click_button "submit_todo_#{todo.id}"
end
wait_for_form_to_go_away(todo)
end
def format_date(date)
# copy-and-past from ApplicationController::format_date
return date ? date.in_time_zone(@current_user.prefs.time_zone).strftime("#{@current_user.prefs.date_format}") : ''
end
def execute_javascript(js)
page.execute_script(js)
end
def clear_context_name_from_next_action_form
execute_javascript("$('#todo_context_name').val('');")
end
def clear_project_name_from_next_action_form
execute_javascript("$('#todo_project_name').val('');")
end
def open_edit_form_for(todo)
within "div#line_todo_#{todo.id}" do
find("a#icon_edit_todo_#{todo.id}").click
end
wait_for_ajax
wait_for_animations_to_end
end
def wait_for_animations_to_end
wait_until do
page.evaluate_script('$(":animated").length') == 0
def submit_form(form_css, button_name)
handle_js_confirm do
within(form_css) do
click_button(button_name)
end
end
def wait_for_ajax
start_time = Time.now
page.evaluate_script('jQuery.isReady&&jQuery.active==0').class.should_not eql(String)
until(page.evaluate_script('jQuery.isReady&&jQuery.active==0') || (start_time + 5.seconds) < Time.now)
sleep 1
end
end
def handle_js_confirm(accept=true)
page.execute_script "window.original_confirm_function = window.confirm"
page.execute_script "window.confirmMsg = null"
page.execute_script "window.confirm = function(msg) { window.confirmMsg = msg; return #{!!accept}; }"
yield
ensure
page.execute_script "window.confirm = window.original_confirm_function"
end
def get_confirm_text
page.evaluate_script "window.confirmMsg"
end
def open_submenu_for(todo)
submenu_arrow = "div#line_todo_#{todo.id} img.todo-submenu"
page.find(submenu_arrow).should be_visible
page.find(submenu_arrow).click
# wait for the submenu to be visible
wait_until do
page.find("div#line_todo_#{todo.id} ul#ultodo_#{todo.id}").visible?
end
wait_for_ajax
wait_for_animations_to_end
end
def context_list_find_index(context_name)
div_id = "context_#{@current_user.contexts.find_by_name(context_name).id}"
contexts = page.all("div.context").map { |x| x[:id] }
return contexts.find_index(div_id)
end
def project_list_find_index(project_name)
# TODO: refactor with context_list_find_index
div_id = "project_#{@current_user.projects.find_by_name(project_name).id}"
project = page.all("div.project").map { |x| x[:id] }
return project.find_index(div_id)
def submit_multiple_next_action_form
submit_form("form#todo-form-multi-new-action", "todo_multi_new_action_submit")
end
def submit_next_action_form
submit_form("#todo-form-new-action", "todo_new_action_submit")
end
def submit_new_context_form
submit_form("form#context-form", "context_new_submit")
end
def submit_new_project_form
submit_form("form#project_form", "project_new_project_submit")
end
def submit_edit_todo_form (todo)
submit_form("div#edit_todo_#{todo.id}", "submit_todo_#{todo.id}")
wait_for_todo_form_to_go_away(todo)
end
def wait_for_todo_form_to_go_away(todo)
page.should_not have_content("button#submit_todo_#{todo.id}")
end
def open_project_edit_form(project)
@ -152,10 +70,75 @@ module TracksStepHelper
end
def edit_project_settings(project)
open_project_edit_form(project)
edit_project(project) do
yield
submit_project_edit_form(project)
page.should_not have_css("button#submit_project_#{project.id}", :visible => true)
end
end
def open_submenu_for(todo)
submenu_arrow = "div#line_todo_#{todo.id} img.todo-submenu"
page.should have_css(submenu_arrow, :visible=>true)
page.find(submenu_arrow).click
page.should have_css("div#line_todo_#{todo.id} ul#ultodo_#{todo.id}", :visible => true)
end
def context_list_find_index(context_name)
div_id = "context_#{@current_user.contexts.find_by_name(context_name).id}"
contexts = page.all("div.context").map { |x| x[:id] }
return contexts.find_index(div_id)
end
def project_list_find_index(project_name)
# TODO: refactor with context_list_find_index
div_id = "project_#{@current_user.projects.find_by_name(project_name).id}"
project = page.all("div.project").map { |x| x[:id] }
return project.find_index(div_id)
end
def wait_for_animations_to_end
wait_until do
page.evaluate_script('$(":animated").length') == 0
end
end
def wait_for_ajax
start_time = Time.now
page.evaluate_script('jQuery.isReady&&jQuery.active==0').class.should_not eql(String)
until(page.evaluate_script('jQuery.isReady&&jQuery.active==0') || (start_time + 5.seconds) < Time.now)
sleep 1
end
end
def format_date(date)
# copy-and-past from ApplicationController::format_date
return date ? date.in_time_zone(@current_user.prefs.time_zone).strftime("#{@current_user.prefs.date_format}") : ''
end
def execute_javascript(js)
page.execute_script(js)
end
def clear_context_name_from_next_action_form
execute_javascript("$('#todo_context_name').val('');")
end
def clear_project_name_from_next_action_form
execute_javascript("$('#todo_project_name').val('');")
end
def handle_js_confirm(accept=true)
page.execute_script "window.original_confirm_function = window.confirm"
page.execute_script "window.confirmMsg = null"
page.execute_script "window.confirm = function(msg) { window.confirmMsg = msg; return #{!!accept}; }"
yield
ensure
page.execute_script "window.confirm = window.original_confirm_function"
end
def get_confirm_text
page.evaluate_script "window.confirmMsg"
end
end

View file

@ -131,7 +131,7 @@ Feature: Show done
When I delete the pattern "test pattern"
Then I should not see "test pattern" in the completed recurring todos container
When I go to the recurring todos page
Then I should see "test pattern" in the active recurring todos container
Then I should not see "test pattern" in the active recurring todos container
@selenium
Scenario Outline: I can toggle a todo active from the done pages

View file

@ -534,12 +534,12 @@ var TodoItems = {
});
$('.item-show').droppable({
drop: TodoItems.drop_todo,
tolerance: 'pointer',
tolerance: 'intersect', /* warning: selenium fails on drag_and_drop when this is 'pointer' */
hoverClass: 'hover'
});
$('.context_target').droppable({
drop: TodoItems.drop_todo_on_context,
tolerance: 'pointer',
tolerance: 'intersect', /* warning: selenium fails on drag_and_drop when this is 'pointer' */
hoverClass: 'hover'
});
},