├── examples ├── some-libs │ ├── __init__.py │ └── mylib │ │ └── mypy.py ├── some-package │ ├── __init__.py │ ├── libs │ │ └── package_lib.py │ ├── resources │ │ └── sample.resource │ └── pyproject.toml ├── some-resources │ ├── SUT Y │ │ ├── Common.robot │ │ ├── .libtoc │ │ └── SettingsMenu.robot │ └── SUT X │ │ ├── robotframework │ │ ├── Common.robot │ │ └── LoginPage.robot │ │ └── python │ │ └── NavigationMenu.py ├── generate_docs.sh └── .libtoc ├── robotframework_libtoc ├── __init__.py ├── homepage_template.html ├── toc_template.html └── libtoc.py ├── Screenshot.png ├── pyproject.toml ├── poetry.lock ├── .gitignore ├── README.md └── LICENSE /examples/some-libs/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/some-package/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /robotframework_libtoc/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/some-package/libs/package_lib.py: -------------------------------------------------------------------------------- 1 | def keyword_inside_package_lib(): 2 | pass -------------------------------------------------------------------------------- /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amochin/robotframework-libtoc/HEAD/Screenshot.png -------------------------------------------------------------------------------- /examples/some-resources/SUT Y/Common.robot: -------------------------------------------------------------------------------- 1 | *** Keywords *** 2 | Start SUT Y 3 | [Documentation] Launches the SUT Y 4 | No Operation -------------------------------------------------------------------------------- /examples/generate_docs.sh: -------------------------------------------------------------------------------- 1 | # Run this script from the 'examples' folder.. 2 | # .. or adjust the paths if running from another dir 3 | libtoc -P . . -------------------------------------------------------------------------------- /examples/some-resources/SUT Y/.libtoc: -------------------------------------------------------------------------------- 1 | [paths] 2 | # Use glob patterns 3 | **/*.robot 4 | **/*.resource 5 | **/*.py 6 | 7 | [libs] 8 | # Use RF library names with params - like for libdoc -------------------------------------------------------------------------------- /examples/some-libs/mylib/mypy.py: -------------------------------------------------------------------------------- 1 | def my_python_keyword(): 2 | """ 3 | This keyword is imported using a Python fully qualified name - 4 | see that setting the PYTHONPATH works 5 | """ 6 | pass -------------------------------------------------------------------------------- /examples/some-package/resources/sample.resource: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation This is an example resource file inside of an installable package. 3 | ... The package must be installed / available in the PYTHONPATH 4 | 5 | 6 | *** Keywords *** 7 | Start Sample Package Application 8 | No Operation -------------------------------------------------------------------------------- /robotframework_libtoc/homepage_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |8 | Please select a library in the navigation sidebar 9 |
10 |11 | Created: 12 | 13 | {0} 14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /examples/some-package/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "some-package" 3 | version = "0.0.1" 4 | description = "This is just an example package to demonstrate the package loading feature of libtoc" 5 | authors = [] 6 | packages = [{include = "example_package", from = "src"}] 7 | 8 | [tool.poetry.dependencies] 9 | python = ">=3.7" 10 | robotframework = ">=4" 11 | 12 | 13 | [build-system] 14 | requires = ["poetry-core"] 15 | build-backend = "poetry.core.masonry.api" 16 | -------------------------------------------------------------------------------- /examples/.libtoc: -------------------------------------------------------------------------------- 1 | [paths] 2 | # Use glob patterns 3 | some-resources/**/*.robot 4 | some-resources/**/*.resource 5 | some-resources/**/*.py 6 | 7 | [libs] 8 | # Use RF library names with params - like for libdoc 9 | # SeleniumLibrary 10 | # Remote::http://10.0.0.42:8270 11 | # Import a library from PYTHONPATH using fully qualified name 12 | some-libs.mylib.mypy 13 | # You can use environment variables in lib params 14 | # SomeLib::$some_env_var/somepath 15 | 16 | [packages] 17 | # Use package name in python path and glob pattern separated by : 18 | some-package:resources/**/*.resource 19 | some-package:libs/**/*.py -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "robotframework-libtoc" 3 | version = "1.4.2" 4 | description = "Docs and TOC generator for Robot Framework resources and libs" 5 | authors = ["Andre Mochinin"] 6 | license = "Apache-2.0" 7 | readme = "README.md" 8 | homepage = "https://github.com/amochin/robotframework-libtoc" 9 | include = ["robotframework_libtoc/*template.html"] 10 | 11 | [tool.poetry.dependencies] 12 | python = ">=3.7" 13 | robotframework = ">=4" 14 | importlib-resources = "~5.12" 15 | 16 | [tool.poetry.scripts] 17 | libtoc = "robotframework_libtoc.libtoc:main" 18 | 19 | [tool.poetry.dev-dependencies] 20 | 21 | [build-system] 22 | requires = ["poetry-core>=1.0.0"] 23 | build-backend = "poetry.core.masonry.api" 24 | -------------------------------------------------------------------------------- /examples/some-resources/SUT X/robotframework/Common.robot: -------------------------------------------------------------------------------- 1 | *** Keywords *** 2 | Start Firefox with no proxy 3 | [Arguments] ${URL} 4 | ${proxy}= Evaluate sys.modules['selenium.webdriver'].Proxy() sys, selenium.webdriver 5 | ${direct}= Evaluate sys.modules['selenium.webdriver'].common.proxy.ProxyType.DIRECT sys, selenium.webdriver 6 | ${proxy.proxyType}= Set Variable ${direct} 7 | ${caps}= Evaluate sys.modules['selenium.webdriver'].DesiredCapabilities.FIREFOX sys, selenium.webdriver 8 | Evaluate $proxy.add_to_capabilities($caps) 9 | Open Browser ${URL} Firefox 10 | 11 | Open SUT X in Browser 12 | [Documentation] Starts the browser und opens the SUT X start page 13 | No Operation -------------------------------------------------------------------------------- /examples/some-resources/SUT X/robotframework/LoginPage.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource Common.robot 3 | 4 | *** Variables *** 5 | 6 | # Locators 7 | ${LoginDummy URL} /login 8 | ${Login Button} //button[text()='Login'] 9 | 10 | *** Keywords *** 11 | 12 | Open 13 | [Documentation] Navigates to the 'Login' page and waits for the 'Login' button to appear 14 | ... 15 | ... _Parameters_: 16 | ... - *Base_URL* - Base address of the SUT X app incl. prefix und port number 17 | [Arguments] ${Base_URL} 18 | 19 | Go To ${Base_URL}${LoginDummy URL} 20 | Wait Until Page Contains Element ${Login Button} 21 | 22 | Click Login 23 | [Documentation] Clicks the 'Login' button 24 | Click Element ${Login Button} -------------------------------------------------------------------------------- /examples/some-resources/SUT Y/SettingsMenu.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource Common.robot 3 | 4 | *** Variables *** 5 | 6 | # Locators 7 | ${Settings Page URL} /settings 8 | ${Save Button} //button[text()='Save'] 9 | 10 | *** Keywords *** 11 | 12 | Navigate 13 | [Documentation] Navigates to the Settings pages and waits for the "Save" button to appear 14 | ... 15 | ... _Parameters_: 16 | ... - *Base_URL* - Base URL of the SUT Y app including prefix und port number 17 | [Arguments] ${Base_URL} 18 | 19 | Go To ${Base_URL}${Settings Page URL} 20 | Wait Until Page Contains Element ${Save Button} 21 | 22 | Click Save 23 | [Documentation] Clicks the 'Save' button 24 | Click Element ${Save Button} -------------------------------------------------------------------------------- /examples/some-resources/SUT X/python/NavigationMenu.py: -------------------------------------------------------------------------------- 1 | from robot.libraries.BuiltIn import BuiltIn 2 | 3 | PAGE_TITLE = 'Some title' 4 | 5 | 6 | def _s(): 7 | return BuiltIn().get_library_instance('SeleniumLibrary') 8 | 9 | locators = { 10 | "some_element": "//label[contains(text(), 'Blahblah')]/../..//input", 11 | } 12 | 13 | # ------ RF keywords ----------------------- 14 | 15 | 16 | def wait_page_loaded(timeout): 17 | """ 18 | Waits for the page to load (meaning the element XYZ is visible), maximum the specified timeout. 19 | If the element is still not visible after timeout, an error is reported. 20 | 21 | _Parameters:_ 22 | - *timeout* - Max. time to wait 23 | """ 24 | _s().wait_until_page_contains_element(locators["some_element"], timeout=timeout) -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. 2 | 3 | [[package]] 4 | name = "importlib-resources" 5 | version = "5.12.0" 6 | description = "Read resources from Python packages" 7 | optional = false 8 | python-versions = ">=3.7" 9 | files = [ 10 | {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, 11 | {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, 12 | ] 13 | 14 | [package.dependencies] 15 | zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} 16 | 17 | [package.extras] 18 | docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] 19 | testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] 20 | 21 | [[package]] 22 | name = "robotframework" 23 | version = "6.1.1" 24 | description = "Generic automation framework for acceptance testing and robotic process automation (RPA)" 25 | optional = false 26 | python-versions = ">=3.6" 27 | files = [ 28 | {file = "robotframework-6.1.1-py3-none-any.whl", hash = "sha256:ee0d512d557e72ed760dd075525f6226baaab309010a48f9c9bf1f416ca434f7"}, 29 | {file = "robotframework-6.1.1.zip", hash = "sha256:3fa18f2596a4df2418c4b59abf43248327c15ed38ad8665f6a9a9c75c95d7789"}, 30 | ] 31 | 32 | [[package]] 33 | name = "zipp" 34 | version = "3.15.0" 35 | description = "Backport of pathlib-compatible object wrapper for zip files" 36 | optional = false 37 | python-versions = ">=3.7" 38 | files = [ 39 | {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, 40 | {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, 41 | ] 42 | 43 | [package.extras] 44 | docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] 45 | testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] 46 | 47 | [metadata] 48 | lock-version = "2.0" 49 | python-versions = ">=3.7" 50 | content-hash = "a67b7ce05acdcdffea591b182e7cc41c0f29a662a44bbdf011f620c6b99bd878" 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created docs except templates 2 | **/*.html 3 | !**/*template.html 4 | 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | pip-wheel-metadata/ 28 | share/python-wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 99 | __pypackages__/ 100 | 101 | # Celery stuff 102 | celerybeat-schedule 103 | celerybeat.pid 104 | 105 | # SageMath parsed files 106 | *.sage.py 107 | 108 | # Environments 109 | .env 110 | .venv 111 | env/ 112 | venv/ 113 | ENV/ 114 | env.bak/ 115 | venv.bak/ 116 | 117 | # Spyder project settings 118 | .spyderproject 119 | .spyproject 120 | 121 | # Rope project settings 122 | .ropeproject 123 | 124 | # mkdocs documentation 125 | /site 126 | 127 | # mypy 128 | .mypy_cache/ 129 | .dmypy.json 130 | dmypy.json 131 | 132 | # Pyre type checker 133 | .pyre/ 134 | .DS_Store 135 | -------------------------------------------------------------------------------- /robotframework_libtoc/toc_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | 25 |