From 41c796cf82cfbd8364604de8fd05d543dd46ee23 Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 7 Jan 2025 12:32:11 -0600 Subject: [PATCH] feat: cypress tests --- cypress/fixtures/pipeline_warnings.json | 18 +++ cypress/integration/pipeline.spec.js | 125 +++++++++++++++++++ cypress/support/commands.js | 10 ++ src/elm/Pages/Org_/Repo_/Build_/Pipeline.elm | 26 ++-- 4 files changed, 171 insertions(+), 8 deletions(-) create mode 100644 cypress/fixtures/pipeline_warnings.json diff --git a/cypress/fixtures/pipeline_warnings.json b/cypress/fixtures/pipeline_warnings.json new file mode 100644 index 000000000..4e387caff --- /dev/null +++ b/cypress/fixtures/pipeline_warnings.json @@ -0,0 +1,18 @@ +{ + "id": 1, + "repo_id": 1, + "commit": "9b1d8bded6e992ab660eaee527c5e3232d0a2441", + "flavor": "", + "platform": "", + "ref": "refs/heads/main", + "type": "yaml", + "version": "1", + "external_secrets": false, + "internal_secrets": false, + "services": false, + "stages": false, + "steps": true, + "templates": true, + "warnings": ["pipeline is using shared secrets", "4:invalid template name"], + "data": "dmVyc2lvbjogIjEiCnN0ZXBzOgotIHRlbXBsYXRlOgogICAgbmFtZTogY3VzdG9tX3RlbXBsYXRlCiAgICB2YXJzOgogICAgICBidWlsZF9ldmVudDogJHtCVUlMRF9FVkVOVH0KICBuYW1lOiBpbnZva2UgdGVtcGxhdGUxX25hbWUKICBwdWxsOiBub3RfcHJlc2VudAotIHRlbXBsYXRlOgogICAgbmFtZTogc2ltcGxlX3RlbXBsYXRlCiAgICB2YXJzOgogICAgICBidWlsZF9ldmVudDogJHtCVUlMRF9FVkVOVH0KICBuYW1lOiBpbnZva2UgdGVtcGxhdGUyX25hbWUKICBwdWxsOiBub3RfcHJlc2VudAotIHRlbXBsYXRlOgogICAgbmFtZTogYnJhbmNoZWRfdGVtcGxhdGUKICAgIHZhcnM6CiAgICAgIGJ1aWxkX2V2ZW50OiAke0JVSUxEX0VWRU5UfQogIG5hbWU6IGludm9rZSB0ZW1wbGF0ZTNfbmFtZQogIHB1bGw6IG5vdF9wcmVzZW50CnRlbXBsYXRlczoKLSBuYW1lOiB0ZW1wbGF0ZTFfbmFtZQogIHNvdXJjZTogZ2l0aHViLmNvbS9naXRodWIvb2N0b2NhdC90ZW1wbGF0ZTEueW1sCiAgdHlwZTogZ2l0aHViCi0gbmFtZTogdGVtcGxhdGUyX25hbWUKICBzb3VyY2U6IGdpdGh1Yi5jb20vZ2l0aHViL29jdG9jYXQvdGVtcGxhdGUyLnltbAogIHR5cGU6IGdpdGh1YgotIG5hbWU6IHRlbXBsYXRlM19uYW1lCiAgc291cmNlOiBnaXRodWIuY29tL2dpdGh1Yi9vY3RvY2F0L3RlbXBsYXRlMy55bWwKICB0eXBlOiBnaXRodWI=" +} diff --git a/cypress/integration/pipeline.spec.js b/cypress/integration/pipeline.spec.js index 3ffcfd906..560079bc1 100644 --- a/cypress/integration/pipeline.spec.js +++ b/cypress/integration/pipeline.spec.js @@ -90,6 +90,10 @@ context('Pipeline', () => { cy.get('[data-test=pipeline-expand]').should('exist'); }); + it('warnings should not be visible', () => { + cy.get('[data-test=pipeline-warnings]').should('not.be.visible'); + }); + context('click expand templates', () => { beforeEach(() => { cy.get('[data-test=pipeline-expand-toggle]').click({ @@ -285,4 +289,125 @@ context('Pipeline', () => { }); }, ); + context( + 'logged in and server returning valid pipeline configuration (with warnings) and templates', + () => { + beforeEach(() => { + cy.server(); + cy.stubBuild(); + cy.stubPipelineWithWarnings(); + cy.stubPipelineExpand(); + cy.stubPipelineTemplates(); + cy.login('/github/octocat/1/pipeline'); + }); + + it('warnings should be visible', () => { + cy.get('[data-test=pipeline-warnings]').should('be.visible'); + }); + + it('should show 2 warnings', () => { + cy.get('[data-test=pipeline-warnings]') + .children() + .should('have.length', 2); + }); + + it('warning with line number should show line number button', () => { + cy.get('[data-test=warning-line-num-4]') + .should('be.visible') + .should('not.have.class', '-disabled'); + }); + + it('warning with line number should show content without line number', () => { + cy.get('[data-test=warning-0] .line-content') + .should('be.visible') + .should('not.contain', '4') + .should('contain', 'template'); + }); + + it('warning without line number should replace button with dash', () => { + cy.get('[data-test=warning-1]') + .should('be.visible') + .should('contain', '-'); + }); + + it('warning without line number should content', () => { + cy.get('[data-test=warning-1] .line-content') + .should('be.visible') + .should('contain', 'secrets'); + }); + + it('log line with warning should show annotation', () => { + cy.get('[data-test=warning-annotation-line-4]').should('be.visible'); + }); + + it('other lines should not show annotations', () => { + cy.get('[data-test=warning-annotation-line-5]').should( + 'not.be.visible', + ); + }); + + context('click warning line number', () => { + beforeEach(() => { + cy.get('[data-test=warning-line-num-4]').click({ force: true }); + }); + + it('should update path with line num', () => { + cy.hash().should('eq', '#4'); + }); + + it('should set focus style on single line', () => { + cy.get('[data-test=config-line-4]').should('have.class', '-focus'); + }); + + it('other lines should not have focus style', () => { + cy.get('[data-test=config-line-3]').should( + 'not.have.class', + '-focus', + ); + }); + }); + + context('click expand templates', () => { + beforeEach(() => { + cy.get('[data-test=pipeline-expand-toggle]').click({ + force: true, + }); + cy.wait('@expand'); + }); + + it('should update path with expand query', () => { + cy.location().should(loc => { + expect(loc.search).to.eq('?expand=true'); + }); + }); + + it('should show pipeline expansion note', () => { + cy.get('[data-test=pipeline-warnings-expand-note]').contains('note'); + }); + + it('warning with line number should show disabled line number button', () => { + cy.get('[data-test=warning-line-num-4]') + .should('be.visible') + .should('have.class', '-disabled'); + }); + + context('click warning line number', () => { + beforeEach(() => { + cy.get('[data-test=warning-line-num-4]').click({ force: true }); + }); + + it('should not update path with line num', () => { + cy.hash().should('not.eq', '#4'); + }); + + it('other lines should not have focus style', () => { + cy.get('[data-test=config-line-3]').should( + 'not.have.class', + '-focus', + ); + }); + }); + }); + }, + ); }); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index ed6de0ea5..8b131522c 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -531,6 +531,16 @@ Cypress.Commands.add('stubPipeline', () => { }); }); +Cypress.Commands.add('stubPipelineWithWarnings', () => { + cy.fixture('pipeline_warnings.json').as('pipeline'); + cy.route({ + method: 'GET', + url: '*api/v1/pipelines/*/*/*', + status: 200, + response: '@pipeline', + }); +}); + Cypress.Commands.add('stubPipelineErrors', () => { cy.route({ method: 'GET', diff --git a/src/elm/Pages/Org_/Repo_/Build_/Pipeline.elm b/src/elm/Pages/Org_/Repo_/Build_/Pipeline.elm index d6358ceff..32a18df28 100644 --- a/src/elm/Pages/Org_/Repo_/Build_/Pipeline.elm +++ b/src/elm/Pages/Org_/Repo_/Build_/Pipeline.elm @@ -534,7 +534,10 @@ view shared route model = [ case model.pipeline of RemoteData.Success p -> if List.length p.warnings > 0 then - div [ class "logs-container", class "-pipeline" ] + div + [ class "logs-container" + , class "-pipeline" + ] [ table [ class "logs-table" , class "pipeline" @@ -545,15 +548,15 @@ view shared route model = ] ] , if model.expand then - span [ class "tip" ] + span [ class "tip", Util.testAttribute "pipeline-warnings-expand-note" ] [ small [] [ text "note: this pipeline is expanded, the line numbers shown only apply to the base pipeline configuration, they are not accurate when viewing an expanded pipeline." ] ] else text "" - , div [ class "warnings" ] <| - List.map (viewWarningAsLogLine model shared) <| + , div [ class "warnings", Util.testAttribute "pipeline-warnings" ] <| + List.indexedMap (viewWarningAsLogLine model shared) <| List.sort p.warnings ] ] @@ -739,6 +742,7 @@ viewLine expand shiftKeyDown lineNumber line warnings focus = ] [ td [ class "annotation" + , Util.testAttribute <| String.join "-" [ "warning", "annotation", "line", String.fromInt lineNumber ] , warnings |> Maybe.Extra.filter (\_ -> not expand) |> Maybe.Extra.unwrap (class "-hide") (\_ -> class "-show") @@ -781,13 +785,16 @@ viewLine expand shiftKeyDown lineNumber line warnings focus = {-| viewWarningAsLogLine : renders a warning as a log line. -} -viewWarningAsLogLine : Model -> Shared.Model -> String -> Html Msg -viewWarningAsLogLine model shared warning = +viewWarningAsLogLine : Model -> Shared.Model -> Int -> String -> Html Msg +viewWarningAsLogLine model shared idx warning = let { maybeLineNumber, content } = Warnings.fromString warning in - tr [ class "warning" ] + tr + [ class "warning" + , Util.testAttribute <| String.join "-" [ "warning", String.fromInt idx ] + ] [ td [ class "annotation", class "-show" ] [ Components.Svgs.annotationCircle "-warning" ] @@ -828,7 +835,10 @@ viewWarningAsLogLine model shared warning = [ span [] [ text <| String.fromInt lineNumber ] ] Nothing -> - span [ class "no-line-number" ] [ text "-" ] + span + [ class "no-line-number" + ] + [ text "-" ] ] , td [ class "line-content" ] [ text content