Videos nach einem Cypress-Testlauf in Jira hochladen

Vorwort
Die Integration von Cypress mit Jira über die API ist einfach. Nach diesem Tutorial werdet ihr in der Lage sein, Videos programmatisch aus eurer Cypress-Test-Suite heraus an Jira-Aufgaben anzuhängen.
Voraussetzungen
- Vorhandene Jira-Plattform
- Node.js
- Grundkenntnisse in JavaScript und dem Cypress-Framework
- Grundkenntnisse in der API-Nutzung
- Praktische Kenntnisse im Umgang mit dem Terminal (oder ähnlichen Tools wie Windows PowerShell)
Erste Schritte mit einem neuen Cypress-Projekt
Zunächst initialisieren wir ein neues Projekt. Dazu erstellen wir das einfachste Projekt mit npm.
Schritt 1: Ein neues Verzeichnis für unser Cypress-Projekt erstellen.
Schritt 2: Aus dem neuen Verzeichnis heraus den Befehl npm init im Terminal ausführen, um ein neues npm-basiertes Projekt zu erstellen. Dieser Schritt erstellt eine package.json-Datei.
Schritt 3: Aus dem Stammverzeichnis (dasselbe wie in Schritt 2) kann der Befehl npm install cypress --save-dev verwendet werden, um Cypress zu den Projektabhängigkeiten hinzuzufügen.
Step 4: Run Cypress open command. There are two ways (at least) to do so:
- Use
cypresscommand from the root directoryopen-e2e -b chrome - “test”: “cypress
open–e2e -b chrome” zumscripts-Abschnitt derpackage.json-Datei hinzufügen und das Skript mit dem Befehlnpm run testaus dem Stammverzeichnis ausführen
Schritt 5: Unten seht ihr ein Bild dessen, was ihr kurz nach dem Ausführen des Befehls im Terminal sehen solltet. Drückt auf Continue und wählt Scaffold example specs aus, um einige Beispiel-Testdateien zu erstellen. Um sicherzustellen, dass alles wie erwartet funktioniert, führt ihr eine der verfügbaren Spec-Dateien aus (z. B. todo aus dem Verzeichnis 1-getting-started).

Schritt 6: Tests sollten bestehen und mit grünen Pfeilen enden, wie in der folgenden Abbildung dargestellt.

