DragEventのdataTransferはスクリプトからは設定できない

  • 2
    いいね
  • 0
    コメント

画像ファイルをドラッグアンドドロップすることで画像がアップロードされる機能のe2eテストを書こうとしたが、 dataTransfer プロパティをスクリプトから設定することができなかったため断念した。

ドキュメントにも書かれていた。

Although, for consistency with other event interfaces, the DragEvent interface has a constructor, it is not particularly useful. In particular, there's no way to create a useful DataTransfer object from script, as DataTransfer objects have a processing and security model that is coordinated by the browser during drag-and-drops.

HTML Standard - 6.7.4 The DragEvent interface

また、こちらは明記されていないが、ブラウザのコンソールで試した結果 ClipboardEventclipboardData にも同様の制約がありそう。

ダメだったテストコード

CapybaraPoltergeist を使って、以下のようなテストコードを書いてみたが、 fakeDropEvent.dataTransfernull になるためどうやってもダメだった。

describe 'Drop an image' do
  def drop_image(file_path, drop_area_id)
    id = 'fakeFileInput'
    page.execute_script <<-JS.strip_heredoc
      var fakeFileInput = document.createElement('input');
      fakeFileInput.id = '#{id}';
      fakeFileInput.type = 'file';
      document.body.appendChild(fakeFileInput);
    JS
    attach_file(id, file_path)
    page.execute_script <<-JS.strip_heredoc
      var fakeDropEvent = document.createEvent('DragEvent');
      fakeDropEvent.initEvent('drop', true, true);
      fakeDropEvent.dataTransfer = {
        files: document.getElemnetById('#{id}').files
      };
      document.getElemnetById('#{drop_area_id}').dispatchEvent(fakeDropEvent);
    JS
  end

  subject do
    drop_image(
      Rails.root.join('spec/fixtures/files/icon.png'),
      'dropzone'
    )
  end

  it 'creates an Image', js: true do
    visit new_article_path
    expect { subject }.to change(Image, :count).by(1)
  end
end

参考にしたサイト