tarantula 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/CHANGELOG +2 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +106 -0
  4. data/Rakefile +80 -0
  5. data/init.rb +1 -0
  6. data/install.rb +1 -0
  7. data/laf/images/background.jpg +0 -0
  8. data/laf/images/relevance-os-logo.gif +0 -0
  9. data/laf/images/tab.png +0 -0
  10. data/laf/images/table-sort.gif +0 -0
  11. data/laf/images/tarantula-sprites.png +0 -0
  12. data/laf/javascripts/jquery-1.2.3.js +3408 -0
  13. data/laf/javascripts/jquery-ui-tabs.js +890 -0
  14. data/laf/javascripts/jquery.tablesorter.js +861 -0
  15. data/laf/javascripts/tarantula.js +10 -0
  16. data/laf/stylesheets/tarantula.css +638 -0
  17. data/laf/stylesheets/ui.tabs.css +113 -0
  18. data/lib/relevance/core_extensions/ellipsize.rb +34 -0
  19. data/lib/relevance/core_extensions/file.rb +9 -0
  20. data/lib/relevance/core_extensions/response.rb +9 -0
  21. data/lib/relevance/core_extensions/test_case.rb +12 -0
  22. data/lib/relevance/tarantula.rb +63 -0
  23. data/lib/relevance/tarantula/attack.rb +15 -0
  24. data/lib/relevance/tarantula/attack_form_submission.rb +75 -0
  25. data/lib/relevance/tarantula/attack_handler.rb +37 -0
  26. data/lib/relevance/tarantula/crawler.rb +240 -0
  27. data/lib/relevance/tarantula/detail.html.erb +77 -0
  28. data/lib/relevance/tarantula/form.rb +21 -0
  29. data/lib/relevance/tarantula/form_submission.rb +70 -0
  30. data/lib/relevance/tarantula/html_document_handler.rb +36 -0
  31. data/lib/relevance/tarantula/html_report_helper.rb +56 -0
  32. data/lib/relevance/tarantula/html_reporter.rb +105 -0
  33. data/lib/relevance/tarantula/index.html.erb +48 -0
  34. data/lib/relevance/tarantula/invalid_html_handler.rb +18 -0
  35. data/lib/relevance/tarantula/io_reporter.rb +34 -0
  36. data/lib/relevance/tarantula/link.rb +56 -0
  37. data/lib/relevance/tarantula/log_grabber.rb +16 -0
  38. data/lib/relevance/tarantula/rails_integration_proxy.rb +70 -0
  39. data/lib/relevance/tarantula/recording.rb +12 -0
  40. data/lib/relevance/tarantula/response.rb +13 -0
  41. data/lib/relevance/tarantula/result.rb +66 -0
  42. data/lib/relevance/tarantula/test_report.html.erb +34 -0
  43. data/lib/relevance/tarantula/tidy_handler.rb +32 -0
  44. data/lib/relevance/tarantula/transform.rb +17 -0
  45. data/manifest.txt +117 -0
  46. data/rails/init.rb +1 -0
  47. data/tarantula.gemspec +48 -0
  48. data/tasks/tarantula_tasks.rake +34 -0
  49. data/template/tarantula_test.rb +12 -0
  50. data/test/relevance/core_extensions/ellipsize_test.rb +19 -0
  51. data/test/relevance/core_extensions/file_test.rb +8 -0
  52. data/test/relevance/core_extensions/response_test.rb +29 -0
  53. data/test/relevance/core_extensions/test_case_test.rb +16 -0
  54. data/test/relevance/tarantula/attack_form_submission_test.rb +79 -0
  55. data/test/relevance/tarantula/attack_handler_test.rb +29 -0
  56. data/test/relevance/tarantula/crawler_test.rb +296 -0
  57. data/test/relevance/tarantula/form_submission_test.rb +71 -0
  58. data/test/relevance/tarantula/form_test.rb +50 -0
  59. data/test/relevance/tarantula/html_document_handler_test.rb +43 -0
  60. data/test/relevance/tarantula/html_report_helper_test.rb +47 -0
  61. data/test/relevance/tarantula/html_reporter_test.rb +82 -0
  62. data/test/relevance/tarantula/invalid_html_handler_test.rb +33 -0
  63. data/test/relevance/tarantula/io_reporter_test.rb +11 -0
  64. data/test/relevance/tarantula/link_test.rb +61 -0
  65. data/test/relevance/tarantula/log_grabber_test.rb +26 -0
  66. data/test/relevance/tarantula/rails_integration_proxy_test.rb +94 -0
  67. data/test/relevance/tarantula/result_test.rb +85 -0
  68. data/test/relevance/tarantula/tidy_handler_test.rb +58 -0
  69. data/test/relevance/tarantula/transform_test.rb +21 -0
  70. data/test/relevance/tarantula_test.rb +23 -0
  71. data/test/test_helper.rb +34 -0
  72. data/tmp/test_output/images/background.jpg +0 -0
  73. data/tmp/test_output/images/relevance-os-logo.gif +0 -0
  74. data/tmp/test_output/images/tab.png +0 -0
  75. data/tmp/test_output/images/table-sort.gif +0 -0
  76. data/tmp/test_output/images/tarantula-sprites.png +0 -0
  77. data/tmp/test_output/index.html +255 -0
  78. data/tmp/test_output/javascripts/jquery-1.2.3.js +3408 -0
  79. data/tmp/test_output/javascripts/jquery-ui-tabs.js +890 -0
  80. data/tmp/test_output/javascripts/jquery.tablesorter.js +861 -0
  81. data/tmp/test_output/javascripts/tarantula.js +10 -0
  82. data/tmp/test_output/stylesheets/tarantula.css +638 -0
  83. data/tmp/test_output/stylesheets/ui.tabs.css +113 -0
  84. data/tmp/test_output/test_user_pages/1.html +71 -0
  85. data/tmp/test_output/test_user_pages/10.html +71 -0
  86. data/tmp/test_output/test_user_pages/11.html +71 -0
  87. data/tmp/test_output/test_user_pages/12.html +71 -0
  88. data/tmp/test_output/test_user_pages/13.html +71 -0
  89. data/tmp/test_output/test_user_pages/14.html +71 -0
  90. data/tmp/test_output/test_user_pages/15.html +71 -0
  91. data/tmp/test_output/test_user_pages/16.html +71 -0
  92. data/tmp/test_output/test_user_pages/17.html +71 -0
  93. data/tmp/test_output/test_user_pages/18.html +71 -0
  94. data/tmp/test_output/test_user_pages/19.html +71 -0
  95. data/tmp/test_output/test_user_pages/2.html +71 -0
  96. data/tmp/test_output/test_user_pages/20.html +71 -0
  97. data/tmp/test_output/test_user_pages/3.html +71 -0
  98. data/tmp/test_output/test_user_pages/4.html +71 -0
  99. data/tmp/test_output/test_user_pages/5.html +71 -0
  100. data/tmp/test_output/test_user_pages/6.html +71 -0
  101. data/tmp/test_output/test_user_pages/7.html +71 -0
  102. data/tmp/test_output/test_user_pages/8.html +71 -0
  103. data/tmp/test_output/test_user_pages/9.html +71 -0
  104. data/uninstall.rb +1 -0
  105. data/vendor/xss-shield/MIT-LICENSE +20 -0
  106. data/vendor/xss-shield/README +76 -0
  107. data/vendor/xss-shield/init.rb +16 -0
  108. data/vendor/xss-shield/lib/xss_shield.rb +6 -0
  109. data/vendor/xss-shield/lib/xss_shield/erb_hacks.rb +111 -0
  110. data/vendor/xss-shield/lib/xss_shield/haml_hacks.rb +42 -0
  111. data/vendor/xss-shield/lib/xss_shield/safe_string.rb +47 -0
  112. data/vendor/xss-shield/lib/xss_shield/secure_helpers.rb +40 -0
  113. data/vendor/xss-shield/test/test_actionview_integration.rb +40 -0
  114. data/vendor/xss-shield/test/test_erb.rb +44 -0
  115. data/vendor/xss-shield/test/test_haml.rb +43 -0
  116. data/vendor/xss-shield/test/test_helpers.rb +25 -0
  117. data/vendor/xss-shield/test/test_safe_string.rb +55 -0
  118. metadata +283 -0
