{"id":50682285,"url":"https://github.com/microsoft/Webwright","last_synced_at":"2026-06-13T04:01:04.022Z","repository":{"id":355723549,"uuid":"1204415882","full_name":"microsoft/Webwright","owner":"microsoft","description":"A simple SWE style browser agent framework that achieves SOTA results on long horizon web tasks. ","archived":false,"fork":false,"pushed_at":"2026-06-03T22:29:25.000Z","size":116952,"stargazers_count":5317,"open_issues_count":33,"forks_count":327,"subscribers_count":17,"default_branch":"main","last_synced_at":"2026-06-11T10:03:03.441Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/microsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-08T01:48:09.000Z","updated_at":"2026-06-11T09:46:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/microsoft/Webwright","commit_stats":null,"previous_names":["microsoft/webwright"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/microsoft/Webwright","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FWebwright","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FWebwright/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FWebwright/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FWebwright/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/microsoft","download_url":"https://codeload.github.com/microsoft/Webwright/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FWebwright/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34231209,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-06-08T20:00:23.311Z","updated_at":"2026-06-13T04:01:04.016Z","avatar_url":"https://github.com/microsoft.png","language":"Python","funding_links":[],"categories":["Agent Frameworks","4. Agentic AI \u0026 Multi-Agent Systems","AI Web Automation Tools","Python","Catalog"],"sub_categories":["Dev Tools","Reference Harness Implementations"],"readme":"# Webwright\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/webwright_logo.svg\" alt=\"Webwright logo\" width=\"320\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cb\u003eTurn Your Coding Models to Be State-of-the-art Browser Agents\u003c/b\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/python-%E2%89%A53.10-blue?logo=python\u0026logoColor=white\" alt=\"Python\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/playwright-chromium-green\" alt=\"Playwright\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/backends-OpenAI%20%7C%20Anthropic%20%7C%20OpenRouter-orange\" alt=\"Backends\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/footprint-%E2%89%A4~1.5k%20LoC-brightgreen\" alt=\"Footprint\"\u003e\n\u003c/p\u003e\n\n- 📝 **Blog:** [Webwright: A Terminal Is All You Need For Web Agents](https://www.microsoft.com/en-us/research/articles/webwright-a-terminal-is-all-you-need-for-web-agents/)\n- 🌐 **Project Page:** [microsoft.github.io/Webwright](https://microsoft.github.io/Webwright/)\n\nWebwright gives LLM a terminal where it can launch multiple browser sessions to inspect the page and complete a web task. It captures and inspects page screenshots/states only when needed. It enforces each web task to be completed end-to-end within a re-runnable Python script, i.e. your web agent browsing history is a single code file. No multi-agent system, no graph engine, no plugin layer, no hidden orchestration — just a terminal, a browser, and a model.\n\nAlready got your favorite agents, and wonder how to make Claude Code, Codex, Hermes, OpenClaw more capable in browser tasks? Consider adding [Webwright plugin/skills](#-use-as-a-claude-code-skill)!\n\n---\n\n## 📰 News\n\n- **2026-05-11** — Support Task2UI mode: Webwright completes the task and renders task results into an HTML-based web app you can easily view and reuse.  \n- **2026-05-06** — Codex and Claude Code plugin manifests added; install via `/plugin install webwright@webwright`. OpenClaw and Hermes Agent integrations shipped; the same `skills/webwright/` folder now loads across Claude Code, Codex, OpenClaw, and Hermes.\n- **2026-05-04** — Initial public release: ~1.5k LoC, OpenAI / Anthropic / OpenRouter backends, Playwright environment.\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e💡 Motivation: Beyond Step-by-Step Web Interaction in a Stateful Browser\u003c/strong\u003e\u003c/summary\u003e\n\nMost web agents today treat the browser session itself as the workspace: at each step the model receives the current page state and predicts a single next operation — a click, a type, a DOM selector, or a short tool call. Whatever the format, the agent is locked into predicting one web action at a time inside a predefined interaction loop. That harness was useful when LLMs were weaker. As models get stronger at writing and debugging code, the same harness becomes a bottleneck.\n\nWebwright takes a different stance: **separate the agent from the browser**, and treat the browser as something the agent can launch, inspect, and discard while developing a program. The persistent artifact is not the browser session — it's the **code and logs in the local workspace**.\n\n- 🧱 **Robust, reusable interaction with web environments** — instead of fragile pixel-level actions, a coding agent with a terminal queries elements, waits for conditions, and handles dynamic behaviors like lazy loading or re-rendering. The resulting scripts can be rerun, adapted, and shared across tasks rather than rediscovered from scratch.\n- ⚡ **Efficient composition of complex workflows** — multi-step interactions like selecting a date or filling a form become a compact program. Loops, functions, and abstractions let the agent generalize across similar tasks (e.g. different dates) without re-predicting the same low-level sequences. Fewer interaction rounds, faster execution, less error accumulation on long horizons.\n- 🧪 **Workspace-as-state, not browser-as-state** — the agent can write exploratory scripts, spawn fresh browser sessions, and decide for itself when to capture screenshots and inspect failures, much like a human engineer iterating on an RPA script.\n- 🪄 **Surprisingly effective despite being minimal** — this stripped-down setup turns out to handle complex and especially long-horizon web tasks well (see [Performance](#-performance)).\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🌟 Why Webwright\u003c/strong\u003e\u003c/summary\u003e\n\nMost web agent frameworks bury the actual agent loop under layers of abstractions. Webwright takes the opposite stance:\n\n- 🪶 **Lightweight by design** — core agent loop in a single ~450-line file, Playwright environment in ~570 lines, CLI in ~150 lines.\n- 🧩 **Pluggable model backends** — OpenAI, Anthropic, and OpenRouter, each ~150–200 lines.\n- 🔍 **Zero hidden frameworks** — just `httpx`, `pydantic`, `playwright`, and `typer`.\n- 🔁 **Flat prompt → observe → execute script loop** — readable end-to-end, easy to debug, easy to fork.\n- 🧪 **Run-artifact first** — every run writes trajectories and screenshots to disk for inspection.\n\nIf you want a minimal, easy-to-debug starting point for browser-using agents instead of another heavyweight platform, this is it.\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🆚 How Webwright Differs From Other Browser-Agent Repos\u003c/strong\u003e\u003c/summary\u003e\n\nHow they differ at the architectural level:\n\n|                     | **Stagehand (Browserbase)**                                  | **agent-browser (Vercel)**                                                | **browser-use**                                       | **Webwright**                                                       |\n| ------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------- |\n| **Paradigm**        | Hybrid: code + NL primitives (`act` / `extract` / `agent`)   | CLI tool that *another* agent (Claude Code, Codex, etc.) calls            | Autonomous LLM agent loop over DOM/AX snapshots       | **Coding agent with a terminal**; browser is just an environment it spawns |\n| **Action space**    | Playwright code, or NL → LLM-translated Playwright           | Discrete subcommands (`open`, `click @e2`, `snapshot`, `eval`)            | Indexed click/type actions selected by the LLM        | **Free-form Python (writes Playwright scripts itself)**                       |\n| **What is \"state\"?**| The browser session                                          | The browser session (held by daemon across CLI calls)                     | The browser session                                   | **The local workspace — code, screenshots, logs.** Browser is disposable. |\n| **Loop shape**      | Imperative; `agent()` does multi-step when needed            | One CLI invocation per micro-step                                         | observe → predict next action → execute → repeat      | write code → execute → inspect screenshots → repair (code-as-action)      |\n\u003c/details\u003e\n\n\n---\n\n## 🎥 Demo\nhttps://github.com/user-attachments/assets/4ed94cd5-11be-4daa-b2d7-1260a803baca\n\n---\n\n## 📊 Performance\n\nState-of-the-art on two real-website benchmarks with a 100-step budget — see the [blog post](https://www.microsoft.com/en-us/research/articles/webwright-a-terminal-is-all-you-need-for-web-agents/) for full details.\n\n- 🏆 **Online-Mind2Web (300 tasks):** **86.7%** with GPT-5.4 — highest among open-sourced harnesses in the AutoEval category. Claude Opus 4.7 reaches **84.7%**, and is stronger on the hard split (**80.5%** vs. 76.6% for GPT-5.4 at N=100).\n- 🚀 **Odysseys (200 long-horizon tasks):** **60.1%** with GPT-5.4 (avg. 76.1 steps) — **+15.6 points** over the prior SOTA (Opus 4.6 at 44.5%, using vision based approach and persistent browser) and **+26.6 points** over base GPT-5.4 (33.5% using xy-coordinate prediction and persistent browser).\n- 🧠 **Code-as-action beats coordinate prediction:** Webwright substantially outperforms a reproduced GPT-5.4 screenshot+xy-coordinate baseline across all difficulty splits.\n- 🧰 **Small models + reusable tools:** generated scripts can be packaged as parameterized CLI tools — even **Qwen-3.5-9B** completes tasks well on Online-Mind2Web sites with 5+ tools available.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/odysseys_eval_step100.png\" alt=\"Odysseys long-horizon eval @ 100 steps\" width=\"49%\"\u003e\n  \u003cimg src=\"assets/om2w_autoeval_step100.png\" alt=\"Online-Mind2Web AutoEval @ 100 steps\" width=\"49%\"\u003e\n\u003c/p\u003e\n\n---\n\n## 🗺️ Project Map\n\n```\nwebwright/\n├── pyproject.toml           # package: webwright\n├── src/webwright/\n│   ├── run/cli.py           # CLI entrypoint (`webwright`)\n│   ├── agents/default.py    # core agent loop\n│   ├── environments/        # Playwright browser workspace\n│   ├── tools/               # image_qa, self_reflection\n│   ├── models/              # openai_model, anthropic_model, base\n│   ├── config/              # base.yaml, model_openai.yaml, model_claude.yaml\n│   └── utils/\n├── assets/\n│   └── task_showcase/       # tiny Flask dashboard for repeatable runs\n│       ├── app.py\n│       ├── templates/       # dashboard.html, task.html\n│       └── tasks/\u003cshort_id\u003e/ # task.json + report.json per task\n├── tests/\n└── outputs/                 # run artifacts (trajectories, screenshots)\n```\n\n---\n\n## 📰 Task Showcase (repeatable runs as a dashboard)\n\nA tiny Flask app under [`assets/task_showcase/`](assets/task_showcase/README.md) consolidates\nWebwright runs for **repeatable** odyssey tasks (deals, inventory, listings,\njob boards, weather, etc.) into a single dashboard. Each task ships only two\nfiles — `task.json` (metadata) and `report.json` (curated, structured output:\nsources + result sections like tables, lists, summaries) — and the templates\nrender them generically, so adding a new task is just dropping a new folder\nin `assets/task_showcase/tasks/`.\n\n```bash\npip install flask\npython assets/task_showcase/app.py    # http://127.0.0.1:5005\n```\n\nTo have Webwright produce a renderer-ready task folder at runtime, stack the\nTask Showcase overlay:\n\n```bash\npython -m webwright.run.cli \\\n    -c base.yaml -c model_openai.yaml -c task_showcase.yaml \\\n    -t \"\u003crepeatable web task\u003e\" \\\n    --task-id my_repeatable_task \\\n    -o outputs/default\n```\n\n\u003e **Note:** `report.json` is only generated when `-c task_showcase.yaml` is\n\u003e included. A plain `base.yaml` run produces `trajectory.json` and debug\n\u003e artifacts but no `report.json`.\n\nThe run writes `task_showcase/tasks/\u003cshort_id\u003e/task.json` and `report.json`\ninside the output workspace. Render those generated files without copying them\nback into the repo:\n\n```bash\npython assets/task_showcase/app.py \\\n    --tasks-dir outputs/default/\u003crun\u003e/task_showcase/tasks\n```\n\n---\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- Python 3.10+\n- Chromium installed through Playwright\n- An API key for your chosen backend (OpenAI, Anthropic, or OpenRouter)\n\n### Install\n\n```bash\npip install -e .\nplaywright install chromium\n```\n\n### Run\n\nExport credentials for the configured backend (for example, `OPENAI_API_KEY`\nwith `model_openai.yaml` or `ANTHROPIC_API_KEY` with `model_claude.yaml`). The\n`image_qa` and `self_reflection` tools use the same configured model by default,\nso an Anthropic run does not require an OpenAI key. Then:\n\n```bash\npython -m webwright.run.cli \\\n    -c base.yaml -c model_openai.yaml \\\n    -t \"Search for flights from SEA to JFK on 2026-08-15 to 2026-08-20\" \\\n    --start-url https://www.google.com/flights \\\n    --task-id demo_openai \\\n    -o outputs/default\n```\n\n### 🚩 Flags\n\n| Flag | Description |\n|------|-------------|\n| `-c` | Config file(s) from `src/webwright/config/` (stackable). |\n| `-t` | Task instruction. |\n| `--start-url` | Initial page. |\n| `--task-id` | Output subfolder name. |\n| `-o` | Output directory. |\n\n---\n\n## 🔌 Use as a Plugin\n\nWebwright ships plugin manifests for both [Claude Code](https://docs.claude.com/en/docs/claude-code/plugins) ([`.claude-plugin/plugin.json`](.claude-plugin/plugin.json)) and [OpenAI Codex](https://developers.openai.com/codex/plugins) ([`.codex-plugin/plugin.json`](.codex-plugin/plugin.json)), with the shared skill at [`skills/webwright/`](skills/webwright/) and slash commands at [`skills/webwright/commands/`](skills/webwright/commands/). The host agent drives the Webwright loop natively — no extra LLM API key or cost beyond your host subscription. Hosts that read PNG screenshots natively skip the `image_qa` / `self_reflection` tools.\n\nCommon runtime deps (install once after either path):\n\n```bash\npip install -e .\nplaywright install chromium\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eClaude Code\u003c/b\u003e\u003c/summary\u003e\n\n### Install\n\nInstall through the bundled marketplace inside Claude Code:\n\n```text\n# 1. Add this repo as a Claude Code plugin marketplace\n/plugin marketplace add microsoft/Webwright\n\n# 2. Install the plugin from that marketplace\n/plugin install webwright@webwright\n```\n\nPrefer a local checkout? Point the marketplace command at the cloned repo instead:\n\n```text\n/plugin marketplace add /absolute/path/to/Webwright\n/plugin install webwright@webwright\n```\n\n### Use\n\n**Start a new Claude Code session** after installing — plugins are loaded at session start and won't appear until you restart.\n\nYou can either ask Claude Code in plain English (the skill auto-activates from its description), or use one of the slash commands:\n\n```\n/webwright:run search Google Flights for flights from SEA to JFK on 2026-08-15 to 2026-08-20\n/webwright:craft search a ticket on Google Flights from LAX to SFO depart June 7 return June 14\n```\n\n- `/webwright:run` (or any plain prompt) produces a **one-shot** `final_script.py` for the literal task values.\n- `/webwright:craft` produces a **reusable CLI tool**: `final_script.py` becomes one parameterized function with a Google-style `Args:` docstring and an `argparse` wrapper whose flags default to the concrete task values, so you can rerun it later with different arguments — e.g. `python final_script.py --origin JFK --destination LAX --depart-date 2026-07-01`.\n\nIn both modes Claude Code scaffolds a workspace with `plan.md`, runs instrumented Playwright scripts under `final_runs/run_\u003cid\u003e/`, and visually self-verifies each critical point against the saved screenshots.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eOpenAI Codex\u003c/b\u003e\u003c/summary\u003e\n\n### Install\n\nCodex reads Claude-style marketplaces, so the same repo works as a Codex plugin marketplace. From the Codex CLI:\n\n```bash\n# 1. Add this repo as a Codex plugin marketplace\ncodex plugin marketplace add microsoft/Webwright\n\n# 2. Open the plugin browser and install Webwright\ncodex\n/plugins\n```\n\nPrefer a local checkout?\n\n```bash\ncodex plugin marketplace add /absolute/path/to/Webwright\n```\n\nThen restart Codex so the new marketplace and plugin are picked up.\n\n### Use\n\nIn a new Codex thread, either ask in plain English (the skill auto-activates from its description) or invoke the bundled skill explicitly with `@webwright`:\n\n```\n@webwright search Google Flights for flights from SEA to JFK on 2026-08-15 to 2026-08-20\n```\n\nCodex scaffolds a workspace with `plan.md`, runs instrumented Playwright scripts under `final_runs/run_\u003cid\u003e/`, and visually self-verifies each critical point against the saved screenshots.\n\nTo turn the plugin off without uninstalling, set its entry in `~/.codex/config.toml` to `enabled = false` and restart Codex.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e🦞 OpenClaw\u003c/b\u003e\u003c/summary\u003e\n\n### Install\n\nInstall directly from a local checkout (path, archive, npm spec, git repo, or `clawhub:` spec all work):\n\n```bash\nopenclaw plugins install /absolute/path/to/Webwright\nopenclaw gateway restart   # reload so the plugin and skill are picked up\n```\n\nVerify:\n\n```bash\nopenclaw plugins list | grep webwright\nopenclaw skills  list | grep webwright   # should show \"✓ ready\"\n```\n\n### Use\n\nThe `webwright` skill is now available to any OpenClaw agent surface (CLI, Telegram, etc.) — invoke it by asking the agent in natural language, or via the slash commands shipped under [`skills/webwright/commands/`](skills/webwright/commands/), e.g. `/webwright run \u003ctask\u003e`.\n\nTo uninstall: `openclaw plugins uninstall webwright`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eHermes Agent\u003c/b\u003e\u003c/summary\u003e\n\n### Install\n\n[Hermes Agent](https://github.com/NousResearch/hermes-agent) is a [skills-compatible client](https://agentskills.io), so the same `skills/webwright/` folder loads as a Hermes skill. Symlink it into your Hermes user-skills directory:\n\n```bash\nmkdir -p ~/.hermes/skills\nln -sfn /absolute/path/to/Webwright/skills/webwright ~/.hermes/skills/webwright\n```\n\nNo Hermes-specific manifest is needed; only `SKILL.md` is loaded.\n\n### Use\n\nStart Hermes (`hermes`) and ask it to drive a web task in natural language — the skill auto-activates from its description. You can also invoke it explicitly with `/webwright`.\n\nNote: the named subcommands shipped under [`skills/webwright/commands/`](skills/webwright/commands/) (`/webwright:run`, `/webwright:craft`) are a Claude Code / Codex convention and are inert in Hermes; the skill itself still works end-to-end.\n\n\u003c/details\u003e\n\n## 📃 Trajectory Comparison \u0026 Viewer\n\nYou can run the same tasks using the Webwright harness and its Codex / GitHub Copilot skill variant, and see how token usage and trajectories stack up between different harnesses. The trajectory viewer supports Codex, GitHub Copilot and Webwright harness traces.\n\n![Trajectory comparison](assets/trajectory-compare.png)\n\n### How to use\n\n```bash\ncd assets/compare_trajectory/\npython3 -m http.server\n```\n\nOpen the webpage in your browser and upload the Webwright `raw_responses.jsonl` and attach `trajectory.json` to view. Then on the other side you can upload your Codex or GitHub Copilot trace.\n\n### Obtaining Codex traces:\n\n```\nls ~/.codex/sessions/2026/MONTH/DAY/SESSION_ID.jsonl\n```\n\n### Obtaining GitHub Copilot traces:\n\n```\n/export file session\n-\u003e session.md is the uploadable trace\n```\n\n### Quick Comparison\n\n#### \"Find the cheapest used 8-cylinder bmw made between 2005-2015 and priced from 25,000 to  50,000 dollars with mileage less than 50,000 miles or less.\"\n\n| Tokens | Webwright Harness (Local Browser Mode) | Codex Webwright Skill |\n| --- | ---: | ---: |\n| Input | 420,433 | 3,271,143 |\n| Output | 3,593 | 20,040 |\n| Reasoning | 0 | 4,410 |\n| Cached | 217,216 | 3,081,3440 |\n| Total | 424,026 | 3,291,183 |\n\nIndividual runs and results may vary.\n\n---\n\n## Credits\n\n- [SWE-agent/mini-swe-agent](https://github.com/SWE-agent/mini-swe-agent/tree/main) — design inspiration for the minimal agent loop.\n- [Playwright](https://playwright.dev/) — browser automation.\n\n## Citation\n\nIf you use Webwright in your research or build on it, please cite this repository:\n\n```bibtex\n@misc{webwright2026,\n  title        = {Webwright: A terminal is all you need for web agents},\n  author       = {Lu, Yadong and Xu, Lingrui and Huang, Chao and Awadallah, Ahmed},\n  year         = {2026},\n  howpublished = {\\url{https://github.com/microsoft/Webwright}},\n  note         = {GitHub repository}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2FWebwright","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicrosoft%2FWebwright","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2FWebwright/lists"}