mvysny / karibu-testing Goto Github PK
View Code? Open in Web Editor NEWVaadin Server-Side Browserless Containerless Unit Testing
License: Apache License 2.0
Vaadin Server-Side Browserless Containerless Unit Testing
License: Apache License 2.0
Hi Martin! Nice talking yesterday ;-).
I tried an Idea yesterday and want to know, if you think it is good :-). Currently I am testing a class which is a subcomponent without a route, so I have to get the parent component with the route first as of your documentantion. I have tried the following, it worked well, so:
I extended the class I want to test in the same package - but in the test folder. There I applied a test route via which is found in the test. Here is my code:
@route("testBv")
public class MyFormTestRoute extends MyForm {
public MyFormTestRoute(MyService myService) {
super(myService);
}
}
And in the test:
@test
public void fieldBinding() {
UI.getCurrent().navigate(MyFormTestRoute.class);
MyForm myForm = _get(MyForm.class);
myForm.setBean(createMyBean());
assertEquals(myForm.myFiled.getValue(), "MyVal");
}
What do you think?
Using a setup like in this one: https://github.com/mvysny/t-shirt-shop-example :
Spring boot, Java, Maven.
Version: 1.2.5
I use a grid which has a row above the actual header, like this (sorry for huge whitespace) :
Unfortunately, "myHeading" and "myButton" get found 3 times (i assume once per column), while this first line of the grid is actually one row with 1 heading and 1 button. Browser confirms. This occurs while prettyPrinting as well as for the actual com.github.mvysny.kaributesting.v10.LocatorJ._get(Button.class, spec -> spec.withCaption("myButton")) method.
I took the workaround with LocatorJ._find(..) which returns a List and now just take the first entry/button to klick on it, but if you could tell me what I have to do in order to get rid of the workaround, or if it is a bug, please let me know.
Best regards
Rene
The package name we are passing to this method is in the form of com.x.y.z.admin and works fine in 1.0.1. When we use version 1.0.2 no views are discovered
The ScanResult doesn't seem to be finding anything, i.e. scanResult.getClassesWithAnnotation(Route::class.java.name)
returns an empty list. I look at ScanResult and all of the maps seem to be empty. Any ideas?
I created a signing pad where I have a changeEventListener on to check, if a signing was given. Then a button will be enabled. I had to check, if the valuechange is a ClientEvent or SystemEvent. Sadly the _setValue from karibu does a SystemEvent so I can't check the flow in my app.
Is there a way to set events as ClientEvent in Karibu?
Vaadin Version: 14.3.2
Karibu version: 1.1.26
btw, I'm Mark from germany, we had some training with you few weeks ago ;)
Currently, karibu testing requires to have no args constructor. But we are using Spring and DI into constructor so karibu fails to instantiate a View component. Is there a way to make karibu-testing use current @SpringBootTest context for autowired fields? Or is there a workaround to inject spring dependencies into mocked ui?
Vaadin 14: spec.withCaption("cap") won't match Checkbox
Hi Martin! It's me again ;-). I am currently failing in two tasks:
Here is my filter code:
filterTextField.addValueChangeListener(keyEvent -> {
dataProvider.addFilter(ma ->
StringUtils.containsIgnoreCase(ma.getName(), filterTextField.getValue()) ||
StringUtils.containsIgnoreCase(ma.getSurname(), filterTextField.getValue())
);
});
It would be nice, if we can sort these issues out, that they'll become part of a tutorial, for they may be pretty common ;-).
Hello,
When I try to test a click on a submenu of the GridContextMenu and I've got this error:
java.lang.AssertionError: Unexpected parent GridMenuItem[text='Affaires']
at kotlin.test.DefaultAsserter.fail(DefaultAsserter.kt:16)
at kotlin.test.AssertionsKt__AssertionsKt.fail(Assertions.kt:91)
at kotlin.test.AssertionsKt.fail(Unknown Source)
at com.github.mvysny.kaributesting.v10.ContextMenuKt.checkMenuItemVisible(ContextMenu.kt:97)
at com.github.mvysny.kaributesting.v10.ContextMenuKt._click(ContextMenu.kt:71)
I think hierarchical GridMenuItem is a new feature of vaadin 13 and in ContextMenu.kt the function checkMenuItemVisible does not check if parent is a GridMenuItem (I tried to read Kotlin code but I'm not sure if I understand correctly :))
Thanks,
When adding maven dependencies in pom.xml, I get the error:
Failed to collect dependencies at com.github.mvysny.kaributesting:karibu-testing-v10:jar:1.1.0: Failed to read artifact descriptor for com.github.mvysny.kaributesting:karibu-testing-v10:jar:1.1.0: Failure to find com.vaadin:vaadin-bom:pom:13.0.0.beta1 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced -> [Help 1]
My pom.xml, only using default maven repositories:
<dependency>
<groupId>com.github.mvysny.kaributesting</groupId>
<artifactId>karibu-testing-v10</artifactId>
<version>1.1.3</version>
<scope>test</scope>
</dependency>
A lookup of components fail with Polymer Templates; that's unfortunately the technical limitation of the Polymer Templates (I'll explain that later on), however Karibu-Testing should definitely fail with a much more informative error message.
Hi Martin,
We are evaluating GridPro and one of the things we're looking at is testing. GridPro allows cell editing through a double-click. I see in Grid.kt code for clicking a cell Renderer (i.e. _clickRenderer). I started to model an approach after what you have there.
By default the GridPro column renderer is ColumnPathRenderer (which doesn't supply a Component). I was thinking that once I get the component I could fire two click events. I'd prefer a solution where I don't have to change the default renderer of GridPro.
Will I need to use a ComponentRenderer and call createComponent and fire click events for this component in order to enter into edit mode for a cell? Suggestions appreciated.
Thanks
Hi guys,
I am using Vaadin component Card (https://vaadin.com/directory/component/card) and encounter the same issue mentioned in #26 .
I am using Vaadin springboot starter 14.3.2
Without the card, the testing works perfect. Am I missing out something?
Any advice will be appreciated.
Stacktrace
Caused by: java.lang.NullPointerException: null at com.vaadin.flow.server.frontend.FrontendUtils.getStatsFromWebpack(FrontendUtils.java:430) ~[flow-server-2.3.2.jar:2.3.2] at com.vaadin.flow.server.frontend.FrontendUtils.getStatsContent(FrontendUtils.java:379) ~[flow-server-2.3.2.jar:2.3.2] at com.vaadin.flow.component.polymertemplate.NpmTemplateParser.getSourcesFromStats(NpmTemplateParser.java:189) ~[flow-server-2.3.2.jar:2.3.2] at com.vaadin.flow.component.polymertemplate.NpmTemplateParser.getTemplateContent(NpmTemplateParser.java:110) ~[flow-server-2.3.2.jar:2.3.2] at com.vaadin.flow.component.polymertemplate.TemplateDataAnalyzer.parseTemplate(TemplateDataAnalyzer.java:200) ~[flow-server-2.3.2.jar:2.3.2] at com.vaadin.flow.component.polymertemplate.TemplateInitializer.<init>(TemplateInitializer.java:91) ~[flow-server-2.3.2.jar:2.3.2] at com.vaadin.flow.component.polymertemplate.PolymerTemplate.<init>(PolymerTemplate.java:88) ~[flow-server-2.3.2.jar:2.3.2] at com.vaadin.flow.component.polymertemplate.PolymerTemplate.<init>(PolymerTemplate.java:103) ~[flow-server-2.3.2.jar:2.3.2] at com.github.appreciated.card.AbstractCard.<init>(AbstractCard.java:22) ~[card-2.0.0.beta4.jar:2.0.0.beta4] at com.github.appreciated.card.Card.<init>(Card.java:19) ~[card-2.0.0.beta4.jar:2.0.0.beta4]
It seems that UtilsKt.makeNotFinal
is no longer possible in Java 12.
Downgrading to Java 10 (and probably 11) helps, but it would be nice if there is a workaround for the latest version.
I ended up using Grid.select() api, but it would be nice if there was support in karibu for this type of operation.
Karibu-Testing 1.1.29; reproducible on the https://github.com/mvysny/t-shirt-shop-example example project.
The following exception is thrown:
java.util.concurrent.ExecutionException: java.lang.AssertionError
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.vaadin.flow.server.FutureAccess.get(FutureAccess.java:62)
at com.vaadin.flow.server.VaadinService.runPendingAccessTasks(VaadinService.java:2031)
at com.vaadin.flow.server.VaadinSession.unlock(VaadinSession.java:660)
at com.github.mvysny.kaributesting.v10.MockVaadin.runUIQueue(MockVaadin.kt:371)
at com.github.mvysny.kaributesting.v10.MockVaadin.runUIQueue$default(MockVaadin.kt:353)
at com.github.mvysny.kaributesting.v10.MockVaadin.closeCurrentSession(MockVaadin.kt:230)
at com.github.mvysny.kaributesting.v10.MockVaadin.clearVaadinInstances$karibu_testing_v10(MockVaadin.kt:215)
at com.github.mvysny.kaributesting.v10.MockVaadin.tearDown(MockVaadin.kt:204)
at com.vaadin.tshirtshop.ApplicationTest.tearDown(ApplicationTest.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptAfterEachMethod(TimeoutExtension.java:108)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeMethodInExtensionContext(ClassBasedTestDescriptor.java:481)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$synthesizeAfterEachMethodAdapter$19(ClassBasedTestDescriptor.java:471)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterEachMethods$9(TestMethodTestDescriptor.java:238)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$12(TestMethodTestDescriptor.java:271)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:271)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:270)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterEachMethods(TestMethodTestDescriptor.java:236)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:141)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: java.lang.AssertionError
at com.vaadin.flow.spring.SpringVaadinServletService.sessionDestroyed(SpringVaadinServletService.java:106)
at com.vaadin.flow.spring.SpringVaadinServletService.lambda$new$39443434$1(SpringVaadinServletService.java:67)
at com.vaadin.flow.server.VaadinService.lambda$fireSessionDestroy$9c853e43$1(VaadinService.java:668)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at com.vaadin.flow.server.VaadinService.runPendingAccessTasks(VaadinService.java:2028)
... 76 more
The problem is that Spring uses SpringVaadinSession
but Karibu-Testing uses MockVaadinSession
.
I currently try to write a test with Karibu, but fail due to a data provider that just does not want to provide new data.
I have an application, where a user can define a filter and then press a button to apply that filter. The button forwards the filter to a ConfigurableFilterDataProvider
of a Grid
and then calls refreshAll()
(on the data provider) to force the grid to update itself. This works fine in practice, but not in my test. There I can see that the button is clicked, the click listener is executed, refreshAll()
is called, but the data provider does not even attempt to retrieve new data.
Debugging showed that there is an additional data provider listener when I start the application normally, but I do not think this has an effect. I currently suspect that the problem lies in the listener that is registered by the DataCommunicator.handleAttach()
method. This indirectly calls DataCommunicator.requestFlush()
which has the following check:
if (!context.isClientSideInitialized()) {
reset();
arrayUpdater.initialize();
}
Could it be that mocking the client side impedes the behaviour here (the entire condition always evaluates to true)? Do you know of any similar issues? If yes, is there a way to avoid this problem and still use Karibu?
P.S.: I am using karibu-testing-v10:1.1.23 and Vaadin 14.1.17.
Add support for clicking on a particular Grid Column for particular row. For example,
grid._clickRenderer(0, "edit")
would click on 0th row, on the column with key "edit". For start only support NativeButtonRenderer
.
Version 1.1.27
The SessionInitListeners are not called when a new session is created.
#42 should fix this
Also [ ] SessionDestroyListener, UIInitListener and UIDestroyListener should be invoked.
With karibu-testing-v10:1.1.14, Vaadin 14.0.7 and Java 13 we always get the following Exception when trying to setup a test:
java.lang.NoSuchFieldException: modifiers
at java.base/java.lang.Class.getDeclaredField(Class.java:2412)
at com.github.mvysny.kaributesting.v10.UtilsKt.makeNotFinal(Utils.kt:61)
at com.github.mvysny.kaributesting.v10.MockNpmTemplateParser$Companion.install(MockNpmTemplateParser.kt:129)
at com.github.mvysny.kaributesting.v10.MockVaadin.mockVaadin14(MockVaadin.kt:152)
at com.github.mvysny.kaributesting.v10.MockVaadin.setup(MockVaadin.kt:126)
at com.github.mvysny.kaributesting.v10.MockVaadin.setup(MockVaadin.kt:106)
...
To me it looks like in Utils.kt#61 you try to change the "modifiers" of class "java.lang.reflect.Field" to being accessible and not final instead of the static "INSTANCE" field in class "com.vaadin.flow.component.polymertemplate.NpmTemplateParser"?!
We verified that (at least) all karibu-testing-v10 versions after 1.1.11 show this behaviour.
Simplified example:
I have a form within my view that implements a BeforeLeaveObserver:
public class QuestionForm extends FormLayout implements BeforeLeaveObserver {
@Override
public void beforeLeave(BeforeLeaveEvent event) {
// postpone the view change
ContinueNavigationAction postponedNavigationAction = event.postpone();
ConfirmDialog dialog = new ConfirmDialog("Unsaved changed", "You sure?", "Leave Page", e -> postponedNavigationAction.proceed(), "Stay", e -> {});
dialog.open();
}
}
In my test I try to verify that the BeforeLeaveObserver is triggered and can be retrigged a second time if the user presses once "Stay" and the second time "Leave Page" -> resulting in a view change.
UI.getCurrent().navigate(QuestionView.class);
// Open other view to trigger confirm dialog
UI.getCurrent().navigate(QuestionsView.class);
// press "cancel"
ConfirmDialogKt._fireCancel(_get(ConfirmDialog.class)); // stay on the view
// Try to navigate again
UI.getCurrent().navigate(QuestionsView.class);
// press confirm
ConfirmDialogKt._fireConfirm(_get(ConfirmDialog.class)); // move to another view
// ... assert view changed
Currently my test fails at line: ConfirmDialogKt._fireConfirm(_get(ConfirmDialog.class))
with: "Too many visible ConfirmDialogs (2) in MockedUI[] matching ConfirmDialog: [ConfirmDialog[], ConfirmDialog[]].
P.S. If I remember correctly, I had an error like this with Notifications as well, I removed that test - so no change to verify it.
Versions:
How about integrating a helper for clicking a dynamic context menu?
I found a way with:
val tree = _get<TreeGrid<ProductTreeItem>>()
val collateralDetail = tree._get(2)
collateralDetail.name() shouldBe "CollateralDetail (Empty)"
val key = tree.dataCommunicator.keyMapper.key(collateralDetail)
val data = JreJsonFactory().parse<JsonObject>("{ \"event.detail\":{\"key\":\"${key}\"}}")
tree._fireDomEvent("vaadin-context-menu-before-open",data)
view.contextMenu._clickItemWithCaption("Add", collateralDetail)
Yes. This is because of how Vaadin 10 currently works. The problem in here is that any DOM manipulation conducted by browser will not make its way into Vaadin server (even with a full Vaadin 10 server running, so this is not just an unfortunate effect of browserless testing). The implications are many.
The original issue was that PolymerTemplate.getChildren()
streams returns no components even when there are components nested inside of the PolymerTemplate. This has been explained in vaadin/flow#3642 - PolymerTemplate nests its contents inside of a Shadow DOM and Shadow DOM elements do not count as children.
Then I thought I could simply enumerate the contents of the template as suggested in this comment: vaadin/flow#3642 (comment)
And it worked, however the Buttons returned had an empty text!
And then the following bug came into play: vaadin/vaadin-button-flow#43 (comment)
In short - PolymerTemplate is parsed client-side and thus the DOM is not transferred server-side. On server-side, only the components mapped with @Id
are constructed server-side; and those are nothing more but empty shells. So, for example the Button nests caption in a <span>
element; however since DOM is not transferred the server-side Button thinks there is no span and therefore no caption and returns an empty text. Similarly all layouts (VerticalLayout
) will have no children since it detects its children by enumerating its element's DOM children, but there is no DOM.
It appears to me that beforeClientResponse
of the current UI is not being run.
While this is expected when running browserless, it would be useful if it could be simulated somehow.
Hi,
When using the getFormatted method for the grid, the method tries to find the column by key. However, if it cannot be found, the method returns the available column ids and not the keys. So it says
java.lang.IllegalArgumentException: There is no column <...>. Available columns: [Optional.empty, Optional.empty, Optional.empty, Optional.empty]
even if some (or all) of the columns have a key (but no id). Also the error message should not display the empty optionals and only the content of the non-empty optionals.
Best regards,
Nils
Currently MenuItem._click() seems to be tied to a contextMenu.
If the parent is a menubar I guess it could fire a simple click event. (?)
Unfortunately MenuBarRootItem has package scope, so we can't search for that easily.
Hi,
This is similar to #2. We have a Vaadin grid with an item click listener: grid.addItemClickListener(...)
Currently there seems no API to perform this click on the whole row. Using the clickRenderer method just leads to a ClassCastException, because the column itself is not clickable, but just the row.
Is there another possibility to perform the click?
Best regards,
Nils
Hi,
I'm having an issue testing a context menu in a View. All written in Java by the way.
I have a button so for instance and associated menu:
Button b = new Button("Prefs");
b.setId("mybutton")
ContextMenu menu = new ContextMenu();
menu.setId("mymenu");
menu.setTarget(target);
menu.setOpenOnClick(true); //left button click to open
Label settingsLabel = new Label("Settings);
settingsLabel.setId("mymenuitem");
menu.addItem(settingsLabel, e -> { /*do stuff });
If I try and test this I can click on the button but I don't seem to be able to find the context menu.
So
ButtonKt._click(_get(Button.class)); //this appear to click the button ok
List contextMenus = _find(ContextMenu.class); // doesn't find the menu
How should I be handling context menu's. I notice from looking at the dom that shadowdom is being used.
Thanks
Steve
Branch feature/vaadin18-support
java.lang.AssertionError: /.: Too many visible Grids (2) in MockedUI[] matching Grid: [CommChannelGrid[width:100% height:100%], Grid[width:100% flex-grow:1.0]]. Component tree:
└── MockedUI[]
└── MainView[width:100% height:100%]
├── TextField[label='Filter:', value='']
└── CommChannelGrid[width:100% height:100%]
├── ColumnGroup[]
│ └── ColumnGroup[]
│ └── Column[]
├── ColumnGroup[]
│ └── ColumnGroup[]
│ └── Column[]
├── ColumnGroup[]
│ ├── ColumnGroup[]
│ │ └── Column[]
│ └── ColumnGroup[]
│ └── Column[]
└── ColumnGroup[]
└── ColumnGroup[]
└── Column[]
There's a Grid nested in one of the CommChannelGrid headers but it's not shown in the dump.
Failed tests could generate design htmls of the entire UI; then you can use the vaadin-declarative-view Chrome plugin to preview that.
Open questions:
build/
or target/
, or we encourage the user to use JUnit Rule.Add Spring example for Vaadin 10. Perhaps take an existing Spring+Vaadin 10 project and test it with Karibu Testing. Please, any suggestions on a simple Vaadin 10+Spring project?
Add some support for testing extensions:
Hi there, I tried to make use of the project to test some Vaadin 13 with SpringBoot code that I have been working on but failed at the first hurdle.
In the demo t-shirt project for SpringBoot testing which is using Vaadin 10 it used the following code.
final RouteRegistry registry = new Routes().autoDiscoverViews("com.vaadin.tshirtshop").createRegistry();
However for Vaadin 13 there does not appear to be a createRegistry method. I played around a little while trying to figure out how to wire things up but basically didn't get it working.
Any tips on what I need to do, I obviously need to setup the servlet and the context but I think Vaadin 13 has changed a bit under the hood ?
Thanks
Steve
PS: great project by the way, it is really needed.
I am trying to run autoDiscoverViews("X.Y.Z")
before my tests, but it does not even compile, and my IDE cannot find this method anywhere.
I am following the README, without success.
Am I doing something wrong?
It is useful to lookup a button which doesn't have a style, e.g. spec -> spec.withoutStyle("current")
Hi there :)
Could you add overloaded methods for GridKt._clickItem method with default values?
Getting a column in Java every time when I need to click a row item looks quite redundant.
Best regards
Recently I upgraded to Vaadin 14.4.0 and Karibu 1.2.5 (from Vaadin 14.2.x and Karibu 1.1.x). After all expected changes I ran into the following Exception when executing tests:
com.vaadin.flow.server.InvalidRouteLayoutConfigurationException: Only one target for an exception should be defined. Found <MyErrorViewName> and 'com.github.mvysny.kaributesting.v10.MockRouteNotFoundError' for exception 'com.vaadin.flow.router.NotFoundException'
at com.vaadin.flow.router.internal.AbstractRouteRegistry.handleRegisteredExceptionType(AbstractRouteRegistry.java:428)
at com.vaadin.flow.router.internal.AbstractRouteRegistry.addErrorTarget(AbstractRouteRegistry.java:394)
at com.vaadin.flow.server.startup.ApplicationRouteRegistry.lambda$setErrorNavigationTargets$3(ApplicationRouteRegistry.java:307)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485)
at com.vaadin.flow.server.startup.ApplicationRouteRegistry.setErrorNavigationTargets(ApplicationRouteRegistry.java:307)
at com.github.mvysny.kaributesting.v10.Routes.register(Routes.kt:47)
at com.github.mvysny.kaributesting.v10.spring.MockSpringServlet.createServletService(MockSpringServlet.java:47)
at com.vaadin.flow.server.VaadinServlet.createServletService(VaadinServlet.java:185)
at com.vaadin.flow.server.VaadinServlet.init(VaadinServlet.java:72)
at com.github.mvysny.kaributesting.v10.MockVaadin.setup(MockVaadin.kt:151)
...
The problem seems to be that both the application and the Karibu Mock register a custom NotFoundException
. I avoided this problem by removing the MockRouteNotFoundError
after views have been detected.
allRoutes = new Routes().autoDiscoverViews("...");
allRoutes.getErrorRoutes().remove(MockRouteNotFoundError.class);
Is it possible to change autoDiscoverViews(...)
such that it only registers the MockRouteNotFoundError
if no other error view is already registered?
P.S.: I am using karibu-testing-v10-spring
and set up the tests as it was done in the corresponding TShirt Example.
Hello Martin,
I am setting an error handler VaadinSession.setErrorHandler, and this is where I launch an error dialog. I see in the test environment the session is an instance of MockVaadinSession.
The issue is that this handler doesn't seem to be called in the event of an application exception.
Any help/advice is appreciated. Thanks.
HI, I see the following error with Vaadin 12 beta2
java.lang.NoSuchMethodException: com.vaadin.flow.component.grid.Grid.getDataGenerator()
at java.base/java.lang.Class.getDeclaredMethod(Class.java:2476)
at com.github.mvysny.kaributesting.v10.GridKt.getDataGenerator2(Grid.kt:101)
Let me know if I can be of any assistance.
Add _expectOne
and _expectCount
method to complement the _expectNone
method. This is
exactly the same as _get()
, but it may communicate the intent of the test better if you're
only asserting that there is exactly one such component.
In the readme, there is a piece of example code:
import static com.github.mvysny.kaributesting.v8.LocatorJ.*;
import static com.github.vok.karibudsl.NavigatorKt.*;
public class MyUITest {
@BeforeAll
public static void beforeAll() {
autoDiscoverViews("com.myproject")
}
@BeforeEach
public void beforeEach() {
MockVaadin.setup(MyUI::new);
}
@Test
public void simpleTest() {
navigateToView(CrudView.class); // this will call Navigator.navigateTo("crud")
// now the view is ready and attached to your UI. We can test.
final Grid<Person> grid = _get(Grid.class);
// etc etc
}
}
note the line: import static com.github.vok.karibudsl.NavigatorKt.*;
This is an import that does not work for me and is not included in the maven dependency of this library. Is this incorrect or am I doing something wrong?
Add support for lit template
Hello guys, I want to test my application with Karibu and before all tests I want to login but I get the error
java.lang.AssertionError: /login: No visible LoginOverlay in UI[] matching LoginOverlay: []. Component tree:
└── UI[]
└── RouteNotFoundError[]
├── Html[]
└── Html[
In order to simulate the login I use this:
UI.getCurrent().navigate("login");
LoginFormKt._login(_get(LoginOverlay.class), "admin", "password");
I use the login class of Spring Security. Does someone have an idea why this doesn't work?
We have a ComponentRenderer that creates a Div and then Spans within for multi-line presentation. There are cases where testing the actual renderer output is desirable, due to manipulations which may occur there.
Previously with the default ColumnPathRenderer we were able to extract the actual value. Now with our custom renderer the output comes out as "Div[]" which isn't very helpful for testing.
Do you have any suggestions for us (other than implementing a custom solution where we might enhance Grid.kt getPresentationValue method to deal with our custom renderer)?
A simple solution could be for the ComponentRenderer block of getPresentationValue to be enhanced to do a deeper representation than component.toPrettyString() does currently. Though I suppose that would break backward compatibility.
Or perhaps there could be some sort of abstraction, registered with the renderer type, for navigating the expected renderer component tree and return a value.
Thanks
Caused by: java.lang.NullPointerException
at com.vaadin.flow.server.frontend.FrontendUtils.getStatsFromWebpack(FrontendUtils.java:402)
at com.vaadin.flow.server.frontend.FrontendUtils.getStatsContent(FrontendUtils.java:367)
at com.vaadin.flow.component.polymertemplate.NpmTemplateParser.getSourcesFromStats(NpmTemplateParser.java:172)
at com.vaadin.flow.component.polymertemplate.NpmTemplateParser.getTemplateContent(NpmTemplateParser.java:105)
at com.vaadin.flow.component.polymertemplate.TemplateDataAnalyzer.parseTemplate(TemplateDataAnalyzer.java:200)
at com.vaadin.flow.component.polymertemplate.TemplateInitializer.<init>(TemplateInitializer.java:91)
at com.vaadin.flow.component.polymertemplate.PolymerTemplate.<init>(PolymerTemplate.java:88)
at com.vaadin.flow.component.polymertemplate.PolymerTemplate.<init>(PolymerTemplate.java:103)
at org.test.MyComponent.<init>(MyComponent.java:32)
at org.test.MainView.<init>(MainView.java:18)
Note: I am using Java8.
I am testing my UI, which at the start reads the user's cookies. I want to be able to inject various cookies into the initial MockRequest.
The Readme says to use currentRequest.mock.addCookie(Cookie("foo", "bar"))
however I cannot find this "currentRequest" variable anywhere, nor do I know how to insert the cookie before the UI is started.
My Test class looks something like this:
@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
@DirtiesContext
public class MyTest {
@Autowired
private BeanFactory beanFactory;
@Before
public void setup() {
UIScopeImpl.setBeanStoreRetrievalStrategy(new SingletonBeanStoreRetrievalStrategy());
MockVaadin.setup(() -> beanFactory.getBean(MyUI.class));
}
@Test
public void notLoggedInUserGetsTheLoginPage() {
assert(UI.getCurrent().getContent().equals(beanFactory.getBean(LoginPage.class)));
}
@Test
public void loggedInUserGetsTheMainPage() {
// For this test to work I need to insert a cookie into the MockRequest that goes into MyUI.class
assertFalse(UI.getCurrent().getContent().equals(beanFactory.getBean(LoginPage.class)));
}
@After
public void tearDown() {
MockVaadin.tearDown();
}
}
The first test works, because the default request has no cookies and my code displays the login page in that case.
How can I inject cookies into the MockRequest?
Hi Martin!
In our Vaadin 14 project we use this parent in our maven pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
</parent>
As soon as we update to 2.3.1 Karibu fails completely.
One issue ist, that _get produces InternalServerError s.
Are we doing something wrong or just braks Sping Boot the compatibility?
Regards,
Christoph
As in the docs, Components with HasErrorParameter should not have any Routes.
It would be really nice if they were detected in the Mock Setup.
For e.g.
@ParentLayout(MainLayout::class)
class AccessDeniedView : VerticalLayout(), HasErrorParameter {
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.