mvysny / karibu-testing

Vaadin Server-Side Browserless Containerless Unit Testing
Apache License 2.0
105 stars 14 forks source link

No visible Dialog in MockedUI while Karibu Unit Testing #156

Open MedAzizTousli opened 11 months ago

MedAzizTousli commented 11 months ago

I am coding in Kotlin. I am trying to migrate my project from Vaadin 22 to Vaadin 23.3. I am using Karibu Testing 1.3.23 for Vaadin Unit Testing.

When I try to: val dialog = _get<Dialog>() in my unit tests, I get the following error: java.lang.AssertionError: /: No visible Dialog in MockedUI["<description_of_mocked_UI>"] matching Dialog: [].

From my investigation so far, I understood that my Unit Test throws an Assertion Error at the the following Karibu function: public fun <T: Component> Component._find(clazz: Class<T>, block: SearchSpec<T>.()->Unit = {}): List<T> after a certain number of iterations.

Any ideas about this? This is my first time working on Karibu Testing.

hfazai commented 11 months ago

The root cause of this issue is that dialogs opened in a background thread are cleaned by the method cleanupDialogs() After doing some debugings I found that somehow the dialog is added to the MockedUI but having the property opened=false which allowed the method cleanupDialogs() to remove it from its parent.

MedAzizTousli commented 11 months ago

The root cause of this issue is that dialogs opened in a background thread are cleaned by the method cleanupDialogs() After doing some debugings I found that somehow the dialog is added to the MockedUI but having the property opened=false which allowed the method cleanupDialogs() to remove it from its parent.

Thank you for your answer. So, you think that the issue is related to Karibu Testing? If yes, what do you recommend doing workaround it?

mvysny commented 11 months ago

Excellent find! In theory, the dialog should be constructed and then immediately opened. That would attach the dialog to the UI and also set its opened property to true. If this is done by the background thread, the thread must do this via ui.access() otherwise the code is not thread-safe (Vaadin is not meant to be manipulated from background threads). I'd expect the dialog to be constructed and opened in one ui.access() call, which would make the operation atomic from the point of Karibu. Afterwards, any lookup code should keep the dialog in place (since opened is true) and would run the ui.access()-scheduled blocks beforehand. Please see https://github.com/mvysny/karibu-testing/tree/master/karibu-testing-v10#testing-asynchronous-application for more details.

However, it may be so that I'm not taking some important use-case into account. If you could simplify your use-case and create an example app which demoes the issue, that would be great!