Skip to content

Commit f76b411

Browse files
danilsomsikovDevtools-frontend LUCI CQ
authored andcommitted
Apply UI eng vision to the KeyValueStorageItemsView
To make it work, implement refresh callback in the data grid web component add make VBox understand element as the first parameter. This could be further improved, but removing the view output and propagate the preview value through this HTML template, but this is left for later. Bug: 394287937 Change-Id: Ic92aaeace4bf90610a46e7882c43736f5451a578 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6249842 Reviewed-by: Benedikt Meurer <[email protected]> Commit-Queue: Danil Somsikov <[email protected]>
1 parent 46c954f commit f76b411

File tree

8 files changed

+256
-198
lines changed

8 files changed

+256
-198
lines changed

front_end/panels/application/ExtensionStorageItemsView.test.ts

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@
55
import type * as Common from '../../core/common/common.js';
66
import type * as SDK from '../../core/sdk/sdk.js';
77
import * as Protocol from '../../generated/protocol.js';
8-
import {dispatchKeyDownEvent, raf} from '../../testing/DOMHelpers.js';
98
import {createTarget} from '../../testing/EnvironmentHelpers.js';
109
import {
1110
describeWithMockConnection,
1211
} from '../../testing/MockConnection.js';
13-
import {getCellElementFromNodeAndColumnId, selectNodeByKey} from '../../testing/StorageItemsViewHelpers.js';
1412
import * as RenderCoordinator from '../../ui/components/render_coordinator/render_coordinator.js';
15-
import type * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
13+
import * as UI from '../../ui/legacy/legacy.js';
1614

1715
import * as Resources from './application.js';
1816

@@ -86,6 +84,17 @@ describeWithMockConnection('ExtensionStorageItemsView', function() {
8684
extensionStorageModel, TEST_EXTENSION_ID, TEST_EXTENSION_NAME, Protocol.Extensions.StorageArea.Local);
8785
});
8886

87+
function createView(): {view: View.ExtensionStorageItemsView, viewFunction: sinon.SinonStub} {
88+
const viewFunction = sinon.stub();
89+
viewFunction.callsFake((_input, output, _target) => {
90+
output.splitWidget = sinon.createStubInstance(UI.SplitWidget.SplitWidget);
91+
output.preview = new UI.Widget.VBox();
92+
output.resizer = sinon.createStubInstance(HTMLElement);
93+
});
94+
const view = new View.ExtensionStorageItemsView(extensionStorage, viewFunction);
95+
return {view, viewFunction};
96+
}
97+
8998
it('displays items', async () => {
9099
assert.exists(extensionStorageModel);
91100
sinon.stub(extensionStorageModel.agent, 'invoke_getStorageItems')
@@ -95,16 +104,13 @@ describeWithMockConnection('ExtensionStorageItemsView', function() {
95104
getError: () => undefined,
96105
});
97106

98-
const view = new View.ExtensionStorageItemsView(extensionStorage);
107+
const {view, viewFunction} = createView();
99108

100109
const itemsListener = new ExtensionStorageItemsListener(view.extensionStorageItemsDispatcher);
101110
await itemsListener.waitForItemsRefreshed();
102111

103112
assert.deepEqual(
104-
view.getEntriesForTesting(), Object.keys(EXAMPLE_DATA).map(key => ({key, value: EXAMPLE_DATA[key]})));
105-
106-
await RenderCoordinator.done();
107-
view.detach();
113+
viewFunction.lastCall.firstArg.items, Object.keys(EXAMPLE_DATA).map(key => ({key, value: EXAMPLE_DATA[key]})));
108114
});
109115

