{"id":18081072,"url":"https://github.com/pdehaan/playwright-codegen-fxa","last_synced_at":"2026-05-02T06:40:56.910Z","repository":{"id":66292129,"uuid":"450255191","full_name":"pdehaan/playwright-codegen-fxa","owner":"pdehaan","description":"Testing Playwright's codegen on Firefox Accounts (FxA).","archived":false,"fork":false,"pushed_at":"2022-01-20T21:06:45.000Z","size":41,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-12T03:36:00.678Z","etag":null,"topics":["codegen","firefoxaccounts","fxa","playwright"],"latest_commit_sha":null,"homepage":"https://playwright.dev/docs/codegen","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pdehaan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2022-01-20T20:55:56.000Z","updated_at":"2022-01-20T20:58:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"8d350269-a9cc-4412-87c5-bd8077983f82","html_url":"https://github.com/pdehaan/playwright-codegen-fxa","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdehaan%2Fplaywright-codegen-fxa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdehaan%2Fplaywright-codegen-fxa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdehaan%2Fplaywright-codegen-fxa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdehaan%2Fplaywright-codegen-fxa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pdehaan","download_url":"https://codeload.github.com/pdehaan/playwright-codegen-fxa/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247406872,"owners_count":20933936,"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":["codegen","firefoxaccounts","fxa","playwright"],"created_at":"2024-10-31T13:12:40.475Z","updated_at":"2026-05-02T06:40:56.883Z","avatar_url":"https://github.com/pdehaan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# playwright-codegen-fxa\n\nTesting Playwright codegen functionality on a multi-page login flow like FxA.\n\n## STEPS\n\n```sh\nnpx playwright codegen accounts.firefox.com\n```\n\nThis prompted me to install `playwright` in my Terminal (since I don't have it installed globally or locally in this project).\n\nNext it seems to launch some flavor of Chromium, and then opens the specified page (https://accounts.firefox.com), and has a separate \"Playwright Inspector\" panel that comes up which records the actions and writes the code for me.\n\nInterestingly, in the \"Target\" dropdown menu, I can choose \"Playwright Test\" (default), or vanilla JavaScript (or other languages I care less about, like Java, Python, Python Async, or C#).\n\n* Choosing \"Target: Playwright Test\" writes `test`/`expect` tests in the style of @playwright/test (using `import` statements which would require .mjs or .ts files).\n* Choosing \"Target: JavaScript\" writes vanilla JavaScript-style tests using `require()` and targeting Chromium (which is easy enough to switch to Firefox, presumably).\n\nThe actual test steps themselves seem very similar, mostly just the scaffolding and `async`/`await` wrappers for the JavaScript version.\n\n## Running tests\n\nAfter the test steps were recorded (go to specified URL, enter email, \"Continue\", enter password, \"Sign in\", done), I installed \"@playwright/test\" locally, \u003ckbd\u003enpm i @playwright/test -D\u003c/kbd\u003e, since my tests were targing \"Playwright Test\" style and added this to package.json scripts:\n\n```js\n  \"scripts\": {\n    \"codegen\": \"npx playwright codegen accounts.firefox.com\",\n    \"test\": \"playwright test\"\n  },\n```\n\nNow running \u003ckbd\u003enpm test\u003c/kbd\u003e runs my single test (albeit at a relatively slow 10s).\n\n---\n\n### Target: Playwright Test\n\n```mjs\nimport { test, expect } from '@playwright/test';\n\ntest('test', async ({ page }) =\u003e {\n  // Go to https://accounts.firefox.com/\n  await page.goto('https://accounts.firefox.com/');\n\n  // Click [placeholder=\"Email\"]\n  await page.click('[placeholder=\"Email\"]');\n\n  // Fill [placeholder=\"Email\"]\n  await page.fill('[placeholder=\"Email\"]', 'xxx@yyy.zzz');\n\n  // Click button:has-text(\"Continue\")\n  await Promise.all([\n    page.waitForNavigation(/*{ url: 'https://accounts.firefox.com/signin' }*/),\n    page.click('button:has-text(\"Continue\")')\n  ]);\n\n  // Fill [placeholder=\"Password\"]\n  await page.fill('[placeholder=\"Password\"]', '12345678');\n  // Click button:has-text(\"Sign in\")\n  await Promise.all([\n    page.waitForNavigation(/*{ url: 'https://accounts.firefox.com/settings?deviceId=xxx\u0026flowBeginTime=123456\u0026flowId=yyy\u0026broker=web\u0026context=web\u0026isSampledUser=false\u0026service=none\u0026uniqueUserId=zzz' }*/),\n    page.click('button:has-text(\"Sign in\")')\n  ]);\n  // Click [data-testid=\"nav-link-connected-services\"]\n  await page.click('[data-testid=\"nav-link-connected-services\"]');\n  await expect(page).toHaveURL('https://accounts.firefox.com/settings?deviceId=xxx\u0026flowBeginTime=123456\u0026flowId=yyy\u0026broker=web\u0026context=web\u0026isSampledUser=false\u0026service=none\u0026uniqueUserId=zzz#connected-services');\n});\n```\n\n### Target: JavaScript\n\n```js\nconst { chromium } = require('playwright');\n\n(async () =\u003e {\n  const browser = await chromium.launch({\n    headless: false\n  });\n  const context = await browser.newContext();\n  // Open new page\n  const page = await context.newPage();\n\n  // Go to https://accounts.firefox.com/\n  await page.goto('https://accounts.firefox.com/');\n\n  // Click [placeholder=\"Email\"]\n  await page.click('[placeholder=\"Email\"]');\n\n  // Fill [placeholder=\"Email\"]\n  await page.fill('[placeholder=\"Email\"]', 'xxx@yyy.zzz');\n\n  // Click button:has-text(\"Continue\")\n  await Promise.all([\n    page.waitForNavigation(/*{ url: 'https://accounts.firefox.com/signin' }*/),\n    page.click('button:has-text(\"Continue\")')\n  ]);\n\n  // Fill [placeholder=\"Password\"]\n  await page.fill('[placeholder=\"Password\"]', '12345678');\n\n  // Click button:has-text(\"Sign in\")\n  await Promise.all([\n    page.waitForNavigation(/*{ url: 'https://accounts.firefox.com/settings?deviceId=xxx\u0026flowBeginTime=123456\u0026flowId=yyy\u0026broker=web\u0026context=web\u0026isSampledUser=false\u0026service=none\u0026uniqueUserId=zzz' }*/),\n    page.click('button:has-text(\"Sign in\")')\n  ]);\n  // Click [data-testid=\"nav-link-connected-services\"]\n  await page.click('[data-testid=\"nav-link-connected-services\"]');\n  // assert.equal(page.url(), 'https://accounts.firefox.com/settings?deviceId=xxx\u0026flowBeginTime=123456\u0026flowId=yyy\u0026broker=web\u0026context=web\u0026isSampledUser=false\u0026service=none\u0026uniqueUserId=zzz#connected-services');\n  // ---------------------\n  await context.close();\n  await browser.close();\n})();\n```\n\nRerunning the tests locally always failed because it appars the query params below change w/ each unique login.\n\nhttps://accounts.firefox.com/settings?deviceId=xxx\u0026flowBeginTime=123456\u0026flowId=yyy\u0026broker=web\u0026context=web\u0026isSampledUser=false\u0026service=none\u0026uniqueUserId=zzz#connected-services\n\nIt might be trivial enough to parse the URL and verify the protocol, hostname, and path. Ant then have a separate method which verifies the general schema for the `deviceId`, `flowBeginTime`, `flowId`, `broker`, `context`, `isSampleUser`, `service`, and `uniqueUserId` are correct-ish using something like ajv schema validator.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpdehaan%2Fplaywright-codegen-fxa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpdehaan%2Fplaywright-codegen-fxa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpdehaan%2Fplaywright-codegen-fxa/lists"}