This is an issue when a test uses a promise-returning assertion or expectation without awaiting it or returning it to the test framework.

Why is this an issue?

Test frameworks determine whether a test passed or failed when the test function completes. When an assertion returns a promise, the framework must wait for that promise before it can evaluate the assertion result.

If the promise is neither awaited nor returned, the test can finish before the assertion runs. The framework sees no failure and reports the test as passed. The assertion then runs later, after the test has already completed.

This can lead to false positives:

In JavaScript/TypeScript, this includes Jest and Vitest .resolves and .rejects, Jasmine expectAsync(), and Playwright’s async assertions.

What is the potential impact?

Unreliable tests that pass even when they should fail can mask critical bugs in production code. Teams lose confidence in their test suite, and bugs may reach production. The effort spent writing tests provides no actual safety net.

How to fix it in Jest

Jest’s .resolves and .rejects assertions return promises. Await the assertion, or return it from the test.

Code examples

Noncompliant code example

describe("User API", () => {
  it("fetches user successfully", () => {
    expect(fetchUser(1)).resolves.toHaveProperty("name"); // Noncompliant
  });

  it("rejects on invalid ID", () => {
    expect(fetchUser(-1)).rejects.toThrow("Invalid ID"); // Noncompliant
  });
});

Compliant solution

describe("User API", () => {
  it("fetches user successfully", () => {
    return expect(fetchUser(1)).resolves.toHaveProperty("name");
  });

  it("rejects on invalid ID", async () => {
    await expect(fetchUser(-1)).rejects.toThrow("Invalid ID");
  });
});

How to fix it in Vitest

Vitest’s .resolves and .rejects assertions return promises. Await the assertion, or return it from the test.

Code examples

Noncompliant code example

import { it, expect } from "vitest";

it("processes data", () => {
  expect(processData()).resolves.toEqual([1, 2, 3]); // Noncompliant
});

Compliant solution

import { it, expect } from "vitest";

it("processes data", () => {
  return expect(processData()).resolves.toEqual([1, 2, 3]);
});

How to fix it in Jasmine

Jasmine’s expectAsync() returns a promise. Await the assertion, or return it from the spec.

Code examples

Noncompliant code example

it("loads configuration", () => {
  expectAsync(loadConfig()).toBeResolvedTo({ port: 3000 }); // Noncompliant
});

Compliant solution

it("loads configuration", () => {
  return expectAsync(loadConfig()).toBeResolvedTo({ port: 3000 });
});

How to fix it in Playwright

Playwright’s auto-retrying assertions are async and must be awaited.

Code examples

Noncompliant code example

import { test, expect } from "@playwright/test";

test("displays welcome message", async ({ page }) => {
  await page.setContent("<h1>Welcome</h1>");
  expect(page.getByRole("heading")).toHaveText("Welcome"); // Noncompliant
});

Compliant solution

import { test, expect } from "@playwright/test";

test("displays welcome message", async ({ page }) => {
  await page.setContent("<h1>Welcome</h1>");
  await expect(page.getByRole("heading")).toHaveText("Welcome");
});

Resources

Documentation