Skip to content

NXT-20357: Added ui test for continue5WayHold of VirtualList - #463

Open
vJIYEv wants to merge 2 commits into
developfrom
feature/NXT-20357
Open

vJIYEv wants to merge 2 commits into
developfrom
feature/NXT-20357

Conversation

@vJIYEv

@vJIYEv vJIYEv commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Checklist

  • I have read and understand the contribution guide
  • A CHANGELOG entry is included
  • At least one test case is included for this feature or bug fix
  • I have run automated testing and it is passed
  • Documentation was added or is not needed
  • This is an API breaking change

Issue Resolved / Feature Added

We don't have any test to verify the continue5WayHold prop in VirtualList.

Resolution

Added UI tests for continue5WayHold with three horizontal VirtualLists stacked vertically.

  • continue5WayHold={true}: holding the down key moves focus through all lists to the last one.
  • continue5WayHold={false}: holding the down key stops focus at the second list. The first keydown is not a repeat, so focus moves once, and the following repeats are blocked.

Additional Considerations

Links

NXT-20357

Comments

Enact-DCO-1.0-Signed-off-by: Jiye Kim (jiye.kim@lge.com)

Enact-DCO-1.0-Signed-off-by: Jiye Kim (jiye.kim@lge.com)
@codecov

codecov Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.54%. Comparing base (ccf5ec6) to head (bff8945).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop     #463   +/-   ##
========================================
  Coverage    83.54%   83.54%           
========================================
  Files          158      158           
  Lines         7908     7908           
  Branches      2446     2446           
========================================
  Hits          6607     6607           
  Misses        1011     1011           
  Partials       290      290           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@alexandrumorariu alexandrumorariu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

const {focusedElement} = require('../../VirtualList-utils');

// WebDriver cannot send auto-repeated keys, so dispatch repeat keydown events directly.
async function holdDownKey (repeatCount) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be moved to VirtualList-utils , same as focusedElement?

await focusFirstItem();
expect(await focusedElement()).toBe('list0-item0');

await holdDownKey(60);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you choose 60?
Each of the 60 iterations is a WebDriver round trip plus a 50 ms pause, which adds seconds to both cases. Isn't 10 repeats enough?

});
}

async function focusFirstItem () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be moved to VirtualList-utils , same as focusedElement?

Comment on lines +44 to +47
await holdDownKey(60);

// The first keydown is not a repeat, so focus moves once to the next list and then stops
expect(await focusedElement()).toBe('list1-item0');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case passes, but it can't tell which layer blocked the repeats. With continue5WayHold={false}, repeated keydowns are blocked twice:

  1. VirtualList itself calls ev.stopPropagation() when focus is about to leave the list on a repeat (VirtualList/useEvent.js, the isLeaving && repeat branch).
  2. Spotlight's spotNext refuses to move focus out of a container while 5-way is held, unless the container is continue5WayHold (spotlight/src/spotlight.js).

If (1) breaks, (2) still keeps focus on list1-item0, so this test stays green even though VirtualList no longer handles the prop. Could we also check that no repeated keydown gets past VirtualList to window, where Spotlight listens? (This needs holdDownKey to return a count; see my comment on the helper.)

Suggested change
await holdDownKey(60);
// The first keydown is not a repeat, so focus moves once to the next list and then stops
expect(await focusedElement()).toBe('list1-item0');
const repeatKeyDownCount = await holdDownKey(60); // maybe we need only 10 here, waiting for feedback
// The first keydown is not a repeat, so focus moves once to the next list and then stops
expect(await focusedElement()).toBe('list1-item0');
// VirtualList itself stops repeat keydown events, not only Spotlight's 5-way hold check
expect(repeatKeyDownCount).toBe(0);

Optionally, for symmetry, the true case (line 34–36) could assert expect(repeatKeyDownCount).toBeGreaterThan(0);. That would check that VirtualList actually lets repeats through to Spotlight instead of focus reaching list2 some other way.

Comment on lines +6 to +18
for (let i = 0; i < repeatCount; i++) {
await browser.execute(function (repeat) {
// eslint-disable-next-line no-undef
const event = new KeyboardEvent('keydown', {bubbles: true, cancelable: true, code: 'ArrowDown', key: 'ArrowDown', keyCode: 40, repeat});
document.activeElement.dispatchEvent(event);
}, i > 0);
await Page.delay(50);
}
await browser.execute(function () {
// eslint-disable-next-line no-undef
const event = new KeyboardEvent('keyup', {bubbles: true, cancelable: true, code: 'ArrowDown', key: 'ArrowDown', keyCode: 40});
document.activeElement.dispatchEvent(event);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The helper would need to report how many repeated keydowns reached window. Note that VirtualList's own accelerator also stops the repeats it skips (about 2 of 3), so a non-zero count in the true case is expected but smaller than repeatCount.

Suggested change
for (let i = 0; i < repeatCount; i++) {
await browser.execute(function (repeat) {
// eslint-disable-next-line no-undef
const event = new KeyboardEvent('keydown', {bubbles: true, cancelable: true, code: 'ArrowDown', key: 'ArrowDown', keyCode: 40, repeat});
document.activeElement.dispatchEvent(event);
}, i > 0);
await Page.delay(50);
}
await browser.execute(function () {
// eslint-disable-next-line no-undef
const event = new KeyboardEvent('keyup', {bubbles: true, cancelable: true, code: 'ArrowDown', key: 'ArrowDown', keyCode: 40});
document.activeElement.dispatchEvent(event);
});
// WebDriverIO cannot send auto-repeated keys, so dispatch repeat keydown events directly.
// Returns the number of repeat keydown events that bubbled up to `window`, where Spotlight handles them.
async function holdDownKey (repeatCount) {
await browser.execute(function () {
window.repeatKeyDownCount = 0;
window.addEventListener('keydown', function (ev) {
if (ev.repeat) {
window.repeatKeyDownCount++;
}
});
});
for (let i = 0; i < repeatCount; i++) {
await browser.execute(function (repeat) {
// eslint-disable-next-line no-undef
const event = new KeyboardEvent('keydown', {bubbles: true, cancelable: true, code: 'ArrowDown', key: 'ArrowDown', keyCode: 40, repeat});
document.activeElement.dispatchEvent(event);
}, i > 0);
await Page.delay(50);
}
await browser.execute(function () {
// eslint-disable-next-line no-undef
const event = new KeyboardEvent('keyup', {bubbles: true, cancelable: true, code: 'ArrowDown', key: 'ArrowDown', keyCode: 40});
document.activeElement.dispatchEvent(event);
});
return await browser.execute(function () {
return window.repeatKeyDownCount;
});
}

@daniel-stoian-lgp

Copy link
Copy Markdown
Contributor

if the reviews apply to the other PRs, please add them also

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.

3 participants