Wie teste ich Dateieingaben mit Cypress?

Lesezeit: 7 Minuten

Wie kann ich einen e2e-Flow-Test schreiben, der eine Interaktion mit dem Dateieingabe-DOM-Element erfordert?

Wenn es sich um eine Texteingabe handelt, kann ich damit interagieren (Wert prüfen, Wert festlegen) usw., da es sich um eine DOM-Komponente handelt. Aber wenn ich ein Dateieingabeelement habe, vermute ich, dass die Interaktion begrenzt ist, bis ich den Dialog öffnen kann, um eine Datei auszuwählen. Ich kann nicht vorwärts gehen und die Datei auswählen, die ich hochladen möchte, da der Dialog nativ wäre und kein Browserelement.

Wie würde ich also testen, ob ein Benutzer eine Datei von meiner Website korrekt hochladen kann? ich benutze Zypresse um meine e2e-Tests zu schreiben.

  • Beachten Sie, dass diese Funktionalität ab 9.3.0 nativ über cy.selectFile unterstützt wird

    – Alex Beardsley

    19. Januar um 19:51 Uhr

Benutzeravatar von Muhammad Bilal
Muhammed Bilal

it('Testing picture uploading', () => {
    cy.fixture('testPicture.png').then(fileContent => {
        cy.get('input[type="file"]').attachFile({
            fileContent: fileContent.toString(),
            fileName: 'testPicture.png',
            mimeType: 'image/png'
        });
    });
});

Verwenden Sie das Cypress-Datei-Upload-Paket: https://www.npmjs.com/package/cypress-file-upload

