Comment télécharger un fichier dans les tests de rapporteur angularjs e2e

Réponses:

137

Voici comment je fais:

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. Utilisez le pathmodule pour résoudre le chemin complet du fichier que vous souhaitez télécharger.
  2. Définissez le chemin d'accès à l' élément input type = "file" .
  3. Cliquez sur le bouton de téléchargement.

Cela ne fonctionnera pas sur Firefox. Le rapporteur se plaindra car l'élément n'est pas visible. Pour télécharger dans Firefox, vous devez rendre l'entrée visible. C'est ce que je fais:

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();
Andres D
la source
+1 Cela fonctionne. Andres, vous devriez demander des commentaires au PO car celui-ci pourrait être accepté comme la bonne réponse.
coma
1
J'ai également travaillé avec Protractor.
Ilia Barahovski
6
FWIW, __dirnamepointe parfois vers un répertoire temporaire (probablement où les tests sont copiés par le lanceur de tests). Vous pouvez utiliser à la process.cwd()place de __dirnamesi c'est le cas.
BorisOkunskiy
Cela fonctionne pour moi dans chrome, mais pour les autres navigateurs, le rapporteur se plaint que l'élément n'est pas visible ... des idées?
Omid Ahourai
Vous ne pouvez pas télécharger avec Firefox car l'élément n'est pas visible. Vous devez rendre l'élément visible pour définir la valeur du chemin. Voir la réponse mise à jour.
Andres D
14

Vous ne pouvez pas directement.

Pour des raisons de sécurité, vous ne pouvez pas simuler un utilisateur qui choisit un fichier sur le système dans une suite de tests fonctionnels telle que ngScenario.

Avec Protractor, puisqu'il est basé sur WebDriver, il devrait être possible d'utiliser cette astuce

Q: WebDriver prend-il en charge les téléchargements de fichiers? R: Oui.

Vous ne pouvez pas interagir directement avec la boîte de dialogue du navigateur de fichiers du système d'exploitation natif, mais nous faisons un peu de magie pour que si vous appelez WebElement # sendKeys ("/ chemin / vers / fichier") sur un élément de téléchargement de fichier, il fasse la bonne chose. Assurez-vous que WebElement # ne clique pas () sur l'élément de téléchargement de fichier, sinon le navigateur se bloquera probablement.

Cela fonctionne très bien:

$('input[type="file"]').sendKeys("/file/path")
bdavidxyz
la source
Cela ne semble pas répondre à la question, et des liens vers un autre site
activedecay
4

Voici un combo des conseils d'Andres D et de davidb583 qui m'auraient aidé pendant que je travaillais à travers cela ...

J'essayais de faire exécuter des tests de rapporteur par rapport aux contrôles 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);
Doug
la source
2
var imagePath = 'http://placehold.it/120x120&text=image1';
element(by.id('fileUpload')).sendKeys(imagePath);

Cela fonctionne pour moi.

Koga
la source
1

C'est ce que je fais pour télécharger un fichier sur Firefox, ce script rend l'élément visible pour définir la valeur du chemin:

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

J'ai réalisé que l'entrée de fichier dans l'application Web que je teste n'est visible dans Firefox que lorsqu'elle est défilée à l'aide de JavaScript, j'ai donc ajouté scrollIntoView () dans le code d'Andres D pour le faire fonctionner pour mon application:

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

        callback();
    });

(J'ai également supprimé tous les styles de l'élément d'entrée de fichier)

pinkninja
la source
0

// Pour télécharger un fichier depuis C: \ Directory

{

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();

};

type au hasard
la source
Alors, à quoi sert la variable fileToUpload?
Lynx 242
-3

les solutions documentées actuelles ne fonctionneraient que si les utilisateurs chargent jQuery. i toutes les situations différentes, les utilisateurs recevront une erreur telle: Échec: $ n'est pas défini

Je suggérerais de documenter une solution en utilisant le code angularjs natif.

Par exemple, je suggérerais au lieu de suggérer:

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

suggérer:

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

cette dernière est plus standard, au sommet d'angulaire et plus importante ne nécessite pas de jquery

Giovanni Pellerano
la source