How to trigger a listener from a test?

I have tried a couple of methods to set the ComboBox value, but the listener never gets triggered. Any ideas?

@Test
    void givenCustomPosition_whenFormIsDisplayed_thenDepartmentIsNotReadOnly() throws Exception {
        loginAndNavigate(ScheduleAssignView.class);
        @SuppressWarnings("unchecked") ComboBox<String> positionField = _get(ComboBox.class, spec -> spec.withLabel("Position"));
//        positionField.setValue("Banana");
        positionField.getElement().executeJs(
                "this.dispatchEvent(new CustomEvent('custom-value-set', { detail: $0 }))",
                "Banana"
        );

        var departmentField = _get(Select.class, spec -> spec.withLabel("Department"));

        assertThat(departmentField.isReadOnly()).isFalse();
    }
private void setupPositionComboBox() {
        position.setHelperText("Select or type a position");
        position.setItems(scheduleRepository.findAllPositionsByOrganization(account.organization())
                .sorted().map(Position::name).toList());
        position.setAllowCustomValue(true);
        position.addCustomValueSetListener(event -> {
            String value = event.getDetail();
            department.setReadOnly(Objects.isNull(value) || value.trim().isEmpty());
        });
    }

Why are you thinking that executing Javascript in a Java Unit Test would work?

You need to skip the client side part and create a server side “CustomValueSetEvent” event and publish to the component.

1 Like

Thanks for the suggestion. This worked:

@Test
    void givenCustomPosition_whenFormIsDisplayed_thenDepartmentIsNotReadOnly() {
        loginAndNavigate(ScheduleAssignView.class);
        @SuppressWarnings("unchecked")
        ComboBox<String> positionField = _get(ComboBox.class, spec -> spec.withLabel("Position"));
        Select<Department> departmentField = _get(Select.class, spec -> spec.withLabel("Department"));
    
        assertThat(departmentField.isReadOnly()).isTrue();
    
        String customPosition = "Banana";
        positionField.setValue(customPosition);
    
        ScheduleAssignForm scheduleAssignForm = _get(ScheduleAssignForm.class);
        scheduleAssignForm.handleCustomPosition(customPosition);
    
        assertThat(departmentField.isReadOnly()).isFalse();
    
        positionField.setValue("A1");
    
        scheduleAssignForm.handlePositionSelection("A1", List.of(position));
    
        assertThat(departmentField.isReadOnly()).isTrue();
    }

You should always use _setValue and _click because directly calling setValue or click will not respect the state of the component!

3 Likes

If you’d like to set a custom value and have the event fired, please take a look at karibu-testing/karibu-testing-v10 at master · mvysny/karibu-testing · GitHub ; perhaps ComboBoxKt._fireCustomValueSet() would do the trick for you.

2 Likes

Thanks Simon. Can you say more about that? In these cases, I’m thinking that I would prefer for the state to be respected since I am in fact testing the state to make sure that the rules I have set up are working.

Thanks Martin! I’m a big fan of Karibu. Thanks for your work on that. I had not considered _fireCustomValueSet. I’ll take a look.

1 Like

You can check the docs: karibu-testing/karibu-testing-v10 at master · mvysny/karibu-testing · GitHub

1 Like

But be careful not the complete state is checked. It is only checked if the InputField is visible and not read-only. But say you have a datepicker. When you specify a date as a min date you can still set a date before the min date with _set. if it is important for you that the validation is correctly set up you can not only rely on _set alone.

1 Like

As I wrote in your other post the DatePicker is a very special component and most of the validation happens on the browser side