How to get the Rally TestCaseStepReferences for a Particular TestCase - rally

I have a requirement where I need to update the teststeps for a particular TestCase ex: TC1020
I have the following code which returns me the TestCaseResopnse
QueryRequest testStepRequest = new QueryRequest("TestCase");
testStepRequest.setFetch(new Fetch("TC2006", "Name", "Steps")); //
testStepRequest.setQueryFilter(new QueryFilter("FormattedID", "=",
"TC2006"));
QueryResponse qresponse = restApi.query(testStepRequest);
OUTPUT
{
"QueryResult": {
"_rallyAPIMajor": "2",
"_rallyAPIMinor": "0",
"Errors": [
],
"Warnings": [
"It is no longer necessary to append \".js\" to WSAPI resources."
],
"TotalResultCount": 1,
"StartIndex": 1,
"PageSize": 200,
"Results": [
{
"_rallyAPIMajor": "2",
"_rallyAPIMinor": "0",
"_ref": "https://us1.rallydev.com/slm/webservice/v2.0/testcase/17577048802",
"_refObjectUUID": "cd9b3b44-9f56-40fc-a486-3149479786a9",
"_objectVersion": "6",
"_refObjectName": "Emp_DataCorrectness_AllUnmatched",
"Name": "Emp_DataCorrectness_AllUnmatched",
"Steps": {
"_rallyAPIMajor": "2",
"_rallyAPIMinor": "0",
"_ref": "https://us1.rallydev.com/slm/webservice/v2.0/TestCase/17577048802/Steps",
"_type": "TestCaseStep",
"Count": 5
},
"_type": "TestCase"
}
]
}
}
I'ma able to get the Count as 5 which is expected. Now I want to get the TestCaseStep reference for all the teststep (ex:https://us1.rallydev.com/slm/webservice/v2.0/testcasestep/17577048860)
When i copy able URL browser I'm able to see the all 5 TestStepReference in the JSON response. Now I wanted to achieve it from the RestAPI.
Any help is highly Appreciated
Regards,
Kiran

In WSAPI 2.0, child collections of an object are no longer returned due to performance reasons, and it's necessary to make a follow-up query to obtain them. So you'll need to do something like the following:
JsonArray myTestCases = qresponse.getResults();
for (int i=0; i<myTestCases.size(); i++) {
JsonObject testCase = myTestCases.get(i).getAsJsonObject();
QueryRequest testStepRequest = new QueryRequest(testCase.getAsJsonObject("Steps"));
testStepRequest.setFetch(new Fetch("StepIndex", "Input", "ExpectedResult"));
JsonArray testCaseSteps = restApi.query(testStepRequest).getResults();
for (int j=0;j<testCaseSteps.size();j++){
System.out.println(
testCaseSteps.get(j).getAsJsonObject().get("StepIndex").getAsString() + ": " +
testCaseSteps.get(j).getAsJsonObject().get("Input").getAsString() + ":" + testCaseSteps.get(j).getAsJsonObject().get("ExpectedResult").getAsString());
}
}
There's a more thorough explanation of this within this answer:
Migrating from Rally API 1.43 to 2.0 - Object Model
Where the example is for obtaining a collection of TestCases from a TestSet, however the process is exactly analogous.

Related

How to update the status on a Jira issue vis Jira Rest Api

