cucumber-api-steps 0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +11 -2
- data/README.md +91 -0
- data/Rakefile +8 -4
- data/cucumber-api-steps.gemspec +9 -5
- data/features/authentication.feature +21 -0
- data/features/fixtures/fake_app.rb +37 -0
- data/features/header.feature +32 -0
- data/features/request.feature +34 -0
- data/features/response.feature +112 -0
- data/features/step_definitions/api_test_steps.rb +45 -0
- data/features/support/env.rb +23 -0
- data/lib/cucumber/api_steps.rb +138 -33
- data/lib/cucumber/api_steps/version.rb +1 -1
- metadata +99 -82
- data/.rvmrc +0 -1
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 47646a126718a454f84de22a7919a0b1433b2b18
|
4
|
+
data.tar.gz: 34255c3e6bc067d566126fa70768abe30ceab12a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ef0f10de3c180d5fd54427138a9dced2d1d11a34a5942a650da16538cdddeabb5eec3cd1ddbf3a7c0452ab5426c1821701b3780c45636804e60c0a0e62fb61be
|
7
|
+
data.tar.gz: 3335fa36c67b4293f11c6389fc5ef95b419dbf8c8d7ef9de6d1ba37dcb8c05f525cf692e691df3081e9e63a9755b14784716bd888291a8ce8e886df59763f74e
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -1,4 +1,13 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
# Specify your gem's dependencies in cuke-api-steps.gemspec
|
4
3
|
gemspec
|
4
|
+
|
5
|
+
gem 'sinatra'
|
6
|
+
gem 'rack-test'
|
7
|
+
gem 'pry'
|
8
|
+
gem 'activesupport'
|
9
|
+
gem 'nokogiri'
|
10
|
+
|
11
|
+
group :test do
|
12
|
+
gem 'rake'
|
13
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# cucumber-api-steps
|
2
|
+
|
3
|
+
[](https://travis-ci.org/jayzes/cucumber-api-steps)
|
4
|
+
[](http://badge.fury.io/rb/cucumber-api-steps)
|
5
|
+
|
6
|
+
A set of [Cucumber](https://github.com/cucumber/cucumber) step definitions utilizing
|
7
|
+
[Rack-Test](https://github.com/brynary/rack-test) that ease basic
|
8
|
+
testing of REST-style APIs using either XML or JSON formats.
|
9
|
+
|
10
|
+
Adapted from [a blog post by Anthony Eden](http://anthonyeden.com/2013/07/10/testing-rest-apis-with-cucumber-and-rack.html) with a few additions based on my own needs. I found myself copying these step definitions around to multiple projects, and decided that it would be worthwhile to gem them up to keep things nice and DRY.
|
11
|
+
|
12
|
+
## Dependencies
|
13
|
+
|
14
|
+
Requires [Cucumber](https://github.com/aslakhellesoy/cucumber) (obviously). Also makes use of [JSONPath](https://github.com/joshbuddy/jsonpath) for setting criteria against JSON responses. See the gemspec for more info.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add the following line to your Gemfile, preferably in the test or cucumber group:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'cucumber-api-steps', :require => false
|
22
|
+
```
|
23
|
+
|
24
|
+
Then add the following line to your env.rb to make the step definitions available in your features:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
require 'cucumber/api_steps'
|
28
|
+
```
|
29
|
+
|
30
|
+
# Usage
|
31
|
+
|
32
|
+
Still a work in progress. For now, read the api_steps.rb file or check out the [stashboard-rails](https://github.com/jayzes/stashboard-rails) project - its Cucumber features make extensive use of the steps in this gem.
|
33
|
+
|
34
|
+
# Examples
|
35
|
+
```cucumber
|
36
|
+
Feature: API
|
37
|
+
|
38
|
+
Scenario: List tweets in JSON
|
39
|
+
When I send and accept JSON
|
40
|
+
And I send a GET request to "/api/tweets"
|
41
|
+
Then the response status should be "200"
|
42
|
+
And the JSON response should be:
|
43
|
+
"""
|
44
|
+
[{"tweet":"Hello World!"},{"tweet":"New Rails has been released"}]
|
45
|
+
"""
|
46
|
+
And the JSON response should have "$..tweet" with the text "Hello World!"
|
47
|
+
And the JSON response should have "$..tweet" with a length of 2
|
48
|
+
|
49
|
+
Scenario: List tweets in XML
|
50
|
+
When I send and accept XML
|
51
|
+
And I send a GET request to "/api/tweets"
|
52
|
+
Then the XML response should have "tweet" with text "Hello World!"
|
53
|
+
|
54
|
+
Scenario: Post tweet using POST-params
|
55
|
+
When I send a POST request to "/api/tweets" with the following:
|
56
|
+
| tweet | Hello World! |
|
57
|
+
| lat | 42.848282 |
|
58
|
+
| lng | 74.634933 |
|
59
|
+
Then the response status should be "201"
|
60
|
+
|
61
|
+
Scenario: Post tweet using json in POST body
|
62
|
+
When I send a POST request to "/api/tweets" with the following:
|
63
|
+
"""
|
64
|
+
{"tweet":"Hello World!","lat":"42.848282", "lng":"74.634933"}
|
65
|
+
"""
|
66
|
+
Then the response status should be "201"
|
67
|
+
|
68
|
+
Scenario: Basic authentication
|
69
|
+
When I authenticate as the user "joe" with the password "password123"
|
70
|
+
And I send a GET request to "/api/tweets"
|
71
|
+
Then the response status should be "200"
|
72
|
+
|
73
|
+
Scenario: Digest authentication
|
74
|
+
When I digest-authenticate as the user "joe" with the password "password123"
|
75
|
+
And I send a GET request to "/api/tweets"
|
76
|
+
Then the response status should be "200"
|
77
|
+
```
|
78
|
+
# Contributors
|
79
|
+
* Jay Zeschin
|
80
|
+
* Justin Smestad
|
81
|
+
* Kevin Pfefferle
|
82
|
+
* Kalys Osmonov
|
83
|
+
* Mingding Han
|
84
|
+
* Gabe Varela
|
85
|
+
* Steven Heidel
|
86
|
+
* Adam Elhardt
|
87
|
+
* Gonzalo Bulnes Guilpain
|
88
|
+
|
89
|
+
## Copyright
|
90
|
+
|
91
|
+
Copyright (c) 2011 Jay Zeschin. Distributed under the MIT License.
|
data/Rakefile
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
Bundler::GemHelper.install_tasks
|
1
|
+
require 'bundler/gem_tasks'
|
3
2
|
|
4
|
-
require '
|
5
|
-
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
|
5
|
+
Cucumber::Rake::Task.new do |t|
|
6
|
+
t.cucumber_opts = %w{--format pretty}
|
7
|
+
end
|
8
|
+
|
9
|
+
task :default => :cucumber
|
data/cucumber-api-steps.gemspec
CHANGED
@@ -7,14 +7,18 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Cucumber::ApiSteps::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Jay Zeschin"]
|
10
|
-
s.email = ["jay
|
10
|
+
s.email = ["jay@zeschin.org"]
|
11
11
|
s.homepage = "http://github.com/jayzes/cucumber-api-steps"
|
12
12
|
s.summary = %q{Cucumber steps to easily test REST-based XML and JSON APIs}
|
13
13
|
s.description = %q{Cucumber steps to easily test REST-based XML and JSON APIs}
|
14
|
-
|
15
|
-
s.
|
16
|
-
|
17
|
-
s.
|
14
|
+
|
15
|
+
s.required_ruby_version = '>= 1.9.3'
|
16
|
+
|
17
|
+
s.add_dependency 'jsonpath', '>= 0.1.2'
|
18
|
+
s.add_dependency 'cucumber', '>= 2.0.2'
|
19
|
+
s.add_development_dependency 'activesupport', '>= 3.0.0'
|
20
|
+
s.add_development_dependency 'rspec', '~> 3.3.0'
|
21
|
+
s.add_development_dependency 'sinatra', '~> 1.4.3'
|
18
22
|
|
19
23
|
s.files = `git ls-files`.split("\n")
|
20
24
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature:
|
2
|
+
As cucumber tester
|
3
|
+
I want to test basic authentication
|
4
|
+
|
5
|
+
Scenario: Basic authentication
|
6
|
+
When I perform the following steps:
|
7
|
+
"""
|
8
|
+
I authenticate as the user "joe" with the password "god"
|
9
|
+
I send a GET request for "/"
|
10
|
+
"""
|
11
|
+
Then I should be authenticated
|
12
|
+
|
13
|
+
|
14
|
+
@digest-auth
|
15
|
+
Scenario: Successful digest authentication
|
16
|
+
When I perform the following steps:
|
17
|
+
"""
|
18
|
+
I digest-authenticate as the user "joe" with the password "god"
|
19
|
+
I send a GET request for "/"
|
20
|
+
"""
|
21
|
+
Then I should be digest authenticated
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "sinatra/base"
|
3
|
+
|
4
|
+
module CucumberApiSteps
|
5
|
+
class FakeApp < Sinatra::Base
|
6
|
+
|
7
|
+
get '/' do end
|
8
|
+
|
9
|
+
get '/api/books' do
|
10
|
+
books = {books: [
|
11
|
+
{title: 'Pride and prejudice'},
|
12
|
+
{title: 'Metaprograming ruby'}
|
13
|
+
]}
|
14
|
+
|
15
|
+
if request.accept.empty? || request.accept?('application/json')
|
16
|
+
content_type :json
|
17
|
+
books.to_json
|
18
|
+
elsif request.accept?('application/xml')
|
19
|
+
content_type :xml
|
20
|
+
books.to_xml
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
post '/api/books' do
|
25
|
+
status 201 if params.values == ["Metaprograming ruby", "Pragprog"]
|
26
|
+
end
|
27
|
+
|
28
|
+
patch '/api/books' do
|
29
|
+
status 200 if params.values == ["Metaprograming ruby", "Pragprog"]
|
30
|
+
end
|
31
|
+
|
32
|
+
post '/api/publishers' do
|
33
|
+
input_data = JSON.parse request.env["rack.input"].read, symbolize_names: true
|
34
|
+
status 201 if input_data == {publisher: 'Pragprog'}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Feature:
|
2
|
+
As cucumber tester
|
3
|
+
I should be able to set headers for request
|
4
|
+
|
5
|
+
Scenario: Set multiple headers
|
6
|
+
When I perform the following step with table:
|
7
|
+
"""
|
8
|
+
I set headers:
|
9
|
+
| Accept | application/vnd.myproject.v1 |
|
10
|
+
| User-Agent | Cucumber Api Steps Client |
|
11
|
+
"""
|
12
|
+
Then the request headers should be:
|
13
|
+
| HTTP_ACCEPT | application/vnd.myproject.v1 |
|
14
|
+
| HTTP_USER_AGENT | Cucumber Api Steps Client |
|
15
|
+
|
16
|
+
Scenario: Send and accept JSON
|
17
|
+
When I perform the following step:
|
18
|
+
"""
|
19
|
+
I send and accept JSON
|
20
|
+
"""
|
21
|
+
Then the request headers should be:
|
22
|
+
| HTTP_ACCEPT | application/json |
|
23
|
+
| CONTENT_TYPE | application/json |
|
24
|
+
|
25
|
+
Scenario: Send and accept HTML
|
26
|
+
When I perform the following step:
|
27
|
+
"""
|
28
|
+
I send and accept HTML
|
29
|
+
"""
|
30
|
+
Then the request headers should be:
|
31
|
+
| HTTP_ACCEPT | text/html |
|
32
|
+
| CONTENT_TYPE | application/x-www-form-urlencoded |
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Feature:
|
2
|
+
|
3
|
+
Scenario: GET request
|
4
|
+
When I perform the following step:
|
5
|
+
"""
|
6
|
+
I send a GET request to "/api/books"
|
7
|
+
"""
|
8
|
+
Then the response status should be "200"
|
9
|
+
|
10
|
+
Scenario: POST request with params
|
11
|
+
When I perform the following step with table:
|
12
|
+
"""
|
13
|
+
I send a POST request to "/api/books" with the following:
|
14
|
+
| title | Metaprograming ruby |
|
15
|
+
| publisher | Pragprog |
|
16
|
+
"""
|
17
|
+
Then the response status should be "201"
|
18
|
+
|
19
|
+
Scenario: PATCH request with params
|
20
|
+
When I perform the following step with table:
|
21
|
+
"""
|
22
|
+
I send a PATCH request to "/api/books" with the following:
|
23
|
+
| title | Metaprograming ruby |
|
24
|
+
| publisher | Pragprog |
|
25
|
+
"""
|
26
|
+
Then the response status should be "200"
|
27
|
+
|
28
|
+
Scenario: POST request with string
|
29
|
+
When I perform the following step with string:
|
30
|
+
"""
|
31
|
+
I send a POST request to "/api/publishers" with the following:
|
32
|
+
{"publisher": "Pragprog"}
|
33
|
+
"""
|
34
|
+
Then the response status should be "201"
|
@@ -0,0 +1,112 @@
|
|
1
|
+
Feature:
|
2
|
+
As cucumber tester
|
3
|
+
I want to test response
|
4
|
+
|
5
|
+
Scenario: Test response status
|
6
|
+
When I perform the following step:
|
7
|
+
"""
|
8
|
+
I send a GET request to "/"
|
9
|
+
"""
|
10
|
+
|
11
|
+
Then the response status should be "200"
|
12
|
+
|
13
|
+
Scenario: Test that JSON response contains a node
|
14
|
+
When I perform the following step:
|
15
|
+
"""
|
16
|
+
I send a GET request to "/api/books"
|
17
|
+
"""
|
18
|
+
Then the JSON response should have "$..title"
|
19
|
+
|
20
|
+
Scenario: Test that JSON response does not contain a node
|
21
|
+
When I perform the following step:
|
22
|
+
"""
|
23
|
+
I send a GET request to "/api/books"
|
24
|
+
"""
|
25
|
+
Then the JSON response should not have "$..nonexistent_key"
|
26
|
+
|
27
|
+
Scenario: Test that XML response contains a node
|
28
|
+
When I send and accept XML
|
29
|
+
When I perform the following step:
|
30
|
+
"""
|
31
|
+
I send a GET request to "/api/books"
|
32
|
+
"""
|
33
|
+
Then show me the unparsed response
|
34
|
+
Then the XML response should have "//title"
|
35
|
+
|
36
|
+
Scenario: Test that XML response does not contain a node
|
37
|
+
When I send and accept XML
|
38
|
+
When I perform the following step:
|
39
|
+
"""
|
40
|
+
I send a GET request to "/api/books"
|
41
|
+
"""
|
42
|
+
Then the XML response should not have "//nonexistent_element"
|
43
|
+
|
44
|
+
Scenario: Test if JSON response contains text
|
45
|
+
When I perform the following step:
|
46
|
+
"""
|
47
|
+
I send a GET request to "/api/books"
|
48
|
+
"""
|
49
|
+
Then the JSON response should have "$..title" with the text "Metaprograming ruby"
|
50
|
+
|
51
|
+
Scenario: Test if JSON response doesn't contain text
|
52
|
+
When I perform the following step:
|
53
|
+
"""
|
54
|
+
I send a GET request to "/api/books"
|
55
|
+
"""
|
56
|
+
Then the JSON response should not have "$..publisher" with the text "Metaprograming ruby"
|
57
|
+
|
58
|
+
Scenario: Test if XML response contains text
|
59
|
+
When I send and accept XML
|
60
|
+
And I perform the following step:
|
61
|
+
"""
|
62
|
+
I send a GET request to "/api/books"
|
63
|
+
"""
|
64
|
+
Then the XML response should have "//title" with the text "Metaprograming ruby"
|
65
|
+
|
66
|
+
Scenario: Test JSON response
|
67
|
+
When I perform the following step:
|
68
|
+
"""
|
69
|
+
I send a GET request to "/api/books"
|
70
|
+
"""
|
71
|
+
Then the JSON response should be:
|
72
|
+
"""
|
73
|
+
{"books":[{"title":"Pride and prejudice"},{"title":"Metaprograming ruby"}]}
|
74
|
+
"""
|
75
|
+
|
76
|
+
Scenario: Test JSON with length of some element
|
77
|
+
When I perform the following step:
|
78
|
+
"""
|
79
|
+
I send a GET request to "/api/books"
|
80
|
+
"""
|
81
|
+
Then the JSON response should have "$..title" with a length of 2
|
82
|
+
|
83
|
+
Scenario: Test debugging the XML response should not blow up
|
84
|
+
When I send and accept XML
|
85
|
+
And I perform the following step:
|
86
|
+
"""
|
87
|
+
I send a GET request to "/api/books"
|
88
|
+
"""
|
89
|
+
Then show me the response
|
90
|
+
|
91
|
+
Scenario: Test debugging the JSON response should not blow up
|
92
|
+
When I send and accept JSON
|
93
|
+
And I perform the following step:
|
94
|
+
"""
|
95
|
+
I send a GET request to "/api/books"
|
96
|
+
"""
|
97
|
+
Then show me the response
|
98
|
+
|
99
|
+
Scenario: Test debugging unparsed JSON response should not blow up
|
100
|
+
When I perform the following step:
|
101
|
+
"""
|
102
|
+
I send a GET request to "/api/books"
|
103
|
+
"""
|
104
|
+
Then show me the unparsed response
|
105
|
+
|
106
|
+
Scenario: Test debugging unparsed XML response should not blow up
|
107
|
+
When I send and accept XML
|
108
|
+
When I perform the following step:
|
109
|
+
"""
|
110
|
+
I send a GET request to "/api/books"
|
111
|
+
"""
|
112
|
+
Then show me the unparsed response
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
When /^I perform the following steps?:$/ do |step_strings|
|
5
|
+
steps = step_strings.split("\n")
|
6
|
+
steps.each {|step_string| step step_string }
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^the response should equal:$/ do |response_body|
|
10
|
+
expect(last_response.body).to eq(response_body)
|
11
|
+
end
|
12
|
+
|
13
|
+
When /^I perform the following step with table:$/ do |step_definition|
|
14
|
+
lines = step_definition.split("\n")
|
15
|
+
step_string = lines.shift
|
16
|
+
|
17
|
+
raw = lines.map do |line|
|
18
|
+
line.squish.gsub(/^\|/, '').gsub(/\|$/, '').squish.split("|").map(&:squish)
|
19
|
+
end
|
20
|
+
|
21
|
+
step step_string, table(raw)
|
22
|
+
end
|
23
|
+
|
24
|
+
When /^I perform the following step with string:$/ do |step_definition|
|
25
|
+
lines = step_definition.split("\n")
|
26
|
+
step_string = lines.shift
|
27
|
+
|
28
|
+
param_string = lines.join("\n")
|
29
|
+
|
30
|
+
step step_string, param_string
|
31
|
+
end
|
32
|
+
|
33
|
+
Then /^the request headers should be:$/ do |headers|
|
34
|
+
headers_hash = headers.rows_hash
|
35
|
+
request '/'
|
36
|
+
expect(last_request.env.slice(*headers_hash.keys).values).to eq(headers_hash.values)
|
37
|
+
end
|
38
|
+
|
39
|
+
Then /^I should be authenticated$/ do
|
40
|
+
expect(last_request.env["HTTP_AUTHORIZATION"]).to eq("Basic #{Base64.encode64("joe:god")}")
|
41
|
+
end
|
42
|
+
|
43
|
+
Then /^I should be digest authenticated$/ do
|
44
|
+
expect(last_request.env["HTTP_AUTHORIZATION"].starts_with?("Digest ")).to be true
|
45
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
|
2
|
+
require 'pry'
|
3
|
+
|
4
|
+
require 'rack'
|
5
|
+
require 'rack/test'
|
6
|
+
require File.dirname(__FILE__) + "/../fixtures/fake_app"
|
7
|
+
|
8
|
+
require 'cucumber/api_steps'
|
9
|
+
|
10
|
+
def app
|
11
|
+
Rack::Lint.new(CucumberApiSteps::FakeApp.new)
|
12
|
+
end
|
13
|
+
|
14
|
+
Before("@digest-auth") do
|
15
|
+
def app
|
16
|
+
app = Rack::Auth::Digest::MD5.new(CucumberApiSteps::FakeApp.new) do |username|
|
17
|
+
{ 'joe' => 'god' }[username]
|
18
|
+
end
|
19
|
+
app.realm = 'TestApi'
|
20
|
+
app.opaque = 'this-should-be-secret'
|
21
|
+
app
|
22
|
+
end
|
23
|
+
end
|
data/lib/cucumber/api_steps.rb
CHANGED
@@ -1,60 +1,165 @@
|
|
1
|
-
|
1
|
+
require 'jsonpath'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
if defined?(Rack)
|
5
|
+
|
6
|
+
# Monkey patch Rack::MockResponse to work properly with response debugging
|
7
|
+
class Rack::MockResponse
|
8
|
+
def to_str
|
9
|
+
body
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
World(Rack::Test::Methods)
|
2
14
|
|
3
|
-
Given /^I send and accept XML$/ do
|
4
|
-
page.driver.header 'Accept', 'text/xml'
|
5
|
-
page.driver.header 'Content-Type', 'text/xml'
|
6
15
|
end
|
7
16
|
|
8
|
-
Given /^I
|
9
|
-
|
10
|
-
page.driver.header 'Content-Type', 'application/json'
|
17
|
+
Given /^I set headers:$/ do |headers|
|
18
|
+
headers.rows_hash.each {|k,v| header k, v }
|
11
19
|
end
|
12
20
|
|
13
|
-
|
14
|
-
|
21
|
+
Given /^I send and accept (XML|JSON)$/ do |type|
|
22
|
+
header 'Accept', "application/#{type.downcase}"
|
23
|
+
header 'Content-Type', "application/#{type.downcase}"
|
15
24
|
end
|
16
25
|
|
17
|
-
|
18
|
-
|
26
|
+
Given /^I send and accept HTML$/ do
|
27
|
+
header 'Accept', "text/html"
|
28
|
+
header 'Content-Type', "application/x-www-form-urlencoded"
|
19
29
|
end
|
20
30
|
|
21
|
-
When /^I
|
22
|
-
|
31
|
+
When /^I authenticate as the user "([^"]*)" with the password "([^"]*)"$/ do |user, pass|
|
32
|
+
authorize user, pass
|
23
33
|
end
|
24
34
|
|
25
|
-
When /^I
|
26
|
-
|
35
|
+
When /^I digest\-authenticate as the user "(.*?)" with the password "(.*?)"$/ do |user, pass|
|
36
|
+
digest_authorize user, pass
|
27
37
|
end
|
28
38
|
|
29
|
-
When /^I send a PUT request to "([
|
30
|
-
|
39
|
+
When /^I send a (GET|PATCH|POST|PUT|DELETE) request (?:for|to) "([^"]*)"(?: with the following:)?$/ do |*args|
|
40
|
+
request_type = args.shift
|
41
|
+
path = args.shift
|
42
|
+
input = args.shift
|
43
|
+
|
44
|
+
request_opts = {method: request_type.downcase.to_sym}
|
45
|
+
|
46
|
+
unless input.nil?
|
47
|
+
if input.class == Cucumber::MultilineArgument::DataTable
|
48
|
+
request_opts[:params] = input.rows_hash
|
49
|
+
else
|
50
|
+
request_opts[:input] = StringIO.new input
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
request path, request_opts
|
31
55
|
end
|
32
56
|
|
33
|
-
|
34
|
-
|
57
|
+
Then /^show me the (unparsed)?\s?response$/ do |unparsed|
|
58
|
+
if unparsed == 'unparsed'
|
59
|
+
puts last_response.body
|
60
|
+
elsif last_response.headers['Content-Type'] =~ /json/
|
61
|
+
json_response = JSON.parse(last_response.body)
|
62
|
+
puts JSON.pretty_generate(json_response)
|
63
|
+
elsif last_response.headers['Content-Type'] =~ /xml/
|
64
|
+
puts Nokogiri::XML(last_response.body)
|
65
|
+
else
|
66
|
+
puts last_response.headers
|
67
|
+
puts last_response.body
|
68
|
+
end
|
35
69
|
end
|
36
70
|
|
37
|
-
Then /^
|
38
|
-
|
71
|
+
Then /^the response status should be "([^"]*)"$/ do |status|
|
72
|
+
if self.respond_to?(:expect)
|
73
|
+
expect(last_response.status).to eq(status.to_i)
|
74
|
+
else
|
75
|
+
assert_equal status.to_i, last_response.status
|
76
|
+
end
|
39
77
|
end
|
40
78
|
|
41
|
-
Then /^the response
|
42
|
-
|
79
|
+
Then /^the JSON response should (not)?\s?have "([^"]*)"$/ do |negative, json_path|
|
80
|
+
json = JSON.parse(last_response.body)
|
81
|
+
results = JsonPath.new(json_path).on(json).to_a.map(&:to_s)
|
82
|
+
if self.respond_to?(:expect)
|
83
|
+
if negative.present?
|
84
|
+
expect(results).to be_empty
|
85
|
+
else
|
86
|
+
expect(results).not_to be_empty
|
87
|
+
end
|
88
|
+
else
|
89
|
+
if negative.present?
|
90
|
+
assert results.empty?
|
91
|
+
else
|
92
|
+
assert !results.empty?
|
93
|
+
end
|
94
|
+
end
|
43
95
|
end
|
44
96
|
|
45
|
-
|
46
|
-
|
47
|
-
|
97
|
+
|
98
|
+
Then /^the JSON response should (not)?\s?have "([^"]*)" with the text "([^"]*)"$/ do |negative, json_path, text|
|
99
|
+
json = JSON.parse(last_response.body)
|
100
|
+
results = JsonPath.new(json_path).on(json).to_a.map(&:to_s)
|
101
|
+
if self.respond_to?(:expect)
|
102
|
+
if negative.present?
|
103
|
+
expect(results).not_to include(text)
|
104
|
+
else
|
105
|
+
expect(results).to include(text)
|
106
|
+
end
|
107
|
+
else
|
108
|
+
if negative.present?
|
109
|
+
assert !results.include?(text)
|
110
|
+
else
|
111
|
+
assert results.include?(text)
|
112
|
+
end
|
113
|
+
end
|
48
114
|
end
|
49
115
|
|
50
|
-
Then /^the
|
51
|
-
|
52
|
-
|
116
|
+
Then /^the XML response should (not)?\s?have "([^"]*)"$/ do |negative, xpath|
|
117
|
+
parsed_response = Nokogiri::XML(last_response.body)
|
118
|
+
elements = parsed_response.xpath(xpath)
|
119
|
+
if self.respond_to?(:expect)
|
120
|
+
if negative.present?
|
121
|
+
expect(elements).to be_empty
|
122
|
+
else
|
123
|
+
expect(elements).not_to be_empty
|
124
|
+
end
|
125
|
+
else
|
126
|
+
if negative.present?
|
127
|
+
assert elements.empty?
|
128
|
+
else
|
129
|
+
assert !elements.empty?
|
130
|
+
end
|
131
|
+
end
|
53
132
|
end
|
54
133
|
|
55
|
-
Then /^the XML response should have "([
|
134
|
+
Then /^the XML response should have "([^"]*)" with the text "([^"]*)"$/ do |xpath, text|
|
56
135
|
parsed_response = Nokogiri::XML(last_response.body)
|
57
136
|
elements = parsed_response.xpath(xpath)
|
58
|
-
|
59
|
-
|
60
|
-
|
137
|
+
if self.respond_to?(:expect)
|
138
|
+
expect(elements).not_to be_empty, "could not find #{xpath} in:\n#{last_response.body}"
|
139
|
+
expect(elements.find { |e| e.text == text }).not_to be_nil, "found elements but could not find #{text} in:\n#{elements.inspect}"
|
140
|
+
else
|
141
|
+
assert !elements.empty?, "could not find #{xpath} in:\n#{last_response.body}"
|
142
|
+
assert elements.find { |e| e.text == text }, "found elements but could not find #{text} in:\n#{elements.inspect}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
Then /^the JSON response should be:$/ do |json|
|
147
|
+
expected = JSON.parse(json)
|
148
|
+
actual = JSON.parse(last_response.body)
|
149
|
+
|
150
|
+
if self.respond_to?(:expect)
|
151
|
+
expect(actual).to eq(expected)
|
152
|
+
else
|
153
|
+
assert_equal actual, response
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
Then /^the JSON response should have "([^"]*)" with a length of (\d+)$/ do |json_path, length|
|
158
|
+
json = JSON.parse(last_response.body)
|
159
|
+
results = JsonPath.new(json_path).on(json)
|
160
|
+
if self.respond_to?(:expect)
|
161
|
+
expect(results.length).to eq(length.to_i)
|
162
|
+
else
|
163
|
+
assert_equal length.to_i, results.length
|
164
|
+
end
|
165
|
+
end
|
metadata
CHANGED
@@ -1,118 +1,135 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber-api-steps
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
version: "0.1"
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
10
5
|
platform: ruby
|
11
|
-
authors:
|
6
|
+
authors:
|
12
7
|
- Jay Zeschin
|
13
8
|
autorequire:
|
14
9
|
bindir: bin
|
15
10
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2017-10-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
21
14
|
name: jsonpath
|
22
|
-
|
23
|
-
|
24
|
-
none: false
|
25
|
-
requirements:
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
26
17
|
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 31
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
- 1
|
32
|
-
- 2
|
18
|
+
- !ruby/object:Gem::Version
|
33
19
|
version: 0.1.2
|
34
20
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: cucumber
|
38
21
|
prerelease: false
|
39
|
-
|
40
|
-
|
41
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: cucumber
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
42
31
|
- - ">="
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
- 8
|
48
|
-
- 3
|
49
|
-
version: 0.8.3
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.2
|
50
34
|
type: :runtime
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
53
|
-
name: bueller
|
54
35
|
prerelease: false
|
55
|
-
|
56
|
-
|
57
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.0.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
58
52
|
- - ">="
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.3.0
|
64
62
|
type: :development
|
65
|
-
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.3.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sinatra
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.4.3
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.4.3
|
66
83
|
description: Cucumber steps to easily test REST-based XML and JSON APIs
|
67
|
-
email:
|
68
|
-
- jay
|
84
|
+
email:
|
85
|
+
- jay@zeschin.org
|
69
86
|
executables: []
|
70
|
-
|
71
87
|
extensions: []
|
72
|
-
|
73
88
|
extra_rdoc_files: []
|
74
|
-
|
75
|
-
|
76
|
-
- .
|
77
|
-
- .rvmrc
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
78
92
|
- Gemfile
|
93
|
+
- README.md
|
79
94
|
- Rakefile
|
80
95
|
- cucumber-api-steps.gemspec
|
96
|
+
- features/authentication.feature
|
97
|
+
- features/fixtures/fake_app.rb
|
98
|
+
- features/header.feature
|
99
|
+
- features/request.feature
|
100
|
+
- features/response.feature
|
101
|
+
- features/step_definitions/api_test_steps.rb
|
102
|
+
- features/support/env.rb
|
81
103
|
- lib/cucumber/api_steps.rb
|
82
104
|
- lib/cucumber/api_steps/version.rb
|
83
|
-
has_rdoc: true
|
84
105
|
homepage: http://github.com/jayzes/cucumber-api-steps
|
85
106
|
licenses: []
|
86
|
-
|
107
|
+
metadata: {}
|
87
108
|
post_install_message:
|
88
109
|
rdoc_options: []
|
89
|
-
|
90
|
-
require_paths:
|
110
|
+
require_paths:
|
91
111
|
- lib
|
92
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
-
|
94
|
-
requirements:
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
95
114
|
- - ">="
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
version: "0"
|
101
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
-
none: false
|
103
|
-
requirements:
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 1.9.3
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
104
119
|
- - ">="
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
|
107
|
-
segments:
|
108
|
-
- 0
|
109
|
-
version: "0"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
110
122
|
requirements: []
|
111
|
-
|
112
123
|
rubyforge_project:
|
113
|
-
rubygems_version:
|
124
|
+
rubygems_version: 2.5.2
|
114
125
|
signing_key:
|
115
|
-
specification_version:
|
126
|
+
specification_version: 4
|
116
127
|
summary: Cucumber steps to easily test REST-based XML and JSON APIs
|
117
|
-
test_files:
|
118
|
-
|
128
|
+
test_files:
|
129
|
+
- features/authentication.feature
|
130
|
+
- features/fixtures/fake_app.rb
|
131
|
+
- features/header.feature
|
132
|
+
- features/request.feature
|
133
|
+
- features/response.feature
|
134
|
+
- features/step_definitions/api_test_steps.rb
|
135
|
+
- features/support/env.rb
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm use ree@cucumber-api-steps
|