Class RestSpec

    • Constructor Detail

      • RestSpec

        public RestSpec​(CommonG spec)
    • Method Detail

      • setupApp

        @Given("^I( securely)? send requests to \'(.*)\'$")
        public void setupApp​(String isSecured,
                             String restHost)
        Set app host and port for Rest requests.

        This is an initialization step. This is used as the first step in rest features to configure the basepath url. This parameters will be used for all future requests in the same scenario. The rest request is build within the HookGSpec class, so, don't forget to use the @rest annotation at the beginning of your feature for a proper initialization.

         
         Examples
        
         Scenario: Setting up the host.
              Given I send requests to 'jsonplaceholder.typicode.com'
        
         Scenario: Setting up host and specific port
              Given I send requests to 'jsonplaceholder.typicode.com:8080'
        
         Scenario: using the keyword 'securely' to use https.
              Given I securely send requests to 'jsonplaceholder.typicode.com'
         
         
        Parameters:
        isSecured - Indicates if https:// should be used (if false, defaults to http://)
        restHost - Base url of the API (without the http/https prefix, like mybaseurl.com). You can also specify a port number with baseURL:port
      • matchWithExpresion

        @Then("^\'(.*)\' matches the following cases:$")
        public void matchWithExpresion​(String envVar,
                                       io.cucumber.datatable.DataTable table)
        Verifies the structure of a json document against a set of test cases defined in a datatable

        This step is typically used to verify the response body of a request. The json to verify must have been previously saved in a variable using for example saveElementEnvironment(String, String, String). In the datatable, the first column represents the jsonpath of the element in the body to verify, the second column the operator operator (equal|not equal|contains|does not contain|length|exists|does not exists|size) and the third column the value to match against

        
         Example
        
         Scenario: Saving result in variable 'response' and evaluating
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'POST' request to '/posts' based on 'schemas/mytestdata.json' as 'json'
              And I save element '$' in environment variable 'response'
              And 'response' matches the following cases:
               | $.title  | contains  | 2              |
               | $.body   | contains  | This is a test |
               | $.userId | not equal | 2              |
         
        Parameters:
        envVar - Environment variable where JSON is stored
        table - Data table in which each row stores one expression
        See Also:
        saveElementEnvironment(String, String, String)
      • sendRequestNoDataTable

        @When("^I send a \'(.+?)\' request to \'(.+?)\'( with user and password \'(.+:.+?)\')?( based on \'([^:]+?)\')?( as \'(json|string|graphql)\')?( with variables \'(.+?)\')?$")
        public void sendRequestNoDataTable​(String requestType,
                                           String endPoint,
                                           String loginInfo,
                                           String baseData,
                                           String type,
                                           String variables)
                                    throws Exception
        Generates a REST request of the type specified to the indicated endpoint

        The endpoint must be relative to the base path previously defined with setupApp(String, String). If needed, you can also specify the body of the request (for POST, PUT and DELETE requests) from a local file. If you need to alter the content of the json document before sending you could use sendRequestDataTable(String, String, String, String, String, String, DataTable). As soon as the request is completed, the request object is re-initialized with the same base URI and port as configured in setupApp(String, String). This is to avoid future requests from re-using the same cookies/headers/url parameters that the user may have configured.

        
         Examples:
        
         Scenario: Executing a simple GET request
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'GET' request to '/posts'
        
         Scenario: Using basic authentication
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'GET' request to '/posts' with user and password 'user:password'
        
         Scenario: Sending a POST request with content of file mytestdata.json as body
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'POST' request to '/posts' based on 'schemas/mytestdata.json' as 'json'
        
         Scenario: Sending a POST request with content of file mytestdata.graphql as body
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'POST' request to '/' based on 'schemas/mytestdata.graphql' as 'graphql'
        
         Scenario: Sending a POST request with content of file mytestdata.graphql with variables as body
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'POST' request to '/' based on 'schemas/mytestdata.graphql' as 'graphql' with variables '{"perPage": 10}' and
         
        Parameters:
        requestType - HTTP verb (type of request): POST, GET, PUT, PATCH, DELETE
        endPoint - Endpoint (i.e /user/1). The base path used is the one indicated in a previous step
        loginInfo - User and password to use if the endpoints requires basic authentication (user:password)
        baseData - If specified, the content of the file will be loaded in the body of the request (POST, PUT, PATCH operations)
        type - If the content of the file should be read as string or json or graphql
        variables - If the content as graphql
        Throws:
        Exception - Exception
        See Also:
        setupApp(String, String), sendRequestDataTable(String, String, String, String, String, String, DataTable), sendRequestInlineBody(String, String, String, String, DocString)
      • sendRequestDataTable

        @When("^I send a \'(.+?)\' request to \'(.+?)\'( with user and password \'(.+:.+?)\')? based on \'([^:]+?)\'( as \'(json|string|graphql)\')? with( variables \'(.+?)\' and)?:$")
        public void sendRequestDataTable​(String requestType,
                                         String endPoint,
                                         String loginInfo,
                                         String baseData,
                                         String type,
                                         String variables,
                                         io.cucumber.datatable.DataTable modifications)
                                  throws Exception
        Generates a REST request of the type specified to the indicated endpoint

        This function works in the same way as sendRequestNoDataTable(String, String, String, String, String, String) the difference is that this one accepts a datatable with a list of modification to be applied to the json body before the request is executed. As soon as the request, is completed, the request object is re-initialized with the same base URI and port as configured in setupApp(String, String). This is to avoid future requests from re-using the same cookies/headers/url parameters that the user may have configured.

        
         Example
        
         Scenario: Send a POST request with the content of schemas/mytestdata.json as body data
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'POST' request to '/posts' based on 'schemas/mytestdata.json' as 'json' with:
                  | $.title | UPDATE | This is a test 2 |
        
        
         About the modifications datatable: The datatable will typically have the following
         structure:
        
              | <key path> | <type of modification> | <new value> | <object type> (optional) |
        
         <key path>: jsonPath to the key to be modified.
         <type of modification>: DELETE|ADD|UPDATE|APPEND|PREPEND|REPLACE|ADDTO
         <new value>: In case of UPDATE or ADD, new value to be used.
        
                      If the element read is: {"key1": "value1", "key2": {"key3": "value3"}}
                      And the modifications datatable is: | key2.key3 | UPDATE | "new value3" |
                      The result will be: {"key1": "value1", "key2": {"key3": "new value3"}}
        
                      (The new value will always by added as a string, that is, will contain double
                      quotes "". If you want to override this behaviour, use REPLACE and specify the <object type> column)
        
         <object type>: In case of REPLACE and ADDTO, specifies the object type the value should be transformed to.
                        Accepted values are: array|object|string|number|array|boolean|null. Use null if you want that
                        value in the json to be null.
        
         
        Parameters:
        requestType - Type of request to be sent. Possible values: GET|DELETE|POST|PUT|PATCH
        endPoint - End point to be used (relative to the base path previously defined with setupApp(String, String))
        baseData - Path to file containing the schema to be used
        type - Element to read from file (element should contain a json)
        variables - If the content as graphql
        loginInfo - Credentials for basic auth (if required)
        modifications - DataTable containing the modifications to be done to the base schema element.
        Throws:
        Exception - Exception
        See Also:
        setupApp(String, String), sendRequestNoDataTable(String, String, String, String, String, String), sendRequestInlineBody(String, String, String, String, DocString)
      • saveElementEnvironment

        @Given("^I save element (in position \'(.+?)\' in )?\'(.+?)\' in environment variable \'(.+?)\'$")
        public void saveElementEnvironment​(String position,
                                           String element,
                                           String envVar)
        Saves value of a json document for future use.

        This step is typically used to save the body response of a HTTP request (either the full body response or just an specific element). If this is the case, a previous HTTP request operation must have been performed (with sendRequestDataTable(String, String, String, String, String, String, DataTable) or with sendRequestNoDataTable(String, String, String, String, String, String))

        
         Example: If element is a jsonpath expression (i.e. $.fragments[0].id), it will be applied over the last httpResponse.
        
         Scenario: Saving ALL body in variable 'response'
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'GET' request to '/posts'
              And I save element '$' in environment variable 'response'
        
         Scenario: Saves only the element $.[0].userId of the response
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'GET' request to '/posts'
              And I save element '$.[0].userId' in environment variable 'USER_ID'
        
         Example: If element is a jsonpath expression preceded by some other string (i.e. ["a","b",,"c"].$.[0]), it will be applied over
         this string. This will help to save the result of a jsonpath expression evaluated over previous stored variable.
        
         Scenario: Evaluating a simple string (Will save 'a' in variable 'letter')
              And I save element '["a","b","c","d"].$.[0]' in environment variable 'letter'
        
         Scenario: Or from a previous HTTP request:
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              When I send a 'GET' request to '/users'
              And I save element '$.[0]' in environment variable 'first_user'
              And I save element '${first_user}.$.username' in environment variable 'username'
              Then '${username}' matches 'Bret'
         
        Parameters:
        position - position from a search result
        element - key in the json response to be saved
        envVar - thread environment variable where to store the value
        See Also:
        sendRequestNoDataTable(String, String, String, String, String, String), sendRequestDataTable(String, String, String, String, String, String, DataTable), http://json-schema.org/
      • setHeaders

        @Given("^I set headers:$")
        public void setHeaders​(io.cucumber.datatable.DataTable modifications)
        Specify a custom map of headers to be added to future requests

        The headers will be applied the following request

        
         Example:
        
         Scenario: Set headers for following requests. This (and following) request(s) will contain those headers
              Given I send requests to 'dummy-test.com:80'
              Given I set headers:
                  | Authorization  | mySecretToken1234 |
                  | Content-Type   | application/json  |
              When I send a 'GET' request to '/api/v1/shipment/1'
         
        Parameters:
        modifications - DataTable containing the custom set of headers to be added to the requests. Syntax will be: | <key> | <value> | where: key: header key name value: value for tue key for example: if we want to add the header "token" with value "12345678", to the request header the modification will be: | token | 12345678 |
        See Also:
        setCookies(DataTable)
      • setCookies

        @Given("^I set cookies:$")
        public void setCookies​(io.cucumber.datatable.DataTable modifications)
        Specify a custom map of cookies to be added to future requests

        Works in a similar way that setHeaders(DataTable). The cookies will be applied to the following request in the same scenario

        
         Example:
        
         Scenario: Set cookies for following requests
              Given I send requests to 'dummy-test.com:80'
              Given I set cookies:
                  | myCookieName  | myCookieValue |
              When I send a 'GET' request to '/api/v1/shipment/1' //this (and following) request(s) will contain those cookies
         
        Parameters:
        modifications - DataTable containing the custom set of cookies to be added to the requests. Syntax will be: | <key> | <value> | where: key: cookie key name value: cookie for tue key for example: if we want to add the cookie "token" with value "12345678", to the request cookie the modification will be: | token | 12345678 |
        See Also:
        setHeaders(DataTable)
      • sendRequestTimeout

        @Deprecated
        @When("^in less than \'(\\d+)\' seconds, checking each \'(\\d+)\' seconds, I send a \'(.*)\' request to \'(.*)\' so that the response( does not)? contains \'(.*)\'$")
        public void sendRequestTimeout​(Integer timeout,
                                       Integer wait,
                                       String requestType,
                                       String endPoint,
                                       String contains,
                                       String responseVal)
                                throws InterruptedException
        Deprecated.
        Executes the given request to the REST endpont for the specified amount of time in regular intervals, until the response body contains the specified text
        Parameters:
        timeout - Maximum time to wait for the text to be present in the response body
        wait - Time between retries
        requestType - Type of request (POST, GET, PATCH, DELETE, PUT)
        endPoint - Endpoint (i.e /user/1)
        responseVal - Expected value to evaluate in the response body
        contains - parameter generated by cucumber because of the optional expression
        Throws:
        InterruptedException - InterruptedException
      • saveCookieValue

        @And("^I save the response cookie \'(.*)\' in environment variable \'(.*)\'$")
        public void saveCookieValue​(String cookieName,
                                    String varName)
                             throws Throwable
        Saves the cookie value for future use

        Similar to saveHeaderValue(String, String)

        Parameters:
        cookieName - Cookie name
        varName - Name of the environmental variable
        Throws:
        Throwable - Throwable
      • iSetUrlQueryParameters

        @Given("^I set url parameters:$")
        public void iSetUrlQueryParameters​(io.cucumber.datatable.DataTable modifications)
        Specify a custom map of url query parameters to be added to future request
        
         Example:
        
         Scenario: Add ?userId=3 to the url query parameters
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              Given I set url parameters:
                   | userId | 3 |
              When I send a 'GET' request to '/posts'
         
        Parameters:
        modifications - DataTable containing the custom set of url query parameters to be added to the requests. Syntax will be: | <key> | <value> | where: key: parameters name value: parameters value for example: if we want to add the parameter "id" with value "1", to the request url the modification will be: Given I set url parameters | id | 1 | When I send a 'GET' request to '/posts' This will produce the request '/posts?id=1'
        See Also:
        setupApp(String, String), sendRequestDataTable(String, String, String, String, String, String, DataTable), sendRequestNoDataTable(String, String, String, String, String, String)
      • iAddTheFileToTheRequest

        @And("^I add the file in \'(.*)\' to the request$")
        public void iAddTheFileToTheRequest​(String filePath)
                                     throws URISyntaxException
        Adds the specified file to the request as a form-params parameter (the request contentType must be changed to 'multipart/form-data')
        Parameters:
        filePath - file path
        Throws:
        URISyntaxException - URISyntaxException
      • setRestProxyWithCredentials

        @Given("I set the proxy to {string} with username {string} and password {string}")
        public void setRestProxyWithCredentials​(String address,
                                                String username,
                                                String password)
                                         throws MalformedURLException
        Sets a proxy for the rest client with credentials

        The given URL must have a hostname, port and scheme (a correctly formed URL), for example "http://localhost:8080".

        
         Example:
        
         Scenario: Setting a proxy with credentials
              Given I securely send requests to 'jsonplaceholder.typicode.com:443'
              Given I set the proxy to 'http://localhost:80' with username 'myusername' and password 'mypassword'
         
         
        Parameters:
        address - Fully formed URL (schema + address + port)
        username - Username
        password - Password
        Throws:
        MalformedURLException - MalformedURLException
        See Also:
        setRestProxy(String)
      • sendRequestInlineBody

        @When("^I send a \'(.+?)\' request to \'(.+?)\'( as \'(json|string|graphql)\')? with( variables \'(.+?)\' and)? body")
        public void sendRequestInlineBody​(String requestType,
                                          String endPoint,
                                          String type,
                                          String variables,
                                          io.cucumber.docstring.DocString body)
        Generates a REST request of the type specified to the indicated endpoint

        This step works in the same way as sendRequestDataTable(String, String, String, String, String, String, DataTable) or to sendRequestNoDataTable(String, String, String, String, String, String), but in this case, you can pass directly the body to send as parameter. This could be useful if you want to give visibility of the data you are sending, although, if the body you want to send is too large, it might be better to store it in a file and use any of the other two steps.

        
         Example:
        
         Scenario: Add the body to be sent directly
             Given I securely send requests to 'jsonplaceholder.typicode.com:443'
             When I send a 'POST' request to '/posts' with body
             """
               {
                 "userId": 1,
                 "title": "This is a test",
                 "body": "This is a test"
               }
             """
             Then the service response status must be '201'
        
         Scenario: Add the graphql body to be sent directly
             Given I securely send requests to 'jsonplaceholder.typicode.com:443'
             When I send a 'POST' request to '/' as 'graphql' with body
             """
                 query {
                     allUsers(perPage: 10) {
                         id
                         name
                     }
                 }
             """
             Then the service response status must be '201'
        
         Scenario: Add the graphql body and variables to be sent directly
             Given I securely send requests to 'jsonplaceholder.typicode.com:443'
             When I send a 'POST' request to '/' as 'graphql' with variables '{"perPage": 10}' and body
             """
                 query ($perPage: Int = 1) {
                     allUsers(perPage: $perPage) {
                         id
                         name
                     }
                 }
             """
             Then the service response status must be '201'
         
         
        Parameters:
        requestType - HTTP verb (type of request): POST, GET, PUT, PATCH, DELETE
        endPoint - end point to be used
        type - If the content as string or json or graphql
        variables - If the content as graphql
        body - Inline body
        See Also:
        sendRequestNoDataTable(String, String, String, String, String, String), sendRequestDataTable(String, String, String, String, String, String, DataTable)
      • assertResponseTime

        @And("the service response time is lower than \'{long}\' milliseconds")
        public void assertResponseTime​(long responseTime)
        Verify that service response time

        This step verifies that the response time of the last request is lower than the given number. The number provided is in milliseconds

        
         Example:
        
          Scenario: Measuring Response Time
             Given I send requests to 'localhost:3000'
             When I send a 'GET' request to '/posts'
             And the service response time is lower than '500' milliseconds
         
         
        Parameters:
        responseTime - Response time value in milliseconds
        See Also:
        assertResponseStatusCode(Integer), assertResponseLength(Integer), assertResponseMessage(String)