Skip to content
Allure report logoAllure Report
Main Navigation ModulesDocumentationStarter Project

English

Español

English

Español

Appearance

Sidebar Navigation

Allure 3

Install & Upgrade

Install Allure

Upgrade Allure

Configure

Create Reports

How to generate a report

How to view a report

Improving readability of your test reports

Improving navigation in your test report

Reading Allure charts

Migrate from Allure 2

Allure 2

Install & Upgrade

Install for Windows

Install for macOS

Install for Linux

Install for Node.js

Upgrade Allure

Create Reports

How to generate a report

How to view a report

Improving readability of your test reports

Improving navigation in your test report

Features

Test steps

Attachments

Test statuses

Assertion diffs

Sorting and filtering

Environments

Multistage Builds

Categories

Visual analytics

Test stability analysis

History and retries

Quality Gate

Global Errors and Attachments

Timeline

Export to CSV

Export metrics

Guides

JUnit 5 parametrization

JUnit 5 & Selenide: screenshots and attachments

JUnit 5 & Selenium: screenshots and attachments

Setting up JUnit 5 with GitHub Actions

Pytest parameterization

Pytest & Selenium: screenshots and attachments

Pytest & Playwright: screenshots and attachments

Pytest & Playwright: videos

Playwright parameterization

Publishing Reports to GitHub Pages

Allure Report 3: XCResults Reader

How it works

Overview

Glossary

Test result file

Container file

Categories file

Environment file

Executor file

History files

Test Identifiers

Integrations

Azure DevOps

Bamboo

GitHub Action

Jenkins

JetBrains IDEs

TeamCity

Visual Studio Code

Frameworks

Behat

Getting started

Configuration

Reference

Behave

Getting started

Configuration

Reference

Bun

Getting started

Configuration

Reference

Chai

Getting started

Reference

Codeception

Getting started

Configuration

Reference

CodeceptJS

Getting started

Configuration

Reference

Cucumber.js

Getting started

Configuration

Reference

Cucumber-JVM

Getting started

Configuration

Reference

Cucumber.rb

Getting started

Configuration

Reference

Cypress

Getting started

Configuration

Reference

Jasmine

Getting started

Configuration

Reference

JBehave

Getting started

Configuration

Reference

Jest

Getting started

Configuration

Reference

JUnit 4

Getting started

Configuration

Reference

JUnit 5

Getting started

Configuration

Reference

Mocha

Getting started

Configuration

Reference

Newman

Getting started

Configuration

Reference

NUnit

Getting started

Configuration

Reference

PHPUnit

Getting started

Configuration

Reference

Playwright

Getting started

Configuration

Reference

pytest

Getting started

Configuration

Reference

Pytest-BDD

Getting started

Configuration

Reference

Reqnroll

Getting started

Configuration

Reference

REST Assured

Getting started

Configuration

Robot Framework

Getting started

Configuration

Reference

Rust Cargo Test

Getting started

Configuration

Reference

RSpec

Getting started

Configuration

Reference

SpecFlow

Getting started

Configuration

Reference

Spock

Getting started

Configuration

Reference

TestNG

Getting started

Configuration

Reference

Vitest

Getting started

Configuration

Reference

WebdriverIO

Getting started

Configuration

Reference

xUnit.net

Getting started

Configuration

Reference

On this page

Allure Chai reference ​

allureChai ​

  • allureChai: ChaiPlugin

The Chai plugin exported by allure-chai. Register it with Chai once before your tests run:

js
import { allureChai } from "allure-chai";
import * as chai from "chai";

chai.use(allureChai);

Once registered, every Chai assertion executed during the test run will be recorded as an Allure step. The plugin instruments the chai.Assertion prototype, the chai.assert interface, and the static methods used to define custom assertions. Calling chai.use(allureChai) more than once has no effect — the plugin guards against double-instrumentation.

Step name format ​

expect and should style ​

Steps from expect() and .should assertions follow this pattern:

expect(⟨actual⟩).to[.⟨modifier⟩...][.have|.be].⟨assertion⟩[(⟨arguments⟩)]
  • ⟨actual⟩ is the value passed to expect(), serialized as described in Value serialization.
  • Modifiers (not, deep, nested, own, ordered, any, all) are included between to and the assertion name when they are active on the assertion chain. include also appears as a modifier when .include (or .contain, .contains, .includes) is chained before another assertion such as .members. When multiple modifiers are active, they always appear in this fixed order: not, include, deep, nested, own, ordered, any, all.
  • Some assertions are prefixed with have or be to match their natural Chai expression. See Assertion path prefixes below.
  • Property assertions (those that take no arguments) omit the trailing parentheses.

Examples:

CodeStep name
expect("a").to.equal("b")expect("a").to.equal("b")
expect(arr).to.have.lengthOf(3)expect([...]).to.have.lengthOf(3)
expect(x).to.be.nullexpect(null).to.be.null
expect(x).to.not.be.undefinedexpect("foo").to.not.be.undefined
expect(obj).to.deep.equal({a:1})expect({...}).to.deep.equal({"a":1})
expect(obj).to.have.own.property("x")expect({...}).to.own.have.property("x")

The step name always follows the structural pattern to[.⟨modifier⟩...][.have|.be].⟨assertion⟩, regardless of the order in which language chains appear in code. For example, the have in .to.have.own.property(...) is a language chain that gets dropped, and have is re-added structurally after the own modifier, yielding .to.own.have.property(...).

assert style ​

Steps from assert.* calls follow this pattern:

