spec: role recontexting and file naming refactor

test:
   1. refactored attribute(class) with have_class
   2. contexted no context specs
   3. split out teachers and student specific specs
   4. refactored have_attribute
   5. refactored eql => ==

Change-Id: I592a063eece8097d5672c164f82a7b1a0c3c8928
Reviewed-on: https://gerrit.instructure.com/13880
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Jake Sorce <jake@instructure.com>
This commit is contained in:
Shawn Meredith 2012-09-21 12:08:01 -06:00
parent 824e0cdb3e
commit 44fde8f378
70 changed files with 1384 additions and 1307 deletions

View File

@ -1,4 +1,4 @@
require File.expand_path(File.dirname(__FILE__) + '/common')
require File.expand_path(File.dirname(__FILE__) + '/../common')
describe "sis imports ui" do
it_should_behave_like "in-process server selenium tests"

View File

@ -10,7 +10,7 @@ describe "managing developer keys" do
it "should allow creating, editing and deleting a developer key" do
get '/developer_keys'
keep_trying_until { f("#loading").attribute('class') != 'loading' }
wait_for_ajaximations
ff("#keys tbody tr").length.should == 0
f(".add_key").click

View File

@ -165,6 +165,29 @@ describe "site admin jobs ui" do
ff("#jobs-grid .slick-row").count.should == 1
f("#jobs-grid .r1").text.should include_text "String#downcase"
end
it "should confirm that clicking on delete button should delete all future jobs" do
2.times { "test".send_at 2.hours.from_now, :to_s }
filter_jobs(FlavorTags::FUTURE)
validate_all_jobs_selected
f("#jobs-grid .odd").should be_displayed
f("#jobs-grid .even").should be_displayed
f("#jobs-total").text.should == "3"
Delayed::Job.all.count.should == 5
num_of_jobs = Delayed::Job.all.count
keep_trying_until do
f("#delete-jobs").click
driver.switch_to.alert.should_not be_nil
driver.switch_to.alert.accept
true
end
wait_for_ajaximations
Delayed::Job.count.should == num_of_jobs - 3
fj("#jobs-grid .odd").should be_nil # using fj to bypass selenium cache
fj("#jobs-grid .even").should be_nil #using fj to bypass selenium cache
end
end
end

View File

@ -134,7 +134,7 @@ describe "announcements" do
expect_new_page_load { submit_form('.form-actions') }
f('#entry_list .discussion_entry .content').should include_text(entry_text)
f('#left-side .announcements').click
f('.topic_reply_count').text.should eql('1')
f('.topic_reply_count').text.should == '1'
end
it "should add and remove an external feed to announcements" do
@ -164,7 +164,7 @@ describe "announcements" do
wait_for_ajax_requests
element_exists('.external_feed').should be_false
}.to change(ExternalFeed, :count).by(-1)
ExternalFeed.count.should eql(0)
ExternalFeed.count.should == 0
end
it "should show announcements to student view student" do

View File

@ -75,7 +75,7 @@ describe "assignment groups" do
4.times do |i|
ags << @course.assignment_groups.create!(:name => "group_#{i}")
end
ags.collect(&:position).should eql([1,2,3,4])
ags.collect(&:position).should == [1,2,3,4]
get "/courses/#{@course.id}/assignments"
@ -85,7 +85,7 @@ describe "assignment groups" do
wait_for_ajaximations
ags.each {|ag| ag.reload}
ags.collect(&:position).should eql([1,3,2,4])
ags.collect(&:position).should == [1,3,2,4]
end
it "should round assignment groups percentages to 2 decimal places" do

View File

@ -37,8 +37,8 @@ describe "assignment rubrics" do
submit_form('#edit_rubric_form')
wait_for_ajaximations
rubric = Rubric.last
rubric.data.first[:points].should eql(initial_points)
rubric.data.first[:ratings].first[:points].should eql(initial_points)
rubric.data.first[:points].should == initial_points
rubric.data.first[:ratings].first[:points].should == initial_points
f('#rubrics .rubric .rubric_title .displaying .title').should include_text(rubric_name)
#Commented out because we still want this test to run but this is the part where the bug is

View File

@ -239,7 +239,7 @@ describe "assignments" do
#save changes
submit_form(form)
wait_for_ajaximations
ff('.loading_image_holder').length.should eql 0
ff('.loading_image_holder').length.should == 0
f('h2.title').should include_text(assignment_name + ' edit')
end
@ -284,7 +284,7 @@ describe "assignments" do
#save changes
submit_form('#edit_assignment_form')
wait_for_ajaximations
ff('.loading_image_holder').length.should eql 0
ff('.loading_image_holder').length.should == 0
f('h2.title').should include_text(orig_title + ' edit')
end
@ -331,16 +331,16 @@ describe "assignments" do
wait_for_animations
errorBoxes = driver.execute_script("return $('.errorBox').filter('[id!=error_box_template]').toArray();")
errorBoxes.size.should eql 2
errorBoxes.size.should == 2
errorBoxes.first.should_not be_displayed # .text just gives us an empty string since it's hidden
errorBoxes.last.text.should eql "There were errors on one or more advanced options"
errorBoxes.last.text.should == "There were errors on one or more advanced options"
errorBoxes.last.should be_displayed
f('a.more_options_link').click
wait_for_animations
errorBoxes = driver.execute_script("return $('.errorBox').filter('[id!=error_box_template]').toArray();")
errorBoxes.size.should eql 1 # the more_options_link one has now been removed from the DOM
errorBoxes.first.text.should eql "The assignment shouldn't be locked again until after the due date"
errorBoxes.size.should == 1 # the more_options_link one has now been removed from the DOM
errorBoxes.first.text.should == "The assignment shouldn't be locked again until after the due date"
errorBoxes.first.should be_displayed
end
end

View File

@ -63,7 +63,7 @@ describe "assignments turn it in" do
wait_for_ajaximations
keep_trying_until do
assignment = Assignment.last
assignment.turnitin_settings.should eql(expected_settings)
assignment.turnitin_settings.should == expected_settings
end
end
@ -79,6 +79,6 @@ describe "assignments turn it in" do
change_turnitin_settings
assignment.reload
assignment.turnitin_settings.should eql(expected_settings)
assignment.turnitin_settings.should ==(expected_settings)
end
end

View File

@ -257,12 +257,12 @@ describe "calendar2" do
f('.fc-event').click
f('.message_students').click
wait_for_ajaximations
ff(".participant_list input").size.should eql 1
ff(".participant_list input").size.should == 1
set_value f('textarea[name="body"]'), 'hello'
fj('.ui-button:contains(Send)').click
wait_for_ajaximations
student1.conversations.first.messages.size.should eql 1
student1.conversations.first.messages.size.should == 1
student2.conversations.should be_empty
end
@ -341,7 +341,7 @@ describe "calendar2" do
get "/calendar2"
wait_for_ajaximations
events = ff('.fc-event')
events.size.should eql 2
events.size.should == 2
events.first.click
details = f('.event-details')
@ -366,7 +366,7 @@ describe "calendar2" do
fj('.ui-button:contains(Update)').click
wait_for_ajaximations
ag.reload.appointments.first.description.should eql description
ag.reload.appointments.first.description.should == description
lambda { f('.fc-event') }.should_not raise_error
end
end
@ -379,7 +379,7 @@ describe "calendar2" do
:due_at => Time.zone.now.beginning_of_week + 1.day - 1.minute)
calendar_events = @teacher.calendar_events_for_calendar.last
calendar_events.title.should eql "super important"
calendar_events.title.should == "super important"
@assignment.due_date == Time.zone.now.beginning_of_week + 1.day - 1.minute
get "/calendar2"
@ -388,7 +388,7 @@ describe "calendar2" do
keep_trying_until do
events = ff('.fc-event').select { |e| e.text =~ /11:59.*super important/ }
# shows on monday night and tuesday morning
events.size.should eql 2
events.size.should == 2
end
end
@ -462,7 +462,7 @@ describe "calendar2" do
get "/calendar2"
wait_for_ajaximations
events = ff('.fc-event')
events.size.should eql 1
events.size.should == 1
events.first.text.should include "1p"
events.first.click
@ -478,7 +478,7 @@ describe "calendar2" do
popup_title = f('.details_title')
popup_title.should be_displayed
popup_title.text.should eql "future event"
popup_title.text.should == "future event"
end
end

View File

@ -95,7 +95,7 @@ shared_examples_for "conversations attachments selenium tests" do
wait_for_ajaximations
ff('img.attachments').size.should eql 2
ff('img.attachments').size.should == 2
messages = get_messages(false) # new conversation auto-selected
messages.size.should == 1
messages.first.text.should include "ohai look an attachment"

View File

@ -50,7 +50,7 @@ describe "conversations context filtering" do
new_conversation
@input = fj("#context_tags_filter input:visible")
search("th", "#context_tags") do
menu.should eql ["the course", "the group", "that course"]
menu.should == ["the course", "the group", "that course"]
end
end
@ -60,24 +60,24 @@ describe "conversations context filtering" do
@input = fj("#context_tags_filter input:visible")
browse_menu
menu.should eql ["that course", "the course", "the group"]
menu.should == ["that course", "the course", "the group"]
browse "that course" do
menu.should eql ["that course", "Everyone", "Teachers", "Students"]
browse("Everyone") { menu.should eql ["nobody@example.com", "student1", "User"] }
browse("Teachers") { menu.should eql ["nobody@example.com", "User"] }
browse("Students") { menu.should eql ["student1"] }
menu.should == ["that course", "Everyone", "Teachers", "Students"]
browse("Everyone") { menu.should == ["nobody@example.com", "student1", "User"] }
browse("Teachers") { menu.should == ["nobody@example.com", "User"] }
browse("Students") { menu.should == ["student1"] }
end
browse "the course" do
menu.should eql ["the course", "Everyone", "Teachers", "Students", "Student Groups"]
browse("Everyone") { menu.should eql ["nobody@example.com", "student1", "student2"] }
browse("Teachers") { menu.should eql ["nobody@example.com"] }
browse("Students") { menu.should eql ["student1", "student2"] }
menu.should == ["the course", "Everyone", "Teachers", "Students", "Student Groups"]
browse("Everyone") { menu.should == ["nobody@example.com", "student1", "student2"] }
browse("Teachers") { menu.should == ["nobody@example.com"] }
browse("Students") { menu.should == ["student1", "student2"] }
browse "Student Groups" do
menu.should eql ["the group"]
browse("the group") { menu.should eql ["the group", "nobody@example.com", "student1", "student2"] }
menu.should == ["the group"]
browse("the group") { menu.should == ["the group", "nobody@example.com", "student1", "student2"] }
end
end
browse("the group") { menu.should eql ["the group", "nobody@example.com", "student1", "student2"] }
browse("the group") { menu.should == ["the group", "nobody@example.com", "student1", "student2"] }
end
it "should let you filter by a course" do
@ -93,19 +93,19 @@ describe "conversations context filtering" do
browse("that course", "Everyone") { click "Select All" }
submit_message_form(:add_recipient => false, :message => "qwerty")
get_conversations.size.should eql 2
get_conversations.size.should == 2
@input = fj("#context_tags_filter input:visible")
search("the course", "#context_tags") { browse("the course") { click("the course") } }
keep_trying_until do
conversations = get_conversations
conversations.size.should eql 1
conversations.first.find_element(:css, 'p').text.should eql 'asdf'
conversations.size.should == 1
conversations.first.find_element(:css, 'p').text.should == 'asdf'
end
#filtered course should be first in the audience's contexts
get_conversations.first.find_element(:css, '.audience em').text.should eql 'the course and that course'
get_conversations.first.find_element(:css, '.audience em').text.should == 'the course and that course'
end
it "should let you filter by a course that was concluded a long time ago" do
@ -119,7 +119,7 @@ describe "conversations context filtering" do
browse("that course", "Everyone") { click "Select All" }
submit_message_form(:add_recipient => false, :message => "qwerty")
get_conversations.size.should eql 2
get_conversations.size.should == 2
@course1.complete!
@course1.update_attribute :conclude_at, 1.year.ago
@ -131,8 +131,8 @@ describe "conversations context filtering" do
keep_trying_until do
conversations = get_conversations
conversations.size.should eql 1
conversations.first.find_element(:css, 'p').text.should eql 'asdf'
conversations.size.should == 1
conversations.first.find_element(:css, 'p').text.should == 'asdf'
end
end
@ -152,12 +152,12 @@ describe "conversations context filtering" do
keep_trying_until do
conversations = get_conversations
conversations.size.should eql 1
conversations.first.find_element(:css, 'p').text.should eql 'asdf'
conversations.size.should == 1
conversations.first.find_element(:css, 'p').text.should == 'asdf'
end
# filtered student should be first in the audience
get_conversations.first.find_element(:css, '.audience').text.should eql 'student2 and student1 the course'
get_conversations.first.find_element(:css, '.audience').text.should == 'student2 and student1 the course'
end
it "should let you filter by a group" do
@ -173,15 +173,15 @@ describe "conversations context filtering" do
@input = fj("#context_tags_filter input:visible")
search("the group", "#context_tags") {
menu.should eql ["the group"]
menu.should == ["the group"]
elements.first.first.text.should include "the course" # make sure the group context is shown
browse("the group") { click("the group") }
}
keep_trying_until do
conversations = get_conversations
conversations.size.should eql 1
conversations.first.find_element(:css, 'p').text.should eql 'qwerty'
conversations.size.should == 1
conversations.first.find_element(:css, 'p').text.should == 'qwerty'
end
end

View File

@ -23,41 +23,41 @@ describe "conversations recipient finder" do
it "should allow browsing" do
browse_menu
menu.should eql ["the course", "the group"]
menu.should == ["the course", "the group"]
browse "the course" do
menu.should eql ["Everyone", "Teachers", "Students", "Course Sections", "Student Groups"]
browse("Everyone") { menu.should eql ["Select All", "nobody@example.com", "student 1", "student 2"] }
browse("Teachers") { menu.should eql ["nobody@example.com"] }
browse("Students") { menu.should eql ["Select All", "student 1", "student 2"] }
menu.should == ["Everyone", "Teachers", "Students", "Course Sections", "Student Groups"]
browse("Everyone") { menu.should == ["Select All", "nobody@example.com", "student 1", "student 2"] }
browse("Teachers") { menu.should == ["nobody@example.com"] }
browse("Students") { menu.should == ["Select All", "student 1", "student 2"] }
browse "Course Sections" do
menu.should eql ["the other section", "the section"]
menu.should == ["the other section", "the section"]
browse "the other section" do
menu.should eql ["Students"]
browse("Students") { menu.should eql ["student 2"] }
menu.should == ["Students"]
browse("Students") { menu.should == ["student 2"] }
end
browse "the section" do
menu.should eql ["Everyone", "Teachers", "Students"]
browse("Everyone") { menu.should eql ["Select All", "nobody@example.com", "student 1"] }
browse("Teachers") { menu.should eql ["nobody@example.com"] }
browse("Students") { menu.should eql ["student 1"] }
menu.should == ["Everyone", "Teachers", "Students"]
browse("Everyone") { menu.should == ["Select All", "nobody@example.com", "student 1"] }
browse("Teachers") { menu.should == ["nobody@example.com"] }
browse("Students") { menu.should == ["student 1"] }
end
end
browse "Student Groups" do
menu.should eql ["the group"]
browse("the group") { menu.should eql ["Select All", "nobody@example.com", "student 1"] }
menu.should == ["the group"]
browse("the group") { menu.should == ["Select All", "nobody@example.com", "student 1"] }
end
end
browse("the group") { menu.should eql ["Select All", "nobody@example.com", "student 1"] }
browse("the group") { menu.should == ["Select All", "nobody@example.com", "student 1"] }
end
it "should return recently concluded courses" do
@course.complete!
browse_menu
menu.should eql ["the course", "the group"]
menu.should == ["the course", "the group"]
search("course") do
menu.should eql ["the course"]
menu.should == ["the course"]
end
end
@ -69,7 +69,7 @@ describe "conversations recipient finder" do
student_1_enrollment.reload
browse_menu
browse("the course") do
browse("Students") { menu.should eql ["Select All", "student 2"] }
browse("Students") { menu.should == ["Select All", "student 2"] }
end
end
end
@ -79,10 +79,10 @@ describe "conversations recipient finder" do
@course.update_attribute :conclude_at, 1.year.ago
browse_menu
menu.should eql ["the group"]
menu.should == ["the group"]
search("course") do
menu.should eql ["No results found"]
menu.should == ["No results found"]
end
end
@ -90,14 +90,14 @@ describe "conversations recipient finder" do
browse_menu
browse("the group") do
menu.should eql ["Select All", "nobody@example.com", "student 1"]
menu.should == ["Select All", "nobody@example.com", "student 1"]
toggle "student 1"
tokens.should eql ["student 1"]
tokens.should == ["student 1"]
end
browse("the course") do
browse("Everyone") do
toggled.should eql ["student 1"]
toggled.should == ["student 1"]
end
end
end
@ -107,108 +107,108 @@ describe "conversations recipient finder" do
browse "the course" do
toggle "Everyone"
toggled.should eql ["Everyone", "Teachers", "Students"]
tokens.should eql ["the course: Everyone"]
toggled.should == ["Everyone", "Teachers", "Students"]
tokens.should == ["the course: Everyone"]
toggle "Everyone"
toggled.should eql []
tokens.should eql []
toggled.should == []
tokens.should == []
toggle "Students"
toggled.should eql ["Students"]
tokens.should eql ["the course: Students"]
toggled.should == ["Students"]
tokens.should == ["the course: Students"]
toggle "Teachers"
toggled.should eql ["Everyone", "Teachers", "Students"]
tokens.should eql ["the course: Everyone"]
toggled.should == ["Everyone", "Teachers", "Students"]
tokens.should == ["the course: Everyone"]
toggle "Teachers"
toggled.should eql ["Students"]
tokens.should eql ["the course: Students"]
toggled.should == ["Students"]
tokens.should == ["the course: Students"]
browse "Teachers" do
toggle "nobody@example.com"
toggled.should eql ["nobody@example.com"]
tokens.should eql ["the course: Students", "nobody@example.com"]
toggled.should == ["nobody@example.com"]
tokens.should == ["the course: Students", "nobody@example.com"]
toggle "nobody@example.com"
toggled.should eql []
tokens.should eql ["the course: Students"]
toggled.should == []
tokens.should == ["the course: Students"]
end
toggled.should eql ["Students"]
toggled.should == ["Students"]
toggle "Teachers"
toggled.should eql ["Everyone", "Teachers", "Students"]
tokens.should eql ["the course: Everyone"]
toggled.should == ["Everyone", "Teachers", "Students"]
tokens.should == ["the course: Everyone"]
browse "Students" do
toggle "Select All"
toggled.should eql []
tokens.should eql ["the course: Teachers"]
toggled.should == []
tokens.should == ["the course: Teachers"]
toggle "student 1"
toggle "student 2"
toggled.should eql ["Select All", "student 1", "student 2"]
tokens.should eql ["the course: Everyone"]
toggled.should == ["Select All", "student 1", "student 2"]
tokens.should == ["the course: Everyone"]
end
toggled.should eql ["Everyone", "Teachers", "Students"]
toggled.should == ["Everyone", "Teachers", "Students"]
browse "Everyone" do
toggle "student 1"
toggled.should eql ["nobody@example.com", "student 2"]
tokens.should eql ["nobody@example.com", "student 2"]
toggled.should == ["nobody@example.com", "student 2"]
tokens.should == ["nobody@example.com", "student 2"]
end
toggled.should eql []
toggled.should == []
end
end
it "should allow searching" do
search("t") do
menu.should eql ["the course", "the other section", "the section", "student 1", "student 2"]
menu.should == ["the course", "the other section", "the section", "student 1", "student 2"]
end
end
it "should show the group context when searching at the top level" do
search("the group") do
menu.first.should eql "the group"
menu.first.should == "the group"
elements.first.first.text.should include "the course"
end
end
it "should omit already-added tokens when searching" do
search("student") do
menu.should eql ["student 1", "student 2"]
menu.should == ["student 1", "student 2"]
click "student 1"
end
tokens.should eql ["student 1"]
tokens.should == ["student 1"]
search("stu") do
menu.should eql ["student 2"]
menu.should == ["student 2"]
end
end
it "should allow searching under supported contexts" do
browse_menu
browse "the course" do
search("t") { menu.should eql ["the other section", "the section", "the group", "student 1", "student 2"] }
search("t") { menu.should == ["the other section", "the section", "the group", "student 1", "student 2"] }
browse "Everyone" do
# only returns users
search("T") { menu.should eql ["student 1", "student 2"] }
search("T") { menu.should == ["student 1", "student 2"] }
end
browse "Course Sections" do
# only returns sections
search("student") { menu.should eql ["No results found"] }
search("r") { menu.should eql ["the other section"] }
search("student") { menu.should == ["No results found"] }
search("r") { menu.should == ["the other section"] }
browse "the section" do
search("s") { menu.should eql ["student 1"] }
search("s") { menu.should == ["student 1"] }
end
end
browse "Student Groups" do
# only returns groups
search("student") { menu.should eql ["No results found"] }
search("the") { menu.should eql ["the group"] }
search("student") { menu.should == ["No results found"] }
search("the") { menu.should == ["the group"] }
browse "the group" do
search("s") { menu.should eql ["student 1"] }
search("group") { menu.should eql ["No results found"] }
search("s") { menu.should == ["student 1"] }
search("group") { menu.should == ["No results found"] }
end
end
end
@ -218,19 +218,19 @@ describe "conversations recipient finder" do
# check without any user_name
get conversations_path(:user_id => @s1.id)
wait_for_ajaximations
tokens.should eql ["student 1"]
tokens.should == ["student 1"]
# explanation of user_name param: we used to pass the user name in the
# hash fragment, and it was spoofable. now we load that data via ajax.
get conversations_path(:user_id => @s1.id, :user_name => "some_fake_name")
wait_for_ajaximations
tokens.should eql ["student 1"]
tokens.should == ["student 1"]
end
it "should reject a non-contactable user id in the url hash" do
other = User.create(:name => "other guy")
get conversations_path(:user_id => other.id)
wait_for_ajaximations
tokens.should eql []
tokens.should == []
end
it "should allow a non-contactable user in the hash if a shared conversation exists" do
@ -239,13 +239,13 @@ describe "conversations recipient finder" do
c = Conversation.initiate([@user.id, other.id], true)
get conversations_path(:user_id => other.id, :from_conversation_id => c.id)
wait_for_ajaximations
tokens.should eql ["other guy"]
tokens.should == ["other guy"]
end
it "should not show student view student to other students" do
@fake_student = @course.student_view_student
search(@fake_student.name) do
menu.should eql ["No results found"]
menu.should == ["No results found"]
end
end
end

