java.lang.NullPointerException with a POST call in Karate - cucumber

I have a feature file like below:
*Feature: Create Quote in D365
Background:
* def myFeature = call read('D365_Authentication.feature')
* header Authorization = 'Bearer ' + myFeature.BearerToken
* def random_string =
"""
function(s){
var text = "";
var pattern = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
for(var i=0; i<s; i++)
text += pattern.charAt(Math.floor(Math.random() * pattern.length()));
return text;
}
"""
* url '<somehost>'
Scenario: Create Opportunity
Given path '<path>'
And def requestPayload = read('CreateOpportunity.json')
And set requestPayload.name = 'Temp Opportunity From Karate ' + random_string(10)
And set requestPayload.hsl_closedate = '2022-03-23T00:00:00.000Z'
And header Content-Type = 'application/json'
And request requestPayload
When method POST
Then status 204*
When running this, getting NullPointerException. Can anybody help me identify why this exception is coming.

Firstly you need to download the jar file specific karate version from https://github.com/karatelabs/karate/releases.
Please unfold the Assets link.
You can run the feature file so:
java - jar jarfinename -m xxx.feature

Related

How to create Wiki Subpages in Azure Devops thru Python?

My Azure devops page will look like :
I have 4 pandas dataframes.
I need to create 4 sub pages in Azure devops wiki from each dataframe.
Say, Sub1 from first dataframe, Sub2 from second dataframe and so on.
My result should be in tab. The result should look like :
Is it possible to create subpages thru API?
I have referenced the following docs. But I am unable to make any sense. Any inputs will be helpful. Thanks.
https://github.com/microsoft/azure-devops-python-samples/blob/main/API%20Samples.ipynb
https://learn.microsoft.com/en-us/rest/api/azure/devops/wiki/pages/create%20or%20update?view=azure-devops-rest-6.0
To create a wiki subpage, you should use Pages - Create Or Update api, and specify the path to pagename/subpagename. Regarding how to use the api in Python, you could use Azure DevOps Python API and refer to the sample below:
def create_or_update_page(self, parameters, project, wiki_identifier, path, version, comment=None, version_descriptor=None):
"""CreateOrUpdatePage.
[Preview API] Creates or edits a wiki page.
:param :class:`<WikiPageCreateOrUpdateParameters> <azure.devops.v6_0.wiki.models.WikiPageCreateOrUpdateParameters>` parameters: Wiki create or update operation parameters.
:param str project: Project ID or project name
:param str wiki_identifier: Wiki ID or wiki name.
:param str path: Wiki page path.
:param String version: Version of the page on which the change is to be made. Mandatory for `Edit` scenario. To be populated in the If-Match header of the request.
:param str comment: Comment to be associated with the page operation.
:param :class:`<GitVersionDescriptor> <azure.devops.v6_0.wiki.models.GitVersionDescriptor>` version_descriptor: GitVersionDescriptor for the page. (Optional in case of ProjectWiki).
:rtype: :class:`<WikiPageResponse> <azure.devops.v6_0.wiki.models.WikiPageResponse>`
"""
route_values = {}
if project is not None:
route_values['project'] = self._serialize.url('project', project, 'str')
if wiki_identifier is not None:
route_values['wikiIdentifier'] = self._serialize.url('wiki_identifier', wiki_identifier, 'str')
query_parameters = {}
if path is not None:
query_parameters['path'] = self._serialize.query('path', path, 'str')
if comment is not None:
query_parameters['comment'] = self._serialize.query('comment', comment, 'str')
if version_descriptor is not None:
if version_descriptor.version_type is not None:
query_parameters['versionDescriptor.versionType'] = version_descriptor.version_type
if version_descriptor.version is not None:
query_parameters['versionDescriptor.version'] = version_descriptor.version
if version_descriptor.version_options is not None:
query_parameters['versionDescriptor.versionOptions'] = version_descriptor.version_options
additional_headers = {}
if version is not None:
additional_headers['If-Match'] = version
content = self._serialize.body(parameters, 'WikiPageCreateOrUpdateParameters')
response = self._send(http_method='PUT',
location_id='25d3fbc7-fe3d-46cb-b5a5-0b6f79caf27b',
version='6.0-preview.1',
route_values=route_values,
query_parameters=query_parameters,
additional_headers=additional_headers,
content=content)
response_object = models.WikiPageResponse()
response_object.page = self._deserialize('WikiPage', response)
response_object.eTag = response.headers.get('ETag')
return response_object
More details, you could refer to the link below:
https://github.com/microsoft/azure-devops-python-api/blob/451cade4c475482792cbe9e522c1fee32393139e/azure-devops/azure/devops/v6_0/wiki/wiki_client.py#L107
Able to achieve with rest api
import requests
import base64
import pandas as pd
pat = 'TO BE FILLED BY YOU' #CONFIDENTIAL
authorization = str(base64.b64encode(bytes(':'+pat, 'ascii')), 'ascii')
headers = {
'Accept': 'application/json',
'Authorization': 'Basic '+authorization
}
df = pd.read_csv('sf_metadata.csv') #METADATA OF 3 TABLES
df.set_index('TABLE_NAME', inplace=True,drop=True)
df_test1 = df.loc['CURRENCY']
x1 = df_test1.to_html() # CONVERTING TO HTML TO PRESERVE THE TABULAR STRUCTURE
#JSON FOR PUT REQUEST
SamplePage1 = {
"content": x1
}
#API CALLS TO AZURE DEVOPS WIKI
response = requests.put(
url="https://dev.azure.com/xxx/yyy/_apis/wiki/wikis/yyy.wiki/pages?path=SamplePag2&api-version=6.0", headers=headers,json=SamplePage1)
print(response.text)
Based on #usr_lal123's answer, here is a function that can update a wiki page or create it if it doesn't:
import requests
import base64
pat = '' # Personal Access Token to be created by you
authorization = str(base64.b64encode(bytes(':'+pat, 'ascii')), 'ascii')
def update_or_create_wiki_page(organization, project, wikiIdentifier, path):
# Check if page exists by performing a Get
headers = {
'Accept': 'application/json',
'Authorization': 'Basic '+authorization
}
response = requests.get(url=f"https://dev.azure.com/{organization}/{project}/_apis/wiki/wikis/{wikiIdentifier}/pages?path={path}&api-version=6.0", headers=headers)
# Existing page will return an ETag in their response, which is required when updating a page
version = ''
if response.ok:
version = response.headers['ETag']
# Modify the headers
headers['If-Match'] = version
pageContent = {
"content": "[[_TOC_]] \n ## Section 1 \n normal text"
+ "\n ## Section 2 \n [ADO link](https://azure.microsoft.com/en-us/products/devops/)"
}
response = requests.put(
url=f"https://dev.azure.com/{organization}/{project}/_apis/wiki/wikis/{wikiIdentifier}/pages?path={path}&api-version=6.0", headers=headers,json=pageContent)
print("response.text: ", response.text)

