Java - Wait for JavaScript event (e.g. onchange) to complete using Selenium









up vote
0
down vote

favorite












A set of logically related input fields have an onchange event. After iterating over the fields and modifying their values some get updated correctly and some don't because of the stuff done by onchange event.



The moment the onchange event triggers on a field, it starts some processing (involving other related fields), stores the value somewhere and clears other related fields if they weren't previously processed by their own onchange event.



I could put the thread to sleep for an arbitrary amount of time but that doesn't look good. It would be just guessing how much time is going to take the processing and choosing between wasting time in a generous sleep or having a script that can abort due timeouts.



Is there a way to know when the JavaScript code (which is called by the onchange event) has finished doing its work?



Original Code



Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
for(int i = 1; i <= fieldCount; i++)
elementId = "field$" + i;
wait.until(ExpectedConditions.elementToBeClickable(By.id(elementId)));
driver.findElementById(elementId).sendKeys(data);
//The mess happens if I don't sleep
Thread.sleep(3000);



Output



With sleep: Field1:_w_ ... Field2:_x_ ... Field3:_y_ ... FieldN:_z_



Without sleep: Field1:_w_ ... Field2:___ ... Field3:_y_ ... FieldN:___



Notes:



I experienced some issues in the way so I just think it's worth mentioning the lessons learned in brief notes:




WARNING: Do not mix implicit and explicit waits.