View File

@ -22,9 +22,9 @@ describe "conversations sent filter" do
get "/conversations/sent"
conversations = get_conversations
conversations.first.attribute('data-id').should eql(@c1.conversation_id.to_s)
conversations.first.attribute('data-id').should == @c1.conversation_id.to_s
conversations.first.should include_text('yay i sent this')
conversations.last.attribute('data-id').should eql(@c2.conversation_id.to_s)
conversations.last.attribute('data-id').should == @c2.conversation_id.to_s
conversations.last.should include_text('test')
end
@ -65,7 +65,7 @@ describe "conversations sent filter" do
end
conversations = get_conversations
conversations.size.should eql 3
conversations.size.should == 3
conversations.each { |conversation| conversation.should include_text(message_text) }
end
end

View File

@ -32,15 +32,15 @@ describe "conversations" do
c = get_conversations.first
c.click
c.should have_class('unread') # not marked immediately
@me.conversations.unread.size.should eql 5
@me.conversations.unread.size.should == 5
keep_trying_until do
get_conversations.first.should_not have_class('unread')
true
end
@me.conversations.unread.size.should eql 4
@me.conversations.unread.size.should == 4
get_conversations.last.click
get_conversations.size.should eql 4 # removed once deselected
get_conversations.size.should == 4 # removed once deselected
end
it "should star a conversation" do
@ -158,7 +158,7 @@ describe "conversations" do
true
end
get '/conversations'
f('.unread-messages-count').text.should eql '4'
f('.unread-messages-count').text.should == '4'
end
end
end

View File

@ -43,7 +43,7 @@ describe "conversations user notes" do
checkbox.should be_displayed
checkbox.click
submit_message_form(:add_recipient => false)
@the_student.user_notes.size.should eql(1)
@the_student.user_notes.size.should == 1
end
it "should allow user notes on existing private conversations with students" do
@ -55,6 +55,6 @@ describe "conversations user notes" do
checkbox.should be_displayed
checkbox.click
submit_message_form
@the_student.user_notes.size.should eql(1)
@the_student.user_notes.size.should == 1
end
end

View File

@ -25,8 +25,8 @@ describe "course copy" do
select_box = f('#copy_from_course')
select_box.find_elements(:css, 'optgroup').length.should == 2
optgroups = select_box.find_elements(:css, 'optgroup')
optgroups.map { |og| og.attribute('label') }.sort.should eql ["Default Term", "Test Term"]
optgroups.map { |og| og.find_elements(:css, 'option').length }.should eql [1, 1]
optgroups.map { |og| og.attribute('label') }.sort.should == ["Default Term", "Test Term"]
optgroups.map { |og| og.find_elements(:css, 'option').length }.should == [1, 1]
click_option('#copy_from_course', 'second course')
f('button[type="submit"]').click

View File

@ -361,7 +361,7 @@ describe "course settings" do
reset_link.click
wait_for_dom_ready
@fake_student_after = @course.student_view_student
@fake_student_before.id.should_not eql @fake_student_after.id
@fake_student_before.id.should_not == @fake_student_after.id
end
it "should not include student view student in the statistics count" do

View File

@ -21,7 +21,7 @@ describe "cross-listing" do
form = f('#crosslist_course_form')
submit_btn = form.find_element(:css, '.submit_button')
form.should_not be_nil
form.find_element(:css, '.submit_button').attribute(:disabled).should eql 'true'
form.find_element(:css, '.submit_button').should have_attribute(:disabled,'true')
course_id = form.find_element(:id, 'course_id')
course_name = f('#course_autocomplete_name')
@ -31,8 +31,8 @@ describe "cross-listing" do
course_id.clear
course_id.send_keys([:control, 'a'], @course2.id.to_s, "\n")
keep_trying_until { course_name.text != "Confirming Course ID \"#{@course2.id}\"..." }
course_name.text.should eql @course2.name
form.find_element(:id, 'course_autocomplete_id').attribute(:value).should eql @course.id.to_s
course_name.text.should == @course2.name
form.find_element(:id, 'course_autocomplete_id').should have_attribute(:value, @course.id.to_s)
submit_btn.should_not have_class('disabled')
submit_form(form)
wait_for_ajaximations
@ -40,7 +40,7 @@ describe "cross-listing" do
# verify teacher doesn't have de-crosslist privileges
get "/courses/#{@course2.id}/sections/#{@section.id}"
ff('.uncrosslist_link').length.should eql 0
ff('.uncrosslist_link').length.should == 0
# enroll teacher and de-crosslist
@course1.enroll_teacher(@user).accept
@ -60,7 +60,7 @@ describe "cross-listing" do
course_id.click
course_id.send_keys "-1\n"
keep_trying_until { course_name.text != 'Confirming Course ID "-1"...' }
course_name.text.should eql 'Course ID "-1" not authorized for cross-listing'
course_name.text.should == 'Course ID "-1" not authorized for cross-listing'
end
@ -80,23 +80,23 @@ describe "cross-listing" do
get "/courses/#{course.id}/sections/#{section.id}"
f(".crosslist_link").click
form = f("#crosslist_course_form")
form.find_element(:css, ".submit_button").attribute(:disabled).should eql("true")
form.find_element(:css, ".submit_button").should have_attribute(:disabled, "true")
form.should_not be_nil
# let's try and crosslist an invalid course
form.find_element(:css, "#course_id").click
form.find_element(:css, "#course_id").send_keys("-1\n")
keep_trying_until { f("#course_autocomplete_name").text != "Confirming Course ID \"-1\"..." }
f("#course_autocomplete_name").text.should eql("Course ID \"-1\" not authorized for cross-listing")
f("#course_autocomplete_name").text.should ==("Course ID \"-1\" not authorized for cross-listing")
# k, let's crosslist to the other course
form.find_element(:css, "#course_id").click
form.find_element(:css, "#course_id").clear
form.find_element(:css, "#course_id").send_keys([:control, 'a'], other_course.id.to_s, "\n")
keep_trying_until { f("#course_autocomplete_name").text != "Confirming Course ID \"#{other_course.id}\"..." }
f("#course_autocomplete_name").text.should eql(other_course.name)
form.find_element(:css, "#course_autocomplete_id").attribute(:value).should eql(other_course.id.to_s)
form.find_element(:css, ".submit_button").attribute(:disabled).should eql("false")
f("#course_autocomplete_name").text.should == other_course.name
form.find_element(:css, "#course_autocomplete_id").attribute(:value).should ==(other_course.id.to_s)
form.find_element(:css, ".submit_button").attribute(:disabled).should == "false"
submit_form(form)
keep_trying_until { driver.current_url.match(/courses\/#{other_course.id}/) }
@ -104,7 +104,7 @@ describe "cross-listing" do
# they were enrolled in got moved). they don't have the rights to
# uncrosslist.
get "/courses/#{other_course.id}/sections/#{section.id}"
ff(".uncrosslist_link").length.should eql(0)
ff(".uncrosslist_link").length.should == 0
# enroll, and make sure the teacher can uncrosslist.
course.enroll_teacher(@user).accept

View File

@ -365,21 +365,21 @@ describe "discussions" do
# make sure everything looks unread
get("/courses/#{@course.id}/discussion_topics/#{@topic.id}", false)
ff('.can_be_marked_as_read.unread').length.should eql(reply_count + 1)
f('.new-and-total-badge .new-items').text.should eql(reply_count.to_s)
ff('.can_be_marked_as_read.unread').length.should == reply_count + 1
f('.new-and-total-badge .new-items').text.should == reply_count.to_s
#wait for the discussionEntryReadMarker to run, make sure it marks everything as .just_read
sleep 2
ff('.can_be_marked_as_read.unread').should be_empty
ff('.can_be_marked_as_read.just_read').length.should eql(reply_count + 1)
f('.new-and-total-badge .new-items').text.should eql('')
ff('.can_be_marked_as_read.just_read').length.should == reply_count + 1
f('.new-and-total-badge .new-items').text.should == ''
# refresh page and make sure nothing is unread/just_read and everthing is .read
get("/courses/#{@course.id}/discussion_topics/#{@topic.id}", false)
['unread', 'just_read'].each do |state|
ff(".can_be_marked_as_read.#{state}").should be_empty
end
f('.new-and-total-badge .new-items').text.should eql('')
f('.new-and-total-badge .new-items').text.should == ''
end
end
end

View File

@ -89,9 +89,9 @@ describe "enhanceable_content" do
accordion = f(".enhanceable_content.accordion")
accordion.should have_class('ui-accordion')
headers = accordion.find_elements(:css, ".ui-accordion-header")
headers.length.should eql(3)
headers.length.should == 3
divs = accordion.find_elements(:css, ".ui-accordion-content")
divs.length.should eql(3)
divs.length.should == 3
headers[0].should have_class('ui-state-active')
divs[0].should be_displayed
divs[1].should_not be_displayed
@ -106,9 +106,9 @@ describe "enhanceable_content" do
tabs = f(".enhanceable_content.tabs")
tabs.should have_class('ui-tabs')
headers = tabs.find_elements(:css, ".ui-tabs-nav li")
headers.length.should eql(3)
headers.length.should == 3
divs = tabs.find_elements(:css, ".ui-tabs-panel")
divs.length.should eql(3)
divs.length.should == 3
headers[0].should have_class('ui-state-active')
headers[1].should have_class('ui-state-default')
divs[0].should be_displayed

View File

@ -20,7 +20,7 @@ describe "eportfolios" do
@eportfolio.eportfolio_entries.count > 0
entry= @eportfolio.eportfolio_entries.first
if opts[:section_type]
entry.content.first[:section_type].should eql(opts[:section_type])
entry.content.first[:section_type].should == opts[:section_type]
end
if opts[:content]
@ -67,7 +67,7 @@ describe "eportfolios" do
f("#section_list_manage .add_section_link").click
f("#section_list input").send_keys("test section name", :return)
wait_for_ajax_requests
fj("#section_list li:last-child .name").text.should eql "test section name"
fj("#section_list li:last-child .name").text.should == "test section name"
end
it "should edit ePortfolio settings" do
@ -78,7 +78,7 @@ describe "eportfolios" do
submit_form('#edit_eportfolio_form')
wait_for_ajax_requests
@eportfolio.reload
@eportfolio.name.should eql "new ePortfolio name"
@eportfolio.name.should == "new ePortfolio name"
end
it "should have a working flickr search dialog" do
@ -116,7 +116,7 @@ describe "eportfolios" do
f("#wrapper-container .eportfolios").click
f("#whats_an_eportfolio .add_eportfolio_link").should be_displayed
fj("#portfolio_#{@eportfolio.id}").should be_nil
Eportfolio.first.workflow_state.should eql 'deleted'
Eportfolio.first.workflow_state.should == 'deleted'
end
describe "add content box" do
@ -170,7 +170,7 @@ describe "eportfolios" do
def add_html
submit_form(".form_content")
wait_for_ajax_requests
f(".section_content b").text.should eql "student"
f(".section_content b").text.should == "student"
entry_verifier ({:section_type => "html", :content => @html_content})
end
@ -183,14 +183,14 @@ describe "eportfolios" do
is_checked(comment_public).should be_true
submit_form(".form_content")
wait_for_ajax_requests
f(".section_content b").text.should eql "student"
f(".section_content b").text.should == "student"
entry_verifier ({:section_type => "html", :content => @html_content})
refresh_page
f("#page_comment_message").send_keys("hi student")
submit_form("#add_page_comment_form")
wait_for_ajax_requests
f("#page_comments .message").should include_text("hi student")
@eportfolio_entry.page_comments[0].message.should eql "hi student"
@eportfolio_entry.page_comments[0].message.should == "hi student"
end
it "should verify that the html is there" do
@ -210,7 +210,7 @@ describe "eportfolios" do
wait_for_ajaximations
submit_form(".form_content")
wait_for_ajaximations
@eportfolio.eportfolio_entries.first.content[0].should eql "No Content Added Yet"
@eportfolio.eportfolio_entries.first.content[0].should == "No Content Added Yet"
f("#edit_page_section_1").should be_nil
end
@ -221,7 +221,7 @@ describe "eportfolios" do
driver.switch_to.alert.accept
wait_for_ajaximations
f("#page_comments .message").should be_nil
PageComment.count.should eql 0
PageComment.count.should == 0
end
end

View File

@ -13,7 +13,6 @@ describe "equation editor" do
submit_form('.question_form')
wait_for_ajaximations
end
wait_for_tiny(f("#quiz_description"))
new_question_link = f('.add_question_link')
@ -21,7 +20,7 @@ describe "equation editor" do
new_question_link.click
questions = ffj(".question_holder:visible")
questions.length.should eql(time + 1)
questions.length.should == time + 1
question = questions[time]
wait_for_tiny(question.find_element(:css, 'textarea.question_content'))
@ -39,7 +38,7 @@ describe "equation editor" do
save_question_and_wait
question.find_elements(:css, 'img.equation_image').size.should == 1
f("#right-side .points_possible").text.should eql((time + 1).to_s)
f("#right-side .points_possible").text.should == (time + 1).to_s
end
end
end

View File

@ -42,10 +42,10 @@ describe "editing external tools" do
tool_elem = fj("#external_tools .external_tool:visible").should be_displayed
tool_elem.should_not be_nil
tool.reload
tool.name.should eql "new tool (updated)"
tool.consumer_key.should eql "key (updated)"
tool.shared_secret.should eql "secret (updated)"
tool.domain.should eql "example2.com"
tool.name.should == "new tool (updated)"
tool.consumer_key.should == "key (updated)"
tool.shared_secret.should == "secret (updated)"
tool.domain.should == "example2.com"
tool.settings[:custom_fields].should == {'a' => '9', 'b' => '8'}
end
@ -63,7 +63,7 @@ describe "editing external tools" do
f("#select_context_content_dialog .add_item_button").click
wait_for_ajax_requests
f("#select_context_content_dialog").should_not be_displayed
ff("#context_module_item_new").length.should eql 0
ff("#context_module_item_new").length.should == 0
@tag = ContentTag.last
@tag.should_not be_nil
@ -118,7 +118,7 @@ describe "editing external tools" do
f("#select_context_content_dialog .add_item_button").click
wait_for_ajax_requests
f("#select_context_content_dialog").should_not be_displayed
keep_trying_until { ff("#context_module_item_new").length.should eql 0 }
keep_trying_until { ff("#context_module_item_new").length.should == 0 }
@tag = ContentTag.last
@tag.should_not be_nil
@ -134,7 +134,7 @@ describe "editing external tools" do
f("#select_context_content_dialog .add_item_button").click
wait_for_ajax_requests
f("#select_context_content_dialog").should_not be_displayed
ff("#context_module_item_new").length.should eql 0
ff("#context_module_item_new").length.should == 0
@tag = ContentTag.last
@tag.should_not be_nil
@ -174,7 +174,7 @@ describe "editing external tools" do
in_frame('resource_selection_iframe') do
keep_trying_until { ff("#basic_lti_link").length > 0 }
ff(".link").length.should eql 4
ff(".link").length.should == 4
f("#basic_lti_link").click
wait_for_ajax_requests
end
@ -217,7 +217,7 @@ describe "editing external tools" do
expect_fired_alert do
in_frame('resource_selection_iframe') do
keep_trying_until { ff("#basic_lti_link").length > 0 }
ff(".link").length.should eql 4
ff(".link").length.should == 4
f("#bad_url_basic_lti_link").click
end
end
@ -233,7 +233,7 @@ describe "editing external tools" do
expect_fired_alert do
in_frame('resource_selection_iframe') do
keep_trying_until { ff("#basic_lti_link").length > 0 }
ff(".link").length.should eql 4
ff(".link").length.should == 4
f("#no_url_basic_lti_link").click
end
end
@ -274,7 +274,7 @@ describe "editing external tools" do
keep_trying_until { f("#resource_selection_dialog").should be_displayed }
in_frame('resource_selection_iframe') do
keep_trying_until { ff("#basic_lti_link").length > 0 }
ff(".link").length.should eql 4
ff(".link").length.should == 4
f("#no_text_basic_lti_link").click
wait_for_ajax_requests
end
@ -334,7 +334,7 @@ describe "editing external tools" do
})
get "/courses/#{@course.id}/modules/items/#{@tag.id}"
ff("#tool_content").length.should eql 1
ff("#tool_content").length.should == 1
keep_trying_until { f("#tool_content").should be_displayed }
end
@ -349,8 +349,8 @@ describe "editing external tools" do
})
get "/courses/#{@course.id}/modules/items/#{@tag.id}"
ff("#tool_content").length.should eql 0
ff("#tool_content").length.should == 0
f("#tool_form").should be_displayed
ff("#tool_form .load_tab").length.should eql 1
ff("#tool_form .load_tab").length.should == 1
end
end

