We needed something similar and the library proposed by Raymond was not enough for us (we didn't want to change the assertion library and also the library lacks a lot of assertion types we needed), so I wrote this one that I think perfectly answers the question:
https://github.com/alfonso-presa/soft-assert
With this soft-assert library you can wrap other assetion libraries (like chai expect that you asked for) so that you can perform both soft and hard assertions in your tests. Here you have an example:
const { proxy, flush } = require("@alfonso-presa/soft-assert");
const { expect } = require("chai");
const softExpect = proxy(expect);
describe("something", () => {
it("should capture exceptions with wrapped chai expectation library", () => {
softExpect("a").to.equal("b");
softExpect(false).to.be.true;
softExpect(() => {}).to.throw("Error");
softExpect(() => {throw new Error();}).to.not.throw();
try {
//This is just to showcase, you should not try catch the result of flush.
flush();
//As there are assertion errors above this will not be reached
expect(false).toBeTruthy();
} catch(e) {
expect(e.message).toContain("expected 'a' to equal 'b'");
expect(e.message).toContain("expected false to be true");
expect(e.message).toContain("to throw an error");
expect(e.message).toContain("to not throw an error but 'Error' was thrown");
}
});
});