bauxite 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +118 -144
- data/Rakefile +1 -1
- data/doc/Bauxite/Action.html +1 -1
- data/doc/Bauxite/ActionModule.html +1 -1
- data/doc/Bauxite/Application.html +11 -9
- data/doc/Bauxite/Context.html +24 -24
- data/doc/Bauxite/Errors/AssertionError.html +1 -1
- data/doc/Bauxite/Errors/FileNotFoundError.html +1 -1
- data/doc/Bauxite/Errors/FormatError.html +1 -1
- data/doc/Bauxite/Errors.html +1 -1
- data/doc/Bauxite/Loggers/CompositeLogger.html +1 -1
- data/doc/Bauxite/Loggers/EchoLogger.html +1 -1
- data/doc/Bauxite/Loggers/FileLogger.html +1 -1
- data/doc/Bauxite/Loggers/NullLogger.html +1 -1
- data/doc/Bauxite/Loggers/TerminalLogger.html +1 -1
- data/doc/Bauxite/Loggers/XtermLogger.html +1 -1
- data/doc/Bauxite/Loggers.html +1 -1
- data/doc/Bauxite/Parser.html +55 -3
- data/doc/Bauxite/ParserModule.html +2 -2
- data/doc/Bauxite/Selector.html +8 -6
- data/doc/Bauxite/SelectorModule.html +4 -10
- data/doc/Bauxite.html +3 -1
- data/doc/README_md.html +438 -0
- data/doc/created.rid +43 -42
- data/doc/index.html +355 -3
- data/doc/js/jquery.js +4 -18
- data/doc/js/search_index.js +1 -1
- data/doc/table_of_contents.html +31 -1
- data/lib/bauxite/core/action.rb +1 -1
- data/lib/bauxite/core/context.rb +1 -0
- data/lib/bauxite/core/parser.rb +13 -5
- data/lib/bauxite/core/selector.rb +3 -11
- data/lib/bauxite.rb +1 -1
- data/test/load.bxt +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b552a2f66dec08146b82d0dbcc3e6fe68aa08ee2
|
4
|
+
data.tar.gz: f3aec0f177563e918670c1266271e438a1574038
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9082c00d552a285f7161e14fd6ec85c53c47cd0a99ae209456795c38e264d6a7599c05b3d66c853dbcbc3258a2622ac79091a764f5b3c21f56ba8f754881bc57
|
7
|
+
data.tar.gz: 55a1780f3c996917744bbba490698dcd7185273a21ae0e9067ec85d9a350e19251400754e84ee5cd207fa7010f20c9704cfa5741ca262c294167c4fc311cbb68
|
data/README.md
CHANGED
@@ -6,36 +6,36 @@ Bauxite is a façade over Selenium intended for non-developers
|
|
6
6
|
The idea behind this project was to create a tool that allows non-developers to write web tests in a human-readable language. Another major requirement is to be able to easily extend the test language to create functional abstractions over technical details.
|
7
7
|
|
8
8
|
Take a look at the following Ruby excerpt from http://code.google.com/p/selenium/wiki/RubyBindings:
|
9
|
-
```ruby
|
10
|
-
require "selenium-webdriver"
|
11
9
|
|
12
|
-
|
13
|
-
|
10
|
+
require "selenium-webdriver"
|
11
|
+
|
12
|
+
driver = Selenium::WebDriver.for :firefox
|
13
|
+
driver.navigate.to "http://google.com"
|
14
|
+
|
15
|
+
element = driver.find_element(:name, 'q')
|
16
|
+
element.send_keys "Hello WebDriver!"
|
17
|
+
element.submit
|
18
|
+
|
19
|
+
puts driver.title
|
20
|
+
|
21
|
+
driver.quit
|
14
22
|
|
15
|
-
element = driver.find_element(:name, 'q')
|
16
|
-
element.send_keys "Hello WebDriver!"
|
17
|
-
element.submit
|
18
|
-
|
19
|
-
puts driver.title
|
20
|
-
|
21
|
-
driver.quit
|
22
|
-
```
|
23
23
|
While developers might find that code expressive enough, non-developers might be a bit shocked.
|
24
24
|
|
25
25
|
The equivalent Bauxite test is easier on the eyes:
|
26
|
-
|
27
|
-
open "http://google.com"
|
28
|
-
write "name=q" "Hello WebDriver!"
|
29
|
-
click "gbqfb"
|
30
|
-
|
26
|
+
|
27
|
+
open "http://google.com"
|
28
|
+
write "name=q" "Hello WebDriver!"
|
29
|
+
click "gbqfb"
|
30
|
+
|
31
31
|
|
32
32
|
Installation
|
33
33
|
------------
|
34
34
|
|
35
35
|
In a nutshell:
|
36
|
-
|
37
|
-
gem install bauxite
|
38
|
-
|
36
|
+
|
37
|
+
gem install bauxite
|
38
|
+
|
39
39
|
|
40
40
|
If you don't have Ruby 2.x yet, check the [Installing Ruby](#installing-ruby) section below.
|
41
41
|
|
@@ -45,14 +45,12 @@ Hello World
|
|
45
45
|
-----------
|
46
46
|
|
47
47
|
Paste the following text into `hello.bxt`:
|
48
|
-
|
49
|
-
open "http://www.gnu.org/fun/jokes/helloworld.html"
|
50
|
-
```
|
48
|
+
|
49
|
+
open "http://www.gnu.org/fun/jokes/helloworld.html"
|
51
50
|
|
52
51
|
Launch a terminal/command prompt and type:
|
53
|
-
|
54
|
-
bauxite hello.bxt
|
55
|
-
```
|
52
|
+
|
53
|
+
bauxite hello.bxt
|
56
54
|
|
57
55
|
Command-line Interface
|
58
56
|
----------------------
|
@@ -68,11 +66,10 @@ The Bauxite Language
|
|
68
66
|
The Bauxite language is composed of two elements `Actions` and `Selectors`: Actions are testing operations such as "open this page", "click this button", "write this text into that textbox", etc. Selectors are ways of locating interesting elements of a page such as a button, a textbox, a label, etc.
|
69
67
|
|
70
68
|
A typical Bauxite test is a plain text file that contains a series of Actions (one per line). Depending on the Action, a few action arguments might need to be specified as well. For example in:
|
71
|
-
|
72
|
-
open "http://google.com"
|
73
|
-
write "name=q" "Hello WebDriver!"
|
74
|
-
click "gbqfb"
|
75
|
-
```
|
69
|
+
|
70
|
+
open "http://google.com"
|
71
|
+
write "name=q" "Hello WebDriver!"
|
72
|
+
click "gbqfb"
|
76
73
|
|
77
74
|
`open`, `write` and `click` are Actions:
|
78
75
|
- `open` takes a single URL argument (`"http://google.com"`) and opens that URL in the browser.
|
@@ -86,33 +83,30 @@ Some Actions operate on page elements (e.g. `write`, `click`, etc.). In order to
|
|
86
83
|
The trivial Selector is just a text that matches the last portion of the `id` attribute of the target element.
|
87
84
|
|
88
85
|
For example, in this HTML fragment:
|
89
|
-
|
90
|
-
<input type="submit" id="gbqfb" value="Search" />
|
91
|
-
```
|
86
|
+
|
87
|
+
<input type="submit" id="gbqfb" value="Search" />
|
92
88
|
|
93
89
|
If we want to click the "Search" button we can do the following:
|
94
|
-
|
95
|
-
click "gbqfb"
|
96
|
-
```
|
90
|
+
|
91
|
+
click "gbqfb"
|
97
92
|
|
98
93
|
Bauxite supports several other Selectors such as `name=` in the example above. The `name` Selector finds elements whose `name` attribute matches the text following the `=` sign.
|
99
94
|
|
100
95
|
For example, in this HTML fragment:
|
101
|
-
|
102
|
-
<input type="text" name="q" />
|
103
|
-
```
|
96
|
+
|
97
|
+
<input type="text" name="q" />
|
104
98
|
|
105
99
|
If we want to type the text "Hello WebDriver!" in textbox we can do the following:
|
106
|
-
|
107
|
-
write "name=q" "Hello WebDriver!"
|
108
|
-
```
|
100
|
+
|
101
|
+
write "name=q" "Hello WebDriver!"
|
109
102
|
|
110
103
|
This section presented a brief introduction into the basic Bauxite concepts. For more details and a list of every Action and Selector available, refer to the RDoc generated documentation in:
|
111
|
-
|
112
|
-
- [Available
|
113
|
-
- [
|
114
|
-
- [
|
115
|
-
- [Creating new
|
104
|
+
|
105
|
+
- [Available Actions](http://pzavolinsky.github.io/bauxite/Bauxite/Action.html#Action+Methods)
|
106
|
+
- [Available Bauxite Selectors](http://pzavolinsky.github.io/bauxite/Bauxite/Selector.html#Selector+Methods)
|
107
|
+
- [Selenium Standard Selectors](http://pzavolinsky.github.io/bauxite/Bauxite/Selector.html#class-Bauxite::Selector-label-Standard+Selenium+Selectors)
|
108
|
+
- [Creating new Actions](http://pzavolinsky.github.io/bauxite/Bauxite/Action.html)
|
109
|
+
- [Creating new Selectors](http://pzavolinsky.github.io/bauxite/Bauxite/Selector.html)
|
116
110
|
|
117
111
|
Installing Ruby
|
118
112
|
---------------
|
@@ -120,19 +114,16 @@ Installing Ruby
|
|
120
114
|
I won't cover all the details of installing Ruby on your system (Google knows best), but the following should probably work.
|
121
115
|
|
122
116
|
In GNU/Linux, you can install [RVM](http://rvm.io/), then Ruby:
|
123
|
-
|
124
|
-
curl -sSL https://get.rvm.io | bash -s stable
|
125
|
-
source ~/.rvm/scripts/rvm
|
126
|
-
rvm install ruby-2.1.0
|
127
|
-
```
|
117
|
+
|
118
|
+
curl -sSL https://get.rvm.io | bash -s stable
|
119
|
+
source ~/.rvm/scripts/rvm
|
120
|
+
rvm install ruby-2.1.0
|
128
121
|
|
129
122
|
In Windows, you can install Ruby 2.x with [RubyInstaller](http://rubyinstaller.org/downloads/). After everything is installed, launch the `Start Command Prompt with Ruby` option in your start menu.
|
130
123
|
|
131
124
|
Regadless of your OS, you should be able to install Bauxite with:
|
132
125
|
|
133
|
-
|
134
|
-
gem install bauxite
|
135
|
-
```
|
126
|
+
gem install bauxite
|
136
127
|
|
137
128
|
Implementation
|
138
129
|
--------------
|
@@ -152,86 +143,75 @@ Bauxite supports two types of extensions: functional extensions and coded plugin
|
|
152
143
|
|
153
144
|
Functional extensions are composite constructs created using existing Bauxite actions to convey functional meaning. For example, imagine a login form:
|
154
145
|
|
155
|
-
|
156
|
-
|
157
|
-
<
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
</form>
|
162
|
-
```
|
146
|
+
<!-- http://hostname/login.html -->
|
147
|
+
<form>
|
148
|
+
<input id="username" name="username" type="text" />
|
149
|
+
<input id="password" name="password" type="password" />
|
150
|
+
<input id="login" type="submit" value="Login"/>
|
151
|
+
</form>
|
163
152
|
|
164
153
|
The Bauxite code to login into this site would be:
|
165
|
-
|
166
|
-
open "http://hostname/login.html"
|
167
|
-
write "username" "jdoe"
|
168
|
-
write "password" "hello world!"
|
169
|
-
click "login"
|
170
|
-
```
|
154
|
+
|
155
|
+
open "http://hostname/login.html"
|
156
|
+
write "username" "jdoe"
|
157
|
+
write "password" "hello world!"
|
158
|
+
click "login"
|
171
159
|
|
172
160
|
If we were creating a suite of automated web tests for our *hostname* site, we'll probably need to login into the site several times. This would mean copy/pasting the four lines above into every test in our suite.
|
173
161
|
|
174
162
|
Of course we can do better. We can split Bauxite tests into many files and include one test into another with the `load` action.
|
175
163
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
...
|
180
|
-
```
|
164
|
+
# my_test.bxt (by the way, this is a comment)
|
165
|
+
load other_test_fragment.bxt
|
166
|
+
...
|
181
167
|
|
182
168
|
Back to our login example, first we can package the login part of our tests into a separate Bauxite file:
|
183
|
-
|
184
|
-
# login.bxt
|
185
|
-
open "http://hostname/login.html"
|
186
|
-
write "username" "jdoe"
|
187
|
-
write "password" "hello world!"
|
188
|
-
click "login"
|
189
|
-
```
|
169
|
+
|
170
|
+
# login.bxt
|
171
|
+
open "http://hostname/login.html"
|
172
|
+
write "username" "jdoe"
|
173
|
+
write "password" "hello world!"
|
174
|
+
click "login"
|
190
175
|
|
191
176
|
Of course we would like to be able to login with different username/password combinations, so we can replace the literals in `login.bxt` with variables:
|
192
|
-
|
193
|
-
# login.bxt
|
194
|
-
open "http://hostname/login.html"
|
195
|
-
write "username" "${username}"
|
196
|
-
write "password" "${password}"
|
197
|
-
click "login"
|
198
|
-
```
|
177
|
+
|
178
|
+
# login.bxt
|
179
|
+
open "http://hostname/login.html"
|
180
|
+
write "username" "${username}"
|
181
|
+
write "password" "${password}"
|
182
|
+
click "login"
|
199
183
|
|
200
184
|
Now, we would like to assert that both `username` and `password` variables are set before calling our test (just in case someone forgets). We can do this with `params`
|
201
|
-
```ruby
|
202
|
-
# login.bxt
|
203
|
-
params username password
|
204
|
-
open "http://hostname/login.html"
|
205
|
-
write "username" "${username}"
|
206
|
-
write "password" "${password}"
|
207
|
-
click "login"
|
208
|
-
```
|
209
185
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
186
|
+
# login.bxt
|
187
|
+
params username password
|
188
|
+
open "http://hostname/login.html"
|
189
|
+
write "username" "${username}"
|
190
|
+
write "password" "${password}"
|
191
|
+
click "login"
|
214
192
|
|
215
|
-
|
216
|
-
|
193
|
+
In our main test we can load `login.bxt` and specify the variables required using this code:
|
194
|
+
|
195
|
+
# main_test.bxt
|
196
|
+
load "login.bxt" "username=jdoe" "password=hello world!"
|
197
|
+
|
198
|
+
# additional actions go here
|
217
199
|
|
218
200
|
We could improve this even further by creating an `alias` to simplify the login process. To do this, lets create an new file called `alias.bxt`:
|
219
|
-
|
220
|
-
# alias.bxt
|
221
|
-
alias "login" "load" "login.bxt" "username=${1}" "password=${2}"
|
222
|
-
```
|
201
|
+
|
202
|
+
# alias.bxt
|
203
|
+
alias "login" "load" "login.bxt" "username=${1}" "password=${2}"
|
223
204
|
|
224
205
|
Note that the `alias` action supports positional arguments.
|
225
206
|
|
226
207
|
Now we can change our main test to use our alias:
|
227
|
-
```ruby
|
228
|
-
# main_test.bxt
|
229
|
-
load "alias.bxt"
|
230
|
-
|
231
|
-
login "jdoe" "hello world!"
|
232
208
|
|
233
|
-
#
|
234
|
-
|
209
|
+
# main_test.bxt
|
210
|
+
load "alias.bxt"
|
211
|
+
|
212
|
+
login "jdoe" "hello world!"
|
213
|
+
|
214
|
+
# additional actions go here
|
235
215
|
|
236
216
|
That was a bit of work but the resulting test is purely functional (minus the load alias part, of course).
|
237
217
|
|
@@ -241,41 +221,35 @@ Coded plugins are Ruby files that extend the Bauxite language by providing addit
|
|
241
221
|
|
242
222
|
For example lets assume that throughout a web application input elements were identified using a custom HTML attribute instead of `id`. For example:
|
243
223
|
|
244
|
-
|
245
|
-
<
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
</form>
|
250
|
-
```
|
224
|
+
<form>
|
225
|
+
<input custom-attr="username" type="text" />
|
226
|
+
<input custom-attr="password" type="password" />
|
227
|
+
<input custom-attr="login" type="submit" value="Login"/>
|
228
|
+
</form>
|
251
229
|
|
252
230
|
Using standard Bauxite language we could select these elements using:
|
253
|
-
|
254
|
-
# === my_test.bxt === #
|
255
|
-
write "attr=custom-attr:username" "jdoe"
|
256
|
-
write "attr=custom-attr:password" "hello world!"
|
257
|
-
click "attr=custom-attr:login"
|
258
|
-
```
|
231
|
+
|
232
|
+
# === my_test.bxt === #
|
233
|
+
write "attr=custom-attr:username" "jdoe"
|
234
|
+
write "attr=custom-attr:password" "hello world!"
|
235
|
+
click "attr=custom-attr:login"
|
259
236
|
|
260
237
|
But we can improve the overall readability of our test by using a coded plugin:
|
261
|
-
|
262
|
-
# === plugins/custom_selector.rb === #
|
263
|
-
class Bauxite::Selector
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
end
|
268
|
-
```
|
238
|
+
|
239
|
+
# === plugins/custom_selector.rb === #
|
240
|
+
class Bauxite::Selector
|
241
|
+
def custom(value)
|
242
|
+
attr "custom-attr:#{value}"
|
243
|
+
end
|
244
|
+
end
|
269
245
|
|
270
246
|
Now we can change our test to look like this:
|
271
|
-
|
272
|
-
# === my_test.bxt === #
|
273
|
-
write "custom=username" "jdoe"
|
274
|
-
write "custom=password" "hello world!"
|
275
|
-
click "custom=login"
|
276
|
-
```
|
247
|
+
|
248
|
+
# === my_test.bxt === #
|
249
|
+
write "custom=username" "jdoe"
|
250
|
+
write "custom=password" "hello world!"
|
251
|
+
click "custom=login"
|
277
252
|
|
278
253
|
Finally, to execute Bauxite loading our plugin we can type:
|
279
|
-
|
280
|
-
bauxite -e plugins my_test.bxt
|
281
|
-
```
|
254
|
+
|
255
|
+
bauxite -e plugins my_test.bxt
|
data/Rakefile
CHANGED
@@ -51,7 +51,7 @@ end
|
|
51
51
|
# === Documentation ========================================================= #
|
52
52
|
desc "Generate Bauxite documentation"
|
53
53
|
task :doc do
|
54
|
-
system("rdoc -O -U -V #{File.join('lib', 'bauxite')}")
|
54
|
+
system("rdoc -O -U -V --main README.md README.md #{File.join('lib', 'bauxite')}")
|
55
55
|
end
|
56
56
|
|
57
57
|
desc "Open documentation in a browser"
|
data/doc/Bauxite/Action.html
CHANGED
@@ -1461,7 +1461,7 @@ href="Context.html#method-i-expand">Bauxite::Context#expand</a>).</p>
|
|
1461
1461
|
|
1462
1462
|
<footer id="validator-badges" role="contentinfo">
|
1463
1463
|
<p><a href="http://validator.w3.org/check/referer">Validate</a>
|
1464
|
-
<p>Generated by <a href="http://rdoc.rubyforge.org">RDoc</a> 4.1.
|
1464
|
+
<p>Generated by <a href="http://rdoc.rubyforge.org">RDoc</a> 4.1.1.
|
1465
1465
|
<p>Based on <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
|
1466
1466
|
</footer>
|
1467
1467
|
|
@@ -336,7 +336,7 @@ might yield different results.</p>
|
|
336
336
|
|
337
337
|
<footer id="validator-badges" role="contentinfo">
|
338
338
|
<p><a href="http://validator.w3.org/check/referer">Validate</a>
|
339
|
-
<p>Generated by <a href="http://rdoc.rubyforge.org">RDoc</a> 4.1.
|
339
|
+
<p>Generated by <a href="http://rdoc.rubyforge.org">RDoc</a> 4.1.1.
|
340
340
|
<p>Based on <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
|
341
341
|
</footer>
|
342
342
|
|
@@ -90,8 +90,8 @@
|
|
90
90
|
|
91
91
|
<p><code>bauxite</code> command-line program.</p>
|
92
92
|
|
93
|
-
<p>This program executes Bauxite tests and
|
94
|
-
tests results to the terminal.</p>
|
93
|
+
<p>This program executes <a href="../Bauxite.html">Bauxite</a> tests and
|
94
|
+
outputs the execution progress and tests results to the terminal.</p>
|
95
95
|
|
96
96
|
<h2 id="class-Bauxite::Application-label-Synopsis">Synopsis<span><a href="#class-Bauxite::Application-label-Synopsis">¶</a> <a href="#documentation">↑</a></span></h2>
|
97
97
|
|
@@ -107,7 +107,8 @@ tests results to the terminal.</p>
|
|
107
107
|
|
108
108
|
<h2 id="class-Bauxite::Application-label-Options">Options<span><a href="#class-Bauxite::Application-label-Options">¶</a> <a href="#documentation">↑</a></span></h2>
|
109
109
|
|
110
|
-
<p>For a detailed list of options for your
|
110
|
+
<p>For a detailed list of options for your <a
|
111
|
+
href="../Bauxite.html">Bauxite</a> version execute:</p>
|
111
112
|
|
112
113
|
<pre>bauxite -h</pre>
|
113
114
|
<dl class="rdoc-list label-list"><dt>-v, --verbose
|
@@ -144,7 +145,8 @@ to try different selector combinations and debug NoSuchElementError errors.</p>
|
|
144
145
|
<p><code>safari</code></p>
|
145
146
|
</li></ul>
|
146
147
|
|
147
|
-
<p>Driver availability dependes on the system running
|
148
|
+
<p>Driver availability dependes on the system running <a
|
149
|
+
href="../Bauxite.html">Bauxite</a>.</p>
|
148
150
|
</dd><dt>-P, --provider-option OPTION
|
149
151
|
<dd>
|
150
152
|
<p>A <code>name=value</code> pair of options that are directly forwarded to
|
@@ -185,9 +187,9 @@ window.</p>
|
|
185
187
|
</dd><dt>-e, --extension DIR
|
186
188
|
<dd>
|
187
189
|
<p>Loads every Ruby file (*.rb) inside <code>DIR</code> (and subdirectories).
|
188
|
-
This option can be used to load custom
|
189
|
-
|
190
|
-
run.</p>
|
190
|
+
This option can be used to load custom <a
|
191
|
+
href="../Bauxite.html">Bauxite</a> extensions (e.g. Actions, Selectors, <a
|
192
|
+
href="Loggers.html">Loggers</a>, etc.) for a specific test run.</p>
|
191
193
|
|
192
194
|
<p>For example:</p>
|
193
195
|
|
@@ -209,7 +211,7 @@ run.</p>
|
|
209
211
|
</pre>
|
210
212
|
</dd><dt>--version
|
211
213
|
<dd>
|
212
|
-
<p>Shows the Bauxite version.</p>
|
214
|
+
<p>Shows the <a href="../Bauxite.html">Bauxite</a> version.</p>
|
213
215
|
</dd></dl>
|
214
216
|
|
215
217
|
<h2 id="class-Bauxite::Application-label-Exit+Status">Exit Status<span><a href="#class-Bauxite::Application-label-Exit+Status">¶</a> <a href="#documentation">↑</a></span></h2>
|
@@ -243,7 +245,7 @@ indicates success).</p>
|
|
243
245
|
|
244
246
|
<footer id="validator-badges" role="contentinfo">
|
245
247
|
<p><a href="http://validator.w3.org/check/referer">Validate</a>
|
246
|
-
<p>Generated by <a href="http://rdoc.rubyforge.org">RDoc</a> 4.1.
|
248
|
+
<p>Generated by <a href="http://rdoc.rubyforge.org">RDoc</a> 4.1.1.
|
247
249
|
<p>Based on <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
|
248
250
|
</footer>
|
249
251
|
|