From a1628d688114d7b0353ce4cd24b34303dd37c1a6 Mon Sep 17 00:00:00 2001 From: Denys Kuchma Date: Wed, 9 Sep 2026 14:38:10 +0200 Subject: [PATCH] Serialize data-driven object titles as JSON --- docs/advanced.md | 2 +- lib/data/context.js | 10 ++++------ test/unit/data/ui_test.js | 12 +++++++++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/advanced.md b/docs/advanced.md index fbd7b0677..e42de3c1f 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -79,7 +79,7 @@ Data(function*() { }).Scenario() // ... ``` -*HINT: If you don't use DataTable. add `toString()` method to each object added to data set, so the data could be pretty printed in a test name* +Objects in a data set are serialized as JSON in the test name. ## Debug diff --git a/lib/data/context.js b/lib/data/context.js index e52c55c4a..50936b8e0 100644 --- a/lib/data/context.js +++ b/lib/data/context.js @@ -72,13 +72,11 @@ function replaceTitle(title, dataRow) { return `${title} | ${dataRow.data.getMasked()}` } - // if `dataRow` is object and has own `toString()` method, - // it should be printed - if (Object.prototype.toString.call(dataRow.data) === Object().toString() && dataRow.data.toString() !== Object().toString()) { - return `${title} | ${dataRow.data}` - } + return `${title} | ${JSON.stringify(dataRow.data, maskSecret)}` +} - return `${title} | ${JSON.stringify(dataRow.data)}` +function maskSecret(key, value) { + return typeof value?.getMasked === 'function' ? value.getMasked() : value } function isTableDataRow(row) { diff --git a/test/unit/data/ui_test.js b/test/unit/data/ui_test.js index 77cadc285..ea18e4981 100644 --- a/test/unit/data/ui_test.js +++ b/test/unit/data/ui_test.js @@ -81,10 +81,10 @@ describe('ui', () => { dataScenarioConfig.scenarios.forEach(scenario => expect(helper).to.equal(scenario.test.config[helperName])) }) - it("should shows object's toString() method in each scenario's name if the toString() method is overridden", () => { - const data = [{ toString: () => 'test case title' }] + it("should use JSON in each scenario's name if the object overrides toString()", () => { + const data = [{ name: 'John Do', toString: () => 'test case title' }] const dataScenarioConfig = context.Data(data).Scenario('scenario', () => {}) - expect('scenario | test case title').to.equal(dataScenarioConfig.scenarios[0].test.title) + expect('scenario | {"name":"John Do"}').to.equal(dataScenarioConfig.scenarios[0].test.title) }) it("should shows JSON.stringify() in each scenario's name if the toString() method isn't overridden", () => { @@ -128,5 +128,11 @@ describe('ui', () => { const dataScenarioConfig = context.Data([new Secret('theSecretPassword')]).Scenario('scenario', () => {}) expect(dataScenarioConfig.scenarios[0].test.title).to.equal('scenario | *****') }) + + it("should not leak a skipped secret object's value into the title", () => { + const data = Secret.secret({ username: 'jon', password: 'theSecretPassword' }, 'password') + context.xData([data]).Scenario('scenario') + expect(suite.tests.at(-1).title).to.equal('scenario | {"username":"jon","password":"*****"}') + }) }) })