Capybara: fill_in sometimes appends to an input rather than overwriting

Created on 31 Oct 2020  路  7Comments  路  Source: teamcapybara/capybara

Meta

  • Capybara 3.33.0
  • selenium-webdriver 3.142.7
  • webdrivers chromedriver 86.0.4240.22
  • Chrome Mac 86.0.4240.111

My code is very simple, and is accessing a user edit page with no special js (other than turbolinks). I've simplified slightly to get rid of the faker names so that it's obvious what's wrong in the screenshot:

let(:user) { User.create(email: Faker::Internet.safe_email, name: "Old Name") }
let(:new_name) { "New Name" }
let(:new_email) { Faker::Internet.safe_email }

it "updates name, email" do
  visit url
  # take_screenshot <- adding this line fixes it, though using sleep instead does not
  fill_in "user[name]", with: new_name
  fill_in "user[email]", with: new_email
  expect {
    click "Save"
  }.to change { user.reload.name }.to(new_name) &
    change { user.email }.to(new_email)
end

However, I get:

expected `user.reload.name` to have changed to "New Name", but is now "Old NameNew Name"

If I add take_screenshot right before expect, you can see the strange behavior. Both name & email had previous values, but name gets appended to, and email gets overwritten.

capybara

Expected Behavior

fill_in "field", with: "string" _overwrites_ existing "field" value with "string"

Actual Behavior

fill_in "field", with: "string" _appends_ "string" to existing "field" value

Steps to reproduce

This only seems to happen with the first filled field after visiting a page. Oddly, adding sleep 1 before the first fill_in doesn't fix it, but using Rails system test's take_screenshot does. Another odd note is that this doesn't occur on my CircleCI (Linux) runs with the exact same Chrome/ChromeDriver versions - but it does occur on both of my Macs. Truly puzzling...

Most helpful comment

Same problem here with our test suite.

I fixed it as follows:

  Capybara.configure do |config|
    config.default_set_options = { clear: :backspace }
  end

This ensures the field is first cleared before the new value is set.

All 7 comments

Without a way to reproduce there鈥檚 really not much we can do. Are you 100%sure there鈥檚 no JS being run on the page (it鈥檚 not a react page, etc)? It sounds like the first click on an element is triggering some sort of page initialization JS

Yeah, I figured as much, and since it passes on CI I'm not terribly worried about it. Just figured out I'd document it here in case someone else has the same issue.

FYI, I removed all of my js includes from my application template and I still get the same behavior. No turbolinks - just pure rails templates!

It鈥檚 also possible this is a chromedriver bug - we have some intermittent failures on the emoji fill in test in capybaras test suite where it sometimes appends

FWIW, we found Chromedriver to be super flaky. Even with things as simple as clicking a link on a static html page, no JS, sometimes it would fail. Switching to Firefox caused pretty much all of the weird issues in our system tests to go away.

I have the same problem.
I had no choice but to put an empty fill_in before the original fill_in to get around it.

fill_in "user[name]", with: ''
fill_in "user[name]", with: new_name

Same problem here with our test suite.

I fixed it as follows:

  Capybara.configure do |config|
    config.default_set_options = { clear: :backspace }
  end

This ensures the field is first cleared before the new value is set.

Here is a chromium bug related to this issue that's been closed as "Won't Fix" because they need repro steps if someone here can produce them:
https://bugs.chromium.org/p/chromedriver/issues/detail?id=2842&q=appends&can=1

Was this page helpful?
0 / 5 - 0 ratings