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 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
@@ -2,3 +2,5 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ .DS_Store
6
+ .idea
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - "2.1.2"
6
+ - jruby-19mode # JRuby in 1.9 mode
7
+ - jruby-20mode # JRuby in 1.9 mode
data/Gemfile CHANGED
@@ -1,4 +1,13 @@
1
- source "http://rubygems.org"
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
+ [![Build Status](https://travis-ci.org/jayzes/cucumber-api-steps.png)](https://travis-ci.org/jayzes/cucumber-api-steps)
4
+ [![Gem Version](https://badge.fury.io/rb/cucumber-api-steps.png)](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 'bueller'
5
- Bueller::Tasks.new
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
@@ -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.zeschin@factorylabs.com"]
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.add_dependency 'jsonpath', '>= 0.1.2'
16
- s.add_dependency 'cucumber', '>= 0.8.3'
17
- s.add_development_dependency 'bueller'
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
@@ -1,60 +1,165 @@
1
- World(Rack::Test::Methods)
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 send and accept JSON$/ do
9
- page.driver.header 'Accept', 'application/json'
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
- When /^I authenticate as the user "([^\"]*)" with the password "([^\"]*)"$/ do |user, pass|
14
- page.driver.authorize(user, pass)
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
- When /^I send a GET request (?:for|to) "([^\"]*)"$/ do |path|
18
- page.driver.get path
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 send a POST request to "([^\"]*)"$/ do |path|
22
- page.driver.post path
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 send a POST request to "([^\"]*)" with the following:$/ do |path, body|
26
- page.driver.post path, body
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 "([^\"]*)" with the following:$/ do |path, body|
30
- page.driver.put path, body
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
- When /^I send a DELETE request to "([^\"]*)"$/ do |path|
34
- page.driver.delete path
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 /^show me the response$/ do
38
- p page.driver.last_response
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 status should be "([^\"]*)"$/ do |status|
42
- page.driver.last_response.status.should == status.to_i
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
- Then /^the JSON response should have "([^\"]*)" with the text "([^\"]*)"$/ do |json_path, text|
46
- json = JSON.parse(page.driver.last_response.body)
47
- JsonPath.new(json_path).on(json).to_a.map(&:to_s).should include(text)
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 JSON response should not have "([^\"]*)" with the text "([^\"]*)"$/ do |json_path, text|
51
- json = JSON.parse(page.driver.last_response.body)
52
- JsonPath.new(json_path).on(json).to_a.map(&:to_s).should_not include(text)
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 "([^\"]*)" with the text "([^\"]*)"$/ do |xpath, text|
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
- elements.should_not be_empty, "could not find #{xpath} in:\n#{last_response.body}"
59
- elements.find { |e| e.text == text }.should_not be_nil, "found elements but could not find #{text} in:\n#{elements.inspect}"
60
- end
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
@@ -1,5 +1,5 @@
1
1
  module Cucumber
2
2
  module ApiSteps
3
- VERSION = "0.1"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  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
- hash: 9
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
- date: 2011-04-12 00:00:00 -06:00
18
- default_executable:
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
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
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
- requirement: &id002 !ruby/object:Gem::Requirement
40
- none: false
41
- requirements:
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
- hash: 57
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
- requirement: &id003 !ruby/object:Gem::Requirement
56
- none: false
57
- requirements:
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
- hash: 3
61
- segments:
62
- - 0
63
- version: "0"
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
- version_requirements: *id003
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.zeschin@factorylabs.com
84
+ email:
85
+ - jay@zeschin.org
69
86
  executables: []
70
-
71
87
  extensions: []
72
-
73
88
  extra_rdoc_files: []
74
-
75
- files:
76
- - .gitignore
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
- none: false
94
- requirements:
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
95
114
  - - ">="
96
- - !ruby/object:Gem::Version
97
- hash: 3
98
- segments:
99
- - 0
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
- hash: 3
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: 1.4.2
124
+ rubygems_version: 2.5.2
114
125
  signing_key:
115
- specification_version: 3
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