Catch Missing `await` Calls in Playwright Tests with ESLint

Have you ever run a Playwright test that just... didn’t behave as expected? Maybe it failed randomly. Maybe it passed locally but broke in CI. The culprit? Often—it’s just a missing await. It’s one of the easiest mistakes to make in async code, and in testing, it can lead to race conditions and flaky results. The Problem: A Missing await Can Break Your Test Let’s look at a simple example. We click a button and expect a modal to appear: await page.getByRole('button', { name: 'Submit' }).click(); expect(page.getByRole('dialog')).toBeVisible(); // ❌ Missing 'await' The expect() call returns a promise, but we didn’t await it, so Playwright moves on before it finishes. Sometimes the modal appears in time. Sometimes it doesn't. Result? Flaky test. What’s worse? VS Code won’t warn you about this by default. The Fix: Let ESLint Catch Floating Promises Luckily, we can set up a TypeScript ESLint rule to help us catch these mistakes automatically. The rule is called @typescript-eslint/no-floating-promises, and it highlights any promise that isn't properly handled. Here’s how to set it up: 1. Install ESLint and TypeScript Support If you haven’t already (ensure you have ESLint v9+ and TypeScript): npm install --save-dev eslint typescript-eslint typescript 2. Create tsconfig.json (If Needed) The @typescript-eslint/no-floating-promises rule requires type information. Ensure you have a tsconfig.json file in your project root. If not, create a basic one: // tsconfig.json { "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "noEmit": true // Important for linting without compiling // Add other options relevant to your project (e.g., "jsx": "react-jsx") }, "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.mjs"], "exclude": ["node_modules"] } 3. Configure ESLint in eslint.config.mjs Create or update eslint.config.mjs in your project root to enable type-aware linting: // eslint.config.mjs import eslint from '@eslint/js'; import tseslint from 'typescript-eslint'; export default tseslint.config( eslint.configs.recommended, // Use recommendedTypeChecked for rules requiring type information ...tseslint.configs.recommendedTypeChecked, { // Configure language options for type checking languageOptions: { parserOptions: { project: true, // Use the tsconfig.json in the root }, }, rules: { '@typescript-eslint/no-floating-promises': 'error', // Other rules can be added here }, }, { // Optionally, ignore specific files/folders ignores: ['dist/**', 'node_modules/**', 'playwright.config.ts'], // Adjust as needed } ); ESLint v9+ uses a new configuration file format. Checkout the ESLint documentation for more details. 4. Install the ESLint VS Code Extension To see the errors directly in your editor, make sure you have the official ESLint extension installed in VS Code. Search for dbaeumer.vscode-eslint in the Extensions view and click Install. Tip: If ESLint warnings don't appear immediately after configuration, try reloading the VS Code window (Command Palette: Developer: Reload Window). The Result: Instant Feedback in VS Code Now, when you forget an await, VS Code will show a squiggly line under the issue before you even run the test. Here’s the fixed version of the earlier code: await page.getByRole('button', { name: 'Submit' }).click(); await expect(page.getByRole('dialog')).toBeVisible(); // ✅ Correct! That one missing keyword can make a world of difference, and now you'll never miss it again. Bonus: Add Type Checking to Your CI Want an extra safety net? Add TypeScript checking to your CI pipeline: npx eslint && tsc It ensures your code compiles cleanly and flags async issues if you enable strict settings. Say Goodbye to Flaky Tests And that’s it! No more sneaky await issues tripping up your Playwright tests. Set up ESLint once, and future you will thank you every time a missing await gets caught before it becomes a flaky bug. If this tip helped you out, drop a comment, and feel free to share it with your team. Happy testing! Happy testing with Playwright! Useful links Playwright documentation Subscribe to our YouTube channel Star us on GitHub Join our Discord server Check out our DEMO: Playwright movies APP

Apr 16, 2025 - 13:18
 0
Catch Missing `await` Calls in Playwright Tests with ESLint

Have you ever run a Playwright test that just... didn’t behave as expected? Maybe it failed randomly. Maybe it passed locally but broke in CI. The culprit? Often—it’s just a missing await.

It’s one of the easiest mistakes to make in async code, and in testing, it can lead to race conditions and flaky results.

The Problem: A Missing await Can Break Your Test

Let’s look at a simple example. We click a button and expect a modal to appear:

await page.getByRole('button', { name: 'Submit' }).click();
expect(page.getByRole('dialog')).toBeVisible(); // ❌ Missing 'await'

The expect() call returns a promise, but we didn’t await it, so Playwright moves on before it finishes. Sometimes the modal appears in time. Sometimes it doesn't. Result? Flaky test.

What’s worse? VS Code won’t warn you about this by default.

The Fix: Let ESLint Catch Floating Promises

Luckily, we can set up a TypeScript ESLint rule to help us catch these mistakes automatically. The rule is called @typescript-eslint/no-floating-promises, and it highlights any promise that isn't properly handled.

Here’s how to set it up:

1. Install ESLint and TypeScript Support

If you haven’t already (ensure you have ESLint v9+ and TypeScript):

npm install --save-dev eslint typescript-eslint typescript

2. Create tsconfig.json (If Needed)

The @typescript-eslint/no-floating-promises rule requires type information. Ensure you have a tsconfig.json file in your project root. If not, create a basic one:

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true // Important for linting without compiling
    // Add other options relevant to your project (e.g., "jsx": "react-jsx")
  },
  "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.mjs"],
  "exclude": ["node_modules"]
}

3. Configure ESLint in eslint.config.mjs

Create or update eslint.config.mjs in your project root to enable type-aware linting:

// eslint.config.mjs
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  eslint.configs.recommended,
  // Use recommendedTypeChecked for rules requiring type information
  ...tseslint.configs.recommendedTypeChecked,
  {
    // Configure language options for type checking
    languageOptions: {
      parserOptions: {
        project: true, // Use the tsconfig.json in the root
      },
    },
    rules: {
      '@typescript-eslint/no-floating-promises': 'error',
      // Other rules can be added here
    },
  },
  {
    // Optionally, ignore specific files/folders
    ignores: ['dist/**', 'node_modules/**', 'playwright.config.ts'], // Adjust as needed
  }
);

ESLint v9+ uses a new configuration file format. Checkout the ESLint documentation for more details.

4. Install the ESLint VS Code Extension

To see the errors directly in your editor, make sure you have the official ESLint extension installed in VS Code. Search for dbaeumer.vscode-eslint in the Extensions view and click Install.

Tip: If ESLint warnings don't appear immediately after configuration, try reloading the VS Code window (Command Palette: Developer: Reload Window).

The Result: Instant Feedback in VS Code

Now, when you forget an await, VS Code will show a squiggly line under the issue before you even run the test.

ESLint Warning in vs code

Here’s the fixed version of the earlier code:

await page.getByRole('button', { name: 'Submit' }).click();
await expect(page.getByRole('dialog')).toBeVisible(); // ✅ Correct!

That one missing keyword can make a world of difference, and now you'll never miss it again.

Bonus: Add Type Checking to Your CI

Want an extra safety net? Add TypeScript checking to your CI pipeline:

npx eslint && tsc

It ensures your code compiles cleanly and flags async issues if you enable strict settings.

Say Goodbye to Flaky Tests

And that’s it! No more sneaky await issues tripping up your Playwright tests. Set up ESLint once, and future you will thank you every time a missing await gets caught before it becomes a flaky bug.

If this tip helped you out, drop a comment, and feel free to share it with your team. Happy testing!

Happy testing with Playwright!

Useful links