vaadin / testbench

Vaadin TestBench is a tool for automated user interface testing of Vaadin applications.
https://vaadin.com/testbench
Other
20 stars 22 forks source link

Add support for LitRenderers to GridTester #1775

Closed joelpop closed 2 months ago

joelpop commented 3 months ago

LitRenderers in Grids can contain properties and functions, but have no way for them to be inspected or invoked, respectively.

This issue is a request to enhance the GridTester to support this capability.

Proposed code is:

    public <V> V getLitRendererPropertyValue(int row, String columnKey, String propertyName, Class<V> propertyClass) {
        var column = getColumn(columnKey);
        if (column.getRenderer() instanceof LitRenderer<Y> litRenderer) {
            var valueProvider = findLitRendererProperty(litRenderer, propertyName);
            var untypedValue = valueProvider.apply(getRow(row));
            if (propertyClass.isInstance(untypedValue)) {
                return propertyClass.cast(untypedValue);
            } else {
                throw new UnexpectedTypeException("Target column property value is the wrong type - expected %s, found %s."
                        .formatted(propertyClass.getCanonicalName(), untypedValue.getClass().getCanonicalName()));
            }
        } else {
            throw new IllegalArgumentException("Target column doesn't have a LitRenderer.");
        }
    }

    public void invokeLitRendererFunction(int row, String columnKey, String functionName) {
        var column = getColumn(columnKey);
        if (column.getRenderer() instanceof LitRenderer<Y> litRenderer) {
            var callable = findLitRendererFunction(litRenderer, functionName);
            callable.accept(getRow(row), Json.createArray());
        } else {
            throw new IllegalArgumentException("Target column doesn't have a LitRenderer.");
        }
    }

    private <V> ValueProvider<Y, V> findLitRendererProperty(LitRenderer<Y> renderer, String propertyName) {
        var valueProvidersField = getField(LitRenderer.class, "valueProviders");
        try {
            @SuppressWarnings("unchecked")
            var valueProviders = (Map<String, ValueProvider<Y, V>>) valueProvidersField.get(renderer);
            var valueProvider = valueProviders.get(propertyName);
            if (valueProvider == null) {
                throw new IllegalArgumentException("Property " + propertyName + " is not registered in LitRenderer.");
            }
            return valueProvider;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private SerializableBiConsumer<Y, JsonArray> findLitRendererFunction(LitRenderer<Y> renderer, String functionName) {
        var clientCallablesField = getField(LitRenderer.class, "clientCallables");
        try {
            @SuppressWarnings("unchecked")
            var clientCallables = (Map<String, SerializableBiConsumer<Y, JsonArray>>) clientCallablesField.get(renderer);
            var callable = clientCallables.get(functionName);
            if (callable == null) {
                throw new IllegalArgumentException("Function " + functionName + " is not registered in LitRenderer.");
            }
            return callable;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }