Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 2
- Log:
Initial import of Instiki 0.11.0 sources from a downloaded Tarball.
Instiki is a Ruby On Rails based Wiki clone.
- Author:
- adh
- Date:
- Sat Jul 22 14:54:51 +0100 2006
- Size:
- 12509 Bytes
1 | require 'fileutils' |
2 | require 'cgi' |
3 | require 'test/unit' |
4 | require 'rexml/document' |
5 | |
6 | INSTIKI_ROOT = File.expand_path(File.dirname(__FILE__) + "/../..") |
7 | require(File.expand_path(File.dirname(__FILE__) + "/../../config/environment")) |
8 | |
9 | # TODO Create tests for: |
10 | # * exporting HTML |
11 | # * exporting markup |
12 | # * include tag |
13 | |
14 | # Use instiki/../watir, if such a directory exists; This can be a CVS HEAD version of Watir. |
15 | # Otherwise Watir has to be installed in ruby/lib. |
16 | $:.unshift INSTIKI_ROOT + '/../watir' if File.exists?(INSTIKI_ROOT + '/../watir/watir.rb') |
17 | require 'watir' |
18 | |
19 | INSTIKI_PORT = 2501 |
20 | HOME = "http://localhost:#{INSTIKI_PORT}" |
21 | |
22 | class E2EInstikiTest < Test::Unit::TestCase |
23 | |
24 | def startup |
25 | @@instiki = InstikiController.start |
26 | |
27 | sleep 8 |
28 | @@ie = Watir::IE.start(HOME) |
29 | @@ie.set_fast_speed if (ARGV & ['-d', '--demo', '-demo', 'demo']).empty? |
30 | |
31 | setup_web |
32 | setup_home_page |
33 | |
34 | @@ie |
35 | end |
36 | |
37 | def self.shutdown |
38 | @@ie.close if defined? @@ie |
39 | @@instiki.stop |
40 | end |
41 | |
42 | def ie |
43 | if defined? @@ie |
44 | @@ie |
45 | else |
46 | startup |
47 | end |
48 | end |
49 | |
50 | def setup |
51 | ie.goto HOME |
52 | ie |
53 | end |
54 | |
55 | # Numbers like _00010_ determine the sequence in which the test cases are executed by Test::Unit |
56 | # Unfortunately, this sequence is important. |
57 | |
58 | def test_00010_home_page_contents |
59 | check_main_menu |
60 | check_bottom_menu |
61 | check_footnote |
62 | end |
63 | |
64 | def test_00020_add_a_page |
65 | # Add reference to a non-existant wiki page |
66 | enter_markup('HomePage', '[[Another Wiki Page]]') |
67 | assert_equal '?', ie.link(:url, url(:new, 'Another Wiki Page')).text |
68 | |
69 | # Edit the first revision of a page |
70 | enter_markup('Another Wiki Page', 'First revision of Another Wiki Page, linked from HomePage') |
71 | |
72 | # Check contents of the new page |
73 | assert_equal url(:show, 'Another Wiki Page'), ie.url |
74 | assert_match /First revision of Another Wiki Page, linked from Home Page/, ie.text |
75 | assert_match /Linked from: Home Page/, ie.text |
76 | |
77 | # There must be three links to HomePage - main menu, contents of the page and navigation bar |
78 | links_to_homepage = ie.links.to_a.select { |link| link.text == 'Home Page' } |
79 | assert_equal 3, links_to_homepage.size |
80 | links_to_homepage.each { |link| assert_equal url(:show, 'HomePage'), link.href } |
81 | |
82 | # Check also the "created on ... by ..." footnote |
83 | assert_match Regexp.new('Created on ' + date_pattern + ' by Anonymous Coward\?'), ie.text |
84 | end |
85 | |
86 | def test_00030_edit_page |
87 | enter_markup('TestEditPage', 'Test Edit Page, revision 1') |
88 | assert_match /Test Edit Page, revision 1/, ie.text |
89 | |
90 | # subsequent revision by the anonymous author |
91 | enter_markup('TestEditPage', 'Test Edit Page, revision 1, altered') |
92 | assert_match /Test Edit Page, revision 1, altered/, ie.text |
93 | assert_match Regexp.new('Created on ' + date_pattern + ' by Anonymous Coward\?'), ie.text |
94 | |
95 | # revision by a named author |
96 | enter_markup('TestEditPage', 'Test Edit Page, revision 2', 'Author') |
97 | assert_match /Test Edit Page, revision 2/, ie.text |
98 | assert_match Regexp.new('Revised on ' + date_pattern + ' by Author\?'), ie.text |
99 | |
100 | link_to_previous_revision = ie.link(:name, 'to_previous_revision') |
101 | assert_equal url(:revision, 'TestEditPage', 1), link_to_previous_revision.href |
102 | assert_equal 'Back in time', link_to_previous_revision.text |
103 | assert_match /Edit \| Back in time \(1 revision\) \| See changes/, ie.text |
104 | |
105 | # another anonymous revision |
106 | enter_markup('TestEditPage', 'Test Edit Page, revision 3') |
107 | assert_match /Test Edit Page, revision 3/, ie.text |
108 | assert_match /Edit \| Back in time \(2 revisions\) \| See changes /, ie.text |
109 | end |
110 | |
111 | def test_00040_traversing_revisions |
112 | ie.goto url(:revision, 'TestEditPage', 2) |
113 | assert_match /Test Edit Page, revision 2/, ie.text |
114 | assert_match(Regexp.new( |
115 | 'Forward in time \(to current\) \| Back in time \(1 more\) \| See current \| See changes \| Rollback'), |
116 | ie.text) |
117 | |
118 | ie.link(:name, 'to_previous_revision').click |
119 | assert_match /Test Edit Page, revision 1, altered/, ie.text |
120 | assert_match /Forward in time \(2 more\) \| See current \| Rollback/, ie.text |
121 | |
122 | ie.link(:name, 'to_next_revision').click |
123 | assert_match /Test Edit Page, revision 2/, ie.text |
124 | |
125 | ie.link(:name, 'to_next_revision').click |
126 | assert_match /Test Edit Page, revision 3/, ie.text |
127 | end |
128 | |
129 | def test_00050_rollback |
130 | ie.goto url(:revision, 'TestEditPage', 2) |
131 | assert_match /Test Edit Page, revision 2/, ie.text |
132 | ie.link(:name, 'rollback').click |
133 | assert_equal url(:rollback, 'TestEditPage', 2), ie.url |
134 | assert_equal 'Test Edit Page, revision 2', ie.text_field(:name, 'content').value |
135 | |
136 | ie.text_field(:name, 'content').set('Test Edit Page, revision 2, rolled back') |
137 | ie.button(:value, 'Update').click |
138 | |
139 | assert_equal url(:show, 'TestEditPage'), ie.url |
140 | assert_match /Test Edit Page, revision 2, rolled back/, ie.text |
141 | end |
142 | |
143 | def test_0060_see_changes |
144 | ie.goto url(:show, 'TestEditPage') |
145 | |
146 | assert_match /Test Edit Page, revision 2, rolled back/, ie.text |
147 | |
148 | ie.link(:text, 'See changes').click |
149 | |
150 | assert_match /Showing changes from revision #2 to #3: Added \| Removed/, ie.text |
151 | assert_match /Test Edit Page, revision 22, rolled back/, ie.text |
152 | |
153 | ie.link(:text, 'Hide changes').click |
154 | |
155 | assert_match /Test Edit Page, revision 2, rolled back/, ie.text |
156 | end |
157 | |
158 | def test_0070_all_pages |
159 | # create a wanted page, and unlink Another Wiki Page from Home Page |
160 | # (to see that it doesn't show up in the orphans, regardless) |
161 | enter_markup('Another Wiki Page', 'Reference to a NonExistantPage') |
162 | |
163 | ie.link(:text, 'All Pages').click |
164 | |
165 | page_links = ie.links.map { |l| l.text } |
166 | expected_page_links = ['Another Wiki Page', 'Home Page', 'Test Edit Page', '?', |
167 | 'Another Wiki Page', 'Test Edit Page'] |
168 | assert_equal expected_page_links, page_links[-6..-1] |
169 | links_sequence = |
170 | 'All Pages.*Another Wiki Page.*Home Page.*Test Edit Page.*' + |
171 | 'Wanted Pages.*Non Existant Page\? wanted by Another Wiki Page.*'+ |
172 | 'Orphaned Pages.*Test Edit Page.*' |
173 | assert_match Regexp.new(links_sequence, Regexp::MULTILINE), ie.text |
174 | # and before that, we have the tail of the main menu |
175 | |
176 | |
177 | require 'breakpoint'; breakpoint |
178 | |
179 | |
180 | assert_equal 'Export', page_links[-7] |
181 | end |
182 | |
183 | def test_0080_recently_revised |
184 | ie.link(:text, 'Recently Revised').click |
185 | |
186 | links = ie.links.map { |l| l.text } |
187 | assert_equal ['Another Wiki Page', '?', 'Test Edit Page', '?', 'Home Page', '?'], links[-6..-1] |
188 | |
189 | expected_text = |
190 | 'Another Wiki Page.*by Anonymous Coward\?.*' + |
191 | 'Test Edit Page.*by Anonymous Coward\?.*' + |
192 | 'Home Page.*by Anonymous Coward\?.*' |
193 | assert_match Regexp.new(expected_text, Regexp::MULTILINE), ie.text |
194 | end |
195 | |
196 | def test_0090_authors |
197 | # create a revision of TestEditPage, and a corresponding author page |
198 | enter_markup('TestEditPage', '3rd revision of this page', 'Another Author') |
199 | ie.link(:afterText, 'Another Author').click |
200 | assert_equal url(:new, 'Another Author'), ie.url |
201 | enter_markup('Another Author', 'Email me at another_author@foo.bar.com', 'Another Author') |
202 | |
203 | ie.link(:text, 'Authors').click |
204 | |
205 | expected_authors = |
206 | 'Anonymous Coward\? co- or authored: Another Wiki Page, Home Page, Test Edit Page.*' + |
207 | 'Another Author co- or authored: Another Author, Test Edit Page.*' + |
208 | 'Author\? co- or authored: Test Edit Page' |
209 | assert_match Regexp.new(expected_authors, Regexp::MULTILINE), ie.text |
210 | |
211 | ie.link(:text, 'Another Author').click |
212 | assert_equal url(:show, 'Another Author'), ie.url |
213 | ie.back |
214 | ie.link(:text, 'Test Edit Page').click |
215 | assert_equal url(:show, 'TestEditPage'), ie.url |
216 | end |
217 | |
218 | def test_0100_feeds |
219 | ie.link(:text, 'Feeds').click |
220 | assert_equal url(:rss_with_content), ie.link(:text, 'Full content (RSS 2.0)').href |
221 | assert_equal url(:rss_with_headlines), ie.link(:text, 'Headlines (RSS 2.0)').href |
222 | |
223 | ie.link(:text, 'Full content (RSS 2.0)').click |
224 | assert_nothing_raised { REXML::Document.new ie.text } |
225 | |
226 | ie.back |
227 | ie.link(:text, 'Headlines (RSS 2.0)').click |
228 | assert_nothing_raised { REXML::Document.new ie.text } |
229 | end |
230 | |
231 | private |
232 | |
233 | def bp |
234 | require 'breakpoint' |
235 | breakpoint |
236 | end |
237 | |
238 | def check_main_menu |
239 | assert_equal HOME + '/wiki/list', ie.link(:text, 'All Pages').href |
240 | assert_equal HOME + '/wiki/recently_revised', ie.link(:text, 'Recently Revised').href |
241 | assert_equal HOME + '/wiki/authors', ie.link(:text, 'Authors').href |
242 | assert_equal HOME + '/wiki/feeds', ie.link(:text, 'Feeds').href |
243 | assert_equal HOME + '/wiki/export', ie.link(:text, 'Export').href |
244 | end |
245 | |
246 | def check_bottom_menu |
247 | assert_equal url(:edit, 'HomePage'), ie.link(:text, 'Edit Page').href |
248 | assert_equal HOME + '/wiki/edit_web', ie.link(:text, 'Edit Web').href |
249 | assert_equal url(:print, 'HomePage'), ie.link(:text, 'Print').href |
250 | end |
251 | |
252 | def check_footnote |
253 | assert_match /This site is running on Instiki/, ie.text |
254 | assert_equal 'http://instiki.org/', ie.link(:text, 'Instiki').href |
255 | assert_match /Powered by Ruby on Rails/, ie.text |
256 | assert_equal 'http://rubyonrails.com/', ie.link(:text, 'Ruby on Rails').href |
257 | end |
258 | |
259 | def date_pattern |
260 | '(January|February|March|April|May|June|July|August|September|October|November|December) ' + |
261 | '\d\d?, \d\d\d\d \d\d:\d\d:\d\d' |
262 | end |
263 | |
264 | def enter_markup(page, content, author = nil) |
265 | ie.goto url(:show, page) |
266 | if ie.url == url(:show, page) |
267 | ie.link(:name, 'edit').click |
268 | assert_equal url(:edit, page), ie.url |
269 | else |
270 | assert_equal url(:new, page), ie.url |
271 | end |
272 | |
273 | ie.text_field(:name, 'content').set(content) |
274 | ie.text_field(:name, 'author').set(author || '') |
275 | ie.button(:value, 'Submit').click |
276 | |
277 | assert_equal url(:show, page), ie.url |
278 | end |
279 | |
280 | def setup_web |
281 | assert_equal 'Wiki', ie.text_field(:name, 'web_name').value |
282 | assert_equal 'wiki', ie.text_field(:name, 'web_address').value |
283 | assert_equal '', ie.text_field(:name, 'password').value |
284 | assert_equal '', ie.text_field(:name, 'password_check').value |
285 | |
286 | ie.text_field(:name, 'password').set('123') |
287 | ie.text_field(:name, 'password_check').set('123') |
288 | ie.button(:value, 'Setup').click |
289 | assert_equal url(:new, 'HomePage'), ie.url |
290 | end |
291 | |
292 | def setup_home_page |
293 | ie.text_field(:name, 'content').set('Homepage of a test wiki') |
294 | ie.button(:value, 'Submit').click |
295 | assert_equal url(:show, 'HomePage'), ie.url |
296 | end |
297 | |
298 | def url(operation, page_name = nil, revision = nil) |
299 | page_name = CGI.escape(page_name) if page_name |
300 | case operation |
301 | when :edit, :new, :show, :print, :revision, :rollback |
302 | "#{HOME}/wiki/#{operation}/#{page_name}" + (revision ? "?rev=#{revision}" : '') |
303 | when :rss_with_content, :rss_with_headlines |
304 | "#{HOME}/wiki/#{operation}" |
305 | else |
306 | raise "Unsupported operation: '#{operation}" |
307 | end |
308 | end |
309 | |
310 | end |
311 | |
312 | class InstikiController |
313 | |
314 | attr_reader :process_id |
315 | |
316 | def self.start |
317 | startup_info = [68].pack('lx64') |
318 | process_info = [0, 0, 0, 0].pack('llll') |
319 | |
320 | clear_database |
321 | startup_command = |
322 | "ruby #{RAILS_ROOT}/instiki.rb --port #{INSTIKI_PORT} --environment development" |
323 | |
324 | result = Win32API.new('kernel32.dll', 'CreateProcess', 'pplllllppp', 'L').call( |
325 | nil, |
326 | startup_command, |
327 | 0, 0, 1, 0, 0, '.', startup_info, process_info) |
328 | |
329 | # TODO print the error code, or better yet a text message |
330 | raise "Failed to start Instiki." if result == 0 |
331 | |
332 | process_id = process_info.unpack('llll')[2] |
333 | return self.new(process_id) |
334 | end |
335 | |
336 | def self.clear_database |
337 | ENV['RAILS_ENV'] = 'development' |
338 | require INSTIKI_ROOT + '/config/environment.rb' |
339 | [WikiReference, Revision, Page, WikiFile, Web, System].each { |entity| entity.delete_all } |
340 | end |
341 | |
342 | def initialize(pid) |
343 | @process_id = pid |
344 | end |
345 | |
346 | def stop |
347 | right_to_terminate_process = 1 |
348 | handle = Win32API.new('kernel32.dll', 'OpenProcess', 'lil', 'l').call( |
349 | right_to_terminate_process, 0, @process_id) |
350 | Win32API.new('kernel32.dll', 'TerminateProcess', 'll', 'L').call(handle, 0) |
351 | end |
352 | |
353 | end |
354 | |
355 | begin |
356 | require 'test/unit/ui/console/testrunner' |
357 | Test::Unit::UI::Console::TestRunner.new(E2EInstikiTest.suite).start |
358 | rescue => e |
359 | $stderr.puts 'Unhandled error during test execution' |
360 | $stderr.puts e.message |
361 | $stderr.puts e.backtrace |
362 | ensure |
363 | begin |
364 | E2EInstikiTest::shutdown |
365 | rescue => e |
366 | $stderr.puts 'Error during shutdown' |
367 | $stderr.puts e.message |
368 | $stderr.puts e.backtrace |
369 | end |
370 | end |