View File

@ -68,7 +68,7 @@ shared_examples_for "file uploads selenium tests" do
submit_form('#submit_online_upload_form')
keep_trying_until { driver.page_source =~ /Download #{Regexp.quote(filename)}<\/a>/ }
link = f(".details a.forward")
link.text.should eql("Submission Details")
link.text.should == "Submission Details"
expect_new_page_load { link.click }
keep_trying_until { driver.page_source =~ /Submission Details<\/h2>/ }
@ -110,7 +110,7 @@ describe "file uploads local tests" do
JS
wait_for_ajax_requests
f('#tree1 .folder').text.should eql("course files")
f('#tree1 .folder').text.should == "course files"
f('#tree1 .folder .sign').click
# work around bizarre bug where the click above doesn't register the first time
# when testing firefox on windows xp WITHOUT firebug installed. (works with firebug enabled!)

View File

@ -20,7 +20,7 @@ describe "assignment column headers" do
end
it "should have a tooltip with the assignment name" do
f(@header_selector)["title"].should eql @assignment.title
f(@header_selector)["title"].should == @assignment.title
end
it "should handle a ton of assignments without wrapping the slick-header" do
@ -30,7 +30,7 @@ describe "assignment column headers" do
get "/courses/#{@course.id}/gradebook2"
wait_for_ajaximations
# being 38px high means it did not wrap
driver.execute_script('return $("#gradebook_grid .slick-header-columns").height()').should eql 38
driver.execute_script('return $("#gradebook_grid .slick-header-columns").height()').should == 38
end
it "should validate row sorting works when first column is clicked" do

View File

@ -20,8 +20,8 @@ describe "edititing grades" do
#refresh page and make sure the grade sticks
get "/courses/#{@course.id}/gradebook2"
wait_for_ajaximations
final_score_for_row(0).should eql expected_edited_total
final_score_for_row(1).should eql expected_edited_total
final_score_for_row(0).should == expected_edited_total
final_score_for_row(1).should == expected_edited_total
#go back to gradebook1 and compare to make sure they match
check_gradebook_1_totals({
@ -53,23 +53,23 @@ describe "edititing grades" do
# make sure it shows like it is not treating ungraded as 0's by default
is_checked('#include_ungraded_assignments').should be_false
final_score_for_row(0).should eql STUDENT_1_TOTAL_IGNORING_UNGRADED
final_score_for_row(1).should eql STUDENT_2_TOTAL_IGNORING_UNGRADED
final_score_for_row(0).should == STUDENT_1_TOTAL_IGNORING_UNGRADED
final_score_for_row(1).should == STUDENT_2_TOTAL_IGNORING_UNGRADED
# set the "treat ungraded as 0's" option in the header
open_gradebook_settings(f('label[for="include_ungraded_assignments"]'))
# now make sure that the grades show as if those ungraded assignments had a '0'
is_checked('#include_ungraded_assignments').should be_true
final_score_for_row(0).should eql STUDENT_1_TOTAL_TREATING_UNGRADED_AS_ZEROS
final_score_for_row(1).should eql STUDENT_2_TOTAL_TREATING_UNGRADED_AS_ZEROS
final_score_for_row(0).should == STUDENT_1_TOTAL_TREATING_UNGRADED_AS_ZEROS
final_score_for_row(1).should == STUDENT_2_TOTAL_TREATING_UNGRADED_AS_ZEROS
# reload the page and make sure it remembered the setting
get "/courses/#{@course.id}/gradebook2"
wait_for_ajaximations
is_checked('#include_ungraded_assignments').should be_true
final_score_for_row(0).should eql STUDENT_1_TOTAL_TREATING_UNGRADED_AS_ZEROS
final_score_for_row(1).should eql STUDENT_2_TOTAL_TREATING_UNGRADED_AS_ZEROS
final_score_for_row(0).should == STUDENT_1_TOTAL_TREATING_UNGRADED_AS_ZEROS
final_score_for_row(1).should == STUDENT_2_TOTAL_TREATING_UNGRADED_AS_ZEROS
# NOTE: gradebook1 does not handle 'remembering' the `include_ungraded_assignments` setting
@ -81,8 +81,8 @@ describe "edititing grades" do
get "/courses/#{@course.id}/gradebook2"
wait_for_ajaximations
final_score_for_row(0).should eql STUDENT_1_TOTAL_IGNORING_UNGRADED
final_score_for_row(1).should eql STUDENT_2_TOTAL_IGNORING_UNGRADED
final_score_for_row(0).should == STUDENT_1_TOTAL_IGNORING_UNGRADED
final_score_for_row(1).should == STUDENT_2_TOTAL_IGNORING_UNGRADED
end
it "should allow setting a letter grade on a no-points assignment" do
@ -139,7 +139,7 @@ describe "edititing grades" do
set_value(grade_input, 3)
ff('body')[0].click
wait_for_ajax_requests
ff('.gradebook_cell_editable').count.should eql 0
ff('.gradebook_cell_editable').count.should == 0
end
it "should validate curving grades option" do

View File

@ -59,7 +59,7 @@ describe "gradebook2" do
submit_dialog(dialog, '.ui-button')
keep_trying_until do
driver.switch_to.alert.should_not be_nil
driver.switch_to.alert.text.should eql 'None to Update'
driver.switch_to.alert.text.should == 'None to Update'
driver.switch_to.alert.dismiss
true
end
@ -285,12 +285,12 @@ describe "gradebook2" do
# expect dialog to show 1 fewer student with the "Haven't been graded" option
f('[data-action="messageStudentsWho"]').click
ffj('.student_list li:visible').size.should eql 2
ffj('.student_list li:visible').size.should == 2
# select option
select = f('#message_assignment_recipients select.message_types')
select.click
select.all(:tag_name => 'option').find { |o| o.text == "Haven't been graded" }.click
ffj('.student_list li:visible').size.should eql 1
ffj('.student_list li:visible').size.should == 1
end
end
@ -422,7 +422,7 @@ describe "gradebook2" do
get "/courses/#{@course.id}/gradebook2"
wait_for_ajaximations
icons = ffj('.gradebook-cell-turnitin')
icons.size.should eql 2
icons.size.should == 2
# make sure it appears in each submission dialog
icons.each do |icon|

View File

@ -84,14 +84,14 @@ describe "gradebooks" do
get "/courses/#{@course.id}/gradebook"
wait_for_ajaximations
ffj('.turnitin:visible').size.should eql 2
ffj('.turnitin:visible').size.should == 2
# now create a ton of students so that the data loads via ajax
100.times { |i| student_in_course(:active_all => true, :name => "other guy #{i}") }
get "/courses/#{@course.id}/gradebook"
wait_for_ajaximations
ffj('.turnitin:visible').size.should eql 2
ffj('.turnitin:visible').size.should == 2
end
it "should include student view student for grading" do

View File

@ -10,7 +10,7 @@ describe "grading standards" do
f(".add_standard_link").click
standard = f("#grading_standard_new")
standard.should_not be_nil
standard.attribute(:class).should match(/editing/)
standard.should have_class(/editing/)
standard.find_elements(:css, ".delete_row_link").select(&:displayed?).each_with_index do |link, i|
if i % 2 == 1
link.click
@ -21,8 +21,8 @@ describe "grading standards" do
standard.find_element(:css, "input.scheme_name").send_keys("New Standard")
standard.find_element(:css, ".save_button").click
keep_trying_until { !standard.attribute(:class).match(/editing/) }
standard.find_elements(:css, ".grading_standard_row").select(&:displayed?).length.should eql(6)
standard.find_element(:css, ".standard_title .title").text.should eql("New Standard")
standard.find_elements(:css, ".grading_standard_row").select(&:displayed?).length.should == 6
standard.find_element(:css, ".standard_title .title").text.should == "New Standard"
id = standard.attribute(:id)
standard.find_element(:css, ".delete_grading_standard_link").click
@ -46,8 +46,8 @@ describe "grading standards" do
form.find_element(:css, ".edit_letter_grades_link").click
dialog = f("#edit_letter_grades_form")
dialog.find_elements(:css, ".grading_standard_row").select(&:displayed?).length.should eql(12)
dialog.find_elements(:css, ".grading_standard_row").select(&:displayed?).map { |e| e.find_element(:css, ".name").text }.should eql(["A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", "D", "D-", "F"])
dialog.find_elements(:css, ".grading_standard_row").select(&:displayed?).length.should == 12
dialog.find_elements(:css, ".grading_standard_row").select(&:displayed?).map { |e| e.find_element(:css, ".name").text }.should == ["A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", "D", "D-", "F"]
dialog.find_element(:css, ".find_grading_standard_link").click
keep_trying_until { f(".find_grading_standard").should have_class("loaded") }
@ -58,14 +58,13 @@ describe "grading standards" do
dialog.find_element(:css, ".display_grading_standard").should be_displayed
dialog.find_element(:css, ".find_grading_standard_link").click
dialog.find_elements(:css, ".grading_standard_select .title")[-1].text.should eql(@standard.title)
dialog.find_elements(:css, ".grading_standard_select .title")[-1].text.should == @standard.title
dialog.find_elements(:css, ".grading_standard_select")[-1].click
dialog.find_element(:css, "#grading_standard_brief_#{@standard.id}").should be_displayed
dialog.find_element(:css, "#grading_standard_brief_#{@standard.id} .select_grading_standard_link").click
dialog.find_element(:css, "#grading_standard_brief_#{@standard.id}").should_not be_displayed
dialog.find_element(:css, ".display_grading_standard").should be_displayed
dialog.find_element(:css, ".standard_title .title").text.should eql(@standard.title)
sleep 2
dialog.find_element(:css, ".standard_title .title").text.should == @standard.title
end
it "should allow setting a grading standard for a course" do
@ -83,12 +82,12 @@ describe "grading standards" do
form.find_element(:css, ".edit_letter_grades_link").click
dialog = f("#edit_letter_grades_form")
dialog.find_elements(:css, ".grading_standard_row").select(&:displayed?).length.should eql(12)
dialog.find_elements(:css, ".grading_standard_row").select(&:displayed?).map { |e| e.find_element(:css, ".name").text }.should eql(["A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", "D", "D-", "F"])
dialog.find_elements(:css, ".grading_standard_row").select(&:displayed?).length.should ==(12)
dialog.find_elements(:css, ".grading_standard_row").select(&:displayed?).map { |e| e.find_element(:css, ".name").text }.should == ["A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", "D", "D-", "F"]
dialog.find_element(:css, ".find_grading_standard_link").click
keep_trying_until { f(".find_grading_standard").should have_class("loaded") }
dialog.find_elements(:css, ".grading_standard_select .title")[-1].text.should eql(@standard.title)
dialog.find_elements(:css, ".grading_standard_select .title")[-1].text.should == @standard.title
dialog.find_elements(:css, ".grading_standard_select")[-1].click
(standard_brief = dialog.find_element(:css, "#grading_standard_brief_#{@standard.id}")).should be_displayed
rows = standard_brief.find_elements(:css, '.details_row')
@ -102,7 +101,7 @@ describe "grading standards" do
dialog.find_element(:css, "#grading_standard_brief_#{@standard.id} .select_grading_standard_link").click
dialog.find_element(:css, "#grading_standard_brief_#{@standard.id}").should_not be_displayed
dialog.find_element(:css, ".display_grading_standard").should be_displayed
dialog.find_element(:css, ".standard_title .title").text.should eql(@standard.title)
dialog.find_element(:css, ".standard_title .title").text.should == @standard.title
dialog.find_element(:css, ".remove_grading_standard_link").should be_displayed
dialog.find_element(:css, ".remove_grading_standard_link").click

View File

@ -36,7 +36,7 @@ describe "handlebars" do
url: 'http://foo.bar'
CS
result.should eql(<<-RESULT)
result.should == <<-RESULT
<h1>greetings</h1>
<p>ohai my name is katie im your <b>yoga</b> instructure!! ;) heres some tips to get you started:</p>
<ol>
@ -53,7 +53,7 @@ describe "handlebars" do
driver.execute_script Handlebars.compile_template("outside partial {{>test_partial}}", "test_template")
result = require_exec "jst/test_template", "test_template()"
result.should eql "outside partial hi from inside partial"
result.should == "outside partial hi from inside partial"
end
end

View File

@ -99,7 +99,7 @@ describe "help dialog" do
er.subject.should == 'test subject'
er.comments.should == 'test comments'
er.data['user_perceived_severity'].should == severity
er.guess_email.should eql @user.email
er.guess_email.should == @user.email
end
end

View File

@ -37,7 +37,7 @@ shared_examples_for "conversations selenium tests" do
def browse_menu
@browser.click
keep_trying_until { ffj('.autocomplete_menu:visible .list').size.should eql(@level) }
keep_trying_until { ffj('.autocomplete_menu:visible .list').size.should == @level }
wait_for_animations
end
@ -49,7 +49,7 @@ shared_examples_for "conversations selenium tests" do
element.first.click
wait_for_ajaximations(150)
keep_trying_until { ffj('.autocomplete_menu:visible .list').size.should eql(@level) }
keep_trying_until { ffj('.autocomplete_menu:visible .list').size.should == @level }
@elements = nil
elements
@ -198,7 +198,7 @@ shared_examples_for "conversations selenium tests" do
driver.switch_to.alert.accept
if confirm_conversation_deleted
keep_trying_until { get_conversations(false).size.should eql(orig_size - 1) }
keep_trying_until { get_conversations(false).size.should == orig_size - 1 }
end
end

View File

@ -25,9 +25,9 @@ shared_examples_for "external tools tests" do
wait_for_ajax_requests
ContextExternalTool.count > 0
tool = ContextExternalTool.last
tool.name.should eql name
tool.consumer_key.should eql key
tool.shared_secret.should eql secret
tool.name.should == name
tool.consumer_key.should == key
tool.shared_secret.should == secret
tool_checker tool, opts
end
@ -35,59 +35,59 @@ shared_examples_for "external tools tests" do
if (opts.include? :xml)
url = "http://example.com/other_url"
tool.url.should eql url
tool.workflow_state.should eql "public"
tool.description.should eql "Description"
tool.url.should == url
tool.workflow_state.should == "public"
tool.description.should == "Description"
tool.has_editor_button.should be_true
tool.has_resource_selection.should be_true
tool.has_course_navigation.should be_true
tool.has_account_navigation.should be_true
tool.has_user_navigation.should be_true
f("#external_tool_#{tool.id} .url").text.should eql url
f("#external_tool_#{tool.id} .url").text.should == url
f("#external_tool_#{tool.id} .editor_button").should be_displayed
f("#external_tool_#{tool.id} .resource_selection").should be_displayed
f("#external_tool_#{tool.id} .course_navigation").should be_displayed
f("#external_tool_#{tool.id} .user_navigation").should be_displayed
f("#external_tool_#{tool.id} .account_navigation").should be_displayed
f("#external_tool_#{tool.id} .readable_state").text.should eql "Public"
f("#external_tool_#{tool.id} .description").text.should eql "Description"
f("#external_tool_#{tool.id} .readable_state").text.should == "Public"
f("#external_tool_#{tool.id} .description").text.should == "Description"
elsif opts.include? :url
url = "https://lti-examples.heroku.com/tool_redirect"
kitten_text = "pictures of kittens to your site"
tool.workflow_state.should eql "anonymous"
tool.url.should eql url
tool.workflow_state.should == "anonymous"
tool.url.should == url
tool.description.should include_text kitten_text
tool.has_editor_button.should be_true
tool.settings.should be_present
tool.settings[:editor_button].should be_present
f("#external_tool_#{tool.id} .url").text.should eql url
f("#external_tool_#{tool.id} .url").text.should == url
f("#external_tool_#{tool.id} .description").text.should include_text kitten_text
f("#external_tool_#{tool.id} .editor_button").should be_displayed
else
tool.description.should eql @description
tool.description.should == @description
tool.settings.count > 0
tool.settings[:custom_fields].keys.count >0
custom_hash = {@custom_key => @custom_value}
tool.settings[:custom_fields].should eql custom_hash
f("#external_tool_#{tool.id} .description").text.should eql @description
tool.settings[:custom_fields].should == custom_hash
f("#external_tool_#{tool.id} .description").text.should == @description
if (opts.include? :manual_url)
f("#external_tool_#{tool.id} .url").text.should eql @manual_url
tool.url.should eql @manual_url
f("#external_tool_#{tool.id} .url").text.should == @manual_url
tool.url.should == @manual_url
else
tool.domain.should eql @domain
tool.domain.should == @domain
end
if (opts.include? :name_only)
tool.workflow_state.should eql "name_only"
f("#external_tool_#{tool.id} .readable_state").text.should eql "Name Only"
tool.workflow_state.should == "name_only"
f("#external_tool_#{tool.id} .readable_state").text.should == "Name Only"
elsif (opts.include? :public)
tool.workflow_state.should eql "public"
f("#external_tool_#{tool.id} .readable_state").text.should eql "Public"
tool.workflow_state.should == "public"
f("#external_tool_#{tool.id} .readable_state").text.should == "Public"
else
tool.workflow_state.should eql "anonymous"
f("#external_tool_#{tool.id} .readable_state").text.should eql "Anonymous"
tool.workflow_state.should == "anonymous"
f("#external_tool_#{tool.id} .readable_state").text.should == "Anonymous"
end
end

View File

@ -115,7 +115,7 @@ shared_examples_for "gradebook2 selenium tests" do
keep_trying_until do
students.each do |student_id, expected_score|
row_total = f(".final_grade .student_#{student_id} .grade").text + '%'
row_total.should eql expected_score
row_total.should == expected_score
end
end
end

View File

@ -31,7 +31,7 @@ shared_examples_for "outcome tests" do
wait_for_ajaximations
keep_trying_until { fj("#outcomes .learning_outcome .short_description").text.should == outcome_name }
f('.show_details_link').click
ffj('#outcomes .rubric_criterion .rating:visible').size.should eql(3)
ffj('#outcomes .rubric_criterion .rating:visible').size.should == 3
end
it "should edit a learning outcome" do
@ -102,7 +102,7 @@ shared_examples_for "outcome tests" do
draggable = f('.outcome_group .reorder_link')
drag_to = f('#section-tabs')
driver.action.drag_and_drop(draggable, drag_to).perform
driver.execute_script('return INST.errorCount;').should eql 0
driver.execute_script('return INST.errorCount;').should == 0
end
it "re-order sibling outcomes" do

View File

@ -10,7 +10,7 @@ shared_examples_for "quizzes selenium tests" do
type_in_tiny ".question_form:visible textarea.question_content", 'Hi, this is a multiple choice question.'
answers = question.find_elements(:css, ".form_answers > .answer")
answers.length.should eql(4)
answers.length.should == 4
replace_content(answers[0].find_element(:css, ".select_answer input"), "Correct Answer")
set_feedback_content(answers[0].find_element(:css, ".answer_comments"), "Good job!")
replace_content(answers[1].find_element(:css, ".select_answer input"), "Wrong Answer #1")
@ -35,7 +35,7 @@ shared_examples_for "quizzes selenium tests" do
type_in_tiny '.question:visible textarea.question_content', 'This is not a true/false question.'
answers = question.find_elements(:css, ".form_answers > .answer")
answers.length.should eql(2)
answers.length.should == 2
answers[1].find_element(:css, ".select_answer_link").click # false - get it?
answers[1].find_element(:css, ".comment_focus").click
answers[1].find_element(:css, ".answer_comments textarea").send_keys("Good job!")
@ -69,8 +69,8 @@ shared_examples_for "quizzes selenium tests" do
submit_form(question)
wait_for_ajax_requests
questions = ffj(".question_holder:visible")
questions.length.should eql(@question_count)
f("#right-side .points_possible").text.should eql(@points_total.to_s)
questions.length.should == @question_count
f("#right-side .points_possible").text.should == @points_total.to_s
end
def quiz_with_new_questions

View File

@ -0,0 +1,104 @@
require File.expand_path(File.dirname(__FILE__) + '/../common')
EDIT_NAME = 'edited appointment'
EDIT_LOCATION = 'edited location'
shared_examples_for "scheduler selenium tests" do
it_should_behave_like "in-process server selenium tests"
def fill_out_appointment_group_form(new_appointment_text, opts = {})
f('.create_link').click
edit_form = f('#edit_appointment_form')
keep_trying_until { edit_form.should be_displayed }
replace_content(fj('input[name="title"]'), new_appointment_text)
f('.ag_contexts_selector').click
f('.ag_sections_toggle').click
if opts[:section_codes]
opts[:section_codes].each { |code| f("[name='sections[]'][value='#{code}']").click }
else
f('[name="context_codes[]"]').click
end
f('.ag_contexts_done').click
if opts[:checkable_options]
if opts[:checkable_options].has_key?(:per_slot_option)
set_value f('[name="per_slot_option"]'), true
end
if opts[:checkable_options].has_key?(:participant_visibility)
set_value f('[name="participant_visibility"]'), true
end
if opts[:checkable_options].has_key?(:max_appointments_per_participant_option)
set_value f('[name="max_appointments_per_participant_option"]'), true
end
end
date_field = edit_form.find_element(:css, '.date_field')
date_field.click
wait_for_animations
fj('.ui-datepicker-trigger:visible').click
datepicker_next
replace_content(edit_form.find_element(:css, '.start_time'), '1')
replace_content(edit_form.find_element(:css, '.end_time'), '3')
end
def submit_appointment_group_form(publish = true)
save, save_and_publish = ff('.ui-dialog-buttonset .ui-button')
if publish
save_and_publish.click
else
save.click
end
wait_for_ajaximations
end
def create_appointment_group_manual(opts = {})
opts = {
:publish => true,
:new_appointment_text => 'new appointment group'
}.with_indifferent_access.merge(opts)
expect {
fill_out_appointment_group_form(opts[:new_appointment_text], opts)
submit_appointment_group_form(opts[:publish])
f('.view_calendar_link').text.should == opts[:new_appointment_text]
}.to change(AppointmentGroup, :count).by(1)
end
def click_scheduler_link
header_buttons = ff('.ui-buttonset > label')
header_buttons[2].click
wait_for_ajaximations
end
def click_appointment_link
f('.view_calendar_link').click
f('.scheduler-mode').should be_displayed
end
def click_al_option(option_selector, offset=0)
ffj('.al-trigger')[offset].click
options = ffj('.al-options')[offset]
options.should be_displayed
options.find_element(:css, option_selector).click
end
def delete_appointment_group
delete_button = fj('.ui-dialog-buttonset .ui-button:contains("Delete")')
delete_button.click
wait_for_ajaximations
end
def edit_appointment_group(appointment_name = EDIT_NAME, location_name = EDIT_LOCATION)
f('#edit_appointment_form').should be_displayed
replace_content(fj('input[name="title"]'), appointment_name)
replace_content(fj('input[name="location"]'), location_name)
f('.ui-dialog-buttonset .ui-button').click
wait_for_ajaximations
f('.view_calendar_link').text.should == appointment_name
f('.ag-location').should include_text(location_name)
end
def open_edit_dialog
driver.action.move_to(f('.appointment-group-item')).perform
click_al_option('.edit_link')
end
end

View File

@ -23,8 +23,8 @@ def add_user (opts={})
wait_for_ajax_requests
user = User.first(:conditions => {:name => name})
user.should be_present
user.sortable_name.should eql sortable_name
user.short_name.should eql short_name
user.email.should eql email
user.sortable_name.should == sortable_name
user.short_name.should == short_name
user.email.should == email
user
end

View File

@ -0,0 +1,49 @@
require File.expand_path(File.dirname(__FILE__) + '/../common')
shared_examples_for "submissions selenium tests" do
it_should_behave_like "in-process server selenium tests"
def create_assignment(type = 'online_text_entry')
assignment = @course.assignments.build({
:name => 'media assignment',
:submission_types => type
})
assignment.workflow_state = 'published'
assignment.save!
assignment
end
def create_assignment_and_go_to_page(type = 'online_text_entry')
assignment = create_assignment type
get "/courses/#{@course.id}/assignments/#{assignment.id}"
assignment
end
def open_media_comment_dialog
f('.media_comment_link').click
# swf and stuff loads, give it a sec to do its thing
sleep 0.5
end
def submit_media_comment_1
open_media_comment_dialog
# pretend like we are flash sending data to the JS
driver.execute_script <<-JS
var entries1 = [{"duration":1.664,"thumbnailUrl":"http://www.instructuremedia.com/p/100/sp/10000/thumbnail/entry_id/0_jd6ger47/version/0","numComments":-1,"status":1,"rank":-1,"userScreenName":"_100_1_1","displayCredit":"_100_1_1","partnerLandingPage":null,"dataUrl":"http://www.instructuremedia.com/p/100/sp/10000/flvclipper/entry_id/0_jd6ger47/version/100000","sourceLink":"","subpId":10000,"puserId":"1_1","views":0,"height":0,"description":null,"hasThumbnail":false,"width":0,"kshowId":"0_pb7id2lf","kuserId":"","userLandingPage":"","mediaType":2,"plays":0,"partnerId":100,"adminTags":"","entryVersion":"","downloadUrl":"http://www.instructuremedia.com/p/100/sp/10000/raw/entry_id/0_jd6ger47/version/100000","createdAtDate":"1970-01-16T09:24:02.931Z","votes":-1,"uploaderName":null,"tags":"","entryName":"ryanf@instructure.com 2012-02-21T16:48:37.729Z","entryType":1,"entryId":"0_jd6ger47","createdAtAsInt":1329842931,"uid":"E78A81CC-D03D-CD10-B449-A0D0D172EF38"}]
addEntryComplete(entries1)
JS
wait_for_ajax_requests
end
def submit_media_comment_2
open_media_comment_dialog
driver.execute_script <<-JS
var entries2 = [{"duration":1.829,"thumbnailUrl":"http://www.instructuremedia.com/p/100/sp/10000/thumbnail/entry_id/0_5hcd9mro/version/0","numComments":-1,"status":1,"rank":-1,"userScreenName":"_100_1_1","displayCredit":"_100_1_1","partnerLandingPage":null,"dataUrl":"http://www.instructuremedia.com/p/100/sp/10000/flvclipper/entry_id/0_5hcd9mro/version/100000","sourceLink":"","subpId":10000,"puserId":"1_1","views":0,"height":0,"description":null,"hasThumbnail":false,"width":0,"kshowId":"0_pb7id2lf","kuserId":"","userLandingPage":"","mediaType":2,"plays":0,"partnerId":100,"adminTags":"","entryVersion":"","downloadUrl":"http://www.instructuremedia.com/p/100/sp/10000/raw/entry_id/0_5hcd9mro/version/100000","createdAtDate":"1970-01-16T09:24:03.563Z","votes":-1,"uploaderName":null,"tags":"","entryName":"ryanf@instructure.com 2012-02-21T16:59:11.249Z","entryType":1,"entryId":"0_5hcd9mro","createdAtAsInt":1329843563,"uid":"22A2C625-5FAB-AF3A-1A76-A0DA7572BFE4"}]
addEntryComplete(entries2)
JS
wait_for_ajax_requests
end
end

View File

@ -11,7 +11,7 @@ describe "jquery" do
driver.execute_script("$(document.body).append('<input type=\"checkbox\" checked=\"checked\" id=\"checkbox_test\">')")
checkbox = f('#checkbox_test')
driver.execute_script("return $('#checkbox_test').attr('checked');").should eql('checked')
driver.execute_script("return $('#checkbox_test').attr('checked');").should == 'checked'
checkbox.click
driver.execute_script("return $('#checkbox_test').attr('checked');").should be_nil
@ -27,7 +27,7 @@ describe "jquery" do
end
it "should handle $.attr('method', post|delete|put|get) by adding a hidden input" do
get('/logout')
driver.execute_script("return $('form').attr('method', 'delete').attr('method')").downcase.should eql("post")
driver.execute_script("return $('form input[name=_method]').val()").should eql("delete")
driver.execute_script("return $('form').attr('method', 'delete').attr('method')").downcase.should == "post"
driver.execute_script("return $('form input[name=_method]').val()").should == "delete"
end
end

View File

@ -42,7 +42,7 @@ describe "jquery ui" do
driver.execute_script("$('#ui-datepicker-time-hour').select();")
f("#ui-datepicker-time-hour").send_keys('5')
f("#ui-datepicker-time-hour").attribute('value').should == "5"
f("#ui-datepicker-time-hour").should have_attribute('value', '5')
end
end

View File

@ -78,8 +78,8 @@ describe "manage groups" do
# submit new category form
add_category(@course, 'New Category')
ff("#category_list li").size.should == 2
ff("#category_list li a").first.text.should eql "New Category"
ff("#category_list li a").last.text.should eql group_category.name
ff("#category_list li a").first.text.should == "New Category"
ff("#category_list li a").last.text.should == group_category.name
end
it "should remove tab and sidebar entries for deleted category" do

View File

@ -277,7 +277,7 @@ describe "manage groups students" do
confirm_dialog.accept
wait_for_ajaximations
ff(".left_side .group").should be_empty
@course.group_categories.all.count.should eql 0
@course.group_categories.all.count.should == 0
end
it "should edit an individual group" do
@ -314,7 +314,7 @@ describe "manage groups students" do
confirm_dialog = driver.switch_to.alert
confirm_dialog.accept
wait_for_ajax_requests
keep_trying_until { f('.right_side .group .user_count').text.should eql '0 students' }
keep_trying_until { f('.right_side .group .user_count').text.should == '0 students' }
end
before (:each) do

View File

@ -112,7 +112,7 @@ describe "profile" do
link = f("#channel_#{channel.id} td:first-child a")
link.click
wait_for_ajaximations
row.attribute(:class).should match(/default/)
row.should have_class("default")
end
it "should display file uploader link on files page" do
@ -200,11 +200,11 @@ describe "profile" do
f('#show_user_services').click
wait_for_ajaximations
@user.reload.show_user_services.should_not eql initial_state
@user.reload.show_user_services.should_not == initial_state
f('#show_user_services').click
wait_for_ajaximations
@user.reload.show_user_services.should eql initial_state
@user.reload.show_user_services.should == initial_state
end
it "should generate a new access token" do
@ -248,7 +248,7 @@ describe "profile" do
submit_form(edit_form)
wait_for_ajaximations
@user.reload
@user.birthdate.should eql(Time.utc(1980, 1, 31))
@user.birthdate.should == Time.utc(1980, 1, 31)
end
it "should not accept a partial birthdate" do
@ -330,7 +330,7 @@ shared_examples_for "profile pictures selenium tests" do
wait_for_ajaximations
keep_trying_until do
profile_pic = fj('.profile_pic_link img')
profile_pic.attribute('src').should == image_src
profile_pic.should have_attribue('src', image_src)
end
Attachment.last.folder.should == @user.profile_pics_folder
end

View File

@ -113,7 +113,7 @@ describe "quizzes question banks" do
wait_for_ajaximations
f(".select_all_link").should be_displayed
}
ffj("#find_question_dialog .bank:visible").size.should eql 1
ffj("#find_question_dialog .bank:visible").size.should == 1
close_visible_dialog
keep_trying_until {
@ -122,7 +122,7 @@ describe "quizzes question banks" do
}
f(".find_bank_link").click
wait_for_ajaximations
ffj("#find_bank_dialog .bank:visible").size.should eql 1
ffj("#find_bank_dialog .bank:visible").size.should == 1
end
it "should import questions from a question bank" do

View File

@ -228,11 +228,11 @@ describe "quizzes question creation" do
fj('.combination_count:visible').send_keys('20') # over the limit
button = fj('button.compute_combinations:visible')
button.click
fj('.combination_count:visible').attribute(:value).should eql "10"
fj('.combination_count:visible').should have_attribute(:value, "10")
keep_trying_until {
button.text == 'Generate'
}
ffj('table.combinations:visible tr').size.should eql 11 # plus header row
ffj('table.combinations:visible tr').size.should == 11 # plus header row
submit_form(question)
wait_for_ajax_requests

View File

@ -1,270 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + '/helpers/quizzes_common')
describe "quizzes questions" do
it_should_behave_like "quizzes selenium tests"
before (:each) do
course_with_teacher_logged_in
end
it "should edit a quiz question" do
@context = @course
q = quiz_model
quest1 = q.quiz_questions.create!(:question_data => {:name => "first question"})
q.generate_quiz_data
q.save!
get "/courses/#{@course.id}/quizzes/#{q.id}/edit"
wait_for_ajax_requests
hover_and_click(".edit_question_link")
wait_for_animations
question = fj(".question_form:visible")
click_option('.question_form:visible .question_type', 'Multiple Choice')
replace_content(question.find_element(:css, 'input[name="question_name"]'), 'edited question')
answers = question.find_elements(:css, ".form_answers > .answer")
answers.length.should eql(2)
question.find_element(:css, ".add_answer_link").click
question.find_element(:css, ".add_answer_link").click
answers = question.find_elements(:css, ".form_answers > .answer")
answers.length.should eql(4)
driver.action.move_to(answers[3]).perform
answers[3].find_element(:css, ".delete_answer_link").click
answers = question.find_elements(:css, "div.form_answers > div.answer")
answers.length.should eql(3)
# check that the wiki sidebar shows up
f('#quiz_options_holder .link_to_content_link').click
f('#editor_tabs h4').should include_text("Insert Content into the Page")
f('#quiz_content_links .quiz_options_link').click
submit_form(question)
question = f("#question_#{quest1.id}")
question.find_element(:css, ".question_name").text.should == 'edited question'
f('#show_question_details').click
question.find_elements(:css, '.answers .answer').length.should == 3
end
it "should not show 'Missing Word' option in question types dropdown" do
get "/courses/#{@course.id}/quizzes/new"
ff("#question_form_template option.missing_word").length.should == 1
keep_trying_until {
f(".add_question .add_question_link").click
ff("#questions .question_holder").length > 0
}
ff("#questions .question_holder option.missing_word").length.should == 0
end
it "should reorder questions with drag and drop" do
quiz_with_new_questions
# ensure they are in the right order
names = ff('.question_name')
names[0].text.should == 'first question'
names[1].text.should == 'second question'
load_simulate_js
# drag the second question up 100px (next slot)
driver.execute_script <<-JS
$('.move_icon:eq(1)').show().simulate('drag', {dx: 0, dy: -100});
JS
# verify they were swapped
names = ff('.question_name')
names[0].text.should == 'second question'
names[1].text.should == 'first question'
end
it "should not show the display details for text questions" do
quiz = start_quiz_question
question = fj(".question_form:visible")
click_option('.question_form:visible .question_type', 'Text (no question)')
submit_form(question)
wait_for_ajax_requests
quiz.reload
show_el = f('#show_question_details')
show_el.should_not be_displayed
end
it "should not show the display details for essay questions" do
quiz = start_quiz_question
question = fj(".question_form:visible")
click_option('.question_form:visible .question_type', 'Essay Question')
submit_form(question)
wait_for_ajax_requests
quiz.reload
show_el = f('#show_question_details')
show_el.should_not be_displayed
end
it "should show the display details when questions other than text or essay questions exist" do
quiz = start_quiz_question
show_el = f('#show_question_details')
question = fj(".question_form:visible")
show_el.should_not be_displayed
click_option('.question_form:visible .question_type', 'Multiple Choice')
submit_form(question)
wait_for_ajax_requests
quiz.reload
show_el.should be_displayed
end
it "should calculate correct quiz question points total" do
get "/courses/#{@course.id}/quizzes"
expect_new_page_load { f('.new-quiz-link').click }
@question_count = 0
@points_total = 0
add_quiz_question('1')
add_quiz_question('2')
add_quiz_question('3')
add_quiz_question('4')
submit_form('#quiz_options_form')
wait_for_ajax_requests
quiz = Quiz.last
quiz.reload
quiz.quiz_questions.length.should == @question_count
end
it "should round published quiz points correctly on main quiz page" do
pending("bug 7402 - Quiz points not rounding correctly") do
q = @course.quizzes.create!(:title => "new quiz")
75.times do
q.quiz_questions.create!(:question_data => {:name => "Quiz Question 1", :question_type=>'essay_question', :question_text=>'qq1', 'answers' => [], :points_possible=>1.33})
end
q.generate_quiz_data
q.workflow_state = 'available'
q.save
q.reload
get "/courses/#{@course.id}/quizzes/#{Quiz.last.id}"
fj('.summary td:eq(2)').text.should == "99.75%"
end
end
it "should round numeric questions the same when created and taking a quiz" do
start_quiz_question
question = fj(".question_form:visible")
click_option('.question_form:visible .question_type', 'Numerical Answer')
type_in_tiny '.question:visible textarea.question_content', 'This is a numerical question.'
answers = question.find_elements(:css, ".form_answers > .answer")
answers[0].find_element(:name, 'answer_exact').send_keys('0.000675')
driver.execute_script <<-JS
$('input[name=answer_exact]').trigger('change');
JS
answers[0].find_element(:name, 'answer_error_margin').send_keys('0')
submit_form(question)
wait_for_ajax_requests
expect_new_page_load {
f('.publish_quiz_button').click
}
expect_new_page_load {
driver.find_element(:link, 'Take the Quiz').click
}
input = f('input[type=text]')
input.click
input.send_keys('0.000675')
driver.execute_script <<-JS
$('input[type=text]').trigger('change');
JS
expect_new_page_load {
submit_form('#submit_quiz_form')
}
f('.score_value').text.strip.should == '1'
end
context "select element behavior" do
before (:each) do
@context = @course
bank = @course.assessment_question_banks.create!(:title=>'Test Bank')
q = quiz_model
b = bank.assessment_questions.create!
quest2 = q.quiz_questions.create!(:assessment_question => b)
quest2.write_attribute(:question_data,
{
:neutral_comments=>"",
:question_text=>"<p>My hair is [x] and my wife's is [y].</p>",
:points_possible=>1, :question_type=>"multiple_dropdowns_question",
:answers=>
[{
:comments=>"",
:weight=>100,
:blank_id=>"x",
:text=>"brown",
:id=>2624
},
{
:comments=>"",
:weight=>0,
:blank_id=>"x",
:text=>"black",
:id=>3085
},
{
:comments=>"",
:weight=>100,
:blank_id=>"y",
:text=>"brown",
:id=>5780
},
{
:comments=>"",
:weight=>0,
:blank_id=>"y",
:text=>"red",
:id=>8840
}],
:correct_comments=>"",
:name=>"Question",
:question_name=>"Question",
:incorrect_comments=>"",
:assessment_question_id=>nil
})
q.generate_quiz_data
q.save!
get "/courses/#{@course.id}/quizzes/#{q.id}/edit"
f('.publish_quiz_button')
get "/courses/#{@course.id}/quizzes/#{q.id}/take?user_id=#{@user.id}"
driver.find_element(:link, 'Take the Quiz').click
wait_for_ajax_requests
end
after do
#This step is to prevent selenium from freezing when the dialog appears when leaving the page
keep_trying_until do
f('#left-side .quizzes').click
confirm_dialog = driver.switch_to.alert
confirm_dialog.accept
true
end
end
it "should selectmenu-ify select elements" do
select = f('.question select')
keep_trying_until { fj('.question_select:visible').should be_nil }
f('.ui-selectmenu').click
ff('.ui-selectmenu-open li')[1].click
select[:selectedIndex].should eql "1"
end
end
end

