How to check if an element is focused using bUnit?

253 Views Asked by At

Suppose I have a Blazor component <MyButton/> that is implemented like this for simplicity:

<button>MyButton</button>

And I unit test my component with bUnit as follows:

@inherits TestContext

@code {
    [Fact]
    public void MyButton_Focuses_Correctly()
    {
        IRenderedFragment cut = Render(@<MyButton></MyButton>);
        IElement button = cut.Find("button");

        button.Click();

        Assert.True(button.IsFocused); // <- does not work for some reason
    }
}

With similar things such as IsDisabled or IsChecked I could take a look at the DOM attribute but I can't use that workaround with IsFocused because there is no such thing as a HTML-focused attribute.

Assert.True(button.HasAttribute("disabled"));
2

There are 2 best solutions below

4
Link On BEST ANSWER

Simply speaking, bUnit is not a browser and therefore doesn't do "browser-things". What do I mean by that. Clicking on a button will set the focus - but that has nothing to do with your logic, Blazor or ASP.NET Core in general. The behavior is driven by your browser. That is why you can't observe that.

Furthermore, Click will not really click your button. The only thing it does, is to invoke your onclick event handler. A real "click" from a user in a browser would dispatch numerous events.

If your only concern is that the button has focus after your user clicks the button, then you don't have to test this behavior anyway, as this is 3rd party code (the browser). Especially with unit tests, the rule of thumb is not to test 3rd party behavior.

EDIT: As discussed in the comments - bUnit leverages AngleSharp under the hood as the DOM representation. So things like IsFocused come from said library. AngleSharp has way more use cases than bUnit has - but bUnit can not opt out of certain properties.

1
Sain Pradeep On

you can call a js method on the button click and set a hidden field or element on the component that document.activeElement is current button or not.

await JS.InvokeAsync<boo>("hasFocus", button);

where hasFocus is just

function hasFocus(button) {
  document.getElementById("isButtonFocus").value = (button === document.activeElement);
}

In your bunit test you can find and check the value of hidden field

// write code to find and check the value of hidden field
cut.Find("#isButtonFocus").value;