Hinweis: testPicture.png muss sich im Fixture-Ordner von Cypress befinden

  • Hatte Probleme, dies zum Laufen zu bringen. Anscheinend hat sich der Code geändert. Anstatt von cy.get( ... ).upload()die Funktion wird jetzt aufgerufen cy.get( ... ).attachFile(). Ich habe die ursprüngliche Antwort bearbeitet.

    – Jules Colle

    21. Juni 2020 um 11:03 Uhr


  • Ja, Jules Colle, ich habe gerade die offizielle Dokumentation überprüft und ja, Sie haben Recht, .upload wurde in .attachFile geändert. Vielen Dank

    – Muhammad Bilal

    23. Juni 2020 um 6:22 Uhr

  • Ich hatte auch Probleme. Um es zu beheben, musste ich dann Anweisungen wie aneinander ketten cy.fixture(...).then( fc => {return Cypress.Blob.base64StringToBlob( fc ) }).then(fileContentasBlob => { cy.get('input[type="file"]').attachFile({ ......

    – Chadd Frasier

    20. Juli 2020 um 22:03 Uhr


  • Ich hatte Probleme mit diesem Ansatz. Der Upload hat funktioniert, aber der Server konnte das hochgeladene Bild nicht verarbeiten: (PIL.UnidentifiedImageError: cannot identify image file). Diesen Fehler konnte ich mit dem Ansatz von Lucas Andrade vermeiden cy.get('['input[type="file"]']').attachFile(fixtureFile) nur (ohne Informationen über mimeType etc.).

    – Jasmin

    20. Januar 2021 um 16:36 Uhr

  • Beachten Sie, dass diese Funktionalität ab 9.3.0 nativ über cy.selectFile unterstützt wird und dass es auf der Cypress-Website einen Migrationsleitfaden für dieses Plugin gibt

    – Alex Beardsley

    19. Januar um 19:50 Uhr


Für mich ist dies der einfachere Weg, dies zu tun Cypress-Datei-Upload-Paket

Es installieren:

npm install --save-dev cypress-file-upload

Fügen Sie dann diese Zeile zu Ihrem Projekt hinzu cypress/support/commands.js:

import 'cypress-file-upload';

Jetzt können Sie Folgendes tun:

const fixtureFile="photo.png";
cy.get('[data-cy="file-input"]').attachFile(fixtureFile);

photo.png muss drin sein cypress/fixtures/

Weitere Beispiele finden Sie unter Verwendungsabschnitt in der README-Datei des Pakets.

  • Wow! Ich habe alle (komplizierteren) Beispiele aus der README des Pakets ausprobiert, aber dieses – das einfachste von allen – ist das einzige, das funktioniert! Vielen Dank!

    – Adrian Joly

    5. September 2020 um 16:10 Uhr

  • das funktioniert bei mir super! Für alle Szenarien jedoch, wenn ich versuche, die clientseitige jQuery-Validierung für die Dateien zu verwenden[] Reihe. Es kann den Dateityp nicht validieren. Ich habe eine Validierung, um zu überprüfen, ob Sie nichts anderes als Bilddateien hochladen können. Aber wenn ich ein Mimetupe in ‚attachfile‘ angebe, ist die Datei-Upload-Datei, die zum Server geht, null?

    – Gweaths

    10. Mai 2021 um 15:54 Uhr

  • Diese Lösung funktionierte (musste zusätzliche Details vom npm-Paketautor erhalten, der als Antwort verlinkt war), aber damit mein Intellisense ‘attachFile’ erkennen konnte, musste ich ` /// ` an ​​den Anfang der Spezifikationsdatei.

    – Tengen

    15. November 2021 um 19:31 Uhr

  • Verwenden Sie die @thisismydesign-Lösung!

    – ismaestro

    31. März um 11:44 Uhr

Seit 9.3.0 Sie können verwenden selectFile.

cy.get('input[type=file]').selectFile('cypress/fixtures/file.json')

Sehen:

Benutzeravatar von Javier Aviles
Javier Avilés

Mit diesem Ansatz/Hack können Sie es tatsächlich schaffen:
https://github.com/javieraviles/cypress-upload-file-post-form

Es basiert auf verschiedenen Antworten aus dem oben genannten Thread https://github.com/cypress-io/cypress/issues/170

Erstes Szenario (upload_file_to_form_spec.js):

Ich möchte eine Benutzeroberfläche testen, bei der vor dem Absenden des Formulars eine Datei ausgewählt/hochgeladen werden muss. Fügen Sie den folgenden Code in Ihre Datei „commands.js“ im Cypress-Supportordner ein, damit der Befehl cy.upload_file() von jedem Test aus verwendet werden kann:

Cypress.Commands.add('upload_file', (fileName, fileType, selector) => {
    cy.get(selector).then(subject => {
        cy.fixture(fileName, 'hex').then((fileHex) => {

            const fileBytes = hexStringToByte(fileHex);
            const testFile = new File([fileBytes], fileName, {
                type: fileType
            });
            const dataTransfer = new DataTransfer()
            const el = subject[0]

            dataTransfer.items.add(testFile)
            el.files = dataTransfer.files
        })
    })
})

// UTILS
function hexStringToByte(str) {
    if (!str) {
        return new Uint8Array();
    }

    var a = [];
    for (var i = 0, len = str.length; i < len; i += 2) {
        a.push(parseInt(str.substr(i, 2), 16));
    }

    return new Uint8Array(a);
}

Falls Sie dann eine Excel-Datei hochladen, andere Eingaben ausfüllen und das Formular absenden möchten, würde der Test in etwa so aussehen:

describe('Testing the excel form', function () {
    it ('Uploading the right file imports data from the excel successfully', function() {

    const testUrl="http://localhost:3000/excel_form";
    const fileName="your_file_name.xlsx";
    const fileType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    const fileInput="input[type=file]";

    cy.visit(testUrl);
    cy.upload_file(fileName, fileType, fileInput);
    cy.get('#other_form_input2').type('input_content2');
    .
    .
    .
    cy.get('button').contains('Submit').click();

    cy.get('.result-dialog').should('contain', 'X elements from the excel where successfully imported');
})

})

Das Testen von Dateieingabeelementen wird in Cypress noch nicht unterstützt. Die einzige Möglichkeit, Dateieingaben zu testen, ist:

  1. Geben Sie native Ereignisse aus (die Cypress auf ihrer Fahrplan).
  2. Verstehen Sie, wie Ihre Anwendung Datei-Uploads mit der Datei-API handhabt, und führen Sie sie dann aus. Es ist möglich, aber nicht allgemein genug, um spezifische Ratschläge zu geben.

Weitere Einzelheiten finden Sie in diesem offenen Problem.

  • Ich unterbreche den Datei-Upload vorerst und werde dieses Problem im Auge behalten. Vielen Dank.

    – sidoshi

    2. November 2017 um 19:30 Uhr

  • Die im Problem beschriebenen Problemumgehungen wurden zusammengefasst github.com/abramenal/cypress-file-upload falls das hilft

    – Tobi

    4. Februar 2019 um 16:12 Uhr

  • Dies wurde mit der neuen Version von Cypress bereitgestellt: stackoverflow.com/a/70771129/6774916

    – t_dom93

    19. Januar um 13:32 Uhr

  • Verwenden Sie die @thisismydesign-Lösung!

    – ismaestro

    31. März um 11:44 Uhr

Vishwas Benutzeravatar
Vishwa

In meinem Fall hatte ich eine client- und serverseitige Dateivalidierung, um zu überprüfen, ob die Datei JPEG oder PDF ist. Also musste ich einen Upload-Befehl erstellen, der die Datei in Binärform von Fixtures liest und einen Blob mit der Dateierweiterung vorbereitet.

Cypress.Commands.add('uploadFile', { prevSubject: true }, (subject, fileName, fileType="") => {
  cy.fixture(fileName,'binary').then(content => {
    return Cypress.Blob.binaryStringToBlob(content, fileType).then(blob => {
      const el = subject[0];
      const testFile = new File([blob], fileName, {type: fileType});
      const dataTransfer = new DataTransfer();

      dataTransfer.items.add(testFile);
      el.files = dataTransfer.files;
      cy.wrap(subject).trigger('change', { force: true });
    });
  });
});

dann benutze es als

cy.get('input[type=file]').uploadFile('smiling_pic.jpg', 'image/jpeg');

smiling_pic.jpg befindet sich im Fixtures-Ordner

  • Ich unterbreche den Datei-Upload vorerst und werde dieses Problem im Auge behalten. Vielen Dank.

    – sidoshi

    2. November 2017 um 19:30 Uhr

  • Die im Problem beschriebenen Problemumgehungen wurden zusammengefasst github.com/abramenal/cypress-file-upload falls das hilft

    – Tobi

    4. Februar 2019 um 16:12 Uhr

  • Dies wurde mit der neuen Version von Cypress bereitgestellt: stackoverflow.com/a/70771129/6774916

    – t_dom93

    19. Januar um 13:32 Uhr

  • Verwenden Sie die @thisismydesign-Lösung!

    – ismaestro

    31. März um 11:44 Uhr

Vikkis Benutzeravatar
Vikki

Bei mir funktioniert folgende Funktion

cy.getTestElement('testUploadFront').should('exist');

const fixturePath="test.png";
const mimeType="application/png";
const filename="test.png";

cy.getTestElement('testUploadFrontID')
  .get('input[type=file')
  .eq(0)
  .then(subject => {
    cy.fixture(fixturePath, 'base64').then(front => {
      Cypress.Blob.base64StringToBlob(front, mimeType).then(function(blob) {
        var testfile = new File([blob], filename, { type: mimeType });
        var dataTransfer = new DataTransfer();
        var fileInput = subject[0];

        dataTransfer.items.add(testfile);
        fileInput.files = dataTransfer.files;
        cy.wrap(subject).trigger('change', { force: true });
      });
    });
  });

// Cypress.Commands.add(`getTestElement`, selector =>
//   cy.get(`[data-testid="${selector}"]`)
// );

  • Ich habe nach dieser “Aktualisierungs” -Funktion nach Änderungsereignis gesucht, hat mir sehr geholfen, danke!

    – Kapcash

    12. März 2020 um 11:13 Uhr

1405300cookie-checkWie teste ich Dateieingaben mit Cypress?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy