Assertions
Introduction
CSTesting includes test assertions in the form of an expect function. To make an assertion, call expect(value) and chain a matcher that reflects the expectation. All matchers are synchronous: they run immediately and do not auto-retry. There is no expect(locator) — you obtain a value (e.g. from the page, from a locator, or from an API response) and then assert on it with expect(value).
expect(success).toBeTruthy();
expect(response.status).toBe(200);
expect(await browser.locator('h1').textContent()).toContain('Welcome');
For page state, get the value first (e.g. content(), url(), locator().textContent(), isVisible()), then use expect on that value. If the element or value might appear after a delay, use waitForSelector or waitForURL before reading the value and asserting.
You will learn
- Available matchers (generic, synchronous)
- Asserting on page and element state
- Negating matchers with
.not - What is not supported (auto-retry, soft assertions, poll, custom matchers)
Generic matchers (synchronous)
These matchers work on any value you pass to expect(value). They do not retry; the assertion runs once. Use them on values you have already obtained (from the browser, from an API call, or from your test logic).
| Assertion | Description | Example |
|---|---|---|
expect(x).toBe(y) | Same value (strict equality, Object.is) | expect(1).toBe(1) |
expect(x).toEqual(y) | Deep equality (JSON comparison) | expect({ a: 1 }).toEqual({ a: 1 }) |
expect(x).toBeTruthy() | Value is truthy | expect(result).toBeTruthy() |
expect(x).toBeFalsy() | Value is falsy (false, 0, null, undefined, '') | expect(flag).toBeFalsy() |
expect(x).toBeNull() | Value is null | expect(el).toBeNull() |
expect(x).toBeDefined() | Value is not undefined | expect(obj.key).toBeDefined() |
expect(x).toBeUndefined() | Value is undefined | expect(obj.missing).toBeUndefined() |
expect(x).toContain(item) | String contains substring, or array contains element | expect('hello').toContain('ell') |
expect(x).toHaveLength(n) | Array or string has length n | expect([1,2]).toHaveLength(2) |
expect(x).toBeGreaterThan(n) | Number is greater than n | expect(5).toBeGreaterThan(3) |
expect(x).toBeLessThan(n) | Number is less than n | expect(2).toBeLessThan(5) |
expect(fn).toThrow(message?) | Function throws when called; optional message or RegExp | expect(() => { throw new Error('x') }).toThrow('x') |
Examples:
expect(1 + 1).toBe(2);
expect({ a: 1 }).toEqual({ a: 1 });
expect('hello').toContain('ell');
expect([1, 2, 3]).toHaveLength(3);
expect(response.status).toBe(200);
expect(() => parse('invalid')).toThrow();
Asserting on page and element state
CSTesting does not have async auto-retrying matchers like await expect(locator).toHaveText('Submitted'). Instead, you get the value from the page (or wait for it first), then assert.
Page title:
const title = await browser.evaluate("document.title");
expect(title).toContain('Example');
Page URL:
const url = await browser.url();
expect(url).toContain('/dashboard');
Page content (HTML):
const html = await browser.content();
expect(html).toContain('Welcome');
Element text:
const text = await browser.locator('h1').textContent();
expect(text).toContain('Submitted');
Element visibility:
const visible = await browser.locator('#status').isVisible();
expect(visible).toBe(true);
Element disabled / enabled:
const disabled = await browser.locator('button').isDisabled();
expect(disabled).toBeFalsy();
Checkbox or radio checked:
const checked = await browser.locator('#agree').isSelected();
expect(checked).toBe(true);
Input value:
const value = await browser.locator('#email').getAttribute('value');
expect(value).toEqual('user@test.com');
Waiting before asserting — If the content appears after a delay, wait first, then read and assert:
await browser.waitForSelector('#status');
const text = await browser.locator('#status').textContent();
expect(text).toContain('Submitted');
Or use waitForURL before asserting on the URL. There is no built-in assertion timeout or auto-retry; you control waiting explicitly.
Negating matchers
Add .not before the matcher to assert the opposite:
expect(value).not.toBe(0);
expect(url).not.toContain('/login');
expect(visible).not.toBe(true);
AssertionError
When an assertion fails, CSTesting throws an AssertionError with a message and optional expected / actual properties. You can catch it or let the test runner report it.
const { expect, AssertionError } = require('cstesting');
try {
expect(1).toBe(2);
} catch (e) {
if (e instanceof AssertionError) {
console.log(e.message, e.expected, e.actual);
}
}
What is not supported (current version)
| Feature | Supported? | Workaround |
|---|---|---|
| Generic matchers (toBe, toEqual, toContain, etc.) | Yes | — |
| Negate with .not | Yes | — |
| AssertionError | Yes | — |
| Auto-retrying assertions (e.g. await expect(locator).toHaveText(...)) | No | Use waitForSelector (or waitForURL), then get the value and expect(value). |
| Assertion timeout (e.g. 5s retry) | No | Implement polling yourself: loop with sleep and expect until condition or timeout. |
| Soft assertions (expect.soft) | No | Run multiple expects; first failure still stops the test. Collect errors in an array and assert at the end if you need "all checks" behavior. |
| Custom message (expect(value, 'message')) | No | Put context in the test name or in a comment; or wrap in try/catch and throw with a custom message. |
| expect.poll (poll until condition) | No | Write a loop that awaits a function and calls expect until it passes or timeout. |
| expect.toPass (retry block until pass) | No | Same: wrap in a loop with timeout. |
| expect.extend (custom matchers) | No | Use a helper function that throws AssertionError on failure, or wrap expect(). |
| Locator-specific matchers (toBeVisible, toHaveText, toHaveAttribute, etc.) | No | Use browser APIs to get the value (isVisible(), textContent(), getAttribute()), then expect(value). |
| Screenshot / snapshot matchers (toHaveScreenshot) | No | Not available. |
| Asymmetric matchers (expect.any(), expect.objectContaining(), etc.) | No | Use toEqual with a plain object or toContain for arrays; no built-in asymmetric matchers. |
| toBeCloseTo, toBeGreaterThanOrEqual, toBeLessThanOrEqual, toBeNaN, toMatch (regex) | No | Use evaluate or JS: e.g. expect(actual >= n).toBe(true), or match with regex in code and then expect(result).toBe(true). |
Summary
- Use expect(value) with matchers: toBe, toEqual, toBeTruthy, toBeFalsy, toBeNull, toBeDefined, toBeUndefined, toContain, toHaveLength, toBeGreaterThan, toBeLessThan, toThrow.
- Use expect(value).not.matcher() to negate.
- For page state: get the value (e.g. content(), url(), locator().textContent(), isVisible(), getAttribute()), then expect on it.
- Use waitForSelector or waitForURL when the value appears asynchronously; then read and assert. There is no auto-retry on assertions.
- Failed assertions throw AssertionError; the test fails and the runner reports it.