## qecore - Library of tools
[![Build Status](https://img.shields.io/gitlab/pipeline/dogtail/qecore)](https://gitlab.com/dogtail/qecore/-/pipelines) [![PyPI Version](https://img.shields.io/pypi/v/qecore)](https://pypi.org/project/qecore/)
Qecore is a Library of Tools designed to complement our automation stack with all that is required.
## Usage
### The `qecore-headless` script.
- The name `headless` in the name is historical, it is a session configuration script that runs our automation stack.
- This script provides a way to start a new session in ssh connected machine.
- It serves only for remote usage, using it locally will not end well. It is designed for fast GDM start and stop with user autologin.
- This script will start GDM and make a few changes to the system to enable start of an automation suite in wanted configuration, for example:
- `qecore-headless "behave -kt automated_test"` - This script takes an argument of a script to run.
- In this case we run `automated_test` via behave. Bash is the default - in bash we can start behave on our own.
- `qecore-headless --session-type xorg` - Start X11 session.
- `qecore-headless --session-type wayland` - Start Wayland session.
- `qecore-headless --session-desktop gnome` - Change desktop to GNOME.
- `qecore-headless --session-desktop gnome-classic` - Change desktop to GNOME Classic.
- `qecore-headless --display` - Set a DISPLAY number for the session, default is `:0`.
- `qecore-headless --dont-start` - Do not start GDM.
- `qecore-headless --dont-kill` - Do not kill GDM.
- `qecore-headless --restart` - Restart running GDM
- `qecore-headless --keep X` - Keep GDM alive for X tests, restart it after.
- `qecore-headless --keep-max` - Keep GDM alive for as long as possible when testing - restart on test fail.
- `qecore-headless --force` - Force will check configuration match and fails if for example X11 is started instead of Wayland.
- `qecore-headless --debug` - Sets environment variable for dogtail, upon which dogtail will be logged.
- `qecore-headless --no-color` - No colors for headless output.
- `qecore-headless --virtual-monitors X` - Experimental option to enable virtual monitors for multi-monitor setup testing.
- `qecore-headless --help` - for more information.
You can of course combine any of these together, if it makes sense.
### Usage with `behave`.
The `behave` expected structure is very simple, we adjust it a bit for better readability:
```
features
├── environment.py
├── scenarios
| └── main.feature
└── steps
└── steps.py
```
The main file that `qecore` interacts with is `environment.py`.
#### `behave` has a few hooks that we can use to start our automation stack - lets look at `before_all`
```python
from qecore.sandbox import TestSandbox
def before_all(context) -> None:
"""
This function will be run once in every 'behave' command called.
"""
# This is the most important part, initiation of TestSandbox.
# Most of the setup happens in this class.
context.sandbox = TestSandbox("gnome-terminal", context=context)
# To define an application for testing, use `get_application` from sandbox.
# If application is not installed as rpm but as a flatpak user can use `get_flatpak`
# Attention: Do not define gnome-shell as an application.
# The gnome-shell accessibility tree is available for you in `context.sandbox.shell`
context.terminal = context.sandbox.get_application(
name="gnome-terminal",
a11y_app_name="gnome-terminal-server",
desktop_file_name="org.gnome.Terminal.desktop",
)
# To modify the application with some functionality or work around some issues.
# Most of the time no changes should be needed.
context.terminal.exit_shortcut = "<Ctrl><Shift><Q>"
```
#### Let's look at `before_scenario` next.
The `before_scenario` will take care of every setup we need, to modify the execution, change the [TestSandbox attributes](https://dogtail.gitlab.io/qecore/_modules/sandbox.html#TestSandbox.__init__) after initiating the class.
All the attributes are set to values that were proven over the years of development. Some corner cases always exist though, so everything is customizable/hackable to enable a large variety of options.
```python
def before_scenario(context, scenario) -> None:
"""
This function will be run before every scenario in 'behave' command called.
"""
context.sandbox.before_scenario(context, scenario)
```
To see everything it does, you can look at [before_scenario](https://dogtail.gitlab.io/qecore/_modules/sandbox.html#TestSandbox.before_scenario) implementation in documentation page.
#### And a final part `after_scenario`.
The `after_scenario` will take care of teardown. It will take care of anything that was set in `before_scenario` like stopping videos, fetching logs for our reports, uploading data to our HTML logs and closing any application started so that the session is cleared for the next test.
```python
def after_scenario(context, scenario) -> None:
"""
This function will be run after every scenario in 'behave' command called.
"""
context.sandbox.after_scenario(context, scenario)
```
To see everything it does, you can look at [after_scenario](https://dogtail.gitlab.io/qecore/_modules/sandbox.html#TestSandbox.after_scenario) implementation in documentation page.
In the [full example](https://gitlab.com/dogtail/qecore/-/blob/master/templates/environment.py) you can also see try/except usage. That is for recovery. Some issues can be fixed while running. We also need a way to end gracefully so that our data is loaded to the HTML page and not thrown away in case of a problem.
#### Working in `steps.py`.
After the setup in `environment.py` we can now start working on our automation in `steps.py`
The setup is important for two reasons.
- Now the test has all machine setup available through the sandbox, so they can query attributes or use sandbox methods that are very useful for testing.
- `context.sandbox.<attribute>`
- `context.sandbox.<method>`
- Users now do not have to start the applications and load accessibility tree to use, as they were defined in `environment.py`
- In `main.feature` users can now use for example `* Start application "terminal" via "command"`
- Application will start.
- Load its accessibility tree.
- Mark the application for cleanup after the test.
- In `steps.py` users now have `context.terminal.instance` which is accessibility tree root of `gnome-terminal-server` so any `dogtail` query to `Atspi` will now work and automation can begin.
## Environment variables.
There is a lot of options we have to modify our runs without the need to change python code.
- `RICH_TRACEBACK=true behave...` - to enable rich Traceback for debugging of issues.
- `AUTORETRY=X behave...` - give an automation test X tries to pass before it is marked as a FAIL.
- This option is also available as a `tag` in feature files `@autoretry=X`
- `STABILITY=X behave...` - run an automation test X times and every try has to pass for it to be marked as a PASS.
- This option is also available as a `tag` in feature files `@stability=X`
- `QECORE_EMBED_ALL=true behave...` - all available data is embedded even if the suite PASSED (We do not embed on PASS by default).
- `QECORE_NO_CACHE=true behave...` - do not keep cache and regenerate files.
- `LOGGING=true behave...` - enables logging, this is a very verbose log about `qecore` execution.
- `PRODUCTION=false behave...` - disables all embedding, video recording, screenshot capture.
- `BACKTRACE=true behave...` - enables backtrace fetching from coredumpctl list.
You are able to use multiple variables, if the combination makes sense, together.
## Hacking.
From everything that I showed here, everything is customizable to some degree.
I implemented most the methods in a way that changing how they operate is done easily from `environment.py`
In case you need some specific change, look through the code and you should be able to identify what needs to be done (everything is in one place really, `sandbox`, `before_scenario`, `after_scenario`, that's it, everything else is called from there)
## This project was featured in Fedora Magazine:
- https://fedoramagazine.org/automation-through-accessibility/
- Full technical solution of our team's (Red Hat DesktopQE) automation stack https://modehnal.github.io/
### Execute unit tests
NOTE: This need to be updated for Fedora 40 and newer and RHEL-10 and newer.
Execute the tests (from the project root directory) on machine with dogtail:
```bash
rm -f /tmp/qecore_version_status.txt
rm -f dist/*.whl
python3 -m build
python3 -m pip install --force-reinstall --upgrade dist/qecore*.whl
sudo -u test scripts/qecore-headless "behave -f html-pretty -o /tmp/report_qecore.html -f plain tests/features"
```
You can use `-f pretty` instead of `-f plain` to get colored output.
The standard output should not contain any python traceback, produced HTML should be complete (after first scenario there is `Status`).
Raw data
{
"_id": null,
"home_page": "https://gitlab.com/dogtail/qecore",
"name": "qecore",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": null,
"author": "Michal Odehnal",
"author_email": "modehnal@redhat.com",
"download_url": "https://files.pythonhosted.org/packages/a6/8b/269e4219b1ea8548891b04d2b5bca73d9144ee4f7732a3a2c9790f2bfcc7/qecore-3.29.2.tar.gz",
"platform": null,
"description": "## qecore - Library of tools\n\n[![Build Status](https://img.shields.io/gitlab/pipeline/dogtail/qecore)](https://gitlab.com/dogtail/qecore/-/pipelines) [![PyPI Version](https://img.shields.io/pypi/v/qecore)](https://pypi.org/project/qecore/)\n\nQecore is a Library of Tools designed to complement our automation stack with all that is required.\n\n## Usage\n### The `qecore-headless` script.\n- The name `headless` in the name is historical, it is a session configuration script that runs our automation stack.\n- This script provides a way to start a new session in ssh connected machine.\n- It serves only for remote usage, using it locally will not end well. It is designed for fast GDM start and stop with user autologin.\n- This script will start GDM and make a few changes to the system to enable start of an automation suite in wanted configuration, for example:\n - `qecore-headless \"behave -kt automated_test\"` - This script takes an argument of a script to run.\n - In this case we run `automated_test` via behave. Bash is the default - in bash we can start behave on our own.\n - `qecore-headless --session-type xorg` - Start X11 session.\n - `qecore-headless --session-type wayland` - Start Wayland session.\n - `qecore-headless --session-desktop gnome` - Change desktop to GNOME.\n - `qecore-headless --session-desktop gnome-classic` - Change desktop to GNOME Classic.\n - `qecore-headless --display` - Set a DISPLAY number for the session, default is `:0`.\n - `qecore-headless --dont-start` - Do not start GDM.\n - `qecore-headless --dont-kill` - Do not kill GDM.\n - `qecore-headless --restart` - Restart running GDM\n - `qecore-headless --keep X` - Keep GDM alive for X tests, restart it after.\n - `qecore-headless --keep-max` - Keep GDM alive for as long as possible when testing - restart on test fail.\n - `qecore-headless --force` - Force will check configuration match and fails if for example X11 is started instead of Wayland.\n - `qecore-headless --debug` - Sets environment variable for dogtail, upon which dogtail will be logged.\n - `qecore-headless --no-color` - No colors for headless output.\n - `qecore-headless --virtual-monitors X` - Experimental option to enable virtual monitors for multi-monitor setup testing.\n - `qecore-headless --help` - for more information.\n\nYou can of course combine any of these together, if it makes sense.\n\n### Usage with `behave`.\n\nThe `behave` expected structure is very simple, we adjust it a bit for better readability:\n```\nfeatures\n\u251c\u2500\u2500 environment.py\n\u251c\u2500\u2500 scenarios\n| \u2514\u2500\u2500 main.feature\n\u2514\u2500\u2500 steps\n \u2514\u2500\u2500 steps.py\n```\n\nThe main file that `qecore` interacts with is `environment.py`.\n#### `behave` has a few hooks that we can use to start our automation stack - lets look at `before_all`\n\n\n```python\nfrom qecore.sandbox import TestSandbox\n\ndef before_all(context) -> None:\n \"\"\"\n This function will be run once in every 'behave' command called.\n \"\"\"\n\n # This is the most important part, initiation of TestSandbox.\n # Most of the setup happens in this class.\n context.sandbox = TestSandbox(\"gnome-terminal\", context=context)\n\n # To define an application for testing, use `get_application` from sandbox.\n # If application is not installed as rpm but as a flatpak user can use `get_flatpak`\n # Attention: Do not define gnome-shell as an application.\n # The gnome-shell accessibility tree is available for you in `context.sandbox.shell`\n context.terminal = context.sandbox.get_application(\n name=\"gnome-terminal\",\n a11y_app_name=\"gnome-terminal-server\",\n desktop_file_name=\"org.gnome.Terminal.desktop\",\n )\n # To modify the application with some functionality or work around some issues.\n # Most of the time no changes should be needed.\n context.terminal.exit_shortcut = \"<Ctrl><Shift><Q>\"\n```\n\n#### Let's look at `before_scenario` next.\n\nThe `before_scenario` will take care of every setup we need, to modify the execution, change the [TestSandbox attributes](https://dogtail.gitlab.io/qecore/_modules/sandbox.html#TestSandbox.__init__) after initiating the class.\n\nAll the attributes are set to values that were proven over the years of development. Some corner cases always exist though, so everything is customizable/hackable to enable a large variety of options.\n\n```python\ndef before_scenario(context, scenario) -> None:\n \"\"\"\n This function will be run before every scenario in 'behave' command called.\n \"\"\"\n context.sandbox.before_scenario(context, scenario)\n```\n\nTo see everything it does, you can look at [before_scenario](https://dogtail.gitlab.io/qecore/_modules/sandbox.html#TestSandbox.before_scenario) implementation in documentation page.\n\n#### And a final part `after_scenario`.\n\nThe `after_scenario` will take care of teardown. It will take care of anything that was set in `before_scenario` like stopping videos, fetching logs for our reports, uploading data to our HTML logs and closing any application started so that the session is cleared for the next test.\n\n```python\ndef after_scenario(context, scenario) -> None:\n \"\"\"\n This function will be run after every scenario in 'behave' command called.\n \"\"\"\n context.sandbox.after_scenario(context, scenario)\n```\n\nTo see everything it does, you can look at [after_scenario](https://dogtail.gitlab.io/qecore/_modules/sandbox.html#TestSandbox.after_scenario) implementation in documentation page.\n\nIn the [full example](https://gitlab.com/dogtail/qecore/-/blob/master/templates/environment.py) you can also see try/except usage. That is for recovery. Some issues can be fixed while running. We also need a way to end gracefully so that our data is loaded to the HTML page and not thrown away in case of a problem.\n\n\n#### Working in `steps.py`.\n\nAfter the setup in `environment.py` we can now start working on our automation in `steps.py`\n\nThe setup is important for two reasons.\n- Now the test has all machine setup available through the sandbox, so they can query attributes or use sandbox methods that are very useful for testing.\n - `context.sandbox.<attribute>`\n - `context.sandbox.<method>`\n- Users now do not have to start the applications and load accessibility tree to use, as they were defined in `environment.py`\n - In `main.feature` users can now use for example `* Start application \"terminal\" via \"command\"`\n - Application will start.\n - Load its accessibility tree.\n - Mark the application for cleanup after the test.\n - In `steps.py` users now have `context.terminal.instance` which is accessibility tree root of `gnome-terminal-server` so any `dogtail` query to `Atspi` will now work and automation can begin.\n\n\n## Environment variables.\n\nThere is a lot of options we have to modify our runs without the need to change python code.\n\n- `RICH_TRACEBACK=true behave...` - to enable rich Traceback for debugging of issues.\n- `AUTORETRY=X behave...` - give an automation test X tries to pass before it is marked as a FAIL.\n - This option is also available as a `tag` in feature files `@autoretry=X`\n- `STABILITY=X behave...` - run an automation test X times and every try has to pass for it to be marked as a PASS.\n - This option is also available as a `tag` in feature files `@stability=X`\n- `QECORE_EMBED_ALL=true behave...` - all available data is embedded even if the suite PASSED (We do not embed on PASS by default).\n- `QECORE_NO_CACHE=true behave...` - do not keep cache and regenerate files.\n- `LOGGING=true behave...` - enables logging, this is a very verbose log about `qecore` execution.\n- `PRODUCTION=false behave...` - disables all embedding, video recording, screenshot capture.\n- `BACKTRACE=true behave...` - enables backtrace fetching from coredumpctl list.\n\nYou are able to use multiple variables, if the combination makes sense, together.\n\n## Hacking.\n\nFrom everything that I showed here, everything is customizable to some degree.\n\nI implemented most the methods in a way that changing how they operate is done easily from `environment.py`\n\nIn case you need some specific change, look through the code and you should be able to identify what needs to be done (everything is in one place really, `sandbox`, `before_scenario`, `after_scenario`, that's it, everything else is called from there)\n\n\n## This project was featured in Fedora Magazine:\n - https://fedoramagazine.org/automation-through-accessibility/\n - Full technical solution of our team's (Red Hat DesktopQE) automation stack https://modehnal.github.io/\n\n\n### Execute unit tests\n\nNOTE: This need to be updated for Fedora 40 and newer and RHEL-10 and newer.\n\nExecute the tests (from the project root directory) on machine with dogtail:\n\n```bash\nrm -f /tmp/qecore_version_status.txt\nrm -f dist/*.whl\npython3 -m build\npython3 -m pip install --force-reinstall --upgrade dist/qecore*.whl\nsudo -u test scripts/qecore-headless \"behave -f html-pretty -o /tmp/report_qecore.html -f plain tests/features\"\n```\n\nYou can use `-f pretty` instead of `-f plain` to get colored output.\n\nThe standard output should not contain any python traceback, produced HTML should be complete (after first scenario there is `Status`).\n",
"bugtrack_url": null,
"license": "GPLv3",
"summary": "DesktopQE Tool for unified test execution",
"version": "3.29.2",
"project_urls": {
"Homepage": "https://gitlab.com/dogtail/qecore"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a179956422f732ad55d1e6ad215d616328dfd7465e5f3be5f79b705d1be5a894",
"md5": "c55a14215eebab72a9835e930b1529f5",
"sha256": "158d4de07a6885ed4a12ac13d90f027c658d2883d10d2fe0cdc45852e8b2121a"
},
"downloads": -1,
"filename": "qecore-3.29.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c55a14215eebab72a9835e930b1529f5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 115945,
"upload_time": "2024-12-06T14:21:55",
"upload_time_iso_8601": "2024-12-06T14:21:55.319095Z",
"url": "https://files.pythonhosted.org/packages/a1/79/956422f732ad55d1e6ad215d616328dfd7465e5f3be5f79b705d1be5a894/qecore-3.29.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a68b269e4219b1ea8548891b04d2b5bca73d9144ee4f7732a3a2c9790f2bfcc7",
"md5": "0e097dc99e2cdc7ab0f8470c2b772d5f",
"sha256": "af5b1a1def88b400c4633b65dd7f58dc05502a6ded0caf0b0b2f6d47d0b1ac41"
},
"downloads": -1,
"filename": "qecore-3.29.2.tar.gz",
"has_sig": false,
"md5_digest": "0e097dc99e2cdc7ab0f8470c2b772d5f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 110262,
"upload_time": "2024-12-06T14:21:57",
"upload_time_iso_8601": "2024-12-06T14:21:57.720576Z",
"url": "https://files.pythonhosted.org/packages/a6/8b/269e4219b1ea8548891b04d2b5bca73d9144ee4f7732a3a2c9790f2bfcc7/qecore-3.29.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-06 14:21:57",
"github": false,
"gitlab": true,
"bitbucket": false,
"codeberg": false,
"gitlab_user": "dogtail",
"gitlab_project": "qecore",
"lcname": "qecore"
}