Karate: Write to a text file - karate

I have the following feature file that reads the input and appends the input id with the response and writes to a text file in the below format:
|123|{"products": [ { "pid": "1a"} ] }|
|124|{"products": [ { "pid": "1b"} ] }|
|125|{"products": [ { "pid": "1c"} ] }|
so that I can make the input table with it and dont need copy each response in text format and paste to make Examples:
I have tried the below:
Feature: sample karate test script
Background:
* url BaseUrl
* configure headers = read('classpath:headers.js')
* def jsonFromCsv = read('data.csv')
* def size = karate.sizeOf(jsonFromCsv)
* print size
Scenario Outline: Get All Tests
* def doStorage =
"""
function(args) {
var DataStorage = Java.type('DataStorage.DataStorage'); // Java class that writes to a text file
var dS = new DataStorage();
return dS.write(args);
}"""
Given path '/v1/path'
When method get
Then status 200
* def json = __row.expected
* def id = __row.id
* def app = '|'+<id>+'|'+json+'|'
* print app # prinst it in the expected format
* def result = call doStorage app
Examples:
| jsonFromCsv |
But the issue is only the last read data is being written to the file.
I had tried the below as well but gives the same result as above:
* def js = function (app){karate.write(app,'input.txt')}
DataStorage.java:
package DataStorage;
import java.io.*;
public class DataStorage {
public void write( String text) throws IOException {
BufferedWriter output = null;
try {
File file = new File("input");
output = new BufferedWriter(new FileWriter(file));
output.append(text);
output.close();
} catch ( IOException e ) {
e.printStackTrace();
} finally {
if ( output != null ) {
output.close();
}
}
}
}

You can use CSV files (have to be comma delimited): https://github.com/intuit/karate#csv-files
Also see this example:
Scenario Outline: cat name: <name>
Given url demoBaseUrl
And path 'cats'
And request { name: '<name>', age: <age> }
When method post
Then status 200
And match response == { id: '#number', name: '<name>' }
# the single cell can be any valid karate expression
# and even reference a variable defined in the Background
Examples:
| read('kittens.csv') |

Related

Galing- does not display session variable

I try to substitute session variable in the request payload, and it doesn't work,
I am reading from csv file
empNo, orderNo
74726,[49 50]
71696,[52 51 53 50 37 36 38]
object BidSubmission extends HttpUtil {
val orders_feeder = csv("data/Round-1.csv").circular
def orderSubmission: ChainBuilder =
pause(pauseBy(5) seconds)
.repeat(1) {
feed(orders_feeder)
.exec(postToUri(s"${Constants.orderSubmission_URL}/#{$AuctionId}/base-orders/proxy-bid", "")
.queryParam("employeeId", "#{empNo}")
.body(StringBody(session => {
println(session)
println(session.attributes("empNo"))
val empNo = session.attributes("empNo").asInstanceOf[String]
val orderNo = session.attributes("orderNo").asInstanceOf[String]
println(s"\n\n\n $orderNo \n\n\n")
var slotNos = orderNo.replace("[", "").replace("]", "").split(" +")
println(s"\n\n\n ${generatePayload(empNo, slotNos)} \n\n\n")
generatePayload(empNo, slotNos)
" "
}))
)
}
private def generatePayload(empNo: String, orderNo: Array[String]) = {
s"""
| {
| "submittedAt": ${DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.now)}
| "allowSameMonth": false,
| "allowConsecutiveMonths": true,
| "selections": [
${generateSlotNo(orderNo)}
| ]
|}
|""".stripMargin
}
private def generateSlotNo(orderNo: Array[String]) = {
orderNo.map(slotNo => s"\"${Constants.proxySubmission_URL}/#{$AuctionId}/base-orders/00000-00000-00000/order-slots/${slotNo}\"").mkString(",")
}
}
AuctionId session variable is printed in the log, however it is not assigned inside the generateSlotNo method.
in generateSlotNo, AuctionId value is not substituted. It actually prints #{AuctionId} as it is, Can you please help me what i am missing here?
{
"submittedAt": 2023-02-12T22:51:47.860567-06:00
"allowSameMonth": false,
"allowConsecutiveMonths": true,
"selections": [
"https://service.east.cbna.dev1.dev.aws.swacorp.com/golden/base-auction/crew/auctions/#{AuctionId}/base-auctions/0da65bd8-a25f-4b2c-b2f6-2a7f5b0f6432/bid-slots/49","https://service.east.cbna.dev1.dev.aws.swacorp.com/golden/base-auction/crew/auctions/#{AuctionId}/base-auctions/0da65bd8-a25f-4b2c-b2f6-2a7f5b0f6432/bid-slots/50"
]
}
Can you please tell me how i can capture the post request - URI in the test? ie the URI that we are sending the post request to.
As explained in the documentation, Gatling Expression Language only works in Strings passed to Gatling DSL methods.
You can't use it in your own custom code, so you have to explicitly pass the value you want for AuctionId in generateSlotNo.