How to get dynamic url of file uploaded to sharepoint using python?

My code does following tasks on daily basis:
Create a date folder on sharepoint.DONE
Create a category folder in the date folder of sharepoint. DONE
Upload a file in respective category folder. DONE
4. Find the url of file. PENDING
Send the url on email. DONE
def upload_files(base_url, site, access_token, fileName, filePath, fileFolderUrl):
try:
fileHandle = open(filePath, 'rb')
#fileFolderUrl = f'Shared Documents/Output/{subFolder}'
requestFileUploadUrl = f"{base_url}/{site}/_api/web/GetFolderByServerRelativeUrl('{fileFolderUrl}')/Files/add(url='{fileName}',overwrite=true)"
headers = {
'Accept':'application/json; odata=verbose',
'Content-Type':'application/json; odata=verbose',
'Authorization': 'Bearer {}'.format(access_token)
}
uploadFileResult = requests.post(requestFileUploadUrl, headers=headers, data=fileHandle)
if uploadFileResult.status_code == 200:
return "success"
else:
return "failure"
except Exception as e:
print(f"Error in uploading files to sharepoint:{e}")
return "error"
Can someone please help me understand the process to obtain the url of this file that I am required to upload in dynamically created folders on sharepoint using python3+?
So,the structure is : SharedDocuments/Output/Today's Date/CategoryA/file.xlsx
One solution could be to create the URL manually as you already know the url, the site and the name of the file.
I figure out that you can create the link to share a file with this pattern :
<base_url>/<site>/<FileFolderUrl>/<File>?&web=1
For example : https://company.sharepoint.com/sites/test/Documents%20partages/testing.jpg?&web=1
It works only for people that already have access it.
I have not yet tested in an automatic solution but only by hand in an empirical way
I know it's been a long while but was scrolling through it today and thought of answering it. Hope it can be helpful to someone in the future.
def get_out_file_url(base_url, site, access_token, file_folder, fileName):
"""
These are random examples of file_folder and base_url
file_folder = 'Shared Documents/Output/Dated/Category'
base_url = 'https://company.sharepoint.com'
"""
requestFileGetUrl = f'{base_url}/sites/{site}/_api/web/GetFolderByServerRelativeUrl(\'' + fileUrl + '/'+ '\')/files?$filter'
headers = {
'Accept':'application/json; odata=verbose',
'Content-Type':'application/json; odata=verbose',
'Authorization': 'Bearer {}'.format(access_token)
}
getFileResult = requests.get(requestFileGetUrl, headers=headers)
values = getFileResult.json()
fileData = values['d']['results']
for key in fileData:
if key['Name'] == fileName:
fileURLLink = key['ServerRelativeUrl']
fileCreatedTime = key['TimeCreated']
fileLastModified = key['TimeLastModified']
fileNewUrl = base_url + urllib.parse.quote(fileURLLink)
return fileNewUrl
else:
return file_folder