View File

@ -1,96 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + '/helpers/quizzes_common')
describe "quiz statistics" do
it_should_behave_like "quizzes selenium tests"
def update_quiz_submission_scores(question_score = '1')
@quiz_submission.update_scores({
'context_id' => @course.id,
'override_scores' => true,
'context_type' => 'Course',
'submission_version_number' => '1',
"question_score_#{@questions[0].id}" => question_score
})
end
def summary_rows
ff('#statistics_summary tr')
end
before (:each) do
quiz_with_graded_submission([{:question_data => {:name => 'question 1', :points_possible => 1, 'question_type' => 'true_false_question'}},
{:question_data => {:name => 'question 2', :points_possible => 1, 'question_type' => 'true_false_question'}}])
course_with_teacher_logged_in(:active_all => true, :course => @course)
end
describe "question graphs" do
it "should validate correct number of questions are showing up" do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
ff('.question').count.should == @quiz.quiz_questions.count
end
it "should validate number attempts on questions" do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
ff('.question .question_attempts').each { |attempt| attempt.text.should == '1 attempt' }
end
it "should validate question graph tooltip" do
update_quiz_submission_scores
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
(0..2).each do |i|
driver.execute_script("$('.tooltip_text:eq(#{i})').css('visibility', 'visible')")
if i == 0 || i == 1
fj(".tooltip_text:eq(#{i})").should include_text '0%'
else
fj(".tooltip_text:eq(#{i})").should include_text '100%'
end
end
end
end
describe "right side info bar with initial data" do
before (:each) do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
end
it "should validate average time taken for quiz" do
summary_rows[0].should include_text 'less than a minute'
end
%w(correct incorrect high_score low_score mean_score standard_deviation).each_with_index do |data_point, i|
it "should validate #{data_point} number for initial info" do
index = (i + 1) # + 1 to get rid of the first row
index == 2 ? (summary_rows[index].should include_text("2")) : (summary_rows[index].should include_text("0"))
end
end
end
describe 'right side info bar with altered data' do
before (:each) do
update_quiz_submission_scores
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
@expected_side_bar_numbers = ["0", "2", "1"]
end
%w(correct incorrect high_score low_score mean_score standard_deviation).each_with_index do |data_point, i|
it "should validate #{data_point} number for altered info" do
index = (i + 1) # + 1 to get rid of the first row
case index
when 1
summary_rows[index].should include_text(@expected_side_bar_numbers[0])
when 2
summary_rows[index].should include_text(@expected_side_bar_numbers[1])
when 3..5
summary_rows[index].should include_text(@expected_side_bar_numbers[2])
when 6
summary_rows[index].should include_text(@expected_side_bar_numbers[0])
end
end
end
end
end

