Пытаюсь реализовать кастомное условие на ожидание изменения списка потомков в DOM. Проблема в том, что размер этого списка может остаться прежним, при этом элементы могут обновиться. У меня есть окно выбора элементов, элементы которого я фильтрую при помощи строки поиска. После ввода строки в input, я хочу быть уверен, что  список элементов был изменен.


Я не смог найти готовое решение среди Conditions в selenide, поэтому решил прибегнуть к исполнению js в рамках теста. Я попытался подключить MutationObserver, который бы отслеживал изменения в родительской ноде для этих элементов, но я не уверен в таком случае, что объект наблюдателя создаться до заполнения строки фильтра из за асинхронности.
Каким образом можно отслеживать изменения в DOM после заполнения строки фильтра?
Код:
Класс с кастомным условием
    public IsElementChanged(){
        super("IsElementChanged");
    }
    @CheckReturnValue
    public @NotNull CheckResult check(Driver driver, WebElement element) {
        String script =
                "var callback = arguments[arguments.length - 1];" +
                "function elementChanged(arguments[0]) {\n" +
                "    return new Promise((resolve) => { \n" +
                "            new MutationObserver((mutationsList, observer) => {\n" +
                "                if (mutationsList.length > 0) {\n" +
                "                    resolve();\n" +
                "                    observer.disconnect();\n" +
                "                }\n" +
                "\n" +
                "            })\n" +
                "        .observe(targetNode, {subtree: true, childList: true});\n" +
                "    });\n" +
                "};\n" +
                "elementChanged(targetNode).then(() => { return callback(true); })";
        Object isElementChanged = null;
        try {
             isElementChanged = executeAsyncJavaScript(script, element);
        }
        catch (Exception e){
            e.printStackTrace();
        }
        boolean result = isElementChanged != null && (boolean) isElementChanged;
        String actualValue = String.format("isElementChanged:%s", result);
        return new CheckResult(result ? CheckResult.Verdict.ACCEPT : CheckResult.Verdict.REJECT, actualValue);
    }
    @CheckReturnValue
    @Nonnull
    public Condition negate() {
        return new Not(this, true);
    }
}
Вызов этого условия:
    /**
     * Метод осуществляет фильтрацию строк по тексту в столбце
     * @param searchStr строка поиска для фильтра
     * @param columnName название столбца
     */
    private void filterForColumn(String searchStr, String columnName) {
        // Xpath для фильтра конкретного столбца в таблице
        final String columnFilterInputXpathString = headerFilterRowXpathString +
                "//td[contains(@aria-label,'" +
                columnName +
                "')]" +
                "//input";
        final By columnFilterInputLocator = By.xpath(columnFilterInputXpathString);
        $(columnFilterInputLocator)
                .shouldBe(Condition.visible)
                .should(ajaxFinished)
                .clear();
        $(columnFilterInputLocator)
                .shouldBe(Condition.visible)
                .should(ajaxFinished)
                .sendKeys(searchStr);
        $(By.xpath(contentXpathString))
                **.should(isElementChanged)**
                .should(ajaxFinished);
    }
Selenide 6.0.3