0
votes

I am writing an RSpec / capybara feature spec to test that, after a form submit button is pressed, the button is disabled and its text is changed to 'ADDING...'.

In the spec, the button is clicked (and if valid, the form is submitted) with:

find(".Booknow-modal-bookingButton button.primaryCTA").click

And the corresponding javascript that is executed is as follows:

$('form#booknow-room').on('submit', function(e) {
    // If form is submitting then html5 validation has passed, 
    // now disable the button to prevent duplicate submissions.
    $('form#booknow-room button.primaryCTA').attr('disabled', true).text('Adding...')
})

When the spec runs I can see that this is working. The next line of the spec is:

expect(page).to have_button('ADDING...', disabled: true)

But I think that, by this time, the form submit has redirected to the basket page so it isn't finding the button, so the test fails.

I have also tried the following variants:

expect(find('.Booknow-modal-bookingButton button.primaryCTA').value).to eq 'ADDING...'
expect(".Booknow-modal-bookingButton button.primaryCTA").to have_content("ADDING...")
expect(page).to eq(".Booknow-modal-bookingButton button.primaryCTA", disabled: true)

But none of them work.

The error message returned by rspec is:

Failure/Error: expect(page).to have_button('ADDING...', disabled: true)
expected to find button "ADDING..." but there were no matches
2
Do you have JS set to true in the scenario? - Hackman
@Hackman yes js: true is set on the surrounding context - Teep

2 Answers

1
votes

Assuming clicking the button triggers a full form submission rather than an XHR based submission what you're trying to do may not be possible. This is because of the defined behavior for clicking an element in the WebDriver spec - https://w3c.github.io/webdriver/#element-click. 12.4.1 steps 10, 11, and 12 are the relevant parts where driver implementors may attempt to detect if a navigation is occurring and wait for it to complete. This can mean your check for disabled won't happen until after the page has already changed.

The question to ask next is whether this is something that needs to be tested via end-to-end Capybara tests, or whether it could instead be tested in Javascript only tests.

If you do consider it necessary to be tested in your Capybara tests you could try registering a driver with the page load strategy capability set to "none" which should tell the driver not to wait for any navigations and MAY allow the button state to be checked (you'd probably only want to use that driver for this specific test). Another potential option would be to use execute_script to install an event handler that prevents the actual submit from occurring - although every time you modify the running page code in your test you're potentially reducing the usefulness of the test.

0
votes

I implemented the other "potential solution" which @Thomas Walpole mentioned -- modify the form, so that when you click the submit button it doesn't actually submit. This allows you to validate that the button is disabled without capybara blocking until the form submits.

page.execute_script(
  "$('form#booknow-room').attr('action', 'javascript: void(0);');"
)

page.click_button('Submit')
expect(page).to have_button('Adding...', disabled: true)