I've parsed the Below Json file and retrieve the username value.
"LogInFunctionTest": [
{
"TestCaseID": "Login-TC_02",
"TestScenario": "Negative Case - Login with unregistered username and Password",
"TestData": [
{
"UserName": "usernameX",
"Password": "passwordX"
}
]
Using the below code to retrieve the UserName Value.
def InputJSON = new JsonSlurper().parse(new File(fileName))
def testDataItem = InputJSON.LogInFunctionTest.find { it.TestCaseID == Login-TC_02 }.TestData.UserName
Output - [usernameX]
After this, I want to remove the brackets from the above.
'Remove brackets from arraylist'
testDataItem = testDataItem.substring(1, testDataItem.length() - 1)
I'm getting the below exception
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMethodException: No signature of method: java.util.ArrayList.length() is applicable for argument types: () values: []
Possible solutions: last(), last(), init(), init(), get(int), get(int)
Anyone guide us on how to remove the brackets from the output?
testDataItem is a list of UserNames as TestData contains a list
That's why when it's displayed to you, it has [] round it...
If you just want the first one in the list, then you can do:
def testDataItem = InputJSON
.LogInFunctionTest
.find { it.TestCaseID == 'Login-TC_02' }
.TestData
.UserName
.first()
(ie: put a call to first() at the end)
Obviously, if there's two of them, you'll only be getting the first one
You could also get the first one with .UserName[0], but .first() is more descriptive
testDataItem = testDataItem.get(0)
might do the job.
Looks like you're reading a list of Strings, not a String.
Technically you referred to 'TestData' as a List with the brackets above so proper reference should be:
TestData[0].UserName
... or since it's all contained in the 'LogInFunctionTest' List:
LogInFunctionTest[0].TestData[0].UserName
That is if you are not going to loop/iterate through them.
Related
An api returns an array with json objects. I want to check if an object in the array exists which has certain key value entries. The approach im using does not work when the value type is different.
"$", hasItem(
allOf(
hasEntry("id", "someid123"),
hasEntry("age", 99)
)
);
My IDE gives the error:
Cannot resolve method 'allOf(Matcher<Map<? extends K, ? extends V>>, Matcher<Map<? extends K, ? extends V>>)'
This method would work if 99 were a String, but in this case I can not control that the API returns a number.
Does anyone know a way to get this done?
Example response body Im trying to parse:
[
{
"id": "someid123",
age: 99
},
{
"id": "anotherid789",
age: 77
}
]
The objects get converted into java maps internally I think.
This is the specific of Java generics which can (and they actually do) align the argument types for the methods.
You can work that around with the help of JsonPath like I'm showing below:
public static void main(String[] args) {
RestAssured.baseURI = "http://demo1954881.mockable.io";
Response resp =
given().
when().get("/collectionTest")
.then().extract().response();
resp.then()
.body("findAll{i -> i.id == 'someid123' && i.age == 99}", not(empty()));
}
So basically you're filtering the collection with the help of JsonPath and then assert that it is not empty.
I am doing a POST call action through my selenium Automation program using Rest Assured API & Java. IO get a response as mentioned below-
{
"cmsContract": "HA1123",
"groupId": "12345",
"siteId": "4444-AP",
"stateCountyCode": "7978790"
},
{
"cmsContract": "HB2345",
"groupId": "9876",
"siteId": "8888-DK",
"stateCountyCode": "111225"
}
There are about 1000 or more JSON Objects in the response. And they don't have a identifier for the response like "name" or "contractinfo"
My query:
1. How do I retrieve the total count of the arrays (like one from '{' to '}') using Rest Assured APIs in conjuncture with JAVA and selenium?
If I had to retrieve 'stateCountyCode' for the result set with 'cmsContract' as HB2345 , how would I do that? I would want to see the value return as 111225
Please suggest.
Libraries used-
org.json.JSONObject;
io.restassured.RestAssured;
io.restassured.response.Response;
io.restassured.specification.RequestSpecification;
You can use JsonPath to parse JSON response. Basically, you can get JsonPath class from String, File or Response.
From String:
JsonPath path = JsonPath.from("json string");
From File:
JsonPath path = JsonPath.from(new File("path to file"));
From Response:
Response response; //we get it from RestAssured by calling POST/GET etc
JsonPath path = response.body().jsonPath();
In order to get any element in the JSON Structure, just like in your case, we have to provide it to JsonPath. Example JSON:
{
"data": [
{
"name": "test"
},
{
"name": "test1"
}
]
}
In order to access an element in the Array, we have to know ALL of its parents.
The structure looks like this:
path.get("parent.child.anotherChild");
The thing gets more tricky with Arrays because we have to use indexes.
The "data" in the example above is an array. In order to access test1 we would use:
path.get("data[1].name"); //second element in the array
But that's the standard approach. JsonPath is a much stronger library.
Finally, to answer your question. How do we get a count of JSON Objects in the Array?
List<HashMap<String, Object>> jsonObjects = path.getList("data"); //You have to provide name of the Array's parent. In my case, it's `data`
In the above List of HashMaps, we have ALL of JSON Objects in the JSON Array. So you can use multiple ways to count the elements.
To count how many JSON Objects there is you can simply use List's method:
jsonObjects.size();
With the same List, we can get cmsContract value, as in your example. We look for value HB2345.
Standard for loop. You can use Streams if you know how.
public String getStateCountryCodeFromCmsContract(String cmsContractValue) {
for (HashMap<String, Object> singleJsonObject : jsonObjects) {
String cmsContract = (String) singleJsonObject.get("cmsContract");
if (cmsContract.equals(cmsContractValue)) {
return (String) singleJsonObject.get("stateCountyCode");
}
}
}
We iterate over each JSON Object, check the value of cmsContract element, and if it equals the desired value - return stateCountryCode value.
Hope it helps!
I have my Apache Flink program:
import org.apache.flink.api.scala._
import scala.util.parsing.json._
object numHits extends App {
val env = ExecutionEnvironment.getExecutionEnvironment
val data=env.readTextFile("file:///path/to/json/file")
val j=data.map { x => ("\"\"\""+x+"\"\"\"") }
/*1*/ println( ((j.first(1).collect())(0)).getClass() )
/*2*/ println( ((j.first(1).collect())(0)) )
/*3*/ println( JSON.parseFull((j.first(1).collect())(0)) )
}
I want to parse the input JSON file into normal scala Map and for that I am using the default scala.util.parsing.json._ library.
The output of the first println statement is class java.lang.String which is required by the JSON parsing function.
Output of the second println function is the actual JSON string appended and prepended by "\"\"\"" which is also required by the JSON parser.
Now at this point if I copy the output of the second println command printed in the console and pass it to the JSON.parseFull() function, it properly parses it.
Therefore the third println function should properly parse the same string passed to it but it does not as it outputs a "None" string which means it failed.
Why does this happen and how can I make it work?
Output of the second println function is the actual JSON string appended and prepended by "\"\"\"" which is also required by the JSON parser.
No, of course it isn't. This produces a string like """{}""", which isn't valid JSON and this properly rejected by the parser. When you write """{}""" in Scala code, the quotes aren't part of the string itself, they just delimit the literal: the content of the string is {}, which is valid JSON.
You will have to just change
val j=data.map { x => ("\"\"\""+x+"\"\"\"") }
to
val j=data.map { x => x.replaceAll("\"", "\\\"") }
But the above code is not required as the code below will work:
val data=env.readTextFile("file:///path/to/json").flatMap( line => JSON.parseFull(line) )
I am attempting to make a course registration system and one of my classes (Course) is centered around course attributes (ie. Course number, course name, instructors, students). I am making an ArrayList so that the Administrator (one of the user types) may add as many instructors to the course as he/she would like- I have created a Scanner and a String variable and everything, but when I write the .add command, Eclipse highlights ".add" and says "the method .add() is undefined for the type of scanner". Now, I can understand this, but I have no idea how to fix it and I've tried so many ideas.
Here is the method:`
public static String Instructor(){
String courseInstructors;
System.out.println("Please add name(s) of course instructors.");
ArrayList<String> Instructors= new ArrayList<String>();
Scanner courseInst = new Scanner(System.in);
courseInstructors = courseInst.next();
//courseInst.add(courseInstructors);
for(String courseInstructors1 : Instructors) {
courseInstructors1 = courseInstructors;
courseInst.add(courseInstructors1);
}
return;
}`
Please adhere to Java naming conventions ad use lower case for variable names - instructors instead of Instructors.
Also, you want to add to your arraylist, so call add() on
instructors.add(courseInstructors1)
You may also want to consider choosing better variable naming than courseInstructors1, for instance just courseInstructor, since you are referring to on instructor of all instructors.
Also in your for loop you are doing the following
for(String courseInstructors1 : Instructors) {
courseInstructors1 = courseInstructors;
courseInst.add(courseInstructors1);
}
This can be simplified to
for(String courseInstructors1 : Instructors) {
courseInst.add(courseInstructors);
}
And if you look at the simplification you will see that iterating through Instructors make no sense here, since you are not using the contents of courseInstructors1.
I'm trying to understand what your loop is for.
if you are trying to get multiple instructor names from one input then you need something like this.
//get input
//"John Peggy Adam blah blah"
courseInstructors = courseInst.next();
//split the string by white space
String[] instArr = courseInstructors.split(" ");
//will give array of John, Peggy, Adam, blah, blah
Then do your foreach loop to add them to the list.
for(String inst: instArr){
instructors.add(inst);
}
Otherwise I would suggest doing something like this so you don't have to worry about splitting names and such.
courseInstructor = courseInst.nextLine();
while(!courseInstructor.equals("done"){
//add name to list of instructors.
instructors.add(courseInstructor);
//get next name.
courseInstructor = courseInt.nextLin();
//if the user types done, it will break the loop.
//otherwise come back around and add it and get next input.
}
I want to check a list contains a specific string .
before checking all entries in list as well as sting should be in. lowercase
I tried like this
def venueName = params.name
def venueNameLists = Venue.executeQuery("select name from Venue")
if(venueNameLists.toLowerCase().contains(venueName.toLowerCase())){
error = true;
log.debug("save :: duplicate name")
flash.message = "Venue name already exist";
render(view: "create", model: [venueInstance: new Venue(params)])
return
}
gives error
No signature of method: java.util.ArrayList.toLowerCase() is applicable for argument types: () values: []. Stacktrace follows:
groovy.lang.MissingMethodException: No signature of method: java.util.ArrayList.toLowerCase() is applicable for argument types: () values: []
I agree with aiolos: use constraints or try to find instance by name ignore case. But to fix this your way try *. (spread operator):
venueNameLists*.toLowerCase().contains(venueName.toLowerCase())
If you would like to check a duplicate entry before saving an element, use constraints on your domain class. Here you could use unique constraint or implement your own if you need it case insensitive.
If you need to check it manually, try this:
def venueWithNameFromParams = Venue.findByNameIlike(params.name) // ignore case
if(venueWithNameFromParams){
// venueName is in venueNameList
}
If you were looking how to check if multiple strings contains a word, while ignoring case-sensitive, use (?i) on a regex of words.
For example, the following will be positive condition:
word = "YES"
word.matches(/(?i)yes|ok|true/)