2016-08-08 3 views
10

Мне нужно протестировать веб-приложение, которое содержит область перетаскивания для загрузки файлов из локальной файловой системы. Моя тестовая среда основана на C#.Selenium: перетаскивание из файловой системы в webdriver?

Для тестирования автоматизации я использовал Selenium, но невозможно перетащить файлы из файловой системы. Область загрузки - это тег div (нет тега input). Так что это лучший способ сделать это? AutoIt (можно ли бросить в веб-браузер)? Sikuli?

+0

Ответ Florent B для меня почему-то не работал - AutoIt сделал трюк https://stackoverflow.com/a/38513989/1141876 – fiat

ответ

11

Это возможно только с селеном, но это не просто. Для получения файла необходимо ввести новый элемент INPUT, чтобы получить файл через SendKeys. Затем сценарий должен моделировать падение, отправив dragenter, dragover, drop событиям в целевую область.

IWebElement droparea = driver.FindElement(By.Id("droparea")); 
DropFile(droparea, @"C:\...\image.png"); 
static void DropFile(IWebElement target, string filePath, int offsetX = 0, int offsetY = 0) { 
    if(!File.Exists(filePath)) 
     throw new FileNotFoundException(filePath); 

    IWebDriver driver = ((RemoteWebElement)target).WrappedDriver; 
    IJavaScriptExecutor jse = (IJavaScriptExecutor)driver; 
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); 

    string JS_DROP_FILE = @" 
     var target = arguments[0], 
      offsetX = arguments[1], 
      offsetY = arguments[2], 
      document = target.ownerDocument || document, 
      window = document.defaultView || window; 

     var input = document.createElement('INPUT'); 
     input.type = 'file'; 
     input.style.display = 'none'; 
     input.onchange = function() { 
      var rect = target.getBoundingClientRect(), 
       x = rect.left + (offsetX || (rect.width >> 1)), 
       y = rect.top + (offsetY || (rect.height >> 1)), 
       dataTransfer = { files: this.files }; 

      ['dragenter', 'dragover', 'drop'].forEach(function (name) { 
      var evt = document.createEvent('DragEvent'); 
      evt.initMouseEvent(name, !0, !0, window, 0, 0, 0, x, y, !1, !1, !1, !1, 0, null); 
      evt.dataTransfer = dataTransfer; 
      target.dispatchEvent(evt); 
      }); 

      setTimeout(function() { document.body.removeChild(input); }, 25); 
     }; 
     document.body.appendChild(input); 
     return input; 
     "; 

    IWebElement input = (IWebElement)jse.ExecuteScript(JS_DROP_FILE, target, offsetX, offsetY); 
    input.SendKeys(filePath); 
    wait.Until(ExpectedConditions.StalenessOf(input)); 
} 
+0

Thx. @Florent B.: Неплохо, это выглядит довольно многообещающе! Я попробую и дам вам обратную связь! – Markoo91

+1

Он работает, спасибо большое !!! – Markoo91

3

Предыдущий ответ является правильным и отлично работает с драйвером Chrome, однако могут возникнуть проблемы с драйверами Mozilla Gecko, который бросает org.openqa.selenium.ElementNotVisibleException

Для того, чтобы избежать этого, удалите input.style.display = 'none';

Вы можете использовать input.style.opacity = 0;, если вам нужно его исчезнуть.