<!-- Feste — End-to-end, component, mobile and desktop testing on one runner -->

Testavimas

# Feste

 `0.1.260913` [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0)

One test runner for everything.

Chromium, Firefox, WebKit · iOS, Android, macOS, Windows · Bun or Node

Component tests in a real browser run 2.18x faster than Vitest browser mode and 3.80x faster than Playwright. End-to-end runs 1.22x faster.

## What it runs

Component and end-to-end tests are layers of one application’s test suite. Feste runs both, and the audits, stories and device tests alongside them, from one configuration.

### Component

Mounted in a real browser, with layout and computed styles.

@feste/test

### End to end

Chromium, Firefox and WebKit.

@feste/test

### Lighthouse

Audits against the page the tests already opened.

@feste/lighthouse

### Storybook

Stories run as tests.

@feste/storybook

### iOS

Real devices and simulators.

@feste/mobile

### Android

Real devices and emulators.

@feste/mobile

### Desktop

Native macOS and Windows apps, and Electron wherever it runs.

@feste/desktop

## Real browsers

Tests in a real browser find real browser problems. A simulated DOM like jsdom or happy-dom has no layout engine, so it cannot tell you that a button moved, that text wrapped, or that something is covering the element you clicked.

Feste runs the same tests in Chromium, Firefox and WebKit — the engines your users actually have.

## Bun runtime

Workers are native Bun processes, so Bun’s own APIs are available inside a test. Postgres, SQLite, S3, Redis and a shell are part of the runtime, so a test can check what the page actually wrote — no driver, no pool, no teardown hook before the assertion.

### Run the suite under Bun

```
bun feste test
```

### Use Bun APIs in a test

```
import { test, expect } from "@feste/test";
import { sql } from "bun";

test("sending an invoice writes it to the ledger", async ({ page }) => {
  await page.goto("/invoices/INV-42");
  await page.getByRole("button", { name: "Send" }).click();

  await expect(page.getByText("Sent to the customer")).toBeVisible();

  // Postgres, no driver and no pool to tear down. The page can only tell you
  // what it rendered; this is what was written.
  const [invoice] = await sql`
    SELECT total, status FROM invoices WHERE number = ${"INV-42"}
  `;

  expect(invoice).toMatchObject({ total: 2048, status: "sent" });
});
```

## Speed

In a real browser, component tests run 3.80x faster than Playwright and 2.18x faster than Vitest browser mode.

### Component, jsdom

A simulated DOM, for tests that do not need layout.

Test time by runner, Component, jsdom
| Runner | Time |
| --- | --- |
| Feste, Bun | 1.42s |
| Feste, Node | 1.68s |
| Vitest, Node | 2.55s |
| Playwright, Node | 2.10s |
| 0–2.55s · lower is better |

### Component, real browser

Real layout, real computed styles, real hit-testing.

Test time by runner, Component, real browser
| Runner | Time |
| --- | --- |
| Feste, Bun | 2.21s |
| Feste, Node | 2.27s |
| Vitest, Node | 4.80s |
| Playwright, Node | 8.39s |
| 0–8.39s · lower is better |

### End to end

Chromium, Firefox and WebKit.

Test time by runner, End to end
| Runner | Time |
| --- | --- |
| Feste, Bun | 5.62s |
| Feste, Node | 6.29s |
| Playwright, Node | 6.85s |
| 0–6.85s · lower is better |

The same application, measured at each layer. Each chart is its own scale, in seconds.

60 tests, 10 files, 4 workers, median of 5 runs, each cell in its own container, against a Vite dev server. Linux, 4 CPUs, 8GB. Feste 0.1.260913, Node 26.8.1, Bun 1.4.2, Playwright 1.63.0, Vitest 5.0.0.

Reproduce: npm run bench -- docker

## Built in

Feste conforms to the Playwright API, so existing tests and the knowledge behind them carry over.

Built in
| Area | Detail |
| --- | --- |
| Runtime | Bun alongside Node. Workers are native Bun processes, so Bun APIs work inside a test. |
| Mobile | Native iOS and Android, with the same locators and assertions as a browser test. Screenshot baselines are per device. |
| Hybrid apps | WebViews are discovered and switched into mid-test, so one test can cross from native into web and back with the same locators. |
| Device farms | Point a run at a remote device farm instead of the devices on your desk. |
| Desktop | Native macOS and Windows applications, and Electron. |
| Storybook | Your existing stories become tests, and a story’s play function can be replayed inside one. |
| Lighthouse | Audits run against the page the test already opened, with pass thresholds per category. No second browser, and no separate run. |
| Composition | The fixtures compose, so one test can mount a story and hold it to a performance budget. |
| Locators | getById and getByClassName on Page, Locator, Frame and FrameLocator. Substring by default, exact on request. |
| Matchers | toBeWithinRange, toHaveResponseProperty, toMatchJsonSchema. |
| Reporters | catalog, ai, csv, jira, new-relic, perfetto and xray, alongside the standard reporters. |

## Read the documentation

[Susisiekite](/lt/contact)[Documentation](https://feste.ai)
