---
title: "Test every state of every data view · Agent Wranglers"
url: https://agentwranglers.se/playbook/app-ui/tests-and-budgets/component-state-tests
updated: 2026-10-20
licence: "All rights reserved"
---

# Test every state of every data view

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Tests and budgets](https://agentwranglers.se/playbook/app-ui/tests-and-budgets)
- Rule: Write a component test for each state of each data view. Fake the network at the request level, and find elements by role and name.
- How: Fake the API with a request-level tool, such as Mock Service Worker, so the component's own fetching code runs. Give each state its own test, such as loading, empty, error and success. Find elements as people do, as [stable selectors](https://agentwranglers.se/playbook/testing/end-to-end-and-browser-tests/stable-selectors) describes. Run an accessibility scan in each test, as [accessibility in CI](https://agentwranglers.se/playbook/testing/non-functional-tests/accessibility-in-ci) describes. For server-rendered partials, render each state through the test client.
- Check: The suite has one passing test per state for every data view. Deleting the empty-state branch of any view makes a test fail.

Example:

```tsx
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { render, screen } from '@testing-library/react';

const server = setupServer();
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

test('shows the first-use empty state', async () => {
  server.use(http.get('/api/orders', () => HttpResponse.json({ items: [], nextCursor: null })));
  render(<OrdersScreen />, { wrapper: AppProviders });
  expect(await screen.findByRole('heading', { name: 'No orders yet' })).toBeVisible();
});

test('shows a retry button when loading fails', async () => {
  server.use(http.get('/api/orders', () => HttpResponse.json({ status: 503, reference: 'ERR-7F3C' }, { status: 503 })));
  render(<OrdersScreen />, { wrapper: AppProviders });
  expect(await screen.findByRole('button', { name: 'Try again' })).toBeVisible();
});
```

```python
def test_orders_panel_shows_empty_state(client, signed_in_user, monkeypatch):
    monkeypatch.setattr(order_service, "recent", lambda account_id: [])
    response = client.get("/panels/orders")
    assert response.status_code == 200
    assert "No orders yet" in response.text

def test_orders_panel_shows_error_with_reference(client, signed_in_user, monkeypatch):
    def unavailable(account_id):
        raise ServiceUnavailable(reference="ERR-7F3C")
    monkeypatch.setattr(order_service, "recent", unavailable)
    response = client.get("/panels/orders")
    assert response.status_code == 503
    assert "ERR-7F3C" in response.text
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/tests-and-budgets/component-state-tests`.

- Next: [Compare screenshots of every component state](https://agentwranglers.se/playbook/app-ui/tests-and-budgets/visual-regression)
- [Tests and budgets](https://agentwranglers.se/playbook/app-ui/tests-and-budgets)
