【问题标题】:How to upload file in angularjs e2e protractor testing如何在angularjs e2e量角器测试中上传文件
【发布时间】:2014-02-13 19:57:08
【问题描述】:

我想使用 angularjs e2e 测试来测试文件上传。您如何在 e2e 测试中做到这一点?我通过 grunt karma 运行我的测试脚本。

【问题讨论】:

标签: angularjs file file-upload gruntjs protractor


【解决方案1】:

这就是我的做法:

var path = require('path');

it('should upload a file', function() {
  var fileToUpload = '../some/path/foo.txt',
      absolutePath = path.resolve(__dirname, fileToUpload);

  element(by.css('input[type="file"]')).sendKeys(absolutePath);    
  element(by.id('uploadButton')).click();
});
  1. 使用path 模块解析您要上传的文件的完整路径。
  2. 设置 input type="file" 元素的路径。
  3. 点击上传按钮。

这不适用于 Firefox。量角器会抱怨,因为元素不可见。要在 Firefox 中上传,您需要使输入可见。我就是这样做的:

browser.executeAsyncScript(function(callback) {
  // You can use any other selector
  document.querySelectorAll('#input-file-element')[0]
      .style.display = 'inline';
  callback();
});

// Now you can upload.
$('input[type="file"]').sendKeys(absolutePath);    
$('#uploadButton').click();

【讨论】:

  • +1 这行得通。 Andres,您应该向 OP 寻求反馈,因为这可能会被接受为正确答案。
  • 也使用量角器。
  • FWIW, __dirname 有时指向一个临时目录(可能是测试运行器复制测试的地方)。如果是这种情况,您可以使用process.cwd() 而不是__dirname
  • 这在 chrome 中对我有用,但对于其他浏览器,量角器抱怨该元素不可见......有什么想法吗?
  • 您无法使用 Firefox 上传,因为该元素不可见。您需要使元素可见以设置路径值。查看更新的答案。
【解决方案2】:

你不能直接。

出于安全原因,您不能在 ngScenario 等功能测试套件中模拟正在系统上选择文件的用户。

使用Protractor,既然是基于WebDriver的,应该可以使用this trick

问:WebDriver 是否支持文件上传?答:是的。

您不能直接与本机操作系统文件浏览器对话框交互, 但我们会做一些魔术,所以如果你打电话 WebElement#sendKeys("/path/to/file") 在文件上传元素上,它确实 正确的事情。确保你没有 WebElement#click() 文件 上传元素,否则浏览器可能会挂起。

这很好用:

$('input[type="file"]').sendKeys("/file/path")

【讨论】:

  • 这似乎没有回答问题,并链接到另一个网站
【解决方案3】:

这里是 Andres D 和 davidb583 的建议的组合,在我解决这个问题时会有所帮助...

我试图对 flowjs 控件执行量角器测试。

    // requires an absolute path
    var fileToUpload = './testPackages/' + packageName + '/' + fileName;
    var absolutePath = path.resolve(__dirname, fileToUpload);

    // Find the file input element
    var fileElem = element(by.css('input[type="file"]'));

    // Need to unhide flowjs's secret file uploader
    browser.executeScript(
      "arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1",
      fileElem.getWebElement());

    // Sending the keystrokes will ultimately submit the request.  No need to simulate the click
    fileElem.sendKeys(absolutePath);

    // Not sure how to wait for the upload and response to return first
    // I need this since I have a test that looks at the results after upload
    //  ...  there is probably a better way to do this, but I punted
    browser.sleep(1000);

【讨论】:

    【解决方案4】:
    var imagePath = 'http://placehold.it/120x120&text=image1';
    element(by.id('fileUpload')).sendKeys(imagePath);
    

    这对我有用。

    【讨论】:

      【解决方案5】:

      这是我在firefox上上传文件所做的,这个脚本使元素可见以设置路径值:

         browser.executeScript("$('input[type=\"file\"]').parent().css('visibility', 'visible').css('height', 1).css('width', 1).css('overflow', 'visible')");
      

      【讨论】:

        【解决方案6】:

        如果上述解决方案不起作用,请阅读本文

        首先,为了上传文件,应该有一个input 元素来获取文件的路径。通常,它紧挨着“上传”按钮... 但是我已经看到了,当按钮周围没有输入时,这似乎令人困惑。保持蛤蜊,输入必须在页面上!尝试在 DOM 中查找具有“上传”或“文件”之类的输入元素,请记住它可以在任何地方。

        找到它后,获取它的选择器,然后输入文件的路径。请记住,它必须是绝对路径,从您的根目录开始(MAC 用户为/something/like/this,Windows 为C:/some/file

        await $('input[type="file"]').sendKeys("/file/path")
        

        这可能行不通,如果...

        protractor 的 sendKeys 只能输入可见的输入。通常,输入将被隐藏或具有0 像素大小。你也可以解决这个问题

        let $input = $('input[type="file"]');
        await browser.executeScript(
            "arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1",
            $input.getWebElement()
        );
        

        【讨论】:

          【解决方案7】:

          我意识到我正在测试的网络应用程序中的文件输入只有在使用 JavaScript 滚动到视图时才在 Firefox 中可见,因此我在 Andres D 的代码中添加了 scrollIntoView() 以使其适用于我的应用程序:

            browser.executeAsyncScript(function (callback) {
                  document.querySelectorAll('input')[2]
               .style = '';
                  document.querySelectorAll('input')[2].scrollIntoView();
          
                  callback();
              });
          

          (我还删除了文件输入元素的所有样式)

          【讨论】:

            【解决方案8】:

            //从C:\目录上传文件

            {

            var path = require('path');
            var dirname = 'C:/';
            var fileToUpload = '../filename.txt';
            var absolutePath = path.resolve('C:\filename.txt');
            var fileElem = ptor.element.all(protractor.By.css('input[type="file"]'));
            
            fileElem.sendKeys(absolutePath);
            cb();
            

            };

            【讨论】:

            • 那么变量fileToUpload是干什么用的?
            【解决方案9】:

            如果你想选择一个文件而不打开下面的弹出窗口就是答案:

            var path = require('path'); 
            var remote = require('../../node_modules/selenium-webdriver/remote'); 
            browser.setFileDetector(new remote.FileDetector()); 
            var fileToUpload = './resume.docx';
            var absolutePath = path.resolve(process.cwd() + fileToUpload); 
            element(by.css('input[type="file"]')).sendKeys(absolutePath);
            

            【讨论】:

              【解决方案10】:

              当前记录的解决方案仅在用户加载 jQuery 时才有效。在所有不同的情况下,用户都会收到这样的错误:Failed: $ is not defined

              我建议使用原生 angularjs 代码记录解决方案。

              例如我会建议而不是建议:

                  $('input[type="file"]') .....
              

              建议:

                  angular.element(document.querySelector('input[type="file"]')) .....
              

              后者更标准,在 angular 之上,更重要的是不需要 jquery

              【讨论】:

                猜你喜欢
                • 2016-07-11
                • 1970-01-01
                • 1970-01-01
                • 2012-10-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多