2011-03-04 3 views
19

버튼을 클릭하면 div가 열리는 웹 페이지가 있습니다. 이 div를 사용하면 바탕 화면의 파일을 해당 영역으로 끌 수 있습니다. 파일은 서버에 업로드됩니다. 저는 Selenium의 Ruby 구현과 함께 작업하고 있습니다.Selenium을 사용하여 업로드 요소로 파일 드래그를 모방합니다.

Firefox에서 JavaScript 디버거를 사용하면 "drop"이벤트가 일부 JavaScript 코드 인 "handleFileDrop (event)"에 전달되는 것을 볼 수 있습니다. 나는 모의 사건을 만들어서 어떻게해서든지이 코드를 실행할 수 있다고 생각한다.

유망한 방향으로 나를 가리키는 것처럼 보인 interesting article이 발견되었지만 여전히 모든 것을 파악하지 못했습니다. Selenium의 get_eval 메소드를 사용하여 JavaScript를 페이지에 전달할 수 있습니다. this.browserbot을 사용하는 메서드를 호출하면 필요한 요소를 얻을 수 있습니다.

그래서 :

  1. 어떻게 필요가 모의 드롭 이벤트의 일부가 될하는 파일 객체를 구축합니까?
  2. 내가 어떻게 div에 파일을 떨어 뜨린 것처럼 드롭 이벤트 이 발생하도록합니까?

답변

0

당신은 Blueduck SDA를 사용할 수 있습니다 (http://sda.blueducktesting.com) 는 (그것은 셀레늄 RC와 함께 작동) 모든 셀레늄의 기능을 구현 않은 OSS하지만 당신이 윈도우 작업을 자동화 할 수 있습니다. 따라서 웹을 테스트하고 OS와 상호 작용할 수 있습니다. 그래서 테스트를 한 다음, 마우스로 요소를 클릭하고 원하는 곳에 놓으라고 말하십시오!

멋진 테스트!

+0

나는 그것이 일할 수 있더라도 그것이 옵션 일 수있는 것처럼 보입니다. OSX에서는 Windows가 아니라 g. 또한 JavaScriptbot과 상호 작용하고 JavaScript 컨텍스트에서 이벤트를 발생시키는 것에 대해 기술적으로 궁금합니다. –

28

Selenium webdriver를 사용하여 파일 끌어서 놓기를 시뮬레이트하는 RSpec 테스트를 게시합니다. jQuery를 사용하여 가짜 'drop'이벤트를 만들고 트리거합니다.

이 코드는 단일 파일의 끌어서 놓기를 시뮬레이션합니다. 간단하게하기 위해 여러 파일을 삭제할 수있는 코드를 제거했습니다. 필요하면 말해줘.

describe "when user drop files", :js => true do 
    before do 
    page.execute_script("seleniumUpload = window.$('<input/>').attr({id: 'seleniumUpload', type:'file'}).appendTo('body');") 

    attach_file('seleniumUpload', Rails.root + 'spec/support/pdffile/pdfTest.pdf') 

    # Trigger the drop event 
    page.execute_script("e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : seleniumUpload.get(0).files } }; $('#fileDropArea').trigger(e);") 
    end 

    it "should ..." do 
    should have_content '...' 
    end 

P.S :은 드롭 영역의 ID와 #fileDropArea를 교체해야합니다.

P.P.S : 복잡한의 jQuery 객체를 평가하고, 그렇지 않으면 셀레늄 집착, execute_script 대신에 evaluate_script 사용하지 마십시오!

UPDATE : 난 당신이 다시 이상 쓸 물건을 할 수있는 방법을 쓰기했습니다.

def drop_files files, drop_area_id 
    js_script = "fileList = Array();" 
    files.count.times do |i| 
    # Generate a fake input selector 
    page.execute_script("if ($('#seleniumUpload#{i}').length == 0) { seleniumUpload#{i} = window.$('<input/>').attr({id: 'seleniumUpload#{i}', type:'file'}).appendTo('body'); }") 
    # Attach file to the fake input selector through Capybara 
    attach_file("seleniumUpload#{i}", files[i]) 
    # Build up the fake js event 
    js_script = "#{js_script} fileList.push(seleniumUpload#{i}.get(0).files[0]);" 
    end 

    # Trigger the fake drop event 
    page.execute_script("#{js_script} e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : fileList } }; $('##{drop_area_id}').trigger(e);") 
end 

사용법 :

describe "when user drop files", :js => true do 
    before do 
    files = [ Rails.root + 'spec/support/pdffile/pdfTest1.pdf', 
       Rails.root + 'spec/support/pdffile/pdfTest2.pdf', 
       Rails.root + 'spec/support/pdffile/pdfTest3.pdf' ] 
    drop_files files, 'fileDropArea' 
    end 

    it "should ..." do 
    should have_content '...' 
    end 
end 
+0

이게 좋을것 같습니다. 현재 프로젝트에서 RSpec을 쓰고 있지 않습니다. 누군가 다른 사람이 코멘트에서 이것을 확인할 수 있다면,이 대답을 받아 들일 것입니다. –

+0

rspec에서 확인되었습니다 - 완벽하게 작동합니다! 선생님, 오늘 하루를 보냈습니다! :) –

+0

감사합니다. - C#을 사용하여 테스트를 수행하기 위해 코드를 성공적으로 번역했습니다. –

3

@Shmoopy는 요청으로, 여기 @micred

private void DropImage(string dropBoxId, string filePath) 
{ 
    var javascriptDriver = this.Driver as IJavaScriptExecutor; 
    var inputId = dropBoxId + "FileUpload"; 

    // append input to HTML to add file path 
    javascriptDriver.ExecuteScript(inputId + " = window.$('<input id=\"" + inputId + "\"/>').attr({type:'file'}).appendTo('body');"); 
    this.Driver.FindElement(By.Id(inputId)).SendKeys(filePath); 

    // fire mock event pointing to inserted file path 
    javascriptDriver.ExecuteScript("e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : " + inputId + ".get(0).files } }; $('#" + dropBoxId + "').trigger(e);"); 
} 
+2

감사합니다. 셀레늄에 예기치 않은 오류가 발생했습니다. 유형 속성을 변경할 수 없습니다. '. attr ({type : 'file'})''$ (' ' + "\"type = \ "file \"/> ')'. –

0

주에서 제공하는 코드의 C#을 번역 : 당신은 추가해야

e.originalEvent.dataTransfer.types = [ 'Files' ]; 
관련 문제