🗂

【Rails × Capybara】ファイルじゃないのに「isn't a file」エラーが出た原因と解決法

に公開

こんにちは

プログラミングスクールで Ruby on Rails を学習している、りゅうです。

卒業制作でWebアプリを作っている中で、Capybara + RSpec + Selenium (Docker環境) を使ったテスト中に
👇このようなエラーに遭遇しました。

You are trying to upload something that isn't a file

この記事では、実際にエラーが出た状況から、原因の特定、そして解決までの流れを丁寧に解説します。
同じようにCapybaraでハマっている方の参考になれば嬉しいです。

⚠️ 注意

プログラミング初心者のため、誤りがあるかもしれません。
また、環境によっては同じ手順でもうまくいかない場合があります。

もしお気づきの点があれば、コメントなどで教えていただけると嬉しいです!

💡 前提

  • capybara、rspec-rails、selenium-webdriver などのGemを導入済み

  • 基本的なRSpecシステムテスト環境が整っている

  • Docker上でRailsを動かしている

🧩 使用環境(バージョン情報)

ツール バージョン
Ruby 3.2.3
Rails 7.2.2.2
PostgreSQL 17.6
開発環境 Docker
capybara 3.40.0
selenium-webdriver 4.35.0

記事の内容

follows_spec.rbのテストが成功するまでの流れになっています。
最初のコード

エラー

原因の特定

変更したコード

結果

最初のコード

spec/support/capybara.rb
Capybara.register_driver :remote_chrome do |app|
  options = Selenium::WebDriver::Chrome::Options.new
  options.add_argument('no-sandbox')
  options.add_argument('headless')
  options.add_argument('disable-gpu')
  options.add_argument('window-size=1680,1050')
Capybara::Selenium::Driver.new(app, browser: :remote, url: ENV['SELENIUM_DRIVER_URL'], capabilities: options)

end
spec/system/follows_spec.rb
describe "フォローの確認" do
    scenario "フォローした遷移先はその場" do
      other_user = create(:user)
      visit users_path
      within("form") do
        fill_in "q_name_cont", with: other_user.name
        find_field("q_name_cont").send_keys(:enter)
      end      
      click_link "フォロー"
      expect(page).to have_current_path(users_path, ignore_query: true)
    end
  end

エラー

bash
Failure/Error: fill_in "q_name_cont", with: other_user.name
    
Selenium::WebDriver::Error::WebDriverError:
You are trying to upload something that isn't a file.

エラー文を読んでいきます
fileではないものをアップロードとしていますよとなっています。何が起きているのでしょうか?
詳しくみていきます

原因の特定

デバッグのために save_and_open_page を追加して、Capybaraが見ている実際の画面を確認します。

spec/system/follows_spec.rb
describe "フォローの確認" do
    scenario "フォローした遷移先はその場" do
+      save_and_open_page
      other_user = create(:user)
      visit users_path
      within("form") do
        fill_in "q_name_cont", with: other_user.name
        find_field("q_name_cont").send_keys(:enter)
      end      
      click_link "フォロー"
      expect(page).to have_current_path(users_path, ignore_query: true)
    end
  end

すると以下のログが出力されました。

bash
2025-10-13 10:38:18 ERROR Selenium [:file_detector] File detector only works with files. "test" isn`t a file!

Capybaraが fill_in で触ろうとした要素を、Seleniumが <input type="file"> と認識 しています。そのため、"test"(=other_user.name)を入力しようとしても「これはファイルじゃない」と拒否されています。

しかし、type = "file"はテストを実行しようとしているDOM要素にはありません。

なぜ、<input type="file"> と認識しているのでしょうか?これを探りにいきます

Some bindings include a basic local file detector by default, and all of them allow for a custom file detector
Selenium WebDriver Documentation, “Remote WebDriver”, SeleniumDev
(参照: https://www.selenium.dev/documentation/webdriver/drivers/remote_webdriver/)

「一部バインディングでは基本の Local File Detector をデフォルトで含むすべてのバインディングでカスタムのFile Detectorを設定できる」

  • 言語とseleniumの翻訳の役割をしているのがバインディングというイメージで、Rubyの場合は、gem "selenium-webdriver"がバインディングになります。

file_detector が 有効なまま だと、Capybara が普通のテキスト入力をしようとする時でも、内部で「この入力値はファイルパスっぽいな?」と判断してしまうことがあるそうです。

変更したコード

file_detector を無効に設定します。

spec/support/capybara.rb
Capybara.register_driver :remote_chrome do |app|
  options = Selenium::WebDriver::Chrome::Options.new
  options.add_argument('no-sandbox')
  options.add_argument('headless')
  options.add_argument('disable-gpu')
  options.add_argument('window-size=1680,1050')
+ driver = Capybara::Selenium::Driver.new(app, browser: :remote, url: ENV['SELENIUM_DRIVER_URL'], capabilities: options)

+ driver.browser.file_detector = nil

+ driver
end

結果

うまくいきました

bash
Finished in 1.39 seconds (files took 1.3 seconds to load)
1 example, 0 failures

まとめ

file_detectorがデフォルトで有効になっていました。かつ、SeleniumがCapybaraから送られてきた値をfileと勘違いしてfile_detectorが作動したことが、エラーの原因でした。

file_detector = nilとすることで解決しましたが、どうしてfileだと誤作動を起こすのかはわかりません。詳しい人がいたら教えて頂きたいです

参考になった記事

https://www.selenium.dev/documentation/webdriver/drivers/remote_webdriver/

最後に

noteで卒業制作の進捗を記録しています。
もし興味があれば、こちらも覗いてみてください!
https://note.com/ryu0121_it/n/n154649d7dce1

Discussion