NoriginMedia / Norigin-Spatial-Navigation

React Hooks based Spatial Navigation (Key & Remote Control Navigation) / Web Browsers, Smart TVs and Connected TVs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Test cases

midhunlanware opened this issue · comments

Is there any doc or example for writing the test case for the navigation?
I have used the https://testing-library.com/ for writing test cases and the arrow events are not getting triggered

commented

Hello @midhunlanware! From what I can remember we have usually used navigateByDirection (docs) to achieve navigation as part of automated tests.

We have no hands on experience with Testing Library, but if you can provide us a demo where there is an obvious flaw in our library we can definitely take a look to see what can be done.

Thanks for the feedback.

@predikament I have used this navigateByDirection and was able to write the test cases. But not able to do the test case for OnEnterPress. Any Idea about how to write test case for the onEnterPress

commented

@midhunlanware: Hello!

Do you mean as in triggering synthetic keydown events?

This is something outside of the scope of this library (as we only handle callbacks for focused elements when a key is pressed).

However, in some cases test tools- and libraries will include APIs to handle this for you.

For example Cypress has Trigger, which works like this:

// Trigger a general KEYDOWN event on the document
cy.document().trigger('keydown', {
  key: 'Enter',
  keyCode: '13',
  which: '13'
});

Not entirely sure what testing-library has, since I have no experience with it, but worst case I assume you could trigger these key-presses yourself in a manual (programmatic) way?

Here's an example of what I mean:

// Trigger a synthetic 'Enter' keydown event on a DOM node
myDomReference.dispatchEvent(new KeyboardEvent('keydown', {'key':'Enter', which: 13, code: 13}));
// Trigger a synthetic click event on a DOM node
myDomReference.dispatchEvent(new MouseEvent('click'));

References:

I will close this as it's not inherently an issue in our library, but best of luck to you with the development and testing!

@predikament
`
import React, { useState } from "react";
import { useFocusable } from "@noriginmedia/norigin-spatial-navigation";

const FocusableButton = ({
buttonClassName,
focusedClassName,
onFocus,
onArrowPress,
focusKey,
onBlur,
}) => {
const [text, setText] = useState("before");

function onEnterPress() {
console.log("onEnterPress:mee")
setText("after");
}

const { ref, focused } = useFocusable({
onEnterPress: onEnterPress,
onFocus: onFocus,
onArrowPress: onArrowPress,
focusKey: focusKey,
onBlur: onBlur,
});
return (
<button
className={${buttonClassName} ${focused ? focusedClassName : ""}}
ref={ref}
focus-key={focusKey}
data-testid={focusKey}
>
{text}

);
};

export default FocusableButton;

`

Test case,

`import React from "react";
import { render, fireEvent, screen } from "@testing-library/react";
// import '@testing-library/jest-dom/extend-expect'; // For additional matchers like toHaveClass
import FocusableButton from "./FocusableButton"; // Update the import path based on your file structure
import { init } from "@noriginmedia/norigin-spatial-navigation";

init({
throttle: 100,
throttleKeypresses: true,
});

describe("FocusableButton Component", () => {
it("renders the button with initial text and without focus", () => {
render(
<FocusableButton
buttonClassName="test-button"
focusedClassName="focused"
onFocus={() => {}}
onArrowPress={() => {}}
focusKey="testKey"
onBlur={() => {}}
/>,
);

const button = screen.getByText("before");
const focusedAttribute = screen
  .getByTestId("testKey")
  .getAttribute("data-n-origin-focusable");

expect(button).toBeInTheDocument();
expect(button).toHaveClass("test-button");
expect(button).not.toHaveClass("focused");
expect(focusedAttribute).toBeNull();

});

it("updates the text onEnterPress", () => {
const { getByText } = render(
<FocusableButton
buttonClassName="test-button"
focusedClassName="focused"
onFocus={() => {}}
onArrowPress={() => {}}
focusKey="testKey"
onBlur={() => {}}
/>,
);

const button = getByText("before");
fireEvent(button, new KeyboardEvent('keydown', { key: 'Enter', which: 13, code: 'Enter' }));
// fireEvent.keyDown(button, { key: "Enter", code: "Enter", charCode: 13 });

expect(button).toHaveTextContent("after");

});

it("adds focus class when focused", () => {
const { getByText } = render(
<FocusableButton
buttonClassName="test-button"
focusedClassName="focused"
onFocus={() => {}}
onArrowPress={() => {}}
focusKey="testKey"
onBlur={() => {}}
/>,
);

const button = getByText("before");
fireEvent.focus(button);
screen.debug();

// expect(button).toHaveClass('focused');

});
});
`
I have tried with fireevent . but the event is not triggering as Expected. when I printed the onKeydown for the button it printing the event. but not onEnterPress call back function not executing

image
The onEnterPress function not executed

commented

@midhunlanware: The code you shared is missing basically all formatting, so it's quite difficult to read.

Please make sure to include code snippets (especially larger ones) in code blocks:
```javascript
// Your code here
```

So it ends up being more readable:

console.log('Like this!');

(Ref.: Github - Creating and highlighting code blocks)


As to why it does not work, I am unsure - This is likely an issue in the specific testing library you are using, for which I have already offered two alternative options in my previous post.

Our library is simply listening for keydown events with an event-listener on the target DOM element that you have created, which we are making focusable with our library.

TLDR; If you cannot trigger "keydown" using a separate library it's unfortunately not a problem on our side.

Sorry I can't be of more help. Good luck!