How to export pdf attachment from soap response using groovy?

Although soap (free version) has an option to export document generated in response. Is there any groovy function to extract application/pdf file and store in my local folder ?
The following script should be able to save the attachment to a file.
Add the below script as Script Assertion to the current request step. Find the appropriate comments inline.
Source for the script is taken from here
/**
* Below script assertion will check
* if the response is not null
* there is an attachment
* and saves file to the specified location, by default saves into system temp
* directory
**/
//change file name as needed
def fileName = System.getProperty('java.io.tmpdir')+'/test.pdf'
//Get the response and check if the response is not null
def response = messageExchange.response
assert null != response, "response is null"
//Create output stream
def outFile = new FileOutputStream(new File(fileName))
//Check if there is one attachment in the response
assert 1 == messageExchange.responseAttachments.length, "Response attachments count not matching"
def ins = messageExchange.responseAttachments[0]?.inputStream
if (ins) {
//Save to file
com.eviware.soapui.support.Tools.writeAll( outFile, ins )
}
ins.close()
outFile.close()

Unable to download completed envelope pdf using dcousign rest API

I am trying to access signed envelop using REST API and I getting response from REST API but when I save the response to pdf, it doesn't show any content.
Below is a small python code that I wrote to achieve this.
import json
import requests
url = "https://demo.docusign.net/restapi/v2/accounts/[Account ID]/envelopes/[Envelope ID]/documents/1"
headers = {'X-DocuSign-Authentication': '<DocuSignCredentials><Username>[username]</Username><Password>[password]</Password><IntegratorKey>[Integrator Key]</IntegratorKey></DocuSignCredentials>'}
Response = requests.get(url, headers = headers)
file = open("agreement.pdf", "w")
file.write(Response.text.encode('UTF-8'))
file.close()
Try using httplib2, also the content is always going to come back formatted as a PDF through DocuSign, so I don't think you need to set the encoding.
import json
import requests
import httplib2
url = "https://demo.docusign.net/restapi/v2/accounts/[Account ID]/envelopes/[Envelope ID]/documents/1"
headers = {'X-DocuSign-Authentication': '<DocuSignCredentials><Username>[username]</Username><Password>[password]</Password><IntegratorKey>[Integrator Key]</IntegratorKey></DocuSignCredentials>'}
http = httplib2.Http();
response, content = http.request(url, 'GET', headers = headers)
status = response.get('status');
if (status != '200'):
print("Error: " % status); sys.exit();
file = open("agreement.pdf", "w")
file.write(content)
file.close()
Have you seen the DocuSign API Walkthroughs? These are accessible through the Developer Center, I suggest you take a look as there are code samples for 9 common API use-cases, each written in Python (and 5 other languages), including the 6th walkthrough which shows you how to query and download docs from completed envelopes.
The main problem with your code is that it's assuming the response only contains the document data, which is not correct. The response will have headers and a body, that's why you can't render your document when you simply write it all to a file.
I suggest you use httplib2, which is what the following Python sample uses:
http://iodocs.docusign.com/APIWalkthrough/getEnvelopeDocuments
Here is a snippet of the Python code but check out the above link for full code:
#
# STEP 2 - Get Envelope Document(s) Info and Download Documents
#
# append envelopeUri to baseURL and use in the request
url = baseUrl + envelopeUri + "/documents";
headers = {'X-DocuSign-Authentication': authenticateStr, 'Accept': 'application/json'};
http = httplib2.Http();
response, content = http.request(url, 'GET', headers=headers);
status = response.get('status');
if (status != '200'):
print("Error calling webservice, status is: %s" % status); sys.exit();
data = json.loads(content);
envelopeDocs = data.get('envelopeDocuments');
uriList = [];
for docs in envelopeDocs:
# print document info
uriList.append(docs.get("uri"));
print("Document Name = %s, Uri = %s" % (docs.get("name"), uriList[len(uriList)-1]));
# download each document
url = baseUrl + uriList[len(uriList)-1];
headers = {'X-DocuSign-Authentication': authenticateStr};
http = httplib2.Http();
response, content = http.request(url, 'GET', headers=headers);
status = response.get('status');
if (status != '200'):
print("Error calling webservice, status is: %s" % status); sys.exit();
fileName = "doc_" + str(len(uriList)) + ".pdf";
file = open(fileName, 'w');
file.write(content);
file.close();
print ("\nDone downloading document(s)!\n");