Videos mit Cypress aufzeichnen
Wie ihr vielleicht bereits bemerkt habt, zeichnet Cypress keine Videos auf, wenn es über den Cypress Runner (Befehl cypress ) ausgeführt wird. Ich konnte keine genauen Informationen darüber finden, warum das so ist, und muss daher annehmen, dass es mit der Cypress-Architektur beim Ausführen im sogenannten Headed-Modus (im Gegensatz zum Headless-Modus) zusammenhängt.open
Andererseits wird die Videoaufzeichnung automatisch durchgeführt, wenn Cypress über den Befehl cypress run ausgeführt wird. Aktualisieren wir also den scripts-Abschnitt der package.json:
"scripts": {
"cy-open": "cypress open --e2e -b chrome",
"cy-run": "cypress run --e2e -b chrome --spec cypress/e2e/1-getting-started/todo.cy.js"
},
Mit dem Flag --spec können wir eine einzelne Spec-Datei angeben, die ausgeführt werden soll. Der nächste Schritt besteht darin, zu überprüfen, ob Videos aufgezeichnet werden. Den Befehl npm run cy-run aus dem Stammverzeichnis ausführen.
Sobald der Test abgeschlossen ist, sollte ein brandneues Verzeichnis namens videos entstehen, das eine Videodatei enthält, die wie die Spec-Datei benannt ist, mit dem Suffix *.mp4 (z. B. todo.cy.js.mp4).
Cypress-Videos in Jira hochladen
Der Einfachheit halber probieren wir die einfachste Lösung für den Video-Upload aus.
Jira Personal Access Token & Base URL
Zunächst müssen wir unseren Cypress-Tests Zugriff auf Jira gewähren. Dazu können wir die integrierte Personal-Access-Token-Funktion von Jira nutzen.
Meldet euch bei eurer Jira-Plattform an und klickt auf euer Profilsymbol. Wählt die Option Profile und navigiert in der Seitennavigation zum Tab Personal Access Tokens.
Drückt die Schaltfläche Create token, gebt einen Titel an und speichert das Token an einem sicheren Ort. Sobald das Token vorliegt, extrahieren wir zusätzlich die Base URL der Jira-Plattform.
Mit beiden Werten können wir Umgebungsvariablen in der Datei cypress.config.js erstellen:
module.exports = defineConfig({
e2e: {
env: {
jiraApiToken: 'yourJiraApiToken',
jiraApiBaseUrl: 'https://yourJiraPlatformBaseUrl/rest/api/2',
}
Überblick über Cypress-Videos
Nun konzentrieren wir uns darauf, wie Cypress bei der Videoaufzeichnung funktioniert.
- Cypress zeichnet Videos der gesamten Spec-Datei auf (nicht pro Testfall)
- Cypress-Aufzeichnungen werden standardmäßig komprimiert. Um das zu ändern, kann das Flag
videoCompression:in der Dateifalsecypress.config.jshinzugefügt werden (wie im folgenden Beispiel). Das Flag für die Videokomprimierung akzeptiert die Wertefalseund numerische Werte im Bereich 0–51.
env: {
videoCompression: , false// either false, or values from 0 to 51
env: {
jiraApiToken: 'yourJiraApiToken',
jiraApiBaseUrl: ‘https://yourJiraPlatformBaseUrl/rest/api/2‘
}
- Cypress löscht das
videos-Verzeichnis vor einem Cypress-Testlauf. Das kann durch Hinzufügen des FlagstrashAssetsBeforeRuns:in der Dateifalsecypress.config.js(Abschnitt e2e) geändert werden - Wir können nur das
after:spec-Ereignis von Cypress nutzen, um die Kontrolle darüber zu erlangen, was mit der Videodatei passiert
Mit diesen Grundregeln können wir mit dem Coden beginnen.
Erforderliche Abhängigkeiten in package.json
Wir müssen unsere package.json-Datei aktualisieren, um uns die Möglichkeit zu geben, Dateien über die API hochzuladen. Dazu fügen wir zwei erforderliche Abhängigkeiten hinzu, wie unten gezeigt:
"dependencies": {
"form-data": "^4.0.0",
"node-fetch": "^2.6.7"
}
form-data ist eine Schnittstelle, die ein Schlüssel-Wert-Format für Formularfelder und ihre jeweiligen Werte bereitstellt, die dann über fetch() gesendet werden können.
node-fetch ist ein Paket, das window. für die Node.js-Umgebung bereitstellt. Mehr dazu: https://www.npmjs.com/package/node-fetchfetch()
Bitte berücksichtigt die Abhängigkeitsversionen, wenn ihr diesen Code in euer Cypress-basiertes Framework implementiert, da es zu Schwierigkeiten kommen kann, wenn ihr diese Werte ändert. Es ist nicht verboten – stellt nur sicher, dass ihr wisst, was ihr tut 🙂
Code-Implementierung
Nachdem alles vorbereitet ist, bleibt nur noch, die Datei cypress.config.js mit dem entsprechenden Code zu aktualisieren.
const {defineConfig} = require("cypress");
const path = require("path");
const fs = require("fs");
const FormData = require('form-data');
const fetch = require('node-fetch');
module.exports = defineConfig({
e2e: {
videoCompression: false,
env: {
jiraApiToken: 'yourJiraApiToken',
jiraApiBaseUrl: 'https://yourJiraPlatformBaseUrl/rest/api/2'
},
setupNodeEvents(on, config) {
on('after:spec', async spec => {
const videoPath = path.normalize(`${config.videosFolder}/${spec.baseName}.mp4`);
if (fs.existsSync(videoPath)) {
const form = new FormData();
form.append('file', fs.createReadStream(videoPath));
const requestDetails = {
method: 'POST',
headers: {
'Authorization': `Bearer ${config.env.jiraApiToken}`,
'Accept': 'application/json',
'X-Atlassian-Token': 'no-check',
'Content-Type': `multipart/form-data; boundary=${form._boundary}`
},
body: form
}
await fetch(`${config.env.jiraApiBaseUrl}/issue/COPQMS-570/attachments`, requestDetails)
.then(response => {
if (response.status !== 200) {
console.log('Server sent wrong status. Status: ' + response.status)
} else {
console.log(`Added video as evidence: ${videoPath}`);
}
})
.catch(err => {
console.error(`Video (${videoPath}) couldn't be uploaded due to an error`);
console.error(err);
});
} else {
console.error(`Video file not found: ${videoPath}`);
}
})
},
},
});
Lassen wir das aufschlüsseln:
- setupNodeEvents(on, config) – ist eine Standard-Cypress-Konfigurationsfunktion, die es uns ermöglicht, das interne Cypress-Verhalten zu ändern (mehr dazu hier)
- on(‘
after:spec‘, async spec => { – wir verwenden denafter:spec-Hook von Cypress, um den Video-Upload durchzuführen, sobald der Testlauf auf Basis der Spec-Datei abgeschlossen ist - const videoPath = path.normalize(${config.videosFolder}/${spec.baseName}.mp4); – diese Zeile ist für die Normalisierung des Videodatei-Pfads verantwortlich (einfach gesagt: wir möchten, dass der Pfad mit verschiedenen Dateisystemen kompatibel ist)
if (fs.existsSync(videoPath)) {
const form = new FormData();
form.append('file', fs.createReadStream(videoPath));
const requestDetails = {
method: 'POST',
headers: {
'Authorization': `Bearer ${config.env.jiraApiToken}`,
'Accept': 'application/json',
'X-Atlassian-Token': 'no-check',
'Content-Type': `multipart/form-data; boundary=${form._boundary}`
},
body: form
}
Der obige Code macht mehrere Dinge:
- if (fs.existsSync(videoPath)) { – prüft, ob die Videodatei vorhanden ist. Falls nicht, wird ein Fehler in der Konsole mit dem Hinweis angezeigt, dass die Videodatei nicht gefunden werden konnte
- const form = new FormData(); form.append(‘file’, fs.createReadStream(videoPath)); – erstellt ein neues FormData und hängt die Videodatei als
ReadStreaman. Das ermöglicht es uns, Binärdateien über die API zu senden - Der gesamte Abschnitt zu
requestDetailsenthält die Details der API-Anfrage. Die wichtigsten Punkte für die Jira-Integration sind: - ‘Authorization’: Bearer ${config.
env.jiraApiToken} – wir verwenden das persönliche Zugriffstoken von Jira - ‘X-Atlassian-Token’
:‘no-check’ – das ist der erforderliche Header (hier erwähnt) - ‘Content-Type’: multipart/form-data;
boundary=${form._boundary} – wir müssen den Content-Type angeben. Andernfalls tritt der Fehler 415 Unsupported Media Type auf. Außerdem ist der Boundary erforderlich, es sei denn, ihr wollt den Fehler 500 Internal Server Error sehen - body: form – wir übergeben das FormData mit der angehängten Datei als API-Anfrage-Body
- await fetch(${config.
env.jiraApiBaseUrl}/issue/COPQMS-570/attachments,requestDetails) – der letzte Teil ist implementiert, um die API-Anfrage durchzuführen. Wir verwenden den hartcodierten Wert des Jira-Tickets (COPQMS-570), aber ihr könnt gerne damit experimentieren (z. B. das Jira-Ticket automatisch aus Test Plan, Test Run oder Test Execution ableiten).
Beachtet außerdem das await neben der fetch()-Funktion. Ohne es wird Cypress einfach weitermachen und den Datei-Upload-Teil komplett überspringen.
Nach dem Abrufen der Antwort führen wir einfache Validierungen basierend auf dem Antwortstatuscode und der Verfügbarkeit der für die fetch()-Funktion bereitgestellten Ressourcen durch.
Lösung testen
Probieren wir den Code aus. Den Befehl npm run cy-run aus dem Stammverzeichnis ausführen und danach das Jira-Ticket prüfen.

Wie ihr sehen könnt, hat mein Test mit Bravour bestanden, und es gibt einen Log-Eintrag, der besagt, dass die Videodatei hochgeladen wurde.

Wir können auch von der Jira-Plattform aus bestätigen, dass der Anhang dem Ticket hinzugefügt wurde.
Bei Fragen – hinterlasst sie gerne im Kommentarbereich.
Viel Spaß beim Coden!
Agent Hub
Gehen Sie über vereinzelte AI-Piloten hinaus und schaffen Sie eine sichere, skalierbare Grundlage für Agentic AI in Ihrer gesamten Organisation.
Zur Demo




