{ "info": { "author": "Mathieu Virbel", "author_email": "mat@meltingrocks.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: End Users/Desktop", "Intended Audience :: Information Technology", "Intended Audience :: Science/Research", "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", "Operating System :: MacOS", "Operating System :: POSIX", "Operating System :: Unix", "Programming Language :: Python", "Programming Language :: Python :: 2", "Topic :: Internet", "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Monitoring", "Topic :: System :: Systems Administration" ], "description": "# Telenium\n\nTelenium provide a framework to remote tests or control Kivy-based application:\n\n- Selector support using XPATH-like syntax (`//BoxLayout[0]/Button[@text~=\"Close\"]`)\n- Create selector by touching the UI\n- Query or set attribute on any widgets\n- Execute remote code\n- `unittests` support\n- Integrate as a Kivy modules\n- Web IDE\n- Python 2 and 3 (since version 0.4, using json-rpc)\n\n![Telenium IDE](https://cloud.githubusercontent.com/assets/37904/22790912/f44b8166-eee7-11e6-9a78-120f78bde220.png)\n\n![Telenium IDE export](https://cloud.githubusercontent.com/assets/37904/22791059/70fb6988-eee8-11e6-91f4-0b87af33b5b6.png)\n\n# Installation\n\n```\npip install telenium\n```\n\n# Run the Telenium IDE\n\nIt will start a webserver on http://127.0.0.1:8080/ and automatically open a new\ntab in your favorite webbrowser. You'll be able to configure where your main.py\nis, and start writing tests directly:\n\n```\ntelenium\n```\n\nYou can also edit telenium-json:\n\n```\ntelenium tests/test-ui-myfeature.json\n```\n\n# Run the application with telenium module\n\nIf you don't use the IDE, in order to remote control your application,\nyou need the Telenium client installed within your application.\n\n## Method 1: Run your application with telenium client\n\nTelenium can execute your application and manually add telenium_client to it.\nJust do:\n\n```python\npython -m telenium.execute main.py\n```\n\n## Method 2: Add telenium_client as a Kivy modules into your application\n\nJust copy/paste `mods/telenium_client.py` in your application, then before\nrunning your application, initialize it:\n\n```python\nfrom os.path import dirname\nfrom kivy.modules import Modules\nfrom kivy.config import Config\nModules.add_path(dirname(__file__))\nConfig.set(\"modules\", \"telenium_client\", \"\")\n```\n\nYou also need to add `python-jsonrpc` in your dependencies (`pip install python-jsonrpc`)\n\n# Connect to a telenium-ready application\n\nWe have a command line client to play with. After the application is started,\nyou can connect with::\n\n $ python -m telenium.client localhost\n\nThen play with it. `cli` is the telenium client where you can invoke remote\ncommands. See the `Telenium commands` to see what you can do:\n\n```python\n>>> id = cli.pick() # then click somewhere on the UI\n>>> cli.click_at(id)\nTrue\n>>> cli.setattr(\"//Label\", \"color\", (0, 1, 0, 1))\nTrue\n```\n\nIf a command returns True, it means it has been successful, otherwise it\nreturns None.\n\n# Create unit tests\n\nTelenium have a module you can use that ease unit tests: it launch the app\nand execute tests. For now, it has been tested and coded to work only\nlocally using subprocess.\n\nAdditionnal methods:\n- `assertExists(selector, timeout=-1)` and\n `assertNotExists(selector, timeout=-1)` to check if a selector exists or not\n in the app. They both have a `timeout` parameter that, if it reach, will fail\n the test.\n- `cli.wait_click(selector, timeout=-1)`: easy way to wait a selector to match,\n then click on the first widget.\n\nHere is a real example that launch an app (default is \"main.py\"):\n\n- It first go in the menu to click where it need to save a CSV (`SaveButton`, `CascadeSaveButton` then `SaveCSVButton`)\n- Then wait at maximum 2s the popup to show with a label \"Export to CSV\"\n- Then click on the \"Close\" button in the popup\n- Then ensure the popup is closed by checking the label is gone.\n\nExample:\n\n```python\nfrom telenium.tests import TeleniumTestCase\n\nclass UITestCase(TeleniumTestCase):\n cmd_entrypoint = [\"main.py\"]\n\n def test_export_csv(self):\n self.cli.wait_click(\"//SaveButton\")\n self.cli.wait_click(\"//CascadeSaveButton\")\n self.cli.wait_click(\"//SaveCSVButton\")\n self.assertExists(\"//Label[@text~=\\\"Export to CSV\\\"]\", timeout=2)\n self.cli.wait_click(\"//FitButton[@text=\\\"Close\\\"]\", timeout=2)\n self.assertNotExists(\"//Label[@text~=\\\"Export to CSV\\\"]\", timeout=2)\n```\n\nEach new TeleniumTestCase will close and start the application, so you always\nrun from a clean app. If you always need to do something before starting the\ntest, you can overload the `init`. This will be executed once before any\ntests in the class starts:\n\n```python\nclass UITestCase(TeleniumTestCase):\n def init(self):\n self.cli.wait_click(\"//PresetSelectionItem[@text!~=\\\"ttyUSB0 on mintel\\\"]\",\n timeout=10)\n self.cli.wait_click(\"//Button[@text=\\\"Connect\\\"]\")\n self.cli.wait(\"//BottomLabel[@text=\\\"Done\\\"]\", timeout=10)\n```\n\nYou can also change few parameters to change/add things in your application for\nunit testing if needed:\n\n```python\nclass UITestCase(TeleniumTestCase):\n process_start_timeout = 5\n cmd_env = {\"I_AM_RUNNING_TEST\": 1}\n```\n\n# Telenium commands\n\n## `version()` (API v1)\n\nReturn the current API version. You can use it to know which methods are\navailable.\n\n```python\n>>> cli.version()\n1\n```\n\n## `select(selector)` (API v1)\n\nReturn unique selectors for all widgets that matches the `selector`.\n\n```python\n>>> cli.select(\"//Label\")\n[u\"/WindowSDL/GridLayout/Label[0]\", u\"/WindowSDL/GridLayout/Label[1]\"]\n```\n\n## `getattr(selector, key)` (API v1)\n\nReturn the value of an attribute on the first widget found by the `selector`.\n\n```python\n>>> cli.getattr(\"//Label\", \"text\")\nu\"Hello world\"\n```\n\n## `setattr(selector, key, value)` (API v1)\n\nSet an attribute named by `key` to `value` for all widgets that matches the\n`selector`.\n\n```python\n>>> cli.setattr(\"//Label\", \"text\", \"Plop\")\nTrue\n```\n\n## `element(selector)` (API v1)\n\nReturn `True` if at least one widget match the `selector`.\n\n```python\n>>> cli.element(\"//Label\")\nTrue\n>>> cli.element(\"//InvalidButton\")\nFalse\n```\n\n## `execute(code)` (API v1)\n\nExecute python code in the application. Only the \"app\" symbol that point to the\ncurrent running application is available. Return True if the code executed, or\nFalse if the code failed. Exception will be print withing the application logs.\n\n```python\n>>> cli.execute(\"app.call_one_app_method\")\nTrue\n```\n\n## `pick(all=False)` (API v1)\n\nReturn either the first widget selector you touch on the screen (`all=False`,\nthe default), either it return the list of all the wigdets that are traversed\nwhere you touch the screen.\n\n```python\n>>> cli.pick()\nu'/WindowSDL/Button[0]'\n>>> cli.pick(all=True)\n[u'/WindowSDL/Button[0]',u'/WindowSDL']\n```\n\n## `click_on(selector)` (API v1)\n\nSimulate a touch down/up on the first widget that match the `selector`. Return\nTrue if it worked.\n\n```python\n>>> cli.click_on(\"//Button[0]\")\nTrue\n```\n\n# Telenium selector syntax (XPATH)\n\nCheat sheet about telenium XPATH-based selector implementation.\n\n- Select any widget that match the widget class in the hierarchy: `//CLASS`\n- Select a widget that match the tree: `/CLASS`\n- Select a widget with attributes `/CLASS[,...]`\n- Index selector if there is multiple match: `/CLASS[INDEX]`\n- Attribute exists: `@attr`\n- Attribute equal to a value: `@attr=VALUE`\n- Attribute not equal to a value: `@attr!=VALUE`\n- Attribute contain a value: `@attr~=VALUE`\n- Attribute does not contain a value: `@attr!~=VALUE`\n- Value can be a string, but must be escaped within double quote only.\n\nSome examples:\n\n```\n# Select all the boxlayout in the app\n//BoxLayout\n\n# Take the first boxlayout\n//BoxLayout[0]\n\n# Get the Button as a direct descendant of the BoxLayout\n//BoxLayout[0]/Button\n\n# Or get the 5th Button that are anywhere under the BoxLayout (may or may\n# not a direct descandant)\n//BoxLayout[0]//Button\n\n# Select the button that is written \"Close\"\n//BoxLayout[0]//Button[@text=\"Close\"]\n\n# Select the button that contain \"Close\"\n//BoxLayout[0]//Button[@text~=\"Close\"]\n```\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/tito/telenium", "keywords": "kivy", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "telenium", "package_url": "https://pypi.org/project/telenium/", "platform": "any", "project_url": "https://pypi.org/project/telenium/", "project_urls": { "Homepage": "http://github.com/tito/telenium" }, "release_url": "https://pypi.org/project/telenium/0.4.2/", "requires_dist": null, "requires_python": "", "summary": "Kivy automation, can be used to do GUI tests.", "version": "0.4.2" }, "last_serial": 4295731, "releases": { "0.2.6": [ { "comment_text": "", "digests": { "md5": "21f2edbed77740bc41565391474af295", "sha256": "8d01081cf305362e293e1420b6721029740e536959d885ad196982610960188d" }, "downloads": -1, "filename": "telenium-0.2.6-py2-none-any.whl", "has_sig": false, "md5_digest": "21f2edbed77740bc41565391474af295", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 331704, "upload_time": "2017-02-16T01:47:58", "url": "https://files.pythonhosted.org/packages/c8/76/d1826f489c1e44c0280e14cbb7601333405b9cc3737f2a3badd69d2dea8b/telenium-0.2.6-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "afeff08a174fee4ba7ad2f5fd892c5ec", "sha256": "eac1aeb217bc1a34c3f72805294efd7a80f77c815893e085c18ecc5fce49a3ad" }, "downloads": -1, "filename": "telenium-0.2.6.tar.gz", "has_sig": false, "md5_digest": "afeff08a174fee4ba7ad2f5fd892c5ec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 325348, "upload_time": "2017-02-16T01:48:05", "url": "https://files.pythonhosted.org/packages/26/e5/b7adb1a8592acb6703239845b05baa6d0091fd92027fa5439f4f320d6fa3/telenium-0.2.6.tar.gz" } ], "0.2.7": [ { "comment_text": "", "digests": { "md5": "44c3d38de229b515883d8a00af94daac", "sha256": "238a2d448d31beeee0483b15dcc707846209f7eaf22fd092479804f5a746061a" }, "downloads": -1, "filename": "telenium-0.2.7-py2-none-any.whl", "has_sig": false, "md5_digest": "44c3d38de229b515883d8a00af94daac", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 331700, "upload_time": "2017-02-16T02:00:02", "url": "https://files.pythonhosted.org/packages/2e/ed/b61625e4528987078276f10c7f2740a58fc6d9eee9ddfc35b00cb4dac115/telenium-0.2.7-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5496c0924798cac8da80b7e5e3b24f2a", "sha256": "5248a1645315b11d00e90391bd91a24025c5afda5248c89b68ee2ca51214d706" }, "downloads": -1, "filename": "telenium-0.2.7.tar.gz", "has_sig": false, "md5_digest": "5496c0924798cac8da80b7e5e3b24f2a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 325339, "upload_time": "2017-02-16T02:00:10", "url": "https://files.pythonhosted.org/packages/9a/07/fcad73734f912a916686b427c97f00685bf631a37510dd747620cc023879/telenium-0.2.7.tar.gz" } ], "0.2.8": [ { "comment_text": "", "digests": { "md5": "6d73b5ce2b8f22e820149b40d00bc83c", "sha256": "712ce204c363b3611bee0748a0b6a5e56d0794e2f1c6576b701207868bedb59c" }, "downloads": -1, "filename": "telenium-0.2.8-py2-none-any.whl", "has_sig": false, "md5_digest": "6d73b5ce2b8f22e820149b40d00bc83c", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 331791, "upload_time": "2017-02-16T15:56:54", "url": "https://files.pythonhosted.org/packages/0f/dd/88f66ed1bf3e1707fd8c7b006ec8cc2326309f9283352ad660d0c8b9aa80/telenium-0.2.8-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ef1026e54c4ffc98da570a9e3d367b6e", "sha256": "44c59fffa274edbdda5d92586811b74df69f8fcdf09ee2fa2fdee3b1e7934bbe" }, "downloads": -1, "filename": "telenium-0.2.8.tar.gz", "has_sig": false, "md5_digest": "ef1026e54c4ffc98da570a9e3d367b6e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 325467, "upload_time": "2017-02-16T15:57:01", "url": "https://files.pythonhosted.org/packages/0e/d3/ac8e615209090d993808e769e3b424ad6c7093d3a9a0553ca0117c743c76/telenium-0.2.8.tar.gz" } ], "0.2.9": [ { "comment_text": "", "digests": { "md5": "c3a45f8c84065f6c3a5decb26276984d", "sha256": "4c6c6f4cdad379e617bc36c564ee505f12154e6787100c12a128b0dc12e5c7af" }, "downloads": -1, "filename": "telenium-0.2.9-py2-none-any.whl", "has_sig": false, "md5_digest": "c3a45f8c84065f6c3a5decb26276984d", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 331816, "upload_time": "2017-02-16T16:05:55", "url": "https://files.pythonhosted.org/packages/2a/8f/86a0587f2c639d2181776c2cfaabdb1df0a71be87f52944f48ffe3d6fc0f/telenium-0.2.9-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "32f0722469c6976ef67f432c1b154389", "sha256": "d80eb1900d17ae78da2eb67c63b196195dde716919cfed7c592f1d6b5b3f164e" }, "downloads": -1, "filename": "telenium-0.2.9.tar.gz", "has_sig": false, "md5_digest": "32f0722469c6976ef67f432c1b154389", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 325497, "upload_time": "2017-02-16T16:06:03", "url": "https://files.pythonhosted.org/packages/7c/98/ef34300131faf669a2e6244dfac0b6af67b79823eddbf99b210df0c85a9f/telenium-0.2.9.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "996abb5c86b5985ad6d08ad5674a4ed7", "sha256": "f147987ba5a52a206e5d84063d50d8b30a4ac1d171067d0ebbdc816ca43a2515" }, "downloads": -1, "filename": "telenium-0.3.0-py2-none-any.whl", "has_sig": false, "md5_digest": "996abb5c86b5985ad6d08ad5674a4ed7", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 331845, "upload_time": "2017-02-16T16:43:43", "url": "https://files.pythonhosted.org/packages/3c/39/6d1b39f286d236a99304b8d00520d91eca81dc7512210e8d9fbe10ab8203/telenium-0.3.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e339c06e4694d65328aacc97953ba0df", "sha256": "c1d301b1b640a74eedfa790421842c4197cdabebf6e22d46d5a159094e9ce76e" }, "downloads": -1, "filename": "telenium-0.3.0.tar.gz", "has_sig": false, "md5_digest": "e339c06e4694d65328aacc97953ba0df", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 325528, "upload_time": "2017-02-16T16:43:50", "url": "https://files.pythonhosted.org/packages/00/bd/e0e8b8cf992bd8b490734e213a6a44cdf1dad9a9a94f9e05851375ee5cf4/telenium-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "fa470a61b48600b2a14da49941f7a1b2", "sha256": "dfab47a09cfc5c86700cc84d47bf11bec6382bcbcca8c3b4df5e0e0bc7bd098d" }, "downloads": -1, "filename": "telenium-0.3.1-py2-none-any.whl", "has_sig": false, "md5_digest": "fa470a61b48600b2a14da49941f7a1b2", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 331879, "upload_time": "2017-02-20T17:34:47", "url": "https://files.pythonhosted.org/packages/37/50/e8558a00113497d66d02b3ddd84610063a9d49863c53384ffb92cf0f2fc0/telenium-0.3.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3079b245793c7bb6ee394ec3b29a4a6e", "sha256": "6ad2a578b8fc3b7ac330a7798b0563e32e8d06324864f772947d56f8b3d27a04" }, "downloads": -1, "filename": "telenium-0.3.1.tar.gz", "has_sig": false, "md5_digest": "3079b245793c7bb6ee394ec3b29a4a6e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 325586, "upload_time": "2017-02-20T17:34:52", "url": "https://files.pythonhosted.org/packages/63/64/1831326490a40eabb7bf3c33401c8912a6d7ae2fce937e49999de1e86fb2/telenium-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "377c6703f049497bd5e77f6f4ce7222d", "sha256": "5ad250ad0d1c1498f96a1397f06883081e3f1db8b5a9528e97efd239c5a2d15f" }, "downloads": -1, "filename": "telenium-0.3.2-py2-none-any.whl", "has_sig": false, "md5_digest": "377c6703f049497bd5e77f6f4ce7222d", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 332474, "upload_time": "2017-03-09T16:29:07", "url": "https://files.pythonhosted.org/packages/96/19/e6610b03b48c63bc6b85f79cdf954a0f82f5186c7815dede0dbe226d667c/telenium-0.3.2-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ab69784e8a8d267a6d088d35f88b838f", "sha256": "ff39d49d6209944851d537516f9e92c8db7d8dcd259d76f1b4aadcc7829b45b7" }, "downloads": -1, "filename": "telenium-0.3.2.tar.gz", "has_sig": false, "md5_digest": "ab69784e8a8d267a6d088d35f88b838f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 326126, "upload_time": "2017-03-09T16:29:14", "url": "https://files.pythonhosted.org/packages/12/e1/c4c90ea81d4ff59d3185737d5dcd5bc55d655f7d98170b34cc613cc2b87c/telenium-0.3.2.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "0f3f31f00a48b11ba13fa5a6db7aa78b", "sha256": "0ac5bf8c461eda3add7bc490fafdd254babdec9ace204c82b06dc2a63c466883" }, "downloads": -1, "filename": "telenium-0.4.0.tar.gz", "has_sig": false, "md5_digest": "0f3f31f00a48b11ba13fa5a6db7aa78b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 326576, "upload_time": "2017-08-26T10:55:00", "url": "https://files.pythonhosted.org/packages/8f/90/6417b970b6f9b19443bd7ec7341ad9a7e038dbe411d25d1e7ef1994ab73b/telenium-0.4.0.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "dd34cbd10a20a27ea6a523ce11088f6e", "sha256": "16aa4058ad86685d2b7a7fbe582c3fba4448bded73c92e17d5acba2c1217007c" }, "downloads": -1, "filename": "telenium-0.4.1.tar.gz", "has_sig": false, "md5_digest": "dd34cbd10a20a27ea6a523ce11088f6e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 326597, "upload_time": "2017-08-27T13:56:03", "url": "https://files.pythonhosted.org/packages/e3/dd/4849aa17a56cddd5746f9a339164588f2e5dbb4ee935800d736bd7157dc1/telenium-0.4.1.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "014a56798a1f06796803de9b2fc38725", "sha256": "8af238d24ee71c45e6eb591448533e60e35f472d907a6a5d8693c5ad4ad35cd7" }, "downloads": -1, "filename": "telenium-0.4.2.tar.gz", "has_sig": false, "md5_digest": "014a56798a1f06796803de9b2fc38725", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 328593, "upload_time": "2018-09-21T10:48:16", "url": "https://files.pythonhosted.org/packages/46/75/a8c593fafc4afc22d52ba38fe5ce18e14a239ee6ce80bce0f49a16fcbad1/telenium-0.4.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "014a56798a1f06796803de9b2fc38725", "sha256": "8af238d24ee71c45e6eb591448533e60e35f472d907a6a5d8693c5ad4ad35cd7" }, "downloads": -1, "filename": "telenium-0.4.2.tar.gz", "has_sig": false, "md5_digest": "014a56798a1f06796803de9b2fc38725", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 328593, "upload_time": "2018-09-21T10:48:16", "url": "https://files.pythonhosted.org/packages/46/75/a8c593fafc4afc22d52ba38fe5ce18e14a239ee6ce80bce0f49a16fcbad1/telenium-0.4.2.tar.gz" } ] }