assert.⟨name⟩(⟨arguments⟩)

All arguments are serialized and joined with , .

Examples:

CodeStep name
assert.equal("a", "b")assert.equal("a", "b")
assert.isTrue(false)assert.isTrue(false)
assert.lengthOf([1,2,3], 3)assert.lengthOf([1,2,3], 3)

Assertion name aliases ​

Several Chai assertion aliases are normalized to their canonical names in step output:

AliasDisplayed as
eq, equalsequal
eqlseql
contain, contains, includesinclude
existsexist
matchesmatch
throws, Throwthrow
greaterThan, gtabove
greaterThanOrEqual, gteleast
lessThan, ltbelow
lessThanOrEqual, ltemost
instanceofinstanceOf
haveOwnPropertyownProperty
haveOwnPropertyDescriptorownPropertyDescriptor
respondsTorespondTo
satisfiessatisfy

Assertion path prefixes ​

Allure Chai adds have or be before the assertion name in expect/should steps to match the natural Chai expression. The prefixes are applied as follows:

  • .have. is added before: keys, key, lengthOf, members, property, ownProperty, ownPropertyDescriptor, string. The .have. prefix is omitted when include is an active modifier. For example, expect([1,2,3]).to.include.members([2,3]) produces expect([1,2,3]).to.include.members([2,3]), not expect([1,2,3]).to.include.have.members([2,3]).
  • .be. is added before: a, an, arguments, Arguments, empty, exist, extensible, false, finite, frozen, instanceOf, NaN, null, ok, sealed, true, undefined.
  • No prefix is added for all other assertions.

Value serialization ​

Values appearing in step names (both ⟨actual⟩ and assertion arguments) are serialized as follows:

  • Strings are JSON-encoded, including surrounding quotes: "hello".
  • Numbers, booleans, null, undefined are converted to their string representations: 42, true, null, undefined.
  • BigInts are serialized as ⟨value⟩n: 9007199254740993n.
  • Symbols are serialized using Symbol.prototype.toString(): Symbol(foo).
  • Functions are serialized as [Function ⟨name⟩], or [Function] if the function has no name. Constructor functions that are subclasses of Error (i.e. where value.prototype instanceof Error is true) are serialized by name only: TypeError. Note that Error itself does not satisfy this check and serializes as [Function Error].
  • RegExp values are serialized using RegExp.prototype.toString() and then JSON-encoded as a string: "/^foo$/i".
  • Error instances are serialized as {"name":"⟨name⟩","message":"⟨message⟩"}, whether they appear as the top-level value or nested inside objects or arrays.
  • Arrays and objects are JSON-serialized up to two levels of nesting. Values nested deeper than two levels are replaced with [Array] or [Object]. Circular references are replaced with [Circular].
  • Serialized values longer than 160 characters are truncated and suffixed with ... <truncated>.

What is and is not recorded ​

Recorded as steps:

  • All method assertions on chai.Assertion.prototype (e.g. equal, include, throw, match).
  • All property assertions on chai.Assertion.prototype that are not language chains or modifiers (e.g. null, ok, empty, exist).
  • Chainable methods used as assertions: a, an, include, contain, contains, includes, length.
  • All methods on chai.assert (e.g. assert.equal, assert.isTrue, assert.throws). assert.* methods are implemented on top of expect internally; those inner expect calls are suppressed so each assert.* call records exactly one step, not two.
  • Custom assertions added via chai.Assertion.addMethod(), chai.Assertion.addProperty(), and chai.Assertion.addChainableMethod(). Assertions already on the prototype when chai.use(allureChai) is called are instrumented at registration time; assertions added afterward are instrumented at the point of the addMethod/addProperty/addChainableMethod call.
  • Inner assertions called from a callback inside a custom assertion. These are recorded as nested child steps of the outer assertion's step.
  • When a failed assertion carries actual and expected on its error (as Chai's AssertionError does), those values are captured in the step's status details.

Not recorded:

  • Language chain properties: to, be, been, is, and, has, have, with, that, which, at, of, same, but, does, still, also. These are cosmetic and have no effect on the report.
  • Modifier properties accessed as part of a chain: not, deep, nested, own, ordered, any, all, itself. These are not recorded as steps themselves. All except itself appear in the name of the assertion step that follows; itself is a silent chain that affects .respondTo() semantics but is never reflected in step names.
  • Internal Assertion.prototype members that are not user-facing assertions: _obj, __flags, __methods, callable, iterable, numeric, assert, constructor. These are skipped during instrumentation.
  • AssertionError on chai.assert. This is a constructor, not a callable assertion, and is not wrapped.
  • Vitest's built-in expect() assertions. Allure Chai detects Vitest-owned assertion chains and skips them automatically to avoid duplicating the steps that allure-vitest already records.
  • Assertions invoked through Cypress's built-in Chai instance. Allure Chai detects when globalThis.Cypress is present and the registered Chai instance matches Cypress's own, and opts out for that instance. A separately imported Chai instance used in the same project (e.g. for chai-http assertions) is not affected by the Cypress check and will still be recorded.
Pager
Previous pageGetting started
Next pageGetting started
Powered by

Subscribe to our newsletter

Get product news you actually need, no spam.

Subscribe
Allure TestOps
  • Overview
  • Why choose us
  • Cloud
  • Self-hosted
  • Success Stories
Company
  • Documentation
  • Blog
  • About us
  • Contact
  • Events
© 2026 Qameta Software Inc. All rights reserved.
A Markdown version of this page is available at /docs/chai-reference.md