name: test-conventions description: Shared test conventions for all testing agents in the Lichtblick repo. Defines GWT pattern, core quality rules, and the standard test-writing workflow.
Test Conventions
Applies to all test agents (unit tests, E2E tests).
Given-When-Then (GWT)
Every test body must include GWT section comments.
Block-comment style (Desktop / E2E)
/**
* GIVEN a .mcap file is loaded
* WHEN play button is clicked
* THEN playback time should advance
*/
test("should start playing when clicking on Play button", async ({ mainWindow }) => {
// Given
await loadFiles({ mainWindow, filenames: "example.mcap" });
const button = mainWindow.getByTestId("play-button");
// When
await button.click();
// Then
await expect(button).toHaveAttribute("title", "Pause");
});
Inline comment style (Unit tests)
it("should return the layout when ID is valid", async () => {
// Given
const layout = LayoutBuilder.layout();
// When
const result = await service.findOne(layout.id);
// Then
expect(result).toEqual(layout);
});
Core Quality Rules
- One logical assertion per test — split complex scenarios into separate
test()/it()blocks. - Mock external dependencies, never business logic — mock file I/O, IPC, HTTP clients; test the real code under test.
- Use existing builders and fixtures — never create raw test data inline when a builder or fixture exists.
- Match sibling test structure exactly — same import style, same fixture usage, same GWT comment format as existing tests in the same directory.
- Run tests after writing — execute to verify they pass before presenting results.
- No
any— use proper TypeScript types in all test code. - Always read before writing — read the source file AND at least one existing sibling test file before generating new tests.
Test-Writing Workflow
- Read the source file — understand the component or feature under test.
- Read an existing sibling test — match the exact import style, fixture setup, and GWT comment format.
- Identify available builders / fixtures — check
testing/builders/(unit),e2e/fixtures/(E2E), ande2e/page-objects/(E2E). - Write tests covering:
- Happy path (valid input → expected outcome)
- Edge cases (boundary values, empty state)
- Error paths (invalid state → expected failure behavior)
- Run the tests to confirm they pass.
- Report which scenarios are covered and flag any missing edge cases.
Test Naming
TypeScript (Unit tests — Jest)
- Describe blocks:
describe('ComponentName')→describe('methodOrBehavior') - Test titles:
it('should <expected outcome> when <condition>')
TypeScript (E2E tests — Playwright)
- Top-level
test()with a descriptive title:"should <expected outcome> when <condition>" - Use a block-comment JSDoc above the test for the full GWT scenario description
Cleanup
Jest (unit tests)
afterEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
});
Playwright (E2E)
- Each test gets an isolated app/page via fixtures — no manual cleanup needed between tests
- If a test opens a dialog or modifies shared state, restore it at the end of that test
Error Testing
Jest
await expect(service.create(dto)).rejects.toThrow(SomeException);
Playwright
await expect(page.getByRole("alert")).toBeVisible();
await expect(page.getByText("Error message")).toBeVisible();