@@ -0,0 +1,85 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
2
+
3
+ describe "Relevance::Tarantula::Result" do
4
+ before do
5
+ @result = Relevance::Tarantula::Result.new(
6
+ :success => true,
7
+ :method => "get",
8
+ :url => "/some/url?arg1=foo&arg2=bar"
9
+ )
10
+ end
11
+
12
+ it "has a short description" do
13
+ @result.short_description.should == "get /some/url?arg1=foo&arg2=bar"
14
+ end
15
+
16
+ it "has a sequence number" do
17
+ @result.class.next_number = 0
18
+ @result.sequence_number.should == 1
19
+ @result.class.next_number.should == 1
20
+ end
21
+
22
+ it "has link to the url at localhost" do
23
+ @result.full_url.should == "http://localhost:3000/some/url?arg1=foo&arg2=bar"
24
+ end
25
+
26
+ end
27
+
28
+ describe "Relevance::Tarantula::Result class methods" do
29
+ before do
30
+ @rh = Relevance::Tarantula::Result
31
+ end
32
+
33
+ it "defines HTTP responses that are considered 'successful' when spidering" do
34
+ %w{200 201 302 401}.each do |code|
35
+ @rh.successful?(stub(:code => code)).should == true
36
+ end
37
+ end
38
+
39
+ it "adds successful responses to success collection" do
40
+ stub = stub_everything(:code => "200")
41
+ @rh.handle(Relevance::Tarantula::Result.new(:response => stub)).success.should == true
42
+ end
43
+
44
+ it "adds failed responses to failure collection" do
45
+ stub = stub_everything(:code => "500")
46
+ result = @rh.handle(Relevance::Tarantula::Result.new(:response => stub))
47
+ result.success.should == false
48
+ result.description.should == "Bad HTTP Response"
49
+ end
50
+
51
+ end
52
+
53
+ describe "Relevance::Tarantula::Result allowed errors" do
54
+ before do
55
+ Relevance::Tarantula::Result.allow_errors_for = {}
56
+ end
57
+
58
+ it "defaults to *not* skip errors" do
59
+ Relevance::Tarantula::Result.can_skip_error?(stub(:code => "404")).should == false
60
+ end
61
+
62
+ it "can skip errors matching code and url" do
63
+ Relevance::Tarantula::Result.allow_errors_for = {"404" => [/some_url/]}
64
+ Relevance::Tarantula::Result.can_skip_error?(stub(:code => "404", :url => "this_is_some_url")).should == true
65
+ end
66
+
67
+ it "does not skip errors matching code only" do
68
+ Relevance::Tarantula::Result.allow_errors_for = {"404" => [/some_other_url/]}
69
+ Relevance::Tarantula::Result.can_skip_error?(stub(:code => "404", :url => "this_is_some_url")).should == false
70
+ end
71
+
72
+ it "users allow_nnn_for syntax to specify allowed errors" do
73
+ Relevance::Tarantula::Result.allow_404_for(/this_url/)
74
+ Relevance::Tarantula::Result.allow_errors_for.should == {"404" => [/this_url/]}
75
+ Relevance::Tarantula::Result.allow_404_for(/another_url/)
76
+ Relevance::Tarantula::Result.allow_errors_for.should == {"404" => [/this_url/, /another_url/]}
77
+ end
78
+
79
+ it "chains to super method missing" do
80
+ lambda{Relevance::Tarantula::Result.allow_xxx_for}.should.raise(NoMethodError)
81
+ end
82
+
83
+ end
84
+
85
+
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
2
+
3
+ if defined?(Tidy) && ENV['TIDY_PATH']
4
+ describe "Relevance::Tarantula::TidyHandler default" do
5
+ before do
6
+ @handler = Relevance::Tarantula::TidyHandler.new
7
+ end
8
+
9
+ it "likes a good document" do
10
+ response = stub(:html? => true, :body => <<-BODY, :code => 200)
11
+ <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2//EN\">
12
+ <html>
13
+ <title></title>
14
+ <body></body>
15
+ </html>
16
+ BODY
17
+ @handler.handle(Result.new(:response => response)).should == nil
18
+ end
19
+
20
+ it "rejects a document with errors" do
21
+ response = stub(:html? => true, :body => "<hotml>", :code => 200)
22
+ result = @handler.handle(Result.new(:response => response))
23
+ result.should.not.be nil
24
+ result.data.should =~ /Error: <hotml> is not recognized!/
25
+ result.description.should == "Bad HTML (Tidy)"
26
+ end
27
+
28
+ it "rejects a document with warnings" do
29
+ response = stub(:html? => true, :body => <<-BODY, :code => 200)
30
+ <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2//EN\">
31
+ <html>
32
+ </html>
33
+ BODY
34
+ result = @handler.handle(Result.new(:response => response))
35
+ result.should.not.be nil
36
+ result.data.should =~ /Warning: inserting missing 'title' element/
37
+ end
38
+
39
+ end
40
+
41
+ describe "Relevance::Tarantula::TidyHandler with :show_warnings => false" do
42
+ before do
43
+ @handler = Relevance::Tarantula::TidyHandler.new(:show_warnings => false)
44
+ end
45
+
46
+ it "permits a document with warnings" do
47
+ response = stub(:html? => true, :body => <<-BODY, :code => 200)
48
+ <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2//EN\">
49
+ <html>
50
+ </html>
51
+ BODY
52
+ result = @handler.handle(Result.new(:response => response))
53
+ result.should.be nil
54
+ end
55
+ end
56
+ else
57
+ puts "TIDY_PATH not set. Tidy test will not run"
58
+ end
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__), "../..", "test_helper.rb")
2
+
3
+ describe "Relevance::Tarantula::Transform" do
4
+ it "can do a simple replace" do
5
+ t = Relevance::Tarantula::Transform.new(/\w/, ".")
6
+ t["hello world"].should == "..... ....."
7
+ end
8
+
9
+ it "can do a replace with a block" do
10
+ t = Relevance::Tarantula::Transform.new(/([aeiou])/, Proc.new {|value| value.upcase})
11
+ t["hello world"].should == "hEllO wOrld"
12
+ end
13
+
14
+ # this is broken in Ruby?
15
+ it "cannot access groups from a block, despite Ruby docs" do
16
+ p = Proc.new {|value| $1.upcase}
17
+ t = Relevance::Tarantula::Transform.new(/([aeiou])/, p)
18
+ lambda {t["hello world"]}.should.raise(NoMethodError).message.should ==
19
+ "undefined method `upcase' for nil:NilClass"
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ require File.join(File.dirname(__FILE__), "..", "test_helper.rb")
2
+
3
+ describe "Relevance::Tarantula" do
4
+ include Relevance::Tarantula
5
+ attr_accessor :verbose
6
+
7
+ it "writes to stdout if verbose" do
8
+ self.verbose = true
9
+ expects(:puts).with("foo")
10
+ log("foo")
11
+ end
12
+
13
+ it "swallows output if !verbose" do
14
+ self.verbose = false
15
+ expects(:puts).never
16
+ log("foo")
17
+ end
18
+
19
+ it "puts RAILS_ROOT behind a method call" do
20
+ lambda{rails_root}.should.raise(NameError).message.should == "uninitialized constant RAILS_ROOT"
21
+ end
22
+ end
23
+
@@ -0,0 +1,34 @@
1
+ basedir = File.dirname(__FILE__)
2
+ $:.unshift "#{basedir}/../lib"
3
+ require 'rubygems'
4
+ gem 'ruby-debug'
5
+ gem 'test-spec'
6
+ gem 'actionpack'
7
+ gem 'activerecord'
8
+ gem 'activesupport'
9
+
10
+ require 'test/spec'
11
+ require 'mocha'
12
+ require 'ostruct'
13
+ require 'ruby-debug'
14
+ require 'activerecord'
15
+ require 'relevance/tarantula'
16
+
17
+ # needed for html-scanner, grr
18
+ require 'active_support'
19
+ require 'action_controller'
20
+
21
+ require 'redgreen' unless (Object.const_defined?("TextMate") || ENV["EMACS"]) rescue nil # just a nice to have, don't blow up if not there
22
+
23
+ class Test::Unit::TestCase
24
+ def test_output_dir
25
+ File.join(File.dirname(__FILE__), "..", "tmp", "test_output")
26
+ end
27
+
28
+ # TODO change puts/print to use a single method for logging, which will then make the stubbing cleaner
29
+ def stub_puts_and_print(obj)
30
+ obj.stubs(:puts)
31
+ obj.stubs(:print)
32
+ end
33
+
34
+ end
Binary file
@@ -0,0 +1,255 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+
3
+ <html>
4
+ <head>
5
+ <meta content="text/html; charset=utf-8" http-equiv="Content-type" />
6
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
7
+ <meta name="Author" content="Erik Yowell; erik[at]thinkrelevance.com" />
8
+ <title>Tarantula report</title>
9
+ <script src="javascripts/jquery-1.2.3.js" type="text/javascript"></script>
10
+ <script src="javascripts/jquery.tablesorter.js" type="text/javascript"></script>
11
+ <script src="javascripts/jquery-ui-tabs.js" type="text/javascript"></script>
12
+ <script src="javascripts/tarantula.js" type="text/javascript"></script>
13
+ <link href="stylesheets/tarantula.css" rel="stylesheet" type="text/css" media="screen" />
14
+ <link href="stylesheets/ui.tabs.css" rel="stylesheet" type="text/css" media="screen" />
15
+ </head>
16
+
17
+ <body id="top">
18
+
19
+ <div id="container">
20
+
21
+ <div id="header">
22
+ <hr class="top" />
23
+ <h1><span>Tarantula : Eight Legs, Two Fangs, and an Attitude</span></h1>
24
+ <ul class="navigation">
25
+ <li><a href="#" class="result-all"><span>All</span> <em>20</em></a></li>
26
+ <li><a href="#" class="result-failure"><span>Failures</span> <em>10</em></a></li>
27
+ <li><a href="#" class="result-success"><span>Successful</span> <em>10</em></a></li>
28
+ </ul>
29
+ </div>
30
+ </div>
31
+ <div id="page-container">
32
+ <hr class="top" />
33
+ <div id="page">
34
+ <p>Generated on Fri Sep 26 11:33:58 -0400 2008</p>
35
+ <div id="tabs-container">
36
+ <ul>
37
+ <li><a href="#test_user_pages"><span>test_user_pages</span></a></li></ul>
38
+ <div id="test_user_pages">
39
+
40
+ <table cellspacing="0" class="grid tablesorter">
41
+ <caption>Failures (10)</caption>
42
+ <thead>
43
+ <tr>
44
+ <th class="sort asc"><span>URL</span><span class="sort"><em>&#8613;</em></span></th>
45
+ <th><span>Action</span><span class="sort"><em>&#8613;</em></span></th>
46
+ <th><span>Response</span><span class="sort"><em>&#8613;</em></span></th>
47
+ <th><span>Description</span><span class="sort"><em>&#8613;</em></span></th>
48
+ <th><span>Referrer</span><span class="sort"><em>&#8613;</em></span></th>
49
+ </tr>
50
+ </thead>
51
+ <tfoot>
52
+ <tr>
53
+ <td colspan="5">
54
+ Footer
55
+ </td>
56
+ </tr>
57
+ </tfoot>
58
+ <tbody>
59
+
60
+ <tr>
61
+ <td class="left"><a href="test_user_pages/11.html">/widgets/1</a></td>
62
+ <td class="center">get</td>
63
+ <td class="center"><span class="r5">500</span></td>
64
+ <td></td>
65
+ <td>/random/92</td>
66
+ </tr>
67
+
68
+ <tr>
69
+ <td class="left"><a href="test_user_pages/12.html">/widgets/2</a></td>
70
+ <td class="center">get</td>
71
+ <td class="center"><span class="r5">500</span></td>
72
+ <td></td>
73
+ <td>/random/83</td>
74
+ </tr>
75
+
76
+ <tr>
77
+ <td class="left"><a href="test_user_pages/13.html">/widgets/3</a></td>
78
+ <td class="center">get</td>
79
+ <td class="center"><span class="r5">500</span></td>
80
+ <td></td>
81
+ <td>/random/7</td>
82
+ </tr>
83
+
84
+ <tr>
85
+ <td class="left"><a href="test_user_pages/14.html">/widgets/4</a></td>
86
+ <td class="center">get</td>
87
+ <td class="center"><span class="r5">500</span></td>
88
+ <td></td>
89
+ <td>/random/97</td>
90
+ </tr>
91
+
92
+ <tr>
93
+ <td class="left"><a href="test_user_pages/15.html">/widgets/5</a></td>
94
+ <td class="center">get</td>
95
+ <td class="center"><span class="r5">500</span></td>
96
+ <td></td>
97
+ <td>/random/49</td>
98
+ </tr>
99
+
100
+ <tr>
101
+ <td class="left"><a href="test_user_pages/16.html">/widgets/6</a></td>
102
+ <td class="center">get</td>
103
+ <td class="center"><span class="r5">500</span></td>
104
+ <td></td>
105
+ <td>/random/89</td>
106
+ </tr>
107
+
108
+ <tr>
109
+ <td class="left"><a href="test_user_pages/17.html">/widgets/7</a></td>
110
+ <td class="center">get</td>
111
+ <td class="center"><span class="r5">500</span></td>
112
+ <td></td>
113
+ <td>/random/62</td>
114
+ </tr>
115
+
116
+ <tr>
117
+ <td class="left"><a href="test_user_pages/18.html">/widgets/8</a></td>
118
+ <td class="center">get</td>
119
+ <td class="center"><span class="r5">500</span></td>
120
+ <td></td>
121
+ <td>/random/70</td>
122
+ </tr>
123
+
124
+ <tr>
125
+ <td class="left"><a href="test_user_pages/19.html">/widgets/9</a></td>
126
+ <td class="center">get</td>
127
+ <td class="center"><span class="r5">500</span></td>
128
+ <td></td>
129
+ <td>/random/15</td>
130
+ </tr>
131
+
132
+ <tr>
133
+ <td class="left"><a href="test_user_pages/20.html">/widgets/10</a></td>
134
+ <td class="center">get</td>
135
+ <td class="center"><span class="r5">500</span></td>
136
+ <td></td>
137
+ <td>/random/67</td>
138
+ </tr>
139
+
140
+ </tbody>
141
+ </table>
142
+
143
+ <table cellspacing="0" class="grid tablesorter">
144
+ <caption>Successes (10)</caption>
145
+ <thead>
146
+ <tr>
147
+ <th class="sort asc"><span>URL</span><span class="sort"><em>&#8613;</em></span></th>
148
+ <th><span>Action</span><span class="sort"><em>&#8613;</em></span></th>
149
+ <th><span>Response</span><span class="sort"><em>&#8613;</em></span></th>
150
+ <th><span>Description</span><span class="sort"><em>&#8613;</em></span></th>
151
+ <th><span>Referrer</span><span class="sort"><em>&#8613;</em></span></th>
152
+ </tr>
153
+ </thead>
154
+ <tfoot>
155
+ <tr>
156
+ <td colspan="5">
157
+ Footer
158
+ </td>
159
+ </tr>
160
+ </tfoot>
161
+ <tbody>
162
+
163
+ <tr>
164
+ <td class="left"><a href="test_user_pages/1.html">/widgets/1</a></td>
165
+ <td class="center">get</td>
166
+ <td class="center"><span class="r2">200</span></td>
167
+ <td></td>
168
+ <td>/random/36</td>
169
+ </tr>
170
+
171
+ <tr>
172
+ <td class="left"><a href="test_user_pages/2.html">/widgets/2</a></td>
173
+ <td class="center">get</td>
174
+ <td class="center"><span class="r2">200</span></td>
175
+ <td></td>
176
+ <td>/random/88</td>
177
+ </tr>
178
+
179
+ <tr>
180
+ <td class="left"><a href="test_user_pages/3.html">/widgets/3</a></td>
181
+ <td class="center">get</td>
182
+ <td class="center"><span class="r2">200</span></td>
183
+ <td></td>
184
+ <td>/random/53</td>
185
+ </tr>
186
+
187
+ <tr>
188
+ <td class="left"><a href="test_user_pages/4.html">/widgets/4</a></td>
189
+ <td class="center">get</td>
190
+ <td class="center"><span class="r2">200</span></td>
191
+ <td></td>
192
+ <td>/random/91</td>
193
+ </tr>
194
+
195
+ <tr>
196
+ <td class="left"><a href="test_user_pages/5.html">/widgets/5</a></td>
197
+ <td class="center">get</td>
198
+ <td class="center"><span class="r2">200</span></td>
199
+ <td></td>
200
+ <td>/random/12</td>
201
+ </tr>
202
+
203
+ <tr>
204
+ <td class="left"><a href="test_user_pages/6.html">/widgets/6</a></td>
205
+ <td class="center">get</td>
206
+ <td class="center"><span class="r2">200</span></td>
207
+ <td></td>
208
+ <td>/random/97</td>
209
+ </tr>
210
+
211
+ <tr>
212
+ <td class="left"><a href="test_user_pages/7.html">/widgets/7</a></td>
213
+ <td class="center">get</td>
214
+ <td class="center"><span class="r2">200</span></td>
215
+ <td></td>
216
+ <td>/random/93</td>
217
+ </tr>
218
+
219
+ <tr>
220
+ <td class="left"><a href="test_user_pages/8.html">/widgets/8</a></td>
221
+ <td class="center">get</td>
222
+ <td class="center"><span class="r2">200</span></td>
223
+ <td></td>
224
+ <td>/random/95</td>
225
+ </tr>
226
+
227
+ <tr>
228
+ <td class="left"><a href="test_user_pages/9.html">/widgets/9</a></td>
229
+ <td class="center">get</td>
230
+ <td class="center"><span class="r2">200</span></td>
231
+ <td></td>
232
+ <td>/random/62</td>
233
+ </tr>
234
+
235
+ <tr>
236
+ <td class="left"><a href="test_user_pages/10.html">/widgets/10</a></td>
237
+ <td class="center">get</td>
238
+ <td class="center"><span class="r2">200</span></td>
239
+ <td></td>
240
+ <td>/random/13</td>
241
+ </tr>
242
+
243
+ </tbody>
244
+ </table>
245
+
246
+ </div></div>
247
+ </div>
248
+ <div id="sidebar">
249
+ <h3><span>Tarantula</span></h3>
250
+ <p>Tarantula is an open-source tool for testing Rails web applications. Tarantula is developed by <a href="http://thinkrelevance.com">Relevance, Inc.</a> and lives at <a href="http://opensource.thinkrelevance.com">http://opensource.thinkrelevance.com</a>.</p>
251
+ </div>
252
+ </div>
253
+ </body>
254
+
255
+ </html>