diff --git a/.github/workflows/release-develop.yml b/.github/workflows/release-develop.yml index 71d487e0a3..3c293b1bb8 100644 --- a/.github/workflows/release-develop.yml +++ b/.github/workflows/release-develop.yml @@ -4,7 +4,7 @@ concurrency: release-develop on: push: branches: - - release + - develop paths: - '.aws/**' - '.github/**' @@ -28,11 +28,11 @@ jobs: runs-on: ubuntu-latest steps: - # - name: Fail if branch is not develop - # if: github.ref != 'refs/heads/develop' - # run: | - # echo "Ref is not develop, you must run this job from develop." - # exit 1 + - name: Fail if branch is not develop + if: github.ref != 'refs/heads/develop' + run: | + echo "Ref is not develop, you must run this job from develop." + exit 1 - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: diff --git a/lerna.json b/lerna.json index 080372bc14..90c55ddb69 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.0.206", + "version": "1.0.207-alpha.0", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 03d03729ce..ec8d2a204f 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.0.206", + "version": "1.0.207-alpha.0", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 61710954d8..771bda5ef1 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", - "version": "1.0.206", + "version": "1.0.207-alpha.0", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,7 +38,7 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "^1.2.1", - "@budibase/string-templates": "^1.0.206", + "@budibase/string-templates": "^1.0.207-alpha.0", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/bbui/src/Button/Button.svelte b/packages/bbui/src/Button/Button.svelte index e8f6b4500e..36abcbf4da 100644 --- a/packages/bbui/src/Button/Button.svelte +++ b/packages/bbui/src/Button/Button.svelte @@ -14,6 +14,7 @@ export let active = false export let tooltip = undefined export let dataCy + export let newStyles = false let showTooltip = false @@ -25,6 +26,7 @@ class:spectrum-Button--warning={warning} class:spectrum-Button--overBackground={overBackground} class:spectrum-Button--quiet={quiet} + class:new-styles={newStyles} class:active class="spectrum-Button spectrum-Button--size{size.toUpperCase()}" {disabled} @@ -93,4 +95,20 @@ padding-left: var(--spacing-m); line-height: 0; } + .spectrum-Button--primary.new-styles { + background: var(--spectrum-global-color-gray-800); + border-color: transparent; + color: var(--spectrum-global-color-gray-50); + } + .spectrum-Button--primary.new-styles:hover { + background: var(--spectrum-global-color-gray-900); + } + .spectrum-Button--secondary.new-styles { + background: var(--spectrum-global-color-gray-200); + border-color: transparent; + color: var(--spectrum-global-color-gray-900); + } + .spectrum-Button--secondary.new-styles:hover { + background: var(--spectrum-global-color-gray-300); + } diff --git a/packages/bbui/src/Form/Core/TextField.svelte b/packages/bbui/src/Form/Core/TextField.svelte index 6a64876a2c..0a723c140a 100644 --- a/packages/bbui/src/Form/Core/TextField.svelte +++ b/packages/bbui/src/Form/Core/TextField.svelte @@ -112,4 +112,8 @@ .spectrum-Textfield { width: 100%; } + input:disabled { + color: var(--spectrum-global-color-gray-600) !important; + -webkit-text-fill-color: var(--spectrum-global-color-gray-600) !important; + } diff --git a/packages/builder/cypress/integration/appOverview.spec.js b/packages/builder/cypress/integration/appOverview.spec.js index 090e4e369b..4b9d072338 100644 --- a/packages/builder/cypress/integration/appOverview.spec.js +++ b/packages/builder/cypress/integration/appOverview.spec.js @@ -1,7 +1,7 @@ import filterTests from "../support/filterTests" import clientPackage from "@budibase/client/package.json" -filterTests(['all'], () => { +filterTests(["all"], () => { context("Application Overview screen", () => { before(() => { cy.login() @@ -10,31 +10,19 @@ filterTests(['all'], () => { it("Should be accessible from the applications list", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - - cy.get(".appTable .title").eq(0) - .invoke('attr', 'data-cy') - .then(($dataCy) => { - const dataCy = $dataCy; - cy.get(".appTable .name").eq(0).click() + cy.get(".appTable .title") + .eq(0) + .invoke("attr", "data-cy") + .then($dataCy => { + const dataCy = $dataCy + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .click({ force: true }) - cy.location().should((loc) => { - expect(loc.pathname).to.eq('/builder/portal/overview/' + dataCy) + 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. @@ -43,24 +31,28 @@ filterTests(['all'], () => { cy.get(".appTable .lock-status").eq(0).contains("Locked by you").click() - cy.unlockApp({ owned : true }) + cy.unlockApp({ owned: true }) cy.get(".appTable").should("exist") - cy.get(".lock-status").should('not.be.visible') + 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.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(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) cy.get(".lock-status").eq(0).contains("Locked by you").click() - cy.unlockApp({ owned : true }) + cy.unlockApp({ owned: true }) cy.get(".lock-status").should("not.be.visible") }) @@ -68,107 +60,149 @@ filterTests(['all'], () => { 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(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) + 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-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.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(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) + 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-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", () => { + 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(".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(".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.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(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) 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-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 and colour", () => { + it("Should allow the editing of the application icon and colour", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable", { timeout: 2000}) - .within(() => { - cy.get(".app-row-actions-icon").eq(0).click() - }) + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) + cy.wait(1000) + cy.get(".app-overview-actions-icon").within(() => { + cy.get(".spectrum-Icon").click({ force: true }) + }) cy.get(".spectrum-Menu").contains("Edit icon").click() // Select random icon cy.get(".grid").within(() => { - cy.get(".icon-item").eq(Math.floor(Math.random() * 23) + 1).click() + 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.get(".color") + .eq(Math.floor(Math.random() * 33) + 1) + .click() }) - cy.intercept('**/applications/**').as('iconChange') + 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.get("@iconChange").its("response.statusCode").should("eq", 200) // Confirm icon has changed from default // Confirm colour has been applied - cy.get(".appTable", { timeout: 2000}) - .within(() => { - cy.get('[aria-label]').eq(0).children() - .should('have.attr', 'xlink:href').and('not.contain', '#spectrum-icon-18-Apps') - cy.get(".title").children().children() - .should('have.attr', 'style').and('contains', 'color') - }) + cy.get(".appTable", { timeout: 2000 }).within(() => { + cy.get("[aria-label]") + .eq(0) + .children() + .should("have.attr", "xlink:href") + .and("not.contain", "#spectrum-icon-18-Apps") + cy.get(".title") + .children() + .children() + .should("have.attr", "style") + .and("contains", "color") + }) }) it("Should reflect the last time the application was edited", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() - - cy.get(".header-right button").contains("Edit").click({ force: true }); + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) + cy.get(".header-right button").contains("Edit").click({ force: true }) cy.navigateToFrontend() @@ -177,41 +211,51 @@ filterTests(['all'], () => { }) cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() - + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) cy.get(".overview-tab [data-cy='edited-by']").within(() => { cy.get(".editor-name").contains("You") cy.get(".last-edit-text").contains("Last edited a few seconds ago") }) - }); + }) it("Should reflect application version is up-to-date", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() - + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) cy.get(".overview-tab [data-cy='app-version']").within(() => { cy.get(".version-status").contains("You're running the latest!") }) - }); + }) it("Should navigate to the settings tab when clicking the App Version card header", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() - + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) cy.get(".spectrum-Tabs-item.is-selected").contains("Overview") cy.get(".overview-tab").should("be.visible") - cy.get(".overview-tab [data-cy='app-version'] .dash-card-header").click({ force : true }) + cy.get(".overview-tab [data-cy='app-version'] .dash-card-header").click({ + force: true, + }) cy.get(".spectrum-Tabs-item.is-selected").contains("Settings") cy.get(".settings-tab").should("be.visible") cy.get(".overview-tab").should("not.exist") - - }); + }) it("Should allow the upgrading of an application, if available.", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) cy.wait(500) cy.location().then(loc => { @@ -219,8 +263,7 @@ filterTests(['all'], () => { const appId = params[params.length - 1] cy.log(appId) //Downgrade the app for the test - cy.alterAppVersion(appId, "0.0.1-alpha.0") - .then(()=>{ + cy.alterAppVersion(appId, "0.0.1-alpha.0").then(() => { cy.reload() cy.wait(1000) cy.log("Current deployment version: " + clientPackage.version) @@ -228,115 +271,163 @@ filterTests(['all'], () => { cy.get(".version-status a").contains("Update").click() cy.get(".spectrum-Tabs-item.is-selected").contains("Settings") - cy.get(".version-section .page-action button").contains("Update").click({ force: true }) - - cy.intercept('POST', '**/applications/**/client/update').as('updateVersion') - cy.get(".spectrum-Modal.is-open button").contains("Update").click({ force: true }) + cy.get(".version-section .page-action button") + .contains("Update") + .click({ force: true }) + + cy.intercept("POST", "**/applications/**/client/update").as( + "updateVersion" + ) + cy.get(".spectrum-Modal.is-open button") + .contains("Update") + .click({ force: true }) cy.wait("@updateVersion") - .its('response.statusCode').should('eq', 200) - .then(() => { - cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() - - cy.get(".spectrum-Tabs-item").contains("Overview").click({ force: true }) - cy.get(".overview-tab [data-cy='app-version']").within(() => { - cy.get(".spectrum-Heading").contains(clientPackage.version) - cy.get(".version-status").contains("You're running the latest!") + .its("response.statusCode") + .should("eq", 200) + .then(() => { + cy.visit(`${Cypress.config().baseUrl}/builder`) + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) + cy.get(".spectrum-Tabs-item") + .contains("Overview") + .click({ force: true }) + cy.get(".overview-tab [data-cy='app-version']").within(() => { + cy.get(".spectrum-Heading").contains(clientPackage.version) + cy.get(".version-status").contains("You're running the latest!") + }) }) - }) }) - }); - + }) }) it("Should allow editing of the app details.", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() - + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) cy.get(".spectrum-Tabs-item").contains("Settings").click() cy.get(".spectrum-Tabs-item.is-selected").contains("Settings") cy.get(".settings-tab").should("be.visible") - cy.get(".details-section .page-action button").contains("Edit").click({ force: true }) + cy.get(".details-section .page-action button") + .contains("Edit") + .click({ force: true }) cy.updateAppName("sample name") //publish and check its disabled cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .app-row-actions button").contains("Edit").eq(0).click({force: true}) + 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.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.wait(1000) - cy.get(".appTable .name").eq(0).click() + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) cy.get(".spectrum-Tabs-item").contains("Settings").click() cy.get(".spectrum-Tabs-item.is-selected").contains("Settings") cy.get(".details-section .page-action .spectrum-Button").scrollIntoView() cy.wait(1000) - cy.get(".details-section .page-action .spectrum-Button").should("be.disabled") - + cy.get(".details-section .page-action .spectrum-Button").should( + "be.disabled" + ) }) xit("Should allow copying of the published application Id", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .app-row-actions").eq(0) - .within(() => { - cy.get(".spectrum-Button").contains("Edit").click({ force: true }) - }) + cy.get(".appTable .app-row-actions") + .eq(0) + .within(() => { + cy.get(".spectrum-Button").contains("Edit").click({ force: true }) + }) cy.publishApp("sample-name") cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) + cy.get(".app-overview-actions-icon > .icon").click({ force: true }) - cy.get(".app-overview-actions-icon > .icon").click({ force : true }) + cy.get("[data-cy='app-overview-menu-popover']") + .eq(0) + .within(() => { + cy.get(".spectrum-Menu-item") + .contains("Copy App ID") + .click({ force: true }) + }) - cy.get("[data-cy='app-overview-menu-popover']").eq(0).within(() => { - cy.get(".spectrum-Menu-item").contains("Copy App ID").click({ force: true }) - }) - - cy.get(".spectrum-Toast-content").contains("App ID copied to clipboard.").should("be.visible") + cy.get(".spectrum-Toast-content") + .contains("App ID copied to clipboard.") + .should("be.visible") }) it("Should allow unpublishing of the application", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) + cy.get(".app-overview-actions-icon > .icon").click({ force: true }) - cy.get(".app-overview-actions-icon > .icon").click({ force : true }) + cy.get("[data-cy='app-overview-menu-popover']") + .eq(0) + .within(() => { + cy.get(".spectrum-Menu-item") + .contains("Unpublish") + .click({ force: true }) + cy.wait(500) + }) - cy.get("[data-cy='app-overview-menu-popover']").eq(0).within(() => { - cy.get(".spectrum-Menu-item").contains("Unpublish").click({ force: true }) - cy.wait(500) - }) - - cy.get("[data-cy='unpublish-modal']").should("be.visible") - .within(() => { - cy.get(".confirm-wrap button").click({ force: true } - )}) + cy.get("[data-cy='unpublish-modal']") + .should("be.visible") + .within(() => { + cy.get(".confirm-wrap button").click({ force: true }) + }) 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-display .icon svg[aria-label='GlobeStrike']").should( + "exist" + ) }) }) it("Should allow deleting of the application", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.get(".appTable .name").eq(0).click() + cy.get(".appTable .app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) + cy.get(".app-overview-actions-icon > .icon").click({ force: true }) - cy.get(".app-overview-actions-icon > .icon").click({ force : true }) - - cy.get("[data-cy='app-overview-menu-popover']").eq(0).within(() => { - cy.get(".spectrum-Menu-item").contains("Delete").click({ force: true }) - cy.wait(500) - }) + cy.get("[data-cy='app-overview-menu-popover']") + .eq(0) + .within(() => { + cy.get(".spectrum-Menu-item") + .contains("Delete") + .click({ force: true }) + cy.wait(500) + }) //The test application was renamed earlier in the spec cy.get(".spectrum-Dialog-grid").within(() => { @@ -344,18 +435,17 @@ filterTests(['all'], () => { cy.get(".spectrum-Button--warning").click() }) - cy.location().should((loc) => { - expect(loc.pathname).to.eq('/builder/portal/apps') + cy.location().should(loc => { + expect(loc.pathname).to.eq("/builder/portal/apps") }) cy.get(".appTable").should("not.exist") - + cy.get(".welcome .container h1").contains("Let's create your first app!") }) after(() => { cy.deleteAllApps() }) - }) }) diff --git a/packages/builder/cypress/integration/createComponents.spec.js b/packages/builder/cypress/integration/createComponents.spec.js index 47063fb026..eff7fc216f 100644 --- a/packages/builder/cypress/integration/createComponents.spec.js +++ b/packages/builder/cypress/integration/createComponents.spec.js @@ -1,7 +1,7 @@ import filterTests from "../support/filterTests" -const interact = require('../support/interact') +const interact = require("../support/interact") -filterTests(['all'], () => { +filterTests(["all"], () => { context("Create Components", () => { let headlineId @@ -19,17 +19,15 @@ filterTests(['all'], () => { //Use the tree to delete a selected component const deleteSelectedComponent = () => { - cy.get(".nav-items-container .nav-item.selected .actions > div > .icon").click({ + cy.get( + ".nav-items-container .nav-item.selected .actions > div > .icon" + ).click({ + force: true, + }) + cy.get(".spectrum-Popover.is-open li").contains("Delete").click() + cy.get(".spectrum-Modal button").contains("Delete Component").click({ force: true, }) - cy.get(".spectrum-Popover.is-open li") - .contains("Delete") - .click() - cy.get(".spectrum-Modal button") - .contains("Delete Component") - .click({ - force: true, - }) } it("should add a container", () => { @@ -47,18 +45,18 @@ filterTests(['all'], () => { it("should change the text of the headline", () => { const text = "Lorem ipsum dolor sit amet." - cy.get("[data-cy=setting-text] input") - .type(text) - .blur() + cy.get("[data-cy=setting-text] input").type(text).blur() cy.getComponent(headlineId).should("have.text", text) }) it("should change the size of the headline", () => { cy.get("[data-cy=setting-size]").scrollIntoView().click() cy.get("[data-cy=setting-size]").within(() => { - cy.get(".spectrum-Form-item li.spectrum-Menu-item").contains("3XL").click() + cy.get(".spectrum-Form-item li.spectrum-Menu-item") + .contains("3XL") + .click() }) - + cy.getComponent(headlineId).within(() => { cy.get(".spectrum-Heading").should("have.css", "font-size", "60px") }) @@ -66,13 +64,9 @@ filterTests(['all'], () => { it("should create a form and reset to match schema", () => { cy.addComponent("Form", "Form").then(() => { - cy.get("[data-cy=setting-dataSource]") - .contains("Custom") - .click() - cy.get(interact.DROPDOWN) - .contains("dog") - .click() - cy.wait(500) + cy.get("[data-cy=setting-dataSource]").contains("Custom").click() + cy.get(interact.DROPDOWN).contains("dog").click() + cy.wait(500) cy.addComponent("Form", "Field Group").then(fieldGroupId => { cy.contains("Update form fields").click() cy.get(".spectrum-Modal") @@ -83,11 +77,9 @@ filterTests(['all'], () => { cy.contains("name").should("exist") cy.contains("age").should("exist") cy.contains("breed").should("exist") - // cy.contains("image").should("exist") + // cy.contains("image").should("exist") }) - cy.getComponent(fieldGroupId) - .find("input") - .should("have.length", 2) + cy.getComponent(fieldGroupId).find("input").should("have.length", 2) cy.getComponent(fieldGroupId) .find(interact.SPECTRUM_PICKER) .should("have.length", 1) @@ -97,191 +89,102 @@ filterTests(['all'], () => { it("deletes a component", () => { cy.addComponent("Elements", "Paragraph").then(componentId => { - cy.get("[data-cy=setting-_instanceName] input") - .type(componentId) - .blur() - cy.get(".nav-items-container .nav-item.selected .actions > div > .icon").click({ + cy.get("[data-cy=setting-_instanceName] input").type(componentId).blur() + cy.get( + ".nav-items-container .nav-item.selected .actions > div > .icon" + ).click({ + force: true, + }) + cy.get(".spectrum-Popover.is-open li").contains("Delete").click() + cy.get(".spectrum-Modal button").contains("Delete Component").click({ force: true, }) - cy.get(".spectrum-Popover.is-open li") - .contains("Delete") - .click() - cy.get(".spectrum-Modal button") - .contains("Delete Component") - .click({ - force: true, - }) cy.getComponent(componentId).should("not.exist") }) }) - it("should set focus to the field setting when fields are added to a form", () => { - cy.addComponent("Form", "Form").then((formId) => { - - //For deletion - cy.get("[data-cy=setting-_instanceName] input") - .clear() - .type(formId) - .blur() - - const componentTypeLabels = ["Text Field", "Number Field", "Password Field", - "Options Picker", "Checkbox", "Long Form Field", "Date Picker", "Attachment", - "JSON Field", "Multi-select Picker", "Relationship Picker"] - - const refocusTest = (componentId) => { - cy.getComponent(componentId) - .find(".showMe").should("exist").click({ force: true }) - - cy.get("[data-cy=setting-field] .spectrum-InputGroup") - .should("have.class", "is-focused") - } - - const testFieldFocusOnCreate = (componentLabel) => { - cy.log("Adding: " + componentLabel) - return cy.addComponent("Form", componentLabel).then((componentId) => { - - refocusTest(componentId) - - cy.get("[data-cy=setting-field] .spectrum-InputGroup") - .should("have.class", "is-focused") - }) - } - - cy.wait(1000) - cy.wrap(componentTypeLabels).each((label) => { - return testFieldFocusOnCreate(label) - }).then(()=>{ - cy.get(".nav-items-container .nav-item").contains(formId).click({ force: true }) - deleteSelectedComponent() - }) - }) - }) - it("should clear the iframe place holder when a form field has been set", () => { - cy.addComponent("Form", "Form").then((formId) => { - + cy.addComponent("Form", "Form").then(formId => { //For deletion cy.get("[data-cy=setting-_instanceName] input") .clear() .type(formId) .blur() - - cy.get("[data-cy=setting-dataSource]") - .contains("Custom") - .click() - cy.get(".dropdown") - .contains("dog") - .click() + cy.get("[data-cy=setting-dataSource]").contains("Custom").click() + cy.get(".dropdown").contains("dog").click() const fieldTypeToColumnName = { - "Text Field" : "name", - "Number Field": "age", - "Options Picker": "breed" + "Text Field": "name", + "Number Field": "age", + "Options Picker": "breed", } const componentTypeLabels = Object.keys(fieldTypeToColumnName) - const testFieldFocusOnCreate = (componentLabel) => { + const testFieldFocusOnCreate = componentLabel => { cy.log("Adding: " + componentLabel) - return cy.addComponent("Form", componentLabel).then((componentId) => { - + return cy.addComponent("Form", componentLabel).then(componentId => { cy.getComponent(componentId) - .find(".placeholder_wrap").should("exist") - - cy.get("[data-cy=setting-field] .spectrum-InputGroup") - .should("have.class", "is-focused") - + .find(".component-placeholder") + .should("exist") cy.get("[data-cy=setting-field] button.spectrum-Picker").click() //Click the first appropriate field. They are filtered by type - cy.get("[data-cy=setting-field] .spectrum-Popover.is-open li.spectrum-Menu-item") - .contains(fieldTypeToColumnName[componentLabel]).click() + cy.get( + "[data-cy=setting-field] .spectrum-Popover.is-open li.spectrum-Menu-item" + ) + .contains(fieldTypeToColumnName[componentLabel]) + .click() cy.wait(500) cy.getComponent(componentId) - .find(".placeholder_wrap").should("not.exist") + .find(".component-placeholder") + .should("not.exist") }) } - + cy.wait(500) - cy.wrap(componentTypeLabels).each((label) => { - return testFieldFocusOnCreate(label) - }).then(()=>{ - cy.get(".nav-items-container .nav-item").contains(formId).click({ force: true }) - deleteSelectedComponent() - }) - }) - }) - - it("should focus a charts settings on data provider if not nested in provider ", () => { - cy.addComponent("Layout", "Container").then((containerId) => { - - //For deletion - cy.get("[data-cy=setting-_instanceName] input") - .clear() - .type(containerId) - .blur() - - const chartTypeLabels = ["Bar Chart", "Line Chart", "Area Chart", "Pie Chart", - "Donut Chart", "Candlestick Chart"] - - const refocusTest = (componentId) => { - cy.getComponent(componentId) - .find(".showMe").should("exist").click({ force: true }) - - cy.get("[data-cy=dataProvider-prop-control] .spectrum-Picker") - .should("have.class", "is-focused") - } - - const testFocusOnCreate = (chartLabel) => { - cy.log("Adding: " + chartLabel) - cy.addComponent("Chart", chartLabel).then((componentId) => { - refocusTest(componentId) - - cy.get("[data-cy=dataProvider-prop-control] .spectrum-Picker") - .should("have.class", "is-focused") + cy.wrap(componentTypeLabels) + .each(label => { + return testFieldFocusOnCreate(label) + }) + .then(() => { + cy.get(".nav-items-container .nav-item") + .contains(formId) + .click({ force: true }) + deleteSelectedComponent() }) - } - - cy.wait(1000) - cy.wrap(chartTypeLabels).each((label) => { - return testFocusOnCreate(label) - }) - .then(()=>{ - cy.get(".nav-items-container .nav-item").contains(containerId).click({ force: true }) - deleteSelectedComponent() - }) - }) - }) it("should populate the provider for charts with a data provider in its path", () => { - cy.addComponent("Data", "Data Provider").then((providerId) => { - + cy.addComponent("Data", "Data Provider").then(providerId => { //For deletion cy.get("[data-cy=setting-_instanceName] input") .clear() .type(providerId) .blur() - - cy.get("[data-cy=setting-dataSource]") .contains("Choose an option") .click() - cy.get(`[data-cy=dataSource-popover-${providerId}] ul li`) .contains("dog") .click() - const chartTypeLabels = ["Bar Chart", "Line Chart", "Area Chart", "Pie Chart", - "Donut Chart", "Candlestick Chart"] + const chartTypeLabels = [ + "Bar Chart", + "Line Chart", + "Area Chart", + "Pie Chart", + "Donut Chart", + "Candlestick Chart", + ] - const testFocusOnCreate = (chartLabel) => { + const testFocusOnCreate = chartLabel => { cy.log("Adding: " + chartLabel) - cy.addComponent("Chart", chartLabel).then((componentId) => { - - cy.get("[data-cy=dataProvider-prop-control] .spectrum-Picker") - .should("not.have.class", "is-focused") + cy.addComponent("Chart", chartLabel).then(componentId => { + cy.get( + "[data-cy=dataProvider-prop-control] .spectrum-Picker" + ).should("not.have.class", "is-focused") // Pre populated. cy.get("[data-cy=dataProvider-prop-control] .spectrum-Picker-label") @@ -289,114 +192,86 @@ filterTests(['all'], () => { .should("exist") }) } - cy.wait(1000) - cy.wrap(chartTypeLabels).each((label) => { - return testFocusOnCreate(label) - }) - .then(()=>{ - cy.get(".nav-items-container .nav-item").contains(providerId).click({ force: true }) - deleteSelectedComponent() - }) + cy.wrap(chartTypeLabels) + .each(label => { + return testFocusOnCreate(label) + }) + .then(() => { + cy.get(".nav-items-container .nav-item") + .contains(providerId) + .click({ force: true }) + deleteSelectedComponent() + }) }) - }) it("should replace the placeholder when a url is set on an image", () => { - cy.addComponent("Elements", "Image").then((imageId) => { - - cy.get("[data-cy=url-prop-control] .spectrum-InputGroup") - .should("have.class", "is-focused") - + cy.addComponent("Elements", "Image").then(imageId => { cy.get("[data-cy=setting-_instanceName] input") .clear() .type(imageId) .blur() - //return $("New Data Provider.Rows")[0]["Attachment"][0]["url"] //No minio, so just enter something local that will not reslove cy.get("[data-cy=url-prop-control] input[type=text]") .type("cypress/fixtures/ghost.png") .blur() - cy.getComponent(imageId) - .find(".placeholder_wrap").should("not.exist") - - cy.getComponent(imageId) - .find(`img[alt=${imageId}]`).should("exist") - + .find(".component-placeholder") + .should("not.exist") + cy.getComponent(imageId).find(`img[alt=${imageId}]`).should("exist") cy.get(".nav-items-container .nav-item") .contains(imageId) .click({ force: true }) - deleteSelectedComponent() }) }) it("should add a markdown component.", () => { - cy.addComponent("Elements", "Markdown Viewer").then((markdownId) => { - - cy.get("[data-cy=value-prop-control] .spectrum-InputGroup") - .should("have.class", "is-focused") - + cy.addComponent("Elements", "Markdown Viewer").then(markdownId => { cy.get("[data-cy=setting-_instanceName] input") .clear() .type(markdownId) .blur() - - cy.get("[data-cy=value-prop-control] input[type=text].spectrum-Textfield-input") - .type("# Hi").blur() - + cy.get( + "[data-cy=value-prop-control] input[type=text].spectrum-Textfield-input" + ) + .type("# Hi") + .blur() cy.getComponent(markdownId) - .find(".placeholder_wrap").should("not.exist") - + .find(".component-placeholder") + .should("not.exist") cy.getComponent(markdownId) - .find(".editor-preview-full h1").contains("Hi") - + .find(".editor-preview-full h1") + .contains("Hi") cy.get(".nav-items-container .nav-item") .contains(markdownId) .click({ force: true }) - deleteSelectedComponent() }) }) it("should direct the user when adding an Icon component.", () => { - cy.addComponent("Elements", "Icon").then((iconId) => { - - cy.get("[data-cy=icon-prop-control] .spectrum-ActionButton") - .should("have.class", "is-focused") - - cy.getComponent(iconId) - .find(".placeholder_wrap").should("exist") - + cy.addComponent("Elements", "Icon").then(iconId => { + cy.getComponent(iconId).find(".component-placeholder").should("exist") cy.get("[data-cy=setting-_instanceName] input") .clear() .type(iconId) .blur() - cy.get("[data-cy=icon-prop-control] .spectrum-ActionButton").click() - cy.get("[data-cy=icon-popover].spectrum-Popover.is-open").within(() => { - cy.get(".search-input input") - .type("save") - .blur() - + cy.get(".search-input input").type("save").blur() cy.get(".search-input button").click({ force: true }) - cy.get(".icon-area .icon-container").eq(0).click({ force: true }) }) - cy.getComponent(iconId) - .find(".placeholder_wrap").should("not.exist") - - cy.getComponent(iconId) - .find("i.ri-save-fill").should("exist") - + .find(".component-placeholder") + .should("not.exist") + cy.getComponent(iconId).find("i.ri-save-fill").should("exist") cy.get(".nav-items-container .nav-item") .contains(iconId) .click({ force: true }) - deleteSelectedComponent() }) }) diff --git a/packages/builder/cypress/integration/renameAnApplication.spec.js b/packages/builder/cypress/integration/renameAnApplication.spec.js index 70c9dd4914..703535a507 100644 --- a/packages/builder/cypress/integration/renameAnApplication.spec.js +++ b/packages/builder/cypress/integration/renameAnApplication.spec.js @@ -1,7 +1,7 @@ import filterTests from "../support/filterTests" -const interact = require('../support/interact') +const interact = require("../support/interact") -filterTests(['all'], () => { +filterTests(["all"], () => { context("Rename an App", () => { beforeEach(() => { cy.login() @@ -32,12 +32,15 @@ filterTests(['all'], () => { const appRename = "Cypress Renamed" // Publish the app cy.get(interact.TOP_RIGHT_NAV) - cy.get(interact.SPECTRUM_BUTTON).contains("Publish").click({ force: true }) - cy.get(interact.SPECTRUM_DIALOG_GRID) - .within(() => { - // Click publish again within the modal - cy.get(interact.SPECTRUM_BUTTON).contains("Publish").click({ force: true }) - }) + cy.get(interact.SPECTRUM_BUTTON) + .contains("Publish") + .click({ force: true }) + cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => { + // Click publish again within the modal + cy.get(interact.SPECTRUM_BUTTON) + .contains("Publish") + .click({ force: true }) + }) // Rename app, Search for app, Confirm name was changed cy.visit(`${Cypress.config().baseUrl}/builder`) cy.wait(500) @@ -64,14 +67,20 @@ filterTests(['all'], () => { const appName = "Cypress Tests" cy.visit(`${Cypress.config().baseUrl}/builder`) cy.wait(500) - cy.get(interact.SPECTRUM_BUTTON).contains("Create app").click({ force: true }) + cy.get(interact.SPECTRUM_BUTTON) + .contains("Create app") + .click({ force: true }) cy.contains(/Start from scratch/).click() - cy.get(interact.SPECTRUM_MODAL) - .within(() => { - cy.get("input").eq(0).type(appName) - cy.get(interact.SPECTRUM_BUTTON_GROUP).contains("Create app").click({ force: true }) - cy.get(interact.ERROR).should("have.text", "Another app with the same name already exists") - }) + cy.get(interact.SPECTRUM_MODAL).within(() => { + cy.get("input").eq(0).type(appName) + cy.get(interact.SPECTRUM_BUTTON_GROUP) + .contains("Create app") + .click({ force: true }) + cy.get(interact.ERROR).should( + "have.text", + "Another app with the same name already exists" + ) + }) }) it("should validate application names", () => { @@ -89,7 +98,10 @@ filterTests(['all'], () => { cy.reload() cy.wait(1000) renameApp(numberName, specialCharName) - cy.get(interact.ERROR).should("have.text", "App name must be letters, numbers and spaces only") + cy.get(interact.ERROR).should( + "have.text", + "App name must be letters, numbers and spaces only" + ) // Set app name back to Cypress Tests cy.reload() cy.wait(1000) @@ -98,24 +110,19 @@ filterTests(['all'], () => { const renameApp = (originalName, changedName, published, noName) => { cy.searchForApplication(originalName) - cy.get(interact.APP_TABLE) - .within(() => { - cy.get(interact.AREA_LABEL_MORE).eq(0).click() - }) - // Check for when an app is published - if (published == true) { - // Should not have Edit as option, will unpublish app - cy.should("not.have.value", "Edit") - cy.get(interact.SPECTRUM_MENU).contains("Unpublish").click() - cy.get(interact.SPECTRUM_DIALOG_GRID).contains("Unpublish app").click() - cy.get(".appTable > :nth-child(5) > :nth-child(2) > .spectrum-Icon").click() - } - cy.get(interact.APP_ROW_ACTION_MENU_POPOVER).eq(0).within(() => { - cy.get(interact.SPECTRUM_MENU_ITEMM).contains("Edit").click({ force: true }) + cy.get(interact.APP_TABLE).within(() => { + cy.get(".app-row-actions button") + .contains("Manage") + .eq(0) + .click({ force: true }) }) - + cy.get(".spectrum-Tabs-item").contains("Settings").click() + cy.get(".spectrum-Tabs-item.is-selected").contains("Settings") + cy.get(".settings-tab").should("be.visible") + cy.get(".details-section .page-action button") + .contains("Edit") + .click({ force: true }) cy.updateAppName(changedName, noName) - } }) }) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index ba820526f0..e638eb6cbb 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -144,20 +144,27 @@ Cypress.Commands.add("deleteApp", name => { return } + // Go to app overview const appIdParsed = appId.split("_").pop() const actionEleId = `[data-cy=row_actions_${appIdParsed}]` cy.get(actionEleId).within(() => { - cy.get(".spectrum-Icon").eq(0).click({ force: true }) + cy.contains("Manage").click({ force: true }) }) - cy.get(".spectrum-Menu").then($menu => { - if ($menu.text().includes("Unpublish")) { - cy.get(".spectrum-Menu").contains("Unpublish").click() - cy.get(".spectrum-Dialog-grid").contains("Unpublish app").click() + cy.wait(1000) + + // Unpublish first if needed + cy.get(`[data-cy="app-status"]`).then($status => { + if ($status.text().includes("Last published")) { + cy.contains("Unpublish").click() + cy.get(".spectrum-Modal").within(() => { + cy.contains("Unpublish app").click() + }) } }) - cy.get(actionEleId).within(() => { - cy.get(".spectrum-Icon").eq(0).click({ force: true }) + // Delete app + cy.get(".app-overview-actions-icon").within(() => { + cy.get(".spectrum-Icon").click({ force: true }) }) cy.get(".spectrum-Menu").contains("Delete").click() cy.get(".spectrum-Dialog-grid").within(() => { @@ -180,17 +187,7 @@ Cypress.Commands.add("deleteAllApps", () => { .its("body") .then(val => { for (let i = 0; i < val.length; i++) { - const appIdParsed = val[i].appId.split("_").pop() - const actionEleId = `[data-cy=row_actions_${appIdParsed}]` - cy.get(actionEleId).within(() => { - cy.get(".spectrum-Icon").eq(0).click({ force: true }) - }) - - cy.get(".spectrum-Menu").contains("Delete").click() - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get("input").type(val[i].name) - cy.get(".spectrum-Button--warning").click() - }) + cy.deleteApp(val[i].name) cy.reload() } }) diff --git a/packages/builder/package.json b/packages/builder/package.json index 5a08d88de0..bc2a3feba9 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "1.0.206", + "version": "1.0.207-alpha.0", "license": "GPL-3.0", "private": true, "scripts": { @@ -69,10 +69,10 @@ } }, "dependencies": { - "@budibase/bbui": "^1.0.206", - "@budibase/client": "^1.0.206", - "@budibase/frontend-core": "^1.0.206", - "@budibase/string-templates": "^1.0.206", + "@budibase/bbui": "^1.0.207-alpha.0", + "@budibase/client": "^1.0.207-alpha.0", + "@budibase/frontend-core": "^1.0.207-alpha.0", + "@budibase/string-templates": "^1.0.207-alpha.0", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/components/common/AppLockModal.svelte b/packages/builder/src/components/common/AppLockModal.svelte index 75e2b15925..5ca35f05db 100644 --- a/packages/builder/src/components/common/AppLockModal.svelte +++ b/packages/builder/src/components/common/AppLockModal.svelte @@ -87,7 +87,7 @@ {#if lockedByYou && getExpiryDuration(app) > 0} {processStringSync( - "This lock will expire in {{ duration time 'millisecond' }} from now", + "This lock will expire in {{ duration time 'millisecond' }} from now.", { time: getExpiryDuration(app), } @@ -141,4 +141,8 @@ gap: var(--spacing-s); max-width: 175px; } + .lock-status-text { + font-weight: 400; + color: var(--spectrum-global-color-gray-800); + } diff --git a/packages/builder/src/components/start/AppRow.svelte b/packages/builder/src/components/start/AppRow.svelte index d30b8079d7..49f99c9f77 100644 --- a/packages/builder/src/components/start/AppRow.svelte +++ b/packages/builder/src/components/start/AppRow.svelte @@ -1,18 +1,11 @@
@@ -20,7 +13,7 @@
-
appOverview(app)}> +
editApp(app)}> {app.name} @@ -37,7 +30,7 @@ {/if}
- +
@@ -52,47 +45,27 @@
+ -
- - - - - {#if app.lockedYou} - releaseLock(app)} icon="LockOpen"> - Release lock - - {/if} - exportApp(app)} icon="Download">Export - {#if app.deployed} - unpublishApp(app)} icon="GlobeRemove"> - Unpublish - - copyAppId(app)} icon="Copy"> - Copy App ID - - {/if} - {#if !app.deployed} - updateApp(app)} icon="Edit">Edit - deleteApp(app)} icon="Delete">Delete - {/if} - editIcon(app)} icon="Brush">Edit icon -