0

I would like to write a requests program instead of curl command to import the test execution results.

The following curl command works for me perfectly, the only problem is that I need to run it manually after robot execution is completed and also my login credentials need to be used:

curl -H "Content-Type: multipart/form-data" -u adminuser:adminpassword -F "file=@output.xml" "https://<xrayurl>/rest/raven/1.0/import/execution/robot?projectKey=TEST&testEnvironments=SIT1&testPlanKey="TEST-25"

I've tried doing the following and finally succeeded after quite a few failed attempts:

import requests
params = (('projectKey', 'TEST'),)
files = {'file': ('output.xml', open(r'C:\workspace\Results\output.xml', 'rb')),}

response = requests.post('https://<xrayurl>/rest/raven/1.0/import/execution/robot', params=params, files=files, auth=('adminuser', 'adminpassword'))

Appreciate your help/guidance in advance. I'll keep trying options and post an answer if I find one.

Keshav Prabhu
  • 83
  • 1
  • 11
  • Ok. So after a few tries, I found a partial solution.. Now the python requests.post method works. I will be editing my question. – Keshav Prabhu Jul 16 '21 at 21:24
  • Another thing that worked for me was the Basic Auth. I am getting closer and closer to what I need. The information on this page was quite helpful. Once I fully accomplish what I need, I will post an answer. But if anyone helps me get there.. even better! https://wiki.resolution.de/doc/api-token-authentication/latest/user-guide/using-tokens-examples?#id-.UsingTokensExamplesv1.7.0-Python – Keshav Prabhu Jul 17 '21 at 04:14

2 Answers2

1

First of all, and to clarify, Xray Cloud and Xray Server/datacenter are different products, with distinct APIs (Xray Server/DC REST API, Xray Cloud REST API). This happens for several reasons, including the fact that Jira Cloud and Jira server are different products with different capabilities. Having said that, let me share some examples both for Xray server/DC and for Xray Cloud.

Xray server/datacenter

The following code snippet shows how to submit results using HTTP basic auth but also an alternate approach, by using Personal Access Tokens which was something recently added to Jira datacenter and that Xray also supports.

import requests
 
jira_base_url = "http://192.168.56.102"
jira_username = "admin"
jira_password = "admin"
personal_access_token = "OTE0ODc2NDE2NTgxOnrhigwOreFoyNIA9lXTZaOcgbNY"


# endpoint doc for importing Robot Framework XML reports: https://docs.getxray.app/display/XRAY/Import+Execution+Results+-+REST#ImportExecutionResultsREST-RobotFrameworkXMLresults
params = (('projectKey', 'CALC'),('fixVersion','v1.0'))
files = {'file': ('output.xml', open(r'output.xml', 'rb')),}

# importing results using HTTP basic authentication
# response = requests.post(f'{jira_base_url}/rest/raven/2.0/import/execution/robot', params=params, files=files, auth=(jira_username, jira_password))

# importing results using Personal Access Tokens 
headers = {'Authorization': 'Bearer ' + personal_access_token}
response = requests.post(f'{jira_base_url}/rest/raven/1.0/import/execution/robot', params=params, files=files, headers=headers)

print(response.status_code)
print(response.content)

Xray Cloud

import requests
import json

xray_cloud_base_url = "https://xray.cloud.xpand-it.com/api/v2"
client_id = "215FFD69FE4644728C72182E00000000"
client_secret = "1c00f8f22f56a8684d7c18cd6147ce2787d95e4da9f3bfb0af8f02ec00000000"

# endpoint doc for authenticating and obtaining token from Xray Cloud: https://docs.getxray.app/display/XRAYCLOUD/Authentication+-+REST+v2
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
auth_data = { "client_id": client_id, "client_secret": client_secret }
response = requests.post(f'{xray_cloud_base_url}/authenticate', data=json.dumps(auth_data), headers=headers)
auth_token = response.json()
print(auth_token)

# endpoint doc for importing Robot Framework XML reports: https://docs.getxray.app/display/XRAYCLOUD/Import+Execution+Results+-+REST+v2#ImportExecutionResultsRESTv2-RobotFrameworkXMLresults
params = (('projectKey', 'BOOK'),('fixVersion','1.0'))
report_content = open(r'output.xml', 'rb')
headers = {'Authorization': 'Bearer ' + auth_token, 'Content-Type': 'application/xml'}
response = requests.post(f'{xray_cloud_base_url}/import/execution/robot', params=params, data=report_content, headers=headers)

print(response.status_code)    
print(response.content)
Sérgio
  • 1,777
  • 2
  • 10
  • 12
0

I found a way to use the Basic Authentication method which does not require my password. Here are the steps I followed:

Generated a Key from My XRAY Profile- Save it somewhere safe.

enter image description here

Followed the directions on the page: https://wiki.resolution.de/doc/api-token-authentication/latest/user-guide/using-tokens-examples?#id-.UsingTokensExamplesv1.7.0-Python

Generated a basic authentication header generator where I supplied my user name and the api_key that was generated from JIRA. Apparently this webpage was recommended in the documentation page: https://www.blitter.se/utils/basic-authentication-header-generator/

You may use the above page or you can use a basic python snippet below to convert the string to your basic authorization key. It hides your credentials from plain sight, but one can still find out your api_key by decoding:

from base64 import urlsafe_b64encode as b64e   
string_to_encode = f"{username}:{api_key}"
encoded_value = b64e(bytearray(string_to_encode, encoding='utf-8'))

My next approach would be to figure out the Bearer Token method. But for some reason I cannot figure out the process yet. I'll keep updating this thread, if I am able to solve it.

import requests
import codecs
params = {'projectKey': 'TEST', 'testPlanKey':'TEST-31', 'testEnvironments': 'SIT'}
with codecs.open(r'C:\workspace\Results\output.xml') as fin:
    content = fin.read()
files = {'file': ('output.xml', content)}
api_token = encoded_value 
api_header = {'Authorization': 'Basic {}'.format(api_token)}
response = requests.post('https://<xrayurl>/rest/raven/1.0/import/execution/robot', params=params, headers=api_header, files=files, verify=False)  # Remove verify=False after you do the necessary SSL certs
print(response.status_code)
print(response.text)
Keshav Prabhu
  • 83
  • 1
  • 11