Add TestBench API/support for accessing and testing Grid inline editor components
When using the inline editing feature of a Grid component, there isn't any API in TestBench to access and test editor components.
Consider the following view (taken from the example in the docs):
Grid<Person> grid = new Grid<>(Person.class, false);
Editor<Person> editor = grid.getEditor();
Grid.Column<Person> firstNameColumn = grid
.addColumn(Person::getFirstName).setHeader("First name")
.setWidth("120px").setFlexGrow(0);
Grid.Column<Person> lastNameColumn = grid.addColumn(Person::getLastName)
.setHeader("Last name").setWidth("120px").setFlexGrow(0);
Grid.Column<Person> emailColumn = grid.addColumn(Person::getEmail)
.setHeader("Email");
Grid.Column<Person> editColumn = grid.addComponentColumn(person -> {
Button editButton = new Button("Edit");
editButton.addClickListener(e -> {
if (editor.isOpen())
editor.cancel();
grid.getEditor().editItem(person);
});
return editButton;
}).setWidth("150px").setFlexGrow(0);
Binder<Person> binder = new Binder<>(Person.class);
editor.setBinder(binder);
editor.setBuffered(true);
TextField firstNameField = new TextField();
firstNameField.setWidthFull();
binder.forField(firstNameField)
.asRequired("First name must not be empty")
.withStatusLabel(firstNameValidationMessage)
.bind(Person::getFirstName, Person::setFirstName);
firstNameColumn.setEditorComponent(firstNameField);
TextField lastNameField = new TextField();
lastNameField.setWidthFull();
binder.forField(lastNameField).asRequired("Last name must not be empty")
.withStatusLabel(lastNameValidationMessage)
.bind(Person::getLastName, Person::setLastName);
lastNameColumn.setEditorComponent(lastNameField);
EmailField emailField = new EmailField();
emailField.setWidthFull();
binder.forField(emailField).asRequired("Email must not be empty")
.withValidator(
new EmailValidator("Enter a valid email address"))
.withStatusLabel(emailValidationMessage)
.bind(Person::getEmail, Person::setEmail);
emailColumn.setEditorComponent(emailField);
Button saveButton = new Button("Save", e -> editor.save());
Button cancelButton = new Button(VaadinIcon.CLOSE.create(),
e -> editor.cancel());
cancelButton.addThemeVariants(ButtonVariant.LUMO_ICON,
ButtonVariant.LUMO_ERROR);
HorizontalLayout actions = new HorizontalLayout(saveButton,
cancelButton);
actions.setPadding(false);
editColumn.setEditorComponent(actions);
If I try to test the "Edit" button:
var grid = $(Grid.java).first();
var editColumn = test(grid).getCellComponent(0, 3);
var editButton = $(Button.class, editColumn).first();
test(editButton).click();
I get the following error:
java.lang.IllegalStateException: Button[caption='Edit'] is not usable
To work around this, I can call click() directly on the component:
...
editButton.click();
var firstNameColumn = (Grid.Column) grid.getColumns().get(0);
var firstNameField = (TextField) firstNameColumn.getEditorComponent();
assertThat(firstNameField.getValue()).isEqualTo("Aria");
Then the assertion fails because the value in the field is empty. I can "force" it to update by doing another query:
...
firstNameField = $(TextField.class, firstNameField).first(); // Doesn't have to involve the first name field
assertThat(firstNameField.getValue()).isEqualTo("Aria");
This time the assertion passes.
There are two issues that this highlights:
- It seems that some simple things like testing components in a grid doesn't work using the tester classes.
- There is no API to test inline editing.
The second used to be possible in Vaadin 8 (GridEditorTest.java).
Example project with failing tests to show the issues: https://github.com/MatthewVaadin/grid-testing