sakai-oae-test-api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'kuali-sakai-common-lib'
4
+ gem 'watir-webdriver'
5
+ gem 'selenium-webdriver'
6
+ gem 'page-object'
7
+ gem 'rake'
@@ -0,0 +1,37 @@
1
+ require 'kuali-sakai-common-lib'
2
+ require 'watir-webdriver'
3
+ require 'page-object'
4
+ require 'cgi'
5
+
6
+ PageObject.javascript_framework = :jquery
7
+
8
+ require 'sakai-oae-test-api/global_methods'
9
+ require 'sakai-oae-test-api/gem_extensions'
10
+ require 'sakai-oae-test-api/cle_frame_classes'
11
+ require 'sakai-oae-test-api/pop_up_dialogs'
12
+ require 'sakai-oae-test-api/toolbars_and_menus'
13
+ require 'sakai-oae-test-api/widgets'
14
+ require 'sakai-oae-test-api/page_classes'
15
+
16
+ # Initialize this class at the start of your test cases to
17
+ # open the specified test browser at the specified Sakai welcome page URL.
18
+ #
19
+ # The initialization will return the LoginPage class object as well as
20
+ # create the @browser variable used throughout the page classes.
21
+ class SakaiOAE
22
+
23
+ attr_reader :browser, :url
24
+
25
+ def initialize(web_browser, url)
26
+
27
+ @url = url
28
+
29
+ @browser = Watir::Browser.new web_browser
30
+ @browser.window.resize_to(1400,900)
31
+ @browser.goto @url
32
+ @browser.button(:id=>"footer_logo_button").wait_until_present
33
+
34
+ LoginPage.new @browser
35
+ end
36
+
37
+ end
@@ -0,0 +1,2160 @@
1
+ # coding: UTF-8
2
+
3
+ #================
4
+ # Assessments pages - "Samigo", a.k.a., "Tests & Quizzes"
5
+ #================
6
+
7
+ # This is a module containing methods that are
8
+ # common to all the question pages inside the
9
+ # Assessment section of a Site.
10
+ module QuestionHelpers
11
+
12
+ include PageObject
13
+
14
+ # Saves the question by clicking the Save button, then makes the determination
15
+ # whether to instantiate the EditAssessment class, or the EditQuestionPool class.
16
+ def save
17
+
18
+ quiz = frm.div(:class=>"portletBody").div(:index=>0).text
19
+ pool = frm.div(:class=>"portletBody").div(:index=>1).text
20
+
21
+ frm.button(:value=>"Save").click
22
+
23
+ if quiz =~ /^Assessments/
24
+ EditAssessment.new(@browser)
25
+ elsif pool =~ /^Question Pools/
26
+ EditQuestionPool.new(@browser)
27
+ else
28
+ puts "Unexpected text: "
29
+ p pool
30
+ p quiz
31
+ end
32
+
33
+ end
34
+
35
+ in_frame(:index=>1) do |frame|
36
+ link(:assessments, :text=>"Assessments", :frame=>frame)
37
+ link(:assessment_types, :text=>"Assessment Types", :frame=>frame)
38
+ link(:question_pools, :text=>"Question Pools", :frame=>frame)
39
+ link(:questions, :text=>/Questions:/, :frame=>frame)
40
+ end
41
+
42
+ end
43
+
44
+
45
+ # The Course Tools "Tests and Quizzes" page for a given site.
46
+ # (Instructor view)
47
+ class AssessmentsList
48
+
49
+ include PageObject
50
+
51
+ # This method reads the type of assessment selected for creation,
52
+ # then clicks the Create button and instantiates the proper class.
53
+ #
54
+ # If the assessment is going to be made in the builder, then
55
+ # EditAssessment is called. If from Markup text...
56
+ def create
57
+ builder_or_text = frm.radio(:value=>"1", :name=>"authorIndexForm:_id29").set?
58
+
59
+ frm.button(:value=>"Create").click
60
+
61
+ if builder_or_text == true
62
+ EditAssessment.new(@browser)
63
+ else
64
+ # Need to add Markup page class, then add the reference here.
65
+ end
66
+
67
+ end
68
+
69
+ # Clicks the Question Pools link, then instantiates
70
+ # the QuestionPoolsList class.
71
+ def question_pools
72
+ #puts "clicking question pools"
73
+ #10.times {frm.link(:text=>"Question Pools").flash}
74
+ frm.link(:text=>"Question Pools").click
75
+ #sleep 200
76
+ #puts "clicked..."
77
+ #frm.link(:text=>"Add New Pool").wait_until_present
78
+ #frm.h3(:text=>"Question Pools").wait_until_present(120)
79
+ QuestionPoolsList.new(@browser)
80
+ end
81
+
82
+ # Collects the titles of the Assessments listed as "Pending"
83
+ # then returns them as an Array.
84
+ def pending_assessment_titles
85
+ titles =[]
86
+ pending_table = frm.table(:id=>"authorIndexForm:coreAssessments")
87
+ 1.upto(pending_table.rows.size-1) do |x|
88
+ titles << pending_table[x][1].span(:id=>/assessmentTitle/).text
89
+ end
90
+ return titles
91
+ end
92
+
93
+ # Collects the titles of the Assessments listed as "Published"
94
+ # then returns them as an Array.
95
+ def published_assessment_titles
96
+ titles =[]
97
+ published_table = frm.div(:class=>"tier2", :index=>2).table(:class=>"listHier", :index=>0)
98
+ 1.upto(published_table.rows.size-1) do |x|
99
+ titles << published_table[x][1].span(:id=>/publishedAssessmentTitle/).text
100
+ end
101
+ return titles
102
+ end
103
+
104
+ # Returns an Array of the inactive Assessment titles displayed
105
+ # in the list.
106
+ def inactive_assessment_titles
107
+ titles =[]
108
+ inactive_table = frm.div(:class=>"tier2", :index=>2).table(:id=>"authorIndexForm:inactivePublishedAssessments")
109
+ 1.upto(inactive_table.rows.size-1) do |x|
110
+ titles << inactive_table[x][1].span(:id=>/inactivePublishedAssessmentTitle/).text
111
+ end
112
+ return titles
113
+ end
114
+
115
+ # Opens the selected test for scoring
116
+ # then instantiates the AssessmentTotalScores class.
117
+ def score_test(test_title)
118
+ frm.tbody(:id=>"authorIndexForm:_id88:tbody_element").row(:text=>/#{Regexp.escape(test_title)}/).link(:id=>/authorIndexToScore/).click
119
+ AssessmentTotalScores.new(@browser)
120
+ end
121
+
122
+ in_frame(:index=>1) do |frame|
123
+ link(:assessment_types, :text=>"Assessment Types", :frame=>frame)
124
+ text_field(:title, :id=>"authorIndexForm:title", :frame=>frame)
125
+ radio_button(:create_using_builder) { |page| page.radio_button_element(:name=>"authorIndexForm:_id29", index=>0, :frame=>frame) }
126
+ radio_button(:create_using_text) { |page| page.radio_button_element(:name=>"authorIndexForm:_id29", :index=>$frame_index, :frame=>frame) }
127
+ select_list(:select_assessment_type, :id=>"authorIndexForm:assessmentTemplate", :frame=>frame)
128
+ button(:import, :id=>"authorIndexForm:import", :frame=>frame)
129
+ #(:, :=>"", :frame=>frame)
130
+ #(:, :=>"", :frame=>frame)
131
+
132
+ end
133
+
134
+ end
135
+
136
+ # Page that appears when previewing an assessment.
137
+ # It shows the basic information about the assessment.
138
+ class PreviewOverview
139
+
140
+ include PageObject
141
+
142
+ # Scrapes the value of the due date from the page. Returns it as a string.
143
+ def due_date
144
+ frm.div(:class=>"tier2").table(:index=>0)[0][0].text
145
+ end
146
+
147
+ # Scrapes the value of the time limit from the page. Returns it as a string.
148
+ def time_limit
149
+ frm.div(:class=>"tier2").table(:index=>0)[3][0].text
150
+ end
151
+
152
+ # Scrapes the submission limit from the page. Returns it as a string.
153
+ def submission_limit
154
+ frm.div(:class=>"tier2").table(:index=>0)[6][0].text
155
+ end
156
+
157
+ # Scrapes the Feedback policy from the page. Returns it as a string.
158
+ def feedback
159
+ frm.div(:class=>"tier2").table(:index=>0)[9][0].text
160
+ end
161
+
162
+ # Clicks the Done button, then instantiates
163
+ # the EditAssessment class.
164
+ def done
165
+ frm.button(:name=>"takeAssessmentForm:_id5").click
166
+ EditAssessment.new(@browser)
167
+ end
168
+
169
+ in_frame(:index=>1) do |frame|
170
+ button(:begin_assessment, :id=>"takeAssessmentForm:beginAssessment3", :frame=>frame)
171
+
172
+ end
173
+
174
+ end
175
+
176
+ # The Settings page for a particular Assessment
177
+ class AssessmentSettings
178
+
179
+ include PageObject
180
+
181
+ # Scrapes the Assessment Type from the page and returns it as a string.
182
+ def assessment_type_title
183
+ frm.div(:class=>"tier2").table(:index=>0)[0][1].text
184
+ end
185
+
186
+ # Scrapes the Assessment Author information from the page and returns it as a string.
187
+ def assessment_type_author
188
+ frm.div(:class=>"tier2").table(:index=>$frame_index)[1][1].text
189
+ end
190
+
191
+ # Scrapes the Assessment Type Description from the page and returns it as a string.
192
+ def assessment_type_description
193
+ frm.div(:class=>"tier2").table(:index=>0)[2][1].text
194
+ end
195
+
196
+ # Clicks the Save Settings and Publish button
197
+ # then instantiates the PublishAssessment class.
198
+ def save_and_publish
199
+ frm.button(:value=>"Save Settings and Publish").click
200
+ PublishAssessment.new(@browser)
201
+ end
202
+
203
+ in_frame(:index=>1) do |frame|
204
+ link(:open, :text=>"Open", :frame=>frame)
205
+ link(:close, :text=>"Close", :frame=>frame)
206
+ text_field(:title, :id=>"assessmentSettingsAction:intro:assessment_title", :frame=>frame)
207
+ text_field(:authors, :id=>"assessmentSettingsAction:intro:assessment_author", :frame=>frame)
208
+ text_area(:description, :id=>"assessmentSettingsAction:intro:_id44_textinput", :frame=>frame)
209
+ button(:add_attachments_to_intro, :name=>"assessmentSettingsAction:intro:_id90", :frame=>frame)
210
+ text_field(:available_date, :id=>"assessmentSettingsAction:startDate", :frame=>frame)
211
+ text_field(:due_date, :id=>"assessmentSettingsAction:endDate", :frame=>frame)
212
+ text_field(:retract_date, :id=>"assessmentSettingsAction:retractDate", :frame=>frame)
213
+ radio_button(:released_to_anonymous) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:_id117", :index=>$frame_index, :frame=>frame) }
214
+ radio_button(:released_to_site) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:_id117", :index=>$frame_index, :frame=>frame) }
215
+ text_area(:specified_ips, :name=>"assessmentSettingsAction:_id132", :frame=>frame)
216
+ text_field(:secondary_id, :id=>"assessmentSettingsAction:username", :frame=>frame)
217
+ text_field(:secondary_pw, :id=>"assessmentSettingsAction:password", :frame=>frame)
218
+ checkbox(:timed_assessment, :id=>"assessmentSettingsAction:selTimeAssess", :frame=>frame)
219
+ select_list(:limit_hour, :id=>"assessmentSettingsAction:timedHours", :frame=>frame)
220
+ select_list(:limit_mins, :id=>"assessmentSettingsAction:timedMinutes", :frame=>frame)
221
+ radio_button(:linear_access) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:itemNavigation", :index=>$frame_index, :frame=>frame) }
222
+ radio_button(:random_access) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:itemNavigation", :index=>$frame_index, :frame=>frame) }
223
+ radio_button(:question_per_page) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:assessmentFormat", :index=>$frame_index, :frame=>frame) }
224
+ radio_button(:part_per_page) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:assessmentFormat", :index=>$frame_index, :frame=>frame) }
225
+ radio_button(:assessment_per_page) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:assessmentFormat", :index=>2, :frame=>frame) }
226
+ radio_button(:continuous_numbering) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:itemNumbering", :index=>$frame_index, :frame=>frame) }
227
+ radio_button(:restart_per_part) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:itemNumbering", :index=>$frame_index, :frame=>frame) }
228
+ checkbox(:add_mark_for_review, :id=>"assessmentSettingsAction:markForReview1", :frame=>frame)
229
+ radio_button(:unlimited_submissions) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:unlimitedSubmissions", :index=>$frame_index, :frame=>frame) }
230
+ radio_button(:only_x_submissions) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:unlimitedSubmissions", :index=>$frame_index, :frame=>frame) }
231
+ text_field(:allowed_submissions, :id=>"assessmentSettingsAction:submissions_Allowed", :frame=>frame)
232
+ radio_button(:late_submissions_not_accepted) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:lateHandling", :index=>$frame_index, :frame=>frame) }
233
+ radio_button(:late_submissions_accepted) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:lateHandling", :index=>$frame_index, :frame=>frame) }
234
+ text_area(:submission_message, :id=>"assessmentSettingsAction:_id245_textinput", :frame=>frame)
235
+ text_field(:final_page_url, :id=>"assessmentSettingsAction:finalPageUrl", :frame=>frame)
236
+ radio_button(:question_level_feedback) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:feedbackAuthoring", :index=>$frame_index, :frame=>frame) }
237
+ radio_button(:selection_level_feedback) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:feedbackAuthoring", :index=>$frame_index, :frame=>frame) }
238
+ radio_button(:both_feedback_levels) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:feedbackAuthoring", :index=>2, :frame=>frame) }
239
+ radio_button(:immediate_feedback) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:feedbackDelivery", :index=>$frame_index, :frame=>frame) }
240
+ radio_button(:feedback_on_submission) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:feedbackDelivery", :index=>$frame_index, :frame=>frame) }
241
+ radio_button(:no_feedback) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:feedbackDelivery", :index=>2, :frame=>frame) }
242
+ radio_button(:feedback_on_date) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:feedbackDelivery", :index=>3, :frame=>frame) }
243
+ text_field(:feedback_date, :id=>"assessmentSettingsAction:feedbackDate", :frame=>frame)
244
+ radio_button(:only_release_scores) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:feedbackComponentOption", :index=>$frame_index, :frame=>frame) }
245
+ radio_button(:release_questions_and) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:feedbackComponentOption", :index=>$frame_index, :frame=>frame) }
246
+ checkbox(:release_student_response, :id=>"assessmentSettingsAction:feedbackCheckbox1", :frame=>frame)
247
+ checkbox(:release_correct_response, :id=>"assessmentSettingsAction:feedbackCheckbox3", :frame=>frame)
248
+ checkbox(:release_students_assessment_scores, :id=>"assessmentSettingsAction:feedbackCheckbox5", :frame=>frame)
249
+ checkbox(:release_students_question_and_part_scores, :id=>"assessmentSettingsAction:feedbackCheckbox7", :frame=>frame)
250
+ checkbox(:release_question_level_feedback, :id=>"assessmentSettingsAction:feedbackCheckbox2", :frame=>frame)
251
+ checkbox(:release_selection_level_feedback, :id=>"assessmentSettingsAction:feedbackCheckbox4", :frame=>frame)
252
+ checkbox(:release_graders_comments, :id=>"assessmentSettingsAction:feedbackCheckbox6", :frame=>frame)
253
+ checkbox(:release_statistics, :id=>"assessmentSettingsAction:feedbackCheckbox8", :frame=>frame)
254
+ radio_button(:student_ids_seen) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:anonymousGrading1", :index=>$frame_index, :frame=>frame) }
255
+ radio_button(:anonymous_grading) { |page| page.radio_button_element( :name=>"assessmentSettingsAction:anonymousGrading1", :index=>$frame_index, :frame=>frame) }
256
+ #radio_button(:no_gradebook_options) { |page| page.radio_button_element( :name=>"", :index=>$frame_index, :frame=>frame) }
257
+ #radio_button(:grades_sent_to_gradebook) { |page| page.radio_button_element( :name=>"", :index=>$frame_index, :frame=>frame) }
258
+ #radio_button(:record_highest_score) { |page| page.radio_button_element( :name=>"", :index=>$frame_index, :frame=>frame) }
259
+ #radio_button(:record_last_score) { |page| page.radio_button_element( :name=>"", :index=>$frame_index, :frame=>frame) }
260
+ #radio_button(:background_color) { |page| page.radio_button_element( :name=>"", :index=>$frame_index, :frame=>frame) }
261
+ #text_field(:color_value, :id=>"", :frame=>frame)
262
+ #radio_button(:background_image) { |page| page.radio_button_element( :name=>"", :index=>$frame_index, :frame=>frame) }
263
+ #text_field(:image_name, :=>"", :frame=>frame)
264
+ #text_field(:keywords, :=>"", :frame=>frame)
265
+ #text_field(:objectives, :=>"", :frame=>frame)
266
+ #text_field(:rubrics, :=>"", :frame=>frame)
267
+ #checkbox(:record_metadata_for_questions, :=>"", :frame=>frame)
268
+ button(:save, :name=>"assessmentSettingsAction:_id383", :frame=>frame)
269
+ button(:cancel, :name=>"assessmentSettingsAction:_id385", :frame=>frame)
270
+
271
+ end
272
+
273
+ end
274
+
275
+ # Instructor's view of Students' assessment scores
276
+ class AssessmentTotalScores
277
+
278
+ include PageObject
279
+
280
+ # Gets the user ids listed in the
281
+ # scores table, returns them as an Array
282
+ # object.
283
+ #
284
+ # Note that this method is only appropriate when student
285
+ # identities are not being obscured on this page. If student
286
+ # submissions are set to be anonymous then this method will fail
287
+ # to return any ids.
288
+ def student_ids
289
+ ids = []
290
+ scores_table = frm.table(:id=>"editTotalResults:totalScoreTable").to_a
291
+ scores_table.delete_at(0)
292
+ scores_table.each { |row| ids << row[1] }
293
+ return ids
294
+ end
295
+
296
+ # Adds a comment to the specified student's comment box.
297
+ #
298
+ # Note that this method assumes that the student identities are not being
299
+ # obscured on this page. If they are, then this method will not work for
300
+ # selecting the appropriate comment box.
301
+ def comment_for_student(student_id, comment)
302
+ index_val = student_ids.index(student_id)
303
+ frm.text_field(:name=>"editTotalResults:totalScoreTable:#{index_val}:_id345").value=comment
304
+ end
305
+
306
+ # Clicks the Submit Date link in the table header to sort/reverse sort the list.
307
+ def sort_by_submit_date
308
+ frm.link(:text=>"Submit Date").click
309
+ end
310
+
311
+ # Enters the specified string into the topmost box listed on the page.
312
+ #
313
+ # This method is especially useful when the student identities are obscured, since
314
+ # in that situation you can't target a specific student's comment box, obviously.
315
+ def comment_in_first_box=(comment)
316
+ frm.text_field(:name=>"editTotalResults:totalScoreTable:0:_id345").value=comment
317
+ end
318
+
319
+ # Clicks the Update button, then instantiates
320
+ # the AssessmentTotalScores class.
321
+ def update
322
+ frm.button(:value=>"Update").click
323
+ AssessmentTotalScores.new(@browser)
324
+ end
325
+
326
+ # Clicks the Assessments link on the page
327
+ # then instantiates the AssessmentsList class.
328
+ def assessments
329
+ frm.link(:text=>"Assessments").click
330
+ AssessmentsList.new(@browser)
331
+ end
332
+
333
+ end
334
+
335
+ # The page that appears when you're creating a new quiz
336
+ # or editing an existing one
337
+ class EditAssessment
338
+
339
+ include PageObject
340
+
341
+ # Allows insertion of a question at a specified
342
+ # point in the Assessment. Must include the
343
+ # part number, the question number, and the type of
344
+ # question. Question Type must match the Type
345
+ # value in the drop down.
346
+ #
347
+ # The method will instantiate the page class
348
+ # based on the selected question type.
349
+ def insert_question_after(part_num, question_num, qtype)
350
+ if question_num.to_i == 0
351
+ frm.select(:id=>"assesssmentForm:parts:#{part_num.to_i - 1}:changeQType").select(qtype)
352
+ else
353
+ frm.select(:id=>"assesssmentForm:parts:#{part_num.to_i - 1}:parts:#{question_num.to_i - 1}:changeQType").select(qtype)
354
+ end
355
+
356
+ page = case(qtype)
357
+ when "Multiple Choice" then MultipleChoice.new(@browser)
358
+ when "True False" then TrueFalse.new(@browser)
359
+ when "Survey" then Survey.new(@browser)
360
+ when "Short Answer/Essay" then ShortAnswer.new(@browser)
361
+ when "Fill in the Blank" then FillInBlank.new(@browser)
362
+ when "Numeric Response" then NumericResponse.new(@browser)
363
+ when "Matching" then Matching.new(@browser)
364
+ when "Audio Recording" then AudioRecording.new(@browser)
365
+ when "File Upload" then FileUpload.new(@browser)
366
+ else puts "#{qtype} is not a valid question type"
367
+ end
368
+
369
+ return page
370
+
371
+ end
372
+
373
+ # Allows removal of question by part number and question number.
374
+ def remove_question(part_num, question_num)
375
+ frm.link(:id=>"assesssmentForm:parts:#{part_num.to_i-1}:parts:#{question_num.to_i-1}:deleteitem").click
376
+ end
377
+
378
+ # Allows editing of a question by specifying its part number
379
+ # and question number.
380
+ def edit_question(part_num, question_num)
381
+ frm.link(:id=>"assesssmentForm:parts:#{part_num.to_i-1}:parts:#{question_num.to_i-1}:modify").click
382
+ end
383
+
384
+ # Allows copying an Assessment part to a Pool.
385
+ def copy_part_to_pool(part_num)
386
+ frm.link(:id=>"assesssmentForm:parts:#{part_num.to_i-1}:copyToPool").click
387
+ end
388
+
389
+ # Allows removing a specified
390
+ # Assessment part number.
391
+ def remove_part(part_num)
392
+ frm.link(:xpath, "//a[contains(@onclick, 'assesssmentForm:parts:#{part_num.to_i-1}:copyToPool')]").click
393
+ end
394
+
395
+ # Clicks the Add Part button, then
396
+ # instantiates the AddEditAssessmentPart page class.
397
+ def add_part
398
+ frm.link(:text=>"Add Part").click
399
+ AddEditAssessmentPart.new(@browser)
400
+ end
401
+
402
+ # Selects the desired question type from the
403
+ # drop down list, then instantiates the appropriate
404
+ # page class.
405
+ def select_question_type(qtype)
406
+ frm.select(:id=>"assesssmentForm:changeQType").select(qtype)
407
+
408
+ page = case(qtype)
409
+ when "Multiple Choice" then MultipleChoice.new(@browser)
410
+ when "True False" then TrueFalse.new(@browser)
411
+ when "Survey" then Survey.new(@browser)
412
+ when "Short Answer/Essay" then ShortAnswer.new(@browser)
413
+ when "Fill in the Blank" then FillInBlank.new(@browser)
414
+ when "Numeric Response" then NumericResponse.new(@browser)
415
+ when "Matching" then Matching.new(@browser)
416
+ when "Audio Recording" then AudioRecording.new(@browser)
417
+ when "File Upload" then FileUpload.new(@browser)
418
+ else puts "#{qtype} is not a valid question type"
419
+ end
420
+
421
+ return page
422
+
423
+ end
424
+
425
+ # Clicks the Preview button,
426
+ # then instantiates the PreviewOverview page class.
427
+ def preview
428
+ frm.link(:text=>"Preview").click
429
+ PreviewOverview.new(@browser)
430
+ end
431
+
432
+ # Clicks the Settings link, then
433
+ # instantiates the AssessmentSettings page class.
434
+ def settings
435
+ frm.link(:text=>"Settings").click
436
+ AssessmentSettings.new(@browser)
437
+ end
438
+
439
+ # Clicks the Publish button, then
440
+ # instantiates the PublishAssessment page class.
441
+ def publish
442
+ frm.link(:text=>"Publish").click
443
+ PublishAssessment.new(@browser)
444
+ end
445
+
446
+ # Clicks the Question Pools button, then
447
+ # instantiates the QuestionPoolsList page class.
448
+ def question_pools
449
+ frm.link(:text=>"Question Pools").click
450
+ QuestionPoolsList.new(@browser)
451
+ end
452
+
453
+ # Allows retrieval of a specified question's
454
+ # text, by part and question number.
455
+ def get_question_text(part_number, question_number)
456
+ frm.table(:id=>"assesssmentForm:parts:#{part_number.to_i-1}:parts").div(:class=>"tier3", :index=>question_number.to_i-1).text
457
+ end
458
+
459
+ in_frame(:index=>1) do |frame|
460
+ link(:assessments, :text=>"Assessments", :frame=>frame)
461
+ link(:assessment_types, :text=>"Assessment Types", :frame=>frame)
462
+ link(:print, :text=>"Print", :frame=>frame)
463
+ button(:update_points, :id=>"assesssmentForm:pointsUpdate", :frame=>frame)
464
+ end
465
+
466
+ end
467
+
468
+ # This is the page for adding and editing a part of an assessment
469
+ class AddEditAssessmentPart
470
+
471
+ include PageObject
472
+
473
+ # Clicks the Save button, then instantiates
474
+ # the EditAssessment page class.
475
+ def save
476
+ frm.button(:name=>"modifyPartForm:_id89").click
477
+ EditAssessment.new(@browser)
478
+ end
479
+
480
+ in_frame(:index=>1) do |frame|
481
+ text_field(:title, :id=>"modifyPartForm:title", :frame=>frame)
482
+ text_area(:information, :id=>"modifyPartForm:_id10_textinput", :frame=>frame)
483
+ button(:add_attachments, :name=>"modifyPartForm:_id54", :frame=>frame)
484
+ radio_button(:questions_one_by_one) { |page| page.radio_button_element(:index=>0, :name=>"modifyPartForm:_id60", :frame=>frame)}
485
+ radio_button(:random_draw) { |page| page.radio_button_element(:index=>1, :name=>"modifyPartForm:_id60", :frame=>frame) }
486
+ select_list(:pool_name, :id=>"modifyPartForm:assignToPool", :frame=>frame)
487
+ text_field(:number_of_questions, :id=>"modifyPartForm:numSelected", :frame=>frame)
488
+ text_field(:point_value_of_questions, :id=>"modifyPartForm:numPointsRandom", :frame=>frame)
489
+ text_field(:negative_point_value, :id=>"modifyPartForm:numDiscountRandom", :frame=>frame)
490
+ radio_button(:randomized_each_time) { |page| page.radio_button_element(:index=>0, :name=>"modifyPartForm:randomizationType", :frame=>frame) }
491
+ radio_button(:randomized_once) { |page| page.radio_button_element(:index=>1, :name=>"modifyPartForm:randomizationType", :frame=>frame) }
492
+ radio_button(:order_as_listed) { |page| page.radio_button_element(:index=>0, :name=>"modifyPartForm:_id81", :frame=>frame) }
493
+ radio_button(:random_within_part) { |page| page.radio_button_element(:index=>1, :name=>"modifyPartForm:_id81", :frame=>frame) }
494
+ text_field(:objective, :id=>"modifyPartForm:obj", :frame=>frame)
495
+ text_field(:keyword, :id=>"modifyPartForm:keyword", :frame=>frame)
496
+ text_field(:rubric, :id=>"modifyPartForm:rubric", :frame=>frame)
497
+ button(:cancel, :name=>"modifyPartForm:_id90", :frame=>frame)
498
+ end
499
+
500
+ end
501
+
502
+ # The review page once you've selected to Save and Publish
503
+ # the assessment
504
+ class PublishAssessment
505
+
506
+ include PageObject
507
+
508
+ # Clicks the Publish button, then
509
+ # instantiates the AssessmentsList page class.
510
+ def publish
511
+ frm.button(:value=>"Publish").click
512
+ AssessmentsList.new(@browser)
513
+ end
514
+
515
+ in_frame(:index=>1) do |frame|
516
+ button(:cancel, :value=>"Cancel", :frame=>frame)
517
+ button(:edit, :name=>"publishAssessmentForm:_id23", :frame=>frame)
518
+ select_list(:notification, :id=>"publishAssessmentForm:number", :frame=>frame)
519
+
520
+ end
521
+
522
+ end
523
+
524
+ # The page for setting up a multiple choice question
525
+ class MultipleChoice
526
+
527
+ include PageObject
528
+ include QuestionHelpers
529
+
530
+ in_frame(:class=>"portletMainIframe") do |frame|
531
+ button(:cancel, :value=>"Cancel", :frame=>frame)
532
+ text_field(:answer_point_value, :id=>"itemForm:answerptr", :frame=>frame)
533
+ link(:whats_this, :text=>"(What's This?)", :frame=>frame)
534
+ radio_button(:single_correct) { |page| page.radio_button_element(:name=>"itemForm:chooseAnswerTypeForMC", :index=>0, :frame=>frame) }
535
+ radio_button(:enable_negative_marking) { |page| page.radio_button_element(:name=>"itemForm:partialCreadit_NegativeMarking", :index=>0, :frame=>frame) }
536
+
537
+ # Element present when negative marking selected:
538
+ text_field(:negative_point_value, :id=>"itemForm:answerdsc", :frame=>frame)
539
+
540
+ radio_button(:enable_partial_credit) { |page| page.radio_button_element(:name=>"itemForm:partialCreadit_NegativeMarking", :index=>1, :frame=>frame) }
541
+ link(:reset_to_default, :text=>"Reset to Default Grading Logic", :frame=>frame)
542
+ radio_button(:multi_single) {|page| page.radio_button_element(:name=>"itemForm:chooseAnswerTypeForMC", :index=>1, :frame=>frame) }
543
+ radio_button(:multi_multi) {|page| page.radio_button_element(:name=>"itemForm:chooseAnswerTypeForMC", :index=>2, :frame=>frame) }
544
+ text_area(:question_text, :id=>"itemForm:_id82_textinput", :frame=>frame)
545
+ button(:add_attachments, :name=>"itemForm:_id126", :frame=>frame)
546
+
547
+ text_area(:answer_a, :id=>"itemForm:mcchoices:0:_id140_textinput", :frame=>frame)
548
+ link(:remove_a, :id=>"itemForm:mcchoices:0:removelinkSingle", :frame=>frame)
549
+ text_area(:answer_b, :id=>"itemForm:mcchoices:1:_id140_textinput", :frame=>frame)
550
+ link(:remove_b, :id=>"itemForm:mcchoices:1:removelinkSingle", :frame=>frame)
551
+ text_area(:answer_c, :id=>"itemForm:mcchoices:2:_id140_textinput", :frame=>frame)
552
+ link(:remove_c, :id=>"itemForm:mcchoices:2:removelinkSingle", :frame=>frame)
553
+ text_area(:answer_d, :id=>"itemForm:mcchoices:3:_id140_textinput", :frame=>frame)
554
+ link(:remove_d, :id=>"itemForm:mcchoices:3:removelinkSingle", :frame=>frame)
555
+
556
+ # Radio buttons that appear when "single correct" is selected
557
+ radio_button(:a_correct, :name=>"itemForm:mcchoices:0:mcradiobtn", :frame=>frame)
558
+ radio_button(:b_correct, :name=>"itemForm:mcchoices:1:mcradiobtn", :frame=>frame)
559
+ radio_button(:c_correct, :name=>"itemForm:mcchoices:2:mcradiobtn", :frame=>frame)
560
+ radio_button(:d_correct, :name=>"itemForm:mcchoices:3:mcradiobtn", :frame=>frame)
561
+
562
+ # % Value fields that appear when "single correct" and "partial credit" selected
563
+ text_field(:a_value, :id=>"itemForm:mcchoices:0:partialCredit", :frame=>frame)
564
+ text_field(:b_value, :id=>"itemForm:mcchoices:1:partialCredit", :frame=>frame)
565
+ text_field(:c_value, :id=>"itemForm:mcchoices:2:partialCredit", :frame=>frame)
566
+ text_field(:d_value, :id=>"itemForm:mcchoices:3:partialCredit", :frame=>frame)
567
+
568
+ link(:reset_score_values, :text=>"Reset Score Values", :frame=>frame)
569
+
570
+ # Checkboxes that appear when "multiple correct" is selected
571
+ checkbox(:a_correct, :name=>"itemForm:mcchoices:0:mccheckboxes", :frame=>frame)
572
+ checkbox(:b_correct, :name=>"itemForm:mcchoices:1:mccheckboxes", :frame=>frame)
573
+ checkbox(:c_correct, :name=>"itemForm:mcchoices:2:mccheckboxes", :frame=>frame)
574
+ checkbox(:d_correct, :name=>"itemForm:mcchoices:3:mccheckboxes", :frame=>frame)
575
+
576
+ select_list(:insert_additional_answers, :id=>"itemForm:insertAdditionalAnswerSelectMenu", :frame=>frame)
577
+ radio_button(:randomize_answers_yes) {|page| page.radio_button_element(:index=>0, :name=>"itemForm:_id162", :frame=>frame) }
578
+ radio_button(:randomize_answers_no) {|page| page.radio_button_element(:index=>1, :name=>"itemForm:_id162", :frame=>frame) }
579
+ radio_button(:require_rationale_yes) {|page| page.radio_button_element(:index=>0, :name=>"itemForm:_id166", :frame=>frame) }
580
+ radio_button(:require_rationale_no) {|page| page.radio_button_element(:index=>1, :name=>"itemForm:_id166", :frame=>frame) }
581
+ select_list(:assign_to_part, :id=>"itemForm:assignToPart", :frame=>frame)
582
+ select_list(:assign_to_pool, :id=>"itemForm:assignToPool", :frame=>frame)
583
+ text_area(:feedback_for_correct, :id=>"itemForm:_id186_textinput", :frame=>frame)
584
+ text_area(:feedback_for_incorrect, :id=>"itemForm:_id190_textinput", :frame=>frame)
585
+
586
+ end
587
+
588
+ end
589
+
590
+ # The page for setting up a Survey question
591
+ class Survey
592
+
593
+ include PageObject
594
+ include QuestionHelpers
595
+
596
+ in_frame(:index=>1) do |frame|
597
+ button(:cancel, :id=>"itemForm:_id63", :frame=>frame)
598
+ text_area(:question_text, :id=>"itemForm:_id69_textinput", :frame=>frame)
599
+ button(:add_attachments, :id=>"itemForm:_id113", :frame=>frame)
600
+ radio_button(:yes_no) { |page| page.radio_button_element(:index=>0, :name=>"itemForm:selectscale", :frame=>frame) }
601
+ radio_button(:disagree_agree) {|page| page.radio_button_element(:index=>1, :name=>"itemForm:selectscale", :frame=>frame) }
602
+ radio_button(:disagree_undecided) {|page| page.radio_button_element(:index=>2, :name=>"itemForm:selectscale", :frame=>frame) }
603
+ radio_button(:below_above) {|page| page.radio_button_element(:index=>3, :name=>"itemForm:selectscale", :frame=>frame)}
604
+ radio_button(:strongly_agree) {|page| page.radio_button_element(:index=>4, :name=>"itemForm:selectscale", :frame=>frame)}
605
+ radio_button(:unacceptable_excellent) {|page| page.radio_button_element(:index=>5, :name=>"itemForm:selectscale", :frame=>frame)}
606
+ radio_button(:one_to_five) {|page| page.radio_button_element(:index=>6, :name=>"itemForm:selectscale", :frame=>frame)}
607
+ radio_button(:one_to_ten) {|page| page.radio_button_element(:index=>7, :name=>"itemForm:selectscale", :frame=>frame)}
608
+ text_area(:feedback, :id=>"itemForm:_id140_textinput", :frame=>frame)
609
+ select_list(:assign_to_part, :id=>"itemForm:assignToPart", :frame=>frame)
610
+ select_list(:assign_to_pool, :id=>"itemForm:assignToPool", :frame=>frame)
611
+
612
+ end
613
+
614
+ end
615
+
616
+ # The page for setting up a Short Answer/Essay question
617
+ class ShortAnswer
618
+
619
+ include PageObject
620
+ include QuestionHelpers
621
+
622
+ in_frame(:index=>1) do |frame|
623
+ button(:cancel, :id=>"itemForm:_id63", :frame=>frame)
624
+ text_field(:answer_point_value, :id=>"itemForm:answerptr", :frame=>frame)
625
+ text_area(:question_text, :id=>"itemForm:_id69_textinput", :frame=>frame)
626
+ button(:add_attachments, :id=>"itemForm:_id113", :frame=>frame)
627
+ text_area(:model_short_answer, :id=>"itemForm:_id129_textinput", :frame=>frame)
628
+ text_area(:feedback, :id=>"itemForm:_id133_textinput", :frame=>frame)
629
+ select_list(:assign_to_part, :id=>"itemForm:assignToPart", :frame=>frame)
630
+ select_list(:assign_to_pool, :id=>"itemForm:assignToPool", :frame=>frame)
631
+
632
+ end
633
+
634
+ end
635
+
636
+ # The page for setting up a Fill-in-the-blank question
637
+ class FillInBlank
638
+
639
+ include PageObject
640
+ include QuestionHelpers
641
+
642
+ in_frame(:index=>1) do |frame|
643
+ button(:cancel, :id=>"itemForm:_id63", :frame=>frame)
644
+ text_field(:answer_point_value, :id=>"itemForm:answerptr", :frame=>frame)
645
+ text_area(:question_text, :id=>"itemForm:_id75_textinput", :frame=>frame)
646
+ checkbox(:case_sensitive, :name=>"itemForm:_id76", :frame=>frame)
647
+ checkbox(:mutually_exclusive, :name=>"itemForm:_id78", :frame=>frame)
648
+ button(:add_attachments, :id=>"itemForm:_id126", :frame=>frame)
649
+ select_list(:assign_to_part, :id=>"itemForm:assignToPart", :frame=>frame)
650
+ select_list(:assign_to_pool, :id=>"itemForm:assignToPool", :frame=>frame)
651
+
652
+ end
653
+
654
+ end
655
+
656
+ # The page for setting up a numeric response question
657
+ class NumericResponse
658
+
659
+ include PageObject
660
+ include QuestionHelpers
661
+
662
+ in_frame(:index=>1) do |frame|
663
+ button(:cancel, :id=>"itemForm:_id63", :frame=>frame)
664
+ text_field(:answer_point_value, :id=>"itemForm:answerptr", :frame=>frame)
665
+ text_area(:question_text, :id=>"itemForm:_id73_textinput", :frame=>frame)
666
+ button(:add_attachments, :id=>"itemForm:_id117", :frame=>frame)
667
+ text_area(:feedback_for_correct, :id=>"itemForm:_id133_textinput", :frame=>frame)
668
+ text_area(:feedback_for_incorrect, :id=>"itemForm:_id135_textinput", :frame=>frame)
669
+ select_list(:assign_to_part, :id=>"itemForm:assignToPart", :frame=>frame)
670
+ select_list(:assign_to_pool, :id=>"itemForm:assignToPool", :frame=>frame)
671
+
672
+ end
673
+
674
+ end
675
+
676
+ # The page for setting up a matching question
677
+ class Matching
678
+
679
+ include PageObject
680
+ include QuestionHelpers
681
+
682
+ in_frame(:index=>1) do |frame|
683
+ button(:cancel, :id=>"itemForm:_id63", :frame=>frame)
684
+ text_field(:answer_point_value, :id=>"itemForm:answerptr", :frame=>frame)
685
+ text_area(:question_text, :id=>"itemForm:_id78_textinput", :frame=>frame)
686
+ button(:add_attachments, :id=>"itemForm:_id122", :frame=>frame)
687
+ text_area(:choice, :id=>"itemForm:_id147_textinput", :frame=>frame)
688
+ text_area(:match, :id=>"itemForm:_id151_textinput", :frame=>frame)
689
+ button(:save_pairing, :name=>"itemForm:_id164", :frame=>frame)
690
+ text_area(:feedback_for_correct, :id=>"itemForm:_id184_textinput", :frame=>frame)
691
+ text_area(:feedback_for_incorrect, :id=>"itemForm:_id189_textinput", :frame=>frame)
692
+ select_list(:assign_to_part, :id=>"itemForm:assignToPart", :frame=>frame)
693
+ select_list(:assign_to_pool, :id=>"itemForm:assignToPool", :frame=>frame)
694
+
695
+ end
696
+
697
+ end
698
+
699
+ # The page for setting up a True/False question
700
+ class TrueFalse
701
+
702
+ include PageObject
703
+ include QuestionHelpers
704
+
705
+ in_frame(:index=>1) do |frame|
706
+ button(:cancel, :id=>"itemForm:_id63", :frame=>frame)
707
+ text_field(:answer_point_value, :id=>"itemForm:answerptr", :frame=>frame)
708
+ text_area(:question_text, :id=>"itemForm:_id77_textinput", :frame=>frame)
709
+ button(:add_attachments, :id=>"itemForm:_id121", :frame=>frame)
710
+ text_field(:negative_point_value, :id=>"itemForm:answerdsc", :frame=>frame)
711
+ radio_button(:answer_true) {|page| page.radio_button_element(:index=>0, :name=>"itemForm:TF", :frame=>frame)}
712
+ radio_button(:answer_false) {|page| page.radio_button_element(:index=>1, :name=>"itemForm:TF", :frame=>frame)}
713
+ radio_button(:required_rationale_yes) {|page| page.radio_button_element(:index=>0, :name=>"itemForm:rational", :frame=>frame)}
714
+ radio_button(:required_rationale_no) {|page| page.radio_button_element(:index=>1, :name=>"itemForm:rational", :frame=>frame)}
715
+ text_area(:feedback_for_correct, :id=>"itemForm:_id148_textinput", :frame=>frame)
716
+ text_area(:feedback_for_incorrect, :id=>"itemForm:_id152_textinput", :frame=>frame)
717
+ select_list(:assign_to_part, :id=>"itemForm:assignToPart", :frame=>frame)
718
+ select_list(:assign_to_pool, :id=>"itemForm:assignToPool", :frame=>frame)
719
+
720
+ end
721
+
722
+ end
723
+
724
+ # The page for setting up a question that requires an audio response
725
+ class AudioRecording
726
+
727
+ include PageObject
728
+ include QuestionHelpers
729
+
730
+ in_frame(:index=>1) do |frame|
731
+ button(:cancel, :id=>"itemForm:_id63", :frame=>frame)
732
+ text_field(:answer_point_value, :id=>"itemForm:answerptr", :frame=>frame)
733
+ text_area(:question_text, :id=>"itemForm:_id69_textinput", :frame=>frame)
734
+ button(:add_attachments, :id=>"itemForm:_id113", :frame=>frame)
735
+ text_field(:time_allowed, :id=>"itemForm:timeallowed", :frame=>frame)
736
+ select_list(:number_of_attempts, :id=>"itemForm:noattempts", :frame=>frame)
737
+ text_field(:feedback, :id=>"itemForm:_id146_textinput", :frame=>frame)
738
+ select_list(:assign_to_part, :id=>"itemForm:assignToPart", :frame=>frame)
739
+ select_list(:assign_to_pool, :id=>"itemForm:assignToPool", :frame=>frame)
740
+
741
+ end
742
+
743
+ end
744
+
745
+ # The page for setting up a question that requires
746
+ # attaching a file
747
+ class FileUpload
748
+
749
+ include PageObject
750
+ include QuestionHelpers
751
+
752
+ in_frame(:index=>1) do |frame|
753
+ button(:cancel, :id=>"itemForm:_id63", :frame=>frame)
754
+ text_field(:answer_point_value, :id=>"itemForm:answerptr", :frame=>frame)
755
+ text_area(:question_text, :id=>"itemForm:_id69_textinput", :frame=>frame)
756
+ button(:add_attachments, :id=>"itemForm:_id113", :frame=>frame)
757
+ text_field(:feedback, :id=>"itemForm:_id130_textinput", :frame=>frame)
758
+ select_list(:assign_to_part, :id=>"itemForm:assignToPart", :frame=>frame)
759
+ select_list(:assign_to_pool, :id=>"itemForm:assignToPool", :frame=>frame)
760
+
761
+ end
762
+
763
+ end
764
+
765
+ # The page that appears when you are editing a type of assessment
766
+ class EditAssessmentType
767
+
768
+ include PageObject
769
+
770
+ in_frame(:index=>1) do |frame|
771
+ #(:, :=>"", :frame=>frame)
772
+ #(:, :=>"", :frame=>frame)
773
+ #(:, :=>"", :frame=>frame)
774
+ #(:, :=>"", :frame=>frame)
775
+ #(:, :=>"", :frame=>frame)
776
+
777
+ end
778
+
779
+ end
780
+
781
+ # The Page that appears when adding a new question pool
782
+ class AddQuestionPool
783
+
784
+ include PageObject
785
+
786
+ # Clicks the Save button, then
787
+ # instantiates the QuestionPoolsList page class.
788
+ def save
789
+ #10.times {frm.button(:id=>"questionpool:submit").flash}
790
+ frm.button(:id=>"questionpool:submit").click
791
+ #sleep 180
792
+ #frm.button(:value=>"Create").wait_until_present(120)
793
+ QuestionPoolsList.new(@browser)
794
+ end
795
+
796
+ def cancel
797
+ frm.button(:value=>"Cancel").click
798
+ QuestionPoolsList.new @browser
799
+ end
800
+
801
+ in_frame(:index=>1) do |frame|
802
+ text_field(:pool_name, :id=>"questionpool:namefield", :frame=>frame)
803
+ text_field(:department_group, :id=>"questionpool:orgfield", :frame=>frame)
804
+ text_area(:description, :id=>"questionpool:descfield", :frame=>frame)
805
+ text_field(:objectives, :id=>"questionpool:objfield", :frame=>frame)
806
+ text_field(:keywords, :id=>"questionpool:keyfield", :frame=>frame)
807
+
808
+ end
809
+
810
+ end
811
+
812
+ # The Page that appears when editing an existing question pool
813
+ class EditQuestionPool
814
+
815
+ include PageObject
816
+
817
+ # Clicks the Add Question link, then
818
+ # instantiates the SelectQuestionType class.
819
+ def add_question
820
+ frm.link(:id=>"editform:addQlink").click
821
+ SelectQuestionType.new(@browser)
822
+ end
823
+
824
+ # Clicks the Question Pools link, then
825
+ # instantiates the QuestionPoolsList class.
826
+ def question_pools
827
+ frm.link(:text=>"Question Pools").click
828
+ QuestionPoolsList.new(@browser)
829
+ end
830
+
831
+ in_frame(:index=>1) do |frame|
832
+ text_field(:pool_name, :id=>"editform:namefield", :frame=>frame)
833
+ text_field(:department_group, :id=>"editform:orgfield", :frame=>frame)
834
+ text_area(:description, :id=>"editform:descfield", :frame=>frame)
835
+ text_field(:objectives, :id=>"editform:objfield", :frame=>frame)
836
+ text_field(:keywords, :id=>"editform:keyfield", :frame=>frame)
837
+ button(:update, :id=>"editform:Update", :frame=>frame)
838
+ button(:save, :id=>"questionpool:submit", :frame=>frame)
839
+ button(:cancel, :id=>"questionpool:_id11", :frame=>frame)
840
+
841
+ end
842
+
843
+ end
844
+
845
+ # The page with the list of existing Question Pools
846
+ class QuestionPoolsList
847
+
848
+ include PageObject
849
+
850
+ # Clicks the edit button, then instantiates
851
+ # the EditQuestionPool page class.
852
+ def edit_pool(name)
853
+ frm.span(:text=>name).fire_event("onclick")
854
+ EditQuestionPool.new(@browser)
855
+ end
856
+
857
+ # Clicks the Add New Pool link, then
858
+ # instantiates the AddQuestionPool page class.
859
+ def add_new_pool
860
+ #puts "clicking add new pool..."
861
+ #10.times {frm.link(:text=>"Add New Pool").flash}
862
+ frm.link(:text=>"Add New Pool").click
863
+ #puts "clicked..."
864
+ #frm.text_field(:id=>"questionpool:namefield").wait_until_present(200)
865
+ AddQuestionPool.new(@browser)
866
+ end
867
+
868
+ # Returns an array containing strings of the pool names listed
869
+ # on the page.
870
+ def pool_names
871
+ names= []
872
+ frm.table(:id=>"questionpool:TreeTable").rows.each do | row |
873
+ if row.span(:id=>/questionpool.+poolnametext/).exist?
874
+ names << row.span(:id=>/questionpool.+poolnametext/).text
875
+ end
876
+ end
877
+ return names
878
+ end
879
+
880
+ # Clicks "Import" and then instantiates the
881
+ # PoolImport page class.
882
+ def import
883
+ frm.link(:text=>"Import").click
884
+ PoolImport.new(@browser)
885
+ end
886
+
887
+ # Clicks the Assessments link and then
888
+ # instantiates the AssessmentsList page class.
889
+ def assessments
890
+ frm.link(:text=>"Assessments").click
891
+ AssessmentsList.new(@browser)
892
+ end
893
+
894
+ in_frame(:index=>1) do |frame|
895
+ link(:assessment_types, :text=>"Assessment Types", :frame=>frame)
896
+ end
897
+
898
+ end
899
+
900
+ # The page that appears when you click to import
901
+ # a pool.
902
+ class PoolImport
903
+
904
+ include PageObject
905
+
906
+ # Enters the target file into the Choose File
907
+ # file field. Note that it assumes the file is in
908
+ # the data/sakai-cle-test-api folder in the expected resources
909
+ # tree.
910
+ def choose_file=(file_name)
911
+ frm.file_field(:name=>"importPoolForm:_id6.upload").set(File.expand_path(File.dirname(__FILE__)) + "/../../data/sakai-cle-test-api/" + file_name)
912
+ end
913
+
914
+ # Clicks the Import button, then
915
+ # instantiates the QuestionPoolsList
916
+ # page class.
917
+ def import
918
+ frm.button(:value=>"Import").click
919
+ QuestionPoolsList.new(@browser)
920
+ end
921
+
922
+ end
923
+
924
+ # This page appears when adding a question to a pool
925
+ class SelectQuestionType
926
+
927
+ include PageObject
928
+
929
+ # Selects the specified question type from the
930
+ # drop-down list, then instantiates the appropriate
931
+ # page class, based on the question type selected.
932
+ def select_question_type(qtype)
933
+ frm.select(:id=>"_id1:selType").select(qtype)
934
+ frm.button(:value=>"Save").click
935
+
936
+ page = case(qtype)
937
+ when "Multiple Choice" then MultipleChoice.new(@browser)
938
+ when "True False" then TrueFalse.new(@browser)
939
+ when "Survey" then Survey.new(@browser)
940
+ when "Short Answer/Essay" then ShortAnswer.new(@browser)
941
+ when "Fill in the Blank" then FillInBlank.new(@browser)
942
+ when "Numeric Response" then NumericResponse.new(@browser)
943
+ when "Matching" then Matching.new(@browser)
944
+ when "Audio Recording" then AudioRecording.new(@browser)
945
+ when "File Upload" then FileUpload.new(@browser)
946
+ else puts "nothing selected"
947
+ end
948
+
949
+ return page
950
+
951
+ end
952
+
953
+ in_frame(:index=>1) do |frame|
954
+ button(:cancel, :value=>"Cancel", :frame=>frame)
955
+ end
956
+
957
+ end
958
+
959
+ # Page of Assessments accessible to a student user
960
+ #
961
+ # It may be that we want to deprecate this class and simply use
962
+ # the AssessmentsList class alone.
963
+ class TakeAssessmentList
964
+
965
+ include PageObject
966
+
967
+ # Returns an array containing the assessment names that appear on the page.
968
+ def available_assessments
969
+ # define this later
970
+ end
971
+
972
+ # Method to get the titles of assessments that
973
+ # the student user has submitted. The titles are
974
+ # returned in an Array object.
975
+ def submitted_assessments
976
+ table_array = @browser.frame(:index=>1).table(:id=>"selectIndexForm:reviewTable").to_a
977
+ table_array.delete_at(0)
978
+ titles = []
979
+ table_array.each { |row|
980
+ unless row[0] == ""
981
+ titles << row[0]
982
+ end
983
+ }
984
+
985
+ return titles
986
+
987
+ end
988
+
989
+ # Clicks the specified assessment
990
+ # then instantiates the BeginAssessment
991
+ # page class.
992
+ def take_assessment(name)
993
+ begin
994
+ frm.link(:text=>name).click
995
+ rescue Watir::Exception::UnknownObjectException
996
+ frm.link(:text=>CGI::escapeHTML(name)).click
997
+ end
998
+ BeginAssessment.new(@browser)
999
+ end
1000
+
1001
+ # This method is in need of improvement to make it
1002
+ # more generalized for finding the correct test.
1003
+ def feedback(test_name)
1004
+ test_table = frm.table(:id=>"selectIndexForm:reviewTable").to_a
1005
+ test_table.delete_if { |row| row[3] != "Immediate" }
1006
+ index_value = test_table.index { |row| row[0] == test_name }
1007
+ frm.link(:text=>"Feedback", :index=>index_value).click
1008
+ # Need to add a call to a New class here, when it's written
1009
+ end
1010
+
1011
+ end
1012
+
1013
+ # The student view of the overview page of an Assessment
1014
+ class BeginAssessment
1015
+
1016
+ include PageObject
1017
+
1018
+ # Clicks the Begin Assessment button.
1019
+ def begin_assessment
1020
+ frm.button(:value=>"Begin Assessment").click
1021
+ end
1022
+
1023
+ # Clicks the Cancel button and instantiates the X Class.
1024
+ def cancel
1025
+ # Define this later
1026
+ end
1027
+
1028
+ # Selects the specified radio button answer
1029
+ def multiple_choice_answer(letter)
1030
+ index = case(letter.upcase)
1031
+ when "A" then "0"
1032
+ when "B" then "1"
1033
+ when "C" then "2"
1034
+ when "D" then "3"
1035
+ when "E" then "4"
1036
+ end
1037
+ frm.radio(:name=>/takeAssessmentForm.+:deliverMultipleChoice.+:_id.+:#{index}/).click
1038
+ end
1039
+
1040
+ # Enters the answer into the specified blank number (1-based).
1041
+ def fill_in_blank_answer(answer, blank_number)
1042
+ index = blank_number.to_i-1
1043
+ frm.text_field(:name=>/deliverFillInTheBlank:_id.+:#{index}/).value=answer
1044
+ end
1045
+
1046
+ # Clicks either the True or the False radio button, as specified.
1047
+ def true_false_answer(answer)
1048
+ answer.upcase=~/t/i ? index = 0 : index = 1
1049
+ frm.radio(:name=>/deliverTrueFalse/, :index=>index).set
1050
+ end
1051
+
1052
+ # Enters the specified string into the Rationale text box.
1053
+ def true_false_rationale(text)
1054
+ frm.text_field(:name=>/:deliverTrueFalse:rationale/).value=text
1055
+ end
1056
+
1057
+ # Enters the specified text into the "Short Answer" field.
1058
+ def short_answer(answer)
1059
+ frm.text_field(:name=>/deliverShortAnswer/).value=answer
1060
+ end
1061
+
1062
+ # Selects the specified matching value, at the spot specified by the number (1-based counting).
1063
+ def match_answer(answer, number)
1064
+ index = number.to_i-1
1065
+ frm.select(:name=>/deliverMatching/, :index=>index).select(answer)
1066
+ end
1067
+
1068
+ # Enters the specified file name (and subdirectory below the expected target Sakai-CLE path) in the file field.
1069
+ def file_answer(file_name)
1070
+ frm.file_field(:name=>/deliverFileUpload/).set(File.expand_path(File.dirname(__FILE__)) + "/../../data/sakai-cle-test-api/" + file_name)
1071
+ frm.button(:value=>"Upload").click
1072
+ end
1073
+
1074
+ # Clicks the Next button and instantiates the BeginAssessment Class.
1075
+ def next
1076
+ frm.button(:value=>"Next").click
1077
+ BeginAssessment.new(@browser)
1078
+ end
1079
+
1080
+ # Clicks the Submit for Grading button and instantiates the ConfirmSubmission Class.
1081
+ def submit_for_grading
1082
+ frm.button(:value=>"Submit for Grading").click
1083
+ ConfirmSubmission.new(@browser)
1084
+ end
1085
+
1086
+ end
1087
+
1088
+ # The confirmation page that appears when submitting an Assessment.
1089
+ # The last step before actually submitting the the Assessment.
1090
+ class ConfirmSubmission
1091
+
1092
+ include PageObject
1093
+
1094
+ # Clicks the Submit for Grading button and instantiates
1095
+ # the SubmissionSummary Class.
1096
+ def submit_for_grading
1097
+ frm.button(:value=>"Submit for Grading").click
1098
+ SubmissionSummary.new(@browser)
1099
+ end
1100
+
1101
+ end
1102
+
1103
+ # The summary page that appears when an Assessment has been submitted.
1104
+ class SubmissionSummary
1105
+
1106
+ include PageObject
1107
+
1108
+ # Clicks the Continue button and instantiates
1109
+ # the TakeAssessmentList Class.
1110
+ def continue
1111
+ frm.button(:value=>"Continue").click
1112
+ TakeAssessmentList.new(@browser)
1113
+ end
1114
+
1115
+ end
1116
+
1117
+ #================
1118
+ # Assignments Pages
1119
+ #================
1120
+
1121
+ module AssignmentsMenu
1122
+
1123
+ include PageObject
1124
+
1125
+ def assignments_frame
1126
+ self.frame(:src=>/sakai2assignments.launch.html/)
1127
+ end
1128
+ alias frm assignments_frame
1129
+
1130
+ def add_assignment
1131
+ frm.link(:title=>"Add").click
1132
+ frm.frame(:id=>"new_assignment_instructions___Frame").td(:id=>"xEditingArea").wait_until_present
1133
+ AddAssignments.new @browser
1134
+ end
1135
+
1136
+ def grade_report
1137
+ frm.link(:text=>"Grade Report").click
1138
+ GradeReport.new @browser
1139
+ end
1140
+
1141
+ def student_view
1142
+ frm.link(:text=>"Student View").click
1143
+ StudentView.new @browser
1144
+ end
1145
+
1146
+ def permissions
1147
+ frm.link(:text=>"Permissions").click
1148
+ AssignmentsPermissions.new @browser
1149
+ end
1150
+
1151
+ def options
1152
+ frm.link(:text=>"Options").click
1153
+ AssignmentsOptions.new @browser
1154
+ end
1155
+
1156
+ def assignment_list
1157
+ frm.link(:text=>"Assignment list").click
1158
+ Assignments.new @browser
1159
+ end
1160
+
1161
+ # Clicks the Reorder button, then instantiates
1162
+ # the AssignmentsReorder page class.
1163
+ def reorder
1164
+ frm.link(:text=>"Reorder").click
1165
+ AssignmentsReorder.new(@browser)
1166
+ end
1167
+
1168
+ end # Assignments Menu module
1169
+
1170
+ #
1171
+ class Assignments # Note that the OAE portion of this class can be found in the page_classes file.
1172
+
1173
+ include PageObject
1174
+ include GlobalMethods
1175
+ include HeaderFooterBar
1176
+ include LeftMenuBar
1177
+ include HeaderBar
1178
+ include DocButtons
1179
+ include AssignmentsMenu
1180
+
1181
+ # Returns an array of the displayed assignment titles.
1182
+ # Use for verification of test steps.
1183
+ def assignments_titles
1184
+ titles = []
1185
+ frm.table(:class=>"listHier lines nolines").links(:href=>/doView_assignment/).each { |x| titles << x.text }
1186
+ titles
1187
+ end
1188
+ alias assignment_titles assignments_titles
1189
+ alias assignments_list assignments_titles
1190
+ alias titles assignments_titles
1191
+ alias list assignments_titles
1192
+
1193
+ # Clicks the Edit link for the Assignment specified.
1194
+ # Then it instantiates the AddAssignments page class.
1195
+ def edit_assignment(assignment_name)
1196
+ index = assignments_titles.index(assignment_name)
1197
+ frm.link(:text=>"Edit", :index=>index).click
1198
+ AddAssignments.new(@browser)
1199
+ end
1200
+
1201
+ # Checks the appropriate checkbox, based on the specified assignment_name
1202
+ # Then clicks the Update button and confirms the deletion request.
1203
+ def delete_assignment(assignment_name)
1204
+ check_assignment(assignment_name)
1205
+ frm.button(:value=>"Update").click
1206
+ sleep 0.2
1207
+ frm.button(:value=>"Delete").click
1208
+ end
1209
+
1210
+ # Clicks on the Duplicate link for the Assignment specified.
1211
+ def duplicate_assignment(assignment_name)
1212
+ index = assignments_titles.index(assignment_name)
1213
+ frm.link(:text=>"Duplicate", :index=>index).click
1214
+ end
1215
+
1216
+ # Checks the checkbox for the specified Assignment,
1217
+ # using the assignment id as the identifier.
1218
+ def check_assignment(assignment_name)
1219
+ assignment_row(assignment_name).checkbox.set
1220
+ end
1221
+
1222
+ # Opens the specified assignment for viewing
1223
+ #
1224
+ # Instantiates the student view or instructor/admin
1225
+ # view based on the landing page attributes
1226
+ def open_assignment(assignment_name)
1227
+ frm.link(:text=>assignment_name).click
1228
+ if frm.div(:class=>"portletBody").p(:class=>"instruction").exist? && frm.div(:class=>"portletBody").p(:class=>"instruction").text == "Add attachment(s), then choose the appropriate button at the bottom."
1229
+ AssignmentStudent.new(@browser)
1230
+ elsif frm.div(:class=>"portletBody").h3.text=="Viewing assignment..." || frm.div(:class=>"portletBody").h3.text.include?("Submitted") || frm.button(:value=>"Back to list").exist?
1231
+ AssignmentsPreview.new(@browser)
1232
+ else
1233
+ frm.frame(:id, "Assignment.view_submission_text___Frame").td(:id, "xEditingArea").wait_until_present
1234
+ AssignmentStudent.new(@browser)
1235
+ end
1236
+ end
1237
+ alias view_assignment open_assignment
1238
+
1239
+ # Gets the contents of the status column
1240
+ # for the specified assignment
1241
+ def status_of(assignment_name)
1242
+ assignment_row(assignment_name).td(:headers=>"status").text
1243
+ end
1244
+
1245
+ # Clicks the View Submissions link for the specified
1246
+ # Assignment, then instantiates the AssignmentSubmissionList
1247
+ # page class.
1248
+ def view_submissions_for(assignment_name)
1249
+ assignment_row(assignment_name).link(:text=>"View Submissions").click
1250
+ AssignmentSubmissionList.new(@browser)
1251
+ end
1252
+
1253
+ # Clicks the Grade link for the specified Assignment,
1254
+ # then instantiates the AssignmentSubmissionList page class.
1255
+ def grade(assignment_name)
1256
+ assignment_row(assignment_name).link(:text=>"Grade").click
1257
+ AssignmentSubmissionList.new(@browser)
1258
+ end
1259
+
1260
+ in_frame(:index=>2) do |frame|
1261
+ link(:grade_report, :text=>"Grade Report", :frame=>frame)
1262
+ link(:student_view, :text=>"Student View", :frame=>frame)
1263
+ link(:options, :text=>"Options", :frame=>frame)
1264
+ link(:sort_assignment_title, :text=>"Assignment title", :frame=>frame)
1265
+ link(:sort_status, :text=>"Status", :frame=>frame)
1266
+ link(:sort_open, :text=>"Open", :frame=>frame)
1267
+ link(:sort_due, :text=>"Due", :frame=>frame)
1268
+ link(:sort_in, :text=>"In", :frame=>frame)
1269
+ link(:sort_new, :text=>"New", :frame=>frame)
1270
+ link(:sort_scale, :text=>"Scale", :frame=>frame)
1271
+ select_list(:view, :id=>"view", :frame=>frame)
1272
+ select_list(:select_page_size, :id=>"selectPageSize", :frame=>frame)
1273
+ button(:next, :name=>"eventSubmit_doList_next", :frame=>frame)
1274
+ button(:last, :name=>"eventSubmit_doList_last", :frame=>frame)
1275
+ button(:previous, :name=>"eventSubmit_doList_prev", :frame=>frame)
1276
+ button(:first, :name=>"eventSubmit_doList_first", :frame=>frame)
1277
+ button(:update, :name=>"eventSubmit_doDelete_confirm_assignment", :frame=>frame)
1278
+ end
1279
+
1280
+ # Private methods
1281
+ private
1282
+
1283
+ def assignment_row(assignment_name)
1284
+ frm.table(:class=>"listHier lines nolines").row(:text=>/#{Regexp.escape(assignment_name)}/)
1285
+ end
1286
+
1287
+ end # Assignments
1288
+
1289
+ #
1290
+ class AddAssignments
1291
+
1292
+ include PageObject
1293
+ include AssignmentsMenu
1294
+
1295
+ # Sends the specified text to the text box in the FCKEditor
1296
+ # on the page.
1297
+ def instructions=(instructions)
1298
+ frm.frame(:id, "new_assignment_instructions___Frame").td(:id, "xEditingArea").frame(:index=>0).send_keys(instructions)
1299
+ end
1300
+
1301
+ # Clicks the Preview button, then instantiates
1302
+ # the AssignmentsPreview page class.
1303
+ def preview
1304
+ frm.button(:value=>"Preview").click
1305
+ AssignmentsPreview.new(@browser)
1306
+ end
1307
+
1308
+ # Clicks the Add Attachments or Add/Remove Attachments button, then
1309
+ # instantiates the AssignmentsAttachments page class.
1310
+ def add_attachments
1311
+ frm.button(:value=>/(Add|Add \/ Remove) Attachments/).click
1312
+ AssignmentsAttachments.new(@browser)
1313
+ end
1314
+ alias add_remove_attachments add_attachments
1315
+
1316
+ # Returns an array listing the files attached to the assignment
1317
+ def attached_files
1318
+ array = []
1319
+ frm.ul(:class=>/attachList/).lis.each { |li| array << li.link.text }
1320
+ array
1321
+ end
1322
+
1323
+ in_frame(:index=>2) do |frame|
1324
+ span(:gradebook_warning, :id=>"gradebookListWarnAssoc", :frame=>frame)
1325
+ div(:alert_box, :class=>"alertMessage", :frame=>frame)
1326
+ button(:save_draft, :name=>"save", :frame=>frame)
1327
+ button(:cancel, :value=>"Cancel", :frame=>frame)
1328
+ button(:post, :value=>"Post", :frame=>frame)
1329
+ hidden_field(:assignment_id, :name=>"assignmentId", :frame=>frame)
1330
+ text_field(:title, :id=>"new_assignment_title", :frame=>frame)
1331
+ select_list(:open_month, :id=>"new_assignment_openmonth", :frame=>frame)
1332
+ select_list(:open_day, :id=>"new_assignment_openday", :frame=>frame)
1333
+ select_list(:open_year, :id=>"new_assignment_openyear", :frame=>frame)
1334
+ select_list(:open_hour, :id=>"new_assignment_openhour", :frame=>frame)
1335
+ select_list(:open_minute, :id=>"new_assignment_openmin", :frame=>frame)
1336
+ select_list(:open_meridian, :id=>"new_assignment_openampm", :frame=>frame)
1337
+ select_list(:due_month, :id=>"new_assignment_duemonth", :frame=>frame)
1338
+ select_list(:due_day, :id=>"new_assignment_dueday", :frame=>frame)
1339
+ select_list(:due_year, :id=>"new_assignment_dueyear", :frame=>frame)
1340
+ select_list(:due_hour, :id=>"new_assignment_duehour", :frame=>frame)
1341
+ select_list(:due_minute, :id=>"new_assignment_duemin", :frame=>frame)
1342
+ select_list(:due_meridian, :id=>"new_assignment_dueampm", :frame=>frame)
1343
+ select_list(:accept_month, :id=>"new_assignment_closemonth", :frame=>frame)
1344
+ select_list(:accept_day, :id=>"new_assignment_closeday", :frame=>frame)
1345
+ select_list(:accept_year, :id=>"new_assignment_closeyear", :frame=>frame)
1346
+ select_list(:accept_hour, :id=>"new_assignment_closehour", :frame=>frame)
1347
+ select_list(:accept_minute, :id=>"new_assignment_closemin", :frame=>frame)
1348
+ select_list(:accept_meridian, :id=>"new_assignment_closeampm", :frame=>frame)
1349
+ select_list(:student_submissions, :id=>"subType", :frame=>frame)
1350
+ select_list(:grade_scale, :id=>"new_assignment_grade_type", :frame=>frame)
1351
+ checkbox(:allow_resubmission, :id=>"allowResToggle", :frame=>frame)
1352
+ select_list(:num_resubmissions, :id=>"allowResubmitNumber", :frame=>frame)
1353
+ select_list(:resub_until_month, :id=>"allow_resubmit_closeMonth", :frame=>frame)
1354
+ select_list(:resub_until_day, :id=>"allow_resubmit_closeDay", :frame=>frame)
1355
+ select_list(:resub_until_year, :id=>"allow_resubmit_closeYear", :frame=>frame)
1356
+ select_list(:resub_until_hour, :id=>"allow_resubmit_closeHour", :frame=>frame)
1357
+ select_list(:resub_until_minute, :id=>"allow_resubmit_closeMin", :frame=>frame)
1358
+ select_list(:resub_until_meridian, :id=>"allow_resubmit_closeAMPM", :frame=>frame)
1359
+ text_field(:max_points, :name=>"new_assignment_grade_points", :frame=>frame)
1360
+ checkbox(:add_due_date, :id=>"new_assignment_check_add_due_date", :frame=>frame)
1361
+ checkbox(:add_open_announcement, :id=>"new_assignment_check_auto_announce", :frame=>frame)
1362
+ checkbox(:add_honor_pledge, :id=>"new_assignment_check_add_honor_pledge", :frame=>frame)
1363
+ checkbox(:use_turnitin, :id=>"new_assignment_use_review_service", :frame=>frame)
1364
+ checkbox(:allow_students_to_view_report, :id=>"new_assignment_allow_student_view", :frame=>frame)
1365
+ radio_button(:do_not_add_to_gradebook, :id=>"no",:name=>"new_assignment_add_to_gradebook", :frame=>frame)
1366
+ radio_button(:add_to_gradebook, :id=>"add", :name=>"new_assignment_add_to_gradebook", :frame=>frame)
1367
+ radio_button(:do_not_send_notifications, :id=>"notsendnotif", :frame=>frame)
1368
+ radio_button(:send_notifications, :id=>"sendnotif", :frame=>frame)
1369
+ radio_button(:send_summary_email, :id=>"sendnotifsummary", :frame=>frame)
1370
+ radio_button(:do_not_send_grade_notif, :id=>"notsendreleasegradenotif", :frame=>frame)
1371
+ radio_button(:send_grade_notif, :id=>"sendreleasegradenotif", :frame=>frame)
1372
+ link(:add_model_answer, :id=>"modelanswer_add", :frame=>frame)
1373
+ link(:add_private_note, :id=>"note_add", :frame=>frame)
1374
+ link(:add_all_purpose_item, :id=>"allPurpose_add", :frame=>frame)
1375
+ text_area(:model_answer, :id=>"modelanswer_text", :frame=>frame)
1376
+ button(:model_answer_attach, :name=>"modelAnswerAttach", :frame=>frame)
1377
+ select_list(:show_model_answer, :id=>"modelanswer_to", :frame=>frame)
1378
+ button(:save_model_answer, :id=>"modelanswer_save", :frame=>frame)
1379
+ button(:cancel_model_answer, :id=>"modelanswer_cancel", :frame=>frame)
1380
+ text_area(:private_note, :id=>"note_text", :frame=>frame)
1381
+ select_list(:share_note_with, :id=>"note_to", :frame=>frame)
1382
+ button(:save_note, :id=>"note_save", :frame=>frame)
1383
+ button(:cancel_note, :id=>"note_cancel", :frame=>frame)
1384
+ text_field(:all_purpose_title, :id=>"allPurpose_title", :frame=>frame)
1385
+ text_area(:all_purpose_text, :id=>"allPurpose_text", :frame=>frame)
1386
+ button(:add_all_purpose_attachments, :id=>"allPurposeAttach", :frame=>frame)
1387
+ radio_button(:show_this_all_purpose_item, :id=>"allPurposeHide1", :frame=>frame)
1388
+ radio_button(:hide_this_all_purpose_item, :id=>"allPurposeHide2", :frame=>frame)
1389
+ checkbox(:show_from, :id=>"allPurposeShowFrom", :frame=>frame)
1390
+ checkbox(:show_until, :id=>"allPurposeShowTo", :frame=>frame)
1391
+ select_list(:show_from_month, :id=>"allPurpose_releaseMonth", :frame=>frame)
1392
+ select_list(:show_from_day, :id=>"allPurpose_releaseDay", :frame=>frame)
1393
+ select_list(:show_from_year, :id=>"allPurpose_releaseYear", :frame=>frame)
1394
+ select_list(:show_from_hour, :id=>"allPurpose_releaseHour", :frame=>frame)
1395
+ select_list(:show_from_minute, :id=>"allPurpose_releaseMin", :frame=>frame)
1396
+ select_list(:show_from_meridian, :id=>"allPurpose_releaseAMPM", :frame=>frame)
1397
+ select_list(:show_until_month, :id=>"allPurpose_retractMonth", :frame=>frame)
1398
+ select_list(:show_until_day, :id=>"allPurpose_retractDay", :frame=>frame)
1399
+ select_list(:show_until_year, :id=>"allPurpose_retractYear", :frame=>frame)
1400
+ select_list(:show_until_hour, :id=>"allPurpose_retractHour", :frame=>frame)
1401
+ select_list(:show_until_minute, :id=>"allPurpose_retractMin", :frame=>frame)
1402
+ select_list(:show_until_meridian, :id=>"allPurpose_retractAMPM", :frame=>frame)
1403
+ link(:expand_guest_list, :id=>"expand_1", :frame=>frame)
1404
+ link(:collapse_guest_list, :id=>"collapse_1", :frame=>frame)
1405
+ link(:expand_TA_list, :id=>"expand_2", :frame=>frame)
1406
+ link(:collapse_TA_list, :id=>"collapse_2", :frame=>frame)
1407
+ link(:expand_instructor_list, :id=>"expand_3", :frame=>frame)
1408
+ link(:collapse_instructor_list, :is=>"collapse_3", :frame=>frame)
1409
+
1410
+ # Note that only the "All" checkboxes are defined, since other items may or may not be there
1411
+ checkbox(:all_guests, :id=>"allPurpose_Guest", :frame=>frame)
1412
+ checkbox(:all_TAs, :id=>"allPurpose_Teaching Assistant", :frame=>frame)
1413
+ checkbox(:all_instructors, :id=>"allPurpose_Instructor", :frame=>frame)
1414
+ end
1415
+
1416
+ end # AddAssignments
1417
+
1418
+ #
1419
+ class AssignmentsPermissions
1420
+
1421
+ include PageObject
1422
+
1423
+ in_frame(:index=>2) do |frame|
1424
+ button(:save, :value=>"Save", :frame=>frame)
1425
+ checkbox(:evaluators_share_drafts, :id=>"Evaluatorasn.share.drafts", :frame=>frame)
1426
+ checkbox(:organizers_share_drafts, :id=>"Organizerasn.share.drafts", :frame=>frame)
1427
+ checkbox(:guests_all_groups, :id=>"Guestasn.all.groups", :frame=>frame)
1428
+ checkbox(:guests_create_assignments, :id=>"Guestasn.new", :frame=>frame)
1429
+ checkbox(:guests_submit_to_assigments, :id=>"Guestasn.submit", :frame=>frame)
1430
+ checkbox(:guests_delete_assignments, :id=>"Guestasn.delete", :frame=>frame)
1431
+ checkbox(:guests_read_assignments, :id=>"Guestasn.read", :frame=>frame)
1432
+ checkbox(:guests_revise_assignments, :id=>"Guestasn.revise", :frame=>frame)
1433
+ checkbox(:guests_grade_assignments, :id=>"Guestasn.grade", :frame=>frame)
1434
+ checkbox(:guests_receive_notifications, :id=>"Guestasn.receive.notifications", :frame=>frame)
1435
+ checkbox(:guests_share_drafts, :id=>"Guestasn.share.drafts", :frame=>frame)
1436
+ checkbox(:instructors_all_groups, :id=>"Instructorasn.all.groups", :frame=>frame)
1437
+ checkbox(:instructors_create_assignments, :id=>"Instructorasn.new", :frame=>frame)
1438
+ checkbox(:instructors_submit_to_assigments, :id=>"Instructorasn.submit", :frame=>frame)
1439
+ checkbox(:instructors_delete_assignments, :id=>"Instructorasn.delete", :frame=>frame)
1440
+ checkbox(:instructors_read_assignments, :id=>"Instructorasn.read", :frame=>frame)
1441
+ checkbox(:instructors_revise_assignments, :id=>"Instructorasn.revise", :frame=>frame)
1442
+ checkbox(:instructors_grade_assignments, :id=>"Instructorasn.grade", :frame=>frame)
1443
+ checkbox(:instructors_receive_notifications, :id=>"Instructorasn.receive.notifications", :frame=>frame)
1444
+ checkbox(:instructors_share_drafts, :id=>"Instructorasn.share.drafts", :frame=>frame)
1445
+ checkbox(:students_all_groups, :id=>"Studentasn.all.groups", :frame=>frame)
1446
+ checkbox(:students_create_assignments, :id=>"Studentasn.new", :frame=>frame)
1447
+ checkbox(:students_submit_to_assigments, :id=>"Studentasn.submit", :frame=>frame)
1448
+ checkbox(:students_delete_assignments, :id=>"Studentasn.delete", :frame=>frame)
1449
+ checkbox(:students_read_assignments, :id=>"Studentasn.read", :frame=>frame)
1450
+ checkbox(:students_revise_assignments, :id=>"Studentasn.revise", :frame=>frame)
1451
+ checkbox(:students_grade_assignments, :id=>"Studentasn.grade", :frame=>frame)
1452
+ checkbox(:students_receive_notifications, :id=>"Studentasn.receive.notifications", :frame=>frame)
1453
+ checkbox(:students_share_drafts, :id=>"Studentasn.share.drafts", :frame=>frame)
1454
+ checkbox(:tas_all_groups, :id=>"Teaching Assistantasn.all.groups", :frame=>frame)
1455
+ checkbox(:tas_create_assignments, :id=>"Teaching Assistantasn.new", :frame=>frame)
1456
+ checkbox(:tas_submit_to_assigments, :id=>"Teaching Assistantasn.submit", :frame=>frame)
1457
+ checkbox(:tas_delete_assignments, :id=>"Teaching Assistantasn.delete", :frame=>frame)
1458
+ checkbox(:tas_read_assignments, :id=>"Teaching Assistantasn.read", :frame=>frame)
1459
+ checkbox(:tas_revise_assignments, :id=>"Teaching Assistantasn.revise", :frame=>frame)
1460
+ checkbox(:tas_grade_assignments, :id=>"Teaching Assistantasn.grade", :frame=>frame)
1461
+ checkbox(:tas_receive_notifications, :id=>"Teaching Assistantasn.receive.notifications", :frame=>frame)
1462
+ checkbox(:tas_share_drafts, :id=>"Teaching Assistantasn.share.drafts", :frame=>frame)
1463
+ link(:undo_changes, :text=>"Undo changes", :frame=>frame)
1464
+ button(:cancel, :id=>"eventSubmit_doCancel", :frame=>frame)
1465
+ link(:permission, :text=>"Permission", :frame=>frame)
1466
+ link(:guest, :text=>"Guest", :frame=>frame)
1467
+ link(:instructor, :text=>"Instructor", :frame=>frame)
1468
+ link(:student, :text=>"Student", :frame=>frame)
1469
+ link(:teaching_assistant, :text=>"Teaching Assistant", :frame=>frame)
1470
+ link(:same_permissions_for_all_groups, :text=>"Same site level permissions for all groups inside the site", :frame=>frame)
1471
+ link(:create_new_assignments, :text=>"Create new assignment(s)", :frame=>frame)
1472
+ link(:submit_to_assignments, :text=>"Submit to assignment(s)", :frame=>frame)
1473
+ link(:delete_assignments, :text=>"Delete assignment(s)", :frame=>frame)
1474
+ link(:read_assignments, :text=>"Read Assignment(s)", :frame=>frame)
1475
+ link(:revise_assignments, :text=>"Revise assignment(s)", :frame=>frame)
1476
+ link(:grade_submissions, :text=>"Grade assignment submission(s)", :frame=>frame)
1477
+ link(:receive_email_notifications, :text=>"Receive email notifications", :frame=>frame)
1478
+ link(:view_drafts_from_others, :text=>"Able to view draft assignment(s) created by other users", :frame=>frame)
1479
+ end
1480
+
1481
+ end # AssignmentsPermissions
1482
+
1483
+ # Options page for Assignments
1484
+ class AssignmentsOptions
1485
+
1486
+ include PageObject
1487
+ include AssignmentsMenu
1488
+
1489
+ in_frame(:index=>2) do |frame|
1490
+ radio_button(:default, :id=>"submission_list_option_default", :frame=>frame)
1491
+ radio_button(:only_show_filtered_submissions, :id=>"submission_list_option_searchonly", :frame=>frame)
1492
+ button(:update, :name=>"eventSubmit_doUpdate_options", :frame=>frame)
1493
+ button(:cancel, :name=>"eventSubmit_doCancel_options", :frame=>frame)
1494
+
1495
+ end
1496
+
1497
+ end # AssignmentsOptions
1498
+
1499
+ # Page that appears when you click to preview an Assignment
1500
+ class AssignmentsPreview
1501
+
1502
+ include PageObject
1503
+ include AssignmentsMenu
1504
+
1505
+ # Returns the text content of the page header
1506
+ def header
1507
+ frm.div(:class=>"portletBody").h3.text
1508
+ end
1509
+
1510
+ # Returns a hash object containing the contents of the Item Summary table.
1511
+ # The hash's key is the header column and the value is the content column.
1512
+ def item_summary
1513
+ hash = {}
1514
+ frm.table(:class=>"itemSummary").rows.each do |row|
1515
+ hash.store(row.th.text, row.td.text)
1516
+ end
1517
+ hash
1518
+ end
1519
+
1520
+ # Grabs the Assignment Instructions text.
1521
+ def assignment_instructions
1522
+ frm.div(:class=>"textPanel").text
1523
+ end
1524
+
1525
+ # Grabs the instructor comments text.
1526
+ def instructor_comments
1527
+ frm.div(:class=>"portletBody").div(:class=>"textPanel", :index=>2).text
1528
+ end
1529
+
1530
+ in_frame(:index=>2) do |frame|
1531
+ hidden_field(:assignment_id, :name=>"assignmentId", :frame=>frame)
1532
+ link(:assignment_list, :text=>"Assignment List", :frame=>frame)
1533
+ link(:permissions, :text=>"Permissions", :frame=>frame)
1534
+ link(:options, :text=>"Options", :frame=>frame)
1535
+ link(:hide_assignment, :href=>/doHide_preview_assignment_assignment/, :frame=>frame)
1536
+ link(:show_assignment, :href=>/doShow_preview_assignment_assignment/, :frame=>frame)
1537
+ link(:hide_student_view, :href=>/doHide_preview_assignment_student_view/, :frame=>frame)
1538
+ link(:show_student_view, :href=>/doShow_preview_assignment_student_view/, :frame=>frame)
1539
+ button(:edit, :name=>"revise", :frame=>frame)
1540
+ button(:save_draft, :name=>"save", :frame=>frame)
1541
+ button(:done, :name=>"done", :frame=>frame)
1542
+ button(:back_to_list, :value=>"Back to list", :frame=>frame)
1543
+ button(:post, :name=>"post", :frame=>frame)
1544
+ button(:cancel, :value=>"Cancel", :frame=>frame)
1545
+ end
1546
+
1547
+ end
1548
+
1549
+ # The reorder page for Assignments
1550
+ class AssignmentsReorder
1551
+
1552
+ include PageObject
1553
+ include AssignmentsMenu
1554
+
1555
+ in_frame(:index=>2) do |frame|
1556
+ link(:add, :text=>"Add", :frame=>frame)
1557
+ link(:assignment_list, :text=>"Assignment List", :frame=>frame)
1558
+ link(:grade_report, :text=>"Grade Report", :frame=>frame)
1559
+ link(:student_view, :text=>"Student View", :frame=>frame)
1560
+ link(:permissions, :text=>"Permissions", :frame=>frame)
1561
+ link(:options, :text=>"Options", :frame=>frame)
1562
+ link(:sort_by_title, :text=>"Sort by title", :frame=>frame)
1563
+ link(:sort_by_open_date, :text=>"Sort by open date", :frame=>frame)
1564
+ link(:sort_by_due_date, :text=>"Sort by due date", :frame=>frame)
1565
+ link(:undo_last, :text=>"Undo last", :frame=>frame)
1566
+ link(:undo_all, :text=>"Undo all", :frame=>frame)
1567
+ button(:cancel, :value=>"Cancel", :frame=>frame)
1568
+ button(:save, :value=>"Save", :frame=>frame)
1569
+ end
1570
+
1571
+ end
1572
+
1573
+ # A Student user's page for editing/submitting/view an assignment.
1574
+ class AssignmentStudent
1575
+
1576
+ include PageObject
1577
+ include AssignmentsMenu
1578
+
1579
+ # Returns a hash object containing the contents of the Item Summary table.
1580
+ # The hash's Key is the header column and the value is the content column.
1581
+ def item_summary
1582
+ hash = {}
1583
+ frm.table(:class=>"itemSummary").rows.each do |row|
1584
+ hash.store(row.th.text, row.td.text)
1585
+ end
1586
+ return hash
1587
+ end
1588
+
1589
+ # Enters the specified text into the Assignment Text FCKEditor.
1590
+ def assignment_text=(text)
1591
+ frm.frame(:id, "Assignment.view_submission_text___Frame").td(:id, "xEditingArea").frame(:index=>0).send_keys(text)
1592
+ end
1593
+
1594
+ # Clears out any existing text from the Assignment Text FCKEditor.
1595
+ def remove_assignment_text
1596
+ frm.frame(:id, "Assignment.view_submission_text___Frame").div(:title=>"Select All").fire_event("onclick")
1597
+ frm.frame(:id, "Assignment.view_submission_text___Frame").td(:id, "xEditingArea").frame(:index=>0).send_keys :backspace
1598
+ end
1599
+
1600
+ # This class variable allows adding an arbitrary number of
1601
+ # files to the page, as long as the adding steps alternate between
1602
+ # selecting the file and clicking the add more files button
1603
+ @@file_number = 0
1604
+
1605
+ # Enters the specified file name into the file field (the
1606
+ # file is assumed to be in the data/sakai_cle folder in the
1607
+ # correct file path relative to the script being run).
1608
+ # Once the filename is entered in the field, the
1609
+ # @@file_number class variable is increased by one
1610
+ # in case any more files need to be added to the upload
1611
+ # list.
1612
+ def select_file=(file_name)
1613
+ frm.file_field(:id=>"clonableUpload", :name=>"upload#{@@file_number}").set(File.expand_path(File.dirname(__FILE__)) + "/../../data/sakai-cle-test-api/" + file_name)
1614
+ @@file_number += 1
1615
+ end
1616
+
1617
+ # Clicks the Submit button, then instantiates
1618
+ # the appropriate page class, based on the
1619
+ # page that gets loaded.
1620
+ def submit
1621
+ frm.button(:value=>"Submit").click
1622
+ @@file_number=0
1623
+ if frm.div(:class=>"portletBody").h3.text=~/Submission Confirmation/
1624
+ SubmissionConfirmation.new(@browser)
1625
+ elsif frm.button(:value=>"Back to list").exist?
1626
+ SubmissionConfirmation.new(@browser)
1627
+ else
1628
+ AssessmentsList.new(@browser)
1629
+ end
1630
+ end
1631
+
1632
+ # Clicks the Resubmit button, then instantiates
1633
+ # the appropriate page class, based on the
1634
+ # page that gets loaded.
1635
+ #
1636
+ # Resets @@file_number to zero so that file
1637
+ # uploads will work if this page is visited again
1638
+ # in the same script.
1639
+ def resubmit
1640
+ frm.button(:value=>"Resubmit").click
1641
+ @@file_number=0
1642
+ if frm.link(:text=>"Assignment title").exist?
1643
+ puts "list..."
1644
+ AssessmentsList.new(@browser)
1645
+ else
1646
+ SubmissionConfirmation.new(@browser)
1647
+ end
1648
+ end
1649
+
1650
+ # Clicks the Preview button, then
1651
+ # instantiates the AssignmentStudentPreview page class.
1652
+ #
1653
+ # Resets @@file_number to zero so that file
1654
+ # uploads will work if this page is visited again
1655
+ # in the same script.
1656
+ def preview
1657
+ frm.button(:value=>"Preview").click
1658
+ @@file_number=0
1659
+ AssignmentStudentPreview.new(@browser)
1660
+ end
1661
+
1662
+ # Clicks the Save Draft button, then
1663
+ # instantiates the SubmissionConfirmation
1664
+ # page class.
1665
+ def save_draft
1666
+ frm.button(:value=>"Save Draft").click
1667
+ SubmissionConfirmation.new(@browser)
1668
+ end
1669
+
1670
+ # Clicks the link to select more files
1671
+ # from the Workspace. Then instantiates
1672
+ # the AssignmentsAttachments page class.
1673
+ def select_more_files_from_workspace
1674
+ frm.link(:id=>"attach").click
1675
+ AssignmentsAttachments.new(@browser)
1676
+ end
1677
+
1678
+ in_frame(:index=>2) do |frame|
1679
+ link(:add_another_file, :id=>"addMoreAttachmentControls", :frame=>frame)
1680
+ h3(:header, :index=>0, :frame=>frame)
1681
+ button(:cancel, :value=>"Cancel", :frame=>frame)
1682
+ button(:back_to_list, :value=>"Back to list", :frame=>frame)
1683
+ div(:instructor_comments, :class=>"textPanel", :index=>2, :frame=>frame)
1684
+ end
1685
+
1686
+ end
1687
+
1688
+ # Page that appears when a Student User clicks to Preview an
1689
+ # assignment that is in progress.
1690
+ class AssignmentStudentPreview
1691
+
1692
+ include PageObject
1693
+ include AssignmentsMenu
1694
+
1695
+ # Clicks the Submit button, then
1696
+ # instantiates the SubmissionConfirmation
1697
+ # page class.
1698
+ def submit
1699
+ frm.button(:value=>"Submit").click
1700
+ SubmissionConfirmation.new(@browser)
1701
+ end
1702
+
1703
+ # Clicks the Save Draft button, then
1704
+ # instantiates the SubmissionConfirmation
1705
+ # page class.
1706
+ def save_draft
1707
+ frm.button(:value=>"Save Draft").click
1708
+ SubmissionConfirmation.new(@browser)
1709
+ end
1710
+
1711
+ # Returns the contents of the submission box.
1712
+ def submission_text
1713
+ frm.div(:class=>"portletBody").div(:class=>/textPanel/).text
1714
+ end
1715
+
1716
+ # Returns an array of strings. Each element in the
1717
+ # array is the name of attached files.
1718
+ def attachments
1719
+ names = []
1720
+ frm.ul(:class=>"attachList indnt1").links.each { |link| names << link.text }
1721
+ return names
1722
+ end
1723
+
1724
+ end
1725
+
1726
+ # The page that appears when a Student user has fully submitted an assignment
1727
+ # or saves it as a draft.
1728
+ class SubmissionConfirmation
1729
+
1730
+ include PageObject
1731
+ include AssignmentsMenu
1732
+
1733
+ # Returns the text of the success message on the page.
1734
+ def confirmation_text
1735
+ frm.div(:class=>"portletBody").div(:class=>"success").text
1736
+ end
1737
+
1738
+ # Returns the text of the assignment submission.
1739
+ def submission_text
1740
+ frm.div(:class=>"portletBody").div(:class=>"textPanel indnt2").text
1741
+ end
1742
+
1743
+ # Clicks the Back to list button, then
1744
+ # instantiates the Assignments page class.
1745
+ def back_to_list
1746
+ frm.button(:value=>"Back to list").click
1747
+ frm.link(:text=>"Assignment title").wait_until_present
1748
+ Assignments.new(@browser)
1749
+ end
1750
+ end
1751
+
1752
+ # The page that appears when you click on an assignment's "Grade" or "View Submission" link
1753
+ # as an instructor. Shows the list of students and their
1754
+ # assignment submission status.
1755
+ class AssignmentSubmissionList
1756
+
1757
+ include PageObject
1758
+ include AssignmentsMenu
1759
+
1760
+ # Clicks the Show Resubmission Settings button
1761
+ def show_resubmission_settings
1762
+ frm.image(:src, "/library/image/sakai/expand.gif?panel=Main").click
1763
+ end
1764
+
1765
+ # Clicks the Show Assignment Details button.
1766
+ def show_assignment_details
1767
+ frm.image(:src, "/library/image/sakai/expand.gif").click
1768
+ end
1769
+
1770
+ # Gets the Student table text and returns it in an Array object.
1771
+ def student_table
1772
+ table = frm.table(:class=>"listHier lines nolines").to_a
1773
+ end
1774
+
1775
+ # Clicks the Grade link for the specified student, then
1776
+ # instantiates the AssignmentSubmission page class.
1777
+ def grade(student_name)
1778
+ frm.table(:class=>"listHier lines nolines").row(:text=>/#{Regexp.escape(student_name)}/).link(:text=>"Grade").click
1779
+ frm.frame(:id, "grade_submission_feedback_comment___Frame").td(:id, "xEditingArea").frame(:index=>0).wait_until_present
1780
+ AssignmentSubmission.new(@browser)
1781
+ end
1782
+
1783
+ # Gets the value of the status field for the specified
1784
+ # Student. Note that the student's name needs to be entered
1785
+ # so that it's unique for the row, but it does not have
1786
+ # to match the entire name/id value--unless there are two
1787
+ # students with the same name.
1788
+ #
1789
+ # Useful for verification purposes.
1790
+ def submission_status_of(student_name)
1791
+ frm.table(:class=>"listHier lines nolines").row(:text=>/#{Regexp.escape(student_name)}/)[4].text
1792
+ end
1793
+
1794
+ in_frame(:index=>2) do |frame|
1795
+ text_field(:search_input, :id=>"search", :frame=>frame)
1796
+ button(:find, :value=>"Find", :frame=>frame)
1797
+ button(:clear, :value=>"Clear", :frame=>frame)
1798
+ link(:download_all, :text=>"Download All", :frame=>frame)
1799
+ link(:upload_all, :text=>"Upload All", :frame=>frame)
1800
+ link(:release_grades, :text=>"Release Grades", :frame=>frame)
1801
+ link(:sort_by_student, :text=>"Student", :frame=>frame)
1802
+ link(:sort_by_submitted, :text=>"Submitted", :frame=>frame)
1803
+ link(:sort_by_status, :text=>"Status", :frame=>frame)
1804
+ link(:sort_by_grade, :text=>"Grade", :frame=>frame)
1805
+ link(:sort_by_release, :text=>"Release", :frame=>frame)
1806
+ select_list(:default_grade, :id=>"defaultGrade_1", :frame=>frame)
1807
+ button(:apply, :name=>"apply", :frame=>frame)
1808
+ select_list(:num_resubmissions, :id=>"allowResubmitNumber", :frame=>frame)
1809
+ select_list(:accept_until_month, :id=>"allow_resubmit_closeMonth", :frame=>frame)
1810
+ select_list(:accept_until_day, :id=>"allow_resubmit_closeDay", :frame=>frame)
1811
+ select_list(:accept_until_year, :id=>"allow_resubmit_closeYear", :frame=>frame)
1812
+ select_list(:accept_until_hour, :id=>"allow_resubmit_closeHour", :frame=>frame)
1813
+ select_list(:accept_until_min, :id=>"allow_resubmit_closeMin", :frame=>frame)
1814
+ select_list(:accept_until_meridian, :id=>"allow_resubmit_closeAMPM", :frame=>frame)
1815
+ button(:update, :id=>"eventSubmit_doSave_resubmission_option", :frame=>frame)
1816
+ select_list(:select_page_size, :id=>"selectPageSize", :frame=>frame)
1817
+ button(:next, :name=>"eventSubmit_doList_next", :frame=>frame)
1818
+ button(:last, :name=>"eventSubmit_doList_last", :frame=>frame)
1819
+ button(:previous, :name=>"eventSubmit_doList_prev", :frame=>frame)
1820
+ button(:first, :name=>"eventSubmit_doList_first", :frame=>frame)
1821
+ button(:update, :name=>"eventSubmit_doDelete_confirm_assignment", :frame=>frame)
1822
+
1823
+ end
1824
+
1825
+ end
1826
+
1827
+ # The page that shows a student's submitted assignment to an instructor user.
1828
+ class AssignmentSubmission
1829
+
1830
+ include PageObject
1831
+ include AssignmentsMenu
1832
+
1833
+ # Enters the specified text string in the FCKEditor box for the assignment text.
1834
+ def assignment_text=(text)
1835
+ frm.frame(:id, "grade_submission_feedback_text___Frame").td(:id, "xEditingArea").frame(:index=>0).send_keys(text)
1836
+ end
1837
+
1838
+ # Removes all the contents of the FCKEditor Assignment Text box.
1839
+ def remove_assignment_text
1840
+ frm.frame(:id, "grade_submission_feedback_text___Frame").div(:title=>"Select All").fire_event("onclick")
1841
+ frm.frame(:id, "grade_submission_feedback_text___Frame").td(:id, "xEditingArea").frame(:index=>0).send_keys :backspace
1842
+ end
1843
+
1844
+ # Enters the specified string into the Instructor Comments FCKEditor box.
1845
+ def instructor_comments=(text)
1846
+ frm.frame(:id, "grade_submission_feedback_comment___Frame").td(:id, "xEditingArea").frame(:index=>0).send_keys(text)
1847
+ end
1848
+
1849
+ # Clicks the Add Attachments button, then instantiates the AssignmentsAttachments Class.
1850
+ def add_attachments
1851
+ frm.button(:name=>"attach").click
1852
+ AssignmentsAttachments.new(@browser)
1853
+ end
1854
+
1855
+ # Clicks the Return to List button, then instantiates the
1856
+ # AssignmentSubmissionList Class.
1857
+ def return_to_list
1858
+ frm.button(:value=>"Return to List").click
1859
+ AssignmentSubmissionList.new(@browser)
1860
+ end
1861
+
1862
+ in_frame(:index=>2) do |frame|
1863
+ select_list(:select_default_grade, :name=>"grade_submission_grade", :frame=>frame)
1864
+ checkbox(:allow_resubmission, :id=>"allowResToggle", :frame=>frame)
1865
+ select_list(:num_resubmissions, :id=>"allowResubmitNumberSelect", :frame=>frame)
1866
+ select_list(:accept_until_month, :id=>"allow_resubmit_closeMonth", :frame=>frame)
1867
+ select_list(:accept_until_day, :id=>"allow_resubmit_closeDay", :frame=>frame)
1868
+ select_list(:accept_until_year, :id=>"allow_resubmit_closeYear", :frame=>frame)
1869
+ select_list(:accept_until_hour, :id=>"allow_resubmit_closeHour", :frame=>frame)
1870
+ select_list(:accept_until_min, :id=>"allow_resubmit_closeMin", :frame=>frame)
1871
+ select_list(:accept_until_meridian, :id=>"allow_resubmit_closeAMPM", :frame=>frame)
1872
+ button(:save_and_release, :value=>"Save and Release to Student", :frame=>frame)
1873
+ button(:save_and_dont_release, :value=>"Save and Don't Release to Student", :frame=>frame)
1874
+ end
1875
+
1876
+ end
1877
+
1878
+ # The Grade Report page accessed from the Assignments page
1879
+ class GradeReport
1880
+
1881
+ include PageObject
1882
+ include AssignmentsMenu
1883
+
1884
+ # Returns an array of hashes. Each hash is a line from the
1885
+ # table. Hash keys are as follows:
1886
+ # :name, :assignment, :grade, :scale, :submitted
1887
+ def grade_report
1888
+ array = []
1889
+ frm.table(:class=>"listHier lines nolines").rows.each do |row|
1890
+ next if row.td(:headers=>"studentname").exists? == false
1891
+ hash = {}
1892
+ hash[:student] = row.td(:headers=>"").text
1893
+ hash[:assignment] = row.td(:headers=>"").text
1894
+ hash[:grade] = row.td(:headers=>"").text
1895
+ hash[:scale] = row.td(:headers=>"").text
1896
+ hash[:submitted] = row.td(:headers=>"").text
1897
+ array << hash
1898
+ end
1899
+ array
1900
+ end
1901
+
1902
+ in_frame(:index=>2) do |frame|
1903
+ h3(:header, :index=>0, :frame=>frame)
1904
+ paragraph(:instruction, :class=>"instruction", :frame=>frame)
1905
+ link(:sort_by_student_name, :title=>" Sort by Last Name", :frame=>frame)
1906
+ link(:sort_by_assignment, :title=>"Checkmark", :frame=>frame)
1907
+ link(:sort_by_grade, :title=>" Sort by Grade", :frame=>frame)
1908
+ link(:sort_by_scale, :title=>"Sort by Scale", :frame=>frame)
1909
+ link(:sort_by_submitted, :title=>"Sort by Turned In Date", :frame=>frame)
1910
+ select_list(:select_page_size, :id=>"selectPageSize", :frame=>frame)
1911
+ end
1912
+
1913
+ end
1914
+
1915
+ # The Student View page accessed from the Assignments page
1916
+ class StudentView
1917
+
1918
+ include PageObject
1919
+ include AssignmentsMenu
1920
+
1921
+ in_frame(:index=>2) do |frame|
1922
+ link(:sort_assignment_title, :text=>"Assignment title", :frame=>frame)
1923
+ link(:sort_status, :text=>"Status", :frame=>frame)
1924
+ link(:sort_open, :text=>"Open", :frame=>frame)
1925
+ link(:sort_due, :text=>"Due", :frame=>frame)
1926
+ link(:sort_scale, :text=>"Scale", :frame=>frame)
1927
+ select_list(:select_page_size, :name=>"selectPageSize", :frame=>frame)
1928
+ button(:next, :name=>"eventSubmit_doList_next", :frame=>frame)
1929
+ button(:last, :name=>"eventSubmit_doList_last", :frame=>frame)
1930
+ button(:previous, :name=>"eventSubmit_doList_prev", :frame=>frame)
1931
+ button(:first, :name=>"eventSubmit_doList_first", :frame=>frame)
1932
+ end
1933
+
1934
+ end
1935
+
1936
+ class AttachPageTools
1937
+
1938
+ @@classes = { :this=>"Superclassdummy", :parent=>"Superclassdummy" }
1939
+
1940
+ # Use this for debugging purposes only...
1941
+ def what_is_parent?
1942
+ puts @@classes[:parent]
1943
+ end
1944
+
1945
+ # Returns an array of the displayed folder names.
1946
+ def folder_names
1947
+ names = []
1948
+ frm.table(:class=>/listHier lines/, :text=>/Title/).rows.each do |row|
1949
+ next if row.td(:class=>"specialLink").exist? == false
1950
+ next if row.td(:class=>"specialLink").link(:title=>"Folder").exist? == false
1951
+ names << row.td(:class=>"specialLink").link(:title=>"Folder").text
1952
+ end
1953
+ return names
1954
+ end
1955
+
1956
+ # Returns an array containing the list of items that are
1957
+ # slated to be attached.
1958
+ def items_to_attach
1959
+ array = []
1960
+ frm.table(:text=>/Items to attach/).links(:href=>/access.content.attachment/).each { |link| array << link.text }
1961
+ array
1962
+ end
1963
+
1964
+ # Returns an array of the file names currently listed
1965
+ # on the page.
1966
+ #
1967
+ # It excludes folder names and does not include any items
1968
+ # slated to be attached.
1969
+ def file_names
1970
+ names = []
1971
+ frm.table(:class=>/listHier lines/, :text=>/Title/).rows.each do |row|
1972
+ next if row.td(:class=>"specialLink").exist? == false
1973
+ next if row.td(:class=>"specialLink").link(:title=>"Folder").exist?
1974
+ names << row.td(:class=>"specialLink").link(:href=>/access.content/, :index=>1).text
1975
+ end
1976
+ return names
1977
+ end
1978
+
1979
+ # Clicks the Select button next to the specified file.
1980
+ def select_file(filename)
1981
+ frm.table(:class=>/listHier lines/).row(:text, /#{Regexp.escape(filename)}/).link(:text=>"Select").click
1982
+ end
1983
+
1984
+ # Clicks the Remove button.
1985
+ def remove
1986
+ frm.button(:value=>"Remove").click
1987
+ end
1988
+
1989
+ # Clicks the remove link for the specified item in the attachment list.
1990
+ def remove_item(file_name)
1991
+ frm.table(:class=>/listHier/).row(:text=>/#{Regexp.escape(file_name)}/).link(:href=>/doRemoveitem/).click
1992
+ end
1993
+
1994
+ # Clicks the Move button.
1995
+ def move
1996
+ frm.button(:value=>"Move").click
1997
+ end
1998
+
1999
+ # Clicks the Show Other Sites link.
2000
+ def show_other_sites
2001
+ frm.link(:text=>"Show other sites").click
2002
+ end
2003
+
2004
+ # Clicks on the specified folder image, which
2005
+ # will open the folder tree and remain on the page.
2006
+ def open_folder(foldername)
2007
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(foldername)}/).link(:title=>"Open this folder").click
2008
+ end
2009
+
2010
+ # Clicks on the specified folder name, which should open
2011
+ # the folder contents on a refreshed page.
2012
+ def go_to_folder(foldername)
2013
+ frm.link(:text=>foldername).click
2014
+ end
2015
+
2016
+ # Sets the URL field to the specified value.
2017
+ def url=(url_string)
2018
+ frm.text_field(:id=>"url").set(url_string)
2019
+ end
2020
+
2021
+ # Clicks the Add button next to the URL field.
2022
+ def add
2023
+ frm.button(:value=>"Add").click
2024
+ end
2025
+
2026
+ # Gets the value of the access level cell for the specified
2027
+ # file.
2028
+ def access_level(filename)
2029
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(filename)}/)[6].text
2030
+ end
2031
+
2032
+ def edit_details(name)
2033
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(name)}/).li(:text=>/Action/, :class=>"menuOpen").fire_event("onclick")
2034
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(name)}/).link(:text=>"Edit Details").click
2035
+ instantiate_class(:file_details)
2036
+ end
2037
+
2038
+ # Enters the specified file into the file field name. Method takes an optional
2039
+ # file_path parameter that it will pre-pend before the supplied filename, allowing
2040
+ # the file name and path name to be distinct variables.
2041
+ #
2042
+ # Does NOT instantiate any class, so use only when no page refresh occurs.
2043
+ def upload_file(filename, file_path="")
2044
+ frm.file_field(:id=>"upload").set(file_path + filename)
2045
+ if frm.div(:class=>"alertMessage").exist?
2046
+ sleep 2
2047
+ upload_file(filename)
2048
+ end
2049
+ end
2050
+
2051
+ # Clicks the Add Menu for the specified
2052
+ # folder, then selects the Upload Files
2053
+ # command in the menu that appears.
2054
+ def upload_file_to_folder(folder_name)
2055
+ upload_files_to_folder(folder_name)
2056
+ end
2057
+
2058
+ # Clicks the Add Menu for the specified
2059
+ # folder, then selects the Upload Files
2060
+ # command in the menu that appears.
2061
+ def upload_files_to_folder(folder_name)
2062
+ if frm.li(:text=>/A/, :class=>"menuOpen").exist?
2063
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(folder_name)}/).li(:text=>/A/, :class=>"menuOpen").fire_event("onclick")
2064
+ else
2065
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(folder_name)}/).link(:text=>"Start Add Menu").fire_event("onfocus")
2066
+ end
2067
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(folder_name)}/).link(:text=>"Upload Files").click
2068
+ instantiate_class(:upload_files)
2069
+ end
2070
+
2071
+ # Clicks the "Attach a copy" link for the specified
2072
+ # file, then reinstantiates the Class.
2073
+ # If an alert box appears, the method will call itself again.
2074
+ # Note that this can lead to an infinite loop. Will need to fix later.
2075
+ def attach_a_copy(file_name)
2076
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(file_name)}/).link(:href=>/doAttachitem/).click
2077
+ if frm.div(:class=>"alertMessage").exist?
2078
+ sleep 1
2079
+ attach_a_copy(file_name) # TODO - This can loop infinitely
2080
+ end
2081
+ instantiate_class(:this)
2082
+ end
2083
+
2084
+ # Clicks the Create Folders menu item in the
2085
+ # Add menu of the specified folder.
2086
+ def create_subfolders_in(folder_name)
2087
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(folder_name)}/).link(:text=>"Start Add Menu").fire_event("onfocus")
2088
+ frm.table(:class=>/listHier lines/).row(:text=>/#{Regexp.escape(folder_name)}/).link(:text=>"Create Folders").click
2089
+ instantiate_class(:create_folders)
2090
+ end
2091
+
2092
+ # Takes the specified array object containing pointers
2093
+ # to local file resources, then uploads those files to
2094
+ # the folder specified, checks if they all uploaded properly and
2095
+ # if not, re-tries the ones that failed the first time.
2096
+ #
2097
+ # Finally, it re-instantiates the AnnouncementsAttach page class.
2098
+ def upload_multiple_files_to_folder(folder, file_array)
2099
+
2100
+ upload = upload_files_to_folder folder
2101
+
2102
+ file_array.each do |file|
2103
+ upload.file_to_upload=file
2104
+ upload.add_another_file
2105
+ end
2106
+
2107
+ resources = upload.upload_files_now
2108
+
2109
+ file_array.each do |file|
2110
+ file =~ /(?<=\/).+/
2111
+ # puts $~.to_s # For debugging purposes
2112
+ unless resources.file_names.include?($~.to_s)
2113
+ upload_files = resources.upload_files_to_folder(folder)
2114
+ upload_files.file_to_upload=file
2115
+ resources = upload_files.upload_files_now
2116
+ end
2117
+ end
2118
+ instantiate_class(:this)
2119
+ end
2120
+
2121
+ # Clicks the Continue button then
2122
+ # decides which page class to instantiate
2123
+ # based on the page that appears. This is going to need to be fixed.
2124
+ def continue
2125
+ frm.div(:class=>"highlightPanel").span(:id=>"submitnotifxxx").wait_while_present
2126
+ frm.button(:value=>"Continue").click
2127
+ end
2128
+
2129
+ private
2130
+
2131
+ # This is a private method that is only used inside this superclass.
2132
+ def instantiate_class(key)
2133
+ eval(@@classes[key]).new(@browser)
2134
+ end
2135
+
2136
+ # This is another private method--a better way to
2137
+ # instantiate the @@classes hash variable.
2138
+ def set_classes_hash(hash_object)
2139
+ @@classes = hash_object
2140
+ end
2141
+
2142
+ end
2143
+
2144
+ # Page for attaching files to Assignments
2145
+ class AssignmentsAttachments < AttachPageTools
2146
+
2147
+ include AssignmentsMenu
2148
+
2149
+ def initialize(browser)
2150
+ @browser = browser
2151
+
2152
+ @@classes = {
2153
+ :this => "AssignmentsAttachments",
2154
+ :parent => "AddAssignments",
2155
+ :second => "AssignmentStudent",
2156
+ :third => "AssignmentSubmission"
2157
+ }
2158
+ end
2159
+
2160
+ end