Search code examples
testingautomationkarate

Dynamically set a XML tag value while building payload


I am trying automate testing using Karate.

I have a XML payload.

I have a static XML payload which I am readying from a file and I want to call my service in loop.

For each call I would like to replace value for a tag name dynamically.

How would I achieve this?

e.g.

Below is my Main Feature which calls my common feature in loop

Feature: Loop Call
Background:
* def common = call read('classpath:CommonFeatures.feature')

Scenario:
* table table
    | payload_file    | field_tag  | field_value |
    | 'HappyPath.xml' | 'car_fuel' | 'Gas'     |
    | 'HappyPath.xml' | 'car_color'| 'Red'     |

* def response = call read('classpath:Car.feature')  table

Car.feature

Feature: Common
Scenario:
    * print payload_file
    * print field_tag
    * print field_value
    * xml payload = read('classpath:/payload/'+payload_file)
    * print payload
    * set payload/$field_tag = field_value

This is where I have issue setting the field_tag value.

I have other option to do this like writing a small java script method to replace the tag value or a small java class which use DOMParser or SAXParser to perform the same.

However I would like to know if there is any karate in build way to perform the same.

Also while using java script method to replace the tag value if I am using var parser = new DOMParser(); and it seems DOMParser is not available to use. Is there a way to make this available?


Solution

  • Thanks to Peter for all help and the examples.

    I feel this is the best way to achieve this.

    Wrote a small javascript function

       """
        * def replaceTag =
          """
          function(x){
            karate.setXml('temp', x.payload);
            karate.pretty(karate.get('temp'));
            if (x.field_tag) karate.set('temp', x.field_tag, x.field_value);
            return karate.get('temp');
          }
        """
    

    and calling the same from Car.feature like below and I get the dynamically replaced payload.

    Feature: Common
    Scenario:
        * print payload_file
        * print field_tag
        * print field_value
        * xml payload = read('classpath:/payload/'+payload_file)
        * print payload
        * def args = { payload: #(payload), field_tag: #(field_tag), field_value: #
              (field_value)}
        * print args
        * xml payload = call common.replaceTag args
    

    Note: I had to upgrade Karate 0.7.0 version in order to use karate.setXml method.