cucumber-api 0.1 → 0.2
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 +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +12 -0
- data/README.md +78 -33
- data/lib/cucumber-api/response.rb +10 -9
- data/lib/cucumber-api/steps.rb +32 -1
- data/lib/cucumber-api/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55a5a265a37af8eafb9ffd06172b125a5ec25f28
|
4
|
+
data.tar.gz: 221235246f1c3156a5765467a96a324773a46ba3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0396739e1f53262ee865c3ec7d3b57cf93917d7a888ddab8308d02de6a3c1915ba14e2828470f696e14e8a51a20b2c35a9d22971215b9d889c18233716360cbc
|
7
|
+
data.tar.gz: 2bf203c41587dfd2728c5dd039897f4ff50e49fe6accfbbff5956635f6655f1a99d9302a1fe1ec2e4154500be8302f9118a6d74bf33293ddc859ff4503efc9fe
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## [Current](https://github.com/hidroh/cucumber-api/compare/0.1...master)
|
4
|
+
|
5
|
+
* Added form request body
|
6
|
+
* Added loading request body from file (YAML/JSON)
|
7
|
+
|
8
|
+
## [0.1](https://github.com/hidroh/cucumber-api/releases/tag/0.1) (March 01, 2015)
|
9
|
+
|
10
|
+
* Initial version
|
11
|
+
* Only JSON response supported
|
12
|
+
* Only JSON POST request body supported
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
# cucumber-api
|
2
|
+
[](https://travis-ci.org/hidroh/cucumber-api) [](http://badge.fury.io/rb/cucumber-api) [](https://gemnasium.com/hidroh/cucumber-api)
|
3
|
+
[](https://codeclimate.com/github/hidroh/cucumber-api) [](https://rubygems.org/gems/cucumber-api)
|
4
|
+
|
2
5
|
API validator in BBD style with [Cucumber](https://cukes.info/). **cucumber-api** lets one validate public APIs JSON response in blazingly fast time.
|
3
6
|
|
4
7
|
Inspired by [cucumber-api-steps](https://github.com/jayzes/cucumber-api-steps).
|
@@ -13,16 +16,20 @@ Add `cucumber-api` gem to your `Gemfile`:
|
|
13
16
|
|
14
17
|
Require `cucumber-api` in your Cucumber's `env.rb`:
|
15
18
|
|
16
|
-
|
19
|
+
```ruby
|
20
|
+
require 'cucumber-api'
|
21
|
+
```
|
17
22
|
|
18
23
|
## Configuration
|
19
24
|
|
20
25
|
**Verbose logging:** enable verbose logging of API calls and responses by setting `cucumber_api_verbose=true` in your `ENV`, preferably via your `cucumber.yml`
|
21
26
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
```yaml
|
28
|
+
# config/cucumber.yml
|
29
|
+
##YAML Template
|
30
|
+
---
|
31
|
+
verbose : cucumber_api_verbose=true
|
32
|
+
```
|
26
33
|
|
27
34
|
## Usage
|
28
35
|
|
@@ -32,46 +39,78 @@ Require `cucumber-api` in your Cucumber's `env.rb`:
|
|
32
39
|
|
33
40
|
Specify your request header's `Content-Type` and `Accept`. The only supported option for `Accept` is `application/json` at the moment.
|
34
41
|
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
```gherkin
|
43
|
+
Given I send and accept JSON
|
44
|
+
Given I send "(.*?)" and accept JSON
|
45
|
+
```
|
46
|
+
|
47
|
+
Specify POST body
|
48
|
+
|
49
|
+
```gherkin
|
50
|
+
When I set JSON request body to '(.*?)'
|
51
|
+
When I set form request body to:
|
52
|
+
| key1 | value1 |
|
53
|
+
| key2 | {value2} |
|
54
|
+
| key3 | file://path-to-file |
|
55
|
+
```
|
56
|
+
|
57
|
+
Or from YAML/JSON file
|
58
|
+
|
59
|
+
```gherkin
|
60
|
+
When I set request body from "(.*?).(yml|json)"
|
61
|
+
```
|
38
62
|
|
39
63
|
Example:
|
40
64
|
|
41
|
-
|
42
|
-
|
65
|
+
```Gherkin
|
66
|
+
Given I send "www-x-form-urlencoded" and accept JSON
|
67
|
+
When I set JSON request body to '{"login": "email@example.com", "password": "password"}'
|
68
|
+
When I set form request body to:
|
69
|
+
| login | email@example.com |
|
70
|
+
| password | password |
|
71
|
+
When I set request body from "data/json-data.json"
|
72
|
+
When I set request body from "data/form-data.yml"
|
73
|
+
```
|
43
74
|
|
44
75
|
**Request steps**
|
45
76
|
|
46
77
|
Specify query string parameters and send an HTTP request to given URL with parameters
|
47
78
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
79
|
+
```gherkin
|
80
|
+
When I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)"
|
81
|
+
When I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)" with:
|
82
|
+
| param1 | param2 | ... |
|
83
|
+
| value1 | value2 | ... |
|
84
|
+
```
|
52
85
|
|
53
86
|
Temporarily save values from the last request to use in the next request in the same scenario:
|
54
87
|
|
55
|
-
|
88
|
+
```gherkin
|
89
|
+
When I grab "(.*?)" as "(.*?)"
|
90
|
+
```
|
56
91
|
|
57
92
|
The saved value can then be used to replace `{placeholder}` in the next request.
|
58
93
|
|
59
94
|
Example:
|
60
95
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
96
|
+
```gherkin
|
97
|
+
When I send a POST request to "http://example.com/token"
|
98
|
+
And I grab "$..request_token" as "token"
|
99
|
+
And I grab "$..access_type" as "type"
|
100
|
+
And I send a GET request to "http://example.com/{token} with:
|
101
|
+
| type | pretty |
|
102
|
+
| {type} | true |
|
103
|
+
```
|
67
104
|
|
68
|
-
Assume that [http://example.com/
|
105
|
+
Assume that [http://example.com/token](http://example.com/token) have an element `{"request_token": 1, "access_type": "full"}`, **cucumber-api** will execute the followings:
|
69
106
|
|
70
|
-
*
|
71
|
-
* Extract the first `
|
72
|
-
* GET [http://example.com/1?
|
107
|
+
* POST [http://example.com/token](http://example.com/token)
|
108
|
+
* Extract the first `request_token` and `access_type` from JSON response and save it for next request
|
109
|
+
* GET [http://example.com/1?type=full&pretty=true](http://example.com/1?type=full&pretty=true)
|
73
110
|
* Clear all saved values
|
74
111
|
|
112
|
+
This will be handy when one needs to make a sequence of calls to authenticate/authorize API access.
|
113
|
+
|
75
114
|
**Assert steps**
|
76
115
|
|
77
116
|
Verify:
|
@@ -79,7 +118,7 @@ Verify:
|
|
79
118
|
* JSON response against a JSON schema conforming to [JSON Schema Draft 4](http://tools.ietf.org/html/draft-zyp-json-schema-04)
|
80
119
|
* Adhoc JSON response key-value type pair, where key is a [JSON path](http://goessner.net/articles/JsonPath/)
|
81
120
|
|
82
|
-
```
|
121
|
+
```gherkin
|
83
122
|
Then the response status should be "(\d+)"
|
84
123
|
Then the JSON response should follow "(.*?)"
|
85
124
|
Then the JSON response root should be (object|array)
|
@@ -89,13 +128,19 @@ Then the JSON response should have (required|optional) key "(.*?)" of type (nume
|
|
89
128
|
|
90
129
|
Example:
|
91
130
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
131
|
+
```gherkin
|
132
|
+
Then the response status should be "200"
|
133
|
+
Then the JSON response should follow "features/schemas/example_all.json"
|
134
|
+
Then the JSON response root should be array
|
135
|
+
Then the JSON response should have key "id"
|
136
|
+
Then the JSON response should have optional key "format" of type string or null
|
137
|
+
```
|
138
|
+
|
139
|
+
Also checkout [sample](/features/sample.feature) for real examples. Run sample with the following command:
|
97
140
|
|
98
|
-
|
141
|
+
```
|
142
|
+
cucumber -p verbose
|
143
|
+
```
|
99
144
|
|
100
145
|
### Response caching
|
101
146
|
|
@@ -107,4 +152,4 @@ Only the first request to that endpoint is made, subsequent requests will use ca
|
|
107
152
|
* [cucumber](https://github.com/cucumber/cucumber) for BDD style specs
|
108
153
|
* [jsonpath](https://github.com/joshbuddy/jsonpath) for traversal of JSON response via [JSON path](http://goessner.net/articles/JsonPath/)
|
109
154
|
* [json-schema](https://github.com/ruby-json-schema/json-schema) for JSON schema validation
|
110
|
-
* [rest-client](https://github.com/rest-client/rest-client) for HTTP REST request
|
155
|
+
* [rest-client](https://github.com/rest-client/rest-client) for HTTP REST request
|
@@ -40,7 +40,7 @@ module CucumberApi
|
|
40
40
|
end
|
41
41
|
results = JsonPath.new(json_path).on(json)
|
42
42
|
if results.empty?
|
43
|
-
raise %/Expected json path '#{json_path}' not found\n#{
|
43
|
+
raise %/Expected json path '#{json_path}' not found\n#{to_json_s}/
|
44
44
|
end
|
45
45
|
results.first
|
46
46
|
end
|
@@ -73,7 +73,7 @@ module CucumberApi
|
|
73
73
|
end
|
74
74
|
|
75
75
|
unless valid
|
76
|
-
raise %/Expect '#{json_path}' as a '#{type}' but was '#{value.class}'\n#{
|
76
|
+
raise %/Expect '#{json_path}' as a '#{type}' but was '#{value.class}'\n#{to_json_s}/
|
77
77
|
end
|
78
78
|
value
|
79
79
|
end
|
@@ -91,13 +91,14 @@ module CucumberApi
|
|
91
91
|
value.nil? ? value : get_as_type(json_path, type, json)
|
92
92
|
end
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
94
|
+
# Retrieve pretty JSON response for logging
|
95
|
+
# @return [String] pretty JSON response if verbose setting is true, empty string otherwise
|
96
|
+
def to_json_s
|
97
|
+
if ENV['cucumber_api_verbose'] == 'true'
|
98
|
+
JSON.pretty_generate(JSON.parse to_s)
|
99
|
+
else
|
100
|
+
''
|
101
101
|
end
|
102
|
+
end
|
102
103
|
end
|
103
104
|
end
|
data/lib/cucumber-api/steps.rb
CHANGED
@@ -25,6 +25,32 @@ When(/^I set JSON request body to '(.*?)'$/) do |body|
|
|
25
25
|
@body = JSON.parse body
|
26
26
|
end
|
27
27
|
|
28
|
+
When(/^I set form request body to:$/) do |params|
|
29
|
+
@body = {}
|
30
|
+
params.rows_hash.each do |key, value|
|
31
|
+
p_value = value
|
32
|
+
@grabbed.each { |k, v| p_value = v if value == %/{#{k}}/ } unless @grabbed.nil?
|
33
|
+
p_value = File.new %-#{Dir.pwd}/#{p_value.sub 'file://', ''}- if %/#{p_value}/.start_with? "file://"
|
34
|
+
@body[%/#{key}/] = p_value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
When(/^I set request body from "(.*?).(yml|json)"$/) do |filename, extension|
|
39
|
+
path = %-#{Dir.pwd}/#{filename}.#{extension}-
|
40
|
+
if File.file? path
|
41
|
+
case extension
|
42
|
+
when 'yml'
|
43
|
+
@body = YAML.load File.open(path)
|
44
|
+
when 'json'
|
45
|
+
@body = JSON.parse File.read(path)
|
46
|
+
else
|
47
|
+
raise %/Unsupported file type: '#{path}'/
|
48
|
+
end
|
49
|
+
else
|
50
|
+
raise %/File not found: '#{path}'/
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
28
54
|
When(/^I grab "(.*?)" as "(.*?)"$/) do |json_path, place_holder|
|
29
55
|
if @response.nil?
|
30
56
|
raise 'No response found, a request need to be made first before you can grab response'
|
@@ -85,7 +111,12 @@ end
|
|
85
111
|
Then(/^the JSON response should follow "(.*?)"$/) do |schema|
|
86
112
|
file_path = %-#{Dir.pwd}/#{schema}-
|
87
113
|
if File.file? file_path
|
88
|
-
|
114
|
+
begin
|
115
|
+
JSON::Validator.validate!(file_path, @response.to_s)
|
116
|
+
rescue JSON::Schema::ValidationError => e
|
117
|
+
raise JSON::Schema::ValidationError.new(%/#{$!.message}\n#{@response.to_json_s}/,
|
118
|
+
$!.fragments, $!.failed_attribute, $!.schema)
|
119
|
+
end
|
89
120
|
else
|
90
121
|
puts %/WARNING: missing schema '#{file_path}'/
|
91
122
|
pending
|
data/lib/cucumber-api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ha Duy Trung
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cucumber
|
@@ -75,6 +75,8 @@ extensions: []
|
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
77
|
- ".gitignore"
|
78
|
+
- ".travis.yml"
|
79
|
+
- CHANGELOG.md
|
78
80
|
- Gemfile
|
79
81
|
- LICENSE
|
80
82
|
- README.md
|