Skip to content

fix(data): detect DataTable structurally so Data() works under tsx/cjs (#5641)#5649

Merged
DavertMik merged 1 commit into
4.xfrom
fix/5641-datatable-instanceof
Jun 19, 2026
Merged

fix(data): detect DataTable structurally so Data() works under tsx/cjs (#5641)#5649
DavertMik merged 1 commit into
4.xfrom
fix/5641-datatable-instanceof

Conversation

@DavertMik

Copy link
Copy Markdown
Contributor

Fixes #5641

Problem

Data(table).Scenario(...) throws Invalid data type. Data accepts either: DataTable || generator || Array || function for a perfectly valid DataTable after migrating to 4.x. It works in 3.x.

import { dataTable as DataTable } from 'codeceptjs';

const cases = new DataTable(['input', 'expected']);
cases.add(['input1', 'expected1']);

Data(cases).Scenario('test something', ({ current }) => { /* ... */ });

Root cause

The check in lib/data/context.js is identity-based:

if (dataTable instanceof DataTable) { return dataTable.rows }

In a 4.x project configured with require: ['tsx/cjs'], the test file is transpiled to CommonJS, so import { dataTable } from 'codeceptjs' resolves through tsx's loader and the test gets its own copy of the DataTable class. The framework runs as ESM with a different DataTable class. So cases instanceof DataTable is false even though cases is a genuine DataTable, and the throw fires.

This worked in 3.x because everything was CommonJS — a single module registry and a single class. It's the same dual-module loading hazard behind #5632 / #5635.

Fix

Detect a DataTable structurally in addition to instanceof, which survives duplicate module instances:

function isDataTable(dataTable) {
  if (dataTable instanceof DataTable) return true
  return Boolean(dataTable) && Array.isArray(dataTable.array) && Array.isArray(dataTable.rows) && typeof dataTable.add === 'function'
}

The duck-type can't collide with the other accepted inputs — plain arrays, generators and functions all fail it and fall through to their existing branches, so behavior is otherwise unchanged.

Verification

  • Reproduced the exact failure (identical stack trace) against the tsx/cjs fixture, then confirmed all data rows run after the fix.
  • Added a regression unit test in test/unit/data/ui_test.js that feeds Data() a DataTable from a different class identity (simulating the tsx/cjs hazard without needing tsx).
  • All data unit tests pass.

🤖 Generated with Claude Code

#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 <noreply@anthropic.com>
@DavertMik DavertMik merged commit 7cb68de into 4.x Jun 19, 2026
13 checks passed
@DavertMik DavertMik deleted the fix/5641-datatable-instanceof branch June 19, 2026 22:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4.x: DataTable fails: Error: Invalid data type. Data accepts either: DataTable || generator || Array || function

1 participant