110116
it('correctly parses set values as JSON, with string fallback', async () => {
@@ -118,34 +124,21 @@ describeWithMockConnection('ExtensionStorageItemsView', function() {
118124
const setStorageItems =
119125
sinon.stub(extensionStorageModel.agent, 'invoke_setStorageItems').resolves({getError: () => undefined});
120126

121-
const view = new View.ExtensionStorageItemsView(extensionStorage);
122-
const dataGrid = view.dataGridForTesting;
127+
const {view, viewFunction} = createView();
123128
const itemsListener = new ExtensionStorageItemsListener(view.extensionStorageItemsDispatcher);
124129
await itemsListener.waitForItemsRefreshed();
125130

126-
view.markAsRoot();
127-
view.show(document.body);
128-
await raf();
129-
130131
const expectedResults = [
131132
{input: '{foo: "bar"}', parsedValue: {foo: 'bar'}},
132133
{input: 'value', parsedValue: 'value'},
133134
];
134135

135136
for (const {input, parsedValue} of expectedResults) {
136137
const key = Object.keys(EXAMPLE_DATA)[0];
137-
const node = selectNodeByKey(dataGrid, key);
138-
assert.exists(node);
139-
await raf();
140-
141-
const selectedNode = node as DataGrid.DataGrid.DataGridNode<Protocol.Storage.SharedStorageEntry>;
142-
dataGrid.startEditingNextEditableColumnOfDataGridNode(selectedNode, 'value', true);
143-
144-
const cellElement = getCellElementFromNodeAndColumnId(dataGrid, selectedNode, 'value');
145-
assert.exists(cellElement);
138+
viewFunction.lastCall.firstArg.onEdit(new CustomEvent('edit', {
139+
detail: {node: {dataset: {key}}, columnId: 'value', valueBeforeEditing: EXAMPLE_DATA[key], newText: input}
140+
}));
146141

147-
cellElement.textContent = input;
148-
dispatchKeyDownEvent(cellElement, {key: 'Enter'});
149142
await itemsListener.waitForItemsEdited();
150143
setStorageItems.calledOnceWithExactly(
151144
{id: TEST_EXTENSION_ID, storageArea: Protocol.Extensions.StorageArea.Local, values: {[key]: parsedValue}});

front_end/panels/application/ExtensionStorageItemsView.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import * as UI from '../../ui/legacy/legacy.js';
3939
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
4040

4141
import type {ExtensionStorage} from './ExtensionStorageModel.js';
42-
import {KeyValueStorageItemsView} from './KeyValueStorageItemsView.js';
42+
import {KeyValueStorageItemsView, type View as KeyValueStorageItemsViewFunction} from './KeyValueStorageItemsView.js';
4343

4444
const UIStrings = {
4545
/**
@@ -72,8 +72,8 @@ export class ExtensionStorageItemsView extends KeyValueStorageItemsView {
7272
readonly extensionStorageItemsDispatcher:
7373
Common.ObjectWrapper.ObjectWrapper<ExtensionStorageItemsDispatcher.EventTypes>;
7474

75-
constructor(extensionStorage: ExtensionStorage) {
76-
super(i18nString(UIStrings.extensionStorageItems), 'extension-storage', true);
75+
constructor(extensionStorage: ExtensionStorage, view?: KeyValueStorageItemsViewFunction) {
76+
super(i18nString(UIStrings.extensionStorageItems), 'extension-storage', true, view);
7777

7878
this.element.setAttribute('jslog', `${VisualLogging.pane().context('extension-storage-data')}`);
7979
this.element.classList.add('storage-view', 'table');
@@ -183,11 +183,4 @@ export class ExtensionStorageItemsView extends KeyValueStorageItemsView {
183183
throw new Error('Unable to clear storage.');
184184
});
185185
}
186-
187-
getEntriesForTesting(): Array<{key: string, value: string}> {
188-
return this.dataGridForTesting.rootNode().children.filter(node => node.data.key).map(node => (node.data as {
189-
key: string,
190-
value: string,
191-
}));
192-
}
193186
}

front_end/panels/application/KeyValueStorageItemsView.test.ts

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@ import {
88
} from '../../testing/DOMHelpers.js';
99
import {describeWithEnvironment} from '../../testing/EnvironmentHelpers.js';
1010
import {expectCalled} from '../../testing/ExpectStubCall.js';
11-
import {
12-
selectNodeByKey,
13-
} from '../../testing/StorageItemsViewHelpers.js';
1411
import * as UI from '../../ui/legacy/legacy.js';
1512

1613
import * as Application from './application.js';
1714

1815
describeWithEnvironment('KeyValueStorageItemsView', () => {
1916
let keyValueStorageItemsView: Application.KeyValueStorageItemsView.KeyValueStorageItemsView;
17+
let viewFunction: sinon.SinonStub;
2018

2119
const MOCK_ITEMS = [
2220
{key: 'foo', value: 'value1'},
@@ -55,7 +53,14 @@ describeWithEnvironment('KeyValueStorageItemsView', () => {
5553
container.markAsRoot();
5654
container.show(div);
5755

58-
keyValueStorageItemsView = new TestKeyValueStorageItemsView('Items', 'key-value-storage-items-view', true);
56+
viewFunction = sinon.stub();
57+
viewFunction.callsFake((_input, output, _target) => {
58+
output.splitWidget = sinon.createStubInstance(UI.SplitWidget.SplitWidget);
59+
output.preview = new UI.Widget.VBox();
60+
output.resizer = sinon.createStubInstance(HTMLElement);
61+
});
62+
keyValueStorageItemsView =
63+
new TestKeyValueStorageItemsView('Items', 'key-value-storage-items-view', true, viewFunction);
5964

6065
keyValueStorageItemsView.showItems(MOCK_ITEMS);
6166
});
@@ -70,29 +75,17 @@ describeWithEnvironment('KeyValueStorageItemsView', () => {
7075
const createPreviewPromise = expectCreatePreviewCalled(key, value);
7176

7277
// Select the first item by key.
73-
const node = selectNodeByKey(keyValueStorageItemsView.dataGridForTesting, key);
74-
assert.isNotNull(node);
78+
viewFunction.lastCall.firstArg.onSelect(new CustomEvent('select', {detail: {dataset: {key, value}}}));
7579

7680
// Check createPreview function was called.
7781
await createPreviewPromise;
78-
79-
// Check preview was updated.
80-
await raf();
8182
assert.include(keyValueStorageItemsView.previewPanelForTesting.element.innerText, `${key}:${value}`);
8283
});
8384

8485
it('shows empty preview when no row is selected', async () => {
85-
// Select the first item by key.
86-
const node = selectNodeByKey(keyValueStorageItemsView.dataGridForTesting, MOCK_ITEMS[0].key);
87-
assert.isNotNull(node);
88-
86+
viewFunction.lastCall.firstArg.onSelect(new CustomEvent('select', {detail: {dataset: {key: MOCK_ITEMS[0].key}}}));
8987
await raf();
90-
91-
// Deselect node.
92-
node.deselect();
93-
94-
await raf();
95-
88+
viewFunction.lastCall.firstArg.onSelect(new CustomEvent('select', {detail: null}));
9689
// Check preview was updated.
9790
assert.include(
9891
keyValueStorageItemsView.previewPanelForTesting.element.innerText,
@@ -105,8 +98,7 @@ describeWithEnvironment('KeyValueStorageItemsView', () => {
10598
let createPreviewPromise = expectCreatePreviewCalled(key, value);
10699

107100
// Select the first item.
108-
const node = selectNodeByKey(keyValueStorageItemsView.dataGridForTesting, key);
109-
assert.isNotNull(node);
101+
viewFunction.lastCall.firstArg.onSelect(new CustomEvent('select', {detail: {dataset: {key, value}}}));
110102

111103
// Check createPreview function was called.
112104
await createPreviewPromise;

0 commit comments

Comments
 (0)