Iterating the table to click on the particular value - testing

I am fetching the "Id" value from the previous page and storing it in text file. In the next page I am trying to iterate the table to find the particular Id by passing the value from the text file and trying to click on the status as "Accept" hyperlink. I have tried with the below steps but it throws me an error.
Code Snippet:
And def Id = commonClass.TextFile('TestData','Id')
* def list = scriptAll('tr td', '_.textContent')
* print list
* def fun = function(x, i){ if (x.contains(Id)) karate.set('index', i) }
* def xpath = "//table[#id='value']/tbody/tr/td[" + (index + 6) + "]/div/a"
* click(xpath)
Error Message:
"//table[#id='value']/tbody/tr/td[" + (index + 6) + "]/div/a", javax.script.ScriptException: ReferenceError: "index" is not defined in <eval> at line number 1
stack trace: jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:470)

Related

Karate - substring - lastindexof trim/ strip/ slice help needed

I have a tricky authentication issue which requires multiple calls to ultimately obtain an access-token.
I am currently stumbling on the conversion of a returned correlation-id to a correct format.
The correlationID from a post response is returned as: Id-c5ea93607b0682a76040b5db 0; Id-c5ea93607b0682a76040b5db 2
I need to convert to c5ea93607b0682a76040b5db
I have tried with * def serviceId1 = correlationID.substring(correlationID.lastIndexOf('-')+ 1).trim()
which is resulting in c5ea93607b0682a76040b5db 2
I need to strip the " 2" value from the backend of the id to make it
from: 'c5ea93607b0682a76040b5db 2'
to: 'c5ea93607b0682a76040b5db'
I have tried many ways but cant refine to get working - ANY HELP IS MUCH APPRECIATED
The code below:
Scenario: Obtaining access_token
* def correlationID = 'Id-c5ea93607b0682a76040b5db 0; Id-c5ea93607b0682a76040b5db 2'
* def serviceId1 = correlationID.substring(correlationID.lastIndexOf('-')+ 1).trim()
* print 'correlationID ' + correlationID
* print 'serviceID ' + serviceId1
is resulting in c5ea93607b0682a76040b5db 2 ( I want to strip the trailing " 2" - how can I do this?
Here you go:
* def temp = 'c5ea93607b0682a76040b5db 2'
* def pos = temp.lastIndexOf(' ')
* def fixed = temp.substring(0, pos)
* match fixed == 'c5ea93607b0682a76040b5db'

Change type from string to float/double for a key value of any json object in an array

i have a json as follows:
* def first = [{"country":"X","code":"XY","cityName":"XYZN","city":"XYZ","timezone":"XYZT","latitude":"57.0928","name":"XYZN","longitude":"9.8492"}, {"country":"A","code":"AB","cityName":"ABCN","city":"ABC","timezone":"ABCT","latitude":"1.234","name":"ABCN","longitude":"29.8482"}]
def second = [{"country":"X","code":"XY","cityName":"XYZN","city":"XYZ","timezone":"XYZT","latitude":57.0928,"name":"XYZN","longitude":9.8492}, {"country":"A","code":"AB","cityName":"ABCN","city":"ABC","timezone":"ABCT","latitude":1.234,"name":"ABCN","longitude":29.8482}]
i want to compare these two, but its failing because the first json has longitude and latitude as string while second json has them as numbers.
Also, i dont want to change second json and has to be used as it is.
Please suggest how can i change the type from string to number in first?
I tried https://github.com/intuit/karate#floats-and-integers
but it didnt work out for object array.
Sample Code:
Feature:
Scenario:
* def first = [{"country":"X","code":"XY","cityName":"XYZN","city":"XYZ","timezone":"XYZT","latitude":"57.0928","name":"XYZN","longitude":"9.8492"}, {"country":"A","code":"AB","cityName":"ABCN","city":"ABC","timezone":"ABCT","latitude":"1.234","name":"ABCN","longitude":"29.8482"}]
* def second = [{"country":"X","code":"XY","cityName":"XYZN","city":"XYZ","timezone":"XYZT","latitude":57.0928,"name":"XYZN","longitude":9.8492}, {"country":"A","code":"AB","cityName":"ABCN","city":"ABC","timezone":"ABCT","latitude":1.234,"name":"ABCN","longitude":29.8482}]
* def first_formatted = []
* def fun = function(x){x.latitude = Number(x.latitude); x.longitude = Number(x.longitude); karate.appendTo(first_formatted, x); }
* karate.forEach(first, fun)
* print first_formatted
* match first_formatted == second

Unable to Parse the variable value to the array variable

I was trying to pass the variable 'i' value to a array index 'locations[i]' using below karate code. but throwing an error saying unable to parse. Please suggest be for any changes.
Feature: Verify Branches
Background: For loop implementation
Given url ''
When method GET
Then status 200
* def i = 0
* def z = $.locations[i].zip
* def p = $.locations[i].phone
* def fun =
"""
function(locations){
for (var i = 0; i < locations.length; i++)
{
print(i)
print('Element at Location ' + i +':' + p)
}
}
"""
Scenario: Validate the locations
Given url ''
When method GET
Then status 200
* call fun p
It is hard to make out anything since you have not provided the value of the response. There are many things wrong here. But I'll try.
Take this line:
* def z = $.locations[i].zip
This will not work, Karate does not support variables within JsonPath by default, refer the docs: https://github.com/intuit/karate#jsonpath-filters
And I think you are un-necessarily using JsonPath where normal JavaScript would have been sufficient:
* def z = response.locations[i].zip
Also it seems you are just trying to loop over an array and call a feature. Please refer to the documentation on Data Driven Features.
Take some time and read the docs and examples please, it will be worth your time. One more tip - before I leave you to understand Karate a little better. There is a way to convert a JSON array into another JSON array should you need it:
* def fun = function(x){ return { value: x } }
* def list = [1, 2, 3]
* def res = karate.map(list, fun)
* match res == [{ value: 1 }, { value: 2 }, { value: 3 }]
So there should never be a need for you to manually do a for loop at all.

Salesforce Apex: Error ORA-01460

I've developed an apex API on salesforce which performs a SOQL on a list of CSV data. It has been working smoothly until yesterday, after making a few changes to code that follow the SOQL query, I started getting a strange 500 error:
[{"errorCode":"APEX_ERROR","message":"System.UnexpectedException:
common.exception.SfdcSqlException: ORA-01460: unimplemented or
unreasonable conversion requested\n\n\nselect /SampledPrequery/
sum(term0) \"cnt0\",\nsum(term1) \"cnt1\",\ncount(*)
\"totalcount\",\nsum(term0 * term1) \"combined\"\nfrom (select /*+
ordered use_nl(t_c1) /\n(case when (t_c1.deleted = '0') then 1 else 0
end) term0,\n(case when (upper(t_c1.val18) = ?) then 1 else 0 end)
term1\nfrom (select /+ index(sampleTab AKENTITY_SAMPLE)
*/\nentity_id\nfrom core.entity_sample sampleTab\nwhere organization_id = '00Dq0000000AMfz'\nand key_prefix = ?\nand rownum <=
?) sampleTab,\ncore.custom_entity_data t_c1\nwhere
t_c1.organization_id = '00Dq0000000AMfz'\nand t_c1.key_prefix = ?\nand
sampleTab.entity_id =
t_c1.custom_entity_data_id)\n\nClass.labFlows.queryContacts: line 13,
column 1\nClass.labFlows.fhaQuery: line 6, column
1\nClass.zAPI.doPost: line 10, column 1"}]
the zAPI.doPost() is simply our router class which takes in the post payload as well as the requested operation. It then calls whatever function the operation requests. In this case, the call is to labFlows.queryContacts():
Public static Map<string,List<string>> queryContacts(string[] stringArray){
//First get the id to get to the associative entity, Contact_Deals__c id
List<Contact_Deals__c> dealQuery = [SELECT id, Deal__r.id, Deal__r.FHA_Number__c, Deal__r.Name, Deal__r.Owner.Name
FROM Contact_Deals__c
Where Deal__r.FHA_Number__c in :stringArray];
//Using the id in the associative entity, grab the contact information
List<Contact_Deals__c> contactQuery = [Select Contact__r.Name, Contact__r.Id, Contact__r.Owner.Name, Contact__r.Owner.Id, Contact__r.Rule_Class__c, Contact__r.Primary_Borrower_Y_N__c
FROM contact_deals__c
WHERE Id in :dealQuery];
//Grab all deal id's
Map<string,List<string>> result = new Map<string,List<string>>();
for(Contact_Deals__c i:dealQuery){
List<string> temp = new list<string>();
temp.add(i.Deal__r.Id);
temp.add(i.Deal__r.Owner.Name);
temp.add(i.Deal__r.FHA_Number__c);
temp.add(i.Deal__r.Name);
for(Contact_Deals__c j:contactQuery){
if(j.id == i.id){
//This doesn't really help if there are multiple primary borrowers on a deal - but that should be a SF worflow rule IMO
if(j.Contact__r.Primary_Borrower_Y_N__c == 'Yes'){
temp.add(j.Contact__r.Owner.Id);
temp.add(j.Contact__r.Id);
temp.add(j.Contact__r.Name);
temp.add(j.Contact__r.Owner.Name);
temp.add(j.Contact__r.Rule_Class__c);
break;
}
}
}
result.put(i.Deal__r.id, temp);
}
return result;
}
The only thing I've changed is moving the temp list to add elements before the inner-loop (previously temp would only capture things from the inner-loop). The error above is referencing line 13, which is specifically the first SOQL call:
List<Contact_Deals__c> dealQuery = [SELECT id, Deal__r.id, Deal__r.FHA_Number__c, Deal__r.Name, Deal__r.Owner.Name
FROM Contact_Deals__c
Where Deal__r.FHA_Number__c in :stringArray];
I've tested this function in the apex anonymous window and it worked perfectly:
string a = '00035398,00035401';
string result = zAPI.doPost(a, 'fhaQuery');
system.debug(result);
Results:
13:36:54:947 USER_DEBUG
[5]|DEBUG|{"a09d000000HRvBAD":["a09d000000HRvBAD","Contacta","11111111","Plaza
Center
Apts"],"a09d000000HsVAD":["a09d000000HsVAD","Contactb","22222222","The
Garden"]}
So this is working. The next part is maybe looking at my python script that is calling the API,
def origQuery(file_name, operation):
csv_text = ""
with open(file_name) as csvfile:
reader = csv.reader(csvfile, dialect='excel')
for row in reader:
csv_text += row[0]+','
csv_text = csv_text[:-1]
data = json.dumps({
'data' : csv_text,
'operation' : operation
})
results = requests.post(url, headers=headers, data=data)
print results.text
origQuery('myfile.csv', 'fhaQuery')
I've tried looking up this ORA-01460 apex error, but I can't find anything that will help me fix this issue.
Can any one shed ore light on what this error is telling me?
Thank you all so much!
It turns out the error was in the PY script. For some reason the following code isn't functioning as it is supposed to:
with open(file_name) as csvfile:
reader = csv.reader(csvfile, dialect='excel')
for row in reader:
csv_text += row[0]+','
csv_text = csv_text[:-1]
This was returning one very long string that had zero delimiters. The final line in the code was cutting off the delimiter. What I needed instead was:
with open(file_name) as csvfile:
reader = csv.reader(csvfile, dialect='excel')
for row in reader:
csv_text += row[0]+','
csv_text = csv_text[:-1]
Which would cut off the final ','
The error was occurring because the single long string was above 4,000 characters.

Cache a variable in groovy

When I try to access the len-variables at the end of the script I get this error: "Cannot iterate twice! If you want to iterate more that once, add _CACHE explicitely."
How can I fix that?
def src_str = query_string
def src_arr = src_str.split(' ')
def trg_arr = doc['my_index'].values
trg_arr_sorted = [:]
trg_arr.each {
_index['my_index'].get(it, _POSITIONS).each { pos ->
trg_arr_sorted[pos.position] = it
}
}
src_len = src_arr.length
def trg_len = trg_arr_sorted.size()
int[][] matrix = new int[src_len + 1][trg_len + 1]
(src_len + 1).times { matrix[it][0] = it }
(trg_len + 1).times { matrix[0][it] = it }
(1..src_len).each { i ->
(1..trg_len).each { j ->
matrix[i][j] = [matrix[i-1][j] + 1, matrix[i][j-1] + 1,
src_arr[i-1] == trg_arr_sorted[j-1] ? matrix[i-1][j-1] : matrix[i-1][j-1] + 1].min()
}
}
return 100 - (100 * matrix[src_len][trg_len] / max(src_len, trg_len)) // over here !!!
The code calculates a score using the levenshtein distance computed in words. It works perfect except of the scoring in the last line.
Okay problem is solved.
I explicitly had to declare cache and positions:
_index['lang'].get(it, _POSITIONS | _CACHE)
The error wasn't in the last line, but I thought so. I changed the script to debug it, but elasticsearch doesn't reload the new scipt instantly.