diff --git a/README.md b/README.md index 5a4520c8..b310466c 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,19 @@ Scenario Outline: Fetching API endpoint from root endpoint | public_gists_url | ``` +You can also pick a field from response headers. + +```gherkin +Scenario: Setting json body from .json fixture file + And set request json body from json_file + When I POST https://examples.com/users + Then response status code should be 201 + And I pick response header location as location + And I clear request body + And I GET {{location}} + And response status code should be 200 +``` + #### Using cookies Cookies are disabled by default, but you've got the ability to enable/disable the feature using a gherkin `Given` expression. @@ -813,7 +826,7 @@ Given: - /^(?:I )?set request multipart body from (.+)$/ - /^(?:I )?clear request body$/ - /^(?:I )?set request query$/ - - /^(?:I )?pick response json (.+) as (.+)$/ + - /^(?:I )?pick response (json|header) (.+) as (.+)$/ - /^(?:I )?enable cookies$/ - /^(?:I )?disable cookies$/ - /^(?:I )?set cookie from (.+)$/ diff --git a/doc/README.tpl.md b/doc/README.tpl.md index 91f5f8d4..d227eb4d 100644 --- a/doc/README.tpl.md +++ b/doc/README.tpl.md @@ -231,6 +231,21 @@ Scenario Outline: Fetching API endpoint from root endpoint ``` <%={{ }}=%> +You can also pick a field from response headers. + +{{=<% %>=}} +```gherkin +Scenario: Setting json body from .json fixture file + And set request json body from json_file + When I POST https://examples.com/users + Then response status code should be 201 + And I pick response header location as location + And I clear request body + And I GET {{location}} + And response status code should be 200 +``` +<%={{ }}=%> + #### Using cookies Cookies are disabled by default, but you've got the ability to enable/disable the feature using a gherkin `Given` expression. diff --git a/examples/features/http_api/fixtures/fixtures.feature b/examples/features/http_api/fixtures/fixtures.feature index 9aa0b9e9..964a666f 100644 --- a/examples/features/http_api/fixtures/fixtures.feature +++ b/examples/features/http_api/fixtures/fixtures.feature @@ -70,3 +70,15 @@ Feature: Using fixtures with http API extension And set request form body from json_00 When I POST http://fake.io/users/json Then response status code should be 200 + + @json @header + Scenario: Setting json body from .json fixture file + Given I mock http call to forward request body for path /users + And set request json body from json_00 + When I POST http://fake.io/users + Then response status code should be 200 + And I pick response header location as location + And I clear request body + Given I mock GET http call to forward request body for path /users/1 + And I GET {{location}} + And response status code should be 200 diff --git a/examples/support/http_api/fixtures.steps.js b/examples/support/http_api/fixtures.steps.js index 57f68d88..85cdeb82 100644 --- a/examples/support/http_api/fixtures.steps.js +++ b/examples/support/http_api/fixtures.steps.js @@ -5,10 +5,18 @@ const { Given, Then } = require('@cucumber/cucumber') const nock = require('nock') const { expect } = require('chai') -Given(/^I mock http call to forward request body for path (.+)$/, function (path) { - nock('http://fake.io') +Given(/^I mock (?:(POST|GET) )?http call to forward request body for path (.+)$/, function (method,path) { + if(method !== 'GET') { + nock('http://fake.io') .post(path) .reply(200, (uri, requestBody) => requestBody) + .defaultReplyHeaders({location: 'http://fake.io/users/1'}) + return + } + + nock('http://fake.io') + .get(path) + .reply(200 ) }) Then(/^response should match url encoded snapshot (.+)$/, function (snapshotId) { diff --git a/src/extensions/http_api/client.js b/src/extensions/http_api/client.js index 71d8fd28..f58bb256 100644 --- a/src/extensions/http_api/client.js +++ b/src/extensions/http_api/client.js @@ -219,6 +219,12 @@ class HttpApiClient { */ makeRequest(method, path, baseUrl) { return new Promise((resolve, reject) => { + if (/https?:\/\//.test(path)) { + const url = new URL(path) + path = path.replace(url.origin, '') + baseUrl = url.origin + } + const options = { baseUrl: baseUrl, uri: path, diff --git a/src/extensions/http_api/definitions.js b/src/extensions/http_api/definitions.js index 2043cde1..2c7ee864 100644 --- a/src/extensions/http_api/definitions.js +++ b/src/extensions/http_api/definitions.js @@ -125,11 +125,14 @@ exports.install = ({ baseUrl = '' } = {}) => { this.httpApiClient.setQuery(Cast.object(this.state.populateObject(step.rowsHash()))) }) - Given(/^(?:I )?pick response json (.+) as (.+)$/, function (path, key) { + /** + * Pick a value from previous json response or header and set it to state + */ + Given(/^(?:I )?pick response (json|header) (.+) as (.+)$/, function (dataSource, path, key) { const response = this.httpApiClient.getResponse() - const body = response.body + let data = dataSource !== 'header' ? response.body : response.headers - this.state.set(key, _.get(body, path)) + this.state.set(key, _.get(data, path)) }) /** diff --git a/tests/extensions/http_api/definitions.test.js b/tests/extensions/http_api/definitions.test.js index 31de9b80..cba37032 100644 --- a/tests/extensions/http_api/definitions.test.js +++ b/tests/extensions/http_api/definitions.test.js @@ -264,13 +264,15 @@ test('do not follow redirect', () => { expect(clientMock.httpApiClient.setFollowRedirect).toHaveBeenCalledWith(false) }) -test('pick response json property', () => { +test('pick response json|header property', () => { const context = helper.getContext() // Extension context - const def = context.getDefinitionByMatcher('pick response json') + const def = context.getDefinitionByMatcher('pick response (json|header) (.+) as (.+)') def.shouldNotMatch('I pick response json as ') - def.shouldMatch('I pick response json key as value', ['key', 'value']) - def.shouldMatch('pick response json key as value', ['key', 'value']) + def.shouldMatch('I pick response json key as value', ['json', 'key', 'value']) + def.shouldMatch('pick response json key as value', ['json', 'key', 'value']) + def.shouldMatch('I pick response header key as value', ['header', 'key', 'value']) + def.shouldMatch('pick response header key as value', ['header', 'key', 'value']) }) test('enable cookies', () => {