View File

@ -1,34 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + '/helpers/quizzes_common')
describe "quizzes students" do
it_should_behave_like "quizzes selenium tests"
it "should allow a student view student to take a quiz" do
course_with_teacher_logged_in
quiz = @course.quizzes.create!(:title => "new quiz")
quiz.quiz_questions.create!(:question_data => {
:name => 'test 3',
:question_type => 'multiple_choice_question',
:answers => {'answer_0' => {'answer_text' => '0'}, 'answer_1' => {'answer_text' => '1'}}})
quiz.generate_quiz_data
quiz.workflow_state = 'available'
quiz.save
@fake_student = @course.student_view_student
enter_student_view
get "/courses/#{@course.id}/quizzes/#{quiz.id}"
f("#take_quiz_link").click
wait_for_ajaximations
q = quiz.stored_questions[0]
f("#question_#{q[:id]}_answer_#{q[:answers][0][:id]}").click
submit_form('#submit_quiz_form')
quiz_sub = @fake_student.reload.submissions.find_by_assignment_id(quiz.assignment.id)
quiz_sub.should be_present
quiz_sub.workflow_state.should eql "graded"
end
end

View File

@ -1,109 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + '/helpers/rubrics_specs')
describe "shared rubric specs" do
let(:rubric_url) { "/courses/#{@course.id}/rubrics" }
let(:who_to_login) { 'teacher' }
it_should_behave_like "rubric tests"
end
describe "course rubrics" do
it_should_behave_like "in-process server selenium tests"
context "importing" do
it "should create a allow immediate editing when adding an imported rubric to a new assignment" do
course_with_teacher_logged_in
rubric_association_model(:user => @user, :context => @course, :purpose => "grading")
@old_course = @course
@course = nil
course_with_teacher(:user => @user, :active_all => true)
@course.merge_into_course(@old_course, :everything => true)
@assignment = @course.assignments.create!(assignment_valid_attributes.merge({:title => "New Course Assignment"}))
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
f("#right-side-wrapper .add_rubric_link").click
fj(".find_rubric_link:visible").click
wait_for_ajaximations
fj(".select_rubric_link:visible").click
wait_for_ajax_requests
wait_for_animations(500)
fj(".edit_rubric_link:visible").click
fj(".rubric_custom_rating:visible").click
fj(".save_button:visible").click
wait_for_ajax_requests
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
ffj(".custom_ratings:visible").size.should eql(1)
end
end
it "should display free-form comments to the student" do
assignment_model
rubric_model(:context => @course, :free_form_criterion_comments => true)
course_with_student(:course => @course, :active_all => true)
@association = @rubric.associate_with(@assignment, @course, :purpose => 'grading', :use_for_grading => true)
comment = "Hi, please see www.example.com.\n\nThanks."
@assessment = @association.assess({
:user => @student,
:assessor => @teacher,
:artifact => @assignment.find_or_create_submission(@student),
:assessment => {
:assessment_type => 'grading',
:criterion_crit1 => {
:points => 5,
:comments => comment,
}
}
})
user_logged_in(:user => @student)
get "/courses/#{@course.id}/grades"
f('.toggle_rubric_assessments_link').click
wait_for_animations
f('.rubric .criterion .custom_rating_comments').text.should == comment
f('.rubric .criterion .custom_rating_comments a').attribute('href').should == 'http://www.example.com/'
get "/courses/#{@course.id}/assignments/#{@assignment.id}/submissions/#{@student.id}"
f('.assess_submission_link').click
wait_for_animations
f('.rubric .criterion .custom_rating_comments').text.should == comment
f('.rubric .criterion .custom_rating_comments a').attribute('href').should == 'http://www.example.com/'
end
it "should ignore outcome rubric lines when calculating total" do
course_with_teacher_logged_in
outcome_with_rubric
@assignment = @course.assignments.create(:name => 'assignment with rubric')
@association = @rubric.associate_with(@assignment, @course, :use_for_grading => true, :purpose => 'grading')
@rubric.data[0][:ignore_for_scoring] = '1'
@rubric.points_possible = 5
@rubric.instance_variable_set('@outcomes_changed', true)
@rubric.save!
get "/courses/#{@course.id}/rubrics/#{@rubric.id}"
f('.rubric_total').should include_text "5"
f('.edit_rubric_link').click
criterion_points = fj(".criterion_points:visible")
replace_content(criterion_points, "10")
criterion_points.send_keys(:return)
submit_form("#edit_rubric_form")
wait_for_ajaximations
fj('.rubric_total').should include_text "10"
# check again after reload
refresh_page
fj('.rubric_total').should include_text "10" #avoid selenium caching
end
it "should not display the edit form more than once" do
course_with_teacher_logged_in
rubric_association_model(:user => @user, :context => @course, :purpose => "grading")
get "/courses/#{@course.id}/rubrics/#{@rubric.id}"
2.times { |n| f('.edit_rubric_link').click }
ff('.rubric .button-container').length.should == 1
end
end

View File

@ -1,17 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + '/common')
describe "section tabs on the left side" do
it_should_behave_like "in-process server selenium tests"
it "should make the active tab white" do
course_with_teacher_logged_in
%w{assignments quizzes settings}.each do |feature|
get "/courses/#{@course.id}/#{feature}"
js = "return $('#section-tabs .#{feature}').css('background-color')"
element_that_is_not_left_side = f('#content')
# make sure to mouse off the link so the :hover and :focus styles do not apply
driver.action.move_to(element_that_is_not_left_side).perform
driver.execute_script(js).should eql('rgb(214, 236, 252)')
end
end
end

View File

@ -1,27 +0,0 @@
# coding: utf-8
require File.expand_path(File.dirname(__FILE__) + '/common')
describe "sections" do
it_should_behave_like "in-process server selenium tests"
it "should only show users enrolled in the section on the section page" do
course_with_teacher_logged_in(:active_course=> true, :active_user => true)
@section = @course.course_sections.create!
e2 = student_in_course(:active_all => true, :name => "Señor Chang")
e2.course_section = @section
e2.save!
get "/courses/#{@course.id}/sections/#{@section.id}"
wait_for_ajaximations
ff("#current-enrollment-list .user").count.should eql 1
f("#enrollment_#{e2.id}").should include_text e2.user.name
get "/courses/#{@course.id}/sections/#{@course.default_section.id}"
wait_for_ajaximations
ff("#current-enrollment-list .user").count.should eql 1
f("#enrollment_#{@teacher.enrollments.first.id}").should include_text @teacher.name
end
end

View File

@ -22,43 +22,43 @@ describe "student interactions report" do
it "should have sortable columns, except the email header" do
ths = ff(".report th")
ths[0].attribute('class').should match(/header/)
ths[1].attribute('class').should match(/header/)
ths[2].attribute('class').should match(/header/)
ths[3].attribute('class').should match(/header/)
ths[4].attribute('class').should match(/header/)
ths[5].attribute('class').should_not match(/header/)
ths[0].should have_class("header")
ths[1].should have_class("header")
ths[2].should have_class("header")
ths[3].should have_class("header")
ths[4].should have_class("header")
ths[5].should_not have_class("header")
end
it "should allow sorting by columns" do
ths = ff(".report th")
trs = ff(".report tbody tr")
ths[0].click
ths[0].attribute('class').should match(/headerSortDown/)
ths[0].should have_class("headerSortDown")
ff(".report tbody tr").should == [trs[0], trs[1]]
ths[0].click
ths[0].attribute('class').should match(/headerSortUp/)
ths[0].should have_class("headerSortUp")
ff(".report tbody tr").should == [trs[1], trs[0]]
ths[2].click
ths[2].attribute('class').should match(/headerSortDown/)
ths[2].should have_class("headerSortDown")
ff(".report tbody tr").should == [trs[0], trs[1]]
ths[2].click
ths[2].attribute('class').should match(/headerSortUp/)
ths[2].should have_class("headerSortUp")
ff(".report tbody tr").should == [trs[1], trs[0]]
ths[3].click
ths[3].attribute('class').should match(/headerSortDown/)
ths[3].should have_class("headerSortDown")
ff(".report tbody tr").should == [trs[0], trs[1]]
ths[3].click
ths[3].attribute('class').should match(/headerSortUp/)
ths[3].should have_class("headerSortUp")
ff(".report tbody tr").should == [trs[1], trs[0]]
ths[5].click
ths[5].attribute('class').should_not match(/header/)
ths[5].should_not have_class("header")
end
end
end

View File