I want to change the status of the project issue on Jira. The status is Open and I want to make it Fixed. My url is PUT https://jiradbg-sandbox.deutsche-boerse.de/rest/api/latest/issue/PID-XX
{
"update": {
"fields":{
"status": [
{
"set": "Fixed"
}
]
}
}
}
and the response is:
{
"errorMessages": ["Can not deserialize instance of java.util.ArrayList out of START_OBJECT token\n at [Source: org.apache.catalina.connector.CoyoteInputStream#5de98556; line: 3, column: 9]
(through reference chain: com.atlassian.jira.rest.v2.issue.IssueUpdateBean[\"update\"])"]
}
There are two problems that you are encountering here.
The first problem is update or fields should be provided separately to Jira's edit issue API, not one inside of the other. They have equivalent functionality so normally only one is used. For example to update the summary field provide either update:
{
"update": {
"summary": [
{
"set": "Updated by update"
}
]
}
}
or fields:
{
"fields": {
"summary": "Summary set by fields"
}
}
However the status field is a special case and can't be updated directly, which is the second problem here. Changing a status in Jira is called a transition. You need to trigger the transition to move the issue into the status you want.
Start by identifying the available transitions by calling the get transitions API:
GET https://example.net/rest/api/latest/issue/PID-XX/transitions
This tells you which transitions are currently available, something like this:
{
"expand": "transitions",
"transitions": [
{
"id": "21",
"name": "Fixed",
"to": {
"self": "https://example.net/rest/api/2/status/10001",
"description": "",
"iconUrl": "https://example.net/images/icons/status_generic.gif",
"name": "Fixed",
"id": "10001",
"statusCategory": {
"self": "https://example.net/rest/api/2/statuscategory/3",
"id": 3,
"key": "done",
"colorName": "green",
"name": "Done"
}
}
}
]
}
Take the id of the transition you want, in this case 21, then post it to the issue transition API:
POST https://example.net/rest/api/latest/issue/PID-XX/transitions
Use a request body like this:
{
"transition": {
"id": 21
}
}
You should get a 204 HTTP response from Jira which indicates the transition was successful.

karate.repeat creates a malformed JSON that is unable to traverse

I have a scenario where I need to call a secondary feature file that contains an API call where the response is a JSON object. However, I need to call this scenario multiple times, so I am using karate.repeat to achieve this. However, the resulting response is a malformed JSON that I cannot traverse.
This is what I am doing:
* def fun = function(i){ return karate.call('abc.feature#abc', value)}
* def loop = karate.repeat(2, fun)
* karate.log(loop)
The response I get is:
{
"Total_packages1": {
"package1": {
"tags": [
"kj21",
"j1",
"sj2",
"z1"
],
"expectedResponse": [
{
"firstName": "Name",
"lastName": "lastName",
"purchase": [
{
"title": "title",
"category": [
"a",
"b",
"c"
]
}
]
}
]
}
}
}
{
"Total_packages2": {
"package2": {
"tags": [
"kj212",
"j12",
"sj22",
"z12"
],
"expectedResponse": [
{
"firstName": "Name2",
"lastName": "lastName2",
"purchase": [
{
"title": "title2",
"category": [
"a2",
"b2",
"c2"
]
}
]
}
]
}
}
}
As you can see, Total_packages2 starts malformed. I need to grab the "tags" values from each package, however, I cannot simply do Total_packages1.package1.tags like I could with a single response in the JSON.
If I cannot achieve what I need by karate.repeat, is there another method that is recommended for looping like this? I haven't found anything in the documentation for this particular scenario.
Don't use karate.repeat() use call with a JSON array. Read this part of the docs: https://github.com/karatelabs/karate#data-driven-features

data.tables is empty - community visualization in DataStudio

I'm trying to draw custom graph with Google DataStudio community visualization and BigQuery source.
But even if data is exist and valid(check with other basic chart), input data of my drawViz function is empty.
See below Javascript code:
function drawViz(data) {
let rowData = data.tables.DEFAULT;
var metricName = data.fields['barMetric'][0].name;
var dimensionName = data.fields['barDimension'][0].name;
title = metricName + ' by ' + dimensionName + '2';
console.log(rowData , title )
}
Console output:
> {DEFAULT : Array(0)} "my metrics by my dimension"
Is there any restriction using community visualization functionality with bigquery?
Or need any additional setting except in codelab (https://codelabs.developers.google.com/codelabs/community-visualization/#0) ?
** update
manifest.json : https://storage.googleapis.com/vd-qoe-bucket/test/manifest.json
myViz.json : https://storage.googleapis.com/vd-qoe-bucket/test/myViz.json
From your links:
The "data" part of your config appears to be invalid:
"data": [
{
"id": "concepts",
"label": "Concepts",
"elements": [ // setting metric and dimension counts
{
"id": "barDimension",
"label": "Dimension",
"type": "DIMENSION",
"options": {
"min": 1,
"max": 2
}
},
{
"id": "barMetric",
"label": "Metric",
"type": "METRIC",
"options": {
"min": 1,
"max": 2
}
}
]
}
]
Removing the comment // setting dimensions... should work.

JSON ResponseSchemaValidation in Karate

"totalRows": 1,
"colDefs": [
{
"entityAttributeId": "acctNm",
"headerName": "Account Name",
"field": "2",
"entityPath": "",
"entityId": "account"
},
{
"entityAttributeId": "acctId",
"headerName": "Account ID",
"field": "1",
"entityPath": "",
"entityId": "account"
}
],
"rowData": [
{
"1": "1939",
"2": "Bay Pond Partners",
"rowMeta": {
"account": {
"acctInstrumentId": "0025-1939",
"acctId": "1939"
}
}
}
]
}
I have following response from a filter query. As the filter should return only one value, that I am validating with this :
And match GetDataSet_Response contains {"totalRows": 1}
The filter is based on Acctid. Now, I need to validate acctID value and entire json schema. How can I do it in KARATE?
In Schema you can define a
The data type of values which you are expecting but don't know the exact values.
Write an expected condition for your data.
Define the variable of data or hardcode data which you already know.
Ignore few data which don't bother.
break down your JSON and create multiple logical schemas(From your JSON you can have a separate schema for "colDefs" and "rowData")
and many more options for complex validations.
I am not sure about your exact requirement, I have tried to create a schema that might suit your requirement.
{
"colDefs": [
{
"entityAttributeId": "acctNm",
"entityId": "account",
"entityPath": "",
"field": "2",
"headerName": "Account Name"
},
{
"entityAttributeId": "acctId",
"entityId": "account",
"entityPath": "",
"field": "1",
"headerName": "Account ID"
}
],
"rowData": [
{
"1": "#string",
"2": "#string",
"rowMeta": {
"account": {
"acctId": "#(acctID)",
"acctInstrumentId": "#string"
}
}
}
],
"totalRows": 1
}
You can store schema in a JSON file / define it directly in your script and match it with your response
assume we stored this schema in a file filterResponseSchema.json
YourFilter.feature
* def acctID = "1939"
# call your filter request
* def myFilterSchema = read('filterResponseSchema.json')
* match response == myFilterSchema
Note:
i) make sure there is a variable name "acctID" before calling this schema so that karate will embed that value to you JSON schema.
ii) my assumption for your "colDefs" values will be always the same, so I hardcoded it.
Karate documentation covers a good amount of example for Schema validation
I suggest you read this for more insights.

