diff --git a/lerna.json b/lerna.json index 8b97445531..f17777f8ec 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.0.74-alpha.2", + "version": "1.0.76-alpha.1", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 987f787e7f..8992be0841 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.0.74-alpha.2", + "version": "1.0.76-alpha.1", "description": "Budibase backend core libraries used in server and worker", "main": "src/index.js", "author": "Budibase", diff --git a/packages/backend-core/src/migrations/index.js b/packages/backend-core/src/migrations/index.js index 4d59f1925d..db0fe6b8ce 100644 --- a/packages/backend-core/src/migrations/index.js +++ b/packages/backend-core/src/migrations/index.js @@ -36,7 +36,7 @@ const runMigration = async (CouchDB, migration, options = {}) => { if (migrationType === exports.MIGRATION_TYPES.GLOBAL) { dbNames = [getGlobalDBName()] } else if (migrationType === exports.MIGRATION_TYPES.APP) { - const apps = await getAllApps(CouchDB, migration.opts) + const apps = await getAllApps(migration.opts) dbNames = apps.map(app => app.appId) } else { throw new Error( diff --git a/packages/bbui/package.json b/packages/bbui/package.json index e57512a507..cf538cc9c6 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.74-alpha.2", + "version": "1.0.76-alpha.1", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", diff --git a/packages/builder/cypress/integration/createTable.spec.js b/packages/builder/cypress/integration/createTable.spec.js index 47ba771524..bac6806bcd 100644 --- a/packages/builder/cypress/integration/createTable.spec.js +++ b/packages/builder/cypress/integration/createTable.spec.js @@ -1,6 +1,6 @@ import filterTests from "../support/filterTests" -filterTests(['smoke', 'all'], () => { +filterTests(["smoke", "all"], () => { context("Create a Table", () => { before(() => { cy.login() @@ -33,7 +33,7 @@ filterTests(['smoke', 'all'], () => { cy.contains("Save Column").click() cy.contains("nameupdated ").should("contain", "nameupdated") }) - + it("edits a row", () => { cy.contains("button", "Edit").click({ force: true }) cy.wait(1000) @@ -42,20 +42,20 @@ filterTests(['smoke', 'all'], () => { cy.contains("Save").click() cy.contains("Updated").should("have.text", "Updated") }) - + it("deletes a row", () => { cy.get(".spectrum-Checkbox-input").check({ force: true }) cy.contains("Delete 1 row(s)").click() cy.get(".spectrum-Modal").contains("Delete").click() cy.contains("RoverUpdated").should("not.exist") }) - + if (Cypress.env("TEST_ENV")) { // No Pagination in CI - Test env only for the next two tests it("Adds 15 rows and checks pagination", () => { // 10 rows per page, 15 rows should create 2 pages within table const totalRows = 16 - for (let i = 1; i < totalRows; i++){ + for (let i = 1; i < totalRows; i++) { cy.addRow([i]) } cy.wait(1000) @@ -66,19 +66,19 @@ filterTests(['smoke', 'all'], () => { cy.get(".spectrum-Body--secondary").contains("Page 2") }) }) - + it("Deletes rows and checks pagination", () => { // Delete rows, removing second page of rows from table const deleteRows = 5 cy.get(".spectrum-Checkbox-input").check({ force: true }) - cy.get(".spectrum-Table-body") + cy.get(".spectrum-Table") cy.contains("Delete 5 row(s)").click() cy.get(".spectrum-Modal").contains("Delete").click() cy.wait(1000) - + // Confirm table only has one page cy.get(".spectrum-Pagination").within(() => { - cy.get(".spectrum-ActionButton").eq(1).should('not.be.enabled') + cy.get(".spectrum-ActionButton").eq(1).should("not.be.enabled") }) }) } diff --git a/packages/builder/cypress/integration/createUserAndRoles.spec.js b/packages/builder/cypress/integration/createUserAndRoles.spec.js index 79367011bb..ce6d370187 100644 --- a/packages/builder/cypress/integration/createUserAndRoles.spec.js +++ b/packages/builder/cypress/integration/createUserAndRoles.spec.js @@ -1,7 +1,6 @@ import filterTests from "../support/filterTests" - -filterTests(['smoke', 'all'], () => { +filterTests(["smoke", "all"], () => { context("Create a User and Assign Roles", () => { before(() => { cy.login() @@ -9,32 +8,32 @@ filterTests(['smoke', 'all'], () => { it("should create a user", () => { cy.createUser("bbuser@test.com") - cy.get(".spectrum-Table-body").should('contain', 'bbuser') + cy.get(".spectrum-Table").should("contain", "bbuser") }) - + it("should confirm there is No Access for a New User", () => { // Click into the user cy.contains("bbuser").click() cy.wait(500) // Get No Access table - Confirm it has apps in it - cy.get(".spectrum-Table").eq(1).should('not.contain', 'No rows found') + cy.get(".spectrum-Table").eq(1).should("not.contain", "No rows found") // Get Configure Roles table - Confirm it has no apps - cy.get(".spectrum-Table").eq(0).contains('No rows found') + cy.get(".spectrum-Table").eq(0).contains("No rows found") }) - + it("should assign role types", () => { // 3 apps minimum required - to assign an app to each role type cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`) - .its("body") - .then(val => { - if (val.length < 3) { - for (let i = 1; i < 3; i++) { - const uuid = () => Cypress._.random(0, 1e6) - const name = uuid() - cy.createApp(name) + .its("body") + .then(val => { + if (val.length < 3) { + for (let i = 1; i < 3; i++) { + const uuid = () => Cypress._.random(0, 1e6) + const name = uuid() + cy.createApp(name) + } } - } - }) + }) // Navigate back to the user cy.visit(`${Cypress.config().baseUrl}/builder`) cy.wait(500) @@ -43,90 +42,139 @@ filterTests(['smoke', 'all'], () => { cy.get(".spectrum-Table").contains("bbuser").click() cy.wait(1000) for (let i = 0; i < 3; i++) { - cy.get(".spectrum-Table-body").eq(1).find('tr').eq(0).click() + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .eq(0) + .find(".spectrum-Table-cell") + .eq(0) + .click() cy.wait(500) - cy.get(".spectrum-Dialog-grid").contains("Choose an option").click().then(() => { - cy.wait(500) - if (i == 0) { - cy.get(".spectrum-Popover").contains("Admin").click() - } - if (i == 1) { - cy.get(".spectrum-Popover").contains("Power").click() - } - if (i == 2) { - cy.get(".spectrum-Popover").contains("Basic").click() - } - cy.wait(500) - cy.get(".spectrum-Button").contains("Update role").click({ force: true }) + cy.get(".spectrum-Dialog-grid") + .contains("Choose an option") + .click() + .then(() => { + cy.wait(1000) + if (i == 0) { + cy.get(".spectrum-Popover").contains("Admin").click() + } + if (i == 1) { + cy.get(".spectrum-Popover").contains("Power").click() + } + if (i == 2) { + cy.get(".spectrum-Popover").contains("Basic").click() + } + cy.wait(1000) + cy.get(".spectrum-Button") + .contains("Update role") + .click({ force: true }) }) - } - // Confirm roles exist within Configure roles table - cy.wait(500) - cy.get(".spectrum-Table-body").eq(0).within((assginedRoles) => { + } + // Confirm roles exist within Configure roles table + cy.wait(2000) + cy.get(".spectrum-Table") + .eq(0) + .within(assginedRoles => { expect(assginedRoles).to.contain("Admin") expect(assginedRoles).to.contain("Power") expect(assginedRoles).to.contain("Basic") }) - }) - + }) + it("should unassign role types", () => { // Set each app within Configure roles table to 'No Access' - cy.get(".spectrum-Table-body").eq(0).find('tr').its('length').then((len) => { - for (let i = 0; i < len; i ++){ - cy.get(".spectrum-Table-body").eq(0).find('tr').eq(0).click().then(() => { - cy.get(".spectrum-Picker").eq(1).click({ force: true }) - cy.wait(500) - cy.get(".spectrum-Popover").contains("No Access").click() - }) - cy.get(".spectrum-Button").contains("Update role").click({ force: true }) + cy.get(".spectrum-Table") + .eq(0) + .find(".spectrum-Table-row") + .its("length") + .then(len => { + for (let i = 0; i < len; i++) { + cy.get(".spectrum-Table") + .eq(0) + .find(".spectrum-Table-row") + .eq(0) + .find(".spectrum-Table-cell") + .eq(0) + .click() + .then(() => { + cy.get(".spectrum-Picker").eq(1).click({ force: true }) + cy.wait(500) + cy.get(".spectrum-Popover").contains("No Access").click() + }) + cy.get(".spectrum-Button") + .contains("Update role") + .click({ force: true }) cy.wait(1000) - } - }) + } + }) // Confirm Configure roles table no longer has any apps in it - cy.get(".spectrum-Table-body").eq(0).contains('No rows found') + cy.get(".spectrum-Table").eq(0).contains("No rows found") }) - + it("should enable Developer access", () => { // Enable Developer access - cy.get(".field").eq(4).within(() => { - cy.get(".spectrum-Switch-input").click({ force: true }) - }) + cy.get(".field") + .eq(4) + .within(() => { + cy.get(".spectrum-Switch-input").click({ force: true }) + }) // No Access table should now be empty - cy.get(".container").contains("No Access").parent().within(() => { - cy.get(".spectrum-Table").contains("No rows found") - }) - + cy.get(".container") + .contains("No Access") + .parent() + .within(() => { + cy.get(".spectrum-Table").contains("No rows found") + }) + // Each app within Configure roles should have Admin access - cy.get(".spectrum-Table-body").eq(0).find('tr').its('length').then((len) => { - for (let i = 0; i < len; i++) { - cy.get(".spectrum-Table-body").eq(0).find('tr').eq(i).contains("Admin") - cy.wait(500) - } - }) + cy.get(".spectrum-Table") + .eq(0) + .find(".spectrum-Table-row") + .its("length") + .then(len => { + for (let i = 0; i < len; i++) { + cy.get(".spectrum-Table") + .eq(0) + .find(".spectrum-Table-row") + .eq(i) + .contains("Admin") + cy.wait(500) + } + }) }) - + it("should disable Developer access", () => { // Disable Developer access - cy.get(".field").eq(4).within(() => { - cy.get(".spectrum-Switch-input").click({ force: true }) - }) + cy.get(".field") + .eq(4) + .within(() => { + cy.get(".spectrum-Switch-input").click({ force: true }) + }) // Configure roles table should now be empty - cy.get(".container").contains("Configure roles").parent().within(() => { - cy.get(".spectrum-Table").contains("No rows found") - }) + cy.get(".container") + .contains("Configure roles") + .parent() + .within(() => { + cy.get(".spectrum-Table").contains("No rows found") + }) }) - + it("should delete a user", () => { // Click Delete user button - cy.get(".spectrum-Button").contains("Delete user").click({force: true}).then(() => { - // Confirm deletion within modal - cy.wait(500) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Button").contains("Delete user").click({force: true}) - cy.wait(4000) + cy.get(".spectrum-Button") + .contains("Delete user") + .click({ force: true }) + .then(() => { + // Confirm deletion within modal + cy.wait(500) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Button") + .contains("Delete user") + .click({ force: true }) + cy.wait(4000) + }) }) - }) - cy.get(".spectrum-Table-body").should("not.have.text", "bbuser") + cy.get(".spectrum-Table").should("not.have.text", "bbuser") }) }) }) diff --git a/packages/builder/cypress/integration/datasources/mySql.spec.js b/packages/builder/cypress/integration/datasources/mySql.spec.js index 673a902f96..03f59a6004 100644 --- a/packages/builder/cypress/integration/datasources/mySql.spec.js +++ b/packages/builder/cypress/integration/datasources/mySql.spec.js @@ -1,191 +1,222 @@ import filterTests from "../../support/filterTests" -filterTests(['all'], () => { - context("MySQL Datasource Testing", () => { - if (Cypress.env("TEST_ENV")) { - - before(() => { - cy.login() - cy.createTestApp() - }) - const datasource = "MySQL" - const queryName = "Cypress Test Query" - const queryRename = "CT Query Rename" - - it("Should add MySQL data source without configuration", () => { - // Select MySQL data source - cy.selectExternalDatasource(datasource) - // Attempt to fetch tables without applying configuration - cy.intercept('**/datasources').as('datasource') +filterTests(["all"], () => { + context("MySQL Datasource Testing", () => { + if (Cypress.env("TEST_ENV")) { + before(() => { + cy.login() + cy.createTestApp() + }) + const datasource = "MySQL" + const queryName = "Cypress Test Query" + const queryRename = "CT Query Rename" + + it("Should add MySQL data source without configuration", () => { + // Select MySQL data source + cy.selectExternalDatasource(datasource) + // Attempt to fetch tables without applying configuration + cy.intercept("**/datasources").as("datasource") + cy.get(".spectrum-Button") + .contains("Save and fetch tables") + .click({ force: true }) + // Intercept Request after button click & apply assertions + cy.wait("@datasource") + cy.get("@datasource") + .its("response.body") + .should( + "have.property", + "message", + "connect ECONNREFUSED 127.0.0.1:3306" + ) + cy.get("@datasource") + .its("response.body") + .should("have.property", "status", 500) + }) + + it("should add MySQL data source and fetch tables", () => { + // Add & configure MySQL data source + cy.selectExternalDatasource(datasource) + cy.intercept("**/datasources").as("datasource") + cy.addDatasourceConfig(datasource) + // Check response from datasource after adding configuration + cy.wait("@datasource") + cy.get("@datasource").its("response.statusCode").should("eq", 200) + // Confirm fetch tables was successful + cy.get(".spectrum-Table") + .eq(0) + .find(".spectrum-Table-row") + .its("length") + .should("be.gt", 0) + }) + + it("should check table fetching error", () => { + // MySQL test data source contains tables without primary keys + cy.get(".spectrum-InLineAlert") + .should("contain", "Error fetching tables") + .and("contain", "No primary key constraint found") + }) + + it("should define a One relationship type", () => { + // Select relationship type & configure + cy.get(".spectrum-Button") + .contains("Define relationship") + .click({ force: true }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Picker").eq(0).click() + cy.get(".spectrum-Popover").contains("One").click() + cy.get(".spectrum-Picker").eq(1).click() + cy.get(".spectrum-Popover").contains("REGIONS").click() + cy.get(".spectrum-Picker").eq(2).click() + cy.get(".spectrum-Popover").contains("REGION_ID").click() + cy.get(".spectrum-Picker").eq(3).click() + cy.get(".spectrum-Popover").contains("COUNTRIES").click() + cy.get(".spectrum-Picker").eq(4).click() + cy.get(".spectrum-Popover").contains("REGION_ID").click() + // Save relationship & reload page + cy.get(".spectrum-Button").contains("Save").click({ force: true }) + cy.reload() + }) + // Confirm table length & column name + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .its("length") + .should("eq", 1) + cy.get(".spectrum-Table-cell").should("contain", "COUNTRIES to REGIONS") + }) + + it("should define a Many relationship type", () => { + // Select relationship type & configure + cy.get(".spectrum-Button") + .contains("Define relationship") + .click({ force: true }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Picker").eq(0).click() + cy.get(".spectrum-Popover").contains("Many").click() + cy.get(".spectrum-Picker").eq(1).click() + cy.get(".spectrum-Popover").contains("LOCATIONS").click() + cy.get(".spectrum-Picker").eq(2).click() + cy.get(".spectrum-Popover").contains("REGIONS").click() + cy.get(".spectrum-Picker").eq(3).click() + cy.get(".spectrum-Popover").contains("COUNTRIES").click() + cy.get(".spectrum-Picker").eq(4).click() + cy.get(".spectrum-Popover").contains("COUNTRY_ID").click() + cy.get(".spectrum-Picker").eq(5).click() + cy.get(".spectrum-Popover").contains("REGION_ID").click() + // Save relationship & reload page + cy.get(".spectrum-Button").contains("Save").click({ force: true }) + cy.reload() + cy.wait(1000) + }) + // Confirm table length & relationship name + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .its("length") + .should("eq", 2) + cy.get(".spectrum-Table-cell").should( + "contain", + "LOCATIONS through COUNTRIES → REGIONS" + ) + }) + + it("should delete relationships", () => { + // Delete both relationships + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .its("length") + .then(len => { + for (let i = 0; i < len; i++) { + cy.get(".spectrum-Table") + .eq(1) + .within(() => { + cy.get(".spectrum-Table-row").eq(0).click() + cy.wait(500) + }) + cy.get(".spectrum-Dialog-grid").within(() => { cy.get(".spectrum-Button") - .contains("Save and fetch tables") - .click({ force: true }) - // Intercept Request after button click & apply assertions - cy.wait("@datasource") - cy.get("@datasource").its('response.body') - .should('have.property', 'message', 'connect ECONNREFUSED 127.0.0.1:3306') - cy.get("@datasource").its('response.body') - .should('have.property', 'status', 500) - }) - - it("should add MySQL data source and fetch tables", () => { - // Add & configure MySQL data source - cy.selectExternalDatasource(datasource) - cy.intercept('**/datasources').as('datasource') - cy.addDatasourceConfig(datasource) - // Check response from datasource after adding configuration - cy.wait("@datasource") - cy.get("@datasource").its('response.statusCode') - .should('eq', 200) - // Confirm fetch tables was successful - cy.get(".spectrum-Table-body").eq(0) - .find('tr') - .its('length') - .should('be.gt', 0) - }) - - it("should check table fetching error", () => { - // MySQL test data source contains tables without primary keys - cy.get(".spectrum-InLineAlert") - .should('contain', 'Error fetching tables') - .and('contain', 'No primary key constraint found') - }) - - it("should define a One relationship type", () => { - // Select relationship type & configure - cy.get(".spectrum-Button").contains("Define relationship").click({ force: true }) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Picker").eq(0).click() - cy.get(".spectrum-Popover").contains("One").click() - cy.get(".spectrum-Picker").eq(1).click() - cy.get(".spectrum-Popover").contains("REGIONS").click() - cy.get(".spectrum-Picker").eq(2).click() - cy.get(".spectrum-Popover").contains("REGION_ID").click() - cy.get(".spectrum-Picker").eq(3).click() - cy.get(".spectrum-Popover").contains("COUNTRIES").click() - cy.get(".spectrum-Picker").eq(4).click() - cy.get(".spectrum-Popover").contains("REGION_ID").click() - // Save relationship & reload page - cy.get(".spectrum-Button").contains("Save").click({ force: true }) - cy.reload() - }) - // Confirm table length & column name - cy.get(".spectrum-Table-body").eq(1) - .find('tr') - .its('length') - .should('eq', 1) - cy.get(".spectrum-Table-cell").should('contain', "COUNTRIES to REGIONS") - }) - - it("should define a Many relationship type", () => { - // Select relationship type & configure - cy.get(".spectrum-Button").contains("Define relationship").click({ force: true }) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Picker").eq(0).click() - cy.get(".spectrum-Popover").contains("Many").click() - cy.get(".spectrum-Picker").eq(1).click() - cy.get(".spectrum-Popover").contains("LOCATIONS").click() - cy.get(".spectrum-Picker").eq(2).click() - cy.get(".spectrum-Popover").contains("REGIONS").click() - cy.get(".spectrum-Picker").eq(3).click() - cy.get(".spectrum-Popover").contains("COUNTRIES").click() - cy.get(".spectrum-Picker").eq(4).click() - cy.get(".spectrum-Popover").contains("COUNTRY_ID").click() - cy.get(".spectrum-Picker").eq(5).click() - cy.get(".spectrum-Popover").contains("REGION_ID").click() - // Save relationship & reload page - cy.get(".spectrum-Button").contains("Save").click({ force: true }) - cy.reload() - cy.wait(1000) - }) - // Confirm table length & relationship name - cy.get(".spectrum-Table-body").eq(1) - .find('tr') - .its('length') - .should('eq', 2) - cy.get(".spectrum-Table-cell") - .should('contain', "LOCATIONS through COUNTRIES → REGIONS") - }) - - it("should delete relationships", () => { - // Delete both relationships - cy.get(".spectrum-Table-body") - .eq(1).find('tr').its('length') - .then((len) => { - for (let i = 0; i < len; i++) { - cy.get(".spectrum-Table-body").eq(1).within(() => { - cy.get(".spectrum-Table-row").eq(0).click() - cy.wait(500) - }) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Button").contains("Delete").click({ force: true }) - }) - cy.reload() - } - // Confirm relationships no longer exist - cy.get(".spectrum-Body").should('contain', 'No relationships configured') - }) - }) - - it("should add a query", () => { - // Add query - cy.get(".spectrum-Button").contains("Add query").click({ force: true }) - cy.get(".spectrum-Form-item").eq(0).within(() => { - cy.get("input").type(queryName) - }) - // Insert Query within Fields section - cy.get(".CodeMirror textarea").eq(0) - .type("SELECT * FROM books", { force: true }) - // Intercept query execution - cy.intercept('**/queries/preview').as('query') - cy.get(".spectrum-Button").contains("Run Query").click({ force: true }) - cy.wait(500) - cy.wait("@query") - // Assert against Status Code & Body - cy.get("@query").its('response.statusCode') - .should('eq', 200) - cy.get("@query").its('response.body') - .should('not.be.empty') - // Save query - cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) - cy.get(".nav-item").should('contain', queryName) - }) - - it("should duplicate a query", () => { - // Get last nav item - The query - cy.get(".nav-item").last().within(() => { - cy.get(".icon").eq(1).click({ force: true }) - }) - // Select and confirm duplication - cy.get(".spectrum-Menu").contains("Duplicate").click() - cy.get(".nav-item").should('contain', queryName + ' (1)') - }) - - it("should edit a query name", () => { - // Rename query - cy.get(".spectrum-Form-item").eq(0).within(() => { - cy.get("input").clear().type(queryRename) - }) - // Save query - cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) - cy.get(".nav-item").should('contain', queryRename) - }) - - it("should delete a query", () => { - // Get last nav item - The query - for (let i = 0; i < 2; i++) { - cy.get(".nav-item").last().within(() => { - cy.get(".icon").eq(1).click({ force: true }) - }) - // Select Delete - cy.get(".spectrum-Menu").contains("Delete").click() - cy.get(".spectrum-Button").contains("Delete Query").click({ force: true }) - cy.wait(1000) - } - // Confirm deletion - cy.get(".nav-item").should('not.contain', queryName) - cy.get(".nav-item").should('not.contain', queryRename) + .contains("Delete") + .click({ force: true }) + }) + cy.reload() + } + // Confirm relationships no longer exist + cy.get(".spectrum-Body").should( + "contain", + "No relationships configured" + ) + }) + }) + + it("should add a query", () => { + // Add query + cy.get(".spectrum-Button").contains("Add query").click({ force: true }) + cy.get(".spectrum-Form-item") + .eq(0) + .within(() => { + cy.get("input").type(queryName) + }) + // Insert Query within Fields section + cy.get(".CodeMirror textarea") + .eq(0) + .type("SELECT * FROM books", { force: true }) + // Intercept query execution + cy.intercept("**/queries/preview").as("query") + cy.get(".spectrum-Button").contains("Run Query").click({ force: true }) + cy.wait(500) + cy.wait("@query") + // Assert against Status Code & Body + cy.get("@query").its("response.statusCode").should("eq", 200) + cy.get("@query").its("response.body").should("not.be.empty") + // Save query + cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) + cy.get(".nav-item").should("contain", queryName) + }) + + it("should duplicate a query", () => { + // Get last nav item - The query + cy.get(".nav-item") + .last() + .within(() => { + cy.get(".icon").eq(1).click({ force: true }) + }) + // Select and confirm duplication + cy.get(".spectrum-Menu").contains("Duplicate").click() + cy.get(".nav-item").should("contain", queryName + " (1)") + }) + + it("should edit a query name", () => { + // Rename query + cy.get(".spectrum-Form-item") + .eq(0) + .within(() => { + cy.get("input").clear().type(queryRename) + }) + // Save query + cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) + cy.get(".nav-item").should("contain", queryRename) + }) + + it("should delete a query", () => { + // Get last nav item - The query + for (let i = 0; i < 2; i++) { + cy.get(".nav-item") + .last() + .within(() => { + cy.get(".icon").eq(1).click({ force: true }) }) + // Select Delete + cy.get(".spectrum-Menu").contains("Delete").click() + cy.get(".spectrum-Button") + .contains("Delete Query") + .click({ force: true }) + cy.wait(1000) } - }) + // Confirm deletion + cy.get(".nav-item").should("not.contain", queryName) + cy.get(".nav-item").should("not.contain", queryRename) + }) + } + }) }) diff --git a/packages/builder/cypress/integration/datasources/oracle.spec.js b/packages/builder/cypress/integration/datasources/oracle.spec.js index ce41ef7936..73c25001c9 100644 --- a/packages/builder/cypress/integration/datasources/oracle.spec.js +++ b/packages/builder/cypress/integration/datasources/oracle.spec.js @@ -1,196 +1,230 @@ import filterTests from "../../support/filterTests" -filterTests(['all'], () => { - context("Oracle Datasource Testing", () => { - if (Cypress.env("TEST_ENV")) { +filterTests(["all"], () => { + context("Oracle Datasource Testing", () => { + if (Cypress.env("TEST_ENV")) { + before(() => { + cy.login() + cy.createTestApp() + }) + const datasource = "Oracle" + const queryName = "Cypress Test Query" + const queryRename = "CT Query Rename" - before(() => { - cy.login() - cy.createTestApp() - }) - const datasource = "Oracle" - const queryName = "Cypress Test Query" - const queryRename = "CT Query Rename" - - it("Should add Oracle data source and skip table fetch", () => { - // Select Oracle data source - cy.selectExternalDatasource(datasource) - // Skip table fetch - no config added - cy.get(".spectrum-Button").contains("Skip table fetch").click({ force: true }) - cy.wait(500) - // Confirm config contains localhost - cy.get(".spectrum-Textfield-input").eq(1).should('have.value', 'localhost') - // Add another Oracle data source, configure & skip table fetch - cy.selectExternalDatasource(datasource) - cy.addDatasourceConfig(datasource, true) - // Confirm config and no tables - cy.get(".spectrum-Textfield-input").eq(1).should('have.value', Cypress.env("oracle").HOST) - cy.get(".spectrum-Body").eq(2).should('contain', 'No tables found.') - }) - - it("Should add Oracle data source and fetch tables without configuration", () => { - // Select Oracle data source - cy.selectExternalDatasource(datasource) - // Attempt to fetch tables without applying configuration - cy.intercept('**/datasources').as('datasource') + it("Should add Oracle data source and skip table fetch", () => { + // Select Oracle data source + cy.selectExternalDatasource(datasource) + // Skip table fetch - no config added + cy.get(".spectrum-Button") + .contains("Skip table fetch") + .click({ force: true }) + cy.wait(500) + // Confirm config contains localhost + cy.get(".spectrum-Textfield-input") + .eq(1) + .should("have.value", "localhost") + // Add another Oracle data source, configure & skip table fetch + cy.selectExternalDatasource(datasource) + cy.addDatasourceConfig(datasource, true) + // Confirm config and no tables + cy.get(".spectrum-Textfield-input") + .eq(1) + .should("have.value", Cypress.env("oracle").HOST) + cy.get(".spectrum-Body").eq(2).should("contain", "No tables found.") + }) + + it("Should add Oracle data source and fetch tables without configuration", () => { + // Select Oracle data source + cy.selectExternalDatasource(datasource) + // Attempt to fetch tables without applying configuration + cy.intercept("**/datasources").as("datasource") + cy.get(".spectrum-Button") + .contains("Save and fetch tables") + .click({ force: true }) + // Intercept Request after button click & apply assertions + cy.wait("@datasource") + cy.get("@datasource") + .its("response.body") + .should("have.property", "status", 500) + }) + + it("should add Oracle data source and fetch tables", () => { + // Add & configure Oracle data source + cy.selectExternalDatasource(datasource) + cy.intercept("**/datasources").as("datasource") + cy.addDatasourceConfig(datasource) + // Check response from datasource after adding configuration + cy.wait("@datasource") + cy.get("@datasource").its("response.statusCode").should("eq", 200) + // Confirm fetch tables was successful + cy.get(".spectrum-Table") + .eq(0) + .find(".spectrum-Table-row") + .its("length") + .should("be.gt", 0) + }) + + it("should define a One relationship type", () => { + // Select relationship type & configure + cy.get(".spectrum-Button") + .contains("Define relationship") + .click({ force: true }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Picker").eq(0).click() + cy.get(".spectrum-Popover").contains("One").click() + cy.get(".spectrum-Picker").eq(1).click() + cy.get(".spectrum-Popover").contains("REGIONS").click() + cy.get(".spectrum-Picker").eq(2).click() + cy.get(".spectrum-Popover").contains("REGION_ID").click() + cy.get(".spectrum-Picker").eq(3).click() + cy.get(".spectrum-Popover").contains("COUNTRIES").click() + cy.get(".spectrum-Picker").eq(4).click() + cy.get(".spectrum-Popover").contains("REGION_ID").click() + // Save relationship & reload page + cy.get(".spectrum-Button").contains("Save").click({ force: true }) + cy.reload() + }) + // Confirm table length & column name + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .its("length") + .should("eq", 1) + cy.get(".spectrum-Table-cell").should("contain", "COUNTRIES to REGIONS") + }) + + it("should define a Many relationship type", () => { + // Select relationship type & configure + cy.get(".spectrum-Button") + .contains("Define relationship") + .click({ force: true }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Picker").eq(0).click() + cy.get(".spectrum-Popover").contains("Many").click() + cy.get(".spectrum-Picker").eq(1).click() + cy.get(".spectrum-Popover").contains("LOCATIONS").click() + cy.get(".spectrum-Picker").eq(2).click() + cy.get(".spectrum-Popover").contains("REGIONS").click() + cy.get(".spectrum-Picker").eq(3).click() + cy.get(".spectrum-Popover").contains("COUNTRIES").click() + cy.get(".spectrum-Picker").eq(4).click() + cy.get(".spectrum-Popover").contains("COUNTRY_ID").click() + cy.get(".spectrum-Picker").eq(5).click() + cy.get(".spectrum-Popover").contains("REGION_ID").click() + // Save relationship & reload page + cy.get(".spectrum-Button").contains("Save").click({ force: true }) + cy.reload() + }) + // Confirm table length & relationship name + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .its("length") + .should("eq", 2) + cy.get(".spectrum-Table-cell").should( + "contain", + "LOCATIONS through COUNTRIES → REGIONS" + ) + }) + + it("should delete relationships", () => { + // Delete both relationships + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .its("length") + .then(len => { + for (let i = 0; i < len; i++) { + cy.get(".spectrum-Table") + .eq(1) + .within(() => { + cy.get(".spectrum-Table-row").eq(0).click() + cy.wait(500) + }) + cy.get(".spectrum-Dialog-grid").within(() => { cy.get(".spectrum-Button") - .contains("Save and fetch tables") - .click({ force: true }) - // Intercept Request after button click & apply assertions - cy.wait("@datasource") - cy.get("@datasource").its('response.body') - .should('have.property', 'status', 500) - }) - - it("should add Oracle data source and fetch tables", () => { - // Add & configure Oracle data source - cy.selectExternalDatasource(datasource) - cy.intercept('**/datasources').as('datasource') - cy.addDatasourceConfig(datasource) - // Check response from datasource after adding configuration - cy.wait("@datasource") - cy.get("@datasource").its('response.statusCode') - .should('eq', 200) - // Confirm fetch tables was successful - cy.get(".spectrum-Table-body").eq(0) - .find('tr') - .its('length') - .should('be.gt', 0) - }) - - it("should define a One relationship type", () => { - // Select relationship type & configure - cy.get(".spectrum-Button").contains("Define relationship").click({ force: true }) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Picker").eq(0).click() - cy.get(".spectrum-Popover").contains("One").click() - cy.get(".spectrum-Picker").eq(1).click() - cy.get(".spectrum-Popover").contains("REGIONS").click() - cy.get(".spectrum-Picker").eq(2).click() - cy.get(".spectrum-Popover").contains("REGION_ID").click() - cy.get(".spectrum-Picker").eq(3).click() - cy.get(".spectrum-Popover").contains("COUNTRIES").click() - cy.get(".spectrum-Picker").eq(4).click() - cy.get(".spectrum-Popover").contains("REGION_ID").click() - // Save relationship & reload page - cy.get(".spectrum-Button").contains("Save").click({ force: true }) - cy.reload() - }) - // Confirm table length & column name - cy.get(".spectrum-Table-body").eq(1) - .find('tr') - .its('length') - .should('eq', 1) - cy.get(".spectrum-Table-cell").should('contain', "COUNTRIES to REGIONS") - }) - - it("should define a Many relationship type", () => { - // Select relationship type & configure - cy.get(".spectrum-Button").contains("Define relationship").click({ force: true }) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Picker").eq(0).click() - cy.get(".spectrum-Popover").contains("Many").click() - cy.get(".spectrum-Picker").eq(1).click() - cy.get(".spectrum-Popover").contains("LOCATIONS").click() - cy.get(".spectrum-Picker").eq(2).click() - cy.get(".spectrum-Popover").contains("REGIONS").click() - cy.get(".spectrum-Picker").eq(3).click() - cy.get(".spectrum-Popover").contains("COUNTRIES").click() - cy.get(".spectrum-Picker").eq(4).click() - cy.get(".spectrum-Popover").contains("COUNTRY_ID").click() - cy.get(".spectrum-Picker").eq(5).click() - cy.get(".spectrum-Popover").contains("REGION_ID").click() - // Save relationship & reload page - cy.get(".spectrum-Button").contains("Save").click({ force: true }) - cy.reload() - }) - // Confirm table length & relationship name - cy.get(".spectrum-Table-body").eq(1) - .find('tr') - .its('length') - .should('eq', 2) - cy.get(".spectrum-Table-cell") - .should('contain', "LOCATIONS through COUNTRIES → REGIONS") - }) - - it("should delete relationships", () => { - // Delete both relationships - cy.get(".spectrum-Table-body") - .eq(1).find('tr').its('length') - .then((len) => { - for (let i = 0; i < len; i++) { - cy.get(".spectrum-Table-body").eq(1).within(() => { - cy.get(".spectrum-Table-row").eq(0).click() - cy.wait(500) - }) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Button").contains("Delete").click({ force: true }) - }) - cy.reload() - } - // Confirm relationships no longer exist - cy.get(".spectrum-Body").should('contain', 'No relationships configured') - }) - }) - - it("should add a query", () => { - // Add query - cy.get(".spectrum-Button").contains("Add query").click({ force: true }) - cy.get(".spectrum-Form-item").eq(0).within(() => { - cy.get("input").type(queryName) - }) - // Insert Query within Fields section - cy.get(".CodeMirror textarea").eq(0) - .type("SELECT * FROM JOBS", { force: true }) - // Intercept query execution - cy.intercept('**/queries/preview').as('query') - cy.get(".spectrum-Button").contains("Run Query").click({ force: true }) - cy.wait(500) - cy.wait("@query") - // Assert against Status Code & Body - cy.get("@query").its('response.statusCode') - .should('eq', 200) - cy.get("@query").its('response.body') - .should('not.be.empty') - // Save query - cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) - cy.get(".nav-item").should('contain', queryName) - }) - - it("should duplicate a query", () => { - // Get query nav item - cy.get(".nav-item").contains(queryName).parent().within(() => { - cy.get(".spectrum-Icon").eq(1).click({ force: true }) - }) - // Select and confirm duplication - cy.get(".spectrum-Menu").contains("Duplicate").click() - cy.get(".nav-item").should('contain', queryName + ' (1)') - }) - - it("should edit a query name", () => { - // Rename query - cy.get(".spectrum-Form-item").eq(0).within(() => { - cy.get("input").clear().type(queryRename) - }) - // Save query - cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) - cy.get(".nav-item").should('contain', queryRename) - }) - - it("should delete a query", () => { - // Get query nav item - QueryName - cy.get(".nav-item").contains(queryName).parent().within(() => { - cy.get(".spectrum-Icon").eq(1).click({ force: true }) - }) - - // Select Delete - cy.get(".spectrum-Menu").contains("Delete").click() - cy.get(".spectrum-Button").contains("Delete Query").click({ force: true }) - cy.wait(1000) - - // Confirm deletion - cy.get(".nav-item").should('not.contain', queryName) - }) - } - }) + .contains("Delete") + .click({ force: true }) + }) + cy.reload() + } + // Confirm relationships no longer exist + cy.get(".spectrum-Body").should( + "contain", + "No relationships configured" + ) + }) + }) + + it("should add a query", () => { + // Add query + cy.get(".spectrum-Button").contains("Add query").click({ force: true }) + cy.get(".spectrum-Form-item") + .eq(0) + .within(() => { + cy.get("input").type(queryName) + }) + // Insert Query within Fields section + cy.get(".CodeMirror textarea") + .eq(0) + .type("SELECT * FROM JOBS", { force: true }) + // Intercept query execution + cy.intercept("**/queries/preview").as("query") + cy.get(".spectrum-Button").contains("Run Query").click({ force: true }) + cy.wait(500) + cy.wait("@query") + // Assert against Status Code & Body + cy.get("@query").its("response.statusCode").should("eq", 200) + cy.get("@query").its("response.body").should("not.be.empty") + // Save query + cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) + cy.get(".nav-item").should("contain", queryName) + }) + + it("should duplicate a query", () => { + // Get query nav item + cy.get(".nav-item") + .contains(queryName) + .parent() + .within(() => { + cy.get(".spectrum-Icon").eq(1).click({ force: true }) + }) + // Select and confirm duplication + cy.get(".spectrum-Menu").contains("Duplicate").click() + cy.get(".nav-item").should("contain", queryName + " (1)") + }) + + it("should edit a query name", () => { + // Rename query + cy.get(".spectrum-Form-item") + .eq(0) + .within(() => { + cy.get("input").clear().type(queryRename) + }) + // Save query + cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) + cy.get(".nav-item").should("contain", queryRename) + }) + + it("should delete a query", () => { + // Get query nav item - QueryName + cy.get(".nav-item") + .contains(queryName) + .parent() + .within(() => { + cy.get(".spectrum-Icon").eq(1).click({ force: true }) + }) + + // Select Delete + cy.get(".spectrum-Menu").contains("Delete").click() + cy.get(".spectrum-Button") + .contains("Delete Query") + .click({ force: true }) + cy.wait(1000) + + // Confirm deletion + cy.get(".nav-item").should("not.contain", queryName) + }) + } + }) }) diff --git a/packages/builder/cypress/integration/datasources/postgreSql.spec.js b/packages/builder/cypress/integration/datasources/postgreSql.spec.js index c8ff915f90..3f55636623 100644 --- a/packages/builder/cypress/integration/datasources/postgreSql.spec.js +++ b/packages/builder/cypress/integration/datasources/postgreSql.spec.js @@ -1,241 +1,285 @@ import filterTests from "../../support/filterTests" -filterTests(['all'], () => { - context("PostgreSQL Datasource Testing", () => { - if (Cypress.env("TEST_ENV")) { - - before(() => { - cy.login() - cy.createTestApp() +filterTests(["all"], () => { + context("PostgreSQL Datasource Testing", () => { + if (Cypress.env("TEST_ENV")) { + before(() => { + cy.login() + cy.createTestApp() + }) + const datasource = "PostgreSQL" + const queryName = "Cypress Test Query" + const queryRename = "CT Query Rename" + + it("Should add PostgreSQL data source without configuration", () => { + // Select PostgreSQL data source + cy.selectExternalDatasource(datasource) + // Attempt to fetch tables without applying configuration + cy.intercept("**/datasources").as("datasource") + cy.get(".spectrum-Button") + .contains("Save and fetch tables") + .click({ force: true }) + // Intercept Request after button click & apply assertions + cy.wait("@datasource") + cy.get("@datasource") + .its("response.body") + .should( + "have.property", + "message", + "connect ECONNREFUSED 127.0.0.1:5432" + ) + cy.get("@datasource") + .its("response.body") + .should("have.property", "status", 500) + }) + + it("should add PostgreSQL data source and fetch tables", () => { + // Add & configure PostgreSQL data source + cy.selectExternalDatasource(datasource) + cy.intercept("**/datasources").as("datasource") + cy.addDatasourceConfig(datasource) + // Check response from datasource after adding configuration + cy.wait("@datasource") + cy.get("@datasource").its("response.statusCode").should("eq", 200) + // Confirm fetch tables was successful + cy.get(".spectrum-Table") + .eq(0) + .find(".spectrum-Table-row") + .its("length") + .should("be.gt", 0) + }) + + it("should define a One relationship type", () => { + // Select relationship type & configure + cy.get(".spectrum-Button") + .contains("Define relationship") + .click({ force: true }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Picker").eq(0).click() + cy.get(".spectrum-Popover").contains("One").click() + cy.get(".spectrum-Picker").eq(1).click() + cy.get(".spectrum-Popover").contains("REGIONS").click() + cy.get(".spectrum-Picker").eq(2).click() + cy.get(".spectrum-Popover").contains("REGION_ID").click() + cy.get(".spectrum-Picker").eq(3).click() + cy.get(".spectrum-Popover").contains("COUNTRIES").click() + cy.get(".spectrum-Picker").eq(4).click() + cy.get(".spectrum-Popover").contains("REGION_ID").click() + // Save relationship & reload page + cy.get(".spectrum-Button").contains("Save").click({ force: true }) + cy.reload() + }) + // Confirm table length & column name + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .its("length") + .should("eq", 1) + cy.get(".spectrum-Table-cell").should("contain", "COUNTRIES to REGIONS") + }) + + it("should define a Many relationship type", () => { + // Select relationship type & configure + cy.get(".spectrum-Button") + .contains("Define relationship") + .click({ force: true }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Picker").eq(0).click() + cy.get(".spectrum-Popover").contains("Many").click() + cy.get(".spectrum-Picker").eq(1).click() + cy.get(".spectrum-Popover").contains("LOCATIONS").click() + cy.get(".spectrum-Picker").eq(2).click() + cy.get(".spectrum-Popover").contains("REGIONS").click() + cy.get(".spectrum-Picker").eq(3).click() + cy.get(".spectrum-Popover").contains("COUNTRIES").click() + cy.get(".spectrum-Picker").eq(4).click() + cy.get(".spectrum-Popover").contains("COUNTRY_ID").click() + cy.get(".spectrum-Picker").eq(5).click() + cy.get(".spectrum-Popover").contains("REGION_ID").click() + // Save relationship & reload page + cy.get(".spectrum-Button").contains("Save").click({ force: true }) + cy.reload() + }) + // Confirm table length & relationship name + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .its("length") + .should("eq", 2) + cy.get(".spectrum-Table-cell").should( + "contain", + "LOCATIONS through COUNTRIES → REGIONS" + ) + }) + + it("should delete a relationship", () => { + cy.get(".hierarchy-items-container").contains(datasource).click() + cy.reload() + // Delete one relationship + cy.get(".spectrum-Table") + .eq(1) + .within(() => { + cy.get(".spectrum-Table-row").eq(0).click() + cy.wait(500) + }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Button").contains("Delete").click({ force: true }) + }) + cy.reload() + // Confirm relationship was deleted + cy.get(".spectrum-Table") + .eq(1) + .find(".spectrum-Table-row") + .its("length") + .should("eq", 1) + }) + + it("should add a query", () => { + // Add query + cy.get(".spectrum-Button").contains("Add query").click({ force: true }) + cy.get(".spectrum-Form-item") + .eq(0) + .within(() => { + cy.get("input").type(queryName) + }) + // Insert Query within Fields section + cy.get(".CodeMirror textarea") + .eq(0) + .type("SELECT * FROM books", { force: true }) + // Intercept query execution + cy.intercept("**/queries/preview").as("query") + cy.get(".spectrum-Button").contains("Run Query").click({ force: true }) + cy.wait(500) + cy.wait("@query") + // Assert against Status Code & Body + cy.get("@query").its("response.statusCode").should("eq", 200) + cy.get("@query").its("response.body").should("not.be.empty") + // Save query + cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) + cy.get(".hierarchy-items-container").should("contain", queryName) + }) + + it("should switch to schema with no tables", () => { + // Switch Schema - To one without any tables + cy.get(".hierarchy-items-container").contains(datasource).click() + switchSchema("randomText") + + // No tables displayed + cy.get(".spectrum-Body").eq(2).should("contain", "No tables found") + + // Previously created query should be visible + cy.get(".spectrum-Table").should("contain", queryName) + }) + + it("should switch schemas", () => { + // Switch schema - To one with tables + switchSchema("1") + + // Confirm tables exist - Check for specific one + cy.get(".spectrum-Table").eq(0).should("contain", "test") + cy.get(".spectrum-Table") + .eq(0) + .find(".spectrum-Table-row") + .its("length") + .should("eq", 1) + + // Confirm specific table visible within left nav bar + cy.get(".hierarchy-items-container").should("contain", "test") + + // Switch back to public schema + switchSchema("public") + + // Confirm tables exist - again + cy.get(".spectrum-Table").eq(0).should("contain", "REGIONS") + cy.get(".spectrum-Table") + .eq(0) + .find(".spectrum-Table-row") + .its("length") + .should("be.gt", 1) + + // Confirm specific table visible within left nav bar + cy.get(".hierarchy-items-container").should("contain", "REGIONS") + + // No relationships and one query + cy.get(".spectrum-Body") + .eq(3) + .should("contain", "No relationships configured.") + cy.get(".spectrum-Table").eq(1).should("contain", queryName) + }) + + it("should duplicate a query", () => { + // Get last nav item - The query + cy.get(".nav-item") + .last() + .within(() => { + cy.get(".icon").eq(1).click({ force: true }) + }) + // Select and confirm duplication + cy.get(".spectrum-Menu").contains("Duplicate").click() + cy.get(".nav-item").should("contain", queryName + " (1)") + }) + + it("should edit a query name", () => { + // Access query + cy.get(".hierarchy-items-container") + .contains(queryName + " (1)") + .click() + + // Rename query + cy.get(".spectrum-Form-item") + .eq(0) + .within(() => { + cy.get("input").clear().type(queryRename) + }) + + // Run and Save query + cy.get(".spectrum-Button").contains("Run Query").click({ force: true }) + cy.wait(500) + cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) + cy.get(".nav-item").should("contain", queryRename) + }) + + it("should delete a query", () => { + // Get last nav item - The query + for (let i = 0; i < 2; i++) { + cy.get(".nav-item") + .last() + .within(() => { + cy.get(".icon").eq(1).click({ force: true }) }) - const datasource = "PostgreSQL" - const queryName = "Cypress Test Query" - const queryRename = "CT Query Rename" - - it("Should add PostgreSQL data source without configuration", () => { - // Select PostgreSQL data source - cy.selectExternalDatasource(datasource) - // Attempt to fetch tables without applying configuration - cy.intercept('**/datasources').as('datasource') - cy.get(".spectrum-Button") - .contains("Save and fetch tables") - .click({ force: true }) - // Intercept Request after button click & apply assertions - cy.wait("@datasource") - cy.get("@datasource").its('response.body') - .should('have.property', 'message', 'connect ECONNREFUSED 127.0.0.1:5432') - cy.get("@datasource").its('response.body') - .should('have.property', 'status', 500) - }) - - it("should add PostgreSQL data source and fetch tables", () => { - // Add & configure PostgreSQL data source - cy.selectExternalDatasource(datasource) - cy.intercept('**/datasources').as('datasource') - cy.addDatasourceConfig(datasource) - // Check response from datasource after adding configuration - cy.wait("@datasource") - cy.get("@datasource").its('response.statusCode') - .should('eq', 200) - // Confirm fetch tables was successful - cy.get(".spectrum-Table-body").eq(0) - .find('tr') - .its('length') - .should('be.gt', 0) - }) - - it("should define a One relationship type", () => { - // Select relationship type & configure - cy.get(".spectrum-Button").contains("Define relationship").click({ force: true }) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Picker").eq(0).click() - cy.get(".spectrum-Popover").contains("One").click() - cy.get(".spectrum-Picker").eq(1).click() - cy.get(".spectrum-Popover").contains("REGIONS").click() - cy.get(".spectrum-Picker").eq(2).click() - cy.get(".spectrum-Popover").contains("REGION_ID").click() - cy.get(".spectrum-Picker").eq(3).click() - cy.get(".spectrum-Popover").contains("COUNTRIES").click() - cy.get(".spectrum-Picker").eq(4).click() - cy.get(".spectrum-Popover").contains("REGION_ID").click() - // Save relationship & reload page - cy.get(".spectrum-Button").contains("Save").click({ force: true }) - cy.reload() - }) - // Confirm table length & column name - cy.get(".spectrum-Table-body").eq(1) - .find('tr') - .its('length') - .should('eq', 1) - cy.get(".spectrum-Table-cell").should('contain', "COUNTRIES to REGIONS") - }) - - it("should define a Many relationship type", () => { - // Select relationship type & configure - cy.get(".spectrum-Button").contains("Define relationship").click({ force: true }) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Picker").eq(0).click() - cy.get(".spectrum-Popover").contains("Many").click() - cy.get(".spectrum-Picker").eq(1).click() - cy.get(".spectrum-Popover").contains("LOCATIONS").click() - cy.get(".spectrum-Picker").eq(2).click() - cy.get(".spectrum-Popover").contains("REGIONS").click() - cy.get(".spectrum-Picker").eq(3).click() - cy.get(".spectrum-Popover").contains("COUNTRIES").click() - cy.get(".spectrum-Picker").eq(4).click() - cy.get(".spectrum-Popover").contains("COUNTRY_ID").click() - cy.get(".spectrum-Picker").eq(5).click() - cy.get(".spectrum-Popover").contains("REGION_ID").click() - // Save relationship & reload page - cy.get(".spectrum-Button").contains("Save").click({ force: true }) - cy.reload() - }) - // Confirm table length & relationship name - cy.get(".spectrum-Table-body").eq(1) - .find('tr') - .its('length') - .should('eq', 2) - cy.get(".spectrum-Table-cell") - .should('contain', "LOCATIONS through COUNTRIES → REGIONS") - }) - - it("should delete a relationship", () => { - cy.get(".hierarchy-items-container").contains(datasource).click() - cy.reload() - // Delete one relationship - cy.get(".spectrum-Table-body").eq(1).within(() => { - cy.get(".spectrum-Table-row").eq(0).click() - cy.wait(500) - }) - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Button").contains("Delete").click({ force: true }) - }) - cy.reload() - // Confirm relationship was deleted - cy.get(".spectrum-Table-body") - .eq(1).find('tr').its('length').should('eq', 1) - }) - - it("should add a query", () => { - // Add query - cy.get(".spectrum-Button").contains("Add query").click({ force: true }) - cy.get(".spectrum-Form-item").eq(0).within(() => { - cy.get("input").type(queryName) - }) - // Insert Query within Fields section - cy.get(".CodeMirror textarea").eq(0) - .type("SELECT * FROM books", { force: true }) - // Intercept query execution - cy.intercept('**/queries/preview').as('query') - cy.get(".spectrum-Button").contains("Run Query").click({ force: true }) - cy.wait(500) - cy.wait("@query") - // Assert against Status Code & Body - cy.get("@query").its('response.statusCode') - .should('eq', 200) - cy.get("@query").its('response.body') - .should('not.be.empty') - // Save query - cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) - cy.get(".hierarchy-items-container").should('contain', queryName) - }) - - it("should switch to schema with no tables", () => { - // Switch Schema - To one without any tables - cy.get(".hierarchy-items-container").contains(datasource).click() - switchSchema("randomText") - - // No tables displayed - cy.get(".spectrum-Body").eq(2).should('contain', 'No tables found') - - // Previously created query should be visible - cy.get(".spectrum-Table-body").should('contain', queryName) - }) - - it("should switch schemas", () => { - // Switch schema - To one with tables - switchSchema("1") - - // Confirm tables exist - Check for specific one - cy.get(".spectrum-Table-body").eq(0).should('contain', 'test') - cy.get(".spectrum-Table-body").eq(0).find('tr').its('length').should('eq', 1) - - // Confirm specific table visible within left nav bar - cy.get(".hierarchy-items-container").should('contain', 'test') - - // Switch back to public schema - switchSchema("public") - - // Confirm tables exist - again - cy.get(".spectrum-Table-body").eq(0).should('contain', 'REGIONS') - cy.get(".spectrum-Table-body").eq(0) - .find('tr').its('length').should('be.gt', 1) - - // Confirm specific table visible within left nav bar - cy.get(".hierarchy-items-container").should('contain', 'REGIONS') - - // No relationships and one query - cy.get(".spectrum-Body").eq(3).should('contain', 'No relationships configured.') - cy.get(".spectrum-Table-body").eq(1).should('contain', queryName) - }) - - it("should duplicate a query", () => { - // Get last nav item - The query - cy.get(".nav-item").last().within(() => { - cy.get(".icon").eq(1).click({ force: true }) - }) - // Select and confirm duplication - cy.get(".spectrum-Menu").contains("Duplicate").click() - cy.get(".nav-item").should('contain', queryName + ' (1)') - }) - - it("should edit a query name", () => { - // Access query - cy.get(".hierarchy-items-container").contains(queryName + ' (1)').click() - - // Rename query - cy.get(".spectrum-Form-item").eq(0).within(() => { - cy.get("input").clear().type(queryRename) - }) - - // Run and Save query - cy.get(".spectrum-Button").contains("Run Query").click({ force: true }) - cy.wait(500) - cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) - cy.get(".nav-item").should('contain', queryRename) - }) - - it("should delete a query", () => { - // Get last nav item - The query - for (let i = 0; i < 2; i++) { - cy.get(".nav-item").last().within(() => { - cy.get(".icon").eq(1).click({ force: true }) - }) - // Select Delete - cy.get(".spectrum-Menu").contains("Delete").click() - cy.get(".spectrum-Button").contains("Delete Query").click({ force: true }) - cy.wait(1000) - } - // Confirm deletion - cy.get(".nav-item").should('not.contain', queryName) - cy.get(".nav-item").should('not.contain', queryRename) - }) - - const switchSchema = (schema) => { - // Edit configuration - Change Schema - cy.get(".spectrum-Textfield").eq(6).within(() => { - cy.get('input').clear().type(schema) - }) - // Save configuration & fetch - cy.get(".spectrum-Button").contains("Save").click({ force: true }) - cy.get(".spectrum-Button").contains("Fetch tables").click({ force: true }) - // Click fetch tables again within modal - cy.get(".spectrum-Dialog-grid").within(() => { - cy.get(".spectrum-Button").contains("Fetch tables").click({ force: true }) - }) - cy.reload() - cy.wait(5000) - } + // Select Delete + cy.get(".spectrum-Menu").contains("Delete").click() + cy.get(".spectrum-Button") + .contains("Delete Query") + .click({ force: true }) + cy.wait(1000) } - }) + // Confirm deletion + cy.get(".nav-item").should("not.contain", queryName) + cy.get(".nav-item").should("not.contain", queryRename) + }) + + const switchSchema = schema => { + // Edit configuration - Change Schema + cy.get(".spectrum-Textfield") + .eq(6) + .within(() => { + cy.get("input").clear().type(schema) + }) + // Save configuration & fetch + cy.get(".spectrum-Button").contains("Save").click({ force: true }) + cy.get(".spectrum-Button") + .contains("Fetch tables") + .click({ force: true }) + // Click fetch tables again within modal + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Button") + .contains("Fetch tables") + .click({ force: true }) + }) + cy.reload() + cy.wait(5000) + } + } + }) }) diff --git a/packages/builder/package.json b/packages/builder/package.json index 4754a5b59d..1c51ad8693 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "1.0.74-alpha.2", + "version": "1.0.76-alpha.1", "license": "GPL-3.0", "private": true, "scripts": { @@ -64,10 +64,10 @@ } }, "dependencies": { - "@budibase/bbui": "^1.0.74-alpha.2", - "@budibase/client": "^1.0.74-alpha.2", - "@budibase/frontend-core": "^1.0.74-alpha.2", - "@budibase/string-templates": "^1.0.74-alpha.2", + "@budibase/bbui": "^1.0.76-alpha.1", + "@budibase/client": "^1.0.76-alpha.1", + "@budibase/frontend-core": "^1.0.76-alpha.1", + "@budibase/string-templates": "^1.0.76-alpha.1", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/components/design/NavigationPanel/ScreenWizard.svelte b/packages/builder/src/components/design/NavigationPanel/ScreenWizard.svelte index 394975e9da..144592035c 100644 --- a/packages/builder/src/components/design/NavigationPanel/ScreenWizard.svelte +++ b/packages/builder/src/components/design/NavigationPanel/ScreenWizard.svelte @@ -12,11 +12,12 @@ let screenName = "" let url = "" let selectedScreens = [] - let roleId = $selectedAccessRole || "BASIC" let showProgressCircle = false let routeError let createdScreens = [] + $: roleId = $selectedAccessRole || "BASIC" + const createScreens = async () => { for (let screen of selectedScreens) { let test = screen.create() diff --git a/packages/cli/package.json b/packages/cli/package.json index 219569d0c7..f5bb80c711 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "1.0.74-alpha.2", + "version": "1.0.76-alpha.1", "description": "Budibase CLI, for developers, self hosting and migrations.", "main": "src/index.js", "bin": { diff --git a/packages/client/package.json b/packages/client/package.json index ad37e20eac..fb6ca3e4d3 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "1.0.74-alpha.2", + "version": "1.0.76-alpha.1", "license": "MPL-2.0", "module": "dist/budibase-client.js", "main": "dist/budibase-client.js", @@ -19,9 +19,9 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/bbui": "^1.0.74-alpha.2", - "@budibase/frontend-core": "^1.0.74-alpha.2", - "@budibase/string-templates": "^1.0.74-alpha.2", + "@budibase/bbui": "^1.0.76-alpha.1", + "@budibase/frontend-core": "^1.0.76-alpha.1", + "@budibase/string-templates": "^1.0.76-alpha.1", "@spectrum-css/button": "^3.0.3", "@spectrum-css/card": "^3.0.3", "@spectrum-css/divider": "^1.0.3", diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index f5c14dfcd4..bb985fff89 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "1.0.74-alpha.2", + "version": "1.0.76-alpha.1", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "^1.0.74-alpha.2", + "@budibase/bbui": "^1.0.76-alpha.1", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/server/package.json b/packages/server/package.json index 3a03fd5b28..46c8eaa125 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "1.0.74-alpha.2", + "version": "1.0.76-alpha.1", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -73,9 +73,9 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "^10.0.3", - "@budibase/backend-core": "^1.0.74-alpha.2", - "@budibase/client": "^1.0.74-alpha.2", - "@budibase/string-templates": "^1.0.74-alpha.2", + "@budibase/backend-core": "^1.0.76-alpha.1", + "@budibase/client": "^1.0.76-alpha.1", + "@budibase/string-templates": "^1.0.76-alpha.1", "@bull-board/api": "^3.7.0", "@bull-board/koa": "^3.7.0", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 84c859d1b3..73717109e6 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "1.0.74-alpha.2", + "version": "1.0.76-alpha.1", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", diff --git a/packages/string-templates/src/index.js b/packages/string-templates/src/index.js index 459386bd67..eedd9423ee 100644 --- a/packages/string-templates/src/index.js +++ b/packages/string-templates/src/index.js @@ -167,8 +167,13 @@ module.exports.disableEscaping = string => { if (matches == null) { return string } - for (let match of matches) { - string = string.replace(match, `{${match}}`) + + // find the unique set + const unique = [...new Set(matches)] + for (let match of unique) { + // add a negative lookahead to exclude any already + const regex = new RegExp(`${match}(?!})`, "g") + string = string.replace(regex, `{${match}}`) } return string } diff --git a/packages/string-templates/test/basic.spec.js b/packages/string-templates/test/basic.spec.js index c5aac2a628..fbd1c5f440 100644 --- a/packages/string-templates/test/basic.spec.js +++ b/packages/string-templates/test/basic.spec.js @@ -194,5 +194,9 @@ describe("check that disabling escaping function works", () => { it("should work with a combination", () => { expect(disableEscaping("{{ name }} welcome to {{{ platform }}}")).toEqual("{{{ name }}} welcome to {{{ platform }}}") }) + + it("should work with multiple escaped", () => { + expect(disableEscaping("{{ name }} welcome to {{ name }}")).toEqual("{{{ name }}} welcome to {{{ name }}}") + }) }) diff --git a/packages/worker/package.json b/packages/worker/package.json index 1635a50c68..fdf6c11c04 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "1.0.74-alpha.2", + "version": "1.0.76-alpha.1", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -34,8 +34,8 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "^1.0.74-alpha.2", - "@budibase/string-templates": "^1.0.74-alpha.2", + "@budibase/backend-core": "^1.0.76-alpha.1", + "@budibase/string-templates": "^1.0.76-alpha.1", "@koa/router": "^8.0.0", "@sentry/node": "^6.0.0", "@techpass/passport-openidconnect": "^0.3.0",