{"id":25619122,"url":"https://github.com/tracktor/playsmart","last_synced_at":"2026-05-14T18:33:26.579Z","repository":{"id":278703202,"uuid":"936499385","full_name":"Tracktor/playsmart","owner":"Tracktor","description":"Playwright \u003e Playsmart! Write reusable and maintainable E2E tests like a human.","archived":false,"fork":false,"pushed_at":"2025-02-21T08:26:54.000Z","size":0,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-02-21T08:29:13.578Z","etag":null,"topics":["automation","e2e","llm","playsmart","playwright","prompt"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tracktor.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-21T07:35:06.000Z","updated_at":"2025-02-21T08:26:58.000Z","dependencies_parsed_at":"2025-02-21T08:40:29.627Z","dependency_job_id":null,"html_url":"https://github.com/Tracktor/playsmart","commit_stats":null,"previous_names":["tracktor/playsmart"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tracktor%2Fplaysmart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tracktor%2Fplaysmart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tracktor%2Fplaysmart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tracktor%2Fplaysmart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tracktor","download_url":"https://codeload.github.com/Tracktor/playsmart/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240131730,"owners_count":19752727,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","e2e","llm","playsmart","playwright","prompt"],"created_at":"2025-02-22T06:15:59.930Z","updated_at":"2026-05-14T18:33:26.573Z","avatar_url":"https://github.com/Tracktor.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Playwright! Playsmart!\n----------------------\n\n[![Downloads](https://img.shields.io/pypi/dm/playsmart.svg)](https://pypistats.org/packages/playsmart)\n[![Supported Versions](https://img.shields.io/pypi/pyversions/playsmart.svg)](https://pypi.org/project/playsmart)\n\nEnd the never ending game of having to manually record, inspect, and update your E2E tests with Playwright.\n\nhttps://github.com/user-attachments/assets/8e5602b7-341c-4dd7-b623-028a08a5a8e7\n\n\u003cdetails\u003e\n  \u003csummary\u003e🎮 \u003cb\u003eSee the Playsmart code\u003c/b\u003e for \u003ci\u003ethe hacker news demo\u003c/i\u003e!\u003c/summary\u003e\n\n```python\nimport time\n\nfrom playwright.sync_api import sync_playwright\nfrom playsmart import Playsmart\n\n\nif __name__ == \"__main__\":\n    driver = sync_playwright().start()\n    chrome = driver.chromium.launch(headless=False)\n    page = chrome.new_page()\n\n    page.goto(\"https://news.ycombinator.com/\")\n    page.wait_for_load_state()\n\n    smart_hub = Playsmart(\n        browser_tab=page,\n    )\n\n    with smart_hub.context(\"home\"):\n        res = smart_hub.want(\"how many news in the page?\")\n\n        assert len(res)\n\n        print(f\"There is {res[0].count()} news in the page!\")\n\n        smart_hub.want(\"click on new\")\n\n        smart_hub.want(\"click on discuss on the third item\")\n\n    with smart_hub.context(\"news item\"):\n        smart_hub.want(\"fill the comment input with a fake criticism\")\n\n    time.sleep(5)\n\n```\n\u003c/details\u003e\n\n\nThis chunk of code[...]\n\n```python\npage.locator(\"#dkDj87djDA-reo\").fill(\"hello@world.tld\")\npage.locator(\"#dflfkZkfAA-reo\").fill(\"$ecr!t\")\npage.get_by_role(\"button\", name=\"Log In\").click()\n```\n\nwill become\n\n```python\nfrom playsmart import Playsmart\n\nsmart_hub = Playsmart(\n    browser_tab=page,\n)\n\nwith smart_hub.context(\"login page\"):\n    smart_hub.want(\"fill email input with hello@world.tld\")\n    smart_hub.want(\"fill password input with $ecr!t\")\n    smart_hub.want(\"click on login\")\n```\n\nnicer, isn't it?\n\n### Get started!\n\nInstall **Playsmart** via PyPI\n\n```shell\npip install playsmart\n```\n\n_requires Python 3.10+_\n\nBefore you get started, either:\n\n- export `OPENAI_API_KEY`\n- or set `openai_key=...` parameter within `Playsmart` class constructor.\n\nHere's the minimum runnable example:\n\n```python\nfrom playwright.sync_api import sync_playwright\nfrom playsmart import Playsmart\n\ndriver = sync_playwright().start()\nchrome = driver.chromium.launch(headless=False)\npage = chrome.new_page()\n\npage.goto(\"https://huggingface.co/docs\")\n\nsmart_hub = Playsmart(\n    browser_tab=page\n)\n\nwith smart_hub.context(\"docs page\"):\n    smart_hub.want(\"click on PEFT doc section\")\n```\n\n### Interactive playground!\n\nDon't want to start coding? Rather see it working via a CLI? We got you covered!\n\nRun `python -m playsmart` or directly `playsmart` to get a fast and friendly testing playground.\n\nExample:\n\n```shell\nplaysmart -v https://github.com/\n```\n\n```\nusage: playsmart [-h] [-v] target\n\nRealtime LLM agent for interacting with web pages\n\npositional arguments:\n  target         Initial URL to get started\n\noptions:\n  -h, --help     show this help message and exit\n  -v, --verbose  Enable advanced debugging\n```\n\nDon't forget to set `OPENAI_API_KEY` in your environment, or you will be prompted for it!\n\n### OpenAI TPM Errors\n\nDid you get an error immediately?\n\n```\nRequest too large for gpt-4o in organization org-XlSkSlxsksdS on tokens per min (TPM): Limit 30000, Requested 67653.\n```\n\nEnsure your OpenAI project can accept higher limits! See https://platform.openai.com/docs/guides/rate-limits?context=tier-five to learn more.\n\nYour DOM might be too large to be processed by our library. Usually it is because you embed large scripts in your DOM\nlike when you use a development (webpack/vite live/dev render) server.\n\n### Caching\n\nWe know how painful consuming needlessly tokens can be. That's why **Playsmart** have a tiny\ncaching layer that helps with keeping LLM hints.\n\nYou may at any moment disable the cache for a specific instruction as:\n\n```python\nsmart_hub.want(\"click on PEFT doc section\", use_cache=False)\n```\n\nA discrete file, named `.playsmart.cache` will be created. You are encouraged to share this file\nacross your teams! Commit it!\n\nYou may choose a filename at your own convenience via the `cache_path=...` parameter within the `Playsmart` class constructor.\n\nIf your application does not have a stable content, you could be embarrassed by the ever invalidating cache.\nTo remediate to this, set the following environment variable:\n\n```shell\nexport PLAYSMART_CACHE_PRESET=\"example.com=v1.22\"\n# or...\nexport PLAYSMART_CACHE_PRESET=\"example.com=v1.22;example.org=v4.33\"\n```\n\nThis will actively prevent the cache to be invalidated.\n\n### The 'want' method in a nutshell\n\nBasically, everything revolve around `Playsmart.want(...)` as you would have already guessed.\n\nThere's two types of action you can execute:\n\nA) Immediate action: e.g. I want to click on something\nB) Deferred action: e.g. How many orders are marked as 'pending'?\n\nFor the case A) you should never expect the method to return anything (aside from empty list).\n\nFinally, for the case B) Playsmart will always translate your query to a (or many) usable `playwright.Locator`.\n\nHere is a solid example for B):\n\n```python\nwith smart_hub.context(\"dashboard\"):\n    locators = smart_hub.want(\"how many orders are labelled as 'pending'?\")\n\n    print(f\"we have {locators[0].count()} order(s) pending\")\n```\n\nYet, another one:\n\n```python\nwith smart_hub.context(\"dashboard\"):\n    locators = smart_hub.want(\"list every fields in the form\")\n\n    for locator in locators:\n        ... # your logic for each 'input\u003ctext/select/...\u003e'\n```\n\n### Limitation\n\nThe \"big\" caveat here, is that we purposely don't use anything else than DOM analysis.\nNo computer vision will be used in this project. We saw that introducing it is nice but unfortunately\nintroduce a lot of \"flaky tests\".\n\nThis immediately prevent you from writing `smart_hub.want(\"ensure we are on the dashboard page\")`.\nMost of the time you should write proper assertion yourself.\n\nThe project does tremendously reduce the burden of maintaining E2E pipelines.\n\n### Debug runtime\n\nIf you are asking yourself \"How did we arrive at that result?\", use the handy function `context_debug`.\n\n```python\nfrom playsmart import context_debug, Playsmart\n\nsmart_hub = Playsmart(\n    browser_tab=...\n)\n\nwith context_debug():\n    smart_hub.want(\"click on PEFT doc section\")\n```\n\nIt will stream a list of detailed events to help you debug your test.\n\n### Disclaimer\n\nThis (heuristic) software is still at an early stage and has not been battle tested (yet).\nAlthough we envision a great future for it, it would be unwise to replace your entire E2E suite\nwith it.\n\nWe encourage its incremental adoption and positive feedbacks to help us improve this.\n\nFinally, note that the library is not thread safe.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftracktor%2Fplaysmart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftracktor%2Fplaysmart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftracktor%2Fplaysmart/lists"}