PUT inventory custom fragment

This is my device inventory with the custom tasks array:
{
...
"c8y_IsDevice": {},
"tasks": [
{
"task_status" : "NEW",
"task_id" : "1",
"task_data" : {
...
}
},
{
"task_status" : "DONE",
"task_id" : "2",
"task_data" : {
...
}
},
...
]
...
}
I want to create a MQTT/SMARTREST PUT template to update a task by id and status.
For example: 800,[task_id],[task_status]
I am not able to find a way for this, especially it's an json array and all my attempts end up in overwriting the complete json array.
Maybe there's sth. like a condition, if task_id = x -> set task_status = y
Thank you.
You can only replace the whole fragment. There is no way to partially modify fragments.
one way to do it is get the whole array, using it for create a new one locally with the changes to want to do and finally put it again into the database. It is not a kind of solution but have been working for me.
Thanks for the info, but I still got a question about updating an array.
Concerning your answers I want to update the whole fragment.
This is my inventory:
"tasks": [
{
"address": {
"street": "Street",
"street_number": "1"
},
"description": "Test Description",
"id": "1",
"status": "NEW"
},
{
"address": {
"street": "Street2",
"street_number": "2"
},
"description": "Test Description 2",
"id": "2",
"status": "DONE"
}
]
My template:
801,<$.tasks.status>,<$.tasks.description>,<$.tasks.address.street>,<$.tasks.address.street_number>
Template screenshot
Now I publish:
//801,SERIAL,status,description,street_name,street_nr
801,SERIAL,NEW,1,2,3,4
Of course, this will overwrite the array and just set a json object tasks.
"tasks": {
"address": {
"street": "2",
"street_number": "3"
},
"description": "1",
"status": "NEW"
}
So I tried tasks[*]/tasks[] in my template (like in response templates), but this won't work too. I don't get it, maybe you can give me a small solution about putting a complete fragment with an array inside.