From 94ba4c6d58176c7c68682f80cc8c2a81feff1e32 Mon Sep 17 00:00:00 2001 From: NarrowsProjects Date: Tue, 23 Jun 2026 16:38:46 +0200 Subject: [PATCH 1/4] feat: make textTokenFilterModel extendRawTextFilterModel --- .../common/filters/TextTokensFilterModel.js | 49 ++----------------- 1 file changed, 4 insertions(+), 45 deletions(-) diff --git a/lib/public/components/Filters/common/filters/TextTokensFilterModel.js b/lib/public/components/Filters/common/filters/TextTokensFilterModel.js index 8c838e5abf..450877df99 100644 --- a/lib/public/components/Filters/common/filters/TextTokensFilterModel.js +++ b/lib/public/components/Filters/common/filters/TextTokensFilterModel.js @@ -10,8 +10,7 @@ * granted to it by virtue of its status as an Intergovernmental Organization * or submit itself to any jurisdiction. */ -import { Observable } from '/js/src/index.js'; -import { FilterModel } from '../FilterModel.js'; +import { RawTextFilterModel } from './RawTextFilterModel.js'; const TOKENS_DELIMITER = ','; @@ -19,52 +18,12 @@ const TOKENS_DELIMITER = ','; * Model which accept string input and treats it as sequence of tokens, which processed in regard to given configuration. @see * TextTokensFilterModel#constructor */ -export class TextTokensFilterModel extends FilterModel { +export class TextTokensFilterModel extends RawTextFilterModel { /** * Constructor */ constructor() { super(); - this._raw = ''; - this._visualChange$ = new Observable(); - } - - /** - * Update value kept by a filter model and inform observers that some change occurred - * @param {string} value value to be stored - * @return {void} - */ - update(value) { - const { _raw: previousRaw } = this; - this._raw = value; - if (previousRaw === value) { - this._visualChange$.notify(); - } else { - this.notify(); - } - } - - /** - * Returns the raw value of the filter - */ - get raw() { - return this._raw; - } - - /** - * Reset the filter to its initial state - * @return {void} - */ - reset() { - this._raw = ''; - } - - /** - * States if the filter has been filled - * @return {boolean} true if the filter is empty - */ - get isEmpty() { - return this._raw.length === 0; } /** @@ -72,7 +31,7 @@ export class TextTokensFilterModel extends FilterModel { * @return {string[]} the normalized value */ get normalized() { - return this._raw + return this._value .split(TOKENS_DELIMITER) .map((token) => token.trim()) .filter((token) => token.length > 0); @@ -82,7 +41,7 @@ export class TextTokensFilterModel extends FilterModel { * @inheritDoc */ set normalized(value) { - this._raw = value.join(TOKENS_DELIMITER); + this._value = value.join(TOKENS_DELIMITER); } /** From 249468629620cce22e41a34ebb9301768b89ce0a Mon Sep 17 00:00:00 2001 From: NarrowsProjects Date: Tue, 23 Jun 2026 16:39:26 +0200 Subject: [PATCH 2/4] chore: replace all mentions of textFilters to inputFilters --- .../ActiveColumns/dataPassesActiveColumns.js | 4 ++-- .../ActiveColumns/qcFlagTypesActiveColumns.js | 6 +++--- .../simulationPassesActiveColumns.js | 7 ++----- .../ActiveColumns/lhcPeriodsActiveColumns.js | 17 ++++------------- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/lib/public/views/DataPasses/ActiveColumns/dataPassesActiveColumns.js b/lib/public/views/DataPasses/ActiveColumns/dataPassesActiveColumns.js index e0b6d87316..4df4cbf04c 100644 --- a/lib/public/views/DataPasses/ActiveColumns/dataPassesActiveColumns.js +++ b/lib/public/views/DataPasses/ActiveColumns/dataPassesActiveColumns.js @@ -20,7 +20,7 @@ import { h } from '/js/src/index.js'; import { formatDataPassName } from '../format/formatDataPassName.js'; import { formatDataPassStatusHistory } from '../format/formatStatusHistory.js'; import { checkboxes } from '../../../components/Filters/common/filters/checkboxFilter.js'; -import { textFilter } from '../../../components/Filters/common/filters/textFilter.js'; +import { textInputFilter } from '../../../components/Filters/common/filters/textInputFilter.js'; /** * List of active columns for a generic data passes table @@ -35,7 +35,7 @@ export const dataPassesActiveColumns = { visible: true, sortable: true, format: (_, dataPass) => formatDataPassName(dataPass), - filter: (filteringModel) => textFilter(filteringModel.get('names'), { class: 'w-75 mt1', placeholder: 'e.g. LHC22a, lhc23b, ...' }), + filter: (filteringModel) => textInputFilter(filteringModel, 'names', 'e.g. LHC22a, lhc23b, ...'), balloon: true, classes: 'w-20', }, diff --git a/lib/public/views/QcFlagTypes/ActiveColumns/qcFlagTypesActiveColumns.js b/lib/public/views/QcFlagTypes/ActiveColumns/qcFlagTypesActiveColumns.js index 6f1ae72b84..1f3bac4f3e 100644 --- a/lib/public/views/QcFlagTypes/ActiveColumns/qcFlagTypesActiveColumns.js +++ b/lib/public/views/QcFlagTypes/ActiveColumns/qcFlagTypesActiveColumns.js @@ -13,9 +13,9 @@ import { h } from '/js/src/index.js'; import { formatTimestamp } from '../../../utilities/formatting/formatTimestamp.js'; -import { textFilter } from '../../../components/Filters/common/filters/textFilter.js'; import { qcFlagTypeColoredBadge } from '../../../components/qcFlags/qcFlagTypeColoredBadge.js'; import radioButtonFilter from '../../../components/Filters/common/filters/radioButtonFilter.js'; +import { textInputFilter } from '../../../components/Filters/common/filters/textInputFilter.js'; /** * List of active columns for a QC Flag Types table @@ -30,7 +30,7 @@ export const qcFlagTypesActiveColumns = { name: { name: 'Name', visible: true, - filter: ({ filteringModel }) => textFilter(filteringModel.get('names'), { class: 'w-75 mt1', placeholder: 'e.g. BadPID, ...' }), + filter: ({ filteringModel }) => textInputFilter(filteringModel, 'names', 'e.g. BadPID, ...'), classes: 'f6', sortable: true, format: (_, qcFlagType) => qcFlagTypeColoredBadge(qcFlagType), @@ -40,7 +40,7 @@ export const qcFlagTypesActiveColumns = { name: 'Method', visible: true, sortable: true, - filter: ({ filteringModel }) => textFilter(filteringModel.get('methods'), { class: 'w-75 mt1', placeholder: 'e.g. Bad PID, ...' }), + filter: ({ filteringModel }) => textInputFilter(filteringModel, 'methods', 'e.g. Bad PID, ...'), classes: 'f6', }, diff --git a/lib/public/views/SimulationPasses/ActiveColumns/simulationPassesActiveColumns.js b/lib/public/views/SimulationPasses/ActiveColumns/simulationPassesActiveColumns.js index 95f9940c22..3085772121 100644 --- a/lib/public/views/SimulationPasses/ActiveColumns/simulationPassesActiveColumns.js +++ b/lib/public/views/SimulationPasses/ActiveColumns/simulationPassesActiveColumns.js @@ -11,13 +11,13 @@ * or submit itself to any jurisdiction. */ -import { textFilter } from '../../../components/Filters/common/filters/textFilter.js'; import { absoluteFrontLink } from '../../../components/common/navigation/absoluteFrontLink.js'; import { frontLink } from '../../../components/common/navigation/frontLink.js'; import { externalLinks } from '../../../components/common/navigation/externalLinks.js'; import { formatItemsCount } from '../../../utilities/formatting/formatItemsCount.js'; import { formatSizeInBytes } from '../../../utilities/formatting/formatSizeInBytes.js'; import { badge } from '../../../components/common/badge.js'; +import { textInputFilter } from '../../../components/Filters/common/filters/textInputFilter.js'; /** * List of active columns for a generic simulation passes table @@ -31,10 +31,7 @@ export const simulationPassesActiveColumns = { name: 'Name', visible: true, sortable: true, - filter: ({ filteringModel }) => textFilter( - filteringModel.get('names'), - { class: 'w-75 mt1', placeholder: 'e.g. LHC23k5, ...' }, - ), + filter: ({ filteringModel }) => textInputFilter(filteringModel, 'names', 'e.g. LHC23k5, ...'), classes: 'w-10 f6', }, diff --git a/lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js b/lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js index 6c312fbecf..e2c1a2a7c3 100644 --- a/lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js +++ b/lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js @@ -14,9 +14,9 @@ import { h } from '/js/src/index.js'; import { formatDistinctLhcBeamEnergies } from '../format/formatDistinctLhcBeamEnergies.js'; import { formatLhcPeriodYear } from '../format/formatYear.js'; -import { textFilter } from '../../../components/Filters/common/filters/textFilter.js'; import { frontLink } from '../../../components/common/navigation/frontLink.js'; import { badge } from '../../../components/common/badge.js'; +import { textInputFilter } from '../../../components/Filters/common/filters/textInputFilter.js'; /** * List of active columns for a generic periods table @@ -30,10 +30,7 @@ export const lhcPeriodsActiveColumns = { name: 'Name', visible: true, sortable: true, - filter: ({ filteringModel }) => textFilter( - filteringModel.get('names'), - { class: 'w-75 mt1', placeholder: 'e.g. LHC22a, lhc23b, ...' }, - ), + filter: ({ filteringModel }) => textInputFilter(filteringModel, 'names', 'e.g. LHC22a, lhc23b, ...'), classes: 'w-15', }, @@ -92,10 +89,7 @@ export const lhcPeriodsActiveColumns = { visible: true, sortable: true, format: (_, lhcPeriod) => formatLhcPeriodYear(lhcPeriod.name), - filter: ({ filteringModel }) => textFilter( - filteringModel.get('years'), - { class: 'w-75 mt1', placeholder: 'e.g. 2022, 2023, ...' }, - ), + filter: ({ filteringModel }) => textInputFilter(filteringModel, 'years', 'e.g. 2022, 2023, ...'), classes: 'w-7', }, @@ -104,10 +98,7 @@ export const lhcPeriodsActiveColumns = { visible: true, sortable: true, format: (pdpBeamTypes) => pdpBeamTypes.length > 0 ? pdpBeamTypes.join(',') : '-', - filter: ({ filteringModel }) => textFilter( - filteringModel.get('pdpBeamTypes'), - { class: 'w-75 mt1', placeholder: 'e.g. pp, PbPb' }, - ), + filter: ({ filteringModel }) => textInputFilter(filteringModel, 'pdpBeamTypes', 'e.g. pp, PbPb'), classes: 'w-7', }, From 26489db952b1e70366c78486270f6cda0967c57b Mon Sep 17 00:00:00 2001 From: NarrowsProjects Date: Tue, 23 Jun 2026 16:40:50 +0200 Subject: [PATCH 3/4] chore: delete the textFilters component --- .../Filters/common/filters/textFilter.js | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 lib/public/components/Filters/common/filters/textFilter.js diff --git a/lib/public/components/Filters/common/filters/textFilter.js b/lib/public/components/Filters/common/filters/textFilter.js deleted file mode 100644 index d6ae0cdfa4..0000000000 --- a/lib/public/components/Filters/common/filters/textFilter.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @license - * Copyright CERN and copyright holders of ALICE O2. This software is - * distributed under the terms of the GNU General Public License v3 (GPL - * Version 3), copied verbatim in the file "COPYING". - * - * See http://alice-o2.web.cern.ch/license for full licensing information. - * - * In applying this license CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. - */ - -import { h } from '/js/src/index.js'; - -/** - * Returns a text filter component - * - * @param {TextTokensFilterModel} textTokensFilterModel the model of the text filter - * @param {Object} attributes the additional attributes to pass to the component, such as id and classes - * @return {Component} the filter component - */ -export const textFilter = (textTokensFilterModel, attributes) => h('input', { - ...attributes, - type: 'text', - value: textTokensFilterModel.raw, - oninput: (e) => textTokensFilterModel.update(e.target.value), -}, ''); From 0c25b53eda6edbd8a0cb4c7d1c0083b669487457 Mon Sep 17 00:00:00 2001 From: NarrowsProjects Date: Tue, 23 Jun 2026 16:41:23 +0200 Subject: [PATCH 4/4] test: change tests to send the 'changed' event instead of input --- test/public/Filters/FilteringModel.test.js | 4 ++-- test/public/Filters/filtersToUrl.test.js | 16 ++++++++-------- .../dataPasses/overviewPerLhcPeriod.test.js | 2 +- .../dataPasses/overviewPerSimulationPass.test.js | 2 +- test/public/lhcPeriods/overview.test.js | 6 +++--- test/public/qcFlagTypes/overview.test.js | 4 ++-- .../overviewAnchoredSimulationPasses.test.js | 4 ++-- .../overviewPerLhcPeriod.test.js | 4 ++-- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/public/Filters/FilteringModel.test.js b/test/public/Filters/FilteringModel.test.js index a00ff7996b..f6ba77b097 100644 --- a/test/public/Filters/FilteringModel.test.js +++ b/test/public/Filters/FilteringModel.test.js @@ -143,9 +143,9 @@ module.exports = () => { await waitForTableTotalRowsCountToEqual(page, 3); // Name - await fillInput(page, '.name-filter input', 'LHC23f'); + await fillInput(page, '.names-textFilter', 'LHC23f', ['change']); await waitForTableTotalRowsCountToEqual(page, 1); - await fillInput(page, '.name-filter input', 'bogus'); + await fillInput(page, '.names-textFilter', 'bogus', ['change']); await waitForTableTotalRowsCountToEqual(page, 0); await page.goBack(); await waitForTableTotalRowsCountToEqual(page, 1); diff --git a/test/public/Filters/filtersToUrl.test.js b/test/public/Filters/filtersToUrl.test.js index c89547e244..a8aa644af7 100644 --- a/test/public/Filters/filtersToUrl.test.js +++ b/test/public/Filters/filtersToUrl.test.js @@ -256,9 +256,9 @@ module.exports = () => { it('should set filters from lhcPriodOverview to the URL', async () => { await goToPage(page, 'lhc-period-overview'); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC22a'); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(2) input[type=text]', '2022'); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(3) input[type=text]', 'PbPb'); + await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC22a', ['change']); + await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(2) input[type=text]', '2022', ['change']); + await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(3) input[type=text]', 'PbPb', ['change']); const queryParameters = getQueryParameters(page); expect(queryParameters).to.deep.equal({ "page": "lhc-period-overview", @@ -271,8 +271,8 @@ module.exports = () => { it('should set filters from qcFlagTypesOverview to the URL', async () => { await goToPage(page, 'qc-flag-types-overview'); - await fillInput(page, '.name-filter input[type=text]', 'bad'); - await fillInput(page, '.method-filter input[type=text]', 'bad'); + await fillInput(page, '.name-filter input[type=text]', 'bad', ['change']); + await fillInput(page, '.method-filter input[type=text]', 'bad', ['change']); await pressElement(page, '#badFilterRadioBad', true); const queryParameters = getQueryParameters(page); @@ -343,7 +343,7 @@ module.exports = () => { it('should set filters from DataPassesPerLhcPeriodOverview to the URL', async () => { await goToPage(page, 'data-passes-per-lhc-period-overview', { queryParameters: { lhcPeriodId: 2 }}); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC22b_apass1', ['input']); + await fillInput(page, '.names-textFilter', 'LHC22b_apass1', ['change']); await pressElement(page, '#checkboxes-checkbox-test', true); @@ -359,7 +359,7 @@ module.exports = () => { it('should set filters from DataPassesPerSimulationPassOverview to the URL', async () => { await goToPage(page, 'data-passes-per-simulation-pass-overview', { queryParameters: { simulationPassId: 1 }}); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC22b_apass1', ['input']); + await fillInput(page, '.names-textFilter', 'LHC22b_apass1', ['change']); await pressElement(page, '#checkboxes-checkbox-test', true); const queryParameters = getQueryParameters(page); @@ -374,7 +374,7 @@ module.exports = () => { it('should set filters from AnchoredSimulationPassesOverview to the URL', async () => { await goToPage(page, 'anchored-simulation-passes-overview', { queryParameters: { dataPassId: 1 }}); - await fillInput(page, '.name-filter input', 'LHC23k6c', ['input']); + await fillInput(page, '.names-textFilter', 'LHC23k6c', ['change']); const queryParameters = getQueryParameters(page); expect(queryParameters).to.deep.equal({ diff --git a/test/public/dataPasses/overviewPerLhcPeriod.test.js b/test/public/dataPasses/overviewPerLhcPeriod.test.js index a6215dd989..6257847a00 100644 --- a/test/public/dataPasses/overviewPerLhcPeriod.test.js +++ b/test/public/dataPasses/overviewPerLhcPeriod.test.js @@ -164,7 +164,7 @@ module.exports = () => { it('should successfully apply data pass name filter', async () => { await pressElement(page, '#openFilterToggle'); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC22b_apass1'); + await fillInput(page, '.names-textFilter', 'LHC22b_apass1', ['change']); await expectColumnValues(page, 'name', ['deleted\nLHC22b_apass1\nSkimmable']); diff --git a/test/public/dataPasses/overviewPerSimulationPass.test.js b/test/public/dataPasses/overviewPerSimulationPass.test.js index 188ec17dc2..a75fbd1391 100644 --- a/test/public/dataPasses/overviewPerSimulationPass.test.js +++ b/test/public/dataPasses/overviewPerSimulationPass.test.js @@ -113,7 +113,7 @@ module.exports = () => { it('should successfully apply data pass name filter', async () => { await pressElement(page, '#openFilterToggle'); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC22b_apass1'); + await fillInput(page, '.names-textFilter', 'LHC22b_apass1', ['change']); await expectColumnValues(page, 'name', ['deleted\nLHC22b_apass1\nSkimmable']); await pressElement(page, '#reset-filters', true); diff --git a/test/public/lhcPeriods/overview.test.js b/test/public/lhcPeriods/overview.test.js index 13beb52714..b203a1677a 100644 --- a/test/public/lhcPeriods/overview.test.js +++ b/test/public/lhcPeriods/overview.test.js @@ -128,7 +128,7 @@ module.exports = () => { await goToPage(page, 'lhc-period-overview'); await pressElement(page, '#openFilterToggle'); await page.waitForSelector('#reset-filters:disabled'); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC22a'); + await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC22a', ['change']); await expectColumnValues(page, 'name', ['LHC22a']); await pressElement(page, '#reset-filters', true); await expectColumnValues(page, 'name', ['LHC23f', 'LHC22b', 'LHC22a']); @@ -139,7 +139,7 @@ module.exports = () => { await goToPage(page, 'lhc-period-overview'); await pressElement(page, '#openFilterToggle'); await page.waitForSelector('#reset-filters:disabled'); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(2) input[type=text]', '2022'); + await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(2) input[type=text]', '2022', ['change']); await page.waitForSelector('#reset-filters:disabled', { hidden: true, timeout: 250 }); await expectColumnValues(page, 'year', ['2022', '2022']); }); @@ -148,7 +148,7 @@ module.exports = () => { await goToPage(page, 'lhc-period-overview'); await pressElement(page, '#openFilterToggle'); await page.waitForSelector('#reset-filters:disabled'); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(3) input[type=text]', 'PbPb'); + await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(3) input[type=text]', 'PbPb', ['change']); await page.waitForSelector('#reset-filters:disabled', { hidden: true, timeout: 250 }); await expectColumnValues(page, 'pdpBeamTypes', ['PbPb']); }); diff --git a/test/public/qcFlagTypes/overview.test.js b/test/public/qcFlagTypes/overview.test.js index 77b4fe656b..0bff97f343 100644 --- a/test/public/qcFlagTypes/overview.test.js +++ b/test/public/qcFlagTypes/overview.test.js @@ -94,7 +94,7 @@ module.exports = () => { await waitForTableLength(page, 7); await pressElement(page, '#openFilterToggle'); - await fillInput(page, '.name-filter input[type=text]', 'bad'); + await fillInput(page, '.name-filter input[type=text]', 'bad', ['change']); await checkColumnValuesWithRegex(page, 'name', '[Bb][Aa][Dd]'); await pressElement(page, '#reset-filters', true); @@ -103,7 +103,7 @@ module.exports = () => { it('should successfully apply QC flag type method filter', async () => { await waitForTableLength(page, 7); - await fillInput(page, '.method-filter input[type=text]', 'bad'); + await fillInput(page, '.method-filter input[type=text]', 'bad', ['change']); await checkColumnValuesWithRegex(page, 'method', '[Bb][Aa][Dd]'); await pressElement(page, '#reset-filters', true); diff --git a/test/public/simulationPasses/overviewAnchoredSimulationPasses.test.js b/test/public/simulationPasses/overviewAnchoredSimulationPasses.test.js index 2693c2000c..0c801f9c00 100644 --- a/test/public/simulationPasses/overviewAnchoredSimulationPasses.test.js +++ b/test/public/simulationPasses/overviewAnchoredSimulationPasses.test.js @@ -117,10 +117,10 @@ module.exports = () => { await goToPage(page, 'anchored-simulation-passes-overview', { queryParameters: { dataPassId: 3 } }); await pressElement(page, '#openFilterToggle'); - await fillInput(page, '.name-filter input[type=text]', 'LHC23k6a'); + await fillInput(page, '.name-filter input[type=text]', 'LHC23k6a', ['change']); await expectColumnValues(page, 'name', ['LHC23k6a']); - await fillInput(page, '.name-filter input[type=text]', 'LHC23k6a, LHC23k6b'); + await fillInput(page, '.name-filter input[type=text]', 'LHC23k6a, LHC23k6b', ['change']); await expectColumnValues(page, 'name', ['LHC23k6b', 'LHC23k6a']); }); }; diff --git a/test/public/simulationPasses/overviewPerLhcPeriod.test.js b/test/public/simulationPasses/overviewPerLhcPeriod.test.js index c80de33d5f..bcad3fab5b 100644 --- a/test/public/simulationPasses/overviewPerLhcPeriod.test.js +++ b/test/public/simulationPasses/overviewPerLhcPeriod.test.js @@ -131,10 +131,10 @@ module.exports = () => { await goToPage(page, 'simulation-passes-per-lhc-period-overview', { queryParameters: { lhcPeriodId: 1 } }); await pressElement(page, '#openFilterToggle'); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC23k6a'); + await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC23k6a', ['change']); await expectColumnValues(page, 'name', ['LHC23k6a']); - await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC23k6a, LHC23k6b'); + await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(1) input[type=text]', 'LHC23k6a, LHC23k6b', ['change']); await expectColumnValues(page, 'name', ['LHC23k6b', 'LHC23k6a']); }); };