How to pass dynamic value in request of API in Karate tool? [duplicate]

I have a scenario :
Call API - Capture Response - Get ID from response and call another API which takes input ID from response 1.
Ex :
Feature: test graphql end point
Background:
* url baseUrl + '/graphql'
Scenario: Create Org Call
Given text query =
"""
mutation {
test: createOrganization(
name: "Org Name"
)
{
Id
name
}
}
"""
And request { query: '#(query)' }
When method post
Then status 200
* def res = response
* def id = res.data.test.Id
* print 'response:', response
* print 'Id:', id
Given text query =
"""
mutation {
createBackendHistory(orgId: '#(id)') {
orgId
}
}
"""
And request { query: '#(query)' }
When method post
Then status 200
How to pass value(Id from call 1) is createBackendHistory API
When i try orgId: '#(id)' i am getting error.
Since query is text you can't use the #() embedded expressions. Please refer to the docs: https://github.com/intuit/karate#replace
Try this:
Given text query =
"""
mutation {
createBackendHistory(orgId: '<id>') {
orgId
}
}
"""
And replace query.id = id
And request { query: '#(query)' }
When method post
Then status 200

Is karate variable values are altered with reference?

In the below code, you can see variable defaultHeaders is copied to a new variable called myHeaders.
Now, When altering the value of myHeaders, is altering the value of defaultHeaders variable.
is this correct? am i missing something fundamental. Please explain.
I was hoping the original defaultHeaders would remain same for other scenarios to use.
Karate version: 0.9.4
Feature: test one
Background:
* def defaultHeaders = { 'app-Id' : "defaultApp" }
#ScenarioOne
Scenario: scenario one
* def myHeaders = defaultHeaders
* print myHeaders \\ prints { "app-Id": "defaultApp" }
* myHeaders["app-Id"] = 'MyNewAppId'
* print myHeaders \\ prints { "app-Id": "MyNewAppId" }
* print defaultHeaders \\ prints { "app-Id": "MyNewAppId" }
* print myHeaders \\ prints { "app-Id": "MyNewAppId" }
* def calltoSecond = call read('featureTwo.feature#ScenarioTwo') { customHeader: '#(myHeaders)'}
Please look at the copy keyword: https://github.com/intuit/karate#type-copy
* copy myHeaders = defaultHeaders

Karate - Exception raises for invalid jsonpath

I have a Json response like below. The difference here is my Json body has a number as the parent node.
def response =
"""
{
"22388043":[
{
"firstName":"Romin",
"lastName":"Irani",
"phoneNumber":"408-1234567",
"emailAddress":"romin.k.irani#gmail.com"
}
]
}
"""
I want to return the mobileNumber attribute value from the response body. In this scenario I don't have that attribute in my response. So here I want to get a null value.
So when I use * def mobile = $.22388043[0].mobileNumber, I'm getting below error.
No results for path: $['22388043'][0]['mobileNumber']
Please advise on this.
Karate does give you a way to get the values of JSON keys.
Hopefully this example answers all your other questions as well:
* def response =
"""
{
"22388043":[
{
"firstName":"Romin",
"lastName":"Irani",
"phoneNumber":"408-1234567",
"emailAddress":"romin.k.irani#gmail.com"
}
]
}
"""
* def id = karate.keysOf(response)[0]
* match id == '22388043'
* def person = response[id][0]
* match person contains { firstName: 'Romin', lastName: 'Irani' }
* match person.mobileNumber == '#notpresent'

how to parameterize string along with variable name in input json file

def userName = 'ABC'
def input json = {
"integration": {
"serviceData": {
"integrationService": {
"name": "fld_<tenantID>_stage00.integrations:<integrationName>"
},
"gitComments": "Commit made by: ABC"
}
}
}
In the above json I need to parameterize the user name 'ABC'
If I send
"gitComments": "#(userName)"
It is checking 'ABC' which is fine
But I need to prefix the String "Commit made by: " And then #(userName) in the input json.
Thanks in Advance
https://github.com/intuit/karate#rules-for-embedded-expressions
* def gitComments = 'Commit made by: ' + userName
* def json = { gitComments: '#(gitComments)' }