rsel 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -2
- data/Rakefile +2 -1
- data/docs/custom.md +11 -11
- data/docs/fitnesse.md +77 -0
- data/docs/history.md +8 -0
- data/docs/index.md +5 -3
- data/docs/install.md +4 -22
- data/docs/locators.md +15 -0
- data/docs/rsel_components.png +0 -0
- data/docs/rsel_components.svg +495 -0
- data/docs/scenarios.md +51 -0
- data/docs/scoping.md +21 -8
- data/docs/todo.md +5 -0
- data/docs/usage.md +48 -50
- data/lib/rsel/selenium_test.rb +8 -1
- data/rsel.gemspec +1 -1
- data/spec/selenium_test_spec.rb +42 -6
- data/test/app.rb +12 -1
- data/test/views/index.erb +1 -0
- data/test/views/slow.erb +10 -0
- metadata +9 -4
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
Rsel
|
2
2
|
====
|
3
3
|
|
4
|
-
Rsel
|
5
|
-
|
4
|
+
Rsel is a [Ruby](http://ruby-lang.org) wrapper for [Selenium](http://seleniumhq.org),
|
5
|
+
making it a little easier to write browser automation scripts. It is especially
|
6
|
+
tailored towards use in [FitNesse](http://fitnesse.org) script tables, though it
|
7
|
+
works equally well with plain Ruby.
|
6
8
|
|
7
9
|
[Full documentation is on rdoc.info](http://rdoc.info/github/a-e/rsel/master/frames).
|
8
10
|
|
data/Rakefile
CHANGED
@@ -5,7 +5,8 @@ require 'rspec/core/rake_task'
|
|
5
5
|
|
6
6
|
ROOT_DIR = File.expand_path(File.dirname(__FILE__))
|
7
7
|
TEST_APP = File.join(ROOT_DIR, 'test', 'app.rb')
|
8
|
-
SELENIUM_RC_JAR = File.join(ROOT_DIR, 'test', 'server', 'selenium-server-1.0.3-SNAPSHOT-standalone.jar')
|
8
|
+
#SELENIUM_RC_JAR = File.join(ROOT_DIR, 'test', 'server', 'selenium-server-1.0.3-SNAPSHOT-standalone.jar')
|
9
|
+
SELENIUM_RC_JAR = File.join(ROOT_DIR, 'test', 'server', 'selenium-server-standalone-2.4.0.jar')
|
9
10
|
SELENIUM_RC_LOG = File.join(ROOT_DIR, 'selenium-rc.log')
|
10
11
|
|
11
12
|
namespace 'testapp' do
|
data/docs/custom.md
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
Customization
|
2
2
|
-------------
|
3
3
|
|
4
|
-
Rsel
|
5
|
-
|
6
|
-
|
4
|
+
When you are using Rsel through FitNesse, you may find yourself needing more
|
5
|
+
high-level steps; it can be tedious to spell out every action using the basic
|
6
|
+
actions provided by the `SeleniumTest` class.
|
7
7
|
|
8
|
-
It's pretty easy to
|
9
|
-
methods to it. Create a sibling directory to your
|
10
|
-
something like `custom_rsel`, then create a Ruby file in
|
11
|
-
can be called whatever you want--it's most logical to name
|
12
|
-
application:
|
8
|
+
It's pretty easy to create custom steps by subclassing `SeleniumTest` and
|
9
|
+
adding your own methods to it. Create a sibling directory to your
|
10
|
+
`FitNesseRoot`, named something like `custom_rsel`, then create a Ruby file in
|
11
|
+
there. The Ruby file can be called whatever you want--it's most logical to name
|
12
|
+
it after your application:
|
13
13
|
|
14
14
|
- `FitNesseRoot`
|
15
15
|
- `custom_rsel`
|
@@ -66,11 +66,11 @@ Note that this name must match the `module` line in your Ruby file, and the
|
|
66
66
|
folder where your Ruby file resides must be the lowercase_and_underscore
|
67
67
|
version of that same module name. Finally, in your actual test table, instead of:
|
68
68
|
|
69
|
-
|
69
|
+
| script | selenium test | ... |
|
70
70
|
|
71
71
|
You'll use:
|
72
72
|
|
73
|
-
|
73
|
+
| script | my app test | ... |
|
74
74
|
|
75
75
|
This will ensure that the `MyAppTest` class will be used for evaluating the
|
76
76
|
steps contained in that table.
|
@@ -83,5 +83,5 @@ for interacting with webpages and performing verifications. If `SeleniumTest`
|
|
83
83
|
itself does not provide the methods you need, you can use the `@browser`
|
84
84
|
attribute directly.
|
85
85
|
|
86
|
-
Next: [
|
86
|
+
Next: [Scenarios](scenarios.md)
|
87
87
|
|
data/docs/fitnesse.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
FitNesse
|
2
|
+
========
|
3
|
+
|
4
|
+
With FitNesse, some initial configuration steps are necessary. Assuming you
|
5
|
+
have a FitNesse wiki-page hierarchy like this:
|
6
|
+
|
7
|
+
- `FitNesseRoot`
|
8
|
+
- `SeleniumTests`
|
9
|
+
- `SetUp`
|
10
|
+
- `LoginTest`
|
11
|
+
|
12
|
+
Put this in your `SeleniumTests.SetUp` page:
|
13
|
+
|
14
|
+
!| import |
|
15
|
+
| Rsel |
|
16
|
+
|
17
|
+
You also need to define the requisite `rubyslim` options in the `SeleniumTests`
|
18
|
+
page content, so they will apply to all sub-wikis:
|
19
|
+
|
20
|
+
!define TEST_SYSTEM {slim}
|
21
|
+
!define TEST_RUNNER {rubyslim}
|
22
|
+
!define COMMAND_PATTERN {rubyslim}
|
23
|
+
|
24
|
+
If you're using Bundler, you may need to use:
|
25
|
+
|
26
|
+
!define TEST_SYSTEM {slim}
|
27
|
+
!define TEST_RUNNER {bundle exec rubyslim}
|
28
|
+
!define COMMAND_PATTERN {bundle exec rubyslim}
|
29
|
+
|
30
|
+
Once you have created your `SetUp` page, you can create sibling pages with
|
31
|
+
tests in them. For instance, continuing with the example test hierarchy above,
|
32
|
+
your `SeleniumTests.LoginTest` might look like this:
|
33
|
+
|
34
|
+
| script | selenium test | http://www.mysite.com |
|
35
|
+
| Open browser |
|
36
|
+
| Fill in | Username | with | castle |
|
37
|
+
| Fill in | Password | with | beckett |
|
38
|
+
| Click button | Log in |
|
39
|
+
| Page loads in | 5 | seconds or less |
|
40
|
+
| See | Logged in as castle |
|
41
|
+
| Close browser |
|
42
|
+
|
43
|
+
By default, the server runs on port 4444, and this is the port that Rsel uses
|
44
|
+
unless you tell it otherwise. Rsel also assumes that you're running
|
45
|
+
selenium-server on your localhost (that is, the same host where FitNesse is
|
46
|
+
running); if you need to use a different host or port number, pass those as
|
47
|
+
a hash argument to the first line of the table. For example, if you are running
|
48
|
+
selenium-server on `my.selenium.host`, port `4455`, do this:
|
49
|
+
|
50
|
+
| script | selenium test | http://www.mysite.com | !{host:my.selenium.host, port:4455} |
|
51
|
+
|
52
|
+
Another useful argument to pass in this hash is `stop_on_error`, which causes
|
53
|
+
the test to be aborted whenever any failure occurs:
|
54
|
+
|
55
|
+
| script | selenium test | http://www.mysite.com | !{stop_on_error:true} |
|
56
|
+
|
57
|
+
By default, when an error occurs, the failing step is simply colored red, and
|
58
|
+
the test continues. With `stop_on_error` set, an exception will be raised.
|
59
|
+
|
60
|
+
The first argument after `selenium test` is the URL of the site you will be testing.
|
61
|
+
This URL is loaded when you call `Open browser`, and all steps that follow are
|
62
|
+
assumed to stay within the same domain. You can navigate around the site by
|
63
|
+
clicking links and filling in forms just as a human user would; you can also go
|
64
|
+
directly to a specific path within the domain with the `Visit` method:
|
65
|
+
|
66
|
+
| Visit | /some/path |
|
67
|
+
| Visit | /some/other/path |
|
68
|
+
|
69
|
+
These paths are evaluated relative to the domain your test is running in. (It's
|
70
|
+
theoretically possible to navigate to a different domain, but the Selenium
|
71
|
+
driver frowns upon it.)
|
72
|
+
|
73
|
+
See the `SeleniumTest` class documentation for a full list of available methods
|
74
|
+
and how to use them.
|
75
|
+
|
76
|
+
Next: [Locators](locators.md)
|
77
|
+
|
data/docs/history.md
CHANGED
data/docs/index.md
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
Rsel
|
2
2
|
====
|
3
3
|
|
4
|
-
Rsel
|
5
|
-
[
|
6
|
-
|
4
|
+
Rsel is a [Selenium](http://seleniumhq.org) wrapper for
|
5
|
+
[Ruby](http://ruby-lang.org), tailored towards web browser automation using
|
6
|
+
[FitNesse](http://fitnesse.org) script tables with a natural English syntax.
|
7
7
|
|
8
8
|
- [Installation](install.md)
|
9
9
|
- [Usage](usage.md)
|
10
|
+
- [FitNesse](fitnesse.md)
|
10
11
|
- [Locators](locators.md)
|
11
12
|
- [Scoping](scoping.md)
|
12
13
|
- [Examples](examples.md)
|
13
14
|
- [Customization](custom.md)
|
15
|
+
- [Scenarios](scenarios.md)
|
14
16
|
- [Development](development.md)
|
15
17
|
- [To-do list](todo.md)
|
16
18
|
- [History](history.md)
|
data/docs/install.md
CHANGED
@@ -5,29 +5,11 @@ To install Rsel from a gem:
|
|
5
5
|
|
6
6
|
$ gem install rsel
|
7
7
|
|
8
|
-
|
8
|
+
Rsel drives browser actions through Selenium Server, so you will need to download
|
9
|
+
[selenium-server-standalone-x.x.x.jar](http://seleniumhq.org/download/), and start
|
10
|
+
it up like this before running any Rsel scripts:
|
9
11
|
|
10
|
-
-
|
11
|
-
- `SeleniumTests`
|
12
|
-
- `SetUp`
|
13
|
-
- `LoginTest`
|
14
|
-
|
15
|
-
You should define the requisite `rubyslim` options in the `SeleniumTests` page content:
|
16
|
-
|
17
|
-
!define TEST_SYSTEM {slim}
|
18
|
-
!define TEST_RUNNER {rubyslim}
|
19
|
-
!define COMMAND_PATTERN {rubyslim}
|
20
|
-
|
21
|
-
If you're using Bundler, you may need to use:
|
22
|
-
|
23
|
-
!define TEST_SYSTEM {slim}
|
24
|
-
!define TEST_RUNNER {bundle exec rubyslim}
|
25
|
-
!define COMMAND_PATTERN {bundle exec rubyslim}
|
26
|
-
|
27
|
-
Finally, put this in your `SeleniumTests.SetUp` page:
|
28
|
-
|
29
|
-
!| import |
|
30
|
-
| Rsel |
|
12
|
+
$ java -jar selenium-server-standalone-x.x.x.jar
|
31
13
|
|
32
14
|
Next: [Usage](usage.md)
|
33
15
|
|
data/docs/locators.md
CHANGED
@@ -14,6 +14,11 @@ their `name` attribute. Given this HTML:
|
|
14
14
|
To click on the "Contact Us" link using a standard Selenium locator, you'd have
|
15
15
|
to do one of the following:
|
16
16
|
|
17
|
+
click "contact_us_link"
|
18
|
+
click "link=Contact Us"
|
19
|
+
|
20
|
+
Or in FitNesse:
|
21
|
+
|
17
22
|
| Click | contact_us_link |
|
18
23
|
| Click | link=Contact Us |
|
19
24
|
|
@@ -36,6 +41,11 @@ For instance, given this HTML:
|
|
36
41
|
|
37
42
|
With Selenium's default selectors, you could do:
|
38
43
|
|
44
|
+
type "id=first_name_text_field", "Eric"
|
45
|
+
type "xpath=.//input[@id = ../label[.='First name']/@for]", "Eric"
|
46
|
+
|
47
|
+
In FitNesse:
|
48
|
+
|
39
49
|
| type | id=first_name_text_field | Eric |
|
40
50
|
| type | xpath=.//input[@id = ../label[.='First name']/@for] | Eric |
|
41
51
|
|
@@ -47,6 +57,11 @@ the `alt` text in the case of an image link. Form fields are matched on their
|
|
47
57
|
plain-text label, `name` or `id` attribute. In Rsel, the above examples become
|
48
58
|
much easier:
|
49
59
|
|
60
|
+
click "Contact Us"
|
61
|
+
type_into_field "Eric", "First name"
|
62
|
+
|
63
|
+
Or in FitNesse:
|
64
|
+
|
50
65
|
| Click | Contact Us |
|
51
66
|
| Type | Eric | into field | First name |
|
52
67
|
|
Binary file
|
@@ -0,0 +1,495 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
6
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
7
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
8
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
9
|
+
xmlns="http://www.w3.org/2000/svg"
|
10
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
11
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
12
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
13
|
+
width="990"
|
14
|
+
height="765"
|
15
|
+
id="svg2985"
|
16
|
+
version="1.1"
|
17
|
+
inkscape:version="0.48.0 r9654"
|
18
|
+
sodipodi:docname="rsel_components.svg">
|
19
|
+
<defs
|
20
|
+
id="defs2987" />
|
21
|
+
<sodipodi:namedview
|
22
|
+
inkscape:document-units="in"
|
23
|
+
pagecolor="#ffffff"
|
24
|
+
bordercolor="#666666"
|
25
|
+
borderopacity="1.0"
|
26
|
+
inkscape:pageopacity="0.0"
|
27
|
+
inkscape:pageshadow="2"
|
28
|
+
inkscape:zoom="0.61399264"
|
29
|
+
inkscape:cx="516.41291"
|
30
|
+
inkscape:cy="417.16324"
|
31
|
+
inkscape:current-layer="layer1"
|
32
|
+
id="namedview2989"
|
33
|
+
showgrid="false"
|
34
|
+
inkscape:window-width="1653"
|
35
|
+
inkscape:window-height="1029"
|
36
|
+
inkscape:window-x="23"
|
37
|
+
inkscape:window-y="17"
|
38
|
+
inkscape:window-maximized="0" />
|
39
|
+
<metadata
|
40
|
+
id="metadata2991">
|
41
|
+
<rdf:RDF>
|
42
|
+
<cc:Work
|
43
|
+
rdf:about="">
|
44
|
+
<dc:format>image/svg+xml</dc:format>
|
45
|
+
<dc:type
|
46
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
47
|
+
<dc:title />
|
48
|
+
</cc:Work>
|
49
|
+
</rdf:RDF>
|
50
|
+
</metadata>
|
51
|
+
<g
|
52
|
+
inkscape:label="Hosts"
|
53
|
+
inkscape:groupmode="layer"
|
54
|
+
id="layer1"
|
55
|
+
style="display:inline">
|
56
|
+
<rect
|
57
|
+
style="fill:#e0e0ff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
58
|
+
id="rect4199"
|
59
|
+
width="329.86951"
|
60
|
+
height="258.82565"
|
61
|
+
x="547.69385"
|
62
|
+
y="174.4735"
|
63
|
+
rx="16.264936"
|
64
|
+
ry="19.188747" />
|
65
|
+
<rect
|
66
|
+
ry="19.188747"
|
67
|
+
rx="16.264936"
|
68
|
+
y="176.42883"
|
69
|
+
x="139.43263"
|
70
|
+
height="474.62628"
|
71
|
+
width="329.86951"
|
72
|
+
id="rect4015"
|
73
|
+
style="fill:#e0e0ff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
74
|
+
<text
|
75
|
+
xml:space="preserve"
|
76
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
77
|
+
x="156.59407"
|
78
|
+
y="205.43953"
|
79
|
+
id="text2994"
|
80
|
+
sodipodi:linespacing="125%"><tspan
|
81
|
+
sodipodi:role="line"
|
82
|
+
id="tspan2996"
|
83
|
+
x="156.59407"
|
84
|
+
y="205.43953"
|
85
|
+
style="font-size:18px">FitNesse Host</tspan></text>
|
86
|
+
<rect
|
87
|
+
ry="19.188747"
|
88
|
+
rx="16.264936"
|
89
|
+
y="478.71463"
|
90
|
+
x="547.69385"
|
91
|
+
height="112.24406"
|
92
|
+
width="329.86948"
|
93
|
+
id="rect4201"
|
94
|
+
style="fill:#e0e0ff;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
95
|
+
<text
|
96
|
+
sodipodi:linespacing="125%"
|
97
|
+
id="text3991"
|
98
|
+
y="200.94649"
|
99
|
+
x="565.43536"
|
100
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
101
|
+
xml:space="preserve"><tspan
|
102
|
+
style="font-size:18px"
|
103
|
+
y="200.94649"
|
104
|
+
x="565.43536"
|
105
|
+
id="tspan3993"
|
106
|
+
sodipodi:role="line">Selenium Host</tspan></text>
|
107
|
+
<text
|
108
|
+
xml:space="preserve"
|
109
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
110
|
+
x="566.02423"
|
111
|
+
y="505.50055"
|
112
|
+
id="text3997"
|
113
|
+
sodipodi:linespacing="125%"><tspan
|
114
|
+
sodipodi:role="line"
|
115
|
+
x="566.02423"
|
116
|
+
y="505.50055"
|
117
|
+
style="font-size:18px"
|
118
|
+
id="tspan4005">Website Host</tspan></text>
|
119
|
+
<text
|
120
|
+
sodipodi:linespacing="125%"
|
121
|
+
id="text3831"
|
122
|
+
y="106.07404"
|
123
|
+
x="384.62146"
|
124
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
125
|
+
xml:space="preserve"><tspan
|
126
|
+
style="font-size:24px"
|
127
|
+
y="106.07404"
|
128
|
+
x="384.62146"
|
129
|
+
id="tspan3833"
|
130
|
+
sodipodi:role="line">Rsel Architecture</tspan></text>
|
131
|
+
</g>
|
132
|
+
<g
|
133
|
+
inkscape:groupmode="layer"
|
134
|
+
id="layer2"
|
135
|
+
inkscape:label="Arrows"
|
136
|
+
style="display:inline"
|
137
|
+
transform="translate(0,-225)">
|
138
|
+
<path
|
139
|
+
style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
140
|
+
d="m 545.31468,480.31599 -36.50773,0 0,344.24279 -70.20193,0"
|
141
|
+
id="path4207"
|
142
|
+
inkscape:connector-curvature="0"
|
143
|
+
sodipodi:nodetypes="cccc" />
|
144
|
+
<path
|
145
|
+
sodipodi:type="star"
|
146
|
+
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
147
|
+
id="path4205"
|
148
|
+
sodipodi:sides="3"
|
149
|
+
sodipodi:cx="245.87804"
|
150
|
+
sodipodi:cy="285.3363"
|
151
|
+
sodipodi:r1="11.46604"
|
152
|
+
sodipodi:r2="5.7330198"
|
153
|
+
sodipodi:arg1="-0.52359878"
|
154
|
+
sodipodi:arg2="0.52359878"
|
155
|
+
inkscape:flatsided="false"
|
156
|
+
inkscape:rounded="0"
|
157
|
+
inkscape:randomized="0"
|
158
|
+
d="m 255.80792,279.60328 -4.96494,8.59953 -4.96494,8.59953 -4.96494,-8.59953 -4.96495,-8.59953 9.92989,0 z"
|
159
|
+
inkscape:transform-center-y="1.7491676"
|
160
|
+
transform="matrix(0,-1,0.61020671,0,373.47134,726.22912)" />
|
161
|
+
<g
|
162
|
+
id="g4332"
|
163
|
+
transform="translate(-276.92592,337.20299)">
|
164
|
+
<path
|
165
|
+
sodipodi:nodetypes="cc"
|
166
|
+
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
167
|
+
d="m 580.34692,435.73068 0,-32.16652"
|
168
|
+
id="path4320"
|
169
|
+
inkscape:connector-curvature="0" />
|
170
|
+
<path
|
171
|
+
sodipodi:type="star"
|
172
|
+
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
173
|
+
id="path4322"
|
174
|
+
sodipodi:sides="3"
|
175
|
+
sodipodi:cx="245.87804"
|
176
|
+
sodipodi:cy="285.3363"
|
177
|
+
sodipodi:r1="11.46604"
|
178
|
+
sodipodi:r2="5.7330198"
|
179
|
+
sodipodi:arg1="-0.52359878"
|
180
|
+
sodipodi:arg2="0.52359878"
|
181
|
+
inkscape:flatsided="false"
|
182
|
+
inkscape:rounded="0"
|
183
|
+
inkscape:randomized="0"
|
184
|
+
d="m 255.80792,279.60328 -4.96494,8.59953 -4.96494,8.59953 -4.96494,-8.59953 -4.96495,-8.59953 9.92989,0 z"
|
185
|
+
inkscape:transform-center-y="1.7491676"
|
186
|
+
transform="matrix(1,0,0,0.61020671,334.43379,263.88734)" />
|
187
|
+
</g>
|
188
|
+
<use
|
189
|
+
x="0"
|
190
|
+
y="0"
|
191
|
+
xlink:href="#g4332"
|
192
|
+
id="use4336"
|
193
|
+
transform="translate(3.1518043e-6,-123.77998)"
|
194
|
+
width="765"
|
195
|
+
height="990" />
|
196
|
+
<use
|
197
|
+
x="0"
|
198
|
+
y="0"
|
199
|
+
xlink:href="#use4336"
|
200
|
+
id="use4338"
|
201
|
+
transform="translate(3.1518043e-6,-90.391962)"
|
202
|
+
width="765"
|
203
|
+
height="990" />
|
204
|
+
<path
|
205
|
+
inkscape:connector-curvature="0"
|
206
|
+
id="path3055"
|
207
|
+
d="m 715.75388,736.85706 0,-115.396"
|
208
|
+
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
209
|
+
sodipodi:nodetypes="cc" />
|
210
|
+
<path
|
211
|
+
transform="matrix(1,0,0,0.61020671,469.84075,564.4379)"
|
212
|
+
inkscape:transform-center-y="1.7491676"
|
213
|
+
d="m 255.80792,279.60328 -4.96494,8.59953 -4.96494,8.59953 -4.96494,-8.59953 -4.96495,-8.59953 9.92989,0 z"
|
214
|
+
inkscape:randomized="0"
|
215
|
+
inkscape:rounded="0"
|
216
|
+
inkscape:flatsided="false"
|
217
|
+
sodipodi:arg2="0.52359878"
|
218
|
+
sodipodi:arg1="-0.52359878"
|
219
|
+
sodipodi:r2="5.7330198"
|
220
|
+
sodipodi:r1="11.46604"
|
221
|
+
sodipodi:cy="285.3363"
|
222
|
+
sodipodi:cx="245.87804"
|
223
|
+
sodipodi:sides="3"
|
224
|
+
id="path3057"
|
225
|
+
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
226
|
+
sodipodi:type="star" />
|
227
|
+
<use
|
228
|
+
x="0"
|
229
|
+
y="0"
|
230
|
+
xlink:href="#g4332"
|
231
|
+
id="use4342"
|
232
|
+
transform="translate(412.33288,-220.97485)"
|
233
|
+
width="765"
|
234
|
+
height="990" />
|
235
|
+
</g>
|
236
|
+
<g
|
237
|
+
inkscape:groupmode="layer"
|
238
|
+
id="layer3"
|
239
|
+
inkscape:label="Processes"
|
240
|
+
style="display:inline"
|
241
|
+
transform="translate(0,-225)">
|
242
|
+
<rect
|
243
|
+
style="fill:#ffffdf;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
244
|
+
id="rect4193"
|
245
|
+
width="302.11731"
|
246
|
+
height="89.442627"
|
247
|
+
x="560.2356"
|
248
|
+
y="439.37634"
|
249
|
+
rx="14.99066"
|
250
|
+
ry="19.188747" />
|
251
|
+
<text
|
252
|
+
sodipodi:linespacing="125%"
|
253
|
+
id="text3006"
|
254
|
+
y="467.15558"
|
255
|
+
x="575.93311"
|
256
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
257
|
+
xml:space="preserve"><tspan
|
258
|
+
style="font-size:16px"
|
259
|
+
y="467.15558"
|
260
|
+
x="575.93311"
|
261
|
+
id="tspan3008"
|
262
|
+
sodipodi:role="line">selenium-server</tspan><tspan
|
263
|
+
style="font-size:12px"
|
264
|
+
y="483.16858"
|
265
|
+
x="575.93311"
|
266
|
+
sodipodi:role="line"
|
267
|
+
id="tspan3965">- Standalone Java .jar application</tspan><tspan
|
268
|
+
style="font-size:12px"
|
269
|
+
y="498.16858"
|
270
|
+
x="575.93311"
|
271
|
+
sodipodi:role="line"
|
272
|
+
id="tspan3969">- Spawns a web browser</tspan><tspan
|
273
|
+
style="font-size:12px"
|
274
|
+
y="513.16858"
|
275
|
+
x="575.93311"
|
276
|
+
sodipodi:role="line"
|
277
|
+
id="tspan3971">- Executes instructions sent by the client</tspan><tspan
|
278
|
+
style="font-size:12px"
|
279
|
+
y="528.16858"
|
280
|
+
x="575.93311"
|
281
|
+
sodipodi:role="line"
|
282
|
+
id="tspan3973" /></text>
|
283
|
+
<rect
|
284
|
+
ry="19.188747"
|
285
|
+
rx="14.99066"
|
286
|
+
y="746.87469"
|
287
|
+
x="560.2356"
|
288
|
+
height="56.620495"
|
289
|
+
width="302.11731"
|
290
|
+
id="rect4203"
|
291
|
+
style="fill:#ffffdf;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
292
|
+
<text
|
293
|
+
xml:space="preserve"
|
294
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
295
|
+
x="575.58661"
|
296
|
+
y="772.58704"
|
297
|
+
id="text3030"
|
298
|
+
sodipodi:linespacing="125%"><tspan
|
299
|
+
sodipodi:role="line"
|
300
|
+
id="tspan3032"
|
301
|
+
x="575.58661"
|
302
|
+
y="772.58704"
|
303
|
+
style="font-size:16px">System Under Test</tspan><tspan
|
304
|
+
sodipodi:role="line"
|
305
|
+
x="575.58661"
|
306
|
+
y="788.60004"
|
307
|
+
style="font-size:12px"
|
308
|
+
id="tspan3987">- Can be any platform that serves webpages</tspan></text>
|
309
|
+
<rect
|
310
|
+
ry="19.188747"
|
311
|
+
rx="14.99066"
|
312
|
+
y="562.34192"
|
313
|
+
x="560.2356"
|
314
|
+
height="79.670555"
|
315
|
+
width="302.11731"
|
316
|
+
id="rect4195"
|
317
|
+
style="fill:#ffffdf;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
318
|
+
<text
|
319
|
+
xml:space="preserve"
|
320
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
321
|
+
x="576.00012"
|
322
|
+
y="592.44348"
|
323
|
+
id="text3010"
|
324
|
+
sodipodi:linespacing="125%"><tspan
|
325
|
+
sodipodi:role="line"
|
326
|
+
id="tspan3012"
|
327
|
+
x="576.00012"
|
328
|
+
y="592.44348"
|
329
|
+
style="font-size:16px">Web browser</tspan><tspan
|
330
|
+
sodipodi:role="line"
|
331
|
+
x="576.00012"
|
332
|
+
y="608.45648"
|
333
|
+
style="font-size:12px"
|
334
|
+
id="tspan3975">- Firefox, MSIE, Chrome, Opera, Safari</tspan><tspan
|
335
|
+
sodipodi:role="line"
|
336
|
+
x="576.00012"
|
337
|
+
y="623.45648"
|
338
|
+
style="font-size:12px"
|
339
|
+
id="tspan3977">- Window is displayed on the Selenium Host</tspan><tspan
|
340
|
+
sodipodi:role="line"
|
341
|
+
x="576.00012"
|
342
|
+
y="638.45648"
|
343
|
+
style="font-size:12px"
|
344
|
+
id="tspan3979" /></text>
|
345
|
+
<rect
|
346
|
+
style="fill:#ffffdf;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
347
|
+
id="rect4017"
|
348
|
+
width="302.11731"
|
349
|
+
height="92.699951"
|
350
|
+
x="151.97441"
|
351
|
+
y="445.40332"
|
352
|
+
rx="14.99066"
|
353
|
+
ry="19.188747" />
|
354
|
+
<text
|
355
|
+
sodipodi:linespacing="125%"
|
356
|
+
id="text4019"
|
357
|
+
y="473.66577"
|
358
|
+
x="169.55675"
|
359
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
360
|
+
xml:space="preserve"><tspan
|
361
|
+
style="font-size:16px"
|
362
|
+
y="473.66577"
|
363
|
+
x="169.55675"
|
364
|
+
sodipodi:role="line"
|
365
|
+
id="tspan4023">FitNesse wiki</tspan><tspan
|
366
|
+
style="font-size:12px"
|
367
|
+
y="489.67877"
|
368
|
+
x="169.55675"
|
369
|
+
sodipodi:role="line"
|
370
|
+
id="tspan4027">- Standalone Java .jar application</tspan><tspan
|
371
|
+
style="font-size:12px"
|
372
|
+
y="504.67877"
|
373
|
+
x="169.55675"
|
374
|
+
sodipodi:role="line"
|
375
|
+
id="tspan4029">- Primary frontend to the testing system</tspan><tspan
|
376
|
+
style="font-size:12px"
|
377
|
+
y="519.67877"
|
378
|
+
x="169.55675"
|
379
|
+
sodipodi:role="line"
|
380
|
+
id="tspan4033">- Anyone can view, edit, and run tests</tspan><tspan
|
381
|
+
style="font-size:12px"
|
382
|
+
y="534.67877"
|
383
|
+
x="169.55675"
|
384
|
+
sodipodi:role="line"
|
385
|
+
id="tspan4031" /></text>
|
386
|
+
<rect
|
387
|
+
ry="19.188747"
|
388
|
+
rx="14.99066"
|
389
|
+
y="569.99762"
|
390
|
+
x="151.97441"
|
391
|
+
height="56.868919"
|
392
|
+
width="302.11731"
|
393
|
+
id="rect4035"
|
394
|
+
style="fill:#ffffdf;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
395
|
+
<text
|
396
|
+
xml:space="preserve"
|
397
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
398
|
+
x="169.55675"
|
399
|
+
y="594.18829"
|
400
|
+
id="text4037"
|
401
|
+
sodipodi:linespacing="125%"><tspan
|
402
|
+
id="tspan4039"
|
403
|
+
sodipodi:role="line"
|
404
|
+
x="169.55675"
|
405
|
+
y="594.18829"
|
406
|
+
style="font-size:16px">rubyslim</tspan><tspan
|
407
|
+
id="tspan4045"
|
408
|
+
sodipodi:role="line"
|
409
|
+
x="169.55675"
|
410
|
+
y="610.20129"
|
411
|
+
style="font-size:12px">- Connects FitNesse to a Ruby backend</tspan><tspan
|
412
|
+
id="tspan4047"
|
413
|
+
sodipodi:role="line"
|
414
|
+
x="169.55675"
|
415
|
+
y="625.20129"
|
416
|
+
style="font-size:12px" /></text>
|
417
|
+
<rect
|
418
|
+
style="fill:#ffffdf;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
419
|
+
id="rect4054"
|
420
|
+
width="302.11731"
|
421
|
+
height="92.699966"
|
422
|
+
x="151.97441"
|
423
|
+
y="659.57526"
|
424
|
+
rx="14.99066"
|
425
|
+
ry="19.188747" />
|
426
|
+
<text
|
427
|
+
sodipodi:linespacing="125%"
|
428
|
+
id="text4056"
|
429
|
+
y="687.02332"
|
430
|
+
x="169.55675"
|
431
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
432
|
+
xml:space="preserve"><tspan
|
433
|
+
style="font-size:16px"
|
434
|
+
y="687.02332"
|
435
|
+
x="169.55675"
|
436
|
+
sodipodi:role="line"
|
437
|
+
id="tspan4058">Rsel</tspan><tspan
|
438
|
+
style="font-size:12px"
|
439
|
+
y="703.03632"
|
440
|
+
x="169.55675"
|
441
|
+
sodipodi:role="line"
|
442
|
+
id="tspan4060">- Pure Ruby backend</tspan><tspan
|
443
|
+
style="font-size:12px"
|
444
|
+
y="718.03632"
|
445
|
+
x="169.55675"
|
446
|
+
sodipodi:role="line"
|
447
|
+
id="tspan4064">- Dynamic and object-oriented</tspan><tspan
|
448
|
+
style="font-size:12px"
|
449
|
+
y="733.03632"
|
450
|
+
x="169.55675"
|
451
|
+
sodipodi:role="line"
|
452
|
+
id="tspan4066">- May be customized and extended</tspan><tspan
|
453
|
+
style="font-size:12px"
|
454
|
+
y="748.03632"
|
455
|
+
x="169.55675"
|
456
|
+
sodipodi:role="line"
|
457
|
+
id="tspan4062" /></text>
|
458
|
+
<rect
|
459
|
+
ry="19.188747"
|
460
|
+
rx="14.99066"
|
461
|
+
y="782.54089"
|
462
|
+
x="151.97441"
|
463
|
+
height="78.041824"
|
464
|
+
width="302.11731"
|
465
|
+
id="rect4068"
|
466
|
+
style="fill:#ffffdf;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
467
|
+
<text
|
468
|
+
xml:space="preserve"
|
469
|
+
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
470
|
+
x="169.55675"
|
471
|
+
y="809.98895"
|
472
|
+
id="text4070"
|
473
|
+
sodipodi:linespacing="125%"><tspan
|
474
|
+
id="tspan4072"
|
475
|
+
sodipodi:role="line"
|
476
|
+
x="169.55675"
|
477
|
+
y="809.98895"
|
478
|
+
style="font-size:16px">selenium-client</tspan><tspan
|
479
|
+
id="tspan4078"
|
480
|
+
sodipodi:role="line"
|
481
|
+
x="169.55675"
|
482
|
+
y="826.00195"
|
483
|
+
style="font-size:12px">- Remote Control for selenium-server</tspan><tspan
|
484
|
+
sodipodi:role="line"
|
485
|
+
x="169.55675"
|
486
|
+
y="841.00195"
|
487
|
+
style="font-size:12px"
|
488
|
+
id="tspan4087">- Rich commands for controlling a browser</tspan><tspan
|
489
|
+
id="tspan4080"
|
490
|
+
sodipodi:role="line"
|
491
|
+
x="169.55675"
|
492
|
+
y="856.00195"
|
493
|
+
style="font-size:12px" /></text>
|
494
|
+
</g>
|
495
|
+
</svg>
|
data/docs/scenarios.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
Scenarios
|
2
|
+
=========
|
3
|
+
|
4
|
+
When writing test scripts in FitNesse, it's likely that you'll have certain
|
5
|
+
steps repeated in several places. For instance, if your website has a user
|
6
|
+
login feature, logging into the site may be something you need to do at the
|
7
|
+
beginning of each script. One way to encapsulate these steps is by writing a
|
8
|
+
[custom step](custom.md) that accepts the username and password as parameters.
|
9
|
+
Another way is to use a [Scenario table](http://fitnesse.org/FitNesse.UserGuide.SliM.ScenarioTable),
|
10
|
+
which lets you define the sub-steps directly in your FitNesse wiki.
|
11
|
+
|
12
|
+
Here is a sample Scenario table for logging in:
|
13
|
+
|
14
|
+
| scenario | Login with username _ and password _ | username, password |
|
15
|
+
| Fill in | Username | with | @username |
|
16
|
+
| Fill in | Password | with | @password |
|
17
|
+
| Press | Login |
|
18
|
+
| Page loads in | 10 | seconds or less |
|
19
|
+
| See | Login successful |
|
20
|
+
|
21
|
+
This Scenario table accepts `username` and `password` parameters; the `@`
|
22
|
+
prefix causes the parameter values to be expanded within the table. To call
|
23
|
+
this Scenario from a Script table:
|
24
|
+
|
25
|
+
| script | selenium test | http://www.example.com |
|
26
|
+
| Open browser |
|
27
|
+
| Login with username Administrator and password LetMeIn |
|
28
|
+
|
29
|
+
For maximum reusability, you may want to create a wiki page (or several)
|
30
|
+
dedicated to helper scenarios, which can be included by the pages that use
|
31
|
+
them. For example, given this page hierarchy:
|
32
|
+
|
33
|
+
- `MyTests`
|
34
|
+
- `SetUp`
|
35
|
+
- `HelperScenarios`
|
36
|
+
- `TestOne`
|
37
|
+
- `TestTwo`
|
38
|
+
|
39
|
+
If your Scenario table is in `HelperScenarios`, and `TestOne` and `TestTwo`
|
40
|
+
both need to call the Login scenario, put this line at the top of `TestOne`
|
41
|
+
and `TestTwo`:
|
42
|
+
|
43
|
+
!include HelperScenarios
|
44
|
+
|
45
|
+
When executing any Script that includes Scenarios, the steps of that scenario
|
46
|
+
are expanded within the results table, so you can see the status of all
|
47
|
+
sub-steps. It's possible to nest scenarios within scenarios, to build more
|
48
|
+
complex steps out of simpler ones.
|
49
|
+
|
50
|
+
Next: [Development](development.md)
|
51
|
+
|
data/docs/scoping.md
CHANGED
@@ -27,6 +27,10 @@ you try to do this in your Rsel table:
|
|
27
27
|
|
28
28
|
| Type | 123-456-7890 | into | Phone number | field |
|
29
29
|
|
30
|
+
Or this with Ruby:
|
31
|
+
|
32
|
+
type_into_field "123-456-7890", "Phone number"
|
33
|
+
|
30
34
|
Rsel will just fill in the first matching field that it finds (in this case,
|
31
35
|
the "work" phone number). If you needed to fill in the "home" phone number,
|
32
36
|
you'd have to refer to it by something less ambiguous, such as its `id`:
|
@@ -45,6 +49,11 @@ of its container:
|
|
45
49
|
| Type | 111-222-3333 | into | Phone number | field | !{within:work} |
|
46
50
|
| Type | 111-222-4444 | into | Phone number | field | !{within:home} |
|
47
51
|
|
52
|
+
With plain Ruby:
|
53
|
+
|
54
|
+
type_into_field "111-222-3333", "Phone number", :within => "work"
|
55
|
+
type_into_field "111-222-4444", "Phone number", :within => "home"
|
56
|
+
|
48
57
|
Yeah I know, we're still using an `id` which could be annoyingly long, but if
|
49
58
|
there are a lot of fields in each container, you only need to keep track of one
|
50
59
|
`id` instead of several.
|
@@ -72,6 +81,10 @@ unique to that row:
|
|
72
81
|
|
73
82
|
| Click | Edit | link | !{in_row:Marcus} |
|
74
83
|
|
84
|
+
In Ruby:
|
85
|
+
|
86
|
+
click_link "Edit", :in_row => "Marcus"
|
87
|
+
|
75
88
|
This works for any method that accepts scoping qualifiers, so you can use it to
|
76
89
|
operate on checkboxes, dropdowns, or text fields as well.
|
77
90
|
|
@@ -79,15 +92,15 @@ operate on checkboxes, dropdowns, or text fields as well.
|
|
79
92
|
Caveat
|
80
93
|
------
|
81
94
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
95
|
+
With FitNesse, when using a scoping hash, your tables must not be fully
|
96
|
+
escaped. This just means you should not include a `!` at the beginning of your
|
97
|
+
table, otherwise the hash syntax will be interpreted literally, instead of as
|
98
|
+
an embedded hash.
|
86
99
|
|
87
|
-
This means you
|
88
|
-
|
89
|
-
|
90
|
-
|
100
|
+
This means you should manually escape any cells in your table that contain
|
101
|
+
URLs, email addresses, or other auto-interpreted text. For example, email
|
102
|
+
addresses normally have HTML added by FitNesse; you'll have to escape those so
|
103
|
+
they'll be treated as literal text:
|
91
104
|
|
92
105
|
| Click | !-epierce@example.com-! | link | !{within:footer} |
|
93
106
|
|
data/docs/todo.md
CHANGED
@@ -8,5 +8,10 @@ To-do list
|
|
8
8
|
- Verify the presence of images, allow clicking on images
|
9
9
|
- Create a Selenium IDE plugin to generate FitNesse-formatted output for
|
10
10
|
recorded scripts
|
11
|
+
- Avoid page-latency issues by automatically waiting for requests to finish.
|
12
|
+
Don't make the user insert wait-for-load / pause-seconds steps everywhere.
|
13
|
+
- Add documentation for non-FitNesse usage
|
14
|
+
- Possibly add a wrapper for selenium-server, so users can easily get started
|
15
|
+
without manually downloading selenium-server.jar and starting it up
|
11
16
|
|
12
17
|
Next: [History](history.md)
|
data/docs/usage.md
CHANGED
@@ -1,58 +1,56 @@
|
|
1
1
|
Usage
|
2
2
|
=====
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
By default,
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
theoretically possible to navigate to a different domain, but the Selenium
|
52
|
-
driver frowns upon it.)
|
4
|
+
Rsel was originally designed for use with [FitNesse](http://fitnesse.org)
|
5
|
+
script tables, but it works just as well without FitNesse. This page describes
|
6
|
+
the basic principles of using Rsel in a Ruby script. If you plan to use Rsel
|
7
|
+
through FitNesse, you can skip to [FitNesse](fitnesse.md).
|
8
|
+
|
9
|
+
Here is a simple example of a Ruby script that uses Rsel to login to a website:
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'rsel/selenium_test'
|
13
|
+
|
14
|
+
# Custom test class
|
15
|
+
class MyTest < SeleniumTest
|
16
|
+
def login
|
17
|
+
visit "/login"
|
18
|
+
fill_in_with "Username", "admin"
|
19
|
+
fill_in_with "Password", "B4tM4n"
|
20
|
+
press "Log in"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# The "main" program
|
25
|
+
if __FILE__ == $0
|
26
|
+
st = MyTest.new("http://my.site.com")
|
27
|
+
st.open_browser
|
28
|
+
st.login
|
29
|
+
st.close_browser
|
30
|
+
end
|
31
|
+
|
32
|
+
The `SeleniumTest` class is the main API to Rsel, handling all browser actions
|
33
|
+
that you might want to do. Overriding it allows you to define custom actions,
|
34
|
+
built upon the ones already provided.
|
35
|
+
|
36
|
+
When you instantiate a `SeleniumTest`, you need to pass a URL. This is the URL
|
37
|
+
of the website you are testing; in this example, we're logging into
|
38
|
+
`http://my.site.com`. By default, `SeleniumTest` assumes your Selenium Server
|
39
|
+
is running on `localhost` port `4444`; if your Selenium Server is running
|
40
|
+
elsewhere, just provide the host and port to the `SeleniumTest` (in this case,
|
41
|
+
`MyTest`) constructor:
|
42
|
+
|
43
|
+
st = MyTest.new("http://my.site.com", :host => 'my.selenium.host', :port => '4445')
|
44
|
+
|
45
|
+
The next step, `open_browser`, is very important. This is what starts up the web
|
46
|
+
browser, connects to the test system's URL, and executes all further actions.
|
47
|
+
|
48
|
+
After opening the browser, you can call any of the methods `SeleniumTest`
|
49
|
+
provides, or any custom ones you have defined in your `MyTest` derived class.
|
50
|
+
When you're done, use `close_browser` to end the session.
|
53
51
|
|
54
52
|
See the `SeleniumTest` class documentation for a full list of available methods
|
55
53
|
and how to use them.
|
56
54
|
|
57
|
-
Next: [
|
55
|
+
Next: [FitNesse](fitnesse.md)
|
58
56
|
|
data/lib/rsel/selenium_test.rb
CHANGED
@@ -37,7 +37,8 @@ module Rsel
|
|
37
37
|
# @option options [String] :port
|
38
38
|
# Port number of selenium-server
|
39
39
|
# @option options [String] :browser
|
40
|
-
# Which browser to
|
40
|
+
# Which browser to run. Should be a string like `'*firefox'` (default),
|
41
|
+
# `'*googlechrome'`, `'*opera'`, `'*iexplore'`, `'*safari'` etc.
|
41
42
|
# @option options [String, Boolean] :stop_on_error
|
42
43
|
# `true` or `'true'` to raise an exception when a step fails,
|
43
44
|
# `false` or `'false'` to simply return false when a step fails
|
@@ -85,6 +86,12 @@ module Rsel
|
|
85
86
|
else
|
86
87
|
visit @url
|
87
88
|
end
|
89
|
+
|
90
|
+
# Use javascript-xpath for IE, since it's a lot faster than the default
|
91
|
+
if @browser.browser_string == '*iexplore'
|
92
|
+
@browser.use_xpath_library('javascript-xpath')
|
93
|
+
end
|
94
|
+
|
88
95
|
# Make Selenium highlight elements whenever it locates them
|
89
96
|
@browser.highlight_located_element = true
|
90
97
|
end
|
data/rsel.gemspec
CHANGED
data/spec/selenium_test_spec.rb
CHANGED
@@ -35,11 +35,16 @@ describe Rsel::SeleniumTest do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
# FIXME: Selenium server 2.3.0 and 2.4.0 no longer fail
|
39
|
+
# when a 404 or 500 error is raised
|
40
|
+
#context "fails when" do
|
41
|
+
#it "page gets a 404 error" do
|
42
|
+
#@st.visit("/404").should be_false
|
43
|
+
#end
|
44
|
+
#it "page gets a 500 error" do
|
45
|
+
#@st.visit("/500").should be_false
|
46
|
+
#end
|
47
|
+
#end
|
43
48
|
end
|
44
49
|
|
45
50
|
context "reload the current page" do
|
@@ -97,7 +102,7 @@ describe Rsel::SeleniumTest do
|
|
97
102
|
end
|
98
103
|
|
99
104
|
context "fails when" do
|
100
|
-
it "
|
105
|
+
it "text is present" do
|
101
106
|
@st.do_not_see("Welcome").should be_false
|
102
107
|
@st.do_not_see("This is a Sinatra webapp").should be_false
|
103
108
|
end
|
@@ -130,6 +135,7 @@ describe Rsel::SeleniumTest do
|
|
130
135
|
end
|
131
136
|
end
|
132
137
|
|
138
|
+
|
133
139
|
describe "#click_link" do
|
134
140
|
context "passes when" do
|
135
141
|
it "link exists" do
|
@@ -935,6 +941,35 @@ describe Rsel::SeleniumTest do
|
|
935
941
|
end # tables
|
936
942
|
|
937
943
|
|
944
|
+
context "waiting" do
|
945
|
+
before(:each) do
|
946
|
+
@st.visit("/").should be_true
|
947
|
+
end
|
948
|
+
|
949
|
+
describe "#page_loads_in_seconds_or_less" do
|
950
|
+
context "passes when" do
|
951
|
+
it "page is already loaded" do
|
952
|
+
@st.click_link("About this site").should be_true
|
953
|
+
sleep 1
|
954
|
+
@st.page_loads_in_seconds_or_less(10).should be_true
|
955
|
+
end
|
956
|
+
it "page loads before the timeout" do
|
957
|
+
@st.click_link("Slow page").should be_true
|
958
|
+
@st.page_loads_in_seconds_or_less(10).should be_true
|
959
|
+
@st.see("This page takes a few seconds to load").should be_true
|
960
|
+
end
|
961
|
+
end
|
962
|
+
|
963
|
+
context "fails when" do
|
964
|
+
it "slow page does not load before the timeout" do
|
965
|
+
@st.click_link("Slow page").should be_true
|
966
|
+
@st.page_loads_in_seconds_or_less(1).should be_false
|
967
|
+
end
|
968
|
+
end
|
969
|
+
end
|
970
|
+
end # waiting
|
971
|
+
|
972
|
+
|
938
973
|
context "stop on error" do
|
939
974
|
before(:each) do
|
940
975
|
@st.visit("/").should be_true
|
@@ -1086,6 +1121,7 @@ describe Rsel::SeleniumTest do
|
|
1086
1121
|
end
|
1087
1122
|
end # stop on error
|
1088
1123
|
|
1124
|
+
|
1089
1125
|
context "Selenium::Client::Driver wrapper" do
|
1090
1126
|
before(:each) do
|
1091
1127
|
@st.visit("/form").should be_true
|
data/test/app.rb
CHANGED
@@ -17,8 +17,19 @@ class TestApp < Sinatra::Base
|
|
17
17
|
# Allow shutting down the app with a request
|
18
18
|
if view == 'shutdown'
|
19
19
|
Process.kill('KILL', Process.pid)
|
20
|
+
elsif view == 'slow'
|
21
|
+
sleep 5
|
22
|
+
erb :slow
|
23
|
+
elsif view == '404'
|
24
|
+
halt 404, "404: not found"
|
25
|
+
elsif view == '500'
|
26
|
+
halt 500, "500: server error"
|
20
27
|
else
|
21
|
-
|
28
|
+
begin
|
29
|
+
erb view.to_sym
|
30
|
+
rescue
|
31
|
+
halt 404, "404: not found"
|
32
|
+
end
|
22
33
|
end
|
23
34
|
end
|
24
35
|
end
|
data/test/views/index.erb
CHANGED
data/test/views/slow.erb
ADDED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Marcus French
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2011-
|
20
|
+
date: 2011-09-23 00:00:00 -06:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
@@ -156,10 +156,14 @@ files:
|
|
156
156
|
- docs/custom.md
|
157
157
|
- docs/development.md
|
158
158
|
- docs/examples.md
|
159
|
+
- docs/fitnesse.md
|
159
160
|
- docs/history.md
|
160
161
|
- docs/index.md
|
161
162
|
- docs/install.md
|
162
163
|
- docs/locators.md
|
164
|
+
- docs/rsel_components.png
|
165
|
+
- docs/rsel_components.svg
|
166
|
+
- docs/scenarios.md
|
163
167
|
- docs/scoping.md
|
164
168
|
- docs/todo.md
|
165
169
|
- docs/usage.md
|
@@ -180,6 +184,7 @@ files:
|
|
180
184
|
- test/views/form.erb
|
181
185
|
- test/views/index.erb
|
182
186
|
- test/views/readonly_form.erb
|
187
|
+
- test/views/slow.erb
|
183
188
|
- test/views/table.erb
|
184
189
|
- test/views/thanks.erb
|
185
190
|
has_rdoc: true
|