Skip to content

Commit 358e04b

Browse files
author
marker dao ®
committed
feat && fix(tests): Lookup and DDList
1 parent 36a675b commit 358e04b

2 files changed

Lines changed: 161 additions & 30 deletions

File tree

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/dropDownList.tests.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ QUnit.module('focus policy', {
101101
}
102102
});
103103

104-
QUnit.test('hover and focus states for list should be initially disabled on mobile devices only', function(assert) {
104+
QUnit.test('hover state for list should be initially disabled on mobile devices, focus state should follow parent', function(assert) {
105105
this.instance.option('opened', true);
106106

107107
const list = $(`.${LIST_CLASS}`).dxList('instance');
@@ -111,11 +111,11 @@ QUnit.module('focus policy', {
111111
assert.ok(list.option('focusStateEnabled'), 'focus state should be enabled on desktop');
112112
} else {
113113
assert.notOk(list.option('hoverStateEnabled'), 'hover state should be disabled on mobiles');
114-
assert.notOk(list.option('focusStateEnabled'), 'focus state should be disabled on mobiles');
114+
assert.ok(list.option('focusStateEnabled'), 'focus state should follow parent value on mobiles');
115115
}
116116
});
117117

118-
QUnit.test('changing hover and focus states for list should be enabled on desktop only', function(assert) {
118+
QUnit.test('changing hover state for list should be enabled on desktop only, focus state should be enabled on both desktop and mobile', function(assert) {
119119
this.instance.option('opened', true);
120120

121121
const list = $(`.${LIST_CLASS}`).dxList('instance');
@@ -129,7 +129,7 @@ QUnit.module('focus policy', {
129129
this.instance.option({ hoverStateEnabled: true, focusStateEnabled: true });
130130

131131
assert.notOk(list.option('hoverStateEnabled'), 'hover state should not be changed on mobiles');
132-
assert.notOk(list.option('focusStateEnabled'), 'focus state should not be changed on mobiles');
132+
assert.ok(list.option('focusStateEnabled'), 'focus state should be changed on mobiles');
133133
}
134134
});
135135

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/lookup.tests.js

Lines changed: 157 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ const SCROLL_VIEW_CONTENT_CLASS = 'dx-scrollview-content';
9292
const LIST_ITEMS_CLASS = 'dx-list-items';
9393
const FOCUSED_CLASS = 'dx-state-focused';
9494

95+
const APPLY_BUTTON_SELECTOR = `.${APPLY_BUTTON_CLASS}.dx-button`;
96+
const CLEAR_BUTTON_SELECTOR = `.${CLEAR_BUTTON_CLASS}.dx-button`;
9597
const CANCEL_BUTTON_SELECTOR = '.dx-popup-cancel.dx-button';
9698

9799
const WINDOW_RATIO = 0.8;
@@ -2654,6 +2656,149 @@ QUnit.module('list options', {
26542656
});
26552657
});
26562658

2659+
QUnit.module('keyboard navigation - focus management', {
2660+
beforeEach: function() {
2661+
fx.off = true;
2662+
this.clock = sinon.useFakeTimers();
2663+
this.getList = (instance) => instance._list;
2664+
},
2665+
afterEach: function() {
2666+
this.clock.restore();
2667+
fx.off = false;
2668+
}
2669+
}, () => {
2670+
QUnit.test('list should have tabIndex=-1 when searchEnabled is true', function(assert) {
2671+
const instance = $('#lookup').dxLookup({
2672+
items: [1, 2, 3],
2673+
focusStateEnabled: true,
2674+
searchEnabled: true,
2675+
opened: true,
2676+
}).dxLookup('instance');
2677+
2678+
assert.strictEqual(this.getList(instance).option('tabIndex'), -1, 'list tabIndex is -1 when searchEnabled is true');
2679+
});
2680+
2681+
QUnit.test('list should have tabIndex=0 when searchEnabled is false', function(assert) {
2682+
const instance = $('#lookup').dxLookup({
2683+
items: [1, 2, 3],
2684+
focusStateEnabled: true,
2685+
searchEnabled: false,
2686+
opened: true,
2687+
}).dxLookup('instance');
2688+
2689+
assert.strictEqual(this.getList(instance).option('tabIndex'), 0, 'list tabIndex is 0 when searchEnabled is false');
2690+
});
2691+
2692+
QUnit.test('list tabIndex should update when searchEnabled changes at runtime', function(assert) {
2693+
const instance = $('#lookup').dxLookup({
2694+
items: [1, 2, 3],
2695+
focusStateEnabled: true,
2696+
searchEnabled: true,
2697+
opened: true,
2698+
}).dxLookup('instance');
2699+
2700+
const list = this.getList(instance);
2701+
2702+
assert.strictEqual(list.option('tabIndex'), -1, 'tabIndex is -1 initially with searchEnabled=true');
2703+
2704+
instance.option('searchEnabled', false);
2705+
assert.strictEqual(list.option('tabIndex'), 0, 'tabIndex changed to 0 after searchEnabled set to false');
2706+
2707+
instance.option('searchEnabled', true);
2708+
assert.strictEqual(list.option('tabIndex'), -1, 'tabIndex changed back to -1 after searchEnabled set to true');
2709+
});
2710+
2711+
QUnit.test('list should receive focusStateEnabled from Lookup', function(assert) {
2712+
const instance = $('#lookup').dxLookup({
2713+
items: [1, 2, 3],
2714+
focusStateEnabled: true,
2715+
opened: true,
2716+
}).dxLookup('instance');
2717+
2718+
assert.ok(this.getList(instance).option('focusStateEnabled'), 'list has focusStateEnabled=true when Lookup has focusStateEnabled=true');
2719+
});
2720+
2721+
QUnit.test('list focusStateEnabled should update when parent focusStateEnabled changes at runtime', function(assert) {
2722+
const instance = $('#lookup').dxLookup({
2723+
items: [1, 2, 3],
2724+
focusStateEnabled: true,
2725+
opened: true,
2726+
}).dxLookup('instance');
2727+
2728+
const list = this.getList(instance);
2729+
2730+
instance.option('focusStateEnabled', false);
2731+
assert.notOk(list.option('focusStateEnabled'), 'list focusStateEnabled updated to false');
2732+
2733+
instance.option('focusStateEnabled', true);
2734+
assert.ok(list.option('focusStateEnabled'), 'list focusStateEnabled updated to true');
2735+
});
2736+
2737+
QUnit.test('done button should receive focusStateEnabled from Lookup', function(assert) {
2738+
const instance = $('#lookup').dxLookup({
2739+
items: [1, 2, 3],
2740+
focusStateEnabled: true,
2741+
applyValueMode: 'useButtons',
2742+
opened: true,
2743+
}).dxLookup('instance');
2744+
2745+
const $doneButton = $(instance.content()).parent().find(APPLY_BUTTON_SELECTOR);
2746+
assert.ok($doneButton.length, 'done button exists');
2747+
2748+
const doneButton = $doneButton.dxButton('instance');
2749+
assert.ok(doneButton.option('focusStateEnabled'), 'done button has focusStateEnabled=true');
2750+
});
2751+
2752+
QUnit.test('clear button should receive focusStateEnabled from Lookup', function(assert) {
2753+
const instance = $('#lookup').dxLookup({
2754+
items: [1, 2, 3],
2755+
focusStateEnabled: true,
2756+
showClearButton: true,
2757+
opened: true,
2758+
}).dxLookup('instance');
2759+
2760+
const $clearButton = $(instance.content()).parent().find(CLEAR_BUTTON_SELECTOR);
2761+
assert.ok($clearButton.length, 'clear button exists');
2762+
2763+
const clearButton = $clearButton.dxButton('instance');
2764+
assert.ok(clearButton.option('focusStateEnabled'), 'clear button has focusStateEnabled=true');
2765+
});
2766+
2767+
QUnit.test('cancel button should receive focusStateEnabled from Lookup', function(assert) {
2768+
const instance = $('#lookup').dxLookup({
2769+
items: [1, 2, 3],
2770+
focusStateEnabled: true,
2771+
showCancelButton: true,
2772+
opened: true,
2773+
}).dxLookup('instance');
2774+
2775+
const $cancelButton = $(instance.content()).parent().find(CANCEL_BUTTON_SELECTOR);
2776+
assert.ok($cancelButton.length, 'cancel button exists');
2777+
2778+
const cancelButton = $cancelButton.dxButton('instance');
2779+
assert.ok(cancelButton.option('focusStateEnabled'), 'cancel button has focusStateEnabled=true');
2780+
});
2781+
2782+
QUnit.test('toolbar buttons should not have focusStateEnabled when Lookup has focusStateEnabled=false', function(assert) {
2783+
const instance = $('#lookup').dxLookup({
2784+
items: [1, 2, 3],
2785+
focusStateEnabled: false,
2786+
showClearButton: true,
2787+
showCancelButton: true,
2788+
applyValueMode: 'useButtons',
2789+
opened: true,
2790+
}).dxLookup('instance');
2791+
2792+
const doneButton = $(instance.content()).parent().find(APPLY_BUTTON_SELECTOR).dxButton('instance');
2793+
const clearButton = $(instance.content()).parent().find(CLEAR_BUTTON_SELECTOR).dxButton('instance');
2794+
const cancelButton = $(instance.content()).parent().find(CANCEL_BUTTON_SELECTOR).dxButton('instance');
2795+
2796+
assert.notOk(doneButton.option('focusStateEnabled'), 'done button has focusStateEnabled=false');
2797+
assert.notOk(clearButton.option('focusStateEnabled'), 'clear button has focusStateEnabled=false');
2798+
assert.notOk(cancelButton.option('focusStateEnabled'), 'cancel button has focusStateEnabled=false');
2799+
});
2800+
});
2801+
26572802
QUnit.module('Native scrolling', () => {
26582803
QUnit.test('After load new page scrollTop should not be changed', function(assert) {
26592804
const data = [];
@@ -2910,25 +3055,6 @@ QUnit.module('keyboard navigation', {
29103055
assert.ok(instance._$list.find('.dx-list-item').first().hasClass(FOCUSED_CLASS), 'list-item is focused after down key pressing');
29113056
});
29123057

2913-
QUnit.testInActiveWindow('lookup-list keyboard navigation should work after focusing on list', function(assert) {
2914-
const $element = $('#widget').dxLookup({
2915-
opened: true,
2916-
items: [1, 2, 3],
2917-
focusStateEnabled: true,
2918-
searchEnabled: true
2919-
});
2920-
const instance = $element.dxLookup('instance');
2921-
2922-
instance._$list.dxList('focus');
2923-
assert.ok(instance._$list.find(`.${LIST_ITEM_CLASS}`).eq(0).hasClass(FOCUSED_CLASS), 'list-item is focused after focusing on list');
2924-
2925-
const $listItemContainer = instance._$list.find(`.${LIST_ITEMS_CLASS}`).parent();
2926-
const keyboard = keyboardMock($listItemContainer);
2927-
keyboard.keyDown('down');
2928-
2929-
assert.ok(instance._$list.find(`.${LIST_ITEM_CLASS}`).eq(1).hasClass(FOCUSED_CLASS), 'second list-item is focused after down key pressing');
2930-
});
2931-
29323058
[true, false].forEach(value => {
29333059
QUnit.test(`focus from last Popover element should ${value ? 'not' : ''} move to Lookup field while keeping Popup open when usePopover: true and _scrollToSelectedItemEnabled: ${value}`, function(assert) {
29343060
const $element = $('#widget').dxLookup({
@@ -3545,7 +3671,7 @@ if(devices.real().deviceType === 'desktop') {
35453671
QUnit.test(`opened: true, searchEnabled: ${searchEnabled}`, function() {
35463672
helper.createWidget({
35473673
opened: true,
3548-
searchEnabled
3674+
searchEnabled,
35493675
});
35503676

35513677
const localizedRoleDescription = messageLocalization.format('dxList-ariaRoleDescription');
@@ -3561,7 +3687,7 @@ if(devices.real().deviceType === 'desktop') {
35613687
};
35623688

35633689
const listItemContainerAttributes = {
3564-
tabindex: '0',
3690+
tabindex: searchEnabled ? '-1' : '0',
35653691
role: 'application',
35663692
};
35673693

@@ -3601,9 +3727,12 @@ if(devices.real().deviceType === 'desktop') {
36013727
helper.checkAttributes($input, expectedAttributes, 'input');
36023728
}
36033729

3604-
helper.widget.option('searchEnabled', !searchEnabled);
3730+
const newSearchEnabled = !searchEnabled;
3731+
3732+
helper.widget.option('searchEnabled', newSearchEnabled);
36053733

36063734
listAttributes.id = helper.widget._listId;
3735+
listItemContainerAttributes.tabindex = newSearchEnabled ? '-1' : '0';
36073736

36083737
fieldAttributes = {
36093738
role: 'combobox',
@@ -3621,8 +3750,10 @@ if(devices.real().deviceType === 'desktop') {
36213750
id: helper.widget._popupContentId,
36223751
};
36233752

3753+
const scrollView = $list.find(`.${SCROLL_VIEW_CONTENT_CLASS}`);
3754+
36243755
helper.checkAttributes($list, listAttributes, 'list');
3625-
helper.checkAttributes($list.find(`.${SCROLL_VIEW_CONTENT_CLASS}`), listItemContainerAttributes, 'scrollview content');
3756+
helper.checkAttributes(scrollView, listItemContainerAttributes, 'scrollview content');
36263757
helper.checkAttributes($field, fieldAttributes, 'field');
36273758
helper.checkAttributes(helper.$widget, widgetAttributes, 'widget');
36283759
helper.checkAttributes(helper.widget._popup.$content(), popupContentAttributes, 'popupContent');
@@ -3714,15 +3845,15 @@ if(devices.real().deviceType === 'desktop') {
37143845
const $scrollView = $list.find(`.${SCROLL_VIEW_CONTENT_CLASS}`);
37153846
const $itemsContainer = $list.find(`.${LIST_ITEMS_CLASS}`);
37163847

3717-
helper.checkAttributes($scrollView, { tabindex: '0', role: 'application' });
3848+
helper.checkAttributes($scrollView, { tabindex: '-1', role: 'application' });
37183849
helper.checkAttributes($itemsContainer, { });
37193850

37203851
helper.widget.option(dataSourcePropertyName, [1, 2, 3]);
3721-
helper.checkAttributes($scrollView, { tabindex: '0', role: 'application' });
3852+
helper.checkAttributes($scrollView, { tabindex: '-1', role: 'application' });
37223853
helper.checkAttributes($itemsContainer, { 'aria-label': 'Items', role: 'listbox' });
37233854

37243855
helper.widget.option(dataSourcePropertyName, []);
3725-
helper.checkAttributes($scrollView, { tabindex: '0', role: 'application' });
3856+
helper.checkAttributes($scrollView, { tabindex: '-1', role: 'application' });
37263857
helper.checkAttributes($itemsContainer, { });
37273858
});
37283859
});

0 commit comments

Comments
 (0)