kelp 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +12 -0
  3. data/Gemfile.lock +91 -0
  4. data/MIT-LICENSE +22 -0
  5. data/README.md +16 -0
  6. data/Rakefile +16 -0
  7. data/docs/Makefile +130 -0
  8. data/docs/_static/custom.css +9 -0
  9. data/docs/conf.py +217 -0
  10. data/docs/development.rst +27 -0
  11. data/docs/future.rst +9 -0
  12. data/docs/index.rst +33 -0
  13. data/docs/make.bat +155 -0
  14. data/docs/testing.rst +15 -0
  15. data/docs/usage.rst +85 -0
  16. data/kelp.gemspec +25 -0
  17. data/lib/kelp.rb +1 -0
  18. data/lib/kelp/capybara.rb +2 -0
  19. data/lib/kelp/capybara/capybara_steps.rb +225 -0
  20. data/lib/kelp/capybara/form_helper.rb +131 -0
  21. data/lib/kelp/capybara/web_helper.rb +148 -0
  22. data/spec/capybara/click_link_in_row_spec.rb +24 -0
  23. data/spec/capybara/dropdown_spec.rb +112 -0
  24. data/spec/capybara/field_should_be_empty_spec.rb +44 -0
  25. data/spec/capybara/field_should_contain_spec.rb +143 -0
  26. data/spec/capybara/fill_in_fields_spec.rb +67 -0
  27. data/spec/capybara/follow_spec.rb +35 -0
  28. data/spec/capybara/page_should_have_spec.rb +48 -0
  29. data/spec/capybara/page_should_not_have_spec.rb +53 -0
  30. data/spec/capybara/press_spec.rb +33 -0
  31. data/spec/capybara/should_be_disabled_spec.rb +28 -0
  32. data/spec/capybara/should_be_enabled_spec.rb +29 -0
  33. data/spec/capybara/should_not_see_spec.rb +97 -0
  34. data/spec/capybara/should_see_in_same_row_spec.rb +41 -0
  35. data/spec/capybara/should_see_spec.rb +80 -0
  36. data/spec/capybara/spec_helper.rb +22 -0
  37. data/spec/test_app/test_app.rb +18 -0
  38. data/spec/test_app/views/about.erb +9 -0
  39. data/spec/test_app/views/edit1.erb +9 -0
  40. data/spec/test_app/views/edit2.erb +9 -0
  41. data/spec/test_app/views/edit3.erb +9 -0
  42. data/spec/test_app/views/form.erb +38 -0
  43. data/spec/test_app/views/home.erb +46 -0
  44. data/spec/test_app/views/thanks.erb +10 -0
  45. metadata +183 -0
