rutemaweb 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/Manifest.txt +4 -2
- data/README.txt +0 -4
- data/Rakefile +6 -9
- data/lib/rutemaweb/gems.rb +6 -3
- data/lib/rutemaweb/main.rb +3 -1
- data/lib/rutemaweb/model.rb +60 -0
- data/lib/rutemaweb/public/css/style.css +1 -1
- data/lib/rutemaweb/public/images/left.png +0 -0
- data/lib/rutemaweb/public/images/right.png +0 -0
- data/lib/rutemaweb/ramaze_controller.rb +240 -72
- data/lib/rutemaweb/ruport_formatter.rb +1 -1
- data/lib/rutemaweb/view/layout.rhtml +4 -2
- data/test/test_rutemaweb.rb +107 -0
- metadata +15 -32
- data/lib/rutemaweb/public/.DS_Store +0 -0
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
=== 0.9.0 / 2008-10-06
|
2
|
+
* Updated design (actually designed something that is half-way usable)
|
3
|
+
* Left panel lists latest runs with status
|
4
|
+
* Scenario list now shows title and description
|
5
|
+
* Lists are now paginated
|
6
|
+
* requires rutema 1.0.0
|
7
|
+
* Moved up to ActiveRecord 2.1.1 and Ramaze 2008.06
|
8
|
+
|
1
9
|
=== 0.8.0 / 2008-07-03
|
2
10
|
* rutemaweb gets it's own gem!
|
3
11
|
* Test case presentation now vertical with new ruport formatter.
|
data/Manifest.txt
CHANGED
@@ -6,7 +6,7 @@ Rakefile
|
|
6
6
|
bin/rutemaweb
|
7
7
|
lib/rutemaweb/gems.rb
|
8
8
|
lib/rutemaweb/main.rb
|
9
|
-
lib/rutemaweb/
|
9
|
+
lib/rutemaweb/model.rb
|
10
10
|
lib/rutemaweb/public/css/style.css
|
11
11
|
lib/rutemaweb/public/images/bg_menu.gif
|
12
12
|
lib/rutemaweb/public/images/bg_submenu.gif
|
@@ -17,8 +17,10 @@ lib/rutemaweb/public/images/step_error.png
|
|
17
17
|
lib/rutemaweb/public/images/step_ok.png
|
18
18
|
lib/rutemaweb/public/images/step_warn.png
|
19
19
|
lib/rutemaweb/public/images/tie_logo.gif
|
20
|
+
lib/rutemaweb/public/images/left.png
|
21
|
+
lib/rutemaweb/public/images/right.png
|
20
22
|
lib/rutemaweb/public/js/folding.js
|
21
23
|
lib/rutemaweb/ramaze_controller.rb
|
22
24
|
lib/rutemaweb/ruport_formatter.rb
|
23
25
|
lib/rutemaweb/view/layout.rhtml
|
24
|
-
|
26
|
+
test/test_rutemaweb.rb
|
data/README.txt
CHANGED
@@ -7,12 +7,10 @@ It can be used as a viewer for database files created with the ActiveRecord repo
|
|
7
7
|
|
8
8
|
== FEATURES/PROBLEMS:
|
9
9
|
|
10
|
-
|
11
10
|
== SYNOPSIS:
|
12
11
|
rutemaweb [results.db] and browse to http://localhost:7000 for the glorious view
|
13
12
|
|
14
13
|
== REQUIREMENTS:
|
15
|
-
|
16
14
|
* patir (http://patir.rubyforge.org)
|
17
15
|
* activerecord (http://ar.rubyonrails.com/)
|
18
16
|
* sqlite3 (http://rubyforge.org/projects/sqlite-ruby/)
|
@@ -22,11 +20,9 @@ rutemaweb [results.db] and browse to http://localhost:7000 for the glorious view
|
|
22
20
|
* erubis
|
23
21
|
|
24
22
|
== INSTALL:
|
25
|
-
|
26
23
|
* sudo gem install rutemaweb
|
27
24
|
|
28
25
|
== LICENSE:
|
29
|
-
|
30
26
|
(The Ruby License)
|
31
27
|
|
32
28
|
rutema is copyright (c) 2007 Vassilis Rizopoulos
|
data/Rakefile
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# Copyright (c) 2008 Vassilis Rizopoulos. All rights reserved.
|
2
2
|
# -*- ruby -*-
|
3
3
|
$:.unshift File.join(File.dirname(__FILE__),"lib")
|
4
|
-
|
4
|
+
require 'rutemaweb/main'
|
5
5
|
require 'rubygems'
|
6
6
|
require 'hoe'
|
7
|
-
require 'rutemaweb/main'
|
8
7
|
|
9
8
|
Hoe.new('rutemaweb', "#{RutemaWeb::Version::STRING}") do |p|
|
10
9
|
p.rubyforge_name = 'patir'
|
@@ -14,15 +13,13 @@ Hoe.new('rutemaweb', "#{RutemaWeb::Version::STRING}") do |p|
|
|
14
13
|
p.description = p.paragraphs_of('README.txt', 1..5).join("\n\n")
|
15
14
|
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
16
15
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
17
|
-
p.extra_deps<<['patir',">=0.
|
18
|
-
p.extra_deps<<['rutema',">=0.
|
19
|
-
p.extra_deps<<['activerecord','=2.
|
16
|
+
p.extra_deps<<['patir',">=0.6.0"]
|
17
|
+
p.extra_deps<<['rutema',">=1.0.0"]
|
18
|
+
p.extra_deps<<['activerecord','=2.1.1']
|
20
19
|
p.extra_deps<<['ruport']
|
21
|
-
p.extra_deps<<['
|
22
|
-
p.extra_deps<<['ramaze','=0.3.9.1']
|
20
|
+
p.extra_deps<<['ramaze','=2008.06']
|
23
21
|
p.extra_deps<<['erubis']
|
24
|
-
p.extra_deps<<['
|
25
|
-
p.extra_deps<<['mailfactory']
|
22
|
+
p.extra_deps<<['acts_as_reportable']
|
26
23
|
p.spec_extras={:executables=>["rutemaweb"],
|
27
24
|
:default_executable=>"rutemaweb"}
|
28
25
|
end
|
data/lib/rutemaweb/gems.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
gem 'ramaze','=
|
2
|
+
gem 'ramaze','=2008.06'
|
3
3
|
require 'ramaze'
|
4
|
-
#
|
5
|
-
|
4
|
+
#this fixes a clash with activesupport 2.1.1 (because it checks start_with? but not end_with?)
|
5
|
+
#end Ramaze on 1.8.6 only creates a start_with? method
|
6
|
+
class String; undef_method :start_with? end
|
7
|
+
gem 'activerecord','=2.1.1'
|
6
8
|
require 'active_record'
|
9
|
+
gem 'rutema',"=1.0.0"
|
7
10
|
require 'patir/configuration'
|
8
11
|
require 'patir/command'
|
9
12
|
require 'patir/base'
|
data/lib/rutemaweb/main.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
$:.unshift File.join(File.dirname(__FILE__),"..")
|
2
|
+
require 'rutemaweb/gems'
|
2
3
|
require 'rutemaweb/ramaze_controller'
|
3
4
|
|
4
5
|
#This is the web frontend for Rutema databases.
|
@@ -7,7 +8,7 @@ module RutemaWeb
|
|
7
8
|
#This module defines the version numbers for the library
|
8
9
|
module Version
|
9
10
|
MAJOR=0
|
10
|
-
MINOR=
|
11
|
+
MINOR=9
|
11
12
|
TINY=0
|
12
13
|
STRING=[ MAJOR, MINOR, TINY ].join( "." )
|
13
14
|
end
|
@@ -17,6 +18,7 @@ module RutemaWeb
|
|
17
18
|
db_file=parse_command_line(ARGV)
|
18
19
|
db_file=File.expand_path(db_file)
|
19
20
|
Rutema.connect_to_ar(db_file,logger)
|
21
|
+
Rutema::UI.ramaze_settings
|
20
22
|
Ramaze.start :force=>true
|
21
23
|
end
|
22
24
|
#Parses the command line arguments
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (c) 2008 Vassilis Rizopoulos. All rights reserved.
|
2
|
+
$:.unshift File.join(File.dirname(__FILE__),"..")
|
3
|
+
require 'rutemaweb/gems'
|
4
|
+
|
5
|
+
|
6
|
+
module Rutema
|
7
|
+
|
8
|
+
module Model
|
9
|
+
#Extensions of Run to accomodate specific view requirements for rutemaweb
|
10
|
+
class Run <ActiveRecord::Base
|
11
|
+
# The view wants to display runs grouped into pages,
|
12
|
+
# where each page shows page_size runs at a time.
|
13
|
+
# This method returns the runs on page page_num (starting
|
14
|
+
# at zero).
|
15
|
+
def self.find_on_page(page_num, page_size,conditions=nil)
|
16
|
+
find(:all,
|
17
|
+
:order => "id DESC",
|
18
|
+
:limit => page_size,
|
19
|
+
:conditions=>conditions,
|
20
|
+
:offset => page_num*page_size)
|
21
|
+
end
|
22
|
+
|
23
|
+
def status
|
24
|
+
st=:success
|
25
|
+
st=:warning if scenarios.empty?
|
26
|
+
self.scenarios.each do |sc|
|
27
|
+
case sc.status
|
28
|
+
when "warning" || "not_executed"
|
29
|
+
st=:warning unless st==:error
|
30
|
+
break
|
31
|
+
when "error"
|
32
|
+
st=:error
|
33
|
+
break
|
34
|
+
end
|
35
|
+
end
|
36
|
+
return st
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Scenario <ActiveRecord::Base
|
41
|
+
# The view wants to display scenarios grouped into pages,
|
42
|
+
# where each page shows page_size scenarios at a time.
|
43
|
+
# This method returns the scenarios grouped by name on page page_num (starting
|
44
|
+
# at zero).
|
45
|
+
def self.find_on_page(page_num, page_size,conditions=nil)
|
46
|
+
find(:all,
|
47
|
+
:order => "name ASC",
|
48
|
+
:group=>"name",
|
49
|
+
:limit => page_size,
|
50
|
+
:conditions=>conditions,
|
51
|
+
:offset => page_num*page_size)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
|
Binary file
|
Binary file
|
@@ -1,18 +1,14 @@
|
|
1
1
|
# Copyright (c) 2008 Vassilis Rizopoulos. All rights reserved.
|
2
2
|
$:.unshift File.join(File.dirname(__FILE__),"..")
|
3
|
-
require 'rutema/system'
|
4
|
-
require 'rutemaweb/ruport_formatter.rb'
|
5
3
|
require 'rutemaweb/gems'
|
6
|
-
|
4
|
+
require 'rutemaweb/ruport_formatter.rb'
|
5
|
+
require 'rutemaweb/model'
|
6
|
+
require 'rutema/system'
|
7
7
|
|
8
8
|
module Rutema
|
9
9
|
module UI
|
10
|
-
|
11
|
-
|
12
|
-
engine :Erubis
|
13
|
-
layout :layout
|
14
|
-
#Time format to use for the start and stop times
|
15
|
-
TIME_FORMAT="%y%m%d - %H:%M:%S"
|
10
|
+
#Helper methods that create HTML snippets
|
11
|
+
module ViewUtilities
|
16
12
|
#image filename to use for succesfull scenarios
|
17
13
|
IMG_SCE_OK="/images/run_ok.png"
|
18
14
|
#image filename to use for failed scenarios
|
@@ -25,75 +21,261 @@ module Rutema
|
|
25
21
|
IMG_STEP_ERROR="/images/step_error.png"
|
26
22
|
#image filename to use for unexecuted steps
|
27
23
|
IMG_STEP_WARN="/images/step_warn.png"
|
24
|
+
#Time format to use for the start and stop times
|
25
|
+
TIME_FORMAT="%d/%m/%Y, %H:%M:%S"
|
26
|
+
#The left arrow
|
27
|
+
IMG_LEFT="/images/left.png"
|
28
|
+
#The right arrow
|
29
|
+
IMG_RIGHT="images/right.png"
|
30
|
+
# returns the image tag appropriate for the given status
|
31
|
+
def status_icon status
|
32
|
+
return case status
|
33
|
+
when :warning ,"not_executed"
|
34
|
+
"<img src=\"#{IMG_STEP_WARN}\" align=\"center\"/>"
|
35
|
+
when :success, "success"
|
36
|
+
"<img src=\"#{IMG_STEP_OK}\" align=\"center\"/>"
|
37
|
+
when :error, "error"
|
38
|
+
"<img src=\"#{IMG_STEP_ERROR}\" align=\"center\"/>"
|
39
|
+
else
|
40
|
+
"<img src=\"#{IMG_STEP_WARN}\" align=\"center\"/>"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# Returns a string with the correct time format for display
|
44
|
+
def time_formatted time
|
45
|
+
time.strftime(TIME_FORMAT)
|
46
|
+
end
|
47
|
+
#Returns the URL of details page for a run
|
48
|
+
def run_url run
|
49
|
+
"/run/#{run.id}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def run_summary r
|
53
|
+
Ramaze::Log.debug("Summary snippet for #{r}") if @logger
|
54
|
+
"#{run_link(r)} started at #{time_formatted(r.context.start_time)}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def run_link r
|
58
|
+
"<a class=\"smallgreytext\" href=\"#{run_url(r)}\">Run #{r.id}</a>"
|
59
|
+
end
|
60
|
+
#will render a hash in a table of key||value rows
|
61
|
+
def context_table context
|
62
|
+
ret="<table><tr>"
|
63
|
+
context.each do |k,v|
|
64
|
+
ret<<"<td>#{k.to_s}</td><td>#{v.to_s}</td>"
|
65
|
+
end
|
66
|
+
ret<<"</tr></table>"
|
67
|
+
end
|
68
|
+
|
69
|
+
#returns the pagination HTML for runs
|
70
|
+
def run_page_link page_number,page_total
|
71
|
+
ret=""
|
72
|
+
unless page_total==1
|
73
|
+
ret<<"<a href=\"/runs/#{page_number-1}\">Previous</a>" unless page_number==0
|
74
|
+
ret<<" | Page #{page_number+1}"
|
75
|
+
ret<<" | <a href=\"/runs/#{page_number+1}\">Next</a>" unless page_number==page_total-1
|
76
|
+
end
|
77
|
+
return ret
|
78
|
+
end
|
79
|
+
#returns the pagination HTML for scenarios
|
80
|
+
def scenario_page_link page_number,page_total
|
81
|
+
ret=""
|
82
|
+
unless page_total==1
|
83
|
+
ret<<"<a href=\"/scenarios/#{page_number-1}\">Previous</a>" unless page_number==0
|
84
|
+
ret<<" | Page #{page_number+1}"
|
85
|
+
ret<<" | <a href=\"/scenarios/#{page_number+1}\">Next</a>" unless page_number==page_total-1
|
86
|
+
end
|
87
|
+
return ret
|
88
|
+
end
|
89
|
+
|
90
|
+
#Gives the HTML to use for the status column of a scenario list
|
91
|
+
def scenario_status r
|
92
|
+
img_src=IMG_SCE_WARN
|
93
|
+
img_src=IMG_SCE_OK if "success"==r.status
|
94
|
+
img_src=IMG_SCE_ERROR if "error"==r.status
|
95
|
+
"<img src=\"#{img_src}\" align=\"center\"/>"
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
#Sets the values we need for public and view directories
|
101
|
+
def self.ramaze_settings
|
102
|
+
Ramaze::Global.public_root = File.expand_path(File.join(File.dirname(__FILE__),"public"))
|
103
|
+
Ramaze::Global.view_root = File.expand_path(File.join(File.dirname(__FILE__),"view"))
|
104
|
+
end
|
105
|
+
|
106
|
+
class MainController < Ramaze::Controller
|
107
|
+
include ViewUtilities
|
108
|
+
map '/'
|
109
|
+
engine :Erubis
|
110
|
+
layout :layout
|
111
|
+
#The number of items to show in lists
|
112
|
+
PAGE_SIZE=10
|
113
|
+
|
28
114
|
def index
|
29
|
-
@
|
30
|
-
@
|
115
|
+
@title="Rutema"
|
116
|
+
@panel_content=panel_runs
|
117
|
+
@content_title="Welcome to Rutema"
|
118
|
+
@content="<p>This is the rutema web interface.<br/>It allows you to browse the contents of the test results database.</p><p>Currently you can view the results for each separate run, the results for a specific scenario (a complete list of all steps executed in the scenario with standard and error output logs) or the complete execution history of a scenario.</p><p>The panel on the left shows a list of the ten most recent runs.</p>"
|
119
|
+
end
|
120
|
+
#Displays a paginated list of all runs
|
121
|
+
def runs page=0
|
122
|
+
@title="All runs"
|
123
|
+
@content_title="Runs"
|
124
|
+
@content=""
|
125
|
+
dt=[]
|
126
|
+
total_pages=(Rutema::Model::Run.count/PAGE_SIZE)+1
|
127
|
+
page_number=validated_page_number(page,total_pages)
|
128
|
+
|
129
|
+
runs=Rutema::Model::Run.find_on_page(page_number,PAGE_SIZE)
|
130
|
+
runs.each do |r|
|
131
|
+
dt<<[status_icon(r.status),run_summary(r)]
|
132
|
+
end
|
133
|
+
@content<< Ruport::Data::Table.new(:data=>dt,:column_names=>["status","description"]).to_html
|
134
|
+
@content<<"<br/>"
|
135
|
+
@content<<run_page_link(page_number,total_pages)
|
136
|
+
return @content
|
31
137
|
end
|
138
|
+
#Displays the details of a run
|
139
|
+
#
|
140
|
+
#Routes to /runs if no id is provided
|
32
141
|
def run run_id=""
|
33
|
-
@panel_content=
|
142
|
+
@panel_content=nil
|
34
143
|
if !run_id.empty?
|
144
|
+
@panel_content=panel_runs
|
145
|
+
@title="Run #{run_id}"
|
146
|
+
@content_title="Summary of run #{run_id}"
|
35
147
|
@content=single_run(run_id)
|
148
|
+
else
|
149
|
+
runs
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
#Displays a paginated list of scenarios
|
154
|
+
def scenarios page=0
|
155
|
+
@title="All scenarios"
|
156
|
+
@content_title="Scenarios"
|
157
|
+
@content=""
|
158
|
+
@panel_content=panel_runs
|
159
|
+
runs=Hash.new
|
160
|
+
#find which runs contain each scenario with the same name
|
161
|
+
Ramaze::Log.debug("Getting the runs for each scenario")
|
162
|
+
conditions="name NOT LIKE '%_teardown' AND name NOT LIKE '%_setup'"
|
163
|
+
Rutema::Model::Scenario.find(:all, :conditions=>conditions).each do |sc|
|
164
|
+
nm=sc.name
|
165
|
+
runs[nm]||=[]
|
166
|
+
runs[nm]<<sc.run.id
|
167
|
+
end
|
168
|
+
#the size of the hash is also the number of unique scenario names
|
169
|
+
total_pages=(runs.size / PAGE_SIZE)+1
|
170
|
+
page_number=validated_page_number(page,total_pages)
|
171
|
+
Ramaze::Log.debug("Getting scenarios for page #{page_number}")
|
172
|
+
scens=Rutema::Model::Scenario.find_on_page(page_number,PAGE_SIZE,conditions)
|
173
|
+
#and now build the table data
|
174
|
+
dt=Array.new
|
175
|
+
scens.each do |sc|
|
176
|
+
nm=sc.name
|
177
|
+
#sort the run ids
|
178
|
+
runs[nm]=runs[nm].sort.reverse[0..4]
|
179
|
+
dt<<["<a href=\"/scenario/#{nm}\">#{nm}</a> : ",sc.title,runs[nm].map{|r| " <a href=\"/run/#{r}\">#{r}</a>"}.join(" ")]
|
36
180
|
end
|
181
|
+
@content<<Ruport::Data::Table.new(:data=>dt,:column_names=>["name","title","last 5 runs"]).to_html
|
182
|
+
@content<<"<br/>"
|
183
|
+
@content<<scenario_page_link(page_number,total_pages)
|
37
184
|
end
|
185
|
+
#Displays the details of a scenario
|
38
186
|
def scenario scenario_id=""
|
39
|
-
@panel_content=
|
187
|
+
@panel_content=""
|
40
188
|
if !scenario_id.empty?
|
41
189
|
if scenario_id.to_i==0
|
42
190
|
@content=scenario_by_name(scenario_id)
|
43
191
|
else
|
44
|
-
@content=scenario_in_a_run(scenario_id)
|
192
|
+
@content=scenario_in_a_run(scenario_id.to_i)
|
45
193
|
end
|
194
|
+
else
|
195
|
+
return scenarios
|
46
196
|
end
|
47
197
|
end
|
198
|
+
|
199
|
+
def error
|
200
|
+
end
|
201
|
+
|
202
|
+
def settings
|
203
|
+
if request.post?
|
204
|
+
end
|
205
|
+
@panel_content=panel_runs()
|
206
|
+
@title="Settings"
|
207
|
+
@content_title="Settings"
|
208
|
+
@content=""
|
209
|
+
end
|
48
210
|
private
|
211
|
+
#Returns a valid page number no matter what __page__ is.
|
212
|
+
def validated_page_number page,total_pages
|
213
|
+
page_number=page.to_i if page
|
214
|
+
page_number||=0
|
215
|
+
Ramaze::Log.debug("Total number of run pages is #{total_pages}")
|
216
|
+
if page_number<0 || page_number>total_pages-1
|
217
|
+
Ramaze::Log.warn("Page number out of bounds: #{page_number}. Reseting")
|
218
|
+
page_number=0
|
219
|
+
end
|
220
|
+
return page_number
|
221
|
+
end
|
222
|
+
|
49
223
|
#Renders the summary of all runs for a single scenario
|
50
224
|
def scenario_by_name scenario_id
|
51
225
|
ret=""
|
226
|
+
@title="Runs for #{scenario_id}"
|
227
|
+
@content_title="Scenario #{scenario_id} runs"
|
52
228
|
begin
|
53
|
-
table=Rutema::Model::Scenario.report_table(:all,:conditions=>["name = :spec_name",{:spec_name=>scenario_id}]
|
229
|
+
table=Rutema::Model::Scenario.report_table(:all,:conditions=>["name = :spec_name",{:spec_name=>scenario_id}],
|
230
|
+
:order=>"run_id DESC")
|
54
231
|
if table.empty?
|
55
|
-
ret="<p>no results for
|
232
|
+
ret="<p>no results for the given name</p>"
|
56
233
|
else
|
57
|
-
table.replace_column("status")
|
58
|
-
|
59
|
-
end
|
60
|
-
table.replace_column("version") {|r| r.version ? r.version : "N/A"}
|
234
|
+
table.replace_column("status"){|r| scenario_status(r)}
|
235
|
+
table.replace_column("name") { |r| "<a href=\"/scenario/#{r}\">#{r}</a>"}
|
61
236
|
table.replace_column("start_time"){|r| r.stop_time ? r.start_time.strftime(TIME_FORMAT) : nil}
|
62
|
-
table.replace_column("stop_time"){|r| r.stop_time.strftime(TIME_FORMAT)}
|
63
|
-
table.
|
237
|
+
table.replace_column("stop_time"){|r| r.stop_time ? r.stop_time.strftime(TIME_FORMAT) : nil}
|
238
|
+
table.replace_column("run_id"){|r| "<a class=\"smallgreytext\" href=\"/run/#{r.run_id}\">Run #{r.run_id}</a>"}
|
239
|
+
table.reorder("status","run_id","title","start_time","stop_time")
|
240
|
+
table.column_names=["status","run","title","started at","ended at"]
|
64
241
|
ret<<table.to_html
|
65
242
|
end
|
66
243
|
rescue
|
67
|
-
|
68
|
-
|
244
|
+
@content_title="Error"
|
245
|
+
@title=@content_title
|
246
|
+
Ramaze::Log.error("Could not retrieve data for the scenario name '#{scenario_id}'")
|
247
|
+
Ramaze::Log.debug("#{$!.message}:\n#{$!.backtrace}")
|
248
|
+
ret="<p>could not retrieve data for the given scenario name</p>"
|
69
249
|
end
|
70
250
|
return ret
|
71
251
|
end
|
72
252
|
#Renders the information for a specific executed scenario
|
73
253
|
#giving a detailed list of the steps, with status and output
|
74
254
|
def scenario_in_a_run scenario_id
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
255
|
+
@panel_content=panel_runs
|
256
|
+
begin
|
257
|
+
scenario=Rutema::Model::Scenario.find(scenario_id)
|
258
|
+
@content_title="Summary for #{scenario.name} in run #{scenario.run_id}"
|
259
|
+
@title=@content_title
|
260
|
+
table=Rutema::Model::Step.report_table(:all,
|
261
|
+
:conditions=>["scenario_id = :scenario_id",{:scenario_id=>scenario_id}],
|
262
|
+
:order=>"number ASC")
|
263
|
+
if table.empty?
|
264
|
+
ret="<p>no results for the given id</p>"
|
265
|
+
else
|
266
|
+
table.replace_column("status"){|r| status_icon(r.status)}
|
267
|
+
ret=table.to_vhtml
|
84
268
|
end
|
85
|
-
|
269
|
+
rescue
|
270
|
+
@content_title="Error"
|
271
|
+
@title=@content_title
|
272
|
+
Ramaze::Log.error("Could not find scenario with the id '#{scenario_id}'")
|
273
|
+
#Ramaze::Log.debug("#{$!.message}:\n#{$!.backtrace}")
|
274
|
+
ret="<p>Could not find scenario with the given id.</p>"
|
86
275
|
end
|
87
276
|
return ret
|
88
277
|
end
|
89
|
-
|
90
|
-
def context_table context
|
91
|
-
ret="<table><tr>"
|
92
|
-
context.each do |k,v|
|
93
|
-
ret<<"<td>#{k.to_s}</td><td>#{v.to_s}</td>"
|
94
|
-
end
|
95
|
-
ret<<"</tr></table>"
|
96
|
-
end
|
278
|
+
|
97
279
|
#Renders the information for a single run providing the context and a list of the scenarios
|
98
280
|
def single_run run_id
|
99
281
|
ret=""
|
@@ -105,46 +287,32 @@ module Rutema
|
|
105
287
|
if run.context
|
106
288
|
ret<<context_table(run.context)
|
107
289
|
end
|
108
|
-
|
290
|
+
conditions="run_id = :run_id AND name NOT LIKE '%_teardown' AND name NOT LIKE '%_setup'"
|
291
|
+
table=Rutema::Model::Scenario.report_table(:all,
|
292
|
+
:conditions=>[conditions,{:run_id=>run_id}],:except=>["run_id"],
|
293
|
+
:order=>"name ASC")
|
109
294
|
if table.empty?
|
110
|
-
|
295
|
+
ret<<"No scenarios for run #{run_id}"
|
111
296
|
else
|
112
|
-
table.replace_column("status")
|
113
|
-
|
114
|
-
|
115
|
-
table.replace_column("
|
116
|
-
table.
|
117
|
-
table.
|
118
|
-
table.reorder("status","name","version","start_time","stop_time")
|
297
|
+
table.replace_column("status") {|r| scenario_status(r) }
|
298
|
+
table.replace_column("name"){ |r| "<a href=\"/scenario/#{r.id}\">#{r.name}</a>" }
|
299
|
+
table.replace_column("start_time"){|r| r.start_time ? r.start_time.strftime(TIME_FORMAT) : nil}
|
300
|
+
table.replace_column("stop_time"){|r| r.stop_time ? r.stop_time.strftime(TIME_FORMAT) : nil}
|
301
|
+
table.reorder("status","name","title","start_time","stop_time")
|
302
|
+
table.column_names=["status","name","title","started at","ended at"]
|
119
303
|
ret<<table.to_html
|
120
304
|
end
|
121
305
|
return ret
|
122
306
|
end
|
123
|
-
|
124
|
-
def
|
125
|
-
if "not_executed"==r.status
|
126
|
-
"<img src=\"#{IMG_SCE_WARN}\" align=\"center\"/>"
|
127
|
-
else
|
128
|
-
img_src=IMG_SCE_OK if "success"==r.status
|
129
|
-
img_src=IMG_SCE_ERROR if "error"==r.status
|
130
|
-
"<a href=\"/scenario/#{r.data["id"]}\"><img src=\"#{img_src}\" align=\"center\"/></a>"
|
131
|
-
end
|
132
|
-
end
|
133
|
-
def panel_content context
|
307
|
+
|
308
|
+
def panel_runs
|
134
309
|
ret=""
|
135
|
-
|
136
|
-
|
137
|
-
Rutema::Model::Run.find(:all,:select=>"id").reverse.each do |r|
|
138
|
-
ret<<"<a class=\"smallgreytext\" href=\"/run/#{r.id}\">Run #{r.id}</a><br/>"
|
139
|
-
end
|
140
|
-
elsif context==:scenarios
|
141
|
-
result=Rutema::Model::Scenario.find(:all).collect{|r| r.name}
|
142
|
-
result.uniq.sort.each do |r|
|
143
|
-
ret<<"<a class=\"smallgreytext\" href=\"/scenario/#{r}\">#{r}</a><br/>"
|
144
|
-
end
|
310
|
+
Rutema::Model::Run.find(:all,:limit=>10,:order=>"id DESC").each do |r|
|
311
|
+
ret<<"#{status_icon(r.status)} #{run_link(r)}<br/>"
|
145
312
|
end
|
146
313
|
return ret
|
147
314
|
end
|
315
|
+
|
148
316
|
end
|
149
317
|
end
|
150
318
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
6
6
|
<link rel="stylesheet" href="/css/style.css" type="text/css" />
|
7
7
|
<script src="/js/folding.js" type="text/javascript"></script>
|
8
|
-
<title
|
8
|
+
<title><%=@title%></title>
|
9
9
|
</head>
|
10
10
|
<body>
|
11
11
|
<div id="page" align="center">
|
@@ -29,14 +29,16 @@
|
|
29
29
|
</div>
|
30
30
|
<div id="contenttext">
|
31
31
|
<div style="padding:10px">
|
32
|
-
<span class="titletext"
|
32
|
+
<span class="titletext"><%=@content_title%></span>
|
33
33
|
</div>
|
34
34
|
<div class="bodytext" style="padding:12px;" align="justify"><%=@content%></div>
|
35
35
|
</div>
|
36
36
|
<div id="leftpanel">
|
37
|
+
<% if @panel_content && !@panel_content.empty? %>
|
37
38
|
<div align="justify" class="graypanel">
|
38
39
|
<%=@panel_content%>
|
39
40
|
</div>
|
41
|
+
<% end %>
|
40
42
|
</div>
|
41
43
|
<div id="footer" class="smallgraytext">
|
42
44
|
<a href="/">Home</a> | <a href="http://patir.rubyforge.org/rutema">about rutema</a> |
|
@@ -0,0 +1,107 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
+
require 'test/unit'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'rutemaweb/ramaze_controller'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'mocha'
|
7
|
+
|
8
|
+
class TestRutemaWeb <Test::Unit::TestCase
|
9
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3",:database =>":memory:")
|
10
|
+
def setup
|
11
|
+
|
12
|
+
end
|
13
|
+
def test_loading
|
14
|
+
controller=nil
|
15
|
+
assert_nothing_raised() { controller = Rutema::UI::MainController.new }
|
16
|
+
return controller
|
17
|
+
end
|
18
|
+
def test_run
|
19
|
+
cntlr=test_loading
|
20
|
+
r=mock()
|
21
|
+
r.expects(:id).returns(5).times(2)
|
22
|
+
r.expects(:context).returns(OpenStruct.new({:start_time=>Time.now}))
|
23
|
+
r.expects(:status).returns(:success)
|
24
|
+
t=mock()
|
25
|
+
t.expects(:to_html).returns("mocked")
|
26
|
+
Rutema::Model::Run.expects(:find).returns([r])
|
27
|
+
Rutema::Model::Run.expects(:count).returns(1)
|
28
|
+
Ruport::Data::Table.expects(:new).returns(t)
|
29
|
+
#Check nothing is raised when calling run (with everything mocked)
|
30
|
+
assert_nothing_raised(){ cntlr.run}
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_runs
|
34
|
+
cntlr=test_loading
|
35
|
+
mock_12_runs
|
36
|
+
#Check nothing is raised when calling run (with everything mocked)
|
37
|
+
assert_nothing_raised(){ cntlr.runs}
|
38
|
+
return cntlr
|
39
|
+
end
|
40
|
+
#unit tests for the pagination code of runs
|
41
|
+
def test_pagination
|
42
|
+
cntlr=test_loading
|
43
|
+
mock_12_runs
|
44
|
+
#Check nothing is raised when calling run (with everything mocked)
|
45
|
+
assert_nothing_raised(){ cntlr.runs(1)}
|
46
|
+
return cntlr
|
47
|
+
end
|
48
|
+
def test_page_number_to_large
|
49
|
+
cntlr=test_loading
|
50
|
+
mock_12_runs
|
51
|
+
#Check nothing is raised when calling run with a page number greater than the available
|
52
|
+
assert_nothing_raised(){ cntlr.runs(50)}
|
53
|
+
end
|
54
|
+
def test_page_number_negative
|
55
|
+
cntlr=test_loading
|
56
|
+
mock_12_runs
|
57
|
+
#Check nothing is raised when calling run with a negative page number greater than the available
|
58
|
+
assert_nothing_raised(){ cntlr.runs(-1)}
|
59
|
+
end
|
60
|
+
def test_page_number_bogus
|
61
|
+
cntlr=test_loading
|
62
|
+
mock_12_runs
|
63
|
+
#Check nothing is raised when calling run with a page number that is not a number
|
64
|
+
assert_nothing_raised(){ cntlr.runs("atttaaaaack!!")}
|
65
|
+
end
|
66
|
+
|
67
|
+
#unit tests for scenarios
|
68
|
+
def test_scenarios
|
69
|
+
ctlr=test_loading
|
70
|
+
mock_12_scenarios
|
71
|
+
Rutema::Model::Run.expects(:find).returns("")
|
72
|
+
assert_nothing_raised() { ctlr.scenarios }
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_scenario_wrong_arguments
|
76
|
+
ctlr=test_loading
|
77
|
+
ctlr.expects(:error).returns("super")
|
78
|
+
assert_raise(ArgumentError) { ctlr.scenario("bla","blu") }
|
79
|
+
end
|
80
|
+
private
|
81
|
+
def mock_12_runs
|
82
|
+
t=mock()
|
83
|
+
t.expects(:to_html).returns("mocked")
|
84
|
+
Ruport::Data::Table.expects(:new).returns(t)
|
85
|
+
runs=[mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock()]
|
86
|
+
runs.each do |r|
|
87
|
+
r.expects(:id).returns(5).times(2)
|
88
|
+
r.expects(:context).returns(OpenStruct.new({:start_time=>Time.now}))
|
89
|
+
r.expects(:status).returns(:success)
|
90
|
+
end
|
91
|
+
Rutema::Model::Run.expects(:find).returns(runs)
|
92
|
+
Rutema::Model::Run.expects(:count).returns(12)
|
93
|
+
end
|
94
|
+
|
95
|
+
def mock_12_scenarios
|
96
|
+
t=mock()
|
97
|
+
t.expects(:to_html).returns("mocked")
|
98
|
+
Ruport::Data::Table.expects(:new).returns(t)
|
99
|
+
scenarios=[mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock(),mock()]
|
100
|
+
scenarios.each do |sc|
|
101
|
+
sc.expects(:name).returns(scenarios.index(sc).to_s).times(2)
|
102
|
+
sc.expects(:title).returns(scenarios.index(sc).to_s)
|
103
|
+
sc.expects(:run).returns(scenarios.index(sc))
|
104
|
+
end
|
105
|
+
Rutema::Model::Scenario.expects(:find).returns(scenarios).times(2)
|
106
|
+
end
|
107
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rutemaweb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vassilis Rizopoulos
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-10-06 00:00:00 +02:00
|
13
13
|
default_executable: rutemaweb
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.
|
23
|
+
version: 0.6.0
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rutema
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 1.0.0
|
34
34
|
version:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: activerecord
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - "="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 2.
|
43
|
+
version: 2.1.1
|
44
44
|
version:
|
45
45
|
- !ruby/object:Gem::Dependency
|
46
46
|
name: ruport
|
@@ -52,16 +52,6 @@ dependencies:
|
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: "0"
|
54
54
|
version:
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: acts_as_reportable
|
57
|
-
type: :runtime
|
58
|
-
version_requirement:
|
59
|
-
version_requirements: !ruby/object:Gem::Requirement
|
60
|
-
requirements:
|
61
|
-
- - ">="
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
version: "0"
|
64
|
-
version:
|
65
55
|
- !ruby/object:Gem::Dependency
|
66
56
|
name: ramaze
|
67
57
|
type: :runtime
|
@@ -70,7 +60,7 @@ dependencies:
|
|
70
60
|
requirements:
|
71
61
|
- - "="
|
72
62
|
- !ruby/object:Gem::Version
|
73
|
-
version:
|
63
|
+
version: "2008.06"
|
74
64
|
version:
|
75
65
|
- !ruby/object:Gem::Dependency
|
76
66
|
name: erubis
|
@@ -83,17 +73,7 @@ dependencies:
|
|
83
73
|
version: "0"
|
84
74
|
version:
|
85
75
|
- !ruby/object:Gem::Dependency
|
86
|
-
name:
|
87
|
-
type: :runtime
|
88
|
-
version_requirement:
|
89
|
-
version_requirements: !ruby/object:Gem::Requirement
|
90
|
-
requirements:
|
91
|
-
- - ">="
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: "0"
|
94
|
-
version:
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
name: mailfactory
|
76
|
+
name: acts_as_reportable
|
97
77
|
type: :runtime
|
98
78
|
version_requirement:
|
99
79
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -112,7 +92,7 @@ dependencies:
|
|
112
92
|
- !ruby/object:Gem::Version
|
113
93
|
version: 1.7.0
|
114
94
|
version:
|
115
|
-
description: "== DESCRIPTION: rutemaweb is the web frontend for rutema. It can be used as a viewer for database files created with the ActiveRecord reporter. == FEATURES/PROBLEMS: == SYNOPSIS: rutemaweb [results.db] and browse to http://localhost:7000 for the glorious view == REQUIREMENTS:"
|
95
|
+
description: "== DESCRIPTION: rutemaweb is the web frontend for rutema. It can be used as a viewer for database files created with the ActiveRecord reporter. == FEATURES/PROBLEMS: == SYNOPSIS: rutemaweb [results.db] and browse to http://localhost:7000 for the glorious view == REQUIREMENTS: * patir (http://patir.rubyforge.org) * activerecord (http://ar.rubyonrails.com/) * sqlite3 (http://rubyforge.org/projects/sqlite-ruby/) * ramaze (http://www.ramaze.net/) * ruport (http://rubyreports.org/) * acts_as_reportable * erubis"
|
116
96
|
email: riva@braveworld.net
|
117
97
|
executables:
|
118
98
|
- rutemaweb
|
@@ -132,7 +112,7 @@ files:
|
|
132
112
|
- bin/rutemaweb
|
133
113
|
- lib/rutemaweb/gems.rb
|
134
114
|
- lib/rutemaweb/main.rb
|
135
|
-
- lib/rutemaweb/
|
115
|
+
- lib/rutemaweb/model.rb
|
136
116
|
- lib/rutemaweb/public/css/style.css
|
137
117
|
- lib/rutemaweb/public/images/bg_menu.gif
|
138
118
|
- lib/rutemaweb/public/images/bg_submenu.gif
|
@@ -143,10 +123,13 @@ files:
|
|
143
123
|
- lib/rutemaweb/public/images/step_ok.png
|
144
124
|
- lib/rutemaweb/public/images/step_warn.png
|
145
125
|
- lib/rutemaweb/public/images/tie_logo.gif
|
126
|
+
- lib/rutemaweb/public/images/left.png
|
127
|
+
- lib/rutemaweb/public/images/right.png
|
146
128
|
- lib/rutemaweb/public/js/folding.js
|
147
129
|
- lib/rutemaweb/ramaze_controller.rb
|
148
130
|
- lib/rutemaweb/ruport_formatter.rb
|
149
131
|
- lib/rutemaweb/view/layout.rhtml
|
132
|
+
- test/test_rutemaweb.rb
|
150
133
|
has_rdoc: true
|
151
134
|
homepage:
|
152
135
|
post_install_message:
|
@@ -170,9 +153,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
153
|
requirements: []
|
171
154
|
|
172
155
|
rubyforge_project: patir
|
173
|
-
rubygems_version: 1.
|
156
|
+
rubygems_version: 1.3.0
|
174
157
|
signing_key:
|
175
158
|
specification_version: 2
|
176
159
|
summary: rutemaweb is the web frontend for rutema
|
177
|
-
test_files:
|
178
|
-
|
160
|
+
test_files:
|
161
|
+
- test/test_rutemaweb.rb
|
Binary file
|