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
+