selenide: Problem with fastSetValue on Material UI Components

The problem

Material UI is one of the most popular React Components library. And when i’m trying to use Selenide with fastSetValues (setting values via js) it’s not working correctly.

Details

When Selenide sets value via JS Material UI component ( Autocomplete ) do not call hooks like onInputChange and others.

Tell us about your environment

  • Selenide Version: 5.8.0
  • Yandex browser: 20.2.0.1145
  • Browser Driver Version: 79
  • Selenium Version: embedded in Selenide
  • OS Version: mac OS

Code To Reproduce Issue [ Good To Have ]

To reproduce the bug you may run the test:

@Test
    void check() {
        Configuration.fastSetValue = true;
        open("https://rusakovstas.github.io/material-autocomplete/");
        $(byText("Вбейте что нибудь или скопируйте")).closest("div").$("input").setValue("123");
        $(byText("Поймали логику!")).shouldBe(visible);
    }

For now it’s failed. If you remove Configuration.fastSetValue = true; it works fine.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (5 by maintainers)

Commits related to this issue

Most upvoted comments

So, since the fix https://github.com/selenide/selenide/issues/1074#issuecomment-593118940 broke tests, i think there is nothing to do. Issue may be closed.

But for now you could use custom commands via execute method) For my case i wrote a command like this:

public static Command<SelenideElement> setValueAttribute(String value) {
       return (proxy, locator, args) -> {
           Selenide.executeJavaScript("arguments[0].focus(); arguments[0].setAttribute('value', arguments[1]);", proxy, value);
           events.fireEvent(locator.driver(), proxy, "keydown", "keypress", "input", "keyup", "change");
           return proxy;
       };
    }

And in tests it’s look like: $("input").execute(setValueAttribute("some value"));

Hi, we also found this issue and evaluated it a little bit further and created an issue at MaterialUI https://github.com/mui-org/material-ui/issues/19346. The issue seems to be exclusive to the ChromeDriver.

Hi! I’ve finally found the solution of this question! It’s really simple) To set value via js properly for Material UI you have to do this by setAttribute('value', 'some text'); Not just element.value = I think the reason in some JS Proxy or something like that.

I even have changed the method setValue in Selenide and it’s working (after local install)! But now:

  1. i can’t push branch (getting 403). Maybe there are some rules for that?
  2. i’m not sure how can i write the test for this?

Just in case the code for fix is pretty simple:

private String setValueByJs(Driver driver, WebElement element, String text) {
    return driver.executeJavaScript(
        "return (function(webelement, text) {" +
            "if (webelement.getAttribute('readonly') != undefined) return 'Cannot change value of readonly element';" +
            "if (webelement.getAttribute('disabled') != undefined) return 'Cannot change value of disabled element';" +
            "webelement.focus();" +
            "var maxlength = webelement.getAttribute('maxlength') == null ? -1 : parseInt(webelement.getAttribute('maxlength'));" +
            "webelement.setAttribute('value', " +
            "maxlength == -1 ? text " +
            ": text.length <= maxlength ? text " +
            ": text.substring(0, maxlength));" +
            "return null;" +
            "})(arguments[0], arguments[1]);",
        element, text);
  }