From e95f4a460396783e358bd292fd137186a945b72f Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Tue, 2 Jun 2026 20:07:56 +0300 Subject: [PATCH 1/2] test(browser-logs): migrate tests from mocha/chai to node:test Replace mocha/chai with node:test, node:assert/strict across 1 test file (33 tests). Key changes: - chai expect() -> node:assert/strict - `require.resolve` -> createRequire(import.meta.url) - `__dirname` -> import.meta.dirname - src/ imports -> dist/ imports for native type stripping - `this.timeout()` -> describe timeout option - `(window as any)` -> window['_serialize'] in page.evaluate callbacks to avoid strip-types whitespace shifting Chrome stack trace column numbers - deepEqual with class instances uses spread to plain object since deepStrictEqual checks constructor unlike chai eql - Updated error stack column assertions to match strip-types function serialization format Assisted-By: Claude Opus 4.6 (1M context) --- packages/browser-logs/package.json | 3 +- .../test/serialize-deserialize.test.ts | 337 +++++++++--------- 2 files changed, 172 insertions(+), 168 deletions(-) diff --git a/packages/browser-logs/package.json b/packages/browser-logs/package.json index 70752ca0a0..e7d70bc034 100644 --- a/packages/browser-logs/package.json +++ b/packages/browser-logs/package.json @@ -26,8 +26,7 @@ }, "scripts": { "build": "tsc", - "test:node": "mocha \"test/**/*.test.{ts,js,mjs,cjs}\" --require ts-node/register --reporter dot", - "test:watch": "mocha \"test/**/*.test.{ts,js,mjs,cjs}\" --require ts-node/register --watch --watch-files src,test" + "test:node": "node --experimental-strip-types --test --test-force-exit test/**/*.test.ts" }, "files": [ "*.d.ts", diff --git a/packages/browser-logs/test/serialize-deserialize.test.ts b/packages/browser-logs/test/serialize-deserialize.test.ts index 5a3232684c..823283cd72 100644 --- a/packages/browser-logs/test/serialize-deserialize.test.ts +++ b/packages/browser-logs/test/serialize-deserialize.test.ts @@ -1,16 +1,19 @@ -import { expect } from 'chai'; -import puppeteer, { Browser, Page } from 'puppeteer'; -import fs from 'fs'; -import path from 'path'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import { createRequire } from 'node:module'; +import path from 'node:path'; +import { describe, it, before, after } from 'node:test'; -import { deserialize } from '../src/deserialize.js'; +import type { Browser, Page } from 'puppeteer'; +import puppeteer from 'puppeteer'; -const serializeScript = fs.readFileSync(require.resolve('../dist/serialize.js'), 'utf-8'); -const defaultOptions = { browserRootDir: __dirname, cwd: __dirname }; +import { deserialize } from '../dist/deserialize.js'; -describe('serialize deserialize', function () { - this.timeout(10000); +const require = createRequire(import.meta.url); +const serializeScript = fs.readFileSync(require.resolve('../dist/serialize.js'), 'utf-8'); +const defaultOptions = { browserRootDir: import.meta.dirname, cwd: import.meta.dirname }; +describe('serialize deserialize', { timeout: 10000 }, function () { let browser: Browser; let page: Page; before(async () => { @@ -26,24 +29,26 @@ describe('serialize deserialize', function () { await browser.close(); }); + // window['_serialize'] avoids TS `as any` cast -- strip-types replaces casts with whitespace, + // which shifts column numbers in Chrome-evaluated code and breaks error stack trace assertions. it('handles strings', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize('foo')); + const serialized = await page.evaluate(() => window['_serialize']('foo')); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal('foo'); + assert.equal(deserialized, 'foo'); }); it('handles numbers', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize(1)); + const serialized = await page.evaluate(() => window['_serialize'](1)); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal(1); + assert.equal(deserialized, 1); }); it('handles Date', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize(new Date('2020-07-25T12:00:00.000Z')), + window['_serialize'](new Date('2020-07-25T12:00:00.000Z')), ); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal('2020-07-25T12:00:00.000Z'); + assert.equal(deserialized, '2020-07-25T12:00:00.000Z'); }); it('handles Function', async () => { @@ -51,11 +56,11 @@ describe('serialize deserialize', function () { function foo(x: number, y: number) { return x * y; } - return (window as any)._serialize(foo); + return window['_serialize'](foo); }); const deserialized = await deserialize(serialized); - expect(typeof deserialized).to.equal('function'); - expect(deserialized.name).to.equal('foo'); + assert.equal(typeof deserialized, 'function'); + assert.equal(deserialized.name, 'foo'); }); it('handles bound Function', async () => { @@ -63,62 +68,62 @@ describe('serialize deserialize', function () { function foo(x: number, y: number) { return x * y; } - return (window as any)._serialize(foo.bind(null)); + return window['_serialize'](foo.bind(null)); }); const deserialized = await deserialize(serialized); - expect(typeof deserialized).to.equal('function'); - expect(deserialized.name).to.equal('foo'); + assert.equal(typeof deserialized, 'function'); + assert.equal(deserialized.name, 'foo'); }); it('handles Symbol', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize(Symbol('foo'))); + const serialized = await page.evaluate(() => window['_serialize'](Symbol('foo'))); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal('Symbol(foo)'); + assert.equal(deserialized, 'Symbol(foo)'); }); it('handles arrow functions', async () => { const serialized = await page.evaluate(() => { const foo = (x: number, y: number) => x * y; - return (window as any)._serialize(foo); + return window['_serialize'](foo); }); const deserialized = await deserialize(serialized); - expect(typeof deserialized).to.equal('function'); - expect(deserialized.name).to.equal('foo'); + assert.equal(typeof deserialized, 'function'); + assert.equal(deserialized.name, 'foo'); }); it('handles anonymous arrow functions', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize((x: number, y: number) => x * y), + window['_serialize']((x: number, y: number) => x * y), ); const deserialized = await deserialize(serialized); - expect(typeof deserialized).to.equal('function'); - expect(deserialized.name).to.equal(''); + assert.equal(typeof deserialized, 'function'); + assert.equal(deserialized.name, ''); }); it('handles Text nodes', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize(document.createTextNode('hello world')), + window['_serialize'](document.createTextNode('hello world')), ); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal('Text: hello world'); + assert.equal(deserialized, 'Text: hello world'); }); it('handles Comment nodes', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize(document.createComment('hello world')), + window['_serialize'](document.createComment('hello world')), ); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal('Comment: hello world'); + assert.equal(deserialized, 'Comment: hello world'); }); it('handles HTMLElement', async () => { const serialized = await page.evaluate(() => { const element = document.createElement('div'); element.innerHTML = '

Hello world

'; - return (window as any)._serialize(element); + return window['_serialize'](element); }); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal('HTMLDivElement:

Hello world

'); + assert.equal(deserialized, 'HTMLDivElement:

Hello world

'); }); it('handles ShadowRoot', async () => { @@ -126,44 +131,44 @@ describe('serialize deserialize', function () { const element = document.createElement('div'); element.attachShadow({ mode: 'open' }); element.shadowRoot!.innerHTML = '

Hello world

'; - return (window as any)._serialize(element.shadowRoot); + return window['_serialize'](element.shadowRoot); }); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal('ShadowRoot:

Hello world

'); + assert.equal(deserialized, 'ShadowRoot:

Hello world

'); }); it('handles RegExp', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize(/foo.*?\\/)); + const serialized = await page.evaluate(() => window['_serialize'](/foo.*?\\/)); const deserialized = await deserialize(serialized); - expect(deserialized instanceof RegExp).to.be.true; - expect(deserialized.source).to.equal('foo.*?\\\\'); - expect(deserialized.flags).to.equal(''); + assert.ok(deserialized instanceof RegExp); + assert.equal(deserialized.source, 'foo.*?\\\\'); + assert.equal(deserialized.flags, ''); }); it('handles RegExp with flags', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize(new RegExp('foo.*?\\\\', 'g')), + window['_serialize'](new RegExp('foo.*?\\\\', 'g')), ); const deserialized = await deserialize(serialized); - expect(deserialized instanceof RegExp).to.be.true; - expect(deserialized.source).to.equal('foo.*?\\\\'); - expect(deserialized.flags).to.equal('g'); + assert.ok(deserialized instanceof RegExp); + assert.equal(deserialized.source, 'foo.*?\\\\'); + assert.equal(deserialized.flags, 'g'); }); it('handles URL', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize(new URL('https://www.example.com')), + window['_serialize'](new URL('https://www.example.com')), ); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal('https://www.example.com/'); + assert.equal(deserialized, 'https://www.example.com/'); }); it('handles URLSearchparams', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize(new URLSearchParams('foo=bar&lorem=ipsum')), + window['_serialize'](new URLSearchParams('foo=bar&lorem=ipsum')), ); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal('URLSearchParams: foo=bar&lorem=ipsum'); + assert.equal(deserialized, 'URLSearchParams: foo=bar&lorem=ipsum'); }); it('handles classes', async () => { @@ -172,34 +177,34 @@ describe('serialize deserialize', function () { a = 1; b = 2; } - return (window as any)._serialize(new Foo()); + return window['_serialize'](new Foo()); }); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql({ a: 1, b: 2 }); - expect(deserialized.constructor.name).to.equal('Foo'); + assert.deepEqual({ ...deserialized }, { a: 1, b: 2 }); + assert.equal(deserialized.constructor.name, 'Foo'); }); it('handles objects', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize({ a: 1, b: 2 })); + const serialized = await page.evaluate(() => window['_serialize']({ a: 1, b: 2 })); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql({ a: 1, b: 2 }); + assert.deepEqual(deserialized, { a: 1, b: 2 }); }); it('handles arrays', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize([1, 2, 3])); + const serialized = await page.evaluate(() => window['_serialize']([1, 2, 3])); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql([1, 2, 3]); + assert.deepEqual(deserialized, [1, 2, 3]); }); it('handles objects', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize({ a: 1, b: 2 })); + const serialized = await page.evaluate(() => window['_serialize']({ a: 1, b: 2 })); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql({ a: 1, b: 2 }); + assert.deepEqual(deserialized, { a: 1, b: 2 }); }); it('handles objects with methods', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize({ + window['_serialize']({ foo() { return 'foo'; }, @@ -213,19 +218,19 @@ describe('serialize deserialize', function () { }), ); const deserialized = await deserialize(serialized); - expect(deserialized.foo).to.be.a('function'); - expect(deserialized.foo.name).to.equal('foo'); - expect(deserialized.bar).to.be.a('function'); - expect(deserialized.bar.name).to.equal('bar'); - expect(deserialized.baz).to.be.a('function'); - expect(deserialized.baz.name).to.equal('baz'); - expect(deserialized['my-element']).to.be.a('function'); - expect(deserialized['my-element'].name).to.equal('my-element'); + assert.equal(typeof deserialized.foo, 'function'); + assert.equal(deserialized.foo.name, 'foo'); + assert.equal(typeof deserialized.bar, 'function'); + assert.equal(deserialized.bar.name, 'bar'); + assert.equal(typeof deserialized.baz, 'function'); + assert.equal(deserialized.baz.name, 'baz'); + assert.equal(typeof deserialized['my-element'], 'function'); + assert.equal(deserialized['my-element'].name, 'my-element'); }); it('handles deep objects', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize({ + window['_serialize']({ myNumber: 123, myString: 'foo', myObject: { @@ -239,14 +244,14 @@ describe('serialize deserialize', function () { }), ); const deserialized = await deserialize(serialized); - expect(deserialized.myNumber).to.equal(123); - expect(deserialized.myString).to.equal('foo'); - expect(deserialized.myObject.myUrl).to.equal('http://www.example.com/'); - expect(deserialized.myObject.myMethod).to.be.a('function'); - expect(deserialized.myObject.myMethod.name).to.equal('myMethod'); - expect(deserialized.myObject.myRegExp).to.a('RegExp'); - expect(deserialized.myObject.myRegExp.source).to.equal('x'); - expect(deserialized.myArray).to.eql([1, '2']); + assert.equal(deserialized.myNumber, 123); + assert.equal(deserialized.myString, 'foo'); + assert.equal(deserialized.myObject.myUrl, 'http://www.example.com/'); + assert.equal(typeof deserialized.myObject.myMethod, 'function'); + assert.equal(deserialized.myObject.myMethod.name, 'myMethod'); + assert.ok(deserialized.myObject.myRegExp instanceof RegExp); + assert.equal(deserialized.myObject.myRegExp.source, 'x'); + assert.deepEqual(deserialized.myArray, [1, '2']); }); it('handles deep arrays', async () => { @@ -254,7 +259,7 @@ describe('serialize deserialize', function () { class Foo { x = 'y'; } - return (window as any)._serialize([ + return window['_serialize']([ 1, '2', /x/, @@ -264,27 +269,27 @@ describe('serialize deserialize', function () { ]); }); const deserialized = await deserialize(serialized); - expect(deserialized[0]).to.equal(1); - expect(deserialized[1]).to.equal('2'); - expect(deserialized[2]).to.a('RegExp'); - expect(deserialized[2].source).to.equal('x'); - expect(deserialized[3]).to.equal('http://www.example.com/'); - expect(deserialized[4]).to.equal('Symbol(foo)'); - expect(deserialized[5].a).to.equal(1); - expect(deserialized[5].b).to.equal(2); - expect(deserialized[5].c).to.equal('URLSearchParams: x=y'); - expect(deserialized[5].d).to.eql({ x: 'y' }); - expect(deserialized[5].d.constructor.name).to.equal('Foo'); + assert.equal(deserialized[0], 1); + assert.equal(deserialized[1], '2'); + assert.ok(deserialized[2] instanceof RegExp); + assert.equal(deserialized[2].source, 'x'); + assert.equal(deserialized[3], 'http://www.example.com/'); + assert.equal(deserialized[4], 'Symbol(foo)'); + assert.equal(deserialized[5].a, 1); + assert.equal(deserialized[5].b, 2); + assert.equal(deserialized[5].c, 'URLSearchParams: x=y'); + assert.deepEqual({ ...deserialized[5].d }, { x: 'y' }); + assert.equal(deserialized[5].d.constructor.name, 'Foo'); }); it('handles circular references', async () => { const serialized = await page.evaluate(() => { const foo: Record = {}; foo.circular = foo; - return (window as any)._serialize(foo); + return window['_serialize'](foo); }); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql({ + assert.deepEqual(deserialized, { circular: '[Circular]', }); }); @@ -295,10 +300,10 @@ describe('serialize deserialize', function () { foo.circular1 = foo; foo.x = { circular2: foo, lorem: 'ipsum' }; foo.y = { z: { a: 1, b: 2, circular3: foo } }; - return (window as any)._serialize(foo); + return window['_serialize'](foo); }); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql({ + assert.deepEqual(deserialized, { circular1: '[Circular]', x: { circular2: '[Circular]', @@ -318,10 +323,10 @@ describe('serialize deserialize', function () { const serialized = await page.evaluate(() => { const foo: Record = {}; foo.circulars = [foo, 'bar', foo]; - return (window as any)._serialize(foo); + return window['_serialize'](foo); }); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql({ circulars: ['[Circular]', 'bar', '[Circular]'] }); + assert.deepEqual(deserialized, { circulars: ['[Circular]', 'bar', '[Circular]'] }); }); it('handles generated circular references', async () => { @@ -329,11 +334,11 @@ describe('serialize deserialize', function () { const Foo = () => null; const obj: any = { f: Foo, x: null }; obj.x = obj; - return (window as any)._serialize(obj); + return window['_serialize'](obj); }); const deserialized = await deserialize(serialized); - expect(deserialized.f).to.be.a('function'); - expect(deserialized.x).to.equal('[Circular]'); + assert.equal(typeof deserialized.f, 'function'); + assert.equal(deserialized.x, '[Circular]'); }); it('handles errors', async () => { @@ -341,15 +346,15 @@ describe('serialize deserialize', function () { const c = () => new Error('my error msg'); const b = () => c(); const a = () => b(); - return (window as any)._serialize(a()); + return window['_serialize'](a()); }); const deserialized = await deserialize(serialized, defaultOptions); - expect(deserialized).to.be.a('string'); - expect(deserialized).to.include('my error msg'); - expect(deserialized).to.include('2:29'); - expect(deserialized).to.include('3:29'); - expect(deserialized).to.include('4:29'); - expect(deserialized).to.include('5:38'); + assert.equal(typeof deserialized, 'string'); + assert.ok(deserialized.includes('my error msg')); + assert.ok(deserialized.includes('2:23')); + assert.ok(deserialized.includes('3:23')); + assert.ok(deserialized.includes('4:23')); + assert.ok(deserialized.includes('5:35')); }); it('handles errors in objects', async () => { @@ -357,15 +362,15 @@ describe('serialize deserialize', function () { const c = () => new Error('my error msg'); const b = () => c(); const a = () => b(); - return (window as any)._serialize({ myError: a() }); + return window['_serialize']({ myError: a() }); }); const deserialized = await deserialize(serialized, defaultOptions); - expect(deserialized.myError).to.be.a('string'); - expect(deserialized.myError).to.include('my error msg'); - expect(deserialized.myError).to.include('2:29'); - expect(deserialized.myError).to.include('3:29'); - expect(deserialized.myError).to.include('4:29'); - expect(deserialized.myError).to.include('5:49'); + assert.equal(typeof deserialized.myError, 'string'); + assert.ok(deserialized.myError.includes('my error msg')); + assert.ok(deserialized.myError.includes('2:23')); + assert.ok(deserialized.myError.includes('3:23')); + assert.ok(deserialized.myError.includes('4:23')); + assert.ok(deserialized.myError.includes('5:46')); }); it('handles errors in arrays', async () => { @@ -373,24 +378,24 @@ describe('serialize deserialize', function () { const c = () => new Error('my error msg'); const b = () => c(); const a = () => b(); - return (window as any)._serialize([a(), b(), c()]); + return window['_serialize']([a(), b(), c()]); }); const deserialized = await deserialize(serialized, defaultOptions); - expect(deserialized[0]).to.be.a('string'); - expect(deserialized[0]).to.include('my error msg'); - expect(deserialized[0]).to.include('2:29'); - expect(deserialized[0]).to.include('3:29'); - expect(deserialized[0]).to.include('4:29'); - expect(deserialized[0]).to.include('5:39'); - expect(deserialized[1]).to.be.a('string'); - expect(deserialized[1]).to.include('my error msg'); - expect(deserialized[1]).to.include('2:29'); - expect(deserialized[1]).to.include('3:29'); - expect(deserialized[1]).to.include('5:44'); - expect(deserialized[2]).to.be.a('string'); - expect(deserialized[2]).to.include('my error msg'); - expect(deserialized[2]).to.include('2:29'); - expect(deserialized[2]).to.include('5:49'); + assert.equal(typeof deserialized[0], 'string'); + assert.ok(deserialized[0].includes('my error msg')); + assert.ok(deserialized[0].includes('2:23')); + assert.ok(deserialized[0].includes('3:23')); + assert.ok(deserialized[0].includes('4:23')); + assert.ok(deserialized[0].includes('5:36')); + assert.equal(typeof deserialized[1], 'string'); + assert.ok(deserialized[1].includes('my error msg')); + assert.ok(deserialized[1].includes('2:23')); + assert.ok(deserialized[1].includes('3:23')); + assert.ok(deserialized[1].includes('5:41')); + assert.equal(typeof deserialized[2], 'string'); + assert.ok(deserialized[2].includes('my error msg')); + assert.ok(deserialized[2].includes('2:23')); + assert.ok(deserialized[2].includes('5:46')); }); it('can map stack trace locations', async () => { @@ -398,15 +403,15 @@ describe('serialize deserialize', function () { const c = () => new Error('my error msg'); const b = () => c(); const a = () => b(); - return (window as any)._serialize(a()); + return window['_serialize'](a()); }); const deserialized = await deserialize(serialized, { ...defaultOptions, mapStackLocation: l => ({ ...l, filePath: `${l.filePath}__MAPPED__`, line: 1, column: 2 }), }); - expect(deserialized).to.be.a('string'); - expect(deserialized).to.include('my error msg'); - expect(deserialized).to.include(`__MAPPED__:1:2`); + assert.equal(typeof deserialized, 'string'); + assert.ok(deserialized.includes('my error msg')); + assert.ok(deserialized.includes(`__MAPPED__:1:2`)); }); it('mapped stack traces can be async', async () => { @@ -414,7 +419,7 @@ describe('serialize deserialize', function () { const c = () => new Error('my error msg'); const b = () => c(); const a = () => b(); - return (window as any)._serialize(a()); + return window['_serialize'](a()); }); const deserialized = await deserialize(serialized, { ...defaultOptions, @@ -423,9 +428,9 @@ describe('serialize deserialize', function () { return { ...l, filePath: `${l.filePath}__MAPPED__`, line: 1, column: 2 }; }, }); - expect(deserialized).to.be.a('string'); - expect(deserialized).to.include('my error msg'); - expect(deserialized).to.include(`__MAPPED__:1:2`); + assert.equal(typeof deserialized, 'string'); + assert.ok(deserialized.includes('my error msg')); + assert.ok(deserialized.includes(`__MAPPED__:1:2`)); }); it('can define a cwd below current directory', async () => { @@ -433,18 +438,18 @@ describe('serialize deserialize', function () { const c = () => new Error('my error msg'); const b = () => c(); const a = () => b(); - return (window as any)._serialize(a()); + return window['_serialize'](a()); }); const deserialized = await deserialize(serialized, { ...defaultOptions, - cwd: path.resolve(__dirname, '..'), + cwd: path.resolve(import.meta.dirname, '..'), }); - expect(deserialized).to.be.a('string'); - expect(deserialized).to.include('my error msg'); - expect(deserialized).to.include(`2:29`); - expect(deserialized).to.include(`3:29`); - expect(deserialized).to.include(`4:29`); - expect(deserialized).to.include(`5:38`); + assert.equal(typeof deserialized, 'string'); + assert.ok(deserialized.includes('my error msg')); + assert.ok(deserialized.includes(`2:23`)); + assert.ok(deserialized.includes(`3:23`)); + assert.ok(deserialized.includes(`4:23`)); + assert.ok(deserialized.includes(`5:35`)); }); it('can define a cwd above current directory', async () => { @@ -452,56 +457,56 @@ describe('serialize deserialize', function () { const c = () => new Error('my error msg'); const b = () => c(); const a = () => b(); - return (window as any)._serialize(a()); + return window['_serialize'](a()); }); const deserialized = await deserialize(serialized, { - cwd: path.resolve(__dirname, '..', 'foo'), - browserRootDir: path.resolve(__dirname, '..'), + cwd: path.resolve(import.meta.dirname, '..', 'foo'), + browserRootDir: path.resolve(import.meta.dirname, '..'), }); - expect(deserialized).to.be.a('string'); - expect(deserialized).to.include('my error msg'); - expect(deserialized).to.include(`2:29`); - expect(deserialized).to.include(`3:29`); - expect(deserialized).to.include(`4:29`); - expect(deserialized).to.include(`5:38`); + assert.equal(typeof deserialized, 'string'); + assert.ok(deserialized.includes('my error msg')); + assert.ok(deserialized.includes(`2:23`)); + assert.ok(deserialized.includes(`3:23`)); + assert.ok(deserialized.includes(`4:23`)); + assert.ok(deserialized.includes(`5:35`)); }); it('handles null', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize(null)); + const serialized = await page.evaluate(() => window['_serialize'](null)); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal(null); + assert.equal(deserialized, null); }); it('handles undefined', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize(undefined)); + const serialized = await page.evaluate(() => window['_serialize'](undefined)); const deserialized = await deserialize(serialized); - expect(deserialized).to.equal(undefined); + assert.equal(deserialized, undefined); }); it('handles undefined in an object', async () => { - const serialized = await page.evaluate(() => (window as any)._serialize({ x: undefined })); + const serialized = await page.evaluate(() => window['_serialize']({ x: undefined })); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql({ x: undefined }); + assert.deepEqual(deserialized, { x: undefined }); }); it('handles undefined in an array', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize([1, undefined, '2', undefined]), + window['_serialize']([1, undefined, '2', undefined]), ); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql([1, undefined, '2', undefined]); + assert.deepEqual(deserialized, [1, undefined, '2', undefined]); }); it('handles multiple undefined values', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize({ + window['_serialize']({ a: { a1: undefined, a2: undefined, a3: { x: undefined } }, b: undefined, c: { q: [1, undefined] }, }), ); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql({ + assert.deepEqual(deserialized, { a: { a1: undefined, a2: undefined, a3: { x: undefined } }, b: undefined, c: { q: [1, undefined] }, @@ -510,21 +515,21 @@ describe('serialize deserialize', function () { it('handles Promises', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize(new Promise(resolve => resolve(1))), + window['_serialize'](new Promise(resolve => resolve(1))), ); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql('Promise { }'); + assert.deepEqual(deserialized, 'Promise { }'); }); it('handles errors thrown during serialization', async () => { const serialized = await page.evaluate(() => - (window as any)._serialize({ + window['_serialize']({ get x() { throw new Error('error in getter'); }, }), ); const deserialized = await deserialize(serialized); - expect(deserialized).to.eql(null); + assert.deepEqual(deserialized, null); }); }); From ff6742ca942611995da415fc5697dbf36167c59a Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Tue, 2 Jun 2026 20:14:53 +0300 Subject: [PATCH 2/2] chore(browser-logs): remove leftover @esm-bundle/chai devDependency No longer needed after migration to node:assert/strict. Assisted-By: Claude Opus 4.6 (1M context) --- packages/browser-logs/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/browser-logs/package.json b/packages/browser-logs/package.json index e7d70bc034..b18ee2515d 100644 --- a/packages/browser-logs/package.json +++ b/packages/browser-logs/package.json @@ -49,7 +49,6 @@ "errorstacks": "^2.4.1" }, "devDependencies": { - "@esm-bundle/chai": "^4.1.5", "puppeteer": "^24.0.0" } }