2

The code I am attempting to test prevents double submitting of a form by detecting the click event via Javascript and disabling the button.

To clarify, the sequence of events is as follows:

  • Navigate to the requisite page
  • Find the button in page
  • Click the button
  • Button gets disabled via Javascript
  • Form is submitted

My test code (as pseudo code) is as follows:

final Page page = getPage();
final WebElement button = page.getButton();
button.click();
Assert.assertFalse(button.isEnabled(), "Button still enabled");

The button is actually a div with an attached onClick handler, which looks like this:

-- Before Click
<div id="button" onclick="..." class="action-button">
    <i class="fa fa-play"></i> Run
</div>

-- After Click
<div id="button" class="action-button" disabled="disabled">
    <i class="fa fa-play"></i> Run
</div>

The actual submit button itself is hidden for reasons I can't change, so when the user clicks on the div I've documented, the onClick event actually calls the hidden submit button's click event and also sets the div to disabled and removes the onClick handler.

It seems as though the .click() event is blocking until the page reloads, which means by the time the assert is executed the button object is no longer referenced, and I can't check the state.

Is there a way to assert something on the button before the page reloads?

  • 1
    Please add the html of button state before n after click – PDHide Apr 8 at 5:17
  • I added some more details. Cheers! – Manky Fox Apr 8 at 5:34
  • if the button is not referenced how you wer able to get the html after the click manually? – PDHide Apr 8 at 5:40
  • I am not sure what you mean? I am able to reference the div, which is the thing in the DOM that gets disabled, but once I call .click() on the div the test blocks until the page loads completely and I'm unable to check the disabled state, as the page reload resets the div's disabled state. – Manky Fox Apr 8 at 5:52
  • What i meant is , on clicking the button the page starts to reload. So how did you able to see the state after the click ? – PDHide Apr 8 at 5:55
1

The below code works for the test HTML shown:

Boolean return_value = (Boolean) js.executeScript("arguments[0].click(); return arguments[1].disabled;",  button1,button2);
Assert.assertTrue(return_value, "Button still enabled");

Were, button 1 is the "Try it" button, and button 2 is the "My button"

The html I used for testing:

<!DOCTYPE html>
<html>
<body>

<button id="myBtn">My Button</button>

<p>Click the button below to disable the button above.</p>

<button onclick="myFunction();window.location.reload();">Try it</button>

<script>
function myFunction() {
  document.getElementById("myBtn").disabled = true;
}
</script>

</body>
</html>

So for your SUT , the code will be:

Boolean return_value = (Boolean) js.executeScript("arguments[0].click(); return arguments[0].disabled;",  button);

Assert.assertTrue(return_value, "Button still enabled");

Try wait: if above doesn't work

 WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

 wait.until((ExpectedCondition<Boolean>) wd ->
    (Boolean) js.executeScript("arguments[0].click(); return 
       arguments[0].disabled;",  button));
| improve this answer | |
  • After a few goes in different configurations, including attempting to override the submit action in the executed Javascript before clicking, it looks that my particular sequence of events doesn't work with this solution either. I can see how it should work, but I can't seem to get it to execute correctly. – Manky Fox Apr 8 at 8:43
  • @MankyFox what error are you getting ? – PDHide Apr 8 at 8:45
  • Try with executeasyncscript – PDHide Apr 8 at 8:46
  • I'm actually getting a response, but it's null, signalling to me that it's still getting the disabled state after the submit has complete. I've done some contrived tests on returning the id instead, and I get that back fine, so I know the Javascript is actually executing. I'll try the Async method and see how I go. – Manky Fox Apr 8 at 9:20
  • @MankyFox ` Boolean return_value = (Boolean)js.executeAsyncScript("var callback = arguments[arguments.length - 1];"+ "arguments[0].click;"+ "while(1){" + "if(arguments[1].disabled){" + "callback(arguments[0].disabled)}}",button); try this one ? – PDHide Apr 8 at 13:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.