Allure Chai reference
allureChai
allureChai: ChaiPlugin
The Chai plugin exported by allure-chai. Register it with Chai once before your tests run:
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 toexpect(), serialized as described in Value serialization.- Modifiers (
not,deep,nested,own,ordered,any,all) are included betweentoand the assertion name when they are active on the assertion chain.includealso 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
haveorbeto match their natural Chai expression. See Assertion path prefixes below. - Property assertions (those that take no arguments) omit the trailing parentheses.
Examples:
| Code | Step 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.null | expect(null).to.be.null |
expect(x).to.not.be.undefined | expect("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:
| Code | Step 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:
| Alias | Displayed as |
|---|---|
eq, equals | equal |
eqls | eql |
contain, contains, includes | include |
exists | exist |
matches | match |
throws, Throw | throw |
greaterThan, gt | above |
greaterThanOrEqual, gte | least |
lessThan, lt | below |
lessThanOrEqual, lte | most |
instanceof | instanceOf |
haveOwnProperty | ownProperty |
haveOwnPropertyDescriptor | ownPropertyDescriptor |
respondsTo | respondTo |
satisfies | satisfy |
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 whenincludeis an active modifier. For example,expect([1,2,3]).to.include.members([2,3])producesexpect([1,2,3]).to.include.members([2,3]), notexpect([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,undefinedare 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 ofError(i.e. wherevalue.prototype instanceof Erroris true) are serialized by name only:TypeError. Note thatErroritself 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.prototypethat 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 ofexpectinternally; those innerexpectcalls are suppressed so eachassert.*call records exactly one step, not two. - Custom assertions added via
chai.Assertion.addMethod(),chai.Assertion.addProperty(), andchai.Assertion.addChainableMethod(). Assertions already on the prototype whenchai.use(allureChai)is called are instrumented at registration time; assertions added afterward are instrumented at the point of theaddMethod/addProperty/addChainableMethodcall. - 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
actualandexpectedon its error (as Chai'sAssertionErrordoes), 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 exceptitselfappear in the name of the assertion step that follows;itselfis a silent chain that affects.respondTo()semantics but is never reflected in step names. - Internal
Assertion.prototypemembers that are not user-facing assertions:_obj,__flags,__methods,callable,iterable,numeric,assert,constructor. These are skipped during instrumentation. AssertionErroronchai.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.Cypressis 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. forchai-httpassertions) is not affected by the Cypress check and will still be recorded.