lecture 8 of 180 completed

Forms and what they refuse

A login test that only tries the correct password would pass on a login that lets anyone in.

Here is a login test that most beginners write, and it hides a serious problem:

await page.getByLabel('Email').fill('demo@nimbus.app');
await page.getByLabel('Password').fill('secure123');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByTestId('welcome-message')).toContainText('Welcome back');

It checks that the right password lets you in. That is good.

Now imagine a developer breaks the password check, and the app accepts any password. Would this test fail?

No. The correct password still works. The test passes, and your app now lets anyone into any account.

The most important part of a form is what it refuses. So test that too:

await page.getByLabel('Email').fill('demo@nimbus.app');
await page.getByLabel('Password').fill('wrong-password');
await page.getByRole('button', { name: 'Sign in' }).click();

await expect(page.getByTestId('login-error')).toContainText('Invalid email or password');
await expect(page.getByTestId('welcome-message')).toBeHidden();

Look at those last two lines, because the second one matters more than people expect. You check that the error appeared and that you did not get in.

Why both? I have seen an app show a red error message and log the user in anyway. The screen said "Invalid password" while the dashboard loaded behind it. A test that only checked the error message passed.

The same thinking applies to every form you will ever test. Before you write anything, list what the form should refuse:

  • Wrong password.
  • Empty required fields.
  • An email with no @ in it.
  • A card number that is too short.

Then write one test for each. In most real projects, the "refuse" tests find more bugs than the happy path.

One small tip: getByLabel finds a field by the label a user reads next to it. If it cannot find the field, the label is probably not connected properly, and screen reader users will have the same problem.

Remember this: for every form, test what it should refuse, and check that the forbidden thing did not happen.

Reference: Assertions.

now prove it

Reading is the setup. Solve these problems in the editor. We break the app on purpose to check your test would catch it.