Executing a Java jar file from within a SoapUI groovy script not working

I am new to SoapUI and Groovy so please forgive this post as it has been posted a number of times in Stackoverflow however I cannot find a fix.
SoapUI version: 4.5.2
I have 2 questions if you guys don't mind:
I have an executable jar file that I've put in the the \bin\ext directory along with another jar that is considered a dependency jar within the code in the jar so I hope it will reference there. The groovy code I found in Stackoverflow that should execute this jar is as follows but does not work as I don't see any output anywhere in the SoapUI directory.
Here is the code:
def command = "java -jar UpdateAppIdXMLRequest.jar file.xml"
def process = command.execute()
process.waitFor()
def output = process.in.text
log.info output
This jar creates 25 xml files that should be able to be picked up by the SoapUI and put them in as TestSteps in the same project. In my java code in what path do I put these files?
Here is the code in my jar:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
class UpdateAppIdXMLRequest {
static main(args) {
try {
SAXBuilder builder = new SAXBuilder();
File xmlFile = new File("c:\\file.xml");
Document doc = (Document) builder.build(xmlFile);
Element rootNode = doc.getRootElement();
// Create loop to create 25 testStepApps
for (int i = 1; i < 26; i++) {
// Get current AppID, incrementAppID and update the ApplicationNumber attribute value for next test script.
int appID = Integer.parseInt(rootNode.getAttributeValue("ApplicationNumber"));
appID++;
String appIDValue = Integer.toString(appID);
rootNode.getAttribute("ApplicationNumber").setValue(appIDValue);
XMLOutputter xmlOutput = new XMLOutputter();
// Create new XML file with next AppID
xmlOutput.setFormat(Format.getPrettyFormat());
xmlOutput.output(doc, new FileWriter("c:\\testStepApp" + i + ".xml"));
// xmlOutput.output(doc, System.out);
// System.out.println("File updated!");
}
} catch (IOException io) {
io.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
}
}
}
Any help/direction would be appreciated.
Thanks.
In order to do so, I recommend that you use directly groovy test step instead of a jar, this way you have more flexibility an you have not recompile the jar each time you must need to change something.
So, in order to achieve your goal, at first you need to create a TestCase inside your project, create a SOAP Test Step and Groovy Test Step inside like this:
I will use SOAP Test Step to create the other test steps (to create test steps it needs the wsdl:operation and so on, and it's more easy to copy the test step that create directly).
In the Groovy Test Step I will put the necessary code to do the work which is showed below:
import com.eviware.soapui.support.XmlHolder
import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestRequestStepFactory
// read your request template
def requestFile = new File("C:/file.xml");
// parse it as xml
def requestXml = new XmlHolder(requestFile.text)
// get the current testCase to add testSteps later
def tc = testRunner.testCase;
// get the testStep as template to create the other requests
def tsTemplate = tc.getTestStepByName("Template");
// loop to create 25 testStep
for(int i = 1; i < 26; i++){
// xpath expression to get applicationNumber attribute in root node
def xpathNodeAttr = "/*/#ApplicationNumber";
// get the root node attribute applicationNumber throught an XPATH
int appId = Integer.parseInt(requestXml.getNodeValue(xpathNodeAttr));
// add 1 to appId
appId++;
// set the value again in the attribute
requestXml.setNodeValue(xpathNodeAttr,appId);
def testStepName = "TestStep_ApplicationNumber_"+ String.valueOf(appId)
log.info testStepName;
log.info testStepName.getClass().getName()
log.info tc.getClass().getName()
// create a new testStepConfig
def testStepFactory = new WsdlTestRequestStepFactory();
def testStepConfig = testStepFactory.createConfig( tsTemplate.getOperation(), testStepName )
// add the new testStep to TestCase
def newTestStep = tc.insertTestStep( testStepConfig, -1 )
// set the request which just create
newTestStep.getTestRequest().setRequestContent(requestXml.getXml())
}
This code it's basically your java code "translated" to groovy and added the necessary code to create the test steps. In a few words this code reads a request from a file, and create 25 test steps in the current test case using the request, in each request it only changes the ApplicationNumber attribute of the root node adding it +1.
EDIT BASED ON COMMENT:
If you use a REST Request step instead of SOAP Request Step you have to change a bit your groovy code to use com.eviware.soapui.impl.wsdl.teststeps.registry.RestRequestStepFactory and getTestRequest() method on it. So if you have a REST Service with a POST method create a Test Case with a REST Request test step and Groovy Test Step like this:
And use this groovy code instead, basically this code it's the same and works like the code above and makes the same thing with REST Request instead of SOAP Request:
import com.eviware.soapui.support.XmlHolder
import com.eviware.soapui.impl.wsdl.teststeps.registry.RestRequestStepFactory
// read your request template
def requestFile = new File("C:/file.xml");
// parse it as xml
def requestXml = new XmlHolder(requestFile.text)
// get the current testCase to add testSteps later
def tc = testRunner.testCase;
// get the testStep as template to create the other requests
def tsTemplate = tc.getTestStepByName("Template");
// loop to create 25 testStep
for(int i = 1; i < 26; i++){
// xpath expression to get applicationNumber attribute in root node
def xpathNodeAttr = "/*/#ApplicationNumber";
// get the root node attribute applicationNumber throught an XPATH
int appId = Integer.parseInt(requestXml.getNodeValue(xpathNodeAttr));
// add 1 to appId
appId++;
// set the value again in the attribute
requestXml.setNodeValue(xpathNodeAttr,appId);
def testStepName = "TestStep_ApplicationNumber_"+ String.valueOf(appId)
log.info testStepName;
log.info testStepName.getClass().getName()
log.info tc.getClass().getName()
// create a new testStepConfig
def testStepFactory = new RestRequestStepFactory();
def testStepConfig = testStepFactory.createConfig( tsTemplate.getTestRequest(), testStepName )
// add the new testStep to TestCase
def newTestStep = tc.insertTestStep( testStepConfig, -1 )
// set the request which just create
newTestStep.getTestRequest().setRequestContent(requestXml.getXml())
}
Hope this helps.

Resources