From 56c6f0004ac2dd6465633d1e03d9d3ea2c037e69 Mon Sep 17 00:00:00 2001 From: DavertMik Date: Sat, 20 Jun 2026 01:20:41 +0300 Subject: [PATCH] fix(data): detect DataTable structurally so Data() works under tsx/cjs (#5641) `Data(table)` threw "Invalid data type" for a valid DataTable when the test file is loaded via `require: ['tsx/cjs']`. tsx transpiles the test to CommonJS and gives it its own copy of the `DataTable` class, while the framework runs as ESM with a different copy, so the `instanceof DataTable` check fails for a genuine DataTable. Detect a DataTable by its structure (`array`/`rows` arrays + `add` method) in addition to `instanceof`, which survives duplicate module instances. Plain arrays, generators and functions still fall through to their own branches. Co-Authored-By: Claude Opus 4.8 --- lib/data/context.js | 7 ++++++- test/unit/data/ui_test.js | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/data/context.js b/lib/data/context.js index c2e0bc2e4..01b9c6403 100644 --- a/lib/data/context.js +++ b/lib/data/context.js @@ -82,8 +82,13 @@ function isTableDataRow(row) { return has.call(row, 'data') && has.call(row, 'skip') } +function isDataTable(dataTable) { + if (dataTable instanceof DataTable) return true + return Boolean(dataTable) && Array.isArray(dataTable.array) && Array.isArray(dataTable.rows) && typeof dataTable.add === 'function' +} + function detectDataType(dataTable) { - if (dataTable instanceof DataTable) { + if (isDataTable(dataTable)) { return dataTable.rows } diff --git a/test/unit/data/ui_test.js b/test/unit/data/ui_test.js index abe871734..8cfa7b730 100644 --- a/test/unit/data/ui_test.js +++ b/test/unit/data/ui_test.js @@ -97,5 +97,29 @@ describe('ui', () => { const dataScenarioConfig = context.Data(dataTable).Scenario('scenario', () => {}) expect('scenario | {"username":"Username","password":"*****"}').to.equal(dataScenarioConfig.scenarios[2].test.title) }) + + it('accepts a DataTable coming from a duplicate module instance', () => { + class ForeignDataTable { + constructor(array) { + this.array = array + this.rows = [] + } + + add(array) { + const data = {} + this.array.forEach((key, i) => (data[key] = array[i])) + this.rows.push({ skip: false, data }) + } + } + + const foreign = new ForeignDataTable(['username', 'password']) + foreign.add(['jon', 'snow']) + foreign.add(['tyrion', 'lannister']) + + expect(foreign).to.not.be.instanceOf(DataTable) + const dataScenarioConfig = context.Data(foreign).Scenario('scenario', () => {}) + expect(dataScenarioConfig.scenarios).to.have.lengthOf(2) + expect(dataScenarioConfig.scenarios[0].test.title).to.equal('scenario | {"username":"jon","password":"snow"}') + }) }) })