@ -0,0 +1,84 @@
require File.expand_path(File.dirname(__FILE__) + '/helpers/quizzes_common')
describe "quizzes" do
it_should_behave_like "quizzes selenium tests"
context "as a student" do
before (:each) do
course_with_student_logged_in
@qsub = quiz_with_submission(false)
end
context "resume functionality" do
def update_quiz_lock(lock_at, unlock_at)
@quiz.update_attributes(:lock_at => lock_at, :unlock_at => unlock_at)
@quiz.reload
@quiz.save!
end
describe "on main page" do
def validate_description_text(does_contain_text, text)
description = f('.description')
if does_contain_text
description.should include_text(text)
else
description.should_not include_text(text)
end
end
it "should show the resume quiz link if quiz is unlocked" do
get "/courses/#{@course.id}/quizzes"
f('.description').should include_text('Resume Quiz')
end
it "should show the resume quiz link if quiz unlock_at date is < now" do
update_quiz_lock(Time.now - 1.day.ago, Time.now - 10.minutes.ago)
get "/courses/#{@course.id}/quizzes"
f('.description').should include_text('Resume Quiz')
end
it "should not show the resume link if the quiz is locked" do
update_quiz_lock(Time.now - 5.minutes, nil)
get "/courses/#{@course.id}/quizzes"
f('.description').should_not include_text('Resume Quiz')
end
it "should grade any submission that needs grading" do
@qsub.end_at = Time.now - 5.minutes
@qsub.save!
get "/courses/#{@course.id}/quizzes"
f('.description').should_not include_text('Resume Quiz')
f('.description').should include_text('0 out of')
end
end
describe "on individual quiz page" do
RESUME_TEXT = 'Resume Quiz'
def validate_resume_button_text(text)
f('#right-side .button').text.should == text
end
it "should show the resume quiz button if the quiz is unlocked" do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}"
validate_resume_button_text(RESUME_TEXT)
end
it "should show the resume quiz button if the quiz unlock_at date is < now" do
update_quiz_lock(Time.now - 1.day.ago, Time.now - 10.minutes.ago)
get "/courses/#{@course.id}/quizzes/#{@quiz.id}"
validate_resume_button_text(RESUME_TEXT)
end
it "should not show the resume quiz button if quiz is locked" do
update_quiz_lock(Time.now - 5.minutes, nil)
get "/courses/#{@course.id}/quizzes/#{@quiz.id}"
right_side = f('#right-side')
right_side.should_not include_text("You're in the middle of taking this quiz.")
right_side.should_not include_text(RESUME_TEXT)
end
end
end
end
end

View File

@ -0,0 +1,102 @@
require File.expand_path(File.dirname(__FILE__) + '/common')
require File.expand_path(File.dirname(__FILE__) + '/helpers/calendar2_common')
require File.expand_path(File.dirname(__FILE__) + '/helpers/scheduler_common')
describe "scheduler" do
it_should_behave_like "calendar2 selenium tests"
it_should_behave_like "scheduler selenium tests"
context "as a student" do
before (:each) do
course_with_student_logged_in
end
def reserve_appointment_manual(n)
ff('.fc-event')[n].click
f('.event-details .reserve_event_link').click
wait_for_ajax_requests
end
it "should let me reserve appointment groups for contexts I am in" do
my_course = @course
course_with_student(:active_all => true)
other_course = @course
create_appointment_group(:contexts => [other_course, my_course])
get "/calendar2"
click_scheduler_link
wait_for_ajaximations
click_appointment_link
reserve_appointment_manual(0)
f('.fc-event').should include_text "Reserved"
end
it "should allow me to cancel existing reservation and sign up for the appointment group from the calendar" do
tomorrow = (Date.today + 1).to_s
create_appointment_group(:max_appointments_per_participant => 1,
:new_appointments => [
[tomorrow + ' 12:00:00', current_date = tomorrow + ' 13:00:00'],
[tomorrow + ' 14:00:00', current_date = tomorrow + ' 15:00:00'],
])
get "/calendar2"
wait_for_ajaximations
click_scheduler_link
click_appointment_link
reserve_appointment_manual(0)
f('.fc-event').should include_text "Reserved"
# try to reserve the second appointment
reserve_appointment_manual(1)
fj('.ui-button:contains(Reschedule)').click
wait_for_ajax_requests
event1, event2 = ff('.fc-event')
event1.should include_text "Available"
event2.should include_text "Reserved"
end
it "should not let me book too many appointments" do
tomorrow = (Date.today + 1).to_s
create_appointment_group(:max_appointments_per_participant => 2,
:new_appointments => [
[tomorrow + ' 12:00:00', current_date = tomorrow + ' 13:00:00'],
[tomorrow + ' 14:00:00', current_date = tomorrow + ' 15:00:00'],
[tomorrow + ' 16:00:00', current_date = tomorrow + ' 17:00:00'],
])
get "/calendar2"
wait_for_ajaximations
click_scheduler_link
click_appointment_link
reserve_appointment_manual(0)
reserve_appointment_manual(1)
e1, e2, *rest = ff('.fc-event')
e1.should include_text "Reserved"
e2.should include_text "Reserved"
reserve_appointment_manual(2)
fj('.ui-button:contains("OK")').click # "can't reserve" dialog
f('.fc-event:nth-child(3)').should include_text "Available"
end
it "should not allow me to cancel reservations from the attendees list" do
create_appointment_group
ag = AppointmentGroup.first
ag.appointments.first.reserve_for(@user, @user)
get "/calendar2"
wait_for_ajaximations
click_scheduler_link
wait_for_ajaximations
click_appointment_link
fj('.fc-event:visible').click
ff('#reservations').size.should be_zero
end
end
end

View File

@ -1,136 +1,16 @@
require File.expand_path(File.dirname(__FILE__) + '/common')
require File.expand_path(File.dirname(__FILE__) + '/helpers/files_common')
require File.expand_path(File.dirname(__FILE__) + '/helpers/submissions_common')
describe "submissions" do
it_should_behave_like "in-process server selenium tests"
def create_assignment(type = 'online_text_entry')
assignment = @course.assignments.build({
:name => 'media assignment',
:submission_types => type
})
assignment.workflow_state = 'published'
assignment.save!
assignment
end
def create_assignment_and_go_to_page(type = 'online_text_entry')
assignment = create_assignment type
get "/courses/#{@course.id}/assignments/#{assignment.id}"
assignment
end
def open_media_comment_dialog
f('.media_comment_link').click
# swf and stuff loads, give it a sec to do its thing
sleep 0.5
end
def submit_media_comment_1
open_media_comment_dialog
# pretend like we are flash sending data to the JS
driver.execute_script <<-JS
var entries1 = [{"duration":1.664,"thumbnailUrl":"http://www.instructuremedia.com/p/100/sp/10000/thumbnail/entry_id/0_jd6ger47/version/0","numComments":-1,"status":1,"rank":-1,"userScreenName":"_100_1_1","displayCredit":"_100_1_1","partnerLandingPage":null,"dataUrl":"http://www.instructuremedia.com/p/100/sp/10000/flvclipper/entry_id/0_jd6ger47/version/100000","sourceLink":"","subpId":10000,"puserId":"1_1","views":0,"height":0,"description":null,"hasThumbnail":false,"width":0,"kshowId":"0_pb7id2lf","kuserId":"","userLandingPage":"","mediaType":2,"plays":0,"partnerId":100,"adminTags":"","entryVersion":"","downloadUrl":"http://www.instructuremedia.com/p/100/sp/10000/raw/entry_id/0_jd6ger47/version/100000","createdAtDate":"1970-01-16T09:24:02.931Z","votes":-1,"uploaderName":null,"tags":"","entryName":"ryanf@instructure.com 2012-02-21T16:48:37.729Z","entryType":1,"entryId":"0_jd6ger47","createdAtAsInt":1329842931,"uid":"E78A81CC-D03D-CD10-B449-A0D0D172EF38"}]
addEntryComplete(entries1);
JS
wait_for_ajax_requests
end
def submit_media_comment_2
open_media_comment_dialog
driver.execute_script <<-JS
var entries2 = [{"duration":1.829,"thumbnailUrl":"http://www.instructuremedia.com/p/100/sp/10000/thumbnail/entry_id/0_5hcd9mro/version/0","numComments":-1,"status":1,"rank":-1,"userScreenName":"_100_1_1","displayCredit":"_100_1_1","partnerLandingPage":null,"dataUrl":"http://www.instructuremedia.com/p/100/sp/10000/flvclipper/entry_id/0_5hcd9mro/version/100000","sourceLink":"","subpId":10000,"puserId":"1_1","views":0,"height":0,"description":null,"hasThumbnail":false,"width":0,"kshowId":"0_pb7id2lf","kuserId":"","userLandingPage":"","mediaType":2,"plays":0,"partnerId":100,"adminTags":"","entryVersion":"","downloadUrl":"http://www.instructuremedia.com/p/100/sp/10000/raw/entry_id/0_5hcd9mro/version/100000","createdAtDate":"1970-01-16T09:24:03.563Z","votes":-1,"uploaderName":null,"tags":"","entryName":"ryanf@instructure.com 2012-02-21T16:59:11.249Z","entryType":1,"entryId":"0_5hcd9mro","createdAtAsInt":1329843563,"uid":"22A2C625-5FAB-AF3A-1A76-A0DA7572BFE4"}]
addEntryComplete(entries2);
JS
wait_for_ajax_requests
end
context 'as a teacher' do
before (:each) do
course_with_teacher_logged_in
end
it "should allow media comments" do
stub_kaltura
student_in_course
assignment = create_assignment
assignment.submissions.create(:user => @student)
get "/courses/#{@course.id}/assignments/#{assignment.id}/submissions/#{@student.id}"
# make sure the JS didn't burn any bridges, and submit two
submit_media_comment_1
submit_media_comment_2
# check that the thumbnails show up on the right sidebar
number_of_comments = driver.execute_script "return $('.comment_list').children().length"
number_of_comments.should == 2
end
it "should display the grade in grade field" do
student_in_course
assignment = create_assignment
assignment.submissions.create(:user => @student)
assignment.grade_student @student, :grade => 2
get "/courses/#{@course.id}/assignments/#{assignment.id}/submissions/#{@student.id}"
f('.grading_value')[:value].should == '2'
end
end
context "student view" do
before (:each) do
course_with_teacher_logged_in
end
it "should allow a student view student to view/submit assignments" do
@assignment = @course.assignments.create(
:title => 'Cool Assignment',
:points_possible => 10,
:submission_types => "online_text_entry",
:due_at => Time.now.utc + 2.days)
enter_student_view
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
f('.assignment .title').should include_text @assignment.title
f('.submit_assignment_link').click
assignment_form = f('#submit_online_text_entry_form')
wait_for_tiny(assignment_form)
type_in_tiny('#submission_body', 'my assigment submission')
expect_new_page_load { submit_form(assignment_form) }
@course.student_view_student.submissions.count.should == 1
f('#sidebar_content .details').should include_text "Turned In!"
end
it "should allow a student view student to submit file upload assignments" do
@assignment = @course.assignments.create(
:title => 'Cool Assignment',
:points_possible => 10,
:submission_types => "online_upload",
:due_at => Time.now.utc + 2.days)
enter_student_view
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
f('.submit_assignment_link').click
filename, fullpath, data = get_file("testfile1.txt")
f('.submission_attachment input').send_keys(fullpath)
expect_new_page_load { f('#submit_file_button').click }
keep_trying_until do
f('.details .header').should include_text "Turned In!"
f('.details .file-big').should include_text "testfile1"
end
end
end
it_should_behave_like "submissions selenium tests"
context 'as a student' do
DUE_DATE = Time.now.utc + 2.days
before (:each) do
before(:each) do
course_with_student_logged_in
@assignment = @course.assignments.create!(:title => 'assignment 1', :name => 'assignment 1', :due_at => DUE_DATE)
@second_assignment = @course.assignments.create!(:title => 'assignment 2', :name => 'assignment 2', :due_at => nil)
@ -140,7 +20,7 @@ describe "submissions" do
it "should not break when you open and close the media comment dialog" do
stub_kaltura
create_assignment_and_go_to_page 'media_recording'
create_assignment_and_go_to_page('media_recording')
f(".submit_assignment_link").click
open_button = f(".record_media_comment_link")
@ -155,7 +35,7 @@ describe "submissions" do
close_visible_dialog
# fire the callback that the flash object fires
driver.execute_script "window.mediaCommentCallback([{entryId:1, entryType:1}]);"
driver.execute_script("window.mediaCommentCallback([{entryId:1, entryType:1}]);")
# see if the confirmation element shows up
f('#media_media_recording_ready').should be_displayed
@ -326,40 +206,40 @@ describe "submissions" do
tooltip_text_elements[1].text.should == 'submitted'
end
end
end
describe 'uploaded files for submission' do
it_should_behave_like "forked server selenium tests"
it_should_behave_like "files selenium shared"
describe 'uploaded files for submission' do
it_should_behave_like "forked server selenium tests"
it_should_behave_like "files selenium shared"
it "should allow uploaded files to be used for submission" do
it "should allow uploaded files to be used for submission" do
Setting.set("file_storage_test_override", "local")
user_with_pseudonym :username => "nobody2@example.com",
:password => "asdfasdf2"
course_with_student_logged_in :user => @user
login "nobody2@example.com", "asdfasdf2"
add_file(fixture_file_upload('files/html-editing-test.html', 'text/html'),
@user, "html-editing-test.html")
File.read(fixture_file_path("files/html-editing-test.html"))
assignment = @course.assignments.create!(:title => 'assignment 1',
:name => 'assignment 1',
:submission_types => "online_upload")
get "/courses/#{@course.id}/assignments/#{assignment.id}"
f('.submit_assignment_link').click
f('.toggle_uploaded_files_link').click
Setting.set("file_storage_test_override", "local")
user_with_pseudonym :username => "nobody2@example.com",
:password => "asdfasdf2"
course_with_student_logged_in :user => @user
login "nobody2@example.com", "asdfasdf2"
add_file(fixture_file_upload('files/html-editing-test.html', 'text/html'),
@user, "html-editing-test.html")
File.read(fixture_file_path("files/html-editing-test.html"))
assignment = @course.assignments.create!(:title => 'assignment 1',
:name => 'assignment 1',
:submission_types => "online_upload")
get "/courses/#{@course.id}/assignments/#{assignment.id}"
f('.submit_assignment_link').click
f('.toggle_uploaded_files_link').click
# traverse the tree
f('#uploaded_files > ul > li.folder > .sign').click
wait_for_animations
f('#uploaded_files > ul > li.folder .file .name').click
wait_for_animations
# traverse the tree
f('#uploaded_files > ul > li.folder > .sign').click
wait_for_animations
f('#uploaded_files > ul > li.folder .file .name').click
wait_for_animations
expect_new_page_load { f('#submit_file_button').click }
expect_new_page_load { f('#submit_file_button').click }
keep_trying_until do
f('.details .header').should include_text "Turned In!"
f('.details .file-big').should include_text "html-editing-test.html"
keep_trying_until do
f('.details .header').should include_text "Turned In!"
f('.details .file-big').should include_text "html-editing-test.html"
end
end
end
end

View File

@ -0,0 +1,273 @@
require File.expand_path(File.dirname(__FILE__) + '/helpers/quizzes_common')
describe "quizzes questions" do
it_should_behave_like "quizzes selenium tests"
before (:each) do
course_with_teacher_logged_in
end
context "as a teacher" do
it "should edit a quiz question" do
@context = @course
q = quiz_model
quest1 = q.quiz_questions.create!(:question_data => {:name => "first question"})
q.generate_quiz_data
q.save!
get "/courses/#{@course.id}/quizzes/#{q.id}/edit"
wait_for_ajax_requests
hover_and_click(".edit_question_link")
wait_for_animations
question = fj(".question_form:visible")
click_option('.question_form:visible .question_type', 'Multiple Choice')
replace_content(question.find_element(:css, 'input[name="question_name"]'), 'edited question')
answers = question.find_elements(:css, ".form_answers > .answer")
answers.length.should == 2
question.find_element(:css, ".add_answer_link").click
question.find_element(:css, ".add_answer_link").click
answers = question.find_elements(:css, ".form_answers > .answer")
answers.length.should == 4
driver.action.move_to(answers[3]).perform
answers[3].find_element(:css, ".delete_answer_link").click
answers = question.find_elements(:css, ".form_answers > div.answer")
answers.length.should == 3
# check that the wiki sidebar shows up
f('#quiz_options_holder .link_to_content_link').click
f('#editor_tabs h4').should include_text("Insert Content into the Page")
f('#quiz_content_links .quiz_options_link').click
submit_form(question)
question = f("#question_#{quest1.id}")
question.find_element(:css, ".question_name").text.should == 'edited question'
f('#show_question_details').click
question.find_elements(:css, '.answers .answer').length.should == 3
end
it "should not show 'Missing Word' option in question types dropdown" do
get "/courses/#{@course.id}/quizzes/new"
ff("#question_form_template option.missing_word").length.should == 1
keep_trying_until {
f(".add_question .add_question_link").click
ff("#questions .question_holder").length > 0
}
ff("#questions .question_holder option.missing_word").length.should == 0
end
it "should reorder questions with drag and drop" do
quiz_with_new_questions
# ensure they are in the right order
names = ff('.question_name')
names[0].text.should == 'first question'
names[1].text.should == 'second question'
load_simulate_js
# drag the second question up 100px (next slot)
driver.execute_script <<-JS
$('.move_icon:eq(1)').show().simulate('drag', {dx: 0, dy: -100});
JS
# verify they were swapped
names = ff('.question_name')
names[0].text.should == 'second question'
names[1].text.should == 'first question'
end
it "should not show the display details for text questions" do
quiz = start_quiz_question
question = fj(".question_form:visible")
click_option('.question_form:visible .question_type', 'Text (no question)')
submit_form(question)
wait_for_ajax_requests
quiz.reload
show_el = f('#show_question_details')
show_el.should_not be_displayed
end
it "should not show the display details for essay questions" do
quiz = start_quiz_question
question = fj(".question_form:visible")
click_option('.question_form:visible .question_type', 'Essay Question')
submit_form(question)
wait_for_ajax_requests
quiz.reload
show_el = f('#show_question_details')
show_el.should_not be_displayed
end
it "should show the display details when questions other than text or essay questions exist" do
quiz = start_quiz_question
show_el = f('#show_question_details')
question = fj(".question_form:visible")
show_el.should_not be_displayed
click_option('.question_form:visible .question_type', 'Multiple Choice')
submit_form(question)
wait_for_ajax_requests
quiz.reload
show_el.should be_displayed
end
it "should calculate correct quiz question points total" do
get "/courses/#{@course.id}/quizzes"
expect_new_page_load { f('.new-quiz-link').click }
@question_count = 0
@points_total = 0
add_quiz_question('1')
add_quiz_question('2')
add_quiz_question('3')
add_quiz_question('4')
submit_form('#quiz_options_form')
wait_for_ajax_requests
quiz = Quiz.last
quiz.reload
quiz.quiz_questions.length.should == @question_count
end
it "should round published quiz points correctly on main quiz page" do
pending("bug 7402 - Quiz points not rounding correctly") do
q = @course.quizzes.create!(:title => "new quiz")
75.times do
q.quiz_questions.create!(:question_data => {:name => "Quiz Question 1", :question_type => 'essay_question', :question_text => 'qq1', 'answers' => [], :points_possible => 1.33})
end
q.generate_quiz_data
q.workflow_state = 'available'
q.save
q.reload
get "/courses/#{@course.id}/quizzes/#{Quiz.last.id}"
fj('.summary td:eq(2)').text.should == "99.75%"
end
end
it "should round numeric questions the same when created and taking a quiz" do
start_quiz_question
question = fj(".question_form:visible")
click_option('.question_form:visible .question_type', 'Numerical Answer')
type_in_tiny '.question:visible textarea.question_content', 'This is a numerical question.'
answers = question.find_elements(:css, ".form_answers > .answer")
answers[0].find_element(:name, 'answer_exact').send_keys('0.000675')
driver.execute_script <<-JS
$('input[name=answer_exact]').trigger('change');
JS
answers[0].find_element(:name, 'answer_error_margin').send_keys('0')
submit_form(question)
wait_for_ajax_requests
expect_new_page_load {
f('.publish_quiz_button').click
}
expect_new_page_load {
driver.find_element(:link, 'Take the Quiz').click
}
input = f('input[type=text]')
input.click
input.send_keys('0.000675')
driver.execute_script <<-JS
$('input[type=text]').trigger('change');
JS
expect_new_page_load {
submit_form('#submit_quiz_form')
}
f('.score_value').text.strip.should == '1'
end
end
context "select element behavior" do
before (:each) do
@context = @course
bank = @course.assessment_question_banks.create!(:title => 'Test Bank')
q = quiz_model
b = bank.assessment_questions.create!
quest2 = q.quiz_questions.create!(:assessment_question => b)
quest2.write_attribute(:question_data,
{
:neutral_comments => "",
:question_text => "<p>My hair is [x] and my wife's is [y].</p>",
:points_possible => 1, :question_type => "multiple_dropdowns_question",
:answers =>
[{
:comments => "",
:weight => 100,
:blank_id => "x",
:text => "brown",
:id => 2624
},
{
:comments => "",
:weight => 0,
:blank_id => "x",
:text => "black",
:id => 3085
},
{
:comments => "",
:weight => 100,
:blank_id => "y",
:text => "brown",
:id => 5780
},
{
:comments => "",
:weight => 0,
:blank_id => "y",
:text => "red",
:id => 8840
}],
:correct_comments => "",
:name => "Question",
:question_name => "Question",
:incorrect_comments => "",
:assessment_question_id => nil
})
q.generate_quiz_data
q.save!
get "/courses/#{@course.id}/quizzes/#{q.id}/edit"
f('.publish_quiz_button')
get "/courses/#{@course.id}/quizzes/#{q.id}/take?user_id=#{@user.id}"
driver.find_element(:link, 'Take the Quiz').click
wait_for_ajax_requests
end
after do
#This step is to prevent selenium from freezing when the dialog appears when leaving the page
keep_trying_until do
f('#left-side .quizzes').click
confirm_dialog = driver.switch_to.alert
confirm_dialog.accept
true
end
end
it "should selectmenu-ify select elements" do
select = f('.question select')
keep_trying_until { fj('.question_select:visible').should be_nil }
f('.ui-selectmenu').click
ff('.ui-selectmenu-open li')[1].click
select[:selectedIndex].should == "1"
end
end
end

