diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index f57b560..38a79bf 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -25,7 +25,7 @@ jobs: - name: Run Robot File run: robot -d ./reports -e offline ./Tests/keyword_tests.robot - name: Upload test results - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 if: always() with: name: robot_reports @@ -37,11 +37,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Download reports - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4 with: name: robot_reports + path: reports - name: Send report to commit uses: joonvena/robotframework-reporter-action@v2.4 with: gh_access_token: ${{ secrets.GITHUB_TOKEN }} - report_path: /robot_reports \ No newline at end of file + report_path: reports \ No newline at end of file diff --git a/.gitignore b/.gitignore index e2c357b..68351dc 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ response_test.xml report.html output.xml log.html +venv/ diff --git a/SoapLibrary/SoapLibrary.py b/SoapLibrary/SoapLibrary.py index f0046e0..077da59 100644 --- a/SoapLibrary/SoapLibrary.py +++ b/SoapLibrary/SoapLibrary.py @@ -64,10 +64,10 @@ def create_soap_client(self, url, ssl_verify=True, client_cert=None, auth=None, session.cert = client_cert session.auth = HTTPBasicAuth(*auth) if auth else None self.client = Client(self.url, transport=Transport(session=session)) - logger.info('Connected to: %s' % self.client.wsdl.location) + logger.info(f'Connected to: {self.client.wsdl.location}') info = self.client.service.__dict__ operations = info["_operations"] - logger.info('Available operations: %s' % list(operations)) + logger.info(f'Available operations: {list(operations)}') if use_binding_address: self.url = self.client.service._binding_options['address'] @@ -124,10 +124,10 @@ def get_data_from_xml_tag(self, xml, tag, index=1): if isinstance(data_list, (float, int)): return int(data_list) if len(data_list) == 0: - logger.warn('The search "%s" did not return any result! Please confirm the tag!' % xpath) + logger.warn(f'The search "{xpath}" did not return any result! Please confirm the tag!') elif len(data_list) > 1: - logger.debug('The tag you entered found %s items, returning the text in the index ' - 'number %s, if you want a different index inform the argument index=N' % (len(data_list), index)) + logger.debug(f'The tag you entered found {len(data_list)} items, returning the text in the index ' + f'number {index}, if you want a different index inform the argument index=N') return data_list[new_index].text @keyword("Edit XML Request") @@ -160,11 +160,11 @@ def edit_xml(self, xml_file_path, new_values_dict, edited_request_name, repeated raise Exception("new_values_dict argument must be a dictionary") for key, value in new_values_dict.items(): if len(xml.xpath(self._replace_xpath_by_local_name(key))) == 0: - logger.warn('Tag "%s" not found' % key) + logger.warn(f'Tag "{key}" not found') continue xml_xpath = self._replace_xpath_by_local_name(key) - count = int(xml.xpath(("count(%s)" % xml_xpath))) - logger.debug("Found %s tags with xpath %s" % (str(count), xml_xpath)) + count = int(xml.xpath(f"count({xml_xpath})")) + logger.debug(f"Found {(str(count))} tags with xpath {xml_xpath}") if repeated_tags == 'All' or count < 2: for i in range(count): xml.xpath(xml_xpath)[i].text = value @@ -221,8 +221,8 @@ def convert_response_dict(self, xml_etree): if type(result[key]) is list: result[key].append(value) else: - tempvalue = result[key].copy() - result[key] = [tempvalue, value] + temp_value = result[key].copy() + result[key] = [temp_value, value] else: result[key] = value return result @@ -400,10 +400,10 @@ def _check_and_print_response(self, response, etree_response, status): :param etree_response: response object in etree format. :param status: if is not None, then don“t raise error. """ - logger.debug('URL: %s' % response.url) + logger.debug(f'URL: {response.url}') logger.debug(etree.tostring(etree_response, pretty_print=True, encoding='unicode')) if status is None and response.status_code != 200: - raise AssertionError('Request Error! Status Code: %s! Reason: %s' % (response.status_code, response.reason)) + raise AssertionError(f'Request Error! Status Code: {response.status_code}! Reason: {response.reason}') self._print_request_info(etree_response) def _save_response_object(self, response): @@ -413,7 +413,7 @@ def _save_response_object(self, response): :param response, zeep response object. """ - logger.info('Status code: %s' % response.status_code) + logger.info(f'Status code: {response.status_code}') self.response_obj = response @staticmethod @@ -446,9 +446,9 @@ def _save_to_file(save_folder, file_name, text): :param save_folder: folder to save the new xml file. :param file_name: name of the new file. :param text: file text. - :return new file path. + :return: new file path. """ - new_file_name = "%s.xml" % file_name + new_file_name = f"{file_name}.xml" new_file_path = os.path.join(save_folder, new_file_name) request_file = open(new_file_path, 'wb') request_file.write(text) diff --git a/SoapLibrary/version.py b/SoapLibrary/version.py index 631932c..3610d01 100644 --- a/SoapLibrary/version.py +++ b/SoapLibrary/version.py @@ -1 +1 @@ -VERSION = '1.3' +VERSION = '1.4' diff --git a/Tests/keyword_tests.robot b/Tests/keyword_tests.robot index f7d37c7..53356c0 100644 --- a/Tests/keyword_tests.robot +++ b/Tests/keyword_tests.robot @@ -104,7 +104,7 @@ Test Read Tags With Index Create Soap Client ${wsdl_correios} ${response} Call SOAP Method With XML ${requests_dir}${/}busca_servicos.xml ${codigo} Get Data From XML By Tag ${response} codigo index=13 - Should Be Equal As Integers ${codigo} 032 + Should Be Equal As Integers ${codigo} 29 Test Response To Dict [Tags] correios diff --git a/dist/robotframework_soaplibrary-1.4.tar.gz b/dist/robotframework_soaplibrary-1.4.tar.gz new file mode 100644 index 0000000..c667f9d Binary files /dev/null and b/dist/robotframework_soaplibrary-1.4.tar.gz differ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..768912a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,23 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "robotframework-soaplibrary" +version = "1.4" +description = "SOAP Library for Robot Framework" +readme = "README.md" +requires-python = ">=3.7" + +dependencies = [ + "robotframework", + "zeep", + "requests", + "urllib3", + "setuptools" +] + +[project.optional-dependencies] + +[project.urls] +Homepage = "https://github.com/MarketSquare/Robot-Framework-SOAP-Library" diff --git a/robotframework_soaplibrary.egg-info/PKG-INFO b/robotframework_soaplibrary.egg-info/PKG-INFO index 3ab71c5..aef5770 100644 --- a/robotframework_soaplibrary.egg-info/PKG-INFO +++ b/robotframework_soaplibrary.egg-info/PKG-INFO @@ -1,13 +1,82 @@ -Metadata-Version: 2.1 +Metadata-Version: 2.4 Name: robotframework-soaplibrary -Version: 1.3 +Version: 1.4 Summary: SOAP Library for Robot Framework -Home-page: https://github.com/Altran-PT-GDC/Robot-Framework-SOAP-Library +Home-page: https://github.com/MarketSquare/Robot-Framework-SOAP-Library Author: Altran Portugal Author-email: samuca@gmail.com -License: MIT License -Platform: UNKNOWN +Project-URL: Homepage, https://github.com/MarketSquare/Robot-Framework-SOAP-Library +Requires-Python: >=3.7 +Description-Content-Type: text/markdown License-File: LICENSE.md +Requires-Dist: robotframework +Requires-Dist: zeep +Requires-Dist: requests +Requires-Dist: urllib3 +Requires-Dist: setuptools +Dynamic: author +Dynamic: author-email +Dynamic: home-page +Dynamic: license-file -Test library for Robot Framework to create automated test like using SOAPUI +[![PyPi downloads](https://img.shields.io/pypi/dm/robotframework-soaplibrary.svg)](https://pypi.org/project/robotframework-soaplibrary) +[![Total downloads](https://static.pepy.tech/personalized-badge/robotframework-soaplibrary?period=total&units=international_system&left_color=lightgrey&right_color=yellow&left_text=Total)](https://pypi.org/project/robotframework-soaplibrary) +[![Latest Version](https://img.shields.io/pypi/v/robotframework-soaplibrary.svg)](https://pypi.org/project/robotframework-soaplibrary) +[![tests](https://github.com/MarketSquare/Robot-Framework-SOAP-Library/actions/workflows/python-app.yml/badge.svg?branch=master)](https://github.com/MarketSquare/Robot-Framework-SOAP-Library/actions/workflows/python-app.yml) + +# Robot-Framework-SOAP-Library +SOAP Library for Robot Framework + +## Compatibility +- _Python 3.7 +_ +- _Zeep 4.2.1 +_ + +## Introduction +The SoapLibrary was created for those who want to use the Robot Framework as if they were using SoapUI, just send the request XML and get the response XML. + +![alt text](https://github.com/MarketSquare/Robot-Framework-SOAP-Library/blob/master/Doc/img_SoapUI.png) + +![alt text](https://github.com/MarketSquare/Robot-Framework-SOAP-Library/blob/master/Doc/img2_SoapLibrary.png) + +## Instalation +For the first time installation: +```commandline +pip install robotframework-soaplibrary +``` +Or you can upgrade with: +```commandline +pip install --upgrade robotframework-soaplibrary +``` + +## Example + +```RobotFramework + *** Settings *** + Library SoapLibrary + Library OperatingSystem + + *** Test Cases *** + Example + Create Soap Client http://endpoint.com/example.asmx?wsdl + ${response} Call SOAP Method With XML ${CURDIR}/request.xml + ${text} Get Data From XML By Tag ${response} tag_name + Log ${text} + Save XML To File ${response} ${CURDIR} response_test +``` + +## Example with certificate + +You can see [here](https://michaelhallik.github.io/blog/2022/04/10/Using-OpenSSL-to-provide-the-RF-SoapLibrary-with-a-TLS-client-certificate) an example of how to use OPENSSL to access a webservice with TLS certificate. (Thanks Michael Hallik) + +## Keyword Documentation + +You can find the keywords documentation [here](https://raw.githack.com/MarketSquare/Robot-Framework-SOAP-Library/master/Doc/SoapLibrary.html) + +## Authors +Initial development was sponsored by [Capgemini Engineering](https://www.capgemini.com/about-us/who-we-are/our-brands/capgemini-engineering/) + - **Samuel Cabral** + - **Joao Gomes** + +## License +This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/MarketSquare/Robot-Framework-SOAP-Library/blob/master/LICENSE.md) file for details. diff --git a/robotframework_soaplibrary.egg-info/SOURCES.txt b/robotframework_soaplibrary.egg-info/SOURCES.txt index a520565..128ff9f 100644 --- a/robotframework_soaplibrary.egg-info/SOURCES.txt +++ b/robotframework_soaplibrary.egg-info/SOURCES.txt @@ -1,5 +1,6 @@ LICENSE.md README.md +pyproject.toml setup.py SoapLibrary/SoapLibrary.py SoapLibrary/__init__.py diff --git a/robotframework_soaplibrary.egg-info/requires.txt b/robotframework_soaplibrary.egg-info/requires.txt index 0d38d18..679eb96 100644 --- a/robotframework_soaplibrary.egg-info/requires.txt +++ b/robotframework_soaplibrary.egg-info/requires.txt @@ -2,3 +2,4 @@ robotframework zeep requests urllib3 +setuptools diff --git a/setup.py b/setup.py index c79eda0..5ab2e0a 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from os.path import abspath, dirname, join try: @@ -6,7 +5,7 @@ except ImportError as error: from distutils.core import setup - +VERSION = None version_file = join(dirname(abspath(__file__)), 'SoapLibrary', 'version.py') with open(version_file) as file: @@ -14,13 +13,13 @@ exec(code) setup(name = 'robotframework-soaplibrary', - version = '1.3', + version = VERSION, description = 'SOAP Library for Robot Framework', long_description = 'Test library for Robot Framework to create automated test like using SOAPUI', author = 'Altran Portugal', author_email = 'samuca@gmail.com', license = 'MIT License', - url = 'https://github.com/Altran-PT-GDC/Robot-Framework-SOAP-Library', + url = 'https://github.com/MarketSquare/Robot-Framework-SOAP-Library', packages = ['SoapLibrary'], - install_requires = ['robotframework', 'zeep', 'requests', 'urllib3'] + install_requires = ['robotframework', 'zeep', 'requests', 'urllib3', 'setuptools'] )