{"id":13651465,"url":"https://github.com/vitalets/playwright-magic-steps","last_synced_at":"2025-04-09T07:09:14.102Z","repository":{"id":248657888,"uuid":"829360545","full_name":"vitalets/playwright-magic-steps","owner":"vitalets","description":"Auto-transform JavaScript comments into Playwright steps","archived":false,"fork":false,"pushed_at":"2025-02-04T10:42:42.000Z","size":1232,"stargazers_count":39,"open_issues_count":1,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T06:07:01.589Z","etag":null,"topics":["playwright","step","test-automation","testing"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/vitalets.png","metadata":{"files":{"readme":"README.md","changelog":null,"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},"funding":{"github":["vitalets"]}},"created_at":"2024-07-16T09:19:48.000Z","updated_at":"2025-03-22T11:00:35.000Z","dependencies_parsed_at":"2024-07-16T10:28:48.114Z","dependency_job_id":"04b3f3fe-af85-4a04-a864-4b711b3e74f5","html_url":"https://github.com/vitalets/playwright-magic-steps","commit_stats":{"total_commits":78,"total_committers":1,"mean_commits":78.0,"dds":0.0,"last_synced_commit":"25ccba604ccbdaf6866c1590cd28501fbefe169d"},"previous_names":["vitalets/playwright-magic-steps"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Fplaywright-magic-steps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Fplaywright-magic-steps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Fplaywright-magic-steps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalets%2Fplaywright-magic-steps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vitalets","download_url":"https://codeload.github.com/vitalets/playwright-magic-steps/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247994121,"owners_count":21030050,"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":["playwright","step","test-automation","testing"],"created_at":"2024-08-02T02:00:49.730Z","updated_at":"2025-04-09T07:09:14.078Z","avatar_url":"https://github.com/vitalets.png","language":"TypeScript","funding_links":["https://github.com/sponsors/vitalets"],"categories":["Utils"],"sub_categories":[],"readme":"# playwright-magic-steps\n\n[![lint](https://github.com/vitalets/playwright-magic-steps/actions/workflows/lint.yaml/badge.svg)](https://github.com/vitalets/playwright-magic-steps/actions/workflows/lint.yaml)\n[![test](https://github.com/vitalets/playwright-magic-steps/actions/workflows/test.yaml/badge.svg)](https://github.com/vitalets/playwright-magic-steps/actions/workflows/test.yaml)\n[![npm version](https://img.shields.io/npm/v/playwright-magic-steps)](https://www.npmjs.com/package/playwright-magic-steps)\n[![license](https://img.shields.io/npm/l/playwright-magic-steps)](https://github.com/vitalets/playwright-magic-steps/blob/main/LICENSE)\n\nAuto-transform JavaScript comments into [Playwright](https://playwright.dev/) steps.\n\n\u003c!-- doc-gen TOC maxDepth=\"3\" --\u003e\n- [Example](#example)\n  - [With AI](#with-ai)\n- [Installation](#installation)\n- [Activation](#activation)\n  - [CommonJS](#commonjs)\n  - [ESM](#esm)\n- [Usage](#usage)\n  - [Step start](#step-start)\n  - [Step end](#step-end)\n  - [Nested steps](#nested-steps)\n  - [Variables](#variables)\n- [Motivation](#motivation)\n- [Caveats](#caveats)\n- [Changelog](#changelog)\n  - [0.4.0](#040)\n- [License](#license)\n\u003c!-- end-doc-gen --\u003e\n\n## Example\nTest code:\n```ts\ntest('Check home page', async ({ page }) =\u003e {\n  // step: Open home page\n  await page.goto('https://playwright.dev');\n  // step: Click \"Get started\" link\n  await page.getByRole('link', { name: 'Get started' }).click();\n  // step: Check page title\n  await expect(page).toHaveTitle('Installation | Playwright');\n});\n```\n\nPlaywright report:\n\n![image](https://github.com/user-attachments/assets/3e11f029-a456-4009-ba75-2357c5f74b63)\n\nTest code actually executed:\n```ts\ntest('Check home page', async ({ page }) =\u003e {\n  await test.step('Open home page', async () =\u003e {\n    await page.goto('https://playwright.dev');\n  });\n  await test.step('Click \"Get started\" link', async () =\u003e {\n    await page.getByRole('link', { name: 'Get started' }).click();\n  });\n  await test.step('Check page title', async () =\u003e {\n    await expect(page).toHaveTitle('Installation | Playwright');\n  });\n});\n```\n\n### With AI\nYou can utilize AI to generate tests with appropriate comments and get nice reports. Example prompt for [ChatGPT](https://chatgpt.com/):\n```\nWrite playwright test in typescript:\n- open playwright homepage\n- navigate to get started section\n- check that page title contains Installation\n\nAdd comment to each step in the format // step: {comment}\n```\n\nGenerated test:\n\n\u003cimg width=\"70%\" src=\"https://github.com/user-attachments/assets/dee422f4-fe70-4e4e-8672-53900a137258\"/\u003e\n\nPlaywright report:\n\n\u003cimg width=\"70%\" src=\"https://github.com/user-attachments/assets/3e019cf1-2e71-4dc5-9cd0-e8a94b755b8c\"/\u003e\n\n## Installation\nInstall from npm:\n```\nnpm install -D playwright-magic-steps\n```\n\n## Activation\nTo enable magic steps transformation, you'll need to run Playwright with a pre-required module. You can include this module using the `NODE_OPTIONS` environment variable. The exact value will depend on whether your project uses CommonJS or ESM:\n\n### CommonJS\nRun Playwright with the following `-r` flag in `NODE_OPTIONS`:\n```\nnpx cross-env NODE_OPTIONS=\"-r playwright-magic-steps\" playwright test\n```\nTo enable magic steps in Playwright VS Code extension, add the following lines to `.vscode/settings.json`:\n```json\n\"playwright.env\": {\n  \"NODE_OPTIONS\": \"-r playwright-magic-steps\"\n},\n```\n\n### ESM\nRun Playwright with the following `--import` flag in `NODE_OPTIONS`:\n```\nnpx cross-env NODE_OPTIONS=\"--import playwright-magic-steps/esm\" playwright test\n```\nTo enable magic steps in Playwright VS Code extension, add the following lines to `.vscode/settings.json`:\n```json\n\"playwright.env\": {\n  \"NODE_OPTIONS\": \"--import playwright-magic-steps/esm\"\n},\n```\n\n## Usage\nYou can define steps with special comments.\n\n### Step start\nStep start is defined by the comment: \n```js\n// step: {title}\n```\n\n### Step end\nStep end is defined by one of the following rules (indent matters):\n\n* start of another step with the same indent:\n  ```ts\n  test('my test', async () =\u003e {\n    // step: Open home page\n    await page.goto('/');\n    // step: Click button\n  });\n  ```\n\n* explicit comment `// stepend` with the same indent:\n  ```ts\n  test('my test', async () =\u003e {\n    // step: Open home page\n    await page.goto('/');\n    // stepend\n  });\n  ```\n\n* line indent is lower than indent of step start:\n  ```ts\n  test('my test', async () =\u003e {\n    // step: Open home page\n    await page.goto('/');\n  });\n  ```\n\n### Nested steps\nSteps can be nested:\n```ts\ntest('my test', async () =\u003e {\n  // step: Open home page\n  await page.goto('/');\n  if (noAuth) {\n    // step: Perform auth\n    await page.goto('/login');\n  }\n});\n```\n\n\u003e [!IMPORTANT]\n\u003e Code **indentation** is important! Consider using [Prettier](https://prettier.io/) or other auto-formatting tools.\n\nIf you need the same level steps to be nested - use anonymous `{}` block:\n```ts\ntest('my test', async () =\u003e {\n  // step: login\n  {\n    // step: Open home page\n    await page.goto('/');    \n    // step: Perform auth\n    await page.goto('/login');\n  }\n});\n```\n\n### Variables\nYou can use variables in step text like in template literals:\n\n```js\nconst searchTerm = 'foo';\n// step: Enter search term ${searchTerm}\nawait page.getByRole('search').fill(searchTerm);\n```\n\nBe careful with variables in comments, as it can be not obvious for other team members.\nAlternatively, you can always use regular `test.step()` for such cases:\n```js\nconst searchTerm = 'foo';\nawait test.step(`Enter search term ${searchTerm}`, async () =\u003e {\n  await page.getByRole('search').fill(searchTerm);\n});  \n```\n\n## Motivation\nAccording to [Golden Rule](https://github.com/goldbergyoni/javascript-testing-best-practices?tab=readme-ov-file#section-0%EF%B8%8F⃣-the-golden-rule) of testing, I try to keep my Playwright tests flat and simple. Wrapping code into `test.step()` adds extra visual complexity and nesting. Creating steps by comments makes test code more readable.\n\n## Caveats\nThis library performs string replacements in your code and can potentially break it. This is a price we pay for convenience.\n\nIf something gets broken, you can always opt-out magic steps. Your tests will run, because all instructions are plain JavaScript comments. Feel free to report any problems in [issues](https://github.com/vitalets/playwright-magic-steps/issues).\n\nExample of broken code:\n```ts\ntest('Check home page', async ({ page }) =\u003e {\n  // step: Open home page\n  await page.goto('https://playwright.dev');\n  const link = page.getByRole('link', { name: 'Get started' });\n\n  // step: Click link\n  await link.click();\n});\n```\n\nError:\n```\nReferenceError: link is not defined\n```\nThere is an error, because in the transformed code `link` variable is wrapped into the scope of the first step and not accessible in the second step:\n```ts\ntest('Check home page', async ({ page }) =\u003e {\n  await test.step('Open home page', async () =\u003e {\n    await page.goto('https://playwright.dev');\n    const link = page.getByRole('link', { name: 'Get started' });\n  });\n\n  await test.step('Click link', async () =\u003e {\n    await link.click();\n  }); \n});\n```\n\nHow to fix:\n\n* Move `link` variable to the second step (that is more logical):\n  ```ts\n  test('Check home page', async ({ page }) =\u003e {\n    // step: Open home page\n    await page.goto('https://playwright.dev');\n\n    // step: Click link\n    const link = page.getByRole('link', { name: 'Get started' });\n    await link.click();\n  });\n  ```\n\n* Close first step earlier (if link variable is shared between several steps):\n  ```ts\n  test('Check home page', async ({ page }) =\u003e {\n    // step: Open home page\n    await page.goto('https://playwright.dev');\n    // stepend\n\n    const link = page.getByRole('link', { name: 'Get started' });\n\n    // step: Click link\n    await link.click();\n  });  \n  ```\n\n## Changelog\n\n### 0.4.0\n* allow blank lines inside steps ([#3](https://github.com/vitalets/playwright-magic-steps/issues/3))\n* dropped support of magic steps activation via `playwright.config.js` as it does not work in Playwright 1.47\n\n## License\n[MIT](https://github.com/vitalets/playwright-magic-steps/blob/main/LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitalets%2Fplaywright-magic-steps","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvitalets%2Fplaywright-magic-steps","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitalets%2Fplaywright-magic-steps/lists"}