View File

@ -102,32 +102,32 @@ describe "quizzes" do
q.save!
# add a student to the course
student = student_in_course(:active_enrollment => true).user
student.conversations.size.should eql(0)
student.conversations.size.should == 0
get "/courses/#{@course.id}/quizzes/#{q.id}"
driver.find_element(:partial_link_text, "Message Students Who...").click
dialog = ffj("#message_students_dialog:visible")
dialog.length.should eql(1)
dialog.length.should == 1
dialog = dialog.first
click_option('.message_types', 'Have taken the quiz')
students = ffj(".student_list > .student:visible")
students.length.should eql(0)
students.length.should == 0
click_option('.message_types', 'Have NOT taken the quiz')
students = ffj(".student_list > .student:visible")
students.length.should eql(1)
students.length.should == 1
dialog.find_element(:css, 'textarea#body').send_keys('This is a test message.')
button = dialog.find_element(:css, "button.send_button")
button.click
keep_trying_until { button.text != "Sending Message..." }
button.text.should eql("Message Sent!")
button.text.should == "Message Sent!"
student.conversations.size.should eql(1)
student.conversations.size.should == 1
end
it "should not duplicate unpublished quizzes each time you open the publish multiple quizzes dialog" do
@ -192,7 +192,7 @@ describe "quizzes" do
pick_count.call('1001')
dismiss_alert
pick_count_field[:value].should eql "1"
pick_count_field.should have_attribute(:value, "1")
f('.add_question_link').click # 1 total, ok
group_form.find_element(:css, '.edit_group_link').click
@ -203,7 +203,7 @@ describe "quizzes" do
pick_count.call('1000') # 1001 total, bad
dismiss_alert
pick_count_field[:value].should eql "999"
pick_count_field.should have_attribute(:value, "999")
end
it "should moderate quiz" do
@ -284,7 +284,7 @@ describe "quizzes" do
input.send_keys('1')
error_displayed?.should be_false
input.send_keys(:tab)
input[:value].should eql "1.0000"
input.should have_attribute(:value, "1.0000")
end
end
@ -306,8 +306,8 @@ describe "quizzes" do
f('#tinymce').send_keys :shift # no content, but it gives the iframe focus
end
wait_for_ajax_requests
ff('#question_list .answered').size.should eql 1
input[:value].should eql "1.0000"
ff('#question_list .answered').size.should == 1
input.should have_attribute(:value, "1.0000")
end
end
@ -327,7 +327,7 @@ describe "quizzes" do
take_quiz do
dropdowns = ff('a.ui-selectmenu.question_input')
dropdowns.size.should eql 6
dropdowns.size.should == 6
# partially answer each question
[dropdowns.first, dropdowns.last].each do |d|
@ -344,7 +344,7 @@ describe "quizzes" do
end
# marked as answer
ff('#question_list .answered').size.should eql 2
ff('#question_list .answered').size.should == 2
wait_for_ajaximations
driver.find_element(:link, 'Quizzes').click
@ -357,11 +357,11 @@ describe "quizzes" do
# be ready right when the page loads
keep_trying_until {
dropdowns = ff('a.ui-selectmenu.question_input')
dropdowns.size.should eql 6
dropdowns.size.should == 6
}
dropdowns.map(&:text).should eql %w{orange green east east east east}
ff('#question_list .answered').size.should eql 2
dropdowns.map(&:text).should == %w{orange green east east east east}
ff('#question_list .answered').size.should == 2
end
end
@ -469,83 +469,5 @@ describe "quizzes" do
f('#content .question_name').should include_text("Question 1")
end
end
context "as a student" do
before (:each) do
course_with_student_logged_in
@qsub = quiz_with_submission(false)
end
context "resume functionality" do
def update_quiz_lock(lock_at, unlock_at)
@quiz.update_attributes(:lock_at => lock_at, :unlock_at => unlock_at)
@quiz.reload
@quiz.save!
end
describe "on main page" do
def validate_description_text(does_contain_text, text)
description = f('.description')
if does_contain_text
description.should include_text(text)
else
description.should_not include_text(text)
end
end
it "should show the resume quiz link if quiz is unlocked" do
get "/courses/#{@course.id}/quizzes"
f('.description').should include_text('Resume Quiz')
end
it "should show the resume quiz link if quiz unlock_at date is < now" do
update_quiz_lock(Time.now - 1.day.ago, Time.now - 10.minutes.ago)
get "/courses/#{@course.id}/quizzes"
f('.description').should include_text('Resume Quiz')
end
it "should not show the resume link if the quiz is locked" do
update_quiz_lock(Time.now - 5.minutes, nil)
get "/courses/#{@course.id}/quizzes"
f('.description').should_not include_text('Resume Quiz')
end
it "should grade any submission that needs grading" do
@qsub.end_at = Time.now - 5.minutes
@qsub.save!
get "/courses/#{@course.id}/quizzes"
f('.description').should_not include_text('Resume Quiz')
f('.description').should include_text('0 out of')
end
end
describe "on individual quiz page" do
RESUME_TEXT = 'Resume Quiz'
def validate_resume_button_text(text)
f('#right-side .button').text.should == text
end
it "should show the resume quiz button if the quiz is unlocked" do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}"
validate_resume_button_text(RESUME_TEXT)
end
it "should show the resume quiz button if the quiz unlock_at date is < now" do
update_quiz_lock(Time.now - 1.day.ago, Time.now - 10.minutes.ago)
get "/courses/#{@course.id}/quizzes/#{@quiz.id}"
validate_resume_button_text(RESUME_TEXT)
end
it "should not show the resume quiz button if quiz is locked" do
update_quiz_lock(Time.now - 5.minutes, nil)
get "/courses/#{@course.id}/quizzes/#{@quiz.id}"
right_side = f('#right-side')
right_side.should_not include_text("You're in the middle of taking this quiz.")
right_side.should_not include_text(RESUME_TEXT)
end
end
end
end
end

View File

@ -0,0 +1,99 @@
require File.expand_path(File.dirname(__FILE__) + '/helpers/quizzes_common')
describe "quiz statistics" do
it_should_behave_like "quizzes selenium tests"
context "as a teacher" do
def update_quiz_submission_scores(question_score = '1')
@quiz_submission.update_scores({
'context_id' => @course.id,
'override_scores' => true,
'context_type' => 'Course',
'submission_version_number' => '1',
"question_score_#{@questions[0].id}" => question_score
})
end
def summary_rows
ff('#statistics_summary tr')
end
before (:each) do
quiz_with_graded_submission([{:question_data => {:name => 'question 1', :points_possible => 1, 'question_type' => 'true_false_question'}},
{:question_data => {:name => 'question 2', :points_possible => 1, 'question_type' => 'true_false_question'}}])
course_with_teacher_logged_in(:active_all => true, :course => @course)
end
describe "question graphs" do
it "should validate correct number of questions are showing up" do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
ff('.question').count.should == @quiz.quiz_questions.count
end
it "should validate number attempts on questions" do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
ff('.question .question_attempts').each { |attempt| attempt.text.should == '1 attempt' }
end
it "should validate question graph tooltip" do
update_quiz_submission_scores
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
(0..2).each do |i|
driver.execute_script("$('.tooltip_text:eq(#{i})').css('visibility', 'visible')")
if i == 0 || i == 1
fj(".tooltip_text:eq(#{i})").should include_text '0%'
else
fj(".tooltip_text:eq(#{i})").should include_text '100%'
end
end
end
end
describe "right side info bar with initial data" do
before (:each) do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
end
it "should validate average time taken for quiz" do
summary_rows[0].should include_text 'less than a minute'
end
%w(correct incorrect high_score low_score mean_score standard_deviation).each_with_index do |data_point, i|
it "should validate #{data_point} number for initial info" do
index = (i + 1) # + 1 to get rid of the first row
index == 2 ? (summary_rows[index].should include_text("2")) : (summary_rows[index].should include_text("0"))
end
end
end
describe 'right side info bar with altered data' do
before (:each) do
update_quiz_submission_scores
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/statistics"
@expected_side_bar_numbers = ["0", "2", "1"]
end
%w(correct incorrect high_score low_score mean_score standard_deviation).each_with_index do |data_point, i|
it "should validate #{data_point} number for altered info" do
index = (i + 1) # + 1 to get rid of the first row
case index
when 1
summary_rows[index].should include_text(@expected_side_bar_numbers[0])
when 2
summary_rows[index].should include_text(@expected_side_bar_numbers[1])
when 3..5
summary_rows[index].should include_text(@expected_side_bar_numbers[2])
when 6
summary_rows[index].should include_text(@expected_side_bar_numbers[0])
end
end
end
end
end
end

View File

@ -0,0 +1,37 @@
require File.expand_path(File.dirname(__FILE__) + '/helpers/quizzes_common')
describe "quizzes students" do
it_should_behave_like "quizzes selenium tests"
context "as a teacher " do
it "should allow a student view student to take a quiz" do
course_with_teacher_logged_in
quiz = @course.quizzes.create!(:title => "new quiz")
quiz.quiz_questions.create!(:question_data => {
:name => 'test 3',
:question_type => 'multiple_choice_question',
:answers => {'answer_0' => {'answer_text' => '0'}, 'answer_1' => {'answer_text' => '1'}}})
quiz.generate_quiz_data
quiz.workflow_state = 'available'
quiz.save
@fake_student = @course.student_view_student
enter_student_view
get "/courses/#{@course.id}/quizzes/#{quiz.id}"
f("#take_quiz_link").click
wait_for_ajaximations
q = quiz.stored_questions[0]
f("#question_#{q[:id]}_answer_#{q[:answers][0][:id]}").click
submit_form('#submit_quiz_form')
quiz_sub = @fake_student.reload.submissions.find_by_assignment_id(quiz.assignment.id)
quiz_sub.should be_present
quiz_sub.workflow_state.should == "graded"
end
end
end

View File

@ -0,0 +1,112 @@
require File.expand_path(File.dirname(__FILE__) + '/helpers/rubrics_specs')
describe "shared rubric specs" do
let(:rubric_url) { "/courses/#{@course.id}/rubrics" }
let(:who_to_login) { 'teacher' }
it_should_behave_like "rubric tests"
end
describe "course rubrics" do
it_should_behave_like "in-process server selenium tests"
context "as a teacher" do
it "should display free-form comments to the student" do
assignment_model
rubric_model(:context => @course, :free_form_criterion_comments => true)
course_with_student(:course => @course, :active_all => true)
@association = @rubric.associate_with(@assignment, @course, :purpose => 'grading', :use_for_grading => true)
comment = "Hi, please see www.example.com.\n\nThanks."
@assessment = @association.assess({
:user => @student,
:assessor => @teacher,
:artifact => @assignment.find_or_create_submission(@student),
:assessment => {
:assessment_type => 'grading',
:criterion_crit1 => {
:points => 5,
:comments => comment,
}
}
})
user_logged_in(:user => @student)
get "/courses/#{@course.id}/grades"
f('.toggle_rubric_assessments_link').click
wait_for_animations
f('.rubric .criterion .custom_rating_comments').text.should == comment
f('.rubric .criterion .custom_rating_comments a').should have_attribute('href', 'http://www.example.com/')
get "/courses/#{@course.id}/assignments/#{@assignment.id}/submissions/#{@student.id}"
f('.assess_submission_link').click
wait_for_animations
f('.rubric .criterion .custom_rating_comments').text.should == comment
f('.rubric .criterion .custom_rating_comments a').should have_attribute('href', 'http://www.example.com/')
end
it "should ignore outcome rubric lines when calculating total" do
course_with_teacher_logged_in
outcome_with_rubric
@assignment = @course.assignments.create(:name => 'assignment with rubric')
@association = @rubric.associate_with(@assignment, @course, :use_for_grading => true, :purpose => 'grading')
@rubric.data[0][:ignore_for_scoring] = '1'
@rubric.points_possible = 5
@rubric.instance_variable_set('@outcomes_changed', true)
@rubric.save!
get "/courses/#{@course.id}/rubrics/#{@rubric.id}"
f('.rubric_total').should include_text "5"
f('.edit_rubric_link').click
criterion_points = fj(".criterion_points:visible")
replace_content(criterion_points, "10")
criterion_points.send_keys(:return)
submit_form("#edit_rubric_form")
wait_for_ajaximations
fj('.rubric_total').should include_text "10"
# check again after reload
refresh_page
fj('.rubric_total').should include_text "10" #avoid selenium caching
end
it "should not display the edit form more than once" do
course_with_teacher_logged_in
rubric_association_model(:user => @user, :context => @course, :purpose => "grading")
get "/courses/#{@course.id}/rubrics/#{@rubric.id}"
2.times { |n| f('.edit_rubric_link').click }
ff('.rubric .button-container').length.should == 1
end
context "importing" do
it "should create a allow immediate editing when adding an imported rubric to a new assignment" do
course_with_teacher_logged_in
rubric_association_model(:user => @user, :context => @course, :purpose => "grading")
@old_course = @course
@course = nil
course_with_teacher(:user => @user, :active_all => true)
@course.merge_into_course(@old_course, :everything => true)
@assignment = @course.assignments.create!(assignment_valid_attributes.merge({:title => "New Course Assignment"}))
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
f("#right-side-wrapper .add_rubric_link").click
fj(".find_rubric_link:visible").click
wait_for_ajaximations
fj(".select_rubric_link:visible").click
wait_for_ajaximations
fj(".edit_rubric_link:visible").click
fj(".rubric_custom_rating:visible").click
fj(".save_button:visible").click
wait_for_ajax_requests
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
ffj(".custom_ratings:visible").size.should == 1
end
end
end
end

View File

