### Install robotframework-gevent via pip Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/README.md Install the library using pip. This is the standard installation command for the package. ```bash pip install robotframework-gevent ``` -------------------------------- ### Add Coroutine usage examples Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/GeventLibrary.html Shows how to add a keyword as a coroutine to a bundle. If no bundle alias is given, the last created bundle is used by default. Examples include adding 'Sleep 1s' with an alias and 'Convert To Lower Case UPPER'. ```robotframework Add Coroutine Sleep 1s Add Coroutine Sleep 1s alias=alias1 Add Coroutine Convert To Lower Case UPPER ``` -------------------------------- ### Create Gevent Bundle usage examples Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/GeventLibrary.html Shows how to create a bundle for coroutines. Once created, keywords can be attached to it and executed asynchronously when 'Run Coroutines' is called. The alias parameter is optional and defaults to None. ```robotframework Create Gevent Bundle Create Gevent Bundle alias=alias1 ``` -------------------------------- ### Waiting for Multiple Greenlets with gevent.joinall Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/GeventLibrary.html Use gevent.joinall to wait for multiple greenlets to complete. The example shows how to spawn several greenlets and wait for all of them. ```python import gevent def task(name): print(f'Task {name} started') gevent.sleep(1) print(f'Task {name} done') jobs = [gevent.spawn(task, i) for i in range(3)] gevent.joinall(jobs) ``` -------------------------------- ### Asynchronous Execution with gevent.spawn Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/GeventLibrary.html Use gevent.spawn to run a function asynchronously. The example shows how to spawn a greenlet and wait for its result. ```python import gevent def task(): print('Task running') gevent.sleep(1) return 'Task done' greenlet = gevent.spawn(task) greenlet.join() print(greenlet.get()) ``` -------------------------------- ### Run Coroutines usage example Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/GeventLibrary.html Shows the Robot Framework syntax for calling the Run Coroutines keyword with an alias parameter. The keyword runs all coroutines asynchronously and returns a list of values in order. ```robotframework ${values} Run Coroutines alias=alias1 ``` -------------------------------- ### JavaScript code for documentation viewer initialization and rendering Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/GeventLibrary.html This JavaScript code is embedded in the page and handles the initialization of the documentation viewer, including rendering templates, handling hash changes, managing keyword search, and setting the theme. It is not a user-facing example but rather the internal logic of the documentation page. ```javascript // Not using jQuery here for speed and to support ancient browsers. document.getElementById('javascript-disabled').style.display = 'none'; window.addEventListener("hashchange", function() { document.getElementsByClassName("hamburger-menu")[0].checked = false; }, false); window.addEventListener("hashchange", function() { if (window.location.hash.indexOf('#type-') == 0) { const hash = '#type-modal-' + decodeURI(window.location.hash.slice(6)); const typeDoc = document.querySelector(".data-types").querySelector(hash); if (typeDoc) { showModal(typeDoc); } } }, false); $(document).ready(function() { parseTemplates(); document.title = libdoc.name; storage.init('libdoc'); setTheme(); renderTemplate('base', libdoc, $('body')); if (libdoc.inits.length) { libdoc.typedocs.map(function(type) { var index = type.usages.indexOf('__init__'); if (index != -1) type.usages[index] = 'Importing'; }); renderTemplate('importing', libdoc); } renderTemplate('shortcuts', libdoc); renderTemplate('keyword-shortcuts', libdoc); renderTemplate('keywords', libdoc); renderTemplate('data-types', libdoc); renderTemplate('footer', libdoc); const params = util.parseQueryString(window.location.search.slice(1)); let selectedTag = ""; if ("tag" in params) { selectedTag = params["tag"]; tagSearch(selectedTag, window.location.hash); } if (libdoc.tags.length) { libdoc.selectedTag = selectedTag; renderTemplate('tags-shortcuts', libdoc); } scrollToHash(); setTimeout(function() { document.getElementById("keyword-statistics-header").innerText = '' + libdoc.keywords.length; if (storage.get('keyword-wall') === 'open') { openKeywordWall(); } }, 0); createModal(); }); function setTheme(theme) { document.documentElement.setAttribute('data-theme', theme || getTheme()); } function getTheme() { if (libdoc['theme']) { return libdoc['theme']; } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) { return 'dark'; } else { return 'light;' } } function parseTemplates() { $('script[type="text/x-jquery-tmpl"]').map(function (idx, elem) { $.template(elem.id, elem.text); }); } function renderTemplate(name, arguments, container) { if (!container) { container = $('#' + name + '-container'); container.empty(); } if (!arguments.search) { arguments.search = false; } $.tmpl(name + '-template', arguments).appendTo(container); } function scrollToHash() { if (window.location.hash) { var hash = window.location.hash.substring(1); var id = decodeURIComponent(hash); document.getElementById(id).scrollIntoView(); } } function tagSearch(tag, hash) { document.getElementsByClassName('search-input')[0].value = ''; const include = {tags: true, tagsExact: true}; const url = window.location.pathname + "?tag=" + tag + (hash || ""); markMatches(tag, include); highlightMatches(tag, include); history.replaceState && history.replaceState(null, '', url); document.getElementById('keyword-shortcuts-container').scrollTop = 0; } function clearTagSearch() { document.getElementsByClassName('search-input')[0].value = ''; history.replaceState && history.replaceState(null, '', window.location.pathname); resetKeywords(); } function closeMenu() { document.getElementById('hamburger-menu-input').checked = false; } function markMatches(pattern, include, givenSearchTime, callback) { if (givenSearchTime && givenSearchTime !== searchTime) { return; } let patternRegexp = util.regexpEscape(pattern); if (include.tagsExact) { patternRegexp = '^' + patternRegexp + '$'; } let regexp = new RegExp(patternRegexp, 'i'); let test = regexp.test.bind(regexp); let result = {}; let keywordMatchCount = 0; result.keywords = util.map(libdoc.keywords, function (kw) { kw = $.extend({}, kw); kw.hidden = !(include.name && test(kw.name)) && !(include.args && test(kw.args)) && !(include.doc && test($(kw.doc).text())) && !(include.tags && util.any(util.map(kw.tags, test))); if (!kw.hidden) keywordMatchCount++; return kw; }); renderTemplate('keyword-shortcuts', result); renderTemplate('keywords', result); if (libdoc.tags.length) { libdoc.selectedTag = include.tagsExact ? pattern : ""; renderTemplate('tags-shortcuts', libdoc); } document.getElementById("keyword-statistics-header").innerText = keywordMatchCount + ' / ' + result.keywords.length; if (keywordMatchCount === 0) $('#keywords-container').find('table').empty(); if (callback) { requestAnimationFrame(callback); } } function highlightMatches(string, include, givenSearchTime) { if (givenSearchTime && givenSearchTime !== searchTime) { return; } const shortcuts = $('#shortcuts-container').find('.match'); const keywords = $('#keywords-container').find('.match'); if (include.name) { ``` -------------------------------- ### create_gevent_bundle error handling Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/GeventKeywords.md Robot Framework example showing that creating a second bundle with the same alias fails with the error 'An alias with name batch1 has already been created.' ```robotframework ${first_alias}= Generate Random String 8 [chars]=ABCDEF # simulate distinct aliases Create Gevent Bundle alias=batch1 # Creating a second bundle with the same alias fails the keyword: Run Keyword And Expect Error An alias with name batch1 has already been created. Create Gevent Bundle alias=batch1 ``` -------------------------------- ### GeventLibrary test case example Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/GeventLibrary.html Shows a Robot Framework test case that uses GeventLibrary to run coroutines. It logs a message, creates a gevent bundle, adds two coroutines that sleep, runs them, and logs the returned values. ```robotframework ** Settings ** Library GeventLibrary ** Test Cases ** Test1 Log Hello World Create Gevent Bundle alias=alias1 Add Coroutine Sleep 1s alias=alias1 Add Coroutine Sleep 1s alias=alias1 ${values} Run Coroutines alias=alias1 Log Many @{values} ``` -------------------------------- ### Import GeventLibrary in Python Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/configuration.md Shows how to import and instantiate the GeventLibrary class in Python code. ```python from GeventLibrary import GeventLibrary lib = GeventLibrary(patch_threads=True) ``` -------------------------------- ### Mutation location: start and end positions Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 18102022.html Indicates the source file and position range for the mutation. The mutation is located in gevent_keywords.py from start position (246, 4) to end position (247, 0). ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (246, 4), end pos: (247, 0) ``` -------------------------------- ### Basic usage of RobotKeywordCoroutine Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/RobotKeywordCoroutine.md Constructs a RobotKeywordCoroutine directly and shows keyword_name and all_args outputs. Demonstrates the expected list format. ```python from GeventLibrary.keywords.gevent_keywords import RobotKeywordCoroutine coro = RobotKeywordCoroutine("Sleep", "10s", alias="batch1") print(coro.keyword_name) # "Sleep" print(coro.all_args) # ["10s", "alias=batch1"] ``` -------------------------------- ### Survived mutation location Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Location of the survived mutation in the source file, showing start and end positions. ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (219, 28), end pos: (219, 29) ``` -------------------------------- ### GeventKeywords.__init__ Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/GeventKeywords.md Initializes the GeventKeywords instance by creating an empty OrderedDict registry for active gevent bundles. Accepts no parameters and returns None. ```APIDOC ## GeventKeywords.__init__ ### Description Initializes the GeventKeywords instance by creating an empty OrderedDict registry for active gevent bundles. Accepts no parameters and returns None. ### Method Constructor ### Signature ```python def __init__(self) -> None: ``` ### Parameters None ### Returns None ### Example ```python from GeventLibrary.keywords import GeventKeywords keywords = GeventKeywords() ``` ``` -------------------------------- ### Mutation position in gevent_keywords.py Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Specifies the start and end positions of the mutation in the source file, which is at line 239, columns 15 to 33. ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (239, 15), end pos: (239, 33) ``` -------------------------------- ### RobotKeywordCoroutine.__init__ Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/RobotKeywordCoroutine.md Constructor for RobotKeywordCoroutine that stores the keyword name, positional arguments, and keyword arguments for later execution. ```APIDOC ## RobotKeywordCoroutine.__init__ ### Description Initializes a new RobotKeywordCoroutine instance with the given keyword name, positional arguments, and keyword arguments. ### Method Constructor ### Endpoint `RobotKeywordCoroutine(keyword_name, *args, **kwargs)` ### Parameters - **keyword_name** (str) - Required - The Robot Framework keyword to execute. - **args** (tuple) - Optional - Positional arguments forwarded to the keyword. - **kwargs** (dict) - Optional - Keyword arguments forwarded to the keyword. ### Return Value None ``` -------------------------------- ### Test run summary output Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Output of the test run showing 13 tests executed in 0.051s with all passing (OK). ```text ............. ---------------------------------------------------------------------- Ran 13 tests in 0.051s OK ``` -------------------------------- ### Mutation location in gevent_keywords.py Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Specifies the file and position of the mutation: start pos (250, 44) to end pos (250, 46). ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (250, 44), end pos: (250, 46) ``` -------------------------------- ### Mutation location Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 07092022.html Location of the mutation in the source file gevent_keywords.py, from start pos (71, 4) to end pos (72, 0). ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (71, 4), end pos: (72, 0) ``` -------------------------------- ### Test Run Summary Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 18102022.html Shows the summary of the test run: 17 tests ran in 0.010s, with 2 failures and 8 errors. ```text Ran 17 tests in 0.010s FAILED (failures=2, errors=8) ``` -------------------------------- ### Basic Run Coroutines usage Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/GeventKeywords.md Basic Robot Framework usage: creates a bundle, adds two coroutines, runs them, and logs the returned values. The result list is ordered by registration order. ```robotframework Create Gevent Bundle alias=batch1 Add Coroutine Sleep 1s alias=batch1 Add Coroutine Convert To Integer 42 alias=batch1 ${values} Run Coroutines alias=batch1 Log Many @{values} ``` -------------------------------- ### add_coroutine basic usage Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/GeventKeywords.md Robot Framework usage of add_coroutine with alias=batch1, adding Sleep, Convert To Lower Case, and GET coroutines. ```robotframework Create Gevent Bundle alias=batch1 Add Coroutine Sleep 1s alias=batch1 Add Coroutine Convert To Lower Case UPPER alias=batch1 Add Coroutine GET https://jsonplaceholder.typicode.com/posts/1 alias=batch1 ``` -------------------------------- ### Run the test with robot Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/README.md Command to execute the Robot Framework test file. After running, the log.html file is generated, showing the asynchronous execution order in a table format. ```text >>> robot simple-test.robot ``` -------------------------------- ### Import GeventLibrary in Robot Framework Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/configuration.md Shows how to import the GeventLibrary in a Robot Framework settings file, with and without the patch_threads option. ```robotframework *** Settings *** Library GeventLibrary Library GeventLibrary patch_threads=True ``` -------------------------------- ### Mutation location in gevent_keywords.py Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Shows the source file and position of the mutation: start pos (199, 30) to end pos (199, 31) in src\GeventLibrary\keywords\gevent_keywords.py. ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (199, 30), end pos: (199, 31) ``` -------------------------------- ### Mutation location for gevent_keywords.py (Job 40) Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Identifies the mutation location in gevent_keywords.py at start position (199, 30) and end position (199, 31). ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (199, 30), end pos: (199, 31) ``` -------------------------------- ### Mutation location for gevent_keywords.py (Job 39) Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Identifies the mutation location in gevent_keywords.py at start position (180, 77) and end position (180, 78). ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (180, 77), end pos: (180, 78) ``` -------------------------------- ### Robot Framework test using GeventLibrary Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/README.md A complete Robot Framework test file that demonstrates creating a gevent bundle, adding coroutines, running them, and asserting on the results. The test uses GeventLibrary, RequestsLibrary, Collections, and String. It shows how to run synchronous keywords asynchronously and retrieve values by order. ```robotframework # simple-test.robot *** Settings *** Library Collections Library String Library GeventLibrary Library RequestsLibrary *** Test Cases *** Test1 [Documentation] Simple test flow with gevent greenlets Log Hello World Create Gevent Bundle alias=alias1 # Create a bundle of coroutines Sleep 10s alias=alias1 # run your synchronous keyword # register all your keywords as coroutines to the gevent bundle Add Coroutine Sleep Wrapper alias=alias1 Add Coroutine Sleep 20s alias=alias1 Add Coroutine Sleep 10s alias=alias1 Add Coroutine GET https://jsonplaceholder.typicode.com/posts/1 alias=alias1 Add Coroutine Convert To Lower Case UPPER # Run your coroutines and get the values by order ${values} Run Coroutines alias=alias1 Log Many @{values} # The 3rd coroutine was a request, take it's value ${jsonplaceholder_resp} Get From List ${values} 3 # assert the returned response code to be 200 Status Should Be 200 ${jsonplaceholder_resp} # assert that the returned `userId` field equals to 1 Should Be Equal As Strings 1 ${jsonplaceholder_resp.json()['userId']} *** Keywords *** Sleep Wrapper Sleep 1s ``` -------------------------------- ### Mutation location in gevent_keywords.py Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Identifies the exact source location of the mutation in gevent_keywords.py, from start position (180, 48) to end position (180, 51). ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (180, 48), end pos: (180, 51) ``` -------------------------------- ### Test run summary output Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Output of a test run showing 13 tests ran in 0.057s with 3 errors. The result is FAILED. ```text ............. ---------------------------------------------------------------------- Ran 13 tests in 0.057s OK ``` -------------------------------- ### Job list entry: source file position Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 18102022.html Identifies the source file and position of the mutation job. The position is given as start and end positions in the file. ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (271, 44), end pos: (271, 46) ``` -------------------------------- ### Mutation Location in gevent_keywords.py Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 07092022.html Identifies the exact source location of the mutation in the file src\GeventLibrary\keywords\gevent_keywords.py, with start position (65, 11) and end position (65, 47). ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (65, 11), end pos: (65, 47) ``` -------------------------------- ### Mutation location in gevent_keywords.py Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 07092022.html Identifies the exact file and position of the mutation: src\GeventLibrary\keywords\gevent_keywords.py, start position (137, 57) to (137, 58). This is the location where the mutation was applied. ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (137, 57), end pos: (137, 58) ``` -------------------------------- ### Handling Timeouts with gevent.Timeout Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/GeventLibrary.html Use gevent.Timeout to limit the execution time of a block of code. The example shows how to raise a timeout exception if the operation takes too long. ```python import gevent from gevent import Timeout with Timeout(2) as timeout: try: gevent.sleep(5) except Timeout: print('Operation timed out') ``` -------------------------------- ### Test run summary output Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 18102022.html This output shows the result of running the test suite. It indicates that 17 tests were run, with 13 errors, and the overall result was FAILED. ```text Ran 17 tests in 0.054s FAILED (errors=13) ``` -------------------------------- ### Mutation location: gevent_keywords.py line 204 Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 18102022.html Specifies the exact source location of the mutation in gevent_keywords.py, with start and end positions at line 204, column 25 to 26. ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (204, 25), end pos: (204, 26) ``` -------------------------------- ### Test output: traceback and summary Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 18102022.html This block shows the output of running the test suite, including a traceback from a failed test and the final test summary. It indicates that 17 tests were run with 1 failure and 3 errors, and the overall result was 'FAILED'. ```text ........Traceback (most recent call last): File "src\\gevent\\greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "C:\Python310\lib\unittest\mock.py", line 1104, in __call__ return self._mock_call(*args, **kwargs) File "C:\Python310\lib\unittest\mock.py", line 1108, in _mock_call return self._execute_mock_call(*args, **kwargs) File "C:\Python310\lib\unittest\mock.py", line 1163, in _execute_mock_call raise effect ValueError: some value error... 2022-10-18T05:30:10Z ('Convert To Integer', '1')> failed with ValueError ......... ---------------------------------------------------------------------- Ran 17 tests in 0.066s OK ``` -------------------------------- ### add_coroutine non-trivial usage Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/GeventKeywords.md Robot Framework example showing add_coroutine with keyword arguments and no alias, using the time_ form to disambiguate from the wrapper's alias argument. ```robotframework Create Gevent Bundle # kwargs of the target keyword are passed through as-is: Add Coroutine Sleep time_=10s Add Coroutine RequestsLibrary.GET https://example.org params=a=1 ${values} Run Coroutines ``` -------------------------------- ### Test execution traceback and summary Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 18102022.html Output from running the test suite, showing a traceback for a failing test and the final test summary. The test run reports 17 tests with 2 errors, and the outcome is 'killed' for the mutation. ```text ........Traceback (most recent call last): File "src\\gevent\\greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "C:\Python310\lib\unittest\mock.py", line 1104, in __call__ return self._mock_call(*args, **kwargs) File "C:\Python310\lib\unittest\mock.py", line 1108, in _mock_call return self._execute_mock_call(*args, **kwargs) File "C:\Python310\lib\unittest\mock.py", line 1163, in _execute_mock_call raise effect ValueError: some value error... 2022-10-18T05:30:16Z ('Convert To Integer', '1')> failed with ValueError ......... ---------------------------------------------------------------------- Ran 17 tests in 0.066s OK ``` -------------------------------- ### Usage as part of a bundle Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/RobotKeywordCoroutine.md Shows constructing a RobotKeywordCoroutine directly and appending it to a bundle registry, then running coroutines and asserting results. ```python from GeventLibrary.keywords import GeventKeywords from GeventLibrary.keywords.gevent_keywords import RobotKeywordCoroutine coros = GeventKeywords() coros.create_gevent_bundle(alias="b") # add_coroutine builds the RobotKeywordCoroutine internally: coros.add_coroutine("Convert To Lower Case", "HELLO", alias="b") # or construct it directly if you manipulate the registry: coros["b"].append(RobotKeywordCoroutine("Convert To Integer", "7")) values = coros.run_coroutines(alias="b") assert values == ["hello", 7] ``` -------------------------------- ### Initialize bundle registry with OrderedDict alias Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/types.md Defines the bundle registry type as a typing.OrderedDict alias and initializes it in GeventKeywords.__init__. The alias expands to typing.OrderedDict[str, List[RobotKeywordCoroutine]] (a collections.OrderedDict). ```python from typing import OrderedDict as od # ... class GeventKeywords: def __init__(self) -> None: self._active_gevent_bundles: od[ str, List[RobotKeywordCoroutine] ] = OrderedDict() ``` -------------------------------- ### Catch NoBundleCreated exception in Python Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/exceptions.md Shows how to catch the custom exceptions in Python. The example imports the exceptions and GeventKeywords, then calls run_coroutines() and catches NoBundleCreated, printing its message. ```python from GeventLibrary.exceptions import ( AliasAlreadyCreated, BundleHasNoCoroutines, NoBundleCreated, ) from GeventLibrary.keywords import GeventKeywords kw = GeventKeywords() try: kw.run_coroutines() except NoBundleCreated as e: print(e) # "Please create a bundle with `Create Gevent Bundle` keyword" ``` -------------------------------- ### Robot Framework usage with thread patching and error handling Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/GeventLibrary.md Usage with patch_threads=True and a timeout for Run Coroutines. Note: the example file uses patch_thread=True (singular) which does not match the constructor parameter patch_threads (plural). ```robotframework *** Settings *** Library GeventLibrary patch_threads=True *** Test Cases *** SSH Workflow Create Gevent Bundle alias=ssh Add Coroutine Sleep 2s alias=ssh ${values} Run Coroutines alias=ssh timeout=60 Log Many @{values} ``` -------------------------------- ### Mutation location: src\GeventLibrary\keywords\gevent_keywords.py (line 133) Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 07092022.html Identifies the exact file and position of the mutation in the source code. The mutation occurs at start position (133, 11) and end position (133, 16), which corresponds to the condition 'alias' being negated. ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (133, 11), end pos: (133, 16) ``` -------------------------------- ### Constructor signature for GeventKeywords Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/GeventKeywords.md Defines the __init__ method of GeventKeywords. It takes no parameters and returns None. The method initializes the internal registry for active gevent bundles. ```python def __init__(self) -> None: ``` -------------------------------- ### Test run output with failure and traceback Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 18102022.html Output from running 17 tests, showing one error in test_run_empty_coroutine_bundle and test_add_coroutine_before_session, with tracebacks and final FAILED (errors=1). ```text ........Traceback (most recent call last): File "src\\gevent\\greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run File "C:\Python310\lib\unittest\mock.py", line 1104, in __call__ return self._mock_call(*args, **kwargs) File "C:\Python310\lib\unittest\mock.py", line 1108, in _mock_call return self._execute_mock_call(*args, **kwargs) File "C:\Python310\lib\unittest\mock.py", line 1163, in _execute_mock_call raise effect ValueError: some value error... 2022-10-18T05:28:39Z ('Convert To Integer', '1')> failed with ValueError .....E... ====================================================================== ERROR: test_run_empty_coroutine_bundle (utests.test_bundle_creation.TestInstanceCreation) When we run a bundle of coroutines, ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\workspace-vscode\robotframework-gevent\utests\test_bundle_creation.py", line 88, in test_run_empty_coroutine_bundle gevent_library_instance.run_coroutines("my_alias") File "C:\workspace-vscode\robotframework-gevent\src\GeventLibrary\keywords\gevent_keywords.py", line 212, in run_coroutines start_keyword_placer = copy(ctx.output.start_keyword) AttributeError: 'NoneType' object has no attribute 'output' ---------------------------------------------------------------------- Ran 17 tests in 0.048s FAILED (errors=1) ``` -------------------------------- ### Mutation location and operator metadata Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 19092022.html Provides the location of the mutation in the source file and the mutation operator used. The location is specified as `src\GeventLibrary\keywords\gevent_keywords.py, start pos: (219, 11), end pos: (219, 31)` and the operator is `core/AddNot` with occurrence 3. ```text src\GeventLibrary\keywords\gevent_keywords.py, start pos: (219, 11), end pos: (219, 31) ``` ```text operator: core/AddNot, occurrence: 3 ``` -------------------------------- ### Robot Framework usage with GeventLibrary Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/_autodocs/api-reference/GeventLibrary.md Basic usage in Robot Framework: import the library, create a bundle, add a coroutine, and run coroutines. ```robotframework *** Settings *** Library GeventLibrary *** Test Cases *** Async Keywords Create Gevent Bundle alias=alias1 Add Coroutine Sleep 1s alias=alias1 ${values} Run Coroutines alias=alias1 ``` -------------------------------- ### Test output with success Source: https://github.com/eldaduzman/robotframework-gevent/blob/main/docs/mutation-testing/MutationTesting - 07092022.html Output from running the test suite after the mutation, showing all tests passing (10 tests in 0.075s, OK). ```text .......... ---------------------------------------------------------------------- Ran 10 tests in 0.075s OK ```