Use WebDriverWait (specialization of FluentWait) instead of FluentWait, unless you have a very specific requirement. E.g., WebDriverWait ignores NotFoundException (NoSuchElementException's superclass) by default. See recomendation.











share|improve this question



























    up vote
    0
    down vote

    favorite












    A set of logically related input fields have an onchange event. After iterating over the fields and modifying their values some get updated correctly and some don't because of the stuff done by onchange event.



    The moment the onchange event triggers on a field, it starts some processing (involving other related fields), stores the value somewhere and clears other related fields if they weren't previously processed by their own onchange event.



    I could put the thread to sleep for an arbitrary amount of time but that doesn't look good. It would be just guessing how much time is going to take the processing and choosing between wasting time in a generous sleep or having a script that can abort due timeouts.



    Is there a way to know when the JavaScript code (which is called by the onchange event) has finished doing its work?



    Original Code



    Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
    for(int i = 1; i <= fieldCount; i++)
    elementId = "field$" + i;
    wait.until(ExpectedConditions.elementToBeClickable(By.id(elementId)));
    driver.findElementById(elementId).sendKeys(data);
    //The mess happens if I don't sleep
    Thread.sleep(3000);



    Output



    With sleep: Field1:_w_ ... Field2:_x_ ... Field3:_y_ ... FieldN:_z_



    Without sleep: Field1:_w_ ... Field2:___ ... Field3:_y_ ... FieldN:___



    Notes:



    I experienced some issues in the way so I just think it's worth mentioning the lessons learned in brief notes:




    WARNING: Do not mix implicit and explicit waits.



    Use WebDriverWait (specialization of FluentWait) instead of FluentWait, unless you have a very specific requirement. E.g., WebDriverWait ignores NotFoundException (NoSuchElementException's superclass) by default. See recomendation.











    share|improve this question

























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      A set of logically related input fields have an onchange event. After iterating over the fields and modifying their values some get updated correctly and some don't because of the stuff done by onchange event.



      The moment the onchange event triggers on a field, it starts some processing (involving other related fields), stores the value somewhere and clears other related fields if they weren't previously processed by their own onchange event.



      I could put the thread to sleep for an arbitrary amount of time but that doesn't look good. It would be just guessing how much time is going to take the processing and choosing between wasting time in a generous sleep or having a script that can abort due timeouts.



      Is there a way to know when the JavaScript code (which is called by the onchange event) has finished doing its work?



      Original Code



      Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
      for(int i = 1; i <= fieldCount; i++)
      elementId = "field$" + i;
      wait.until(ExpectedConditions.elementToBeClickable(By.id(elementId)));
      driver.findElementById(elementId).sendKeys(data);
      //The mess happens if I don't sleep
      Thread.sleep(3000);



      Output



      With sleep: Field1:_w_ ... Field2:_x_ ... Field3:_y_ ... FieldN:_z_



      Without sleep: Field1:_w_ ... Field2:___ ... Field3:_y_ ... FieldN:___



      Notes:



      I experienced some issues in the way so I just think it's worth mentioning the lessons learned in brief notes:




      WARNING: Do not mix implicit and explicit waits.



      Use WebDriverWait (specialization of FluentWait) instead of FluentWait, unless you have a very specific requirement. E.g., WebDriverWait ignores NotFoundException (NoSuchElementException's superclass) by default. See recomendation.











      share|improve this question















      A set of logically related input fields have an onchange event. After iterating over the fields and modifying their values some get updated correctly and some don't because of the stuff done by onchange event.



      The moment the onchange event triggers on a field, it starts some processing (involving other related fields), stores the value somewhere and clears other related fields if they weren't previously processed by their own onchange event.



      I could put the thread to sleep for an arbitrary amount of time but that doesn't look good. It would be just guessing how much time is going to take the processing and choosing between wasting time in a generous sleep or having a script that can abort due timeouts.



      Is there a way to know when the JavaScript code (which is called by the onchange event) has finished doing its work?



      Original Code



      Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
      for(int i = 1; i <= fieldCount; i++)
      elementId = "field$" + i;
      wait.until(ExpectedConditions.elementToBeClickable(By.id(elementId)));
      driver.findElementById(elementId).sendKeys(data);
      //The mess happens if I don't sleep
      Thread.sleep(3000);



      Output



      With sleep: Field1:_w_ ... Field2:_x_ ... Field3:_y_ ... FieldN:_z_



      Without sleep: Field1:_w_ ... Field2:___ ... Field3:_y_ ... FieldN:___



      Notes:



      I experienced some issues in the way so I just think it's worth mentioning the lessons learned in brief notes:




      WARNING: Do not mix implicit and explicit waits.



      Use WebDriverWait (specialization of FluentWait) instead of FluentWait, unless you have a very specific requirement. E.g., WebDriverWait ignores NotFoundException (NoSuchElementException's superclass) by default. See recomendation.








      javascript java selenium events onchange






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 19:04

























      asked Nov 7 at 22:56









      CamelCamelius

      439




      439






















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          0
          down vote













          You might try this method which waits until JQuery is set to inactive:



          /**
          * Wait until JQuery is inactive
          * @author Bill Hileman
          */
          public void waitForJQueryToBeInactive()

          Boolean isJqueryUsed = (Boolean) ((JavascriptExecutor) driver)
          .executeScript("return (typeof(jQuery) != 'undefined')");

          if (isJqueryUsed)
          while (true)
          // JavaScript test to verify jQuery is active or not
          Boolean ajaxIsComplete = (Boolean) (((JavascriptExecutor) driver)
          .executeScript("return jQuery.active == 0"));
          if (ajaxIsComplete)
          break;
          try
          Thread.sleep(100);
          catch (InterruptedException e)










          share|improve this answer




















          • Thanks. JQuery is not being used. Interesting jQuery.active. Didn't know about it. According to question it would work only if the code in execution is an ajax call, did I get it right ? Is there anything like that but that works with JavaScript ?
            – CamelCamelius
            Nov 8 at 16:49











          • I do have a more general waitForPageToLoad method that uses javascript to check the document ready state for "complete" It might help, since that flag might be getting changed while the web elements are "busy" I'll post it as a separate answer.
            – Bill Hileman
            Nov 8 at 17:41

















          up vote
          0
          down vote













          The following routine checks the document ready state for "complete" and returns when the page is finished loading/changing.



          /**
          * Wait for the web page to finish loading
          * @author Bill Hileman
          */
          public void waitForPageToLoad()

          WebDriverWait wait = new WebDriverWait(driver, 10);
          wait.until(new ExpectedCondition<Boolean>()

          public Boolean apply(WebDriver wdriver)
          return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");

          );






          share|improve this answer




















          • Thanks Bill! Unfortunately I am already executing return document.readyState so everything is already loaded. Sometimes I even have to get the element everytime I want to execute an action on it or I end up getting an error saying that the element is no longer in cache, so I verify elements are there.
            – CamelCamelius
            Nov 8 at 22:07

















          up vote
          0
          down vote













          To my best of knowledge, you can't wait for an asynchronous event using Selenium Web Driver. You may, however, be able to wait for effects of that event using WebDriverWait class. If events You mentioned, make some changes in the DOM, you can detect those changes by using selected ExpectedConditions.



           Wait<WebDriver> wait = new WebDriverWait(driver, 15, 500);

          // here you make some change to the input

          wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//input")));


          This simple example would wait until a button is active.
          If the expected conditions are not met in the next 15s exception will be thrown.



          In case, that provided set of ExpectedConditions is insufficient you can always create your own by implementing ExpectedCondition interface.
          For more information visit the documentation.



          https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/package-summary.html
          https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/package-summary.html






          share|improve this answer






















          • Thanks. Just a side note, I am working with input fields instead of buttons. I would use ExpectedConditions.elementToBeClickable but I get an exception so I just check ExpectedConditions.visibilityOf. The issue is that the onchange events on fields seem to be clearing other fields if they haven't been validated so I wanted to see a way to determine when the event finishes
            – CamelCamelius
            Nov 8 at 16:21










          • That was just an idea, maybe I could give a better solution, but I'm still unclear about what You're trying to achieve. If the idea is to see if the fields are empty you could write some custom ExpectedCondition to wait for that specific situation.
            – Mateusz
            Nov 8 at 17:01










          • Got it. Fields are empty and I setup a value. After that it runs some JavaScript. If I populate the next related field immediately, it loses it's content but if I give some time so the JavaScript finishes whatever it is doing, I can update the next related field without issues. Also they look the same before and after the onchange event...it's just the background processing what's giving issues and wanted to check if there was a way to do it without hardcoding a sleep time. Thanks
            – CamelCamelius
            Nov 8 at 19:41











          • Ok, I think I understand now. You have a set of connected input fields, that if you change one, the asynchronous task prohibits you from changing the next one, however, it does not change its original value (the next one).
            – Mateusz
            Nov 8 at 20:19











          • I also must ask are there any visible indications for the user of such process taking place in the background?
            – Mateusz
            Nov 8 at 20:30

















          up vote
          0
          down vote



          accepted










          After serious refactoring and some research, I finally made it. The onchange event fires when the value of the input field is changed and the element loses focus. Manipulating the fields with WebElement (e.g. sendKeys()) is not an option because you are not in control of the background processing, so using JavascriptExecutor is the choice. First, I updated the value of the field using JavaScript (which does NOT trigger the event), and after that, I triggered the onchange event, also using JavaScript:



          //Setting implicit wait to 0 to avoid mess with explicit waits
          driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
          //Use WebDriverWait instead of FluentWait (it's superclass)
          Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
          for(int i = 1; i <= fieldCount; i++)
          String elementId = "field$" + i;
          String javaScript = String.format("document.getElementById('%s').value='%s';", elementId , myValue);
          Object jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
          javaScript = String.format("return document.getElementById('%s').dispatchEvent(new Event('change'));", elementId);
          jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));



          There are some key aspects here.



          • Do NOT mix implicit and explicit waits (I learnt it the hard way), it will cause unexpected results.

          • Use WebDriverWait (specialization of FluentWait) instead of its superclass, unless you have a very specific requirement. If you use FluentWait make sure to ignore appropriate exceptions; otherwise you will start getting NoSuchElementException.

          • The onchange event fires when the value of the input field is changed and the element loses focus.


          • dispatchEvent() dispatches an Event at the specified EventTarget, (synchronously) invoking the affected EventListeners in the appropriate order. This applies for custom events as well. This is a very nice post for events.

          I used the following code to get a better grasp of ExpectedConditions.javaScriptThrowsNoExceptions and ExpectedConditions.jsReturnsValue. It is a JavaScript function call that just keeps the engine busy for few seconds. That way you can see the interaction of the explicit wait with JavaScript and inspect the return values. Notice that the JS code is slightly different for each ExpectedCondition:



          //ExpectedConditions.jsReturnsValue
          String javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);return 'success';";
          log.trace("javaScript=", javaScript);
          Object jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));
          log.trace("jsResult=", jsResult);

          //ExpectedConditions.javaScriptThrowsNoExceptions
          javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);";
          log.trace("javaScript=", javaScript);
          jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
          log.trace("jsResult=", jsResult);





          share|improve this answer




















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53199159%2fjava-wait-for-javascript-event-e-g-onchange-to-complete-using-selenium%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            0
            down vote













            You might try this method which waits until JQuery is set to inactive:



            /**
            * Wait until JQuery is inactive
            * @author Bill Hileman
            */
            public void waitForJQueryToBeInactive()

            Boolean isJqueryUsed = (Boolean) ((JavascriptExecutor) driver)
            .executeScript("return (typeof(jQuery) != 'undefined')");

            if (isJqueryUsed)
            while (true)
            // JavaScript test to verify jQuery is active or not
            Boolean ajaxIsComplete = (Boolean) (((JavascriptExecutor) driver)
            .executeScript("return jQuery.active == 0"));
            if (ajaxIsComplete)
            break;
            try
            Thread.sleep(100);
            catch (InterruptedException e)










            share|improve this answer




















            • Thanks. JQuery is not being used. Interesting jQuery.active. Didn't know about it. According to question it would work only if the code in execution is an ajax call, did I get it right ? Is there anything like that but that works with JavaScript ?
              – CamelCamelius
              Nov 8 at 16:49











            • I do have a more general waitForPageToLoad method that uses javascript to check the document ready state for "complete" It might help, since that flag might be getting changed while the web elements are "busy" I'll post it as a separate answer.
              – Bill Hileman
              Nov 8 at 17:41














            up vote
            0
            down vote













            You might try this method which waits until JQuery is set to inactive:



            /**
            * Wait until JQuery is inactive
            * @author Bill Hileman
            */
            public void waitForJQueryToBeInactive()

            Boolean isJqueryUsed = (Boolean) ((JavascriptExecutor) driver)
            .executeScript("return (typeof(jQuery) != 'undefined')");

            if (isJqueryUsed)
            while (true)
            // JavaScript test to verify jQuery is active or not
            Boolean ajaxIsComplete = (Boolean) (((JavascriptExecutor) driver)
            .executeScript("return jQuery.active == 0"));
            if (ajaxIsComplete)
            break;
            try
            Thread.sleep(100);
            catch (InterruptedException e)










            share|improve this answer




















            • Thanks. JQuery is not being used. Interesting jQuery.active. Didn't know about it. According to question it would work only if the code in execution is an ajax call, did I get it right ? Is there anything like that but that works with JavaScript ?
              – CamelCamelius
              Nov 8 at 16:49











            • I do have a more general waitForPageToLoad method that uses javascript to check the document ready state for "complete" It might help, since that flag might be getting changed while the web elements are "busy" I'll post it as a separate answer.
              – Bill Hileman
              Nov 8 at 17:41












            up vote
            0
            down vote










            up vote
            0
            down vote









            You might try this method which waits until JQuery is set to inactive:



            /**
            * Wait until JQuery is inactive
            * @author Bill Hileman
            */
            public void waitForJQueryToBeInactive()

            Boolean isJqueryUsed = (Boolean) ((JavascriptExecutor) driver)
            .executeScript("return (typeof(jQuery) != 'undefined')");

            if (isJqueryUsed)
            while (true)
            // JavaScript test to verify jQuery is active or not
            Boolean ajaxIsComplete = (Boolean) (((JavascriptExecutor) driver)
            .executeScript("return jQuery.active == 0"));
            if (ajaxIsComplete)
            break;
            try
            Thread.sleep(100);
            catch (InterruptedException e)










            share|improve this answer












            You might try this method which waits until JQuery is set to inactive:



            /**
            * Wait until JQuery is inactive
            * @author Bill Hileman
            */
            public void waitForJQueryToBeInactive()

            Boolean isJqueryUsed = (Boolean) ((JavascriptExecutor) driver)
            .executeScript("return (typeof(jQuery) != 'undefined')");

            if (isJqueryUsed)
            while (true)
            // JavaScript test to verify jQuery is active or not
            Boolean ajaxIsComplete = (Boolean) (((JavascriptExecutor) driver)
            .executeScript("return jQuery.active == 0"));
            if (ajaxIsComplete)
            break;
            try
            Thread.sleep(100);
            catch (InterruptedException e)











            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 8 at 14:29









            Bill Hileman

            1,9922617




            1,9922617











            • Thanks. JQuery is not being used. Interesting jQuery.active. Didn't know about it. According to question it would work only if the code in execution is an ajax call, did I get it right ? Is there anything like that but that works with JavaScript ?
              – CamelCamelius
              Nov 8 at 16:49











            • I do have a more general waitForPageToLoad method that uses javascript to check the document ready state for "complete" It might help, since that flag might be getting changed while the web elements are "busy" I'll post it as a separate answer.
              – Bill Hileman
              Nov 8 at 17:41
















            • Thanks. JQuery is not being used. Interesting jQuery.active. Didn't know about it. According to question it would work only if the code in execution is an ajax call, did I get it right ? Is there anything like that but that works with JavaScript ?
              – CamelCamelius
              Nov 8 at 16:49











            • I do have a more general waitForPageToLoad method that uses javascript to check the document ready state for "complete" It might help, since that flag might be getting changed while the web elements are "busy" I'll post it as a separate answer.
              – Bill Hileman
              Nov 8 at 17:41















            Thanks. JQuery is not being used. Interesting jQuery.active. Didn't know about it. According to question it would work only if the code in execution is an ajax call, did I get it right ? Is there anything like that but that works with JavaScript ?
            – CamelCamelius
            Nov 8 at 16:49





            Thanks. JQuery is not being used. Interesting jQuery.active. Didn't know about it. According to question it would work only if the code in execution is an ajax call, did I get it right ? Is there anything like that but that works with JavaScript ?
            – CamelCamelius
            Nov 8 at 16:49













            I do have a more general waitForPageToLoad method that uses javascript to check the document ready state for "complete" It might help, since that flag might be getting changed while the web elements are "busy" I'll post it as a separate answer.
            – Bill Hileman
            Nov 8 at 17:41




            I do have a more general waitForPageToLoad method that uses javascript to check the document ready state for "complete" It might help, since that flag might be getting changed while the web elements are "busy" I'll post it as a separate answer.
            – Bill Hileman
            Nov 8 at 17:41












            up vote
            0
            down vote













            The following routine checks the document ready state for "complete" and returns when the page is finished loading/changing.



            /**
            * Wait for the web page to finish loading
            * @author Bill Hileman
            */
            public void waitForPageToLoad()

            WebDriverWait wait = new WebDriverWait(driver, 10);
            wait.until(new ExpectedCondition<Boolean>()

            public Boolean apply(WebDriver wdriver)
            return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");

            );






            share|improve this answer




















            • Thanks Bill! Unfortunately I am already executing return document.readyState so everything is already loaded. Sometimes I even have to get the element everytime I want to execute an action on it or I end up getting an error saying that the element is no longer in cache, so I verify elements are there.
              – CamelCamelius
              Nov 8 at 22:07














            up vote
            0
            down vote













            The following routine checks the document ready state for "complete" and returns when the page is finished loading/changing.



            /**
            * Wait for the web page to finish loading
            * @author Bill Hileman
            */
            public void waitForPageToLoad()

            WebDriverWait wait = new WebDriverWait(driver, 10);
            wait.until(new ExpectedCondition<Boolean>()

            public Boolean apply(WebDriver wdriver)
            return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");

            );






            share|improve this answer




















            • Thanks Bill! Unfortunately I am already executing return document.readyState so everything is already loaded. Sometimes I even have to get the element everytime I want to execute an action on it or I end up getting an error saying that the element is no longer in cache, so I verify elements are there.
              – CamelCamelius
              Nov 8 at 22:07












            up vote
            0
            down vote










            up vote
            0
            down vote









            The following routine checks the document ready state for "complete" and returns when the page is finished loading/changing.



            /**
            * Wait for the web page to finish loading
            * @author Bill Hileman
            */
            public void waitForPageToLoad()

            WebDriverWait wait = new WebDriverWait(driver, 10);
            wait.until(new ExpectedCondition<Boolean>()

            public Boolean apply(WebDriver wdriver)
            return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");

            );






            share|improve this answer












            The following routine checks the document ready state for "complete" and returns when the page is finished loading/changing.



            /**
            * Wait for the web page to finish loading
            * @author Bill Hileman
            */
            public void waitForPageToLoad()

            WebDriverWait wait = new WebDriverWait(driver, 10);
            wait.until(new ExpectedCondition<Boolean>()

            public Boolean apply(WebDriver wdriver)
            return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");

            );







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 8 at 17:43









            Bill Hileman

            1,9922617




            1,9922617











            • Thanks Bill! Unfortunately I am already executing return document.readyState so everything is already loaded. Sometimes I even have to get the element everytime I want to execute an action on it or I end up getting an error saying that the element is no longer in cache, so I verify elements are there.
              – CamelCamelius
              Nov 8 at 22:07
















            • Thanks Bill! Unfortunately I am already executing return document.readyState so everything is already loaded. Sometimes I even have to get the element everytime I want to execute an action on it or I end up getting an error saying that the element is no longer in cache, so I verify elements are there.
              – CamelCamelius
              Nov 8 at 22:07















            Thanks Bill! Unfortunately I am already executing return document.readyState so everything is already loaded. Sometimes I even have to get the element everytime I want to execute an action on it or I end up getting an error saying that the element is no longer in cache, so I verify elements are there.
            – CamelCamelius
            Nov 8 at 22:07




            Thanks Bill! Unfortunately I am already executing return document.readyState so everything is already loaded. Sometimes I even have to get the element everytime I want to execute an action on it or I end up getting an error saying that the element is no longer in cache, so I verify elements are there.
            – CamelCamelius
            Nov 8 at 22:07










            up vote
            0
            down vote













            To my best of knowledge, you can't wait for an asynchronous event using Selenium Web Driver. You may, however, be able to wait for effects of that event using WebDriverWait class. If events You mentioned, make some changes in the DOM, you can detect those changes by using selected ExpectedConditions.



             Wait<WebDriver> wait = new WebDriverWait(driver, 15, 500);

            // here you make some change to the input

            wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//input")));


            This simple example would wait until a button is active.
            If the expected conditions are not met in the next 15s exception will be thrown.



            In case, that provided set of ExpectedConditions is insufficient you can always create your own by implementing ExpectedCondition interface.
            For more information visit the documentation.



            https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/package-summary.html
            https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/package-summary.html






            share|improve this answer






















            • Thanks. Just a side note, I am working with input fields instead of buttons. I would use ExpectedConditions.elementToBeClickable but I get an exception so I just check ExpectedConditions.visibilityOf. The issue is that the onchange events on fields seem to be clearing other fields if they haven't been validated so I wanted to see a way to determine when the event finishes
              – CamelCamelius
              Nov 8 at 16:21










            • That was just an idea, maybe I could give a better solution, but I'm still unclear about what You're trying to achieve. If the idea is to see if the fields are empty you could write some custom ExpectedCondition to wait for that specific situation.
              – Mateusz
              Nov 8 at 17:01










            • Got it. Fields are empty and I setup a value. After that it runs some JavaScript. If I populate the next related field immediately, it loses it's content but if I give some time so the JavaScript finishes whatever it is doing, I can update the next related field without issues. Also they look the same before and after the onchange event...it's just the background processing what's giving issues and wanted to check if there was a way to do it without hardcoding a sleep time. Thanks
              – CamelCamelius
              Nov 8 at 19:41











            • Ok, I think I understand now. You have a set of connected input fields, that if you change one, the asynchronous task prohibits you from changing the next one, however, it does not change its original value (the next one).
              – Mateusz
              Nov 8 at 20:19











            • I also must ask are there any visible indications for the user of such process taking place in the background?
              – Mateusz
              Nov 8 at 20:30














            up vote
            0
            down vote













            To my best of knowledge, you can't wait for an asynchronous event using Selenium Web Driver. You may, however, be able to wait for effects of that event using WebDriverWait class. If events You mentioned, make some changes in the DOM, you can detect those changes by using selected ExpectedConditions.



             Wait<WebDriver> wait = new WebDriverWait(driver, 15, 500);

            // here you make some change to the input

            wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//input")));


            This simple example would wait until a button is active.
            If the expected conditions are not met in the next 15s exception will be thrown.



            In case, that provided set of ExpectedConditions is insufficient you can always create your own by implementing ExpectedCondition interface.
            For more information visit the documentation.



            https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/package-summary.html
            https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/package-summary.html






            share|improve this answer






















            • Thanks. Just a side note, I am working with input fields instead of buttons. I would use ExpectedConditions.elementToBeClickable but I get an exception so I just check ExpectedConditions.visibilityOf. The issue is that the onchange events on fields seem to be clearing other fields if they haven't been validated so I wanted to see a way to determine when the event finishes
              – CamelCamelius
              Nov 8 at 16:21










            • That was just an idea, maybe I could give a better solution, but I'm still unclear about what You're trying to achieve. If the idea is to see if the fields are empty you could write some custom ExpectedCondition to wait for that specific situation.
              – Mateusz
              Nov 8 at 17:01










            • Got it. Fields are empty and I setup a value. After that it runs some JavaScript. If I populate the next related field immediately, it loses it's content but if I give some time so the JavaScript finishes whatever it is doing, I can update the next related field without issues. Also they look the same before and after the onchange event...it's just the background processing what's giving issues and wanted to check if there was a way to do it without hardcoding a sleep time. Thanks
              – CamelCamelius
              Nov 8 at 19:41











            • Ok, I think I understand now. You have a set of connected input fields, that if you change one, the asynchronous task prohibits you from changing the next one, however, it does not change its original value (the next one).
              – Mateusz
              Nov 8 at 20:19











            • I also must ask are there any visible indications for the user of such process taking place in the background?
              – Mateusz
              Nov 8 at 20:30












            up vote
            0
            down vote










            up vote
            0
            down vote









            To my best of knowledge, you can't wait for an asynchronous event using Selenium Web Driver. You may, however, be able to wait for effects of that event using WebDriverWait class. If events You mentioned, make some changes in the DOM, you can detect those changes by using selected ExpectedConditions.



             Wait<WebDriver> wait = new WebDriverWait(driver, 15, 500);

            // here you make some change to the input

            wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//input")));


            This simple example would wait until a button is active.
            If the expected conditions are not met in the next 15s exception will be thrown.



            In case, that provided set of ExpectedConditions is insufficient you can always create your own by implementing ExpectedCondition interface.
            For more information visit the documentation.



            https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/package-summary.html
            https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/package-summary.html






            share|improve this answer














            To my best of knowledge, you can't wait for an asynchronous event using Selenium Web Driver. You may, however, be able to wait for effects of that event using WebDriverWait class. If events You mentioned, make some changes in the DOM, you can detect those changes by using selected ExpectedConditions.



             Wait<WebDriver> wait = new WebDriverWait(driver, 15, 500);

            // here you make some change to the input

            wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//input")));


            This simple example would wait until a button is active.
            If the expected conditions are not met in the next 15s exception will be thrown.



            In case, that provided set of ExpectedConditions is insufficient you can always create your own by implementing ExpectedCondition interface.
            For more information visit the documentation.



            https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/package-summary.html
            https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/package-summary.html







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 11 at 1:14









            CamelCamelius

            439




            439










            answered Nov 7 at 23:49









            Mateusz

            263




            263











            • Thanks. Just a side note, I am working with input fields instead of buttons. I would use ExpectedConditions.elementToBeClickable but I get an exception so I just check ExpectedConditions.visibilityOf. The issue is that the onchange events on fields seem to be clearing other fields if they haven't been validated so I wanted to see a way to determine when the event finishes
              – CamelCamelius
              Nov 8 at 16:21










            • That was just an idea, maybe I could give a better solution, but I'm still unclear about what You're trying to achieve. If the idea is to see if the fields are empty you could write some custom ExpectedCondition to wait for that specific situation.
              – Mateusz
              Nov 8 at 17:01










            • Got it. Fields are empty and I setup a value. After that it runs some JavaScript. If I populate the next related field immediately, it loses it's content but if I give some time so the JavaScript finishes whatever it is doing, I can update the next related field without issues. Also they look the same before and after the onchange event...it's just the background processing what's giving issues and wanted to check if there was a way to do it without hardcoding a sleep time. Thanks
              – CamelCamelius
              Nov 8 at 19:41











            • Ok, I think I understand now. You have a set of connected input fields, that if you change one, the asynchronous task prohibits you from changing the next one, however, it does not change its original value (the next one).
              – Mateusz
              Nov 8 at 20:19











            • I also must ask are there any visible indications for the user of such process taking place in the background?
              – Mateusz
              Nov 8 at 20:30
















            • Thanks. Just a side note, I am working with input fields instead of buttons. I would use ExpectedConditions.elementToBeClickable but I get an exception so I just check ExpectedConditions.visibilityOf. The issue is that the onchange events on fields seem to be clearing other fields if they haven't been validated so I wanted to see a way to determine when the event finishes
              – CamelCamelius
              Nov 8 at 16:21










            • That was just an idea, maybe I could give a better solution, but I'm still unclear about what You're trying to achieve. If the idea is to see if the fields are empty you could write some custom ExpectedCondition to wait for that specific situation.
              – Mateusz
              Nov 8 at 17:01










            • Got it. Fields are empty and I setup a value. After that it runs some JavaScript. If I populate the next related field immediately, it loses it's content but if I give some time so the JavaScript finishes whatever it is doing, I can update the next related field without issues. Also they look the same before and after the onchange event...it's just the background processing what's giving issues and wanted to check if there was a way to do it without hardcoding a sleep time. Thanks
              – CamelCamelius
              Nov 8 at 19:41











            • Ok, I think I understand now. You have a set of connected input fields, that if you change one, the asynchronous task prohibits you from changing the next one, however, it does not change its original value (the next one).
              – Mateusz
              Nov 8 at 20:19











            • I also must ask are there any visible indications for the user of such process taking place in the background?
              – Mateusz
              Nov 8 at 20:30















            Thanks. Just a side note, I am working with input fields instead of buttons. I would use ExpectedConditions.elementToBeClickable but I get an exception so I just check ExpectedConditions.visibilityOf. The issue is that the onchange events on fields seem to be clearing other fields if they haven't been validated so I wanted to see a way to determine when the event finishes
            – CamelCamelius
            Nov 8 at 16:21




            Thanks. Just a side note, I am working with input fields instead of buttons. I would use ExpectedConditions.elementToBeClickable but I get an exception so I just check ExpectedConditions.visibilityOf. The issue is that the onchange events on fields seem to be clearing other fields if they haven't been validated so I wanted to see a way to determine when the event finishes
            – CamelCamelius
            Nov 8 at 16:21












            That was just an idea, maybe I could give a better solution, but I'm still unclear about what You're trying to achieve. If the idea is to see if the fields are empty you could write some custom ExpectedCondition to wait for that specific situation.
            – Mateusz
            Nov 8 at 17:01




            That was just an idea, maybe I could give a better solution, but I'm still unclear about what You're trying to achieve. If the idea is to see if the fields are empty you could write some custom ExpectedCondition to wait for that specific situation.
            – Mateusz
            Nov 8 at 17:01












            Got it. Fields are empty and I setup a value. After that it runs some JavaScript. If I populate the next related field immediately, it loses it's content but if I give some time so the JavaScript finishes whatever it is doing, I can update the next related field without issues. Also they look the same before and after the onchange event...it's just the background processing what's giving issues and wanted to check if there was a way to do it without hardcoding a sleep time. Thanks
            – CamelCamelius
            Nov 8 at 19:41





            Got it. Fields are empty and I setup a value. After that it runs some JavaScript. If I populate the next related field immediately, it loses it's content but if I give some time so the JavaScript finishes whatever it is doing, I can update the next related field without issues. Also they look the same before and after the onchange event...it's just the background processing what's giving issues and wanted to check if there was a way to do it without hardcoding a sleep time. Thanks
            – CamelCamelius
            Nov 8 at 19:41













            Ok, I think I understand now. You have a set of connected input fields, that if you change one, the asynchronous task prohibits you from changing the next one, however, it does not change its original value (the next one).
            – Mateusz
            Nov 8 at 20:19





            Ok, I think I understand now. You have a set of connected input fields, that if you change one, the asynchronous task prohibits you from changing the next one, however, it does not change its original value (the next one).
            – Mateusz
            Nov 8 at 20:19













            I also must ask are there any visible indications for the user of such process taking place in the background?
            – Mateusz
            Nov 8 at 20:30




            I also must ask are there any visible indications for the user of such process taking place in the background?
            – Mateusz
            Nov 8 at 20:30










            up vote
            0
            down vote



            accepted










            After serious refactoring and some research, I finally made it. The onchange event fires when the value of the input field is changed and the element loses focus. Manipulating the fields with WebElement (e.g. sendKeys()) is not an option because you are not in control of the background processing, so using JavascriptExecutor is the choice. First, I updated the value of the field using JavaScript (which does NOT trigger the event), and after that, I triggered the onchange event, also using JavaScript:



            //Setting implicit wait to 0 to avoid mess with explicit waits
            driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
            //Use WebDriverWait instead of FluentWait (it's superclass)
            Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
            for(int i = 1; i <= fieldCount; i++)
            String elementId = "field$" + i;
            String javaScript = String.format("document.getElementById('%s').value='%s';", elementId , myValue);
            Object jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
            javaScript = String.format("return document.getElementById('%s').dispatchEvent(new Event('change'));", elementId);
            jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));



            There are some key aspects here.



            • Do NOT mix implicit and explicit waits (I learnt it the hard way), it will cause unexpected results.

            • Use WebDriverWait (specialization of FluentWait) instead of its superclass, unless you have a very specific requirement. If you use FluentWait make sure to ignore appropriate exceptions; otherwise you will start getting NoSuchElementException.

            • The onchange event fires when the value of the input field is changed and the element loses focus.


            • dispatchEvent() dispatches an Event at the specified EventTarget, (synchronously) invoking the affected EventListeners in the appropriate order. This applies for custom events as well. This is a very nice post for events.

            I used the following code to get a better grasp of ExpectedConditions.javaScriptThrowsNoExceptions and ExpectedConditions.jsReturnsValue. It is a JavaScript function call that just keeps the engine busy for few seconds. That way you can see the interaction of the explicit wait with JavaScript and inspect the return values. Notice that the JS code is slightly different for each ExpectedCondition:



            //ExpectedConditions.jsReturnsValue
            String javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);return 'success';";
            log.trace("javaScript=", javaScript);
            Object jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));
            log.trace("jsResult=", jsResult);

            //ExpectedConditions.javaScriptThrowsNoExceptions
            javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);";
            log.trace("javaScript=", javaScript);
            jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
            log.trace("jsResult=", jsResult);





            share|improve this answer
























              up vote
              0
              down vote



              accepted










              After serious refactoring and some research, I finally made it. The onchange event fires when the value of the input field is changed and the element loses focus. Manipulating the fields with WebElement (e.g. sendKeys()) is not an option because you are not in control of the background processing, so using JavascriptExecutor is the choice. First, I updated the value of the field using JavaScript (which does NOT trigger the event), and after that, I triggered the onchange event, also using JavaScript:



              //Setting implicit wait to 0 to avoid mess with explicit waits
              driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
              //Use WebDriverWait instead of FluentWait (it's superclass)
              Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
              for(int i = 1; i <= fieldCount; i++)
              String elementId = "field$" + i;
              String javaScript = String.format("document.getElementById('%s').value='%s';", elementId , myValue);
              Object jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
              javaScript = String.format("return document.getElementById('%s').dispatchEvent(new Event('change'));", elementId);
              jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));



              There are some key aspects here.



              • Do NOT mix implicit and explicit waits (I learnt it the hard way), it will cause unexpected results.

              • Use WebDriverWait (specialization of FluentWait) instead of its superclass, unless you have a very specific requirement. If you use FluentWait make sure to ignore appropriate exceptions; otherwise you will start getting NoSuchElementException.

              • The onchange event fires when the value of the input field is changed and the element loses focus.


              • dispatchEvent() dispatches an Event at the specified EventTarget, (synchronously) invoking the affected EventListeners in the appropriate order. This applies for custom events as well. This is a very nice post for events.

              I used the following code to get a better grasp of ExpectedConditions.javaScriptThrowsNoExceptions and ExpectedConditions.jsReturnsValue. It is a JavaScript function call that just keeps the engine busy for few seconds. That way you can see the interaction of the explicit wait with JavaScript and inspect the return values. Notice that the JS code is slightly different for each ExpectedCondition:



              //ExpectedConditions.jsReturnsValue
              String javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);return 'success';";
              log.trace("javaScript=", javaScript);
              Object jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));
              log.trace("jsResult=", jsResult);

              //ExpectedConditions.javaScriptThrowsNoExceptions
              javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);";
              log.trace("javaScript=", javaScript);
              jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
              log.trace("jsResult=", jsResult);





              share|improve this answer






















                up vote
                0
                down vote



                accepted







                up vote
                0
                down vote



                accepted






                After serious refactoring and some research, I finally made it. The onchange event fires when the value of the input field is changed and the element loses focus. Manipulating the fields with WebElement (e.g. sendKeys()) is not an option because you are not in control of the background processing, so using JavascriptExecutor is the choice. First, I updated the value of the field using JavaScript (which does NOT trigger the event), and after that, I triggered the onchange event, also using JavaScript:



                //Setting implicit wait to 0 to avoid mess with explicit waits
                driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
                //Use WebDriverWait instead of FluentWait (it's superclass)
                Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
                for(int i = 1; i <= fieldCount; i++)
                String elementId = "field$" + i;
                String javaScript = String.format("document.getElementById('%s').value='%s';", elementId , myValue);
                Object jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
                javaScript = String.format("return document.getElementById('%s').dispatchEvent(new Event('change'));", elementId);
                jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));



                There are some key aspects here.



                • Do NOT mix implicit and explicit waits (I learnt it the hard way), it will cause unexpected results.

                • Use WebDriverWait (specialization of FluentWait) instead of its superclass, unless you have a very specific requirement. If you use FluentWait make sure to ignore appropriate exceptions; otherwise you will start getting NoSuchElementException.

                • The onchange event fires when the value of the input field is changed and the element loses focus.


                • dispatchEvent() dispatches an Event at the specified EventTarget, (synchronously) invoking the affected EventListeners in the appropriate order. This applies for custom events as well. This is a very nice post for events.

                I used the following code to get a better grasp of ExpectedConditions.javaScriptThrowsNoExceptions and ExpectedConditions.jsReturnsValue. It is a JavaScript function call that just keeps the engine busy for few seconds. That way you can see the interaction of the explicit wait with JavaScript and inspect the return values. Notice that the JS code is slightly different for each ExpectedCondition:



                //ExpectedConditions.jsReturnsValue
                String javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);return 'success';";
                log.trace("javaScript=", javaScript);
                Object jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));
                log.trace("jsResult=", jsResult);

                //ExpectedConditions.javaScriptThrowsNoExceptions
                javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);";
                log.trace("javaScript=", javaScript);
                jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
                log.trace("jsResult=", jsResult);





                share|improve this answer












                After serious refactoring and some research, I finally made it. The onchange event fires when the value of the input field is changed and the element loses focus. Manipulating the fields with WebElement (e.g. sendKeys()) is not an option because you are not in control of the background processing, so using JavascriptExecutor is the choice. First, I updated the value of the field using JavaScript (which does NOT trigger the event), and after that, I triggered the onchange event, also using JavaScript:



                //Setting implicit wait to 0 to avoid mess with explicit waits
                driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
                //Use WebDriverWait instead of FluentWait (it's superclass)
                Wait<WebDriver> wait = new WebDriverWait(driver, 25, 500);
                for(int i = 1; i <= fieldCount; i++)
                String elementId = "field$" + i;
                String javaScript = String.format("document.getElementById('%s').value='%s';", elementId , myValue);
                Object jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
                javaScript = String.format("return document.getElementById('%s').dispatchEvent(new Event('change'));", elementId);
                jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));



                There are some key aspects here.



                • Do NOT mix implicit and explicit waits (I learnt it the hard way), it will cause unexpected results.

                • Use WebDriverWait (specialization of FluentWait) instead of its superclass, unless you have a very specific requirement. If you use FluentWait make sure to ignore appropriate exceptions; otherwise you will start getting NoSuchElementException.

                • The onchange event fires when the value of the input field is changed and the element loses focus.


                • dispatchEvent() dispatches an Event at the specified EventTarget, (synchronously) invoking the affected EventListeners in the appropriate order. This applies for custom events as well. This is a very nice post for events.

                I used the following code to get a better grasp of ExpectedConditions.javaScriptThrowsNoExceptions and ExpectedConditions.jsReturnsValue. It is a JavaScript function call that just keeps the engine busy for few seconds. That way you can see the interaction of the explicit wait with JavaScript and inspect the return values. Notice that the JS code is slightly different for each ExpectedCondition:



                //ExpectedConditions.jsReturnsValue
                String javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);return 'success';";
                log.trace("javaScript=", javaScript);
                Object jsResult = wait.until(ExpectedConditions.jsReturnsValue(javaScript));
                log.trace("jsResult=", jsResult);

                //ExpectedConditions.javaScriptThrowsNoExceptions
                javaScript = "(function watcher(ms)var start=new Date().getTime();var end = start;while(end<start+ms)end=new Date().getTime();;return 'complete';)(5000);";
                log.trace("javaScript=", javaScript);
                jsResult = wait.until(ExpectedConditions.javaScriptThrowsNoExceptions(javaScript));
                log.trace("jsResult=", jsResult);






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 11 at 10:21









                CamelCamelius

                439




                439



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53199159%2fjava-wait-for-javascript-event-e-g-onchange-to-complete-using-selenium%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    How to read a connectionString WITH PROVIDER in .NET Core?

                    In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

                    Museum of Modern and Contemporary Art of Trento and Rovereto