@ -1,106 +1,10 @@
require File.expand_path(File.dirname(__FILE__) + '/common')
require File.expand_path(File.dirname(__FILE__) + '/helpers/calendar2_common')
EDIT_NAME = 'edited appointment'
EDIT_LOCATION = 'edited location'
require File.expand_path(File.dirname(__FILE__) + '/helpers/scheduler_common')
describe "scheduler" do
it_should_behave_like "calendar2 selenium tests"
def fill_out_appointment_group_form(new_appointment_text, opts = {})
f('.create_link').click
edit_form = f('#edit_appointment_form')
keep_trying_until { edit_form.should be_displayed }
replace_content(fj('input[name="title"]'), new_appointment_text)
f('.ag_contexts_selector').click
f('.ag_sections_toggle').click
if opts[:section_codes]
opts[:section_codes].each { |code| f("[name='sections[]'][value='#{code}']").click }
else
f('[name="context_codes[]"]').click
end
f('.ag_contexts_done').click
if opts[:checkable_options]
if opts[:checkable_options].has_key?(:per_slot_option)
set_value f('[name="per_slot_option"]'), true
end
if opts[:checkable_options].has_key?(:participant_visibility)
set_value f('[name="participant_visibility"]'), true
end
if opts[:checkable_options].has_key?(:max_appointments_per_participant_option)
set_value f('[name="max_appointments_per_participant_option"]'), true
end
end
date_field = edit_form.find_element(:css, '.date_field')
date_field.click
wait_for_animations
fj('.ui-datepicker-trigger:visible').click
datepicker_next
replace_content(edit_form.find_element(:css, '.start_time'), '1')
replace_content(edit_form.find_element(:css, '.end_time'), '3')
end
def submit_appointment_group_form(publish = true)
save, save_and_publish = ff('.ui-dialog-buttonset .ui-button')
if publish
save_and_publish.click
else
save.click
end
wait_for_ajaximations
end
def create_appointment_group_manual(opts = {})
opts = {
:publish => true,
:new_appointment_text => 'new appointment group'
}.with_indifferent_access.merge(opts)
expect {
fill_out_appointment_group_form(opts[:new_appointment_text], opts)
submit_appointment_group_form(opts[:publish])
f('.view_calendar_link').text.should == opts[:new_appointment_text]
}.to change(AppointmentGroup, :count).by(1)
end
def click_scheduler_link
header_buttons = ff('.ui-buttonset > label')
header_buttons[2].click
wait_for_ajaximations
end
def click_appointment_link
f('.view_calendar_link').click
f('.scheduler-mode').should be_displayed
end
def click_al_option(option_selector, offset=0)
ffj('.al-trigger')[offset].click
options = ffj('.al-options')[offset]
options.should be_displayed
options.find_element(:css, option_selector).click
end
def delete_appointment_group
delete_button = fj('.ui-dialog-buttonset .ui-button:contains("Delete")')
delete_button.click
wait_for_ajaximations
end
def edit_appointment_group(appointment_name = EDIT_NAME, location_name = EDIT_LOCATION)
f('#edit_appointment_form').should be_displayed
replace_content(fj('input[name="title"]'), appointment_name)
replace_content(fj('input[name="location"]'), location_name)
f('.ui-dialog-buttonset .ui-button').click
wait_for_ajaximations
f('.view_calendar_link').text.should == appointment_name
f('.ag-location').should include_text(location_name)
end
def open_edit_dialog
driver.action.move_to(f('.appointment-group-item')).perform
click_al_option('.edit_link')
end
it_should_behave_like "scheduler selenium tests"
context "as a teacher" do
@ -111,7 +15,6 @@ describe "scheduler" do
it "should create a new appointment group" do
get "/calendar2"
click_scheduler_link
create_appointment_group_manual
end
@ -284,11 +187,11 @@ describe "scheduler" do
fj('#message_participants_form').should be_nil # using fj to avoid selenium caching
end
end
student1.conversations.first.messages.size.should eql 6 # registered/all * 3
student2.conversations.first.messages.size.should eql 6 # unregistered/all * 2 + registered/all (ug1)
student3.conversations.first.messages.size.should eql 6 # unregistered/all * 3
student4.conversations.first.messages.size.should eql 4 # unregistered/all * 2 (not in any group)
student5.conversations.first.messages.size.should eql 2 # unregistered/all * 1 (doesn't meet any sub_context criteria)
student1.conversations.first.messages.size.should == 6 # registered/all * 3
student2.conversations.first.messages.size.should == 6 # unregistered/all * 2 + registered/all (ug1)
student3.conversations.first.messages.size.should == 6 # unregistered/all * 3
student4.conversations.first.messages.size.should == 4 # unregistered/all * 2 (not in any group)
student5.conversations.first.messages.size.should == 2 # unregistered/all * 1 (doesn't meet any sub_context criteria)
end
it "should validate the appointment group shows up on the calendar" do
@ -355,19 +258,19 @@ describe "scheduler" do
wait_for_ajax_requests
fj('.fc-event:visible').click
ff('#attendees li').size.should eql 2
ff('#attendees li').size.should == 2
# delete the first appointment
fj('.cancel_appointment_link:visible').click
fj('button:visible:contains(Delete)').click
wait_for_ajax_requests
ff('#attendees li').size.should eql 1
ff('#attendees li').size.should == 1
# make sure the appointment was really deleted
f('#refresh_calendar_link').click
wait_for_ajax_requests
fj('.fc-event-time:visible').click
ff('#attendees li').size.should eql 1
ff('#attendees li').size.should == 1
f('.single_item_done_button').click
end
@ -392,8 +295,8 @@ describe "scheduler" do
wait_for_ajaximations
ag = AppointmentGroup.first
ag.appointments.first.participants_per_appointment.should eql 5
ag.participants_per_appointment.should eql 2
ag.appointments.first.participants_per_appointment.should == 5
ag.participants_per_appointment.should == 2
open_edit_event_dialog
f('[name=max_participants_option]').click
@ -432,102 +335,8 @@ describe "scheduler" do
ag = AppointmentGroup.first
ag.contexts.should include course1
ag.contexts.should include @course
ag.sub_contexts.should eql []
ag.sub_contexts.should == []
end
end
context "as a student" do
before (:each) do
course_with_student_logged_in
end
def reserve_appointment_manual(n)
ff('.fc-event')[n].click
f('.event-details .reserve_event_link').click
wait_for_ajax_requests
end
it "should let me reserve appointment groups for contexts I am in" do
my_course = @course
course_with_student(:active_all => true)
other_course = @course
create_appointment_group(:contexts => [other_course, my_course])
get "/calendar2"
click_scheduler_link
wait_for_ajaximations
click_appointment_link
reserve_appointment_manual(0)
f('.fc-event').should include_text "Reserved"
end
it "should allow me to cancel existing reservation and sign up for the appointment group from the calendar" do
tomorrow = (Date.today + 1).to_s
create_appointment_group(:max_appointments_per_participant => 1,
:new_appointments => [
[tomorrow + ' 12:00:00', current_date = tomorrow + ' 13:00:00'],
[tomorrow + ' 14:00:00', current_date = tomorrow + ' 15:00:00'],
])
get "/calendar2"
wait_for_ajaximations
click_scheduler_link
click_appointment_link
reserve_appointment_manual(0)
f('.fc-event').should include_text "Reserved"
# try to reserve the second appointment
reserve_appointment_manual(1)
fj('.ui-button:contains(Reschedule)').click
wait_for_ajax_requests
event1, event2 = ff('.fc-event')
event1.should include_text "Available"
event2.should include_text "Reserved"
end
it "should not let me book too many appointments" do
tomorrow = (Date.today + 1).to_s
create_appointment_group(:max_appointments_per_participant => 2,
:new_appointments => [
[tomorrow + ' 12:00:00', current_date = tomorrow + ' 13:00:00'],
[tomorrow + ' 14:00:00', current_date = tomorrow + ' 15:00:00'],
[tomorrow + ' 16:00:00', current_date = tomorrow + ' 17:00:00'],
])
get "/calendar2"
wait_for_ajaximations
click_scheduler_link
click_appointment_link
reserve_appointment_manual(0)
reserve_appointment_manual(1)
e1, e2, *rest = ff('.fc-event')
e1.should include_text "Reserved"
e2.should include_text "Reserved"
reserve_appointment_manual(2)
fj('.ui-button:contains("OK")').click # "can't reserve" dialog
f('.fc-event:nth-child(3)').should include_text "Available"
end
it "should not allow me to cancel reservations from the attendees list" do
create_appointment_group
ag = AppointmentGroup.first
ag.appointments.first.reserve_for(@user, @user)
get "/calendar2"
wait_for_ajaximations
click_scheduler_link
wait_for_ajaximations
click_appointment_link
fj('.fc-event:visible').click
ff('#reservations').size.should be_zero
end
end
end

View File

@ -0,0 +1,20 @@
require File.expand_path(File.dirname(__FILE__) + '/common')
describe "section tabs on the left side" do
it_should_behave_like "in-process server selenium tests"
context "as a teacher" do
it "should make the active tab white" do
course_with_teacher_logged_in
%w{assignments quizzes settings}.each do |feature|
get "/courses/#{@course.id}/#{feature}"
js = "return $('#section-tabs .#{feature}').css('background-color')"
element_that_is_not_left_side = f('#content')
# make sure to mouse off the link so the :hover and :focus styles do not apply
driver.action.move_to(element_that_is_not_left_side).perform
driver.execute_script(js).should ==('rgb(214, 236, 252)')
end
end
end
end

View File

@ -0,0 +1,29 @@
# coding: utf-8
require File.expand_path(File.dirname(__FILE__) + '/common')
describe "sections" do
it_should_behave_like "in-process server selenium tests"
context "as a teacher" do
it "should only show users enrolled in the section on the section page" do
course_with_teacher_logged_in(:active_course => true, :active_user => true)
@section = @course.course_sections.create!
e2 = student_in_course(:active_all => true, :name => "Señor Chang")
e2.course_section = @section
e2.save!
get "/courses/#{@course.id}/sections/#{@section.id}"
wait_for_ajaximations
ff("#current-enrollment-list .user").count.should == 1
f("#enrollment_#{e2.id}").should include_text e2.user.name
get "/courses/#{@course.id}/sections/#{@course.default_section.id}"
wait_for_ajaximations
ff("#current-enrollment-list .user").count.should == 1
f("#enrollment_#{@teacher.enrollments.first.id}").should include_text @teacher.name
end
end
end

View File

@ -69,7 +69,7 @@ describe "speed grader" do
question_inputs.each { |qi| replace_content(qi, 3) }
submit_form('#update_history_form')
end
keep_trying_until { f('#grade_container input').attribute('value').should == expected_points }
keep_trying_until { f('#grade_container input').should have_attribute('value', expected_points) }
end
it "should properly display student quiz results when the teacher also has a student enrollment" do
@ -285,7 +285,7 @@ describe "speed grader" do
wait_for_animations
f("#avatar_image").should_not be_displayed
f('#combo_box_container .ui-selectmenu .ui-selectmenu-item-header').text.should eql "Student 1"
f('#combo_box_container .ui-selectmenu .ui-selectmenu-item-header').text.should == "Student 1"
f('#comments > .comment').should include_text('ohai')
f("#comments > .comment .avatar").should_not be_displayed
@ -297,7 +297,7 @@ describe "speed grader" do
keep_trying_until { ff('#comments > .comment').size == 2 }
# make sure name and avatar show up for teacher comment
ffj("#comments > .comment .avatar:visible").size.should eql 1
ffj("#comments > .comment .avatar:visible").size.should == 1
ff('#comments > .comment .author_name')[1].should include_text('nobody@example.com')
end
@ -309,8 +309,8 @@ describe "speed grader" do
wait_for_animations
keep_trying_until { ffj('#students_selectmenu option').size > 0 }
ffj('#students_selectmenu option').size.should eql(1) # just the one student
ffj('#section-menu ul li').size.should eql(1) # "Show all sections"
ffj('#students_selectmenu option').size.should == 1 # just the one student
ffj('#section-menu ul li').size.should == 1 # "Show all sections"
fj('#students_selectmenu #section-menu').should be_nil # doesn't get inserted into the menu
end

View File

@ -3,6 +3,8 @@ require File.expand_path(File.dirname(__FILE__) + '/helpers/speed_grader_common'
describe "speed grader submissions" do
it_should_behave_like "speed grader tests"
context "as a teacher" do
it "should display submission of first student and then second student" do
student_submission
@ -99,9 +101,9 @@ describe "speed grader submissions" do
end
it "should handle versions correctly" do
submission1 = student_submission :username => "student1@example.com", :body => 'first student, first version'
submission2 = student_submission :username => "student2@example.com", :body => 'second student'
submission3 = student_submission :username => "student3@example.com", :body => 'third student'
submission1 = student_submission(:username => "student1@example.com", :body => 'first student, first version')
submission2 = student_submission(:username => "student2@example.com", :body => 'second student')
submission3 = student_submission(:username => "student3@example.com", :body => 'third student')
# This is "no submissions" guy
submission3.delete
@ -153,8 +155,8 @@ describe "speed grader submissions" do
end
it "should leave the full rubric open when switching submissions" do
student_submission :username => "student1@example.com"
student_submission :username => "student2@example.com"
student_submission(:username => "student1@example.com")
student_submission(:username => "student2@example.com")
get "/courses/#{@course.id}/gradebook/speed_grader?assignment_id=#{@assignment.id}"
wait_for_ajaximations
@ -319,3 +321,4 @@ describe "speed grader submissions" do
end
end
end
end

View File

@ -0,0 +1,91 @@
require File.expand_path(File.dirname(__FILE__) + '/common')
require File.expand_path(File.dirname(__FILE__) + '/helpers/files_common')
require File.expand_path(File.dirname(__FILE__) + '/helpers/submissions_common')
describe "submissions" do
it_should_behave_like "in-process server selenium tests"
it_should_behave_like "submissions selenium tests"
context 'as a teacher' do
before (:each) do
course_with_teacher_logged_in
end
it "should allow media comments" do
stub_kaltura
student_in_course
assignment = create_assignment
assignment.submissions.create(:user => @student)
get "/courses/#{@course.id}/assignments/#{assignment.id}/submissions/#{@student.id}"
# make sure the JS didn't burn any bridges, and submit two
submit_media_comment_1
submit_media_comment_2
# check that the thumbnails show up on the right sidebar
number_of_comments = driver.execute_script("return $('.comment_list').children().length")
number_of_comments.should == 2
end
it "should display the grade in grade field" do
student_in_course
assignment = create_assignment
assignment.submissions.create(:user => @student)
assignment.grade_student @student, :grade => 2
get "/courses/#{@course.id}/assignments/#{assignment.id}/submissions/#{@student.id}"
f('.grading_value')[:value].should == '2'
end
end
context "student view" do
before (:each) do
course_with_teacher_logged_in
end
it "should allow a student view student to view/submit assignments" do
@assignment = @course.assignments.create(
:title => 'Cool Assignment',
:points_possible => 10,
:submission_types => "online_text_entry",
:due_at => Time.now.utc + 2.days)
enter_student_view
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
f('.assignment .title').should include_text @assignment.title
f('.submit_assignment_link').click
assignment_form = f('#submit_online_text_entry_form')
wait_for_tiny(assignment_form)
type_in_tiny('#submission_body', 'my assigment submission')
expect_new_page_load { submit_form(assignment_form) }
@course.student_view_student.submissions.count.should == 1
f('#sidebar_content .details').should include_text "Turned In!"
end
it "should allow a student view student to submit file upload assignments" do
@assignment = @course.assignments.create(
:title => 'Cool Assignment',
:points_possible => 10,
:submission_types => "online_upload",
:due_at => Time.now.utc + 2.days)
enter_student_view
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
f('.submit_assignment_link').click
filename, fullpath, data = get_file("testfile1.txt")
f('.submission_attachment input').send_keys(fullpath)
expect_new_page_load { f('#submit_file_button').click }
keep_trying_until do
f('.details .header').should include_text "Turned In!"
f('.details .file-big').should include_text "testfile1"
end
end
end
end

View File

@ -38,7 +38,6 @@ describe "Wiki pages and Tiny WYSIWYG editor Images" do
it "should properly clone images, including thumbnails, and display" do
skip_if_ie('Out of memory')
wiki_page_tools_file_tree_setup
old_course = @course
new_course = old_course.clone_for(old_course.account)
@ -50,7 +49,7 @@ describe "Wiki pages and Tiny WYSIWYG editor Images" do
keep_trying_until do
images = ffj('#editor_tabs_4 .image_list .img')
images.length.should == 2
images.each { |i| i.attribute('complete').should == 'true' } # - commented out because it is breaking with
images.each { |i| i.should have_attribute('complete', 'true') } # - commented out because it is breaking with
#webdriver 2.22 and firefox 12
end
end

View File

@ -216,7 +216,7 @@ describe "Wiki pages and Tiny WYSIWYG editor features" do
keep_trying_until do
drag_with_js('.editor_box_resizer', 0, resizer_to)
sleep 3
driver.execute_script("return $('#wiki_page_body_ifr').height()").should eql(200)
driver.execute_script("return $('#wiki_page_body_ifr').height()").should == 200
end
f('.editor_box_resizer').attribute('style').should be_blank
@ -231,7 +231,6 @@ describe "Wiki pages and Tiny WYSIWYG editor features" do
end
it "should add bold and italic text to the rce" do
skip_if_ie('Out of memory')
get "/courses/#{@course.id}/wiki"
wait_for_tiny(keep_trying_until { f("#new_wiki_page") })
@ -260,7 +259,6 @@ describe "Wiki pages and Tiny WYSIWYG editor features" do
end
it "should add an equation to the rce by using equation buttons" do
skip_if_ie('Out of memory')
get "/courses/#{@course.id}/wiki"
f('#wiki_page_body_instructure_equation').click
@ -332,13 +330,12 @@ describe "Wiki pages and Tiny WYSIWYG editor features" do
# spec should still pass.
src = f('.equation_image').attribute('src')
response = Net::HTTP.get_response(URI.parse(src))
response.code.should eql "302"
response.code.should == "302"
response.header['location'].should include URI.encode(equation_text, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
end
end
it "should display record video dialog" do
skip_if_ie('Out of memory')
stub_kaltura
get "/courses/#{@course.id}/wiki"
@ -351,7 +348,6 @@ describe "Wiki pages and Tiny WYSIWYG editor features" do
end
it "should handle table borders correctly" do
skip_if_ie('Out of memory')
get "/courses/#{@course.id}/wiki"
def check_table(attributes = {})

View File

@ -164,7 +164,7 @@ describe "user selenium tests" do
expect_new_page_load { form.submit }
# confirm the user is authenticated into the dashboard
f('#identity .logout').should be_present
User.last.initial_enrollment_type.should eql 'student'
User.last.initial_enrollment_type.should == 'student'
end
it "should register a student without a join code" do
@ -184,7 +184,7 @@ describe "user selenium tests" do
expect_new_page_load { form.submit }
# confirm the user is authenticated into the dashboard
f('#identity .logout').should be_present
User.last.initial_enrollment_type.should eql 'student'
User.last.initial_enrollment_type.should == 'student'
end
it "should register a teacher" do
@ -199,7 +199,7 @@ describe "user selenium tests" do
expect_new_page_load { form.submit }
# confirm the user is authenticated into the dashboard
f('#identity .logout').should be_present
User.last.initial_enrollment_type.should eql 'teacher'
User.last.initial_enrollment_type.should == 'teacher'
end
it "should register an observer" do
@ -218,7 +218,7 @@ describe "user selenium tests" do
expect_new_page_load { form.submit }
# confirm the user is authenticated into the dashboard
f('#identity .logout').should be_present
User.last.initial_enrollment_type.should eql 'observer'
User.last.initial_enrollment_type.should == 'observer'
end
end