@@ -0,0 +1,27 @@
1
+ Development
2
+ ===========
3
+
4
+ If you'd like to hack on Kelp, fork the repository, then clone your fork::
5
+
6
+ $ git clone git://github.com/<your_username>/kelp.git
7
+
8
+ Install bundler_::
9
+
10
+ $ gem install bundler
11
+
12
+ Then install Kelp's dependencies (specified in ``Gemfile``)::
13
+
14
+ $ cd /path/to/kelp
15
+ $ bundle install
16
+
17
+ It's a good idea to use RVM_ with a new gemset to keep things tidy.
18
+
19
+ If you make changes that you'd like to share, push them into your Kelp fork,
20
+ then `submit a pull request`_.
21
+
22
+
23
+ .. _bundler: http://gembundler.com/
24
+ .. _RVM: http://rvm.beginrescueend.com/
25
+ .. _submit a pull request: http://github.com/wapcaplet/kelp/pulls
26
+
27
+
data/docs/future.rst ADDED
@@ -0,0 +1,9 @@
1
+ Future plans
2
+ ============
3
+
4
+ * Write Cucumber integration tests
5
+ * Support other stuff besides Caypbara
6
+ * Turn the project into a proper Rails plugin, with generators
7
+ * Create a gem
8
+
9
+
data/docs/index.rst ADDED
@@ -0,0 +1,33 @@
1
+ .. Kelp documentation master file, created by
2
+ sphinx-quickstart on Sun Dec 12 16:07:03 2010.
3
+ You can adapt this file completely to your liking, but it should at least
4
+ contain the root `toctree` directive.
5
+
6
+ Kelp
7
+ ====
8
+
9
+ This is the documentation for Kelp_, a collection of helpers that makes it
10
+ easier to write step definitions for Cucumber_. The Kelp gem is hosted on
11
+ Rubygems_, so you can install it with::
12
+
13
+ $ gem install kelp
14
+
15
+ The name "Kelp" is a contraction of "Cuke Helpers". It was chosen because it's
16
+ short, easy to remember, and is in keeping with the theme of greenish plants.
17
+ Kelp is licensed under the `MIT License`_.
18
+
19
+ Please use the `issue tracker`_ to report any bugs or feature requests.
20
+
21
+ .. toctree::
22
+ :maxdepth: 2
23
+
24
+ usage
25
+ development
26
+ testing
27
+ future
28
+
29
+ .. _Kelp: http://github.com/wapcaplet/kelp
30
+ .. _Cucumber: http://cukes.info/
31
+ .. _Rubygems: http://rubygems.org/gems/kelp
32
+ .. _MIT License: http://www.opensource.org/licenses/mit-license.php
33
+ .. _issue tracker: http://github.com/wapcaplet/kelp/issues
data/docs/make.bat ADDED
@@ -0,0 +1,155 @@
1
+ @ECHO OFF
2
+
3
+ REM Command file for Sphinx documentation
4
+
5
+ if "%SPHINXBUILD%" == "" (
6
+ set SPHINXBUILD=sphinx-build
7
+ )
8
+ set BUILDDIR=_build
9
+ set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10
+ if NOT "%PAPER%" == "" (
11
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
12
+ )
13
+
14
+ if "%1" == "" goto help
15
+
16
+ if "%1" == "help" (
17
+ :help
18
+ echo.Please use `make ^<target^>` where ^<target^> is one of
19
+ echo. html to make standalone HTML files
20
+ echo. dirhtml to make HTML files named index.html in directories
21
+ echo. singlehtml to make a single large HTML file
22
+ echo. pickle to make pickle files
23
+ echo. json to make JSON files
24
+ echo. htmlhelp to make HTML files and a HTML help project
25
+ echo. qthelp to make HTML files and a qthelp project
26
+ echo. devhelp to make HTML files and a Devhelp project
27
+ echo. epub to make an epub
28
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
29
+ echo. text to make text files
30
+ echo. man to make manual pages
31
+ echo. changes to make an overview over all changed/added/deprecated items
32
+ echo. linkcheck to check all external links for integrity
33
+ echo. doctest to run all doctests embedded in the documentation if enabled
34
+ goto end
35
+ )
36
+
37
+ if "%1" == "clean" (
38
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
39
+ del /q /s %BUILDDIR%\*
40
+ goto end
41
+ )
42
+
43
+ if "%1" == "html" (
44
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
45
+ echo.
46
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
47
+ goto end
48
+ )
49
+
50
+ if "%1" == "dirhtml" (
51
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
52
+ echo.
53
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
54
+ goto end
55
+ )
56
+
57
+ if "%1" == "singlehtml" (
58
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
59
+ echo.
60
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
61
+ goto end
62
+ )
63
+
64
+ if "%1" == "pickle" (
65
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
66
+ echo.
67
+ echo.Build finished; now you can process the pickle files.
68
+ goto end
69
+ )
70
+
71
+ if "%1" == "json" (
72
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
73
+ echo.
74
+ echo.Build finished; now you can process the JSON files.
75
+ goto end
76
+ )
77
+
78
+ if "%1" == "htmlhelp" (
79
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
80
+ echo.
81
+ echo.Build finished; now you can run HTML Help Workshop with the ^
82
+ .hhp project file in %BUILDDIR%/htmlhelp.
83
+ goto end
84
+ )
85
+
86
+ if "%1" == "qthelp" (
87
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
88
+ echo.
89
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
90
+ .qhcp project file in %BUILDDIR%/qthelp, like this:
91
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Kelp.qhcp
92
+ echo.To view the help file:
93
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Kelp.ghc
94
+ goto end
95
+ )
96
+
97
+ if "%1" == "devhelp" (
98
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
99
+ echo.
100
+ echo.Build finished.
101
+ goto end
102
+ )
103
+
104
+ if "%1" == "epub" (
105
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
106
+ echo.
107
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
108
+ goto end
109
+ )
110
+
111
+ if "%1" == "latex" (
112
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
113
+ echo.
114
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
115
+ goto end
116
+ )
117
+
118
+ if "%1" == "text" (
119
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
120
+ echo.
121
+ echo.Build finished. The text files are in %BUILDDIR%/text.
122
+ goto end
123
+ )
124
+
125
+ if "%1" == "man" (
126
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
127
+ echo.
128
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
129
+ goto end
130
+ )
131
+
132
+ if "%1" == "changes" (
133
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
134
+ echo.
135
+ echo.The overview file is in %BUILDDIR%/changes.
136
+ goto end
137
+ )
138
+
139
+ if "%1" == "linkcheck" (
140
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
141
+ echo.
142
+ echo.Link check complete; look for any errors in the above output ^
143
+ or in %BUILDDIR%/linkcheck/output.txt.
144
+ goto end
145
+ )
146
+
147
+ if "%1" == "doctest" (
148
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
149
+ echo.
150
+ echo.Testing of doctests in the sources finished, look at the ^
151
+ results in %BUILDDIR%/doctest/output.txt.
152
+ goto end
153
+ )
154
+
155
+ :end
data/docs/testing.rst ADDED
@@ -0,0 +1,15 @@
1
+ Testing
2
+ =======
3
+
4
+ Kelp comes with a ``Rakefile``, so you can run the RSpec tests like so::
5
+
6
+ $ rake spec
7
+
8
+ You can also generate an rcov_ coverage report via::
9
+
10
+ $ rake rcov
11
+
12
+ This will write an HTML report to ``coverage/index.html``.
13
+
14
+ .. _rcov: http://eigenclass.org/hiki.rb?rcov
15
+
data/docs/usage.rst ADDED
@@ -0,0 +1,85 @@
1
+ Usage
2
+ =====
3
+
4
+ To use Kelp's helpers in your Cucumber step definitions, simply ``require`` the
5
+ helper module you're interested in:
6
+
7
+ .. code-block:: ruby
8
+
9
+ require 'kelp/capybara/web_helper'
10
+
11
+ Then add the relevant modules to Cucumber's ``World``:
12
+
13
+ .. code-block:: ruby
14
+
15
+ World(WebHelper)
16
+
17
+ Many of the provided helpers are designed to make it easier to do things you
18
+ might otherwise be tempted to do with nested step definitions. For example, if
19
+ you need to verify the presence of several text strings on a webpage, you might
20
+ have a step definition like this:
21
+
22
+ .. code-block:: ruby
23
+
24
+ Then /^I should see the login page$/ do
25
+ Then %{I should see "Welcome"}
26
+ And %{I should see "Thanks for visiting"}
27
+ And %{I should see "Login"}
28
+ end
29
+
30
+ Using the provided helper method ``should_see``, you can do this instead:
31
+
32
+ .. code-block:: ruby
33
+
34
+ Then /^I should see the login page$/ do
35
+ should_see "Welcome"
36
+ should_see "Thanks for visiting"
37
+ should_see "Login"
38
+ end
39
+
40
+ Or even this:
41
+
42
+ .. code-block:: ruby
43
+
44
+ Then /^I should see the login page$/ do
45
+ should_see [
46
+ "Welcome",
47
+ "Thanks for visiting",
48
+ "Login"
49
+ ]
50
+ end
51
+
52
+ Many of the provided methods are similar to their counterparts in the
53
+ Cucumber-Rails generated step definitions. Following links, filling in fields,
54
+ and pressing buttons can all be easily done with Ruby code instead of nested
55
+ steps. Thus this:
56
+
57
+ .. code-block:: ruby
58
+
59
+ When %{I follow "Login"}
60
+ And %{I fill in "Username" with "skroob"}
61
+ And %{I fill in "Password" with "12345"}
62
+ And %{I press "Log me in"}
63
+
64
+ translates to this:
65
+
66
+ .. code-block:: ruby
67
+
68
+ follow "Login"
69
+ fill_in_fields \
70
+ "Username" => "skroob",
71
+ "Password" => "12345"
72
+ press "Log me in"
73
+
74
+ Several methods also accept keywords to define the scope of an action. For
75
+ instance, if you want to look within an element with ``id="greeting"``, do:
76
+
77
+ .. code-block:: ruby
78
+
79
+ should_see "Welcome", :within => "#greeting"
80
+
81
+ At the moment, the ``:within`` keyword is the only accepted scope; the locator
82
+ you pass to this should be in whatever format your ``Capybara.default_selector``
83
+ is set to. Other keywords like ``:before`` or ``:after`` may be supported in future
84
+ revisions.
85
+
data/kelp.gemspec ADDED
@@ -0,0 +1,25 @@
1
+
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "kelp"
5
+ s.version = "0.1.1"
6
+ s.summary = "Cucumber helper methods"
7
+ s.description = <<-EOS
8
+ Kelp is a collection of helper methods for Cucumber to ease the process of
9
+ writing step definitions.
10
+ EOS
11
+ s.authors = ["Eric Pierce"]
12
+ s.email = "wapcaplet88@gmail.com"
13
+ s.homepage = "http://github.com/wapcaplet/kelp"
14
+ s.platform = Gem::Platform::RUBY
15
+
16
+ s.add_dependency 'capybara', '>= 0.4.0'
17
+
18
+ s.add_development_dependency 'sinatra'
19
+ s.add_development_dependency 'rspec', '>= 2.2.0'
20
+ s.add_development_dependency 'rspec-rails'
21
+ s.add_development_dependency 'rcov'
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.require_path = 'lib'
25
+ end
data/lib/kelp.rb ADDED
@@ -0,0 +1 @@
1
+ require 'kelp/capybara'
@@ -0,0 +1,2 @@
1
+ require 'kelp/capybara/web_helper'
2
+ require 'kelp/capybara/form_helper'
@@ -0,0 +1,225 @@
1
+ # <%= embed_file('support/edit_warning.txt') %>
2
+
3
+ require 'uri'
4
+ require 'cgi'
5
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
6
+
7
+ module WithinHelpers
8
+ def with_scope(locator)
9
+ locator ? within(locator) { yield } : yield
10
+ end
11
+ end
12
+ World(WithinHelpers)
13
+
14
+ Given /^(?:|I )am on (.+)$/ do |page_name|
15
+ visit path_to(page_name)
16
+ end
17
+
18
+ When /^(?:|I )go to (.+)$/ do |page_name|
19
+ visit path_to(page_name)
20
+ end
21
+
22
+ When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector|
23
+ press button, :within => selector
24
+ #with_scope(selector) do
25
+ #click_button(button)
26
+ #end
27
+ end
28
+
29
+ When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector|
30
+ follow link, :within => selector
31
+ #with_scope(selector) do
32
+ #click_link(link)
33
+ #end
34
+ end
35
+
36
+ When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field, value, selector|
37
+ fields = {field => value}
38
+ fill_in_fields fields, :within => selector
39
+ #with_scope(selector) do
40
+ #fill_in(field, :with => value)
41
+ #end
42
+ end
43
+
44
+ When /^(?:|I )fill in "([^"]*)" for "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
45
+ fields = {field => value}
46
+ fill_in_fields fields, :within => selector
47
+ #with_scope(selector) do
48
+ #fill_in(field, :with => value)
49
+ #end
50
+ end
51
+
52
+ # Use this to fill in an entire form with data from a table. Example:
53
+ #
54
+ # When I fill in the following:
55
+ # | Account Number | 5002 |
56
+ # | Expiry date | 2009-11-01 |
57
+ # | Note | Nice guy |
58
+ # | Wants Email? | |
59
+ #
60
+ # TODO: Add support for checkbox, select og option
61
+ # based on naming conventions.
62
+ #
63
+ When /^(?:|I )fill in the following(?: within "([^"]*)")?:$/ do |selector, fields|
64
+ fill_in_fields fields.rows_hash, :within => selector
65
+ #with_scope(selector) do
66
+ #fields.rows_hash.each do |name, value|
67
+ #When %{I fill in "#{name}" with "#{value}"}
68
+ #end
69
+ #end
70
+ end
71
+
72
+ When /^(?:|I )select "([^"]*)" from "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
73
+ with_scope(selector) do
74
+ select(value, :from => field)
75
+ end
76
+ end
77
+
78
+ When /^(?:|I )check "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
79
+ with_scope(selector) do
80
+ check(field)
81
+ end
82
+ end
83
+
84
+ When /^(?:|I )uncheck "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
85
+ with_scope(selector) do
86
+ uncheck(field)
87
+ end
88
+ end
89
+
90
+ When /^(?:|I )choose "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
91
+ with_scope(selector) do
92
+ choose(field)
93
+ end
94
+ end
95
+
96
+ When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"(?: within "([^"]*)")?$/ do |path, field, selector|
97
+ with_scope(selector) do
98
+ attach_file(field, path)
99
+ end
100
+ end
101
+
102
+ Then /^(?:|I )should see JSON:$/ do |expected_json|
103
+ require 'json'
104
+ expected = JSON.pretty_generate(JSON.parse(expected_json))
105
+ actual = JSON.pretty_generate(JSON.parse(response.body))
106
+ expected.should == actual
107
+ end
108
+
109
+ Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
110
+ should_see text, :within => selector
111
+ #with_scope(selector) do
112
+ #if page.respond_to? :should
113
+ #page.should have_content(text)
114
+ #else
115
+ #assert page.has_content?(text)
116
+ #end
117
+ #end
118
+ end
119
+
120
+ Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
121
+ should_see Regexp.new(regexp), :within => selector
122
+ #regexp = Regexp.new(regexp)
123
+ #with_scope(selector) do
124
+ #if page.respond_to? :should
125
+ #page.should have_xpath('//*', :text => regexp)
126
+ #else
127
+ #assert page.has_xpath?('//*', :text => regexp)
128
+ #end
129
+ #end
130
+ end
131
+
132
+ Then /^(?:|I )should not see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
133
+ should_not_see text, :within => selector
134
+ #with_scope(selector) do
135
+ #if page.respond_to? :should
136
+ #page.should have_no_content(text)
137
+ #else
138
+ #assert page.has_no_content?(text)
139
+ #end
140
+ #end
141
+ end
142
+
143
+ Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
144
+ should_not_see Regexp.new(regexp), :within => selector
145
+ #regexp = Regexp.new(regexp)
146
+ #with_scope(selector) do
147
+ #if page.respond_to? :should
148
+ #page.should have_no_xpath('//*', :text => regexp)
149
+ #else
150
+ #assert page.has_no_xpath?('//*', :text => regexp)
151
+ #end
152
+ #end
153
+ end
154
+
155
+ Then /^the "([^"]*)" field(?: within "([^"]*)")? should contain "([^"]*)"$/ do |field, selector, value|
156
+ with_scope(selector) do
157
+ field = find_field(field)
158
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
159
+ if field_value.respond_to? :should
160
+ field_value.should =~ /#{value}/
161
+ else
162
+ assert_match(/#{value}/, field_value)
163
+ end
164
+ end
165
+ end
166
+
167
+ Then /^the "([^"]*)" field(?: within "([^"]*)")? should not contain "([^"]*)"$/ do |field, selector, value|
168
+ with_scope(selector) do
169
+ field = find_field(field)
170
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
171
+ if field_value.respond_to? :should_not
172
+ field_value.should_not =~ /#{value}/
173
+ else
174
+ assert_no_match(/#{value}/, field_value)
175
+ end
176
+ end
177
+ end
178
+
179
+ Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should be checked$/ do |label, selector|
180
+ with_scope(selector) do
181
+ field_checked = find_field(label)['checked']
182
+ if field_checked.respond_to? :should
183
+ field_checked.should be_true
184
+ else
185
+ assert field_checked
186
+ end
187
+ end
188
+ end
189
+
190
+ Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |label, selector|
191
+ with_scope(selector) do
192
+ field_checked = find_field(label)['checked']
193
+ if field_checked.respond_to? :should
194
+ field_checked.should be_false
195
+ else
196
+ assert !field_checked
197
+ end
198
+ end
199
+ end
200
+
201
+ Then /^(?:|I )should be on (.+)$/ do |page_name|
202
+ current_path = URI.parse(current_url).path
203
+ if current_path.respond_to? :should
204
+ current_path.should == path_to(page_name)
205
+ else
206
+ assert_equal path_to(page_name), current_path
207
+ end
208
+ end
209
+
210
+ Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
211
+ query = URI.parse(current_url).query
212
+ actual_params = query ? CGI.parse(query) : {}
213
+ expected_params = {}
214
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
215
+
216
+ if actual_params.respond_to? :should
217
+ actual_params.should == expected_params
218
+ else
219
+ assert_equal expected_params, actual_params
220
+ end
221
+ end
222
+
223
+ Then /^show me the page$/ do
224
+ save_and_open_page
225
+ end