TestWatchStart free

Test a login with authenticator-app 2FA

Logins with a 6-digit authenticator code are where hand-written end-to-end tests usually give up. Here is a real one TestWatch wrote for the open-source demo shop.

by Vasyl Harastei

The test it wrote

await test.step('Sign in as the 2FA shopper', async () => {
  await page.getByRole('link', { name: 'Sign in' }).click();
  await page.getByRole('textbox', { name: 'Username' }).fill(process.env.TARGET_EMAIL!);
  await page.getByRole('textbox', { name: 'Password' }).fill(process.env.TARGET_PASSWORD!);
  await page.getByRole('button', { name: 'Sign in' }).click();

  await page.getByRole('textbox', { name: 'Authentication code' }).fill(otp());
  await page.getByRole('button', { name: 'Verify' }).click();

  await expect(page.getByRole('button', { name: 'Sign out' })).toBeVisible();
});

From checkout-with-2fa-sign-in.spec.ts, generated 3 October 2026. Unedited.

How the 2FA code is handled

The code changes every 30 seconds, so it can’t be written into the test. You save the account’s 2FA secret once, with its username and password, as a test account. When a run reaches the code field, otp() computes the current code from that secret.

Secrets are encrypted at rest and scrubbed from the page snapshots and logs we store. While writing this test, the agent’s log showed “Computing the current 2FA code” at that step.

The run

The sign-in step took 310 ms on a passing run from 3 October 2026, with no AI calls: a passing run is plain Playwright.

When the login breaks

If the password is changed or the 2FA secret no longer works, TestWatch says the login no longer works instead of reporting a bug in your app, and the run doesn’t try to “fix” the test.

Other kinds of codes

Codes and links sent by email work too: a test can read them from a built-in test inbox, on every plan. See testing email verification.

Not supported: codes sent by SMS, and signing in through Google, GitHub or SSO in the app you test.

Start free See the whole test

Free: 5 tests, 500 runs a month, 2 apps and one daily schedule. Unlimited teammates, no card.