From 59e3601ee7862c5993536df0553b81f1ce0cc088 Mon Sep 17 00:00:00 2001 From: Alan Greene Date: Tue, 21 Feb 2023 12:24:15 +0000 Subject: [PATCH] Add browser E2E tests for TaskRun YAML editor --- ...linerun.cy.js => pipelinerun-create.cy.js} | 19 +- ...pelinerun.cy.js => pipelinerun-edit.cy.js} | 6 +- .../e2e/cypress/e2e/run/taskrun-create.cy.js | 181 ++++++++++++++++++ .../e2e/cypress/e2e/run/taskrun-edit.cy.js | 72 +++++++ packages/e2e/cypress/support/commands.js | 14 +- 5 files changed, 275 insertions(+), 17 deletions(-) rename packages/e2e/cypress/e2e/run/{create-pipelinerun.cy.js => pipelinerun-create.cy.js} (90%) rename packages/e2e/cypress/e2e/run/{actions-pipelinerun.cy.js => pipelinerun-edit.cy.js} (93%) create mode 100644 packages/e2e/cypress/e2e/run/taskrun-create.cy.js create mode 100644 packages/e2e/cypress/e2e/run/taskrun-edit.cy.js diff --git a/packages/e2e/cypress/e2e/run/create-pipelinerun.cy.js b/packages/e2e/cypress/e2e/run/pipelinerun-create.cy.js similarity index 90% rename from packages/e2e/cypress/e2e/run/create-pipelinerun.cy.js rename to packages/e2e/cypress/e2e/run/pipelinerun-create.cy.js index 6167966b6..bb1cafae2 100644 --- a/packages/e2e/cypress/e2e/run/create-pipelinerun.cy.js +++ b/packages/e2e/cypress/e2e/run/pipelinerun-create.cy.js @@ -11,14 +11,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -function preserveIndentation(input) { - return input - .split('\n') - .map(line => `{home}${line}`) // {home} is interpreted by Cypress and returns the cursor to the start of the line - .join('\n'); -} - -const namespace = 'tekton-dashboard-e2e'; +const namespace = 'tekton-dashboard-e2e-pipelinerun-create'; describe('Create PipelineRun', () => { before(() => { cy.exec('kubectl version --client'); @@ -29,7 +22,7 @@ describe('Create PipelineRun', () => { cy.exec(`kubectl delete namespace ${namespace} || true`); }); - it('should create pipelinerun', function () { + it('should create PipelineRun', function () { const uniqueNumber = Date.now(); const pipelineName = `simple-pipeline-${uniqueNumber}`; @@ -127,7 +120,7 @@ spec: .should('have.text', 'Succeeded'); }); - it('should create pipelinerun yaml mode', function () { + it('should create PipelineRun in YAML mode', function () { const uniqueNumber = Date.now(); const pipelineRunName = `yaml-mode-${uniqueNumber}`; @@ -154,7 +147,7 @@ spec: cy.url().should('include', 'mode=yaml'); cy.get('.cm-content').clear(); - cy.get('.cm-content').type(preserveIndentation(pipelineRun)); + cy.get('.cm-content').type(pipelineRun, { preserveIndentation: true }); cy.contains('button', 'Create').click(); @@ -166,7 +159,7 @@ spec: .should('have.text', 'Succeeded'); }); - it('should create pipelinerun yaml mode when open yaml mode directly', function () { + it('should create PipelineRun when open YAML mode directly', function () { const uniqueNumber = Date.now(); const pipelineRunName = `yaml-mode-${uniqueNumber}`; @@ -190,7 +183,7 @@ spec: cy.visit(`/#/pipelineruns/create?mode=yaml`); cy.get('.cm-content').clear(); - cy.get('.cm-content').type(preserveIndentation(pipelineRun)); + cy.get('.cm-content').type(pipelineRun, { preserveIndentation: true }); cy.contains('button', 'Create').click(); diff --git a/packages/e2e/cypress/e2e/run/actions-pipelinerun.cy.js b/packages/e2e/cypress/e2e/run/pipelinerun-edit.cy.js similarity index 93% rename from packages/e2e/cypress/e2e/run/actions-pipelinerun.cy.js rename to packages/e2e/cypress/e2e/run/pipelinerun-edit.cy.js index 0e5015841..ba57ca5df 100644 --- a/packages/e2e/cypress/e2e/run/actions-pipelinerun.cy.js +++ b/packages/e2e/cypress/e2e/run/pipelinerun-edit.cy.js @@ -11,8 +11,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -const namespace = 'tkn-dashboard-e2e-actions'; -describe('Edit and run Pipeline Run', () => { +const namespace = 'tkn-dashboard-e2e-pipelinerun-edit'; +describe('Edit and run PipelineRun', () => { before(() => { cy.exec('kubectl version --client'); cy.exec(`kubectl create namespace ${namespace} || true`); @@ -22,7 +22,7 @@ describe('Edit and run Pipeline Run', () => { cy.exec(`kubectl delete namespace ${namespace} || true`); }); - it('should create pipelinerun on edit and run', function () { + it('should create PipelineRun on edit and run', function () { const uniqueNumber = Date.now(); const pipelineName = `sp-${uniqueNumber}`; const pipeline = `apiVersion: tekton.dev/v1beta1 diff --git a/packages/e2e/cypress/e2e/run/taskrun-create.cy.js b/packages/e2e/cypress/e2e/run/taskrun-create.cy.js new file mode 100644 index 000000000..9b19b48bf --- /dev/null +++ b/packages/e2e/cypress/e2e/run/taskrun-create.cy.js @@ -0,0 +1,181 @@ +/* +Copyright 2023 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +const namespace = 'tekton-dashboard-e2e-taskrun-create'; +describe('Create TaskRun', () => { + before(() => { + cy.exec('kubectl version --client'); + cy.exec(`kubectl create namespace ${namespace} || true`); + }); + + after(() => { + cy.exec(`kubectl delete namespace ${namespace} || true`); + }); + + it('should create TaskRun', function () { + const uniqueNumber = Date.now(); + + const taskName = `simple-task-${uniqueNumber}`; + const task = `apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: ${taskName} + namespace: ${namespace} +spec: + steps: + - name: echo + image: busybox + script: | + #!/bin/ash + echo "Hello World!" + `; + cy.exec(`echo "${task}" | kubectl apply -f -`); + cy.visit(`/#/taskruns/create?namespace=${namespace}&taskName=${taskName}`); + cy.get('[id=create-taskrun--namespaces-dropdown]').should( + 'have.value', + namespace + ); + cy.get('[id=create-taskrun--tasks-dropdown]').should( + 'have.value', + taskName + ); + + cy.contains('button', 'Create').click(); + + cy.contains('h1', 'TaskRuns'); + cy.contains('a', `${taskName}-run`).click(); + + cy.get('header[class="tkn--pipeline-run-header"]') + .find('span[class="tkn--status-label"]', { timeout: 15000 }) + .should('have.text', 'Succeeded'); + }); + + it('should populate YAML editor based on form inputs', function () { + const uniqueNumber = Date.now(); + + const taskName = `simple-task-${uniqueNumber}`; + const taskRunName = `run-${uniqueNumber}`; + const task = `apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: ${taskName} + namespace: ${namespace} +spec: + steps: + - name: echo + image: busybox + script: | + #!/bin/ash + echo "Hello World!" + `; + cy.exec(`echo "${task}" | kubectl apply -f -`); + cy.visit(`/#/taskruns/create?namespace=${namespace}&taskName=${taskName}`); + cy.get('[id=create-taskrun--namespaces-dropdown]').should( + 'have.value', + namespace + ); + cy.get('[id=create-taskrun--tasks-dropdown]').should( + 'have.value', + taskName + ); + + cy.get('#create-taskrun--taskrunname').type(taskRunName); + + cy.get('#create-taskrun--timeout').type('10m'); + + cy.contains('button', 'YAML Mode').click(); + cy.url().should('include', 'mode=yaml'); + + cy.contains('.cm-content', `name: ${taskRunName}`); + cy.contains('.cm-content', `name: ${taskName}`); + cy.contains('.cm-content', 'timeout: 10m'); + + cy.contains('button', 'Create').click(); + + cy.contains('h1', 'TaskRuns'); + cy.contains('a', taskRunName).click(); + + cy.get('header[class="tkn--pipeline-run-header"]') + .find('span[class="tkn--status-label"]', { timeout: 15000 }) + .should('have.text', 'Succeeded'); + }); + + it('should create TaskRun in YAML mode', function () { + const uniqueNumber = Date.now(); + + const taskRunName = `yaml-mode-${uniqueNumber}`; + const taskRun = `apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + name: ${taskRunName} + namespace: ${namespace} +spec: + taskSpec: + steps: + - name: echo + image: busybox + script: | + #!/bin/ash + echo "Hello World!" + `; + cy.visit(`/#/taskruns/create`); + + cy.contains('button', 'YAML Mode').click(); + cy.url().should('include', 'mode=yaml'); + + cy.get('.cm-content').clear(); + cy.get('.cm-content').type(taskRun, { preserveIndentation: true }); + + cy.contains('button', 'Create').click(); + + cy.contains('h1', 'TaskRuns'); + cy.get(`[title=${taskRunName}]`).click(); + + cy.get('header[class="tkn--pipeline-run-header"]') + .find('span[class="tkn--status-label"]', { timeout: 15000 }) + .should('have.text', 'Succeeded'); + }); + + it('should create TaskRun when open YAML mode directly', function () { + const uniqueNumber = Date.now(); + + const taskRunName = `yaml-mode-${uniqueNumber}`; + const taskRun = `apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + name: ${taskRunName} + namespace: ${namespace} +spec: + taskSpec: + steps: + - name: echo + image: busybox + script: | + #!/bin/ash + echo "Hello World!" + `; + cy.visit(`/#/taskruns/create?mode=yaml`); + + cy.get('.cm-content').clear(); + cy.get('.cm-content').type(taskRun, { preserveIndentation: true }); + + cy.contains('button', 'Create').click(); + + cy.contains('h1', 'TaskRuns'); + cy.get(`[title=${taskRunName}]`).click(); + + cy.get('header[class="tkn--pipeline-run-header"]') + .find('span[class="tkn--status-label"]', { timeout: 15000 }) + .should('have.text', 'Succeeded'); + }); +}); diff --git a/packages/e2e/cypress/e2e/run/taskrun-edit.cy.js b/packages/e2e/cypress/e2e/run/taskrun-edit.cy.js new file mode 100644 index 000000000..08b92100b --- /dev/null +++ b/packages/e2e/cypress/e2e/run/taskrun-edit.cy.js @@ -0,0 +1,72 @@ +/* +Copyright 2023 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +const namespace = 'tkn-dashboard-e2e-taskrun-edit'; +describe('Edit and run TaskRun', () => { + before(() => { + cy.exec('kubectl version --client'); + cy.exec(`kubectl create namespace ${namespace} || true`); + }); + + after(() => { + cy.exec(`kubectl delete namespace ${namespace} || true`); + }); + + it('should create TaskRun on edit and run', function () { + const uniqueNumber = Date.now(); + const taskName = `sp-${uniqueNumber}`; + const task = `apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: ${taskName} + namespace: ${namespace} +spec: + steps: + - name: echo + image: busybox + script: | + #!/bin/ash + echo "Hello World!" + `; + cy.exec(`echo "${task}" | kubectl apply -f -`); + cy.visit(`/#/taskruns/create?namespace=${namespace}&taskName=${taskName}`); + cy.get('[id=create-taskrun--namespaces-dropdown]').should( + 'have.value', + namespace + ); + cy.get('[id=create-taskrun--tasks-dropdown]').should( + 'have.value', + taskName + ); + cy.contains('button', 'Create').click(); + + cy.contains('h1', 'TaskRuns'); + + cy.get( + `td:has(.bx--link[title*=${taskName}-run]) + td:has(.tkn--status[data-reason=Succeeded])`, + { timeout: 15000 } + ).should('have.length', 1); + + cy.contains('a', `${taskName}-run`).click(); + cy.contains('button', 'Actions').click(); + cy.contains('button', 'Edit and run').click(); + cy.get('.cm-content').contains(`name: ${taskName}`); + cy.contains('button', 'Create').click(); + cy.contains('h1', 'TaskRuns'); + + cy.get( + `td:has(.bx--link[title*=${taskName}-run]) + td:has(.tkn--status[data-reason=Succeeded])`, + { timeout: 15000 } + ).should('have.length', 2); + }); +}); diff --git a/packages/e2e/cypress/support/commands.js b/packages/e2e/cypress/support/commands.js index f4e0f4949..88305a28b 100644 --- a/packages/e2e/cypress/support/commands.js +++ b/packages/e2e/cypress/support/commands.js @@ -1,5 +1,5 @@ /* -Copyright 2022 The Tekton Authors +Copyright 2022-2023 The Tekton Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -36,3 +36,15 @@ limitations under the License. // // -- This will overwrite an existing command -- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) + +Cypress.Commands.overwrite('type', (originalFn, element, text, options) => { + let textToType = text; + if (options && options.preserveIndentation) { + textToType = text + .split('\n') + .map(line => `{home}${line}`) // {home} is interpreted by Cypress and returns the cursor to the start of the line + .join('\n'); + } + + return originalFn(element, textToType, options); +});