@ExtendWith(KaribuUIExtension.class)
@WithLocale
public class BusinessPartnerViewTest {
Tutorial
Step 11: UI Tests
| This step shows you how to write UI tests (using Karibu-Testing) for the components written in linkki. |
KaribuUIExtension
Let’s start with writing UI tests for BusinessPartnerView .
Create a test class named BusinessPartnerViewTest:
The annotations on the test class instantiate a Vaadin UI for testing and configure the default locale.
Testing the BusinessPartnerView
As a first test, you should test the search functionality of the BusinessPartnerView.
The test should:
-
Programmatically enter a value in the search field
-
Click the search button
-
Verify the results
Access the UI components by using the static method LocatorJ._get.
It is recommended to use the utility methods provided in KaribuUtils, as they offer more convenient and robust options for interacting with the UI.
The following example shows how to search for a partner and check if a matching result is present.
@Test
void testSearchFieldWithResult() {
var businessPartnerView = new BusinessPartnerView(InMemoryBusinessPartnerRepository.newSampleRepository());
var searchField = _get(businessPartnerView, TextField.class, ss -> ss.withId("searchText"));
KaribuUtils.Fields.setValue(searchField, "John");
var searchButton = _get(businessPartnerView, Button.class, ss -> ss.withId("search"));
searchButton.click();
var resultTable = KaribuUtils.Grids.get(businessPartnerView);
assertThat(resultTable.getColumns()).hasSize(3);
var nameColumnValues = KaribuUtils.Grids.getTextContentsInColumn(resultTable, "name");
var addressColumnValues = KaribuUtils.Grids.getTextContentsInColumn(resultTable, "firstAddress");
assertThat(nameColumnValues).containsExactly("John Doe");
assertThat(addressColumnValues).containsExactly("Im Zollhafen 15/17\n50678 Cologne\nGermany");
}
|
Always use |
As you can see in the example, the _get-function obtains the search field from the BusinessPartnerView by its ID searchText.
The ID of a component created by linkki is the name of the corresponding PMO property.
KaribuUtils also provides convenient functions to extract all values from a column as strings. As you can see, this is used to acquire the names and addresses written in the name and address column, allowing to write assertions for those values.
Now, write a test case, where the search yields no result because there is no business partner matching the search criteria. Once you are done, it should look similar to the following example:
@Test
void testSearchFieldWithNoResult() {
var businessPartnerView = new BusinessPartnerView(InMemoryBusinessPartnerRepository.newSampleRepository());
var searchField = _get(businessPartnerView, TextField.class, ss -> ss.withId("searchText"));
KaribuUtils.Fields.setValue(searchField, "non-existent");
var searchButton = _get(businessPartnerView, Button.class, ss -> ss.withId("search"));
searchButton.click();
var resultTable = KaribuUtils.Grids.get(businessPartnerView);
assertThat(resultTable.getColumns()).hasSize(3);
var nameColumnValues = KaribuUtils.Grids.getTextContentsInColumn(resultTable, "name");
var addressColumnValues = KaribuUtils.Grids.getTextContentsInColumn(resultTable, "firstAddress");
assertThat(nameColumnValues).isEmpty();
assertThat(addressColumnValues).isEmpty();
}
Testing the PartnerDetailsView
After having properly tested the search page, your next task is to test PartnerDetailsView as well!
PartnerDetailsView implements HasUrlParameter, which will require some special attention during testing.
Therefore, we have to configure Vaadin so that we can navigate to the PartnerDetailsView.
class PartnerDetailsViewTest {
private final String johnDoesId = "ac54f2f9-7b82-4bc8-ab69-554cac5926f1";
@RegisterExtension
KaribuUIExtension karibuUIExtension = KaribuUIExtension
.withConfiguration(new KaribuConfiguration()
.addRoute(PartnerDetailsView.class,
() -> new PartnerDetailsView(InMemoryBusinessPartnerRepository
.newSampleRepository()))
.setLocale(Locale.GERMAN));
As you can see, instead of annotating the test-class with @ExtendWith, you have to declare a field of type KaribuUIExtension and annotate that field with @RegisterExtension.
This way, KaribuUIExtension can be configured beyond its default configuration, and we can register a route to PartnerDetailsView.
The next test uses UI.getCurrent().navigate(…) to navigate to the PartnerDetailsView given a business partner ID.
It then tests if the business partner information is displayed correctly.
@Test
void testExistingPartner() {
var partnerDetailsView = UI.getCurrent()
.navigate(PartnerDetailsView.class, johnDoesId).get();
var partnerDetailsSection = _get(partnerDetailsView, LinkkiSection.class,
ss -> ss.withId(PartnerDetailsSectionPmo.class.getSimpleName()));
var name = _get(partnerDetailsSection, TextField.class, ss -> ss.withId("name")).getValue();
var dateOfBirth = _get(partnerDetailsSection, DatePicker.class, ss -> ss.withId("dateOfBirth")).getValue();
var note = _get(partnerDetailsSection, TextArea.class, ss -> ss.withId("note")).getValue();
assertThat(name).isEqualTo("John Doe");
assertThat(dateOfBirth).isBefore(LocalDate.now());
assertThat(note).isEmpty();
}
Now try to write a test case yourself where no partner could be found for the given ID!
It should look like the following test:
@Test
void testPartnerDoesNotExist() {
var partnerDetailsView = UI.getCurrent()
.navigate(PartnerDetailsView.class, "9999-9999-9999-9999-9999").get();
var errorText = _get(partnerDetailsView, Text.class);
assertThat(errorText.getText()).isEqualTo("No partner could be found with the given ID");
}
Testing Dialogs and Validation-Messages
Finally, it’s time to test dialogs and validation messages!
To test the dialog for adding a new address, you must:
-
Navigate to the appropriate tab
-
Trigger the dialog
-
Interact with and write assertions for the dialog’s content
The first test should check the happy path, when all fields are set, the dialog closes properly and another entry appears in our address table.
@Test
void testAddAddress_valid() {
// given
UI.getCurrent().navigate(PartnerDetailsView.class, johnDoesId);
_get(Tabs.class).setSelectedIndex(2);
var addressTable = KaribuUtils.Layouts.getWithPmo(LinkkiSection.class, AddressTablePmo.class);
// when
_get(addressTable, Button.class, ss -> ss.withId("addAddressDialogPmo")).click();
var dialog = _get(Dialog.class);
var street = _get(dialog, TextField.class, ss -> ss.withId("street"));
var streetNumber = _get(dialog, TextField.class, ss -> ss.withId("streetNumber"));
var postalCode = _get(dialog, TextField.class, ss -> ss.withId("postalCode"));
var city = _get(dialog, TextField.class, ss -> ss.withId("city"));
var country = _get(dialog, TextField.class, ss -> ss.withId("country"));
KaribuUtils.Fields.setValue(street, "Mediterranean Avenue");
KaribuUtils.Fields.setValue(streetNumber, "1");
KaribuUtils.Fields.setValue(postalCode, "12345");
KaribuUtils.Fields.setValue(city, "San Francisco");
KaribuUtils.Fields.setValue(country, "USA");
KaribuUtils.Dialogs.clickOkButton();
// then
LocatorJ._assertNoDialogs();
var grid = KaribuUtils.Grids.get(addressTable);
assertThat(KaribuUtils.Grids.getTextContentsInColumn(grid, "street")).contains("Mediterranean Avenue");
assertThat(KaribuUtils.Grids.getTextContentsInColumn(grid, "streetNumber")).contains("1");
assertThat(KaribuUtils.Grids.getTextContentsInColumn(grid, "postalCode")).contains("12345");
assertThat(KaribuUtils.Grids.getTextContentsInColumn(grid, "city")).contains("San Francisco");
assertThat(KaribuUtils.Grids.getTextContentsInColumn(grid, "country")).contains("USA");
}
Next, you need to check that the validations work correctly. Therefore, you can press the OK-Button right after the dialog opened and while all fields are empty. The result should be that all fields have an error message saying that the field must not be empty.
@Test
void testAddAddress_invalid() {
// given
UI.getCurrent().navigate(PartnerDetailsView.class, johnDoesId);
_get(Tabs.class).setSelectedIndex(2);
var addressTablePmo = KaribuUtils.Layouts.getWithPmo(LinkkiSection.class, AddressTablePmo.class);
// when
_get(addressTablePmo, Button.class, ss -> ss.withId("addAddressDialogPmo")).click();
var dialog = _get(Dialog.class);
var street = _get(dialog, TextField.class, ss -> ss.withId("street"));
var number = _get(dialog, TextField.class, ss -> ss.withId("streetNumber"));
var postalCode = _get(dialog, TextField.class, ss -> ss.withId("postalCode"));
var city = _get(dialog, TextField.class, ss -> ss.withId("city"));
KaribuUtils.Dialogs.clickOkButton();
// then
assertThat(street.getErrorMessage()).isEqualTo("The field Street must not be empty.");
assertThat(number.getErrorMessage()).isEqualTo("The field Street number must not be empty.");
assertThat(postalCode.getErrorMessage()).isEqualTo("The field Postal code must not be empty.");
assertThat(city.getErrorMessage()).isEqualTo("The field City must not be empty.");
}
Congratulations! You’ve now seen how to:
-
Write simple UI tests with KaribuUIExtension,
-
Test interactive components like search fields and tables,
-
Handle routing and navigation in tests,
-
Assert on validation messages and dialog interactions.