From 044d52edb4d9bf344e32e5ab62101b7bff703764 Mon Sep 17 00:00:00 2001 From: Dean Date: Tue, 10 May 2022 16:58:55 +0100 Subject: [PATCH] Cypress tests for the overview tab --- .../cypress/integration/appOverview.spec.js | 215 ++++++++++++++++++ packages/builder/cypress/support/commands.js | 62 +++++ .../src/components/common/AppLockModal.svelte | 14 +- .../src/components/common/DashCard.svelte | 3 +- .../src/components/start/AppRow.svelte | 2 +- .../overview/[application]/index.svelte | 5 +- .../overview/_components/OverviewTab.svelte | 7 +- 7 files changed, 297 insertions(+), 11 deletions(-) create mode 100644 packages/builder/cypress/integration/appOverview.spec.js diff --git a/packages/builder/cypress/integration/appOverview.spec.js b/packages/builder/cypress/integration/appOverview.spec.js new file mode 100644 index 0000000000..893386385e --- /dev/null +++ b/packages/builder/cypress/integration/appOverview.spec.js @@ -0,0 +1,215 @@ +import filterTests from "../support/filterTests" + +filterTests(['all'], () => { + context("Application Overview screen", () => { + before(() => { + cy.login() + cy.createTestApp() + }) + + /* + The ability to switch accounts will deffo be necessary + + x APP Screen + Click on app name + Click on edit + + x Edit Icon Functionality + + Lock button display and behaviour + + Edit button status and behaviour + + ** To ratifying alot of this stuff will require the app itself + cy.visit(`${Cypress.config().baseUrl}/builder`) + cy.wait(2000) + cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`) + .its("body") + .then(val => { + const findAppName = val.some(val => val.name == name) + if (findAppName) { + + Publish Card + x Never published + Unpublished + Should show the last valid publish date + x Published + Should show the valid publish date + Edit Card + D or DH or the first letter of their email. + Timestamp vaguely matches. + Version Card + How to get use cases? Available/Unavailable? + + Settings Tab + Edit Url + Edit Name + + Versioning? + + Tab behaviour + Click all 3 main tabs. + Check positioning. + Dashcard behaviour. Concentrate on the App version + Header behaviour on click + Quick link behaviour + + Locking behaviour + Button contents, D or DH or the first letter of their email. + Locked by you + Locked by someone else + + Timeout check. Apps > edit > back > app title + "This lock will expire in 10 minutes from now" + */ + + it("Should be accessible from the applications list", () => { + cy.visit(`${Cypress.config().baseUrl}/builder`) + + // Reusable command? toAppOverview + cy.get(".appTable .title").eq(0) + .invoke('attr', 'data-cy') + .then(($dataCy) => { + const dataCy = $dataCy; + cy.get(".appTable .name").eq(0).click() + + cy.location().should((loc) => { + expect(loc.pathname).to.eq('/builder/portal/overview/' + dataCy) + }) + }) + + cy.visit(`${Cypress.config().baseUrl}/builder`) + + cy.get(".appTable .title").eq(0) + .invoke('attr', 'data-cy') + .then(($dataCy) => { + const dataCy = $dataCy; + cy.get(".appTable .app-row-actions button").contains("View").click({force: true}) + + cy.location().should((loc) => { + expect(loc.pathname).to.eq('/builder/portal/overview/' + dataCy) + }) + }) + + }) + + // Find a more suitable place for this. + it("Should allow unlocking in the app list", () => { + cy.visit(`${Cypress.config().baseUrl}/builder`) + + cy.get(".appTable .lock-status").eq(0).contains("Locked by you").click() + + cy.unlockApp({ owned : true }) + + cy.get(".appTable").should("exist") + cy.get(".lock-status").should('not.be.visible') + }) + + it("Should allow unlocking in the app overview screen", () => { + cy.visit(`${Cypress.config().baseUrl}/builder`) + + cy.get(".appTable .app-row-actions button").contains("Edit").eq(0).click({force: true}) + cy.wait(1000) + cy.visit(`${Cypress.config().baseUrl}/builder`) + + cy.get(".appTable .name").eq(0).click() + + cy.get(".lock-status").eq(0).contains("Locked by you").click() + + cy.unlockApp({ owned : true }) + + cy.get(".lock-status").should("not.be.visible") + }) + + it("Should reflect the deploy state of an app that hasn't been published.", () => { + cy.visit(`${Cypress.config().baseUrl}/builder`) + + cy.get(".appTable .name").eq(0).click() + + cy.get(".header-right button.spectrum-Button[data-cy='view-app']").should("be.disabled") + + cy.get(".spectrum-Tabs-item.is-selected").contains("Overview") + cy.get(".overview-tab").should("be.visible") + + cy.get(".overview-tab [data-cy='app-status']").within(() => { + cy.get(".status-display").contains("Unpublished") + cy.get(".status-display .icon svg[aria-label='GlobeStrike']").should("exist") + cy.get(".status-text").contains("-") + }) + }) + + it("Should reflect the app deployment state", () => { + cy.visit(`${Cypress.config().baseUrl}/builder`) + cy.get(".appTable .app-row-actions button").contains("Edit").eq(0).click({force: true}) + + cy.get(".toprightnav button.spectrum-Button").contains("Publish").click({ force : true }) + cy.get(".spectrum-Modal [data-cy='deploy-app-modal']").should("be.visible") + .within(() => { + cy.get(".spectrum-Button").contains("Publish").click({ force : true }) + cy.wait(1000) + }); + + cy.visit(`${Cypress.config().baseUrl}/builder`) + cy.get(".appTable .name").eq(0).click() + + cy.get(".header-right button.spectrum-Button[data-cy='view-app']").should("not.be.disabled") + + cy.get(".overview-tab [data-cy='app-status']").within(() => { + cy.get(".status-display").contains("Published") + cy.get(".status-display .icon svg[aria-label='GlobeCheck']").should("exist") + cy.get(".status-text").contains("Last published a few seconds ago") + }) + }) + + it("Should reflect an application that has been unpublished", () => { + cy.visit(`${Cypress.config().baseUrl}/builder`) + cy.get(".appTable .app-row-actions button").contains("Edit").eq(0).click({force: true}) + + cy.get(".deployment-top-nav svg[aria-label='Globe']") + .click({ force: true }) + + cy.get("[data-cy='publish-popover-menu']").should("be.visible") + cy.get("[data-cy='publish-popover-menu'] [data-cy='publish-popover-action']") + .click({ force : true }) + + cy.get("[data-cy='unpublish-modal']").should("be.visible") + .within(() => { + cy.get(".confirm-wrap button").click({ force: true } + )}) + cy.wait(1000) + + cy.visit(`${Cypress.config().baseUrl}/builder`) + cy.get(".appTable .name").eq(0).click() + + cy.get(".overview-tab [data-cy='app-status']").within(() => { + cy.get(".status-display").contains("Unpublished") + cy.get(".status-display .icon svg[aria-label='GlobeStrike']").should("exist") + cy.get(".status-text").contains("Last published a few seconds ago") + }) + }) + + it("Should allow the editing of the application icon", () => { + cy.visit(`${Cypress.config().baseUrl}/builder`) + + cy.get(".appTable .name").eq(0).click() + + cy.get(".app-logo .edit-hover").should("exist").invoke("show").click() + + cy.customiseAppIcon() + + cy.get(".app-logo") + .within(() => { + cy.get('[aria-label]').eq(0).children() + .should('have.attr', 'xlink:href').and('not.contain', '#spectrum-icon-18-Apps') + cy.get(".app-icon") + .should('have.attr', 'style').and('contains', 'color') + }) + }) + + it("Should log out.", () => { + //You + //Last edited a few seconds ago. + cy.logOut(); + }) + }) +}) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index ce1fe2ec50..c37bd0ffd0 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -32,6 +32,18 @@ Cypress.Commands.add("login", () => { }) }) +Cypress.Commands.add("basicOnboardAppUser", () => { + cy.createUser("another@budibase.com") +}) + +// log out. +// Cypress.Commands.add("logOut", () => { +// cy.visit(`${Cypress.config().baseUrl}/builder`) +// cy.get(".user-dropdown .avatar > .icon").click({ force: true }) + +// cy.wait(2000) +// }) + Cypress.Commands.add("closeModal", () => { cy.get(".spectrum-Modal").within(() => { cy.get(".close-icon").click() @@ -141,6 +153,56 @@ Cypress.Commands.add("deleteAllApps", () => { }) }) +Cypress.Commands.add("customiseAppIcon", () => { + // Select random icon + cy.get(".grid").within(() => { + cy.get(".icon-item") + .eq(Math.floor(Math.random() * 23) + 1) + .click() + }) + // Select random colour + cy.get(".fill").click() + cy.get(".colors").within(() => { + cy.get(".color") + .eq(Math.floor(Math.random() * 33) + 1) + .click() + }) + cy.intercept("**/applications/**").as("iconChange") + cy.get(".spectrum-Button").contains("Save").click({ force: true }) + cy.wait("@iconChange") + cy.get("@iconChange").its("response.statusCode").should("eq", 200) + cy.wait(1000) +}) + +Cypress.Commands.add("unlockApp", unlock_config => { + let config = { ...unlock_config } + + cy.get(".spectrum-Modal .spectrum-Dialog[data-cy='app-lock-modal']") + .should("be.visible") + .within(() => { + if (config.owned) { + cy.get(".spectrum-Dialog-heading").contains("Locked by you") + cy.get(".lock-expiry-body").contains( + "This lock will expire in 10 minutes from now" + ) + + cy.intercept("**/lock").as("unlockApp") + cy.get(".spectrum-Button") + .contains("Release Lock") + .click({ force: true }) + cy.wait("@unlockApp") + cy.get("@unlockApp").its("response.statusCode").should("eq", 200) + cy.get("@unlockApp").its("response.body").should("deep.equal", { + message: "Lock released successfully.", + }) + } else { + //Show the name ? + cy.get(".lock-expiry-body").should("not.be.visible") + cy.get(".spectrum-Button").contains("Done") + } + }) +}) + Cypress.Commands.add("createTestApp", () => { const appName = "Cypress Tests" cy.deleteApp(appName) diff --git a/packages/builder/src/components/common/AppLockModal.svelte b/packages/builder/src/components/common/AppLockModal.svelte index 931999ca95..a30d1c6698 100644 --- a/packages/builder/src/components/common/AppLockModal.svelte +++ b/packages/builder/src/components/common/AppLockModal.svelte @@ -87,12 +87,14 @@

{#if lockedByYou && lockExpiry > 0} - {processStringSync( - "This lock will expire in {{ duration time 'millisecond' }} from now", - { - time: lockExpiry, - } - )} + + {processStringSync( + "This lock will expire in {{ duration time 'millisecond' }} from now", + { + time: lockExpiry, + } + )} + {/if}
diff --git a/packages/builder/src/components/common/DashCard.svelte b/packages/builder/src/components/common/DashCard.svelte index c6d52489f6..1d7ea9120a 100644 --- a/packages/builder/src/components/common/DashCard.svelte +++ b/packages/builder/src/components/common/DashCard.svelte @@ -4,11 +4,12 @@ export let title = "" export let actionIcon export let action + export let dataCy $: actionDefined = typeof action === "function" -
+
{ diff --git a/packages/builder/src/components/start/AppRow.svelte b/packages/builder/src/components/start/AppRow.svelte index b329b7a84e..f197c76fdd 100644 --- a/packages/builder/src/components/start/AppRow.svelte +++ b/packages/builder/src/components/start/AppRow.svelte @@ -14,7 +14,7 @@ export let editIcon -
+
diff --git a/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte b/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte index 4159343d37..3dfc761a43 100644 --- a/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte +++ b/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte @@ -176,8 +176,11 @@ secondary icon="Globe" disabled={!isPublished} - on:click={viewApp}>View app + View app +