Merge branch 'develop' of github.com:Budibase/budibase into develop
This commit is contained in:
commit
41ef22f01c
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/backend-core",
|
"name": "@budibase/backend-core",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"description": "Budibase backend core libraries used in server and worker",
|
"description": "Budibase backend core libraries used in server and worker",
|
||||||
"main": "dist/src/index.js",
|
"main": "dist/src/index.js",
|
||||||
"types": "dist/src/index.d.ts",
|
"types": "dist/src/index.d.ts",
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
"test:watch": "jest --watchAll"
|
"test:watch": "jest --watchAll"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/types": "^1.0.212-alpha.5",
|
"@budibase/types": "^1.0.212-alpha.8",
|
||||||
"@techpass/passport-openidconnect": "0.3.2",
|
"@techpass/passport-openidconnect": "0.3.2",
|
||||||
"aws-sdk": "2.1030.0",
|
"aws-sdk": "2.1030.0",
|
||||||
"bcrypt": "5.0.1",
|
"bcrypt": "5.0.1",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
exports.SEPARATOR = "_"
|
exports.SEPARATOR = "_"
|
||||||
|
exports.UNICODE_MAX = "\ufff0"
|
||||||
|
|
||||||
const PRE_APP = "app"
|
const PRE_APP = "app"
|
||||||
const PRE_DEV = "dev"
|
const PRE_DEV = "dev"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { newid } from "../hashing"
|
import { newid } from "../hashing"
|
||||||
import { DEFAULT_TENANT_ID, Configs } from "../constants"
|
import { DEFAULT_TENANT_ID, Configs } from "../constants"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import { SEPARATOR, DocumentTypes } from "./constants"
|
import { SEPARATOR, DocumentTypes, UNICODE_MAX } from "./constants"
|
||||||
import { getTenantId, getGlobalDBName, getGlobalDB } from "../tenancy"
|
import { getTenantId, getGlobalDBName, getGlobalDB } from "../tenancy"
|
||||||
import fetch from "node-fetch"
|
import fetch from "node-fetch"
|
||||||
import { doWithDB, allDbs } from "./index"
|
import { doWithDB, allDbs } from "./index"
|
||||||
|
@ -12,8 +12,6 @@ import { isDevApp, isDevAppID } from "./conversions"
|
||||||
import { APP_PREFIX } from "./constants"
|
import { APP_PREFIX } from "./constants"
|
||||||
import * as events from "../events"
|
import * as events from "../events"
|
||||||
|
|
||||||
const UNICODE_MAX = "\ufff0"
|
|
||||||
|
|
||||||
export const ViewNames = {
|
export const ViewNames = {
|
||||||
USER_BY_EMAIL: "by_email",
|
USER_BY_EMAIL: "by_email",
|
||||||
BY_API_KEY: "by_api_key",
|
BY_API_KEY: "by_api_key",
|
||||||
|
@ -93,13 +91,17 @@ export function generateGlobalUserID(id?: any) {
|
||||||
/**
|
/**
|
||||||
* Gets parameters for retrieving users.
|
* Gets parameters for retrieving users.
|
||||||
*/
|
*/
|
||||||
export function getGlobalUserParams(globalId: any, otherProps = {}) {
|
export function getGlobalUserParams(globalId: any, otherProps: any = {}) {
|
||||||
if (!globalId) {
|
if (!globalId) {
|
||||||
globalId = ""
|
globalId = ""
|
||||||
}
|
}
|
||||||
|
const startkey = otherProps?.startkey
|
||||||
return {
|
return {
|
||||||
...otherProps,
|
...otherProps,
|
||||||
startkey: `${DocumentTypes.USER}${SEPARATOR}${globalId}`,
|
// need to include this incase pagination
|
||||||
|
startkey: startkey
|
||||||
|
? startkey
|
||||||
|
: `${DocumentTypes.USER}${SEPARATOR}${globalId}`,
|
||||||
endkey: `${DocumentTypes.USER}${SEPARATOR}${globalId}${UNICODE_MAX}`,
|
endkey: `${DocumentTypes.USER}${SEPARATOR}${globalId}${UNICODE_MAX}`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,6 +436,26 @@ export const getPlatformUrl = async (opts = { tenantAware: true }) => {
|
||||||
return platformUrl
|
return platformUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function pagination(
|
||||||
|
data: any[],
|
||||||
|
pageSize: number,
|
||||||
|
{ paginate, property } = { paginate: true, property: "_id" }
|
||||||
|
) {
|
||||||
|
if (!paginate) {
|
||||||
|
return { data, hasNextPage: false }
|
||||||
|
}
|
||||||
|
const hasNextPage = data.length > pageSize
|
||||||
|
let nextPage = undefined
|
||||||
|
if (hasNextPage) {
|
||||||
|
nextPage = property ? data[pageSize]?.[property] : data[pageSize]?._id
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
data: data.slice(0, pageSize),
|
||||||
|
hasNextPage,
|
||||||
|
nextPage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function getScopedConfig(db: any, params: any) {
|
export async function getScopedConfig(db: any, params: any) {
|
||||||
const configDoc = await getScopedFullConfig(db, params)
|
const configDoc = await getScopedFullConfig(db, params)
|
||||||
return configDoc && configDoc.config ? configDoc.config : configDoc
|
return configDoc && configDoc.config ? configDoc.config : configDoc
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const { ViewNames } = require("./db/utils")
|
const { ViewNames } = require("./db/utils")
|
||||||
const { queryGlobalView } = require("./db/views")
|
const { queryGlobalView } = require("./db/views")
|
||||||
|
const { UNICODE_MAX } = require("./db/constants")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an email address this will use a view to search through
|
* Given an email address this will use a view to search through
|
||||||
|
@ -19,3 +20,24 @@ exports.getGlobalUserByEmail = async email => {
|
||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a starts with search on the global email view.
|
||||||
|
*/
|
||||||
|
exports.searchGlobalUsersByEmail = async (email, opts) => {
|
||||||
|
if (typeof email !== "string") {
|
||||||
|
throw new Error("Must provide a string to search by")
|
||||||
|
}
|
||||||
|
const lcEmail = email.toLowerCase()
|
||||||
|
// handle if passing up startkey for pagination
|
||||||
|
const startkey = opts && opts.startkey ? opts.startkey : lcEmail
|
||||||
|
let response = await queryGlobalView(ViewNames.USER_BY_EMAIL, {
|
||||||
|
...opts,
|
||||||
|
startkey,
|
||||||
|
endkey: `${lcEmail}${UNICODE_MAX}`,
|
||||||
|
})
|
||||||
|
if (!response) {
|
||||||
|
response = []
|
||||||
|
}
|
||||||
|
return Array.isArray(response) ? response : [response]
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/bbui",
|
"name": "@budibase/bbui",
|
||||||
"description": "A UI solution used in the different Budibase projects.",
|
"description": "A UI solution used in the different Budibase projects.",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"module": "dist/bbui.es.js",
|
"module": "dist/bbui.es.js",
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adobe/spectrum-css-workflow-icons": "^1.2.1",
|
"@adobe/spectrum-css-workflow-icons": "^1.2.1",
|
||||||
"@budibase/string-templates": "^1.0.212-alpha.5",
|
"@budibase/string-templates": "^1.0.212-alpha.8",
|
||||||
"@spectrum-css/actionbutton": "^1.0.1",
|
"@spectrum-css/actionbutton": "^1.0.1",
|
||||||
"@spectrum-css/actiongroup": "^1.0.1",
|
"@spectrum-css/actiongroup": "^1.0.1",
|
||||||
"@spectrum-css/avatar": "^3.0.2",
|
"@spectrum-css/avatar": "^3.0.2",
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
"HOST_IP": ""
|
"HOST_IP": ""
|
||||||
},
|
},
|
||||||
"retries": {
|
"retries": {
|
||||||
"runMode": 2,
|
"runMode": 1,
|
||||||
"openMode": 0
|
"openMode": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,18 +16,15 @@ filterTests(['all'], () => {
|
||||||
|
|
||||||
it("should add form with multi select picker, containing 5 options", () => {
|
it("should add form with multi select picker, containing 5 options", () => {
|
||||||
cy.navigateToFrontend()
|
cy.navigateToFrontend()
|
||||||
cy.wait(500)
|
|
||||||
// Add data provider
|
// Add data provider
|
||||||
cy.get(interact.CATEGORY_DATA).click()
|
cy.get(interact.CATEGORY_DATA, { timeout: 500 }).click()
|
||||||
cy.get(interact.COMPONENT_DATA_PROVIDER).click()
|
cy.get(interact.COMPONENT_DATA_PROVIDER).click()
|
||||||
cy.get(interact.DATASOURCE_PROP_CONTROL).click()
|
cy.get(interact.DATASOURCE_PROP_CONTROL).click()
|
||||||
cy.get(interact.DROPDOWN).contains("Multi Data").click()
|
cy.get(interact.DROPDOWN).contains("Multi Data").click()
|
||||||
cy.wait(500)
|
|
||||||
// Add Form with schema to match table
|
// Add Form with schema to match table
|
||||||
cy.addComponent("Form", "Form")
|
cy.addComponent("Form", "Form")
|
||||||
cy.get(interact.DATASOURCE_PROP_CONTROL).click()
|
cy.get(interact.DATASOURCE_PROP_CONTROL).click()
|
||||||
cy.get(interact.DROPDOWN).contains("Multi Data").click()
|
cy.get(interact.DROPDOWN).contains("Multi Data").click()
|
||||||
cy.wait(500)
|
|
||||||
// Add multi-select picker to form
|
// Add multi-select picker to form
|
||||||
cy.addComponent("Form", "Multi-select Picker").then(componentId => {
|
cy.addComponent("Form", "Multi-select Picker").then(componentId => {
|
||||||
cy.get(interact.DATASOURCE_FIELD_CONTROL).type("Test Data").type("{enter}")
|
cy.get(interact.DATASOURCE_FIELD_CONTROL).type("Test Data").type("{enter}")
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
import filterTests from "../../support/filterTests"
|
||||||
|
const interact = require('../../support/interact')
|
||||||
|
|
||||||
|
filterTests(["smoke", "all"], () => {
|
||||||
|
context("Account Portals", () => {
|
||||||
|
|
||||||
|
const bbUserEmail = "bbuser@test.com"
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
cy.login()
|
||||||
|
cy.deleteApp("Cypress Tests")
|
||||||
|
cy.createApp("Cypress Tests")
|
||||||
|
|
||||||
|
// Create new user
|
||||||
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 1000})
|
||||||
|
cy.createUser(bbUserEmail)
|
||||||
|
cy.contains("bbuser").click()
|
||||||
|
cy.wait(500)
|
||||||
|
|
||||||
|
// Reset password
|
||||||
|
cy.get(".spectrum-ActionButton-label", { timeout: 2000 }).contains("Force password reset").click({ force: true })
|
||||||
|
|
||||||
|
cy.get(".spectrum-Dialog-grid")
|
||||||
|
.find(interact.SPECTRUM_TEXTFIELD_INPUT).invoke('val').as('pwd')
|
||||||
|
|
||||||
|
cy.get(interact.SPECTRUM_BUTTON).contains("Reset password").click({ force: true })
|
||||||
|
|
||||||
|
// Login as new user and set password
|
||||||
|
cy.logOut()
|
||||||
|
cy.get('@pwd').then((pwd) => {
|
||||||
|
cy.login(bbUserEmail, pwd)
|
||||||
|
})
|
||||||
|
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).eq(i).type("test")
|
||||||
|
}
|
||||||
|
cy.get(interact.SPECTRUM_BUTTON).contains("Reset your password").click({ force: true })
|
||||||
|
cy.logoutNoAppGrid()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should verify Admin Portal", () => {
|
||||||
|
cy.login()
|
||||||
|
cy.contains("Users").click()
|
||||||
|
cy.contains("bbuser").click()
|
||||||
|
|
||||||
|
// Enable Development & Administration access
|
||||||
|
cy.wait(500)
|
||||||
|
for (let i = 4; i < 6; i++) {
|
||||||
|
cy.get(interact.FIELD).eq(i).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_SWITCH_INPUT).click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_SWITCH_INPUT).should('be.enabled')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
bbUserLogin()
|
||||||
|
|
||||||
|
// Verify available options for Admin portal
|
||||||
|
cy.get(".spectrum-SideNav")
|
||||||
|
.should('contain', 'Apps')
|
||||||
|
//.and('contain', 'Usage')
|
||||||
|
.and('contain', 'Users')
|
||||||
|
.and('contain', 'Auth')
|
||||||
|
.and('contain', 'Email')
|
||||||
|
.and('contain', 'Organisation')
|
||||||
|
.and('contain', 'Theming')
|
||||||
|
.and('contain', 'Update')
|
||||||
|
//.and('contain', 'Upgrade')
|
||||||
|
|
||||||
|
cy.logOut()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should verify Development Portal", () => {
|
||||||
|
// Only Development access should be enabled
|
||||||
|
cy.login()
|
||||||
|
cy.contains("Users").click()
|
||||||
|
cy.contains("bbuser").click()
|
||||||
|
cy.wait(500)
|
||||||
|
cy.get(interact.FIELD).eq(5).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_SWITCH_INPUT).click({ force: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
bbUserLogin()
|
||||||
|
|
||||||
|
// Verify available options for Admin portal
|
||||||
|
cy.get(interact.SPECTRUM_SIDENAV)
|
||||||
|
.should('contain', 'Apps')
|
||||||
|
//.and('contain', 'Usage')
|
||||||
|
.and('not.contain', 'Users')
|
||||||
|
.and('not.contain', 'Auth')
|
||||||
|
.and('not.contain', 'Email')
|
||||||
|
.and('not.contain', 'Organisation')
|
||||||
|
.and('contain', 'Theming')
|
||||||
|
.and('not.contain', 'Update')
|
||||||
|
.and('not.contain', 'Upgrade')
|
||||||
|
|
||||||
|
cy.logOut()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should verify Standard Portal", () => {
|
||||||
|
// Development access should be disabled (Admin access is already disabled)
|
||||||
|
cy.login()
|
||||||
|
cy.contains("Users").click()
|
||||||
|
cy.contains("bbuser").click()
|
||||||
|
cy.wait(500)
|
||||||
|
cy.get(interact.FIELD).eq(4).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_SWITCH_INPUT).click({ force: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
bbUserLogin()
|
||||||
|
|
||||||
|
// Verify Standard Portal
|
||||||
|
cy.get(interact.SPECTRUM_SIDENAV).should('not.exist') // No config sections
|
||||||
|
cy.get(interact.CREATE_APP_BUTTON).should('not.exist') // No create app button
|
||||||
|
cy.get(".app").should('not.exist') // No apps -> no roles assigned to user
|
||||||
|
cy.get(interact.CONTAINER).should('contain', bbUserEmail) // Message containing users email
|
||||||
|
|
||||||
|
cy.logoutNoAppGrid()
|
||||||
|
})
|
||||||
|
|
||||||
|
const bbUserLogin = () => {
|
||||||
|
// Login as bbuser
|
||||||
|
cy.logOut()
|
||||||
|
cy.login(bbUserEmail, "test")
|
||||||
|
}
|
||||||
|
|
||||||
|
after(() => {
|
||||||
|
cy.login()
|
||||||
|
// Delete BB user
|
||||||
|
cy.deleteUser(bbUserEmail)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -1,28 +1,34 @@
|
||||||
import filterTests from "../support/filterTests"
|
import filterTests from "../../support/filterTests"
|
||||||
const interact = require('../support/interact')
|
const interact = require('../../support/interact')
|
||||||
|
|
||||||
filterTests(["smoke", "all"], () => {
|
filterTests(["smoke", "all"], () => {
|
||||||
context("Create a User and Assign Roles", () => {
|
context("User Management", () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.login()
|
cy.login()
|
||||||
cy.deleteApp("Cypress Tests")
|
cy.deleteApp("Cypress Tests")
|
||||||
cy.createApp("Cypress Tests")
|
cy.createApp("Cypress Tests")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should create a user", () => {
|
it("should create a user via basic onboarding", () => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 1000})
|
||||||
cy.wait(1000)
|
|
||||||
cy.createUser("bbuser@test.com")
|
cy.createUser("bbuser@test.com")
|
||||||
cy.get(interact.SPECTRUM_TABLE).should("contain", "bbuser")
|
cy.get(interact.SPECTRUM_TABLE).should("contain", "bbuser")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should confirm there is No Access for a New User", () => {
|
it("should confirm basic permission for a New User", () => {
|
||||||
// Click into the user
|
// Basic permission = development & administraton disabled
|
||||||
cy.contains("bbuser").click()
|
cy.contains("bbuser").click()
|
||||||
|
// Confirm development and admin access are disabled
|
||||||
|
for (let i = 4; i < 6; i++) {
|
||||||
cy.wait(500)
|
cy.wait(500)
|
||||||
// Get No Access table - Confirm it has apps in it
|
cy.get(interact.FIELD).eq(i).within(() => {
|
||||||
cy.get(interact.SPECTRUM_TABLE).eq(1).should("not.contain", "No rows found")
|
//cy.get(interact.SPECTRUM_SWITCH_INPUT).should('be.disabled')
|
||||||
// Get Configure Roles table - Confirm it has no apps
|
cy.get(".spectrum-Switch-switch").should('not.be.checked')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Existing apps appear within the No Access table
|
||||||
|
cy.get(interact.SPECTRUM_TABLE, { timeout: 500 }).eq(1).should("not.contain", "No rows found")
|
||||||
|
// Configure roles table should not contain apps
|
||||||
cy.get(interact.SPECTRUM_TABLE).eq(0).contains("No rows found")
|
cy.get(interact.SPECTRUM_TABLE).eq(0).contains("No rows found")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -40,20 +46,16 @@ filterTests(["smoke", "all"], () => {
|
||||||
cy.createApp(name)
|
cy.createApp(name)
|
||||||
} else {
|
} else {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(500)
|
cy.get(interact.CREATE_APP_BUTTON, { timeout: 1000 }).click({ force: true })
|
||||||
cy.get(interact.CREATE_APP_BUTTON).click({ force: true })
|
|
||||||
cy.createAppFromScratch(name)
|
cy.createAppFromScratch(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Navigate back to the user
|
// Navigate back to the user
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 500})
|
||||||
cy.wait(500)
|
|
||||||
cy.get(interact.SPECTRUM_SIDENAV).contains("Users").click()
|
cy.get(interact.SPECTRUM_SIDENAV).contains("Users").click()
|
||||||
cy.wait(500)
|
cy.get(interact.SPECTRUM_TABLE, { timeout: 500 }).contains("bbuser").click()
|
||||||
cy.get(interact.SPECTRUM_TABLE).contains("bbuser").click()
|
|
||||||
cy.wait(1000)
|
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
cy.get(interact.SPECTRUM_TABLE, { timeout: 3000})
|
cy.get(interact.SPECTRUM_TABLE, { timeout: 3000})
|
||||||
.eq(1)
|
.eq(1)
|
||||||
|
@ -62,31 +64,28 @@ filterTests(["smoke", "all"], () => {
|
||||||
.find(interact.SPECTRUM_TABLE_CELL)
|
.find(interact.SPECTRUM_TABLE_CELL)
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.click()
|
.click()
|
||||||
cy.wait(500)
|
cy.get(interact.SPECTRUM_DIALOG_GRID, { timeout: 500 })
|
||||||
cy.get(interact.SPECTRUM_DIALOG_GRID)
|
|
||||||
.contains("Choose an option")
|
.contains("Choose an option")
|
||||||
.click()
|
.click()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
cy.wait(1000)
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
cy.get(interact.SPECTRUM_MENU).contains("Admin").click({ force: true })
|
cy.get(interact.SPECTRUM_MENU, { timeout: 1000 }).contains("Admin").click({ force: true })
|
||||||
}
|
}
|
||||||
else if (i == 1) {
|
else if (i == 1) {
|
||||||
cy.get(interact.SPECTRUM_MENU).contains("Power").click({ force: true })
|
cy.get(interact.SPECTRUM_MENU, { timeout: 1000 }).contains("Power").click({ force: true })
|
||||||
}
|
}
|
||||||
else if (i == 2) {
|
else if (i == 2) {
|
||||||
cy.get(interact.SPECTRUM_MENU).contains("Basic").click({ force: true })
|
cy.get(interact.SPECTRUM_MENU, { timeout: 1000 }).contains("Basic").click({ force: true })
|
||||||
}
|
}
|
||||||
cy.wait(1000)
|
cy.get(interact.SPECTRUM_BUTTON, { timeout: 1000 })
|
||||||
cy.get(interact.SPECTRUM_BUTTON)
|
|
||||||
.contains("Update role")
|
.contains("Update role")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
})
|
})
|
||||||
cy.reload()
|
cy.reload()
|
||||||
|
cy.wait(1000)
|
||||||
}
|
}
|
||||||
// Confirm roles exist within Configure roles table
|
// Confirm roles exist within Configure roles table
|
||||||
cy.wait(2000)
|
cy.get(interact.SPECTRUM_TABLE, { timeout: 2000 })
|
||||||
cy.get(interact.SPECTRUM_TABLE)
|
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.within(assginedRoles => {
|
.within(assginedRoles => {
|
||||||
expect(assginedRoles).to.contain("Admin")
|
expect(assginedRoles).to.contain("Admin")
|
||||||
|
@ -112,21 +111,19 @@ filterTests(["smoke", "all"], () => {
|
||||||
.click()
|
.click()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
cy.get(interact.SPECTRUM_PICKER).eq(1).click({ force: true })
|
cy.get(interact.SPECTRUM_PICKER).eq(1).click({ force: true })
|
||||||
cy.wait(500)
|
cy.get(interact.SPECTRUM_POPOVER, { timeout: 500 }).contains("No Access").click()
|
||||||
cy.get(interact.SPECTRUM_POPOVER).contains("No Access").click()
|
|
||||||
})
|
})
|
||||||
cy.get(interact.SPECTRUM_BUTTON)
|
cy.get(interact.SPECTRUM_BUTTON)
|
||||||
.contains("Update role")
|
.contains("Update role")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.wait(1000)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Confirm Configure roles table no longer has any apps in it
|
// Confirm Configure roles table no longer has any apps in it
|
||||||
cy.get(interact.SPECTRUM_TABLE).eq(0).contains("No rows found")
|
cy.get(interact.SPECTRUM_TABLE, { timeout: 1000 }).eq(0).contains("No rows found")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should enable Developer access", () => {
|
it("should enable Developer access and verify application access", () => {
|
||||||
// Enable Developer access
|
// Enable Developer access
|
||||||
cy.get(interact.FIELD)
|
cy.get(interact.FIELD)
|
||||||
.eq(4)
|
.eq(4)
|
||||||
|
@ -158,15 +155,15 @@ filterTests(["smoke", "all"], () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should disable Developer access", () => {
|
it("should disable Developer access and verify application access", () => {
|
||||||
// Disable Developer access
|
// Disable Developer access
|
||||||
cy.get(".field")
|
cy.get(interact.FIELD)
|
||||||
.eq(4)
|
.eq(4)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(".spectrum-Switch-input").click({ force: true })
|
cy.get(".spectrum-Switch-input").click({ force: true })
|
||||||
})
|
})
|
||||||
// Configure roles table should now be empty
|
// Configure roles table should now be empty
|
||||||
cy.get(".container")
|
cy.get(interact.CONTAINER)
|
||||||
.contains("Configure roles")
|
.contains("Configure roles")
|
||||||
.parent()
|
.parent()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
|
@ -174,22 +171,64 @@ filterTests(["smoke", "all"], () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("Should edit user details within user details page", () => {
|
||||||
|
// Add First name
|
||||||
|
cy.get(interact.FIELD, { timeout: 500 }).eq(2).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT, { timeout: 500 }).type("bb")
|
||||||
|
})
|
||||||
|
// Add Last name
|
||||||
|
cy.get(interact.FIELD).eq(3).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).type("test")
|
||||||
|
})
|
||||||
|
cy.get(interact.FIELD).eq(0).click()
|
||||||
|
// Reload page
|
||||||
|
cy.reload()
|
||||||
|
|
||||||
|
// Confirm details have been saved
|
||||||
|
cy.get(interact.FIELD, { timeout: 1000 }).eq(2).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).should('have.value', "bb")
|
||||||
|
})
|
||||||
|
cy.get(interact.FIELD).eq(3).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT, { timeout: 500 }).should('have.value', "test")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should reset the users password", () => {
|
||||||
|
cy.get(interact.REGENERATE, { timeout: 500 }).contains("Force password reset").click({ force: true })
|
||||||
|
|
||||||
|
// Reset password modal
|
||||||
|
cy.get(interact.SPECTRUM_DIALOG_GRID)
|
||||||
|
.find(interact.SPECTRUM_TEXTFIELD_INPUT).invoke('val').as('pwd')
|
||||||
|
cy.get(interact.SPECTRUM_BUTTON).contains("Reset password").click({ force: true })
|
||||||
|
|
||||||
|
// Logout, then login with new password
|
||||||
|
cy.logOut()
|
||||||
|
cy.get('@pwd').then((pwd) => {
|
||||||
|
cy.login("bbuser@test.com", pwd)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Reset password screen
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).eq(i).type("test")
|
||||||
|
}
|
||||||
|
cy.get(interact.SPECTRUM_BUTTON).contains("Reset your password").click({ force: true })
|
||||||
|
|
||||||
|
// Confirm user logged in afer password change
|
||||||
|
cy.get(".avatar > .icon").click({ force: true })
|
||||||
|
|
||||||
|
cy.get(".spectrum-Menu-item").contains("Update user information").click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT)
|
||||||
|
.eq(0)
|
||||||
|
.invoke('val').should('eq', 'bbuser@test.com')
|
||||||
|
|
||||||
|
// Logout and login as previous user
|
||||||
|
cy.logoutNoAppGrid()
|
||||||
|
cy.login()
|
||||||
|
})
|
||||||
|
|
||||||
it("should delete a user", () => {
|
it("should delete a user", () => {
|
||||||
// Click Delete user button
|
cy.deleteUser("bbuser@test.com")
|
||||||
cy.get(interact.SPECTRUM_BUTTON)
|
cy.get(interact.SPECTRUM_TABLE, { timeout: 4000 }).should("not.have.text", "bbuser")
|
||||||
.contains("Delete user")
|
|
||||||
.click({ force: true })
|
|
||||||
.then(() => {
|
|
||||||
// Confirm deletion within modal
|
|
||||||
cy.wait(500)
|
|
||||||
cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => {
|
|
||||||
cy.get(interact.SPECTRUM_BUTTON)
|
|
||||||
.contains("Delete user")
|
|
||||||
.click({ force: true })
|
|
||||||
cy.wait(4000)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
cy.get(interact.SPECTRUM_TABLE).should("not.have.text", "bbuser")
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
|
@ -0,0 +1,108 @@
|
||||||
|
import filterTests from "../../support/filterTests"
|
||||||
|
const interact = require('../../support/interact')
|
||||||
|
|
||||||
|
filterTests(["smoke", "all"], () => {
|
||||||
|
context("User Settings Menu", () => {
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
cy.login()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should update user information via user settings menu", () => {
|
||||||
|
const fname = "test"
|
||||||
|
const lname = "user"
|
||||||
|
|
||||||
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
|
cy.updateUserInformation(fname, lname)
|
||||||
|
|
||||||
|
// Go to user info and confirm name update
|
||||||
|
cy.contains("Users").click()
|
||||||
|
cy.contains("test@test.com").click()
|
||||||
|
|
||||||
|
cy.get(interact.FIELD, { timeout: 1000 }).eq(2).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).should('have.value', fname)
|
||||||
|
})
|
||||||
|
cy.get(interact.FIELD).eq(3).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).should('have.value', lname)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should allow copying of the users API key", () => {
|
||||||
|
cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_MENU_ITEM).contains("View API key").click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_DIALOG_CONTENT).within(() => {
|
||||||
|
cy.get(interact.SPECTRUM_ICON).click({force: true})
|
||||||
|
})
|
||||||
|
// There may be timing issues with this on the smoke build
|
||||||
|
cy.wait(500)
|
||||||
|
cy.get(".spectrum-Toast-content")
|
||||||
|
.contains("URL copied to clipboard")
|
||||||
|
.should("be.visible")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should allow API key regeneration", () => {
|
||||||
|
// Get initial API key value
|
||||||
|
cy.get(interact.SPECTRUM_DIALOG_CONTENT)
|
||||||
|
.find(interact.SPECTRUM_TEXTFIELD_INPUT).invoke('val').as('keyOne')
|
||||||
|
|
||||||
|
// Click re-generate key button
|
||||||
|
cy.get("button").contains("Re-generate key").click({ force: true })
|
||||||
|
|
||||||
|
// Verify API key was changed
|
||||||
|
cy.get(interact.SPECTRUM_DIALOG_CONTENT).within(() => {
|
||||||
|
cy.get('@keyOne').then((keyOne) => {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).invoke('val').should('not.eq', keyOne)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
cy.closeModal()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should update password", () => {
|
||||||
|
// Access Update password modal
|
||||||
|
cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_MENU_ITEM).contains("Update password").click({ force: true })
|
||||||
|
|
||||||
|
// Enter new password and update
|
||||||
|
cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => {
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
// password set to 'newpwd'
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).eq(i).type("newpwd")
|
||||||
|
}
|
||||||
|
cy.get("button").contains("Update password").click({ force: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
// Logout & in with new password
|
||||||
|
cy.logOut()
|
||||||
|
cy.login("test@test.com", "newpwd")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should open and close developer mode", () => {
|
||||||
|
cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ force: true })
|
||||||
|
|
||||||
|
// Close developer mode & verify
|
||||||
|
cy.get(interact.SPECTRUM_MENU_ITEM).contains("Close developer mode").click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_SIDENAV).should('not.exist') // No config sections
|
||||||
|
cy.get(interact.CREATE_APP_BUTTON).should('not.exist') // No create app button
|
||||||
|
cy.get(".app").should('not.exist') // At least one app should be available
|
||||||
|
|
||||||
|
// Open developer mode & verify
|
||||||
|
cy.get(".avatar > .icon").click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_MENU_ITEM).contains("Open developer mode").click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_SIDENAV).should('exist') // config sections available
|
||||||
|
cy.get(interact.CREATE_APP_BUTTON).should('exist') // create app button available
|
||||||
|
cy.get(interact.APP_TABLE).should('exist') // App table available
|
||||||
|
})
|
||||||
|
|
||||||
|
after(() => {
|
||||||
|
// Change password back to original value
|
||||||
|
cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_MENU_ITEM).contains("Update password").click({ force: true })
|
||||||
|
cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => {
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).eq(i).type("test")
|
||||||
|
}
|
||||||
|
cy.get("button").contains("Update password").click({ force: true })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -136,7 +136,6 @@ filterTests(["all"], () => {
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(".confirm-wrap button").click({ force: true })
|
cy.get(".confirm-wrap button").click({ force: true })
|
||||||
})
|
})
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.get(".appTable .app-row-actions button")
|
cy.get(".appTable .app-row-actions button")
|
||||||
|
@ -158,12 +157,9 @@ filterTests(["all"], () => {
|
||||||
.contains("Manage")
|
.contains("Manage")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.wait(1000)
|
cy.get(".edit-hover", { timeout: 1000 }).eq(0).click({ force: true })
|
||||||
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
|
// Select random icon
|
||||||
|
cy.wait(400)
|
||||||
cy.get(".grid").within(() => {
|
cy.get(".grid").within(() => {
|
||||||
cy.get(".icon-item")
|
cy.get(".icon-item")
|
||||||
.eq(Math.floor(Math.random() * 23) + 1)
|
.eq(Math.floor(Math.random() * 23) + 1)
|
||||||
|
@ -182,6 +178,7 @@ filterTests(["all"], () => {
|
||||||
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 icon has changed from default
|
||||||
// Confirm colour has been applied
|
// Confirm colour has been applied
|
||||||
|
cy.get(".spectrum-ActionButton-label").contains("Back").click({ force: true })
|
||||||
cy.get(".appTable", { timeout: 2000 }).within(() => {
|
cy.get(".appTable", { timeout: 2000 }).within(() => {
|
||||||
cy.get("[aria-label]")
|
cy.get("[aria-label]")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
|
@ -265,10 +262,9 @@ filterTests(["all"], () => {
|
||||||
//Downgrade the app for the test
|
//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.reload()
|
||||||
cy.wait(1000)
|
|
||||||
cy.log("Current deployment version: " + clientPackage.version)
|
cy.log("Current deployment version: " + clientPackage.version)
|
||||||
|
|
||||||
cy.get(".version-status a").contains("Update").click()
|
cy.get(".version-status a", { timeout: 1000 }).contains("Update").click()
|
||||||
cy.get(".spectrum-Tabs-item.is-selected").contains("Settings")
|
cy.get(".spectrum-Tabs-item.is-selected").contains("Settings")
|
||||||
|
|
||||||
cy.get(".version-section .page-action button")
|
cy.get(".version-section .page-action button")
|
||||||
|
@ -336,8 +332,7 @@ filterTests(["all"], () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(1000)
|
cy.get(".appTable .app-row-actions button", { timeout: 1000 })
|
||||||
cy.get(".appTable .app-row-actions button")
|
|
||||||
.contains("Manage")
|
.contains("Manage")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
|
@ -345,8 +340,7 @@ filterTests(["all"], () => {
|
||||||
cy.get(".spectrum-Tabs-item.is-selected").contains("Settings")
|
cy.get(".spectrum-Tabs-item.is-selected").contains("Settings")
|
||||||
|
|
||||||
cy.get(".details-section .page-action .spectrum-Button").scrollIntoView()
|
cy.get(".details-section .page-action .spectrum-Button").scrollIntoView()
|
||||||
cy.wait(1000)
|
cy.get(".details-section .page-action .spectrum-Button", { timeout: 1000 }).should(
|
||||||
cy.get(".details-section .page-action .spectrum-Button").should(
|
|
||||||
"be.disabled"
|
"be.disabled"
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -381,21 +375,15 @@ filterTests(["all"], () => {
|
||||||
.should("be.visible")
|
.should("be.visible")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Should allow unpublishing of the application", () => {
|
it("Should allow unpublishing of the application via the Unpublish link", () => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.get(".appTable .app-row-actions button")
|
cy.get(".appTable .app-row-actions button")
|
||||||
.contains("Manage")
|
.contains("Manage")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.get(".app-overview-actions-icon > .icon").click({ force: true })
|
|
||||||
|
|
||||||
cy.get("[data-cy='app-overview-menu-popover']")
|
cy.get(`[data-cy="app-status"]`).within(() => {
|
||||||
.eq(0)
|
cy.contains("Unpublish").click({ force: true })
|
||||||
.within(() => {
|
|
||||||
cy.get(".spectrum-Menu-item")
|
|
||||||
.contains("Unpublish")
|
|
||||||
.click({ force: true })
|
|
||||||
cy.wait(500)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.get("[data-cy='unpublish-modal']")
|
cy.get("[data-cy='unpublish-modal']")
|
||||||
|
@ -406,9 +394,8 @@ filterTests(["all"], () => {
|
||||||
|
|
||||||
cy.get(".overview-tab [data-cy='app-status']").within(() => {
|
cy.get(".overview-tab [data-cy='app-status']").within(() => {
|
||||||
cy.get(".status-display").contains("Unpublished")
|
cy.get(".status-display").contains("Unpublished")
|
||||||
cy.get(".status-display .icon svg[aria-label='GlobeStrike']").should(
|
cy.get(".status-display .icon svg[aria-label='GlobeStrike']")
|
||||||
"exist"
|
.should("exist")
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,8 @@ filterTests(['all'], () => {
|
||||||
|
|
||||||
it("Should reflect the unpublished status correctly", () => {
|
it("Should reflect the unpublished status correctly", () => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
cy.get(interact.APP_TABLE_STATUS).eq(0)
|
cy.get(interact.APP_TABLE_STATUS, { timeout: 3000 }).eq(0)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.contains("Unpublished")
|
cy.contains("Unpublished")
|
||||||
cy.get(interact.GLOBESTRIKE).should("exist")
|
cy.get(interact.GLOBESTRIKE).should("exist")
|
||||||
|
@ -35,11 +34,10 @@ filterTests(['all'], () => {
|
||||||
cy.get(interact.DEPLOY_APP_MODAL).should("be.visible")
|
cy.get(interact.DEPLOY_APP_MODAL).should("be.visible")
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(interact.SPECTRUM_BUTTON).contains("Publish").click({ force : true })
|
cy.get(interact.SPECTRUM_BUTTON).contains("Publish").click({ force : true })
|
||||||
cy.wait(1000)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Verify that the app url is presented correctly to the user
|
//Verify that the app url is presented correctly to the user
|
||||||
cy.get(interact.DEPLOY_SUCCESS_MODAL)
|
cy.get(interact.DEPLOY_SUCCESS_MODAL, { timeout: 1000 })
|
||||||
.should("be.visible")
|
.should("be.visible")
|
||||||
.within(() => {
|
.within(() => {
|
||||||
let appUrl = Cypress.config().baseUrl + '/app/cypress-tests'
|
let appUrl = Cypress.config().baseUrl + '/app/cypress-tests'
|
||||||
|
@ -48,9 +46,8 @@ filterTests(['all'], () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
cy.get(interact.APP_TABLE_STATUS).eq(0)
|
cy.get(interact.APP_TABLE_STATUS, { timeout: 3000 }).eq(0)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.contains("Published")
|
cy.contains("Published")
|
||||||
cy.get(interact.GLOBE).should("exist")
|
cy.get(interact.GLOBE).should("exist")
|
||||||
|
@ -58,7 +55,7 @@ filterTests(['all'], () => {
|
||||||
|
|
||||||
cy.get(interact.APP_TABLE_ROW_ACTION).eq(0)
|
cy.get(interact.APP_TABLE_ROW_ACTION).eq(0)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(interact.SPECTRUM_BUTTON).contains("View")
|
cy.get(interact.SPECTRUM_BUTTON).contains("Manage")
|
||||||
cy.get(interact.SPECTRUM_BUTTON).contains("Edit").click({ force: true })
|
cy.get(interact.SPECTRUM_BUTTON).contains("Edit").click({ force: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -83,24 +80,25 @@ filterTests(['all'], () => {
|
||||||
cy.get("svg[aria-label='Globe']").should("exist")
|
cy.get("svg[aria-label='Globe']").should("exist")
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.get(interact.APP_TABLE_ROW_ACTION).eq(0)
|
cy.get(interact.APP_TABLE).eq(0)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(interact.SPECTRUM_BUTTON).contains("View")
|
|
||||||
cy.get(interact.APP_TABLE_APP_NAME).click({ force: true })
|
cy.get(interact.APP_TABLE_APP_NAME).click({ force: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.get(interact.SPECTRUM_LINK).contains('Unpublish').click();
|
cy.get(interact.DEPLOYMENT_TOP_NAV).click()
|
||||||
|
cy.get(interact.PUBLISH_POPOVER_ACTION).click({ force: true })
|
||||||
|
cy.get(interact.UNPUBLISH_MODAL)
|
||||||
|
.within(() => {
|
||||||
|
cy.get(interact.CONFIRM_WRAP_BUTTON).click({ force: true })
|
||||||
|
})
|
||||||
|
|
||||||
cy.get(interact.UNPUBLISH_MODAL).should("be.visible")
|
cy.get(interact.UNPUBLISH_MODAL).should("be.visible")
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(interact.CONFIRM_WRAP_BUTTON).click({ force: true }
|
cy.get(interact.CONFIRM_WRAP_BUTTON).click({ force: true }
|
||||||
)})
|
)})
|
||||||
|
|
||||||
cy.get(interact.DEPLOYMENT_TOP_NAV_GLOBESTRIKE).should("exist")
|
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
|
cy.get(interact.APP_TABLE_STATUS, { timeout: 1000 }).eq(0).contains("Unpublished")
|
||||||
cy.get(interact.APP_TABLE_STATUS).eq(0).contains("Unpublished")
|
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,6 +5,7 @@ filterTests(['smoke', 'all'], () => {
|
||||||
context("Auto Screens UI", () => {
|
context("Auto Screens UI", () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.login()
|
cy.login()
|
||||||
|
cy.deleteAllApps()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should disable the autogenerated screen options if no sources are available", () => {
|
it("should disable the autogenerated screen options if no sources are available", () => {
|
||||||
|
|
|
@ -6,14 +6,14 @@ filterTests(['smoke', 'all'], () => {
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.login()
|
cy.login()
|
||||||
cy.deleteApp("Cypress Tests")
|
cy.deleteAllApps()
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!(Cypress.env("TEST_ENV"))) {
|
if (!(Cypress.env("TEST_ENV"))) {
|
||||||
it("should show the new user UI/UX", () => {
|
it("should show the new user UI/UX", () => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder/portal/apps/create`) //added /portal/apps/create
|
cy.visit(`${Cypress.config().baseUrl}/builder/portal/apps/create`, { timeout: 5000 }) //added /portal/apps/create
|
||||||
|
cy.wait(1000)
|
||||||
cy.get(interact.CREATE_APP_BUTTON).contains('Start from scratch').should("exist")
|
cy.get(interact.CREATE_APP_BUTTON).contains('Start from scratch').should("exist")
|
||||||
cy.get(interact.CREATE_APP_BUTTON).should("exist")
|
|
||||||
|
|
||||||
cy.get(interact.TEMPLATE_CATEGORY_FILTER).should("exist")
|
cy.get(interact.TEMPLATE_CATEGORY_FILTER).should("exist")
|
||||||
cy.get(interact.TEMPLATE_CATEGORY).should("exist")
|
cy.get(interact.TEMPLATE_CATEGORY).should("exist")
|
||||||
|
@ -23,7 +23,7 @@ filterTests(['smoke', 'all'], () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should provide filterable templates", () => {
|
it("should provide filterable templates", () => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000 })
|
||||||
cy.wait(500)
|
cy.wait(500)
|
||||||
|
|
||||||
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
||||||
|
@ -48,11 +48,10 @@ filterTests(['smoke', 'all'], () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should enforce a valid url before submission", () => {
|
it("should enforce a valid url before submission", () => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 10000 })
|
||||||
cy.wait(500)
|
|
||||||
|
|
||||||
// Start create app process. If apps already exist, click second button
|
// Start create app process. If apps already exist, click second button
|
||||||
cy.get(interact.CREATE_APP_BUTTON).click({ force: true })
|
cy.get(interact.CREATE_APP_BUTTON, { timeout: 1000 }).click({ force: true })
|
||||||
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
||||||
.its("body")
|
.its("body")
|
||||||
.then(val => {
|
.then(val => {
|
||||||
|
@ -92,21 +91,16 @@ filterTests(['smoke', 'all'], () => {
|
||||||
|
|
||||||
it("should create the first application from scratch", () => {
|
it("should create the first application from scratch", () => {
|
||||||
const appName = "Cypress Tests"
|
const appName = "Cypress Tests"
|
||||||
cy.createApp(appName)
|
cy.createApp(appName, false)
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
cy.applicationInAppTable(appName)
|
cy.applicationInAppTable(appName)
|
||||||
cy.deleteApp(appName)
|
cy.deleteApp(appName)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should create the first application from scratch with a default name", () => {
|
it("should create the first application from scratch with a default name", () => {
|
||||||
cy.createApp()
|
cy.createApp("", false)
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
cy.applicationInAppTable("My app")
|
cy.applicationInAppTable("My app")
|
||||||
cy.deleteApp("My app")
|
cy.deleteApp("My app")
|
||||||
})
|
})
|
||||||
|
@ -116,26 +110,22 @@ filterTests(['smoke', 'all'], () => {
|
||||||
|
|
||||||
cy.updateUserInformation("Ted", "Userman")
|
cy.updateUserInformation("Ted", "Userman")
|
||||||
|
|
||||||
cy.createApp()
|
cy.createApp("", false)
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
cy.applicationInAppTable("Teds app")
|
cy.applicationInAppTable("Teds app")
|
||||||
cy.deleteApp("Teds app")
|
cy.deleteApp("Teds app")
|
||||||
cy.wait(2000)
|
|
||||||
|
|
||||||
//Accomodate names that end in 'S'
|
//Accomodate names that end in 'S'
|
||||||
cy.updateUserInformation("Chris", "Userman")
|
cy.updateUserInformation("Chris", "Userman")
|
||||||
|
|
||||||
cy.createApp()
|
cy.createApp("", false)
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
cy.applicationInAppTable("Chris app")
|
cy.applicationInAppTable("Chris app")
|
||||||
cy.deleteApp("Chris app")
|
cy.deleteApp("Chris app")
|
||||||
cy.wait(2000)
|
|
||||||
|
|
||||||
cy.updateUserInformation("", "")
|
cy.updateUserInformation("", "")
|
||||||
})
|
})
|
||||||
|
@ -145,7 +135,7 @@ filterTests(['smoke', 'all'], () => {
|
||||||
|
|
||||||
cy.importApp(exportedApp, "")
|
cy.importApp(exportedApp, "")
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 2000 })
|
||||||
|
|
||||||
cy.applicationInAppTable("My app")
|
cy.applicationInAppTable("My app")
|
||||||
|
|
||||||
|
@ -224,14 +214,12 @@ filterTests(['smoke', 'all'], () => {
|
||||||
cy.createApp(appName)
|
cy.createApp(appName)
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(500)
|
|
||||||
|
|
||||||
// Create second app
|
// Create second app
|
||||||
const secondAppName = "Second App Demo"
|
const secondAppName = "Second App Demo"
|
||||||
cy.createApp(secondAppName)
|
cy.createApp(secondAppName)
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(500)
|
|
||||||
|
|
||||||
//Both applications should exist and be searchable
|
//Both applications should exist and be searchable
|
||||||
cy.searchForApplication(appName)
|
cy.searchForApplication(appName)
|
||||||
|
|
|
@ -16,17 +16,15 @@ filterTests(['smoke', 'all'], () => {
|
||||||
cy.get(interact.MODAL_INNER_WRAPPER).within(() => {
|
cy.get(interact.MODAL_INNER_WRAPPER).within(() => {
|
||||||
cy.get("input").type("Add Row")
|
cy.get("input").type("Add Row")
|
||||||
cy.contains("Row Created").click({ force: true })
|
cy.contains("Row Created").click({ force: true })
|
||||||
cy.wait(500)
|
cy.get(interact.SPECTRUM_BUTTON_CTA, { timeout: 500 }).click()
|
||||||
cy.get(interact.SPECTRUM_BUTTON_CTA).click()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Setup trigger
|
// Setup trigger
|
||||||
cy.get(interact.SPECTRUM_PICKER_LABEL).click()
|
cy.get(interact.SPECTRUM_PICKER_LABEL).click()
|
||||||
cy.wait(500)
|
cy.wait(500)
|
||||||
cy.contains("dog").click()
|
cy.contains("dog").click()
|
||||||
cy.wait(2000)
|
|
||||||
// Create action
|
// Create action
|
||||||
cy.get('[aria-label="AddCircle"]').eq(1).click()
|
cy.get('[aria-label="AddCircle"]', { timeout: 2000 }).eq(1).click()
|
||||||
cy.get(interact.MODAL_INNER_WRAPPER).within(() => {
|
cy.get(interact.MODAL_INNER_WRAPPER).within(() => {
|
||||||
cy.wait(1000)
|
cy.wait(1000)
|
||||||
cy.contains("Create Row").trigger('mouseover').click().click()
|
cy.contains("Create Row").trigger('mouseover').click().click()
|
||||||
|
@ -43,11 +41,9 @@ filterTests(['smoke', 'all'], () => {
|
||||||
cy.contains("Finish and test automation").click()
|
cy.contains("Finish and test automation").click()
|
||||||
|
|
||||||
cy.get(interact.MODAL_INNER_WRAPPER).within(() => {
|
cy.get(interact.MODAL_INNER_WRAPPER).within(() => {
|
||||||
cy.wait(1000)
|
cy.get(interact.SPECTRUM_PICKER_LABEL, { timeout: 1000 }).click()
|
||||||
cy.get(interact.SPECTRUM_PICKER_LABEL).click()
|
|
||||||
cy.contains("dog").click()
|
cy.contains("dog").click()
|
||||||
cy.wait(1000)
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT, { timeout: 1000 })
|
||||||
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT)
|
|
||||||
.first()
|
.first()
|
||||||
.type("automationGoodboy")
|
.type("automationGoodboy")
|
||||||
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT)
|
cy.get(interact.SPECTRUM_TEXTFIELD_INPUT)
|
||||||
|
|
|
@ -10,9 +10,8 @@ filterTests(["smoke", "all"], () => {
|
||||||
|
|
||||||
it("should create a new Table", () => {
|
it("should create a new Table", () => {
|
||||||
cy.createTable("dog")
|
cy.createTable("dog")
|
||||||
cy.wait(1000)
|
|
||||||
// Check if Table exists
|
// Check if Table exists
|
||||||
cy.get(interact.TABLE_TITLE_H1).should("have.text", "dog")
|
cy.get(interact.TABLE_TITLE_H1, { timeout: 1000 }).should("have.text", "dog")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("adds a new column to the table", () => {
|
it("adds a new column to the table", () => {
|
||||||
|
@ -40,7 +39,7 @@ filterTests(["smoke", "all"], () => {
|
||||||
|
|
||||||
it("edits a row", () => {
|
it("edits a row", () => {
|
||||||
cy.contains("button", "Edit").click({ force: true })
|
cy.contains("button", "Edit").click({ force: true })
|
||||||
cy.wait(1000)
|
cy.wait(500)
|
||||||
cy.get(interact.SPECTRUM_MODAL_INPUT).clear()
|
cy.get(interact.SPECTRUM_MODAL_INPUT).clear()
|
||||||
cy.get(interact.SPECTRUM_MODAL_INPUT).type("Updated")
|
cy.get(interact.SPECTRUM_MODAL_INPUT).type("Updated")
|
||||||
cy.contains("Save").click()
|
cy.contains("Save").click()
|
||||||
|
@ -63,8 +62,7 @@ filterTests(["smoke", "all"], () => {
|
||||||
cy.addRow([i])
|
cy.addRow([i])
|
||||||
}
|
}
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.wait(2000)
|
cy.get(interact.SPECTRUM_PAGINATION, { timeout: 2000 }).within(() => {
|
||||||
cy.get(interact.SPECTRUM_PAGINATION).within(() => {
|
|
||||||
cy.get(interact.SPECTRUM_ACTION_BUTTON).eq(1).click()
|
cy.get(interact.SPECTRUM_ACTION_BUTTON).eq(1).click()
|
||||||
})
|
})
|
||||||
cy.get(interact.SPECTRUM_PAGINATION).within(() => {
|
cy.get(interact.SPECTRUM_PAGINATION).within(() => {
|
||||||
|
@ -79,10 +77,9 @@ filterTests(["smoke", "all"], () => {
|
||||||
cy.get(interact.SPECTRUM_BUTTON).click({ force: true })
|
cy.get(interact.SPECTRUM_BUTTON).click({ force: true })
|
||||||
})
|
})
|
||||||
cy.get(interact.SPECTRUM_DIALOG_GRID).contains("Delete").click({ force: true })
|
cy.get(interact.SPECTRUM_DIALOG_GRID).contains("Delete").click({ force: true })
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
// Confirm table only has one page
|
// Confirm table only has one page
|
||||||
cy.get(interact.SPECTRUM_PAGINATION).within(() => {
|
cy.get(interact.SPECTRUM_PAGINATION, { timeout: 1000 }).within(() => {
|
||||||
cy.get(interact.SPECTRUM_ACTION_BUTTON).eq(1).should("not.be.enabled")
|
cy.get(interact.SPECTRUM_ACTION_BUTTON).eq(1).should("not.be.enabled")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -69,8 +69,8 @@ filterTests(['smoke', 'all'], () => {
|
||||||
|
|
||||||
cy.get(interact.SPECTRUM_BUTTON).contains("Save").click({ force: true })
|
cy.get(interact.SPECTRUM_BUTTON).contains("Save").click({ force: true })
|
||||||
})
|
})
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
|
cy.wait(1000)
|
||||||
cy.get(interact.TITLE).then($headers => {
|
cy.get(interact.TITLE).then($headers => {
|
||||||
expect($headers).to.have.length(7)
|
expect($headers).to.have.length(7)
|
||||||
const headers = Array.from($headers).map(header =>
|
const headers = Array.from($headers).map(header =>
|
||||||
|
|
|
@ -34,7 +34,6 @@ filterTests(['all'], () => {
|
||||||
Large = 16px */
|
Large = 16px */
|
||||||
it("should test button roundness", () => {
|
it("should test button roundness", () => {
|
||||||
const buttonRoundnessValues = ["0", "4px", "8px", "16px"]
|
const buttonRoundnessValues = ["0", "4px", "8px", "16px"]
|
||||||
cy.wait(1000)
|
|
||||||
// Add button, change roundness and confirm value
|
// Add button, change roundness and confirm value
|
||||||
cy.addComponent("Button", null).then((componentId) => {
|
cy.addComponent("Button", null).then((componentId) => {
|
||||||
buttonRoundnessValues.forEach(function (item, index){
|
buttonRoundnessValues.forEach(function (item, index){
|
||||||
|
|
|
@ -17,11 +17,10 @@ filterTests(['all'], () => {
|
||||||
// Navigate back within datasource wizard
|
// Navigate back within datasource wizard
|
||||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
cy.get(".spectrum-Dialog-grid").within(() => {
|
||||||
cy.get(".spectrum-Button").contains("Back").click({ force: true })
|
cy.get(".spectrum-Button").contains("Back").click({ force: true })
|
||||||
cy.wait(1000)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Select PostgreSQL datasource again
|
// Select PostgreSQL datasource again
|
||||||
cy.get(".item-list").contains(datasource).click()
|
cy.get(".item-list", { timeout: 1000 }).contains(datasource).click()
|
||||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
cy.get(".spectrum-Dialog-grid").within(() => {
|
||||||
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
||||||
})
|
})
|
||||||
|
|
|
@ -111,10 +111,9 @@ filterTests(["all"], () => {
|
||||||
// Save relationship & reload page
|
// Save relationship & reload page
|
||||||
cy.get(".spectrum-Button").contains("Save").click({ force: true })
|
cy.get(".spectrum-Button").contains("Save").click({ force: true })
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.wait(1000)
|
|
||||||
})
|
})
|
||||||
// Confirm table length & relationship name
|
// Confirm table length & relationship name
|
||||||
cy.get(".spectrum-Table")
|
cy.get(".spectrum-Table", { timeout: 1000 })
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.find(".spectrum-Table-row")
|
.find(".spectrum-Table-row")
|
||||||
.its("length")
|
.its("length")
|
||||||
|
@ -136,15 +135,15 @@ filterTests(["all"], () => {
|
||||||
cy.get(".spectrum-Table")
|
cy.get(".spectrum-Table")
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(".spectrum-Table-row").eq(0).click({ force: true })
|
cy.get(".spectrum-Table-cell").eq(0).click({ force: true })
|
||||||
cy.wait(500)
|
|
||||||
})
|
})
|
||||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
cy.get(".spectrum-Dialog-grid", { timeout: 500 }).within(() => {
|
||||||
cy.get(".spectrum-Button")
|
cy.get(".spectrum-Button")
|
||||||
.contains("Delete")
|
.contains("Delete")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
})
|
})
|
||||||
cy.reload()
|
cy.reload()
|
||||||
|
cy.wait(500)
|
||||||
}
|
}
|
||||||
// Confirm relationships no longer exist
|
// Confirm relationships no longer exist
|
||||||
cy.get(".spectrum-Body").should(
|
cy.get(".spectrum-Body").should(
|
||||||
|
@ -217,9 +216,8 @@ filterTests(["all"], () => {
|
||||||
cy.get(".spectrum-Button")
|
cy.get(".spectrum-Button")
|
||||||
.contains("Delete Query")
|
.contains("Delete Query")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.wait(1000)
|
|
||||||
// Confirm deletion
|
// Confirm deletion
|
||||||
cy.get(".nav-item").should("not.contain", queryName)
|
cy.get(".nav-item", { timeout: 1000 }).should("not.contain", queryName)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,7 +20,7 @@ filterTests(["all"], () => {
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.wait(500)
|
cy.wait(500)
|
||||||
// Confirm config contains localhost
|
// Confirm config contains localhost
|
||||||
cy.get(".spectrum-Textfield-input")
|
cy.get(".spectrum-Textfield-input", { timeout: 500 })
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.should("have.value", "localhost")
|
.should("have.value", "localhost")
|
||||||
// Add another Oracle data source, configure & skip table fetch
|
// Add another Oracle data source, configure & skip table fetch
|
||||||
|
@ -140,9 +140,8 @@ filterTests(["all"], () => {
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(".spectrum-Table-row").eq(0).click()
|
cy.get(".spectrum-Table-row").eq(0).click()
|
||||||
cy.wait(500)
|
|
||||||
})
|
})
|
||||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
cy.get(".spectrum-Dialog-grid", { timeout: 500 }).within(() => {
|
||||||
cy.get(".spectrum-Button")
|
cy.get(".spectrum-Button")
|
||||||
.contains("Delete")
|
.contains("Delete")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
|
@ -221,10 +220,9 @@ filterTests(["all"], () => {
|
||||||
cy.get(".spectrum-Button")
|
cy.get(".spectrum-Button")
|
||||||
.contains("Delete Query")
|
.contains("Delete Query")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.wait(1000)
|
|
||||||
|
|
||||||
// Confirm deletion
|
// Confirm deletion
|
||||||
cy.get(".nav-item").should("not.contain", queryName)
|
cy.get(".nav-item", { timeout: 1000 }).should("not.contain", queryName)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -35,6 +35,7 @@ filterTests(["all"], () => {
|
||||||
// Check response from datasource after adding configuration
|
// Check response from datasource after adding configuration
|
||||||
cy.wait("@datasource")
|
cy.wait("@datasource")
|
||||||
cy.get("@datasource").its("response.statusCode").should("eq", 200)
|
cy.get("@datasource").its("response.statusCode").should("eq", 200)
|
||||||
|
cy.wait(2000)
|
||||||
// Confirm fetch tables was successful
|
// Confirm fetch tables was successful
|
||||||
cy.get(".spectrum-Table")
|
cy.get(".spectrum-Table")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
|
@ -113,13 +114,13 @@ filterTests(["all"], () => {
|
||||||
cy.get(".spectrum-Table")
|
cy.get(".spectrum-Table")
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(".spectrum-Table-row").eq(0).click({ force: true })
|
cy.get(".spectrum-Table-cell").eq(0).click({ force: true })
|
||||||
cy.wait(500)
|
|
||||||
})
|
})
|
||||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
cy.get(".spectrum-Dialog-grid", { timeout: 500 }).within(() => {
|
||||||
cy.get(".spectrum-Button").contains("Delete").click({ force: true })
|
cy.get(".spectrum-Button").contains("Delete").click({ force: true })
|
||||||
})
|
})
|
||||||
cy.reload()
|
cy.reload()
|
||||||
|
cy.wait(500)
|
||||||
// Confirm relationship was deleted
|
// Confirm relationship was deleted
|
||||||
cy.get(".spectrum-Table")
|
cy.get(".spectrum-Table")
|
||||||
.eq(1)
|
.eq(1)
|
||||||
|
@ -159,7 +160,7 @@ filterTests(["all"], () => {
|
||||||
switchSchema("randomText")
|
switchSchema("randomText")
|
||||||
|
|
||||||
// No tables displayed
|
// No tables displayed
|
||||||
cy.get(".spectrum-Body").eq(2).should("contain", "No tables found")
|
cy.get(".spectrum-Body", { timeout: 5000 }).eq(2).should("contain", "No tables found")
|
||||||
|
|
||||||
// Previously created query should be visible
|
// Previously created query should be visible
|
||||||
cy.get(".spectrum-Table").should("contain", queryName)
|
cy.get(".spectrum-Table").should("contain", queryName)
|
||||||
|
@ -170,7 +171,7 @@ filterTests(["all"], () => {
|
||||||
switchSchema("1")
|
switchSchema("1")
|
||||||
|
|
||||||
// Confirm tables exist - Check for specific one
|
// Confirm tables exist - Check for specific one
|
||||||
cy.get(".spectrum-Table").eq(0).should("contain", "test")
|
cy.get(".spectrum-Table", { timeout: 5000 }).eq(0).should("contain", "test")
|
||||||
cy.get(".spectrum-Table")
|
cy.get(".spectrum-Table")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.find(".spectrum-Table-row")
|
.find(".spectrum-Table-row")
|
||||||
|
@ -184,7 +185,7 @@ filterTests(["all"], () => {
|
||||||
switchSchema("public")
|
switchSchema("public")
|
||||||
|
|
||||||
// Confirm tables exist - again
|
// Confirm tables exist - again
|
||||||
cy.get(".spectrum-Table").eq(0).should("contain", "REGIONS")
|
cy.get(".spectrum-Table", { timeout: 5000 }).eq(0).should("contain", "REGIONS")
|
||||||
cy.get(".spectrum-Table")
|
cy.get(".spectrum-Table")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.find(".spectrum-Table-row")
|
.find(".spectrum-Table-row")
|
||||||
|
@ -230,7 +231,9 @@ filterTests(["all"], () => {
|
||||||
// Run and Save query
|
// Run and Save query
|
||||||
cy.get(".spectrum-Button").contains("Run Query").click({ force: true })
|
cy.get(".spectrum-Button").contains("Run Query").click({ force: true })
|
||||||
cy.wait(500)
|
cy.wait(500)
|
||||||
cy.get(".spectrum-Button").contains("Save Query").click({ force: true })
|
cy.get(".spectrum-Button", { timeout: 500 }).contains("Save Query").click({ force: true })
|
||||||
|
//cy.reload()
|
||||||
|
//cy.wait(500)
|
||||||
cy.get(".nav-item").should("contain", queryRename)
|
cy.get(".nav-item").should("contain", queryRename)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -247,9 +250,8 @@ filterTests(["all"], () => {
|
||||||
cy.get(".spectrum-Button")
|
cy.get(".spectrum-Button")
|
||||||
.contains("Delete Query")
|
.contains("Delete Query")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.wait(1000)
|
|
||||||
// Confirm deletion
|
// Confirm deletion
|
||||||
cy.get(".nav-item").should("not.contain", queryName)
|
cy.get(".nav-item", { timeout: 1000 }).should("not.contain", queryName)
|
||||||
})
|
})
|
||||||
|
|
||||||
const switchSchema = schema => {
|
const switchSchema = schema => {
|
||||||
|
@ -271,7 +273,7 @@ filterTests(["all"], () => {
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
})
|
})
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.wait(5000)
|
cy.wait(1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -14,8 +14,7 @@ filterTests(["smoke", "all"], () => {
|
||||||
// Select REST data source
|
// Select REST data source
|
||||||
cy.selectExternalDatasource(datasource)
|
cy.selectExternalDatasource(datasource)
|
||||||
// Enter incorrect api & attempt to send query
|
// Enter incorrect api & attempt to send query
|
||||||
cy.wait(500)
|
cy.get(".spectrum-Button", { timeout: 500 }).contains("Add query").click({ force: true })
|
||||||
cy.get(".spectrum-Button").contains("Add query").click({ force: true })
|
|
||||||
cy.intercept("**/preview").as("queryError")
|
cy.intercept("**/preview").as("queryError")
|
||||||
cy.get("input").clear().type("random text")
|
cy.get("input").clear().type("random text")
|
||||||
cy.get(".spectrum-Button").contains("Send").click({ force: true })
|
cy.get(".spectrum-Button").contains("Send").click({ force: true })
|
||||||
|
@ -36,8 +35,7 @@ filterTests(["smoke", "all"], () => {
|
||||||
// createRestQuery confirms query creation
|
// createRestQuery confirms query creation
|
||||||
cy.createRestQuery("GET", restUrl, "/breweries")
|
cy.createRestQuery("GET", restUrl, "/breweries")
|
||||||
// Confirm status code response within REST datasource
|
// Confirm status code response within REST datasource
|
||||||
cy.wait(1000)
|
cy.get(".stats", { timeout: 1000 }).within(() => {
|
||||||
cy.get(".stats").within(() => {
|
|
||||||
cy.get(".spectrum-FieldLabel")
|
cy.get(".spectrum-FieldLabel")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.should("contain", 200)
|
.should("contain", 200)
|
||||||
|
|
|
@ -13,16 +13,13 @@ filterTests(["all"], () => {
|
||||||
const appRename = "Cypress Renamed"
|
const appRename = "Cypress Renamed"
|
||||||
// Rename app, Search for app, Confirm name was changed
|
// Rename app, Search for app, Confirm name was changed
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(500)
|
|
||||||
renameApp(appName, appRename)
|
renameApp(appName, appRename)
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.wait(1000)
|
|
||||||
cy.searchForApplication(appRename)
|
cy.searchForApplication(appRename)
|
||||||
cy.get(interact.APP_TABLE).find(interact.TITLE).should("have.length", 1)
|
cy.get(interact.APP_TABLE).find(interact.TITLE).should("have.length", 1)
|
||||||
cy.applicationInAppTable(appRename)
|
cy.applicationInAppTable(appRename)
|
||||||
// Set app name back to Cypress Tests
|
// Set app name back to Cypress Tests
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.wait(1000)
|
|
||||||
renameApp(appRename, appName)
|
renameApp(appRename, appName)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -43,7 +40,6 @@ filterTests(["all"], () => {
|
||||||
})
|
})
|
||||||
// Rename app, Search for app, Confirm name was changed
|
// Rename app, Search for app, Confirm name was changed
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(500)
|
|
||||||
renameApp(appName, appRename, true)
|
renameApp(appName, appRename, true)
|
||||||
cy.get(interact.APP_TABLE).find(interact.WRAPPER).should("have.length", 1)
|
cy.get(interact.APP_TABLE).find(interact.WRAPPER).should("have.length", 1)
|
||||||
cy.applicationInAppTable(appRename)
|
cy.applicationInAppTable(appRename)
|
||||||
|
@ -52,13 +48,9 @@ filterTests(["all"], () => {
|
||||||
it("Should try to rename an application to have no name", () => {
|
it("Should try to rename an application to have no name", () => {
|
||||||
const appName = "Cypress Tests"
|
const appName = "Cypress Tests"
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(500)
|
|
||||||
renameApp(appName, " ", false, true)
|
renameApp(appName, " ", false, true)
|
||||||
cy.wait(500)
|
|
||||||
// Close modal and confirm name has not been changed
|
// Close modal and confirm name has not been changed
|
||||||
cy.get(interact.SPECTRUM_DIALOG_GRID).contains("Cancel").click()
|
cy.get(interact.SPECTRUM_DIALOG_GRID, { timeout: 1000 }).contains("Cancel").click()
|
||||||
cy.reload()
|
|
||||||
cy.wait(1000)
|
|
||||||
cy.applicationInAppTable(appName)
|
cy.applicationInAppTable(appName)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -66,8 +58,7 @@ filterTests(["all"], () => {
|
||||||
// It is not possible to have applications with the same name
|
// It is not possible to have applications with the same name
|
||||||
const appName = "Cypress Tests"
|
const appName = "Cypress Tests"
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(500)
|
cy.get(interact.SPECTRUM_BUTTON), { timeout: 500 }
|
||||||
cy.get(interact.SPECTRUM_BUTTON)
|
|
||||||
.contains("Create app")
|
.contains("Create app")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.contains(/Start from scratch/).click()
|
cy.contains(/Start from scratch/).click()
|
||||||
|
@ -90,13 +81,10 @@ filterTests(["all"], () => {
|
||||||
const numberName = 12345
|
const numberName = 12345
|
||||||
const specialCharName = "£$%^"
|
const specialCharName = "£$%^"
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(500)
|
|
||||||
renameApp(appName, numberName)
|
renameApp(appName, numberName)
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.wait(1000)
|
|
||||||
cy.applicationInAppTable(numberName)
|
cy.applicationInAppTable(numberName)
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.wait(1000)
|
|
||||||
renameApp(numberName, specialCharName)
|
renameApp(numberName, specialCharName)
|
||||||
cy.get(interact.ERROR).should(
|
cy.get(interact.ERROR).should(
|
||||||
"have.text",
|
"have.text",
|
||||||
|
@ -104,13 +92,12 @@ filterTests(["all"], () => {
|
||||||
)
|
)
|
||||||
// Set app name back to Cypress Tests
|
// Set app name back to Cypress Tests
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.wait(1000)
|
|
||||||
renameApp(numberName, appName)
|
renameApp(numberName, appName)
|
||||||
})
|
})
|
||||||
|
|
||||||
const renameApp = (originalName, changedName, published, noName) => {
|
const renameApp = (originalName, changedName, published, noName) => {
|
||||||
cy.searchForApplication(originalName)
|
cy.searchForApplication(originalName)
|
||||||
cy.get(interact.APP_TABLE).within(() => {
|
cy.get(interact.APP_TABLE, { timeout: 1000 }).within(() => {
|
||||||
cy.get(".app-row-actions button")
|
cy.get(".app-row-actions button")
|
||||||
.contains("Manage")
|
.contains("Manage")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
|
|
|
@ -36,8 +36,8 @@ filterTests(['smoke', 'all'], () => {
|
||||||
cy.get(interact.SPECTRUM_BUTTON_GROUP).within(() => {
|
cy.get(interact.SPECTRUM_BUTTON_GROUP).within(() => {
|
||||||
cy.get(interact.SPECTRUM_BUTTON).contains("Publish").click({ force: true })
|
cy.get(interact.SPECTRUM_BUTTON).contains("Publish").click({ force: true })
|
||||||
})
|
})
|
||||||
cy.wait(1000)
|
cy.wait(1000) // Wait for next modal to finish loading
|
||||||
cy.get(interact.SPECTRUM_BUTTON_GROUP).within(() => {
|
cy.get(interact.SPECTRUM_BUTTON_GROUP, { timeout: 1000 }).within(() => {
|
||||||
cy.get(interact.SPECTRUM_BUTTON).contains("Done").click({ force: true })
|
cy.get(interact.SPECTRUM_BUTTON).contains("Done").click({ force: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -50,18 +50,17 @@ filterTests(['smoke', 'all'], () => {
|
||||||
cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => {
|
cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => {
|
||||||
// Click Revert
|
// Click Revert
|
||||||
cy.get(interact.SPECTRUM_BUTTON).contains("Revert").click({ force: true })
|
cy.get(interact.SPECTRUM_BUTTON).contains("Revert").click({ force: true })
|
||||||
cy.wait(1000)
|
cy.wait(2000) // Wait for app to finish reverting
|
||||||
})
|
})
|
||||||
// Confirm Paragraph component is still visible
|
// Confirm Paragraph component is still visible
|
||||||
cy.get(interact.ROOT).contains("New Paragraph")
|
cy.get(interact.ROOT, { timeout: 1000 }).contains("New Paragraph")
|
||||||
// Confirm Button component is not visible
|
// Confirm Button component is not visible
|
||||||
cy.get(interact.ROOT).should("not.have.text", "New Button")
|
cy.get(interact.ROOT, { timeout: 1000 }).should("not.have.text", "New Button")
|
||||||
cy.wait(500)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should enter incorrect app name when reverting", () => {
|
it("should enter incorrect app name when reverting", () => {
|
||||||
// Click Revert
|
// Click Revert
|
||||||
cy.get(interact.TOP_RIGHT_NAV).within(() => {
|
cy.get(interact.TOP_RIGHT_NAV, { timeout: 1000 }).within(() => {
|
||||||
cy.get(interact.AREA_LABEL_REVERT).click({ force: true })
|
cy.get(interact.AREA_LABEL_REVERT).click({ force: true })
|
||||||
})
|
})
|
||||||
// Enter incorrect app name
|
// Enter incorrect app name
|
||||||
|
|
|
@ -3,7 +3,7 @@ Cypress.on("uncaught:exception", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// ACCOUNTS & USERS
|
// ACCOUNTS & USERS
|
||||||
Cypress.Commands.add("login", () => {
|
Cypress.Commands.add("login", (email, password) => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
cy.wait(2000)
|
cy.wait(2000)
|
||||||
cy.url().then(url => {
|
cy.url().then(url => {
|
||||||
|
@ -17,8 +17,13 @@ Cypress.Commands.add("login", () => {
|
||||||
if (url.includes("builder/auth/login") || url.includes("builder/admin")) {
|
if (url.includes("builder/auth/login") || url.includes("builder/admin")) {
|
||||||
// login
|
// login
|
||||||
cy.contains("Sign in to Budibase").then(() => {
|
cy.contains("Sign in to Budibase").then(() => {
|
||||||
|
if (email == null) {
|
||||||
cy.get("input").first().type("test@test.com")
|
cy.get("input").first().type("test@test.com")
|
||||||
cy.get('input[type="password"]').type("test")
|
cy.get('input[type="password"]').type("test")
|
||||||
|
} else {
|
||||||
|
cy.get("input").first().type(email)
|
||||||
|
cy.get('input[type="password"]').type(password)
|
||||||
|
}
|
||||||
cy.get("button").first().click({ force: true })
|
cy.get("button").first().click({ force: true })
|
||||||
cy.wait(1000)
|
cy.wait(1000)
|
||||||
})
|
})
|
||||||
|
@ -27,7 +32,7 @@ Cypress.Commands.add("login", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
Cypress.Commands.add("logOut", () => {
|
Cypress.Commands.add("logOut", () => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 2000 })
|
||||||
cy.get(".user-dropdown .avatar > .icon").click({ force: true })
|
cy.get(".user-dropdown .avatar > .icon").click({ force: true })
|
||||||
cy.get(".spectrum-Popover[data-cy='user-menu']").within(() => {
|
cy.get(".spectrum-Popover[data-cy='user-menu']").within(() => {
|
||||||
cy.get("li[data-cy='user-logout']").click({ force: true })
|
cy.get("li[data-cy='user-logout']").click({ force: true })
|
||||||
|
@ -35,24 +40,58 @@ Cypress.Commands.add("logOut", () => {
|
||||||
cy.wait(2000)
|
cy.wait(2000)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Cypress.Commands.add("logoutNoAppGrid", () => {
|
||||||
|
// Logs user out when app grid is not present
|
||||||
|
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||||
|
cy.get(".avatar > .icon").click({ force: true })
|
||||||
|
cy.get(".spectrum-Popover[data-cy='user-menu']").within(() => {
|
||||||
|
cy.get(".spectrum-Menu-item").contains("Log out").click({ force: true })
|
||||||
|
})
|
||||||
|
cy.wait(2000)
|
||||||
|
})
|
||||||
|
|
||||||
Cypress.Commands.add("createUser", email => {
|
Cypress.Commands.add("createUser", email => {
|
||||||
// quick hacky recorded way to create a user
|
// quick hacky recorded way to create a user
|
||||||
cy.contains("Users").click()
|
cy.contains("Users").click()
|
||||||
cy.get(`[data-cy="add-user"]`).click()
|
cy.get(`[data-cy="add-user"]`).click()
|
||||||
|
cy.get(".spectrum-Dialog-grid").within(() => {
|
||||||
cy.get(".spectrum-Picker-label").click()
|
cy.get(".spectrum-Picker-label").click()
|
||||||
cy.get(".spectrum-Menu-item:nth-child(2) > .spectrum-Menu-itemLabel").click()
|
cy.get(
|
||||||
|
".spectrum-Menu-item:nth-child(2) > .spectrum-Menu-itemLabel"
|
||||||
|
).click()
|
||||||
|
|
||||||
// Onboarding type selector
|
// Onboarding type selector
|
||||||
cy.get(
|
cy.get(".spectrum-Textfield-input")
|
||||||
":nth-child(2) > .spectrum-Form-itemField > .spectrum-Textfield > .spectrum-Textfield-input"
|
.eq(0)
|
||||||
)
|
|
||||||
.first()
|
.first()
|
||||||
.type(email, { force: true })
|
.type(email, { force: true })
|
||||||
cy.get(".spectrum-Button--cta").click({ force: true })
|
cy.get(".spectrum-Button--cta").click({ force: true })
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Cypress.Commands.add("deleteUser", email => {
|
||||||
|
// Assumes user has access to Users section
|
||||||
|
cy.contains("Users", { timeout: 2000 }).click()
|
||||||
|
cy.contains(email).click()
|
||||||
|
|
||||||
|
// Click Delete user button
|
||||||
|
cy.get(".spectrum-Button")
|
||||||
|
.contains("Delete user")
|
||||||
|
.click({ force: true })
|
||||||
|
.then(() => {
|
||||||
|
// Confirm deletion within modal
|
||||||
|
cy.get(".spectrum-Dialog-grid", { timeout: 500 }).within(() => {
|
||||||
|
cy.get(".spectrum-Button")
|
||||||
|
.contains("Delete user")
|
||||||
|
.click({ force: true })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
Cypress.Commands.add("updateUserInformation", (firstName, lastName) => {
|
Cypress.Commands.add("updateUserInformation", (firstName, lastName) => {
|
||||||
cy.get(".user-dropdown .avatar > .icon").click({ force: true })
|
cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({
|
||||||
|
force: true,
|
||||||
|
})
|
||||||
|
|
||||||
cy.get(".spectrum-Popover[data-cy='user-menu']").within(() => {
|
cy.get(".spectrum-Popover[data-cy='user-menu']").within(() => {
|
||||||
cy.get("li[data-cy='user-info']").click({ force: true })
|
cy.get("li[data-cy='user-info']").click({ force: true })
|
||||||
|
@ -95,9 +134,8 @@ Cypress.Commands.add("createApp", (name, addDefaultTable) => {
|
||||||
const shouldCreateDefaultTable =
|
const shouldCreateDefaultTable =
|
||||||
typeof addDefaultTable != "boolean" ? true : addDefaultTable
|
typeof addDefaultTable != "boolean" ? true : addDefaultTable
|
||||||
|
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000 })
|
||||||
cy.wait(1000)
|
cy.get(`[data-cy="create-app-btn"]`, { timeout: 2000 }).click({ force: true })
|
||||||
cy.get(`[data-cy="create-app-btn"]`).click({ force: true })
|
|
||||||
|
|
||||||
// If apps already exist
|
// If apps already exist
|
||||||
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
||||||
|
@ -117,7 +155,7 @@ Cypress.Commands.add("createApp", (name, addDefaultTable) => {
|
||||||
cy.get(".spectrum-ButtonGroup")
|
cy.get(".spectrum-ButtonGroup")
|
||||||
.contains("Create app")
|
.contains("Create app")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.wait(10000)
|
cy.wait(2000)
|
||||||
})
|
})
|
||||||
if (shouldCreateDefaultTable) {
|
if (shouldCreateDefaultTable) {
|
||||||
cy.createTable("Cypress Tests", true)
|
cy.createTable("Cypress Tests", true)
|
||||||
|
@ -125,7 +163,7 @@ Cypress.Commands.add("createApp", (name, addDefaultTable) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
Cypress.Commands.add("deleteApp", name => {
|
Cypress.Commands.add("deleteApp", name => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000 })
|
||||||
cy.wait(2000)
|
cy.wait(2000)
|
||||||
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
||||||
.its("body")
|
.its("body")
|
||||||
|
@ -150,14 +188,15 @@ Cypress.Commands.add("deleteApp", name => {
|
||||||
cy.get(actionEleId).within(() => {
|
cy.get(actionEleId).within(() => {
|
||||||
cy.contains("Manage").click({ force: true })
|
cy.contains("Manage").click({ force: true })
|
||||||
})
|
})
|
||||||
cy.wait(1000)
|
cy.wait(500)
|
||||||
|
|
||||||
// Unpublish first if needed
|
// Unpublish first if needed
|
||||||
cy.get(`[data-cy="app-status"]`).then($status => {
|
cy.get(`[data-cy="app-status"]`).then($status => {
|
||||||
if ($status.text().includes("Last published")) {
|
if ($status.text().includes("- Unpublish")) {
|
||||||
cy.contains("Unpublish").click()
|
// Exact match for Unpublish
|
||||||
|
cy.contains("Unpublish").click({ force: true })
|
||||||
cy.get(".spectrum-Modal").within(() => {
|
cy.get(".spectrum-Modal").within(() => {
|
||||||
cy.contains("Unpublish app").click()
|
cy.contains("Unpublish app").click({ force: true })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -276,16 +315,18 @@ Cypress.Commands.add("alterAppVersion", (appId, version) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
Cypress.Commands.add("importApp", (exportFilePath, name) => {
|
Cypress.Commands.add("importApp", (exportFilePath, name) => {
|
||||||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000 })
|
||||||
|
|
||||||
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
||||||
.its("body")
|
.its("body")
|
||||||
.then(val => {
|
.then(val => {
|
||||||
if (val.length > 0) {
|
if (val.length > 0) {
|
||||||
cy.get(`[data-cy="create-app-btn"]`).click({ force: true })
|
cy.get(`[data-cy="create-app-btn"]`).click({ force: true })
|
||||||
cy.wait(500)
|
|
||||||
}
|
}
|
||||||
cy.get(`[data-cy="import-app-btn"]`).click({ force: true })
|
cy.wait(500)
|
||||||
|
cy.get(`[data-cy="import-app-btn"]`).click({
|
||||||
|
force: true,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.get(".spectrum-Modal").within(() => {
|
cy.get(".spectrum-Modal").within(() => {
|
||||||
|
@ -303,7 +344,7 @@ Cypress.Commands.add("importApp", (exportFilePath, name) => {
|
||||||
cy.get(".confirm-wrap button")
|
cy.get(".confirm-wrap button")
|
||||||
.should("not.be.disabled")
|
.should("not.be.disabled")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
cy.wait(5000)
|
cy.wait(3000)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -332,7 +373,8 @@ Cypress.Commands.add("searchForApplication", appName => {
|
||||||
|
|
||||||
// Assumes there are no others
|
// Assumes there are no others
|
||||||
Cypress.Commands.add("applicationInAppTable", appName => {
|
Cypress.Commands.add("applicationInAppTable", appName => {
|
||||||
cy.get(".appTable").within(() => {
|
cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 10000 })
|
||||||
|
cy.get(".appTable", { timeout: 2000 }).within(() => {
|
||||||
cy.get(".title").contains(appName).should("exist")
|
cy.get(".title").contains(appName).should("exist")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -360,7 +402,7 @@ Cypress.Commands.add("createTable", (tableName, initialTable) => {
|
||||||
cy.navigateToDataSection()
|
cy.navigateToDataSection()
|
||||||
cy.get(`[data-cy="new-table"]`).click()
|
cy.get(`[data-cy="new-table"]`).click()
|
||||||
}
|
}
|
||||||
cy.wait(5000)
|
cy.wait(2000)
|
||||||
cy.get(".item")
|
cy.get(".item")
|
||||||
.contains("Budibase DB")
|
.contains("Budibase DB")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
|
@ -368,8 +410,7 @@ Cypress.Commands.add("createTable", (tableName, initialTable) => {
|
||||||
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
||||||
})
|
})
|
||||||
cy.get(".spectrum-Modal").within(() => {
|
cy.get(".spectrum-Modal").within(() => {
|
||||||
cy.wait(1000)
|
cy.get("input", { timeout: 1000 }).first().type(tableName).blur()
|
||||||
cy.get("input").first().type(tableName).blur()
|
|
||||||
cy.get(".spectrum-ButtonGroup").contains("Create").click()
|
cy.get(".spectrum-ButtonGroup").contains("Create").click()
|
||||||
})
|
})
|
||||||
cy.contains(tableName).should("be.visible")
|
cy.contains(tableName).should("be.visible")
|
||||||
|
@ -451,8 +492,7 @@ Cypress.Commands.add("addCustomSourceOptions", totalOptions => {
|
||||||
.contains("Add Option")
|
.contains("Add Option")
|
||||||
.click({ force: true })
|
.click({ force: true })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
cy.wait(500)
|
cy.get("[placeholder='Label']", { timeout: 500 }).eq(i).type(i)
|
||||||
cy.get("[placeholder='Label']").eq(i).type(i)
|
|
||||||
cy.get("[placeholder='Value']").eq(i).type(i)
|
cy.get("[placeholder='Value']").eq(i).type(i)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -464,10 +504,14 @@ Cypress.Commands.add("addCustomSourceOptions", totalOptions => {
|
||||||
// DESIGN AREA
|
// DESIGN AREA
|
||||||
Cypress.Commands.add("addComponent", (category, component) => {
|
Cypress.Commands.add("addComponent", (category, component) => {
|
||||||
if (category) {
|
if (category) {
|
||||||
cy.get(`[data-cy="category-${category}"]`).click({ force: true })
|
cy.get(`[data-cy="category-${category}"]`, { timeout: 1000 }).click({
|
||||||
|
force: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if (component) {
|
if (component) {
|
||||||
cy.get(`[data-cy="component-${component}"]`).click({ force: true })
|
cy.get(`[data-cy="component-${component}"]`, { timeout: 1000 }).click({
|
||||||
|
force: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
cy.wait(1000)
|
cy.wait(1000)
|
||||||
cy.location().then(loc => {
|
cy.location().then(loc => {
|
||||||
|
@ -496,15 +540,14 @@ Cypress.Commands.add("createScreen", (route, accessLevelLabel) => {
|
||||||
cy.get(".spectrum-Modal").within(() => {
|
cy.get(".spectrum-Modal").within(() => {
|
||||||
cy.get("[data-cy='blank-screen']").click()
|
cy.get("[data-cy='blank-screen']").click()
|
||||||
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
||||||
cy.wait(500)
|
|
||||||
})
|
})
|
||||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
cy.wait(500)
|
||||||
|
cy.get(".spectrum-Dialog-grid", { timeout: 500 }).within(() => {
|
||||||
cy.get(".spectrum-Form-itemField").eq(0).type(route)
|
cy.get(".spectrum-Form-itemField").eq(0).type(route)
|
||||||
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
cy.get(".confirm-wrap").contains("Continue").click({ force: true })
|
||||||
cy.wait(1000)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.get(".spectrum-Modal").within(() => {
|
cy.get(".spectrum-Modal", { timeout: 1000 }).within(() => {
|
||||||
if (accessLevelLabel) {
|
if (accessLevelLabel) {
|
||||||
cy.get(".spectrum-Picker-label").click()
|
cy.get(".spectrum-Picker-label").click()
|
||||||
cy.wait(500)
|
cy.wait(500)
|
||||||
|
@ -522,10 +565,12 @@ Cypress.Commands.add(
|
||||||
cy.get(".spectrum-Modal").within(() => {
|
cy.get(".spectrum-Modal").within(() => {
|
||||||
cy.get(".item").contains("Autogenerated screens").click()
|
cy.get(".item").contains("Autogenerated screens").click()
|
||||||
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
||||||
cy.wait(500)
|
|
||||||
})
|
})
|
||||||
cy.get(".spectrum-Modal [data-cy='data-source-modal']").within(() => {
|
cy.get(".spectrum-Modal [data-cy='data-source-modal']", {
|
||||||
|
timeout: 500,
|
||||||
|
}).within(() => {
|
||||||
for (let i = 0; i < datasourceNames.length; i++) {
|
for (let i = 0; i < datasourceNames.length; i++) {
|
||||||
|
cy.wait(500)
|
||||||
cy.get(".data-source-entry").contains(datasourceNames[i]).click()
|
cy.get(".data-source-entry").contains(datasourceNames[i]).click()
|
||||||
//Ensure the check mark is visible
|
//Ensure the check mark is visible
|
||||||
cy.get(".data-source-entry")
|
cy.get(".data-source-entry")
|
||||||
|
@ -574,7 +619,7 @@ Cypress.Commands.add(
|
||||||
// NAVIGATION
|
// NAVIGATION
|
||||||
Cypress.Commands.add("navigateToFrontend", () => {
|
Cypress.Commands.add("navigateToFrontend", () => {
|
||||||
// Clicks on Design tab and then the Home nav item
|
// Clicks on Design tab and then the Home nav item
|
||||||
cy.wait(1000)
|
cy.wait(500)
|
||||||
cy.contains("Design").click()
|
cy.contains("Design").click()
|
||||||
cy.get(".spectrum-Search").type("/")
|
cy.get(".spectrum-Search").type("/")
|
||||||
cy.get(".nav-item").contains("home").click()
|
cy.get(".nav-item").contains("home").click()
|
||||||
|
@ -606,11 +651,11 @@ Cypress.Commands.add("selectExternalDatasource", datasourceName => {
|
||||||
cy.get(".add-button").click()
|
cy.get(".add-button").click()
|
||||||
})
|
})
|
||||||
// Clicks specified datasource & continue
|
// Clicks specified datasource & continue
|
||||||
cy.wait(1000)
|
cy.get(".item-list", { timeout: 1000 }).contains(datasourceName).click()
|
||||||
cy.get(".item-list").contains(datasourceName).click()
|
|
||||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
cy.get(".spectrum-Dialog-grid").within(() => {
|
||||||
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
cy.get(".spectrum-Button").contains("Continue").click({ force: true })
|
||||||
})
|
})
|
||||||
|
cy.wait(500)
|
||||||
})
|
})
|
||||||
|
|
||||||
Cypress.Commands.add("addDatasourceConfig", (datasource, skipFetch) => {
|
Cypress.Commands.add("addDatasourceConfig", (datasource, skipFetch) => {
|
||||||
|
@ -618,8 +663,7 @@ Cypress.Commands.add("addDatasourceConfig", (datasource, skipFetch) => {
|
||||||
// Adds the config for specified datasource & fetches tables
|
// Adds the config for specified datasource & fetches tables
|
||||||
// Currently supports MySQL, PostgreSQL, Oracle
|
// Currently supports MySQL, PostgreSQL, Oracle
|
||||||
// Host IP Address
|
// Host IP Address
|
||||||
cy.wait(500)
|
cy.get(".spectrum-Dialog-grid", { timeout: 500 }).within(() => {
|
||||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
|
||||||
cy.get(".form-row")
|
cy.get(".form-row")
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
|
@ -719,16 +763,18 @@ Cypress.Commands.add("addDatasourceConfig", (datasource, skipFetch) => {
|
||||||
Cypress.Commands.add("createRestQuery", (method, restUrl, queryPrettyName) => {
|
Cypress.Commands.add("createRestQuery", (method, restUrl, queryPrettyName) => {
|
||||||
// addExternalDatasource should be called prior to this
|
// addExternalDatasource should be called prior to this
|
||||||
// Configures REST datasource & sends query
|
// Configures REST datasource & sends query
|
||||||
cy.wait(1000)
|
cy.get(".spectrum-Button", { timeout: 1000 })
|
||||||
cy.get(".spectrum-Button").contains("Add query").click({ force: true })
|
.contains("Add query")
|
||||||
|
.click({ force: true })
|
||||||
// Select Method & add Rest URL
|
// Select Method & add Rest URL
|
||||||
cy.get(".spectrum-Picker-label").eq(1).click()
|
cy.get(".spectrum-Picker-label").eq(1).click()
|
||||||
cy.get(".spectrum-Menu").contains(method).click()
|
cy.get(".spectrum-Menu").contains(method).click()
|
||||||
cy.get("input").clear().type(restUrl)
|
cy.get("input").clear().type(restUrl)
|
||||||
// Send query
|
// Send query
|
||||||
cy.get(".spectrum-Button").contains("Send").click({ force: true })
|
cy.get(".spectrum-Button").contains("Send").click({ force: true })
|
||||||
cy.wait(500)
|
cy.get(".spectrum-Button", { timeout: 500 })
|
||||||
cy.get(".spectrum-Button").contains("Save").click({ force: true })
|
.contains("Save")
|
||||||
|
.click({ force: true })
|
||||||
cy.get(".hierarchy-items-container")
|
cy.get(".hierarchy-items-container")
|
||||||
.should("contain", method)
|
.should("contain", method)
|
||||||
.and("contain", queryPrettyName)
|
.and("contain", queryPrettyName)
|
||||||
|
|
|
@ -62,6 +62,7 @@ export const GLOBESTRIKE = "svg[aria-label=GlobeStrike]"
|
||||||
export const GLOBE = "svg[aria-label=Globe]"
|
export const GLOBE = "svg[aria-label=Globe]"
|
||||||
export const UNPUBLISH_MODAL = "[data-cy=unpublish-modal]"
|
export const UNPUBLISH_MODAL = "[data-cy=unpublish-modal]"
|
||||||
export const CONFIRM_WRAP_BUTTON = ".confirm-wrap button"
|
export const CONFIRM_WRAP_BUTTON = ".confirm-wrap button"
|
||||||
|
export const DEPLOYMENT_TOP_NAV = ".deployment-top-nav"
|
||||||
|
|
||||||
//changeAppiconAndColour
|
//changeAppiconAndColour
|
||||||
export const APP_ROW_ACTION = ".app-row-actions-icon"
|
export const APP_ROW_ACTION = ".app-row-actions-icon"
|
||||||
|
@ -97,13 +98,16 @@ export const ACTION_SPECTRUM_ICON = ".actions .spectrum-Icon"
|
||||||
export const SPECTRUM_MENU_CHILD2 = ".spectrum-Menu > :nth-child(2)"
|
export const SPECTRUM_MENU_CHILD2 = ".spectrum-Menu > :nth-child(2)"
|
||||||
export const DELETE_TABLE_CONFIRM = '[data-cy="delete-table-confirm"]'
|
export const DELETE_TABLE_CONFIRM = '[data-cy="delete-table-confirm"]'
|
||||||
|
|
||||||
//createUSerAndRoles
|
//adminAndManagement Folder
|
||||||
export const SPECTRUM_TABLE = ".spectrum-Table"
|
export const SPECTRUM_TABLE = ".spectrum-Table"
|
||||||
export const SPECTRUM_SIDENAV = ".spectrum-SideNav"
|
export const SPECTRUM_SIDENAV = ".spectrum-SideNav"
|
||||||
export const SPECTRUM_TABLE_ROW = ".spectrum-Table-row"
|
export const SPECTRUM_TABLE_ROW = ".spectrum-Table-row"
|
||||||
export const SPECTRUM_TABLE_CELL = ".spectrum-Table-cell"
|
export const SPECTRUM_TABLE_CELL = ".spectrum-Table-cell"
|
||||||
export const FIELD = ".field"
|
export const FIELD = ".field"
|
||||||
export const CONTAINER = ".container"
|
export const CONTAINER = ".container"
|
||||||
|
export const REGENERATE = ".regenerate"
|
||||||
|
export const SPECTRUM_DIALOG_CONTENT = ".spectrum-Dialog-content"
|
||||||
|
export const SPECTRUM_ICON = ".spectrum-Icon"
|
||||||
|
|
||||||
//createView
|
//createView
|
||||||
export const SPECTRUM_MENU_ITEM_LABEL = ".spectrum-Menu-itemLabel"
|
export const SPECTRUM_MENU_ITEM_LABEL = ".spectrum-Menu-itemLabel"
|
||||||
|
@ -113,14 +117,17 @@ export const TOP_RIGHT_NAV = ".toprightnav"
|
||||||
export const AREA_LABEL_REVERT = "[aria-label=Revert]"
|
export const AREA_LABEL_REVERT = "[aria-label=Revert]"
|
||||||
export const ROOT = ".root"
|
export const ROOT = ".root"
|
||||||
|
|
||||||
//quertLevelTransformers
|
//queryLevelTransformers
|
||||||
export const SPECTRUM_TABS_ITEM = ".spectrum-Tabs-itemLabel"
|
export const SPECTRUM_TABS_ITEM = ".spectrum-Tabs-itemLabel"
|
||||||
export const CODEMIRROR_TEXTAREA = ".CodeMirror textarea"
|
export const CODEMIRROR_TEXTAREA = ".CodeMirror textarea"
|
||||||
|
|
||||||
//renemaApplication
|
//renameApplication
|
||||||
export const WRAPPER = ".wrapper"
|
export const WRAPPER = ".wrapper"
|
||||||
export const ERROR = ".error"
|
export const ERROR = ".error"
|
||||||
export const AREA_LABEL_MORE = "[aria-label=More]"
|
export const AREA_LABEL_MORE = "[aria-label=More]"
|
||||||
export const APP_ROW_ACTION_MENU_POPOVER =
|
export const APP_ROW_ACTION_MENU_POPOVER =
|
||||||
'[data-cy="app-row-actions-menu-popover"]'
|
'[data-cy="app-row-actions-menu-popover"]'
|
||||||
export const SPECTRUM_MENU_ITEMM = ".spectrum-Menu-item"
|
export const SPECTRUM_MENU_ITEM = ".spectrum-Menu-item"
|
||||||
|
|
||||||
|
//commands
|
||||||
|
export const HOME_LOGO = ".home-logo"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -69,10 +69,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^1.0.212-alpha.5",
|
"@budibase/bbui": "^1.0.212-alpha.8",
|
||||||
"@budibase/client": "^1.0.212-alpha.5",
|
"@budibase/client": "^1.0.212-alpha.8",
|
||||||
"@budibase/frontend-core": "^1.0.212-alpha.5",
|
"@budibase/frontend-core": "^1.0.212-alpha.8",
|
||||||
"@budibase/string-templates": "^1.0.212-alpha.5",
|
"@budibase/string-templates": "^1.0.212-alpha.8",
|
||||||
"@sentry/browser": "5.19.1",
|
"@sentry/browser": "5.19.1",
|
||||||
"@spectrum-css/page": "^3.0.1",
|
"@spectrum-css/page": "^3.0.1",
|
||||||
"@spectrum-css/vars": "^3.0.1",
|
"@spectrum-css/vars": "^3.0.1",
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { writable } from "svelte/store"
|
||||||
|
|
||||||
|
function defaultValue() {
|
||||||
|
return {
|
||||||
|
nextPage: null,
|
||||||
|
page: undefined,
|
||||||
|
hasPrevPage: false,
|
||||||
|
hasNextPage: false,
|
||||||
|
loading: false,
|
||||||
|
pageNumber: 1,
|
||||||
|
pages: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createPaginationStore() {
|
||||||
|
const { subscribe, set, update } = writable(defaultValue())
|
||||||
|
|
||||||
|
function prevPage() {
|
||||||
|
update(state => {
|
||||||
|
state.pageNumber--
|
||||||
|
state.nextPage = state.pages.pop()
|
||||||
|
state.page = state.pages[state.pages.length - 1]
|
||||||
|
state.hasPrevPage = state.pageNumber > 1
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextPage() {
|
||||||
|
update(state => {
|
||||||
|
state.pageNumber++
|
||||||
|
state.page = state.nextPage
|
||||||
|
state.pages.push(state.page)
|
||||||
|
state.hasPrevPage = state.pageNumber > 1
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetched(hasNextPage, nextPage) {
|
||||||
|
update(state => {
|
||||||
|
state.hasNextPage = hasNextPage
|
||||||
|
state.nextPage = nextPage
|
||||||
|
state.loading = false
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function loading(loading = true) {
|
||||||
|
update(state => {
|
||||||
|
state.loading = loading
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
set(defaultValue())
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
subscribe,
|
||||||
|
prevPage,
|
||||||
|
nextPage,
|
||||||
|
fetched,
|
||||||
|
loading,
|
||||||
|
reset,
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,9 @@
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { createValidationStore, emailValidator } from "helpers/validation"
|
import { createValidationStore, emailValidator } from "helpers/validation"
|
||||||
import { users } from "stores/portal"
|
import { users } from "stores/portal"
|
||||||
|
import { createEventDispatcher } from "svelte"
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
const password = Math.random().toString(36).substring(2, 22)
|
const password = Math.random().toString(36).substring(2, 22)
|
||||||
const options = ["Email onboarding", "Basic onboarding"]
|
const options = ["Email onboarding", "Basic onboarding"]
|
||||||
const [email, error, touched] = createValidationStore("", emailValidator)
|
const [email, error, touched] = createValidationStore("", emailValidator)
|
||||||
|
@ -39,6 +41,7 @@
|
||||||
forceResetPassword: true,
|
forceResetPassword: true,
|
||||||
})
|
})
|
||||||
notifications.success("Successfully created user")
|
notifications.success("Successfully created user")
|
||||||
|
dispatch("created")
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error("Error creating user")
|
notifications.error("Error creating user")
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,41 +12,36 @@
|
||||||
Layout,
|
Layout,
|
||||||
Modal,
|
Modal,
|
||||||
notifications,
|
notifications,
|
||||||
|
Pagination,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import TagsRenderer from "./_components/TagsTableRenderer.svelte"
|
import TagsRenderer from "./_components/TagsTableRenderer.svelte"
|
||||||
import AddUserModal from "./_components/AddUserModal.svelte"
|
import AddUserModal from "./_components/AddUserModal.svelte"
|
||||||
import { users } from "stores/portal"
|
import { users } from "stores/portal"
|
||||||
import { onMount } from "svelte"
|
import { createPaginationStore } from "helpers/pagination"
|
||||||
|
|
||||||
const schema = {
|
const schema = {
|
||||||
email: {},
|
email: {},
|
||||||
developmentAccess: { displayName: "Development Access", type: "boolean" },
|
developmentAccess: { displayName: "Development Access", type: "boolean" },
|
||||||
adminAccess: { displayName: "Admin Access", type: "boolean" },
|
adminAccess: { displayName: "Admin Access", type: "boolean" },
|
||||||
// role: { type: "options" },
|
|
||||||
group: {},
|
group: {},
|
||||||
// access: {},
|
|
||||||
// group: {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let search
|
let pageInfo = createPaginationStore()
|
||||||
$: filteredUsers = $users
|
let search = undefined
|
||||||
.filter(user => user.email.includes(search || ""))
|
$: page = $pageInfo.page
|
||||||
.map(user => ({
|
$: fetchUsers(page, search)
|
||||||
...user,
|
|
||||||
group: ["All users"],
|
|
||||||
developmentAccess: !!user.builder?.global,
|
|
||||||
adminAccess: !!user.admin?.global,
|
|
||||||
}))
|
|
||||||
|
|
||||||
let createUserModal
|
let createUserModal
|
||||||
|
|
||||||
onMount(async () => {
|
async function fetchUsers(page, search) {
|
||||||
try {
|
try {
|
||||||
await users.init()
|
pageInfo.loading()
|
||||||
|
await users.search({ page, search })
|
||||||
|
pageInfo.fetched($users.hasNextPage, $users.nextPage)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error("Error getting user list")
|
notifications.error("Error getting user list")
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Layout noPadding>
|
<Layout noPadding>
|
||||||
|
@ -75,17 +70,31 @@
|
||||||
<Table
|
<Table
|
||||||
on:click={({ detail }) => $goto(`./${detail._id}`)}
|
on:click={({ detail }) => $goto(`./${detail._id}`)}
|
||||||
{schema}
|
{schema}
|
||||||
data={filteredUsers || $users}
|
data={$users.data}
|
||||||
allowEditColumns={false}
|
allowEditColumns={false}
|
||||||
allowEditRows={false}
|
allowEditRows={false}
|
||||||
allowSelectRows={false}
|
allowSelectRows={false}
|
||||||
customRenderers={[{ column: "group", component: TagsRenderer }]}
|
customRenderers={[{ column: "group", component: TagsRenderer }]}
|
||||||
/>
|
/>
|
||||||
|
<div class="pagination">
|
||||||
|
<Pagination
|
||||||
|
page={$pageInfo.pageNumber}
|
||||||
|
hasPrevPage={$pageInfo.loading ? false : $pageInfo.hasPrevPage}
|
||||||
|
hasNextPage={$pageInfo.loading ? false : $pageInfo.hasNextPage}
|
||||||
|
goToPrevPage={pageInfo.prevPage}
|
||||||
|
goToNextPage={pageInfo.nextPage}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<Modal bind:this={createUserModal}>
|
<Modal bind:this={createUserModal}>
|
||||||
<AddUserModal />
|
<AddUserModal
|
||||||
|
on:created={async () => {
|
||||||
|
pageInfo.reset()
|
||||||
|
await fetchUsers()
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import DashCard from "components/common/DashCard.svelte"
|
import DashCard from "components/common/DashCard.svelte"
|
||||||
import { AppStatus } from "constants"
|
import { AppStatus } from "constants"
|
||||||
import {
|
import { Icon, Heading, Link, Avatar, Layout } from "@budibase/bbui"
|
||||||
Icon,
|
|
||||||
Heading,
|
|
||||||
Link,
|
|
||||||
Avatar,
|
|
||||||
notifications,
|
|
||||||
Layout,
|
|
||||||
} from "@budibase/bbui"
|
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
import clientPackage from "@budibase/client/package.json"
|
import clientPackage from "@budibase/client/package.json"
|
||||||
import { processStringSync } from "@budibase/string-templates"
|
import { processStringSync } from "@budibase/string-templates"
|
||||||
|
@ -20,29 +13,22 @@
|
||||||
export let navigateTab
|
export let navigateTab
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
const userInit = async () => {
|
|
||||||
try {
|
|
||||||
await users.init()
|
|
||||||
} catch (error) {
|
|
||||||
notifications.error("Error getting user list")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const unpublishApp = () => {
|
const unpublishApp = () => {
|
||||||
dispatch("unpublish", app)
|
dispatch("unpublish", app)
|
||||||
}
|
}
|
||||||
|
|
||||||
let userPromise = userInit()
|
let appEditor, appEditorPromise
|
||||||
|
|
||||||
$: updateAvailable = clientPackage.version !== $store.version
|
$: updateAvailable = clientPackage.version !== $store.version
|
||||||
$: isPublished = app && app?.status === AppStatus.DEPLOYED
|
$: isPublished = app && app?.status === AppStatus.DEPLOYED
|
||||||
$: appEditorId = !app?.updatedBy ? $auth.user._id : app?.updatedBy
|
$: appEditorId = !app?.updatedBy ? $auth.user._id : app?.updatedBy
|
||||||
$: appEditorText = appEditor?.firstName || appEditor?.email
|
$: appEditorText = appEditor?.firstName || appEditor?.email
|
||||||
$: filteredUsers = !appEditorId
|
$: fetchAppEditor(appEditorId)
|
||||||
? []
|
|
||||||
: $users.filter(user => user._id === appEditorId)
|
|
||||||
|
|
||||||
$: appEditor = filteredUsers.length ? filteredUsers[0] : null
|
async function fetchAppEditor(editorId) {
|
||||||
|
appEditorPromise = users.get(editorId)
|
||||||
|
appEditor = await appEditorPromise
|
||||||
|
}
|
||||||
|
|
||||||
const getInitials = user => {
|
const getInitials = user => {
|
||||||
let initials = ""
|
let initials = ""
|
||||||
|
@ -90,7 +76,7 @@
|
||||||
</DashCard>
|
</DashCard>
|
||||||
<DashCard title={"Last Edited"} dataCy={"edited-by"}>
|
<DashCard title={"Last Edited"} dataCy={"edited-by"}>
|
||||||
<div class="last-edited-content">
|
<div class="last-edited-content">
|
||||||
{#await userPromise}
|
{#await appEditorPromise}
|
||||||
<Avatar size="M" initials={"-"} />
|
<Avatar size="M" initials={"-"} />
|
||||||
{:then _}
|
{:then _}
|
||||||
<div class="updated-by">
|
<div class="updated-by">
|
||||||
|
|
|
@ -3,11 +3,24 @@ import { API } from "api"
|
||||||
import { update } from "lodash"
|
import { update } from "lodash"
|
||||||
|
|
||||||
export function createUsersStore() {
|
export function createUsersStore() {
|
||||||
const { subscribe, set } = writable([])
|
const { subscribe, set } = writable({})
|
||||||
|
|
||||||
async function init() {
|
// opts can contain page and search params
|
||||||
const users = await API.getUsers()
|
async function search(opts = {}) {
|
||||||
set(users)
|
const paged = await API.searchUsers(opts)
|
||||||
|
set({
|
||||||
|
...paged,
|
||||||
|
...opts,
|
||||||
|
})
|
||||||
|
return paged
|
||||||
|
}
|
||||||
|
|
||||||
|
async function get(userId) {
|
||||||
|
try {
|
||||||
|
return await API.getUser(userId)
|
||||||
|
} catch (err) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function invite({ email, builder, admin }) {
|
async function invite({ email, builder, admin }) {
|
||||||
|
@ -47,7 +60,8 @@ export function createUsersStore() {
|
||||||
body.admin = { global: true }
|
body.admin = { global: true }
|
||||||
}
|
}
|
||||||
await API.saveUser(body)
|
await API.saveUser(body)
|
||||||
await init()
|
// re-search from first page
|
||||||
|
await search()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function del(id) {
|
async function del(id) {
|
||||||
|
@ -61,7 +75,8 @@ export function createUsersStore() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
subscribe,
|
subscribe,
|
||||||
init,
|
search,
|
||||||
|
get,
|
||||||
invite,
|
invite,
|
||||||
acceptInvite,
|
acceptInvite,
|
||||||
create,
|
create,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/cli",
|
"name": "@budibase/cli",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"module": "dist/budibase-client.js",
|
"module": "dist/budibase-client.js",
|
||||||
"main": "dist/budibase-client.js",
|
"main": "dist/budibase-client.js",
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
"dev:builder": "rollup -cw"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^1.0.212-alpha.5",
|
"@budibase/bbui": "^1.0.212-alpha.8",
|
||||||
"@budibase/frontend-core": "^1.0.212-alpha.5",
|
"@budibase/frontend-core": "^1.0.212-alpha.8",
|
||||||
"@budibase/string-templates": "^1.0.212-alpha.5",
|
"@budibase/string-templates": "^1.0.212-alpha.8",
|
||||||
"@spectrum-css/button": "^3.0.3",
|
"@spectrum-css/button": "^3.0.3",
|
||||||
"@spectrum-css/card": "^3.0.3",
|
"@spectrum-css/card": "^3.0.3",
|
||||||
"@spectrum-css/divider": "^1.0.3",
|
"@spectrum-css/divider": "^1.0.3",
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/frontend-core",
|
"name": "@budibase/frontend-core",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"description": "Budibase frontend core libraries used in builder and client",
|
"description": "Budibase frontend core libraries used in builder and client",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^1.0.212-alpha.5",
|
"@budibase/bbui": "^1.0.212-alpha.8",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"svelte": "^3.46.2"
|
"svelte": "^3.46.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,34 @@ export const buildUserEndpoints = API => ({
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of users in the current tenant.
|
||||||
|
* @param {string} page The page to retrieve
|
||||||
|
* @param {string} search The starts with string to search username/email by.
|
||||||
|
*/
|
||||||
|
searchUsers: async ({ page, search } = {}) => {
|
||||||
|
const opts = {}
|
||||||
|
if (page) {
|
||||||
|
opts.page = page
|
||||||
|
}
|
||||||
|
if (search) {
|
||||||
|
opts.search = search
|
||||||
|
}
|
||||||
|
return await API.post({
|
||||||
|
url: `/api/global/users/search`,
|
||||||
|
body: opts,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single user by ID.
|
||||||
|
*/
|
||||||
|
getUser: async userId => {
|
||||||
|
return await API.get({
|
||||||
|
url: `/api/global/users/${userId}`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a user for an app.
|
* Creates a user for an app.
|
||||||
* @param user the user to create
|
* @param user the user to create
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/server",
|
"name": "@budibase/server",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"description": "Budibase Web Server",
|
"description": "Budibase Web Server",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -77,11 +77,11 @@
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apidevtools/swagger-parser": "10.0.3",
|
"@apidevtools/swagger-parser": "10.0.3",
|
||||||
"@budibase/backend-core": "^1.0.212-alpha.5",
|
"@budibase/backend-core": "^1.0.212-alpha.8",
|
||||||
"@budibase/client": "^1.0.212-alpha.5",
|
"@budibase/client": "^1.0.212-alpha.8",
|
||||||
"@budibase/pro": "1.0.212-alpha.5",
|
"@budibase/pro": "1.0.212-alpha.8",
|
||||||
"@budibase/string-templates": "^1.0.212-alpha.5",
|
"@budibase/string-templates": "^1.0.212-alpha.8",
|
||||||
"@budibase/types": "^1.0.212-alpha.5",
|
"@budibase/types": "^1.0.212-alpha.8",
|
||||||
"@bull-board/api": "3.7.0",
|
"@bull-board/api": "3.7.0",
|
||||||
"@bull-board/koa": "3.9.4",
|
"@bull-board/koa": "3.9.4",
|
||||||
"@elastic/elasticsearch": "7.10.0",
|
"@elastic/elasticsearch": "7.10.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/string-templates",
|
"name": "@budibase/string-templates",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"description": "Handlebars wrapper for Budibase templating.",
|
"description": "Handlebars wrapper for Budibase templating.",
|
||||||
"main": "src/index.cjs",
|
"main": "src/index.cjs",
|
||||||
"module": "dist/bundle.mjs",
|
"module": "dist/bundle.mjs",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/types",
|
"name": "@budibase/types",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"description": "Budibase types",
|
"description": "Budibase types",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/worker",
|
"name": "@budibase/worker",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "1.0.212-alpha.5",
|
"version": "1.0.212-alpha.8",
|
||||||
"description": "Budibase background service",
|
"description": "Budibase background service",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -34,10 +34,10 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/backend-core": "^1.0.212-alpha.5",
|
"@budibase/backend-core": "^1.0.212-alpha.8",
|
||||||
"@budibase/pro": "1.0.212-alpha.5",
|
"@budibase/pro": "1.0.212-alpha.8",
|
||||||
"@budibase/string-templates": "^1.0.212-alpha.5",
|
"@budibase/string-templates": "^1.0.212-alpha.8",
|
||||||
"@budibase/types": "^1.0.212-alpha.5",
|
"@budibase/types": "^1.0.212-alpha.8",
|
||||||
"@koa/router": "8.0.8",
|
"@koa/router": "8.0.8",
|
||||||
"@sentry/node": "6.17.7",
|
"@sentry/node": "6.17.7",
|
||||||
"@techpass/passport-openidconnect": "0.3.2",
|
"@techpass/passport-openidconnect": "0.3.2",
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const {
|
const {
|
||||||
generateConfigID,
|
generateConfigID,
|
||||||
getConfigParams,
|
getConfigParams,
|
||||||
getGlobalUserParams,
|
|
||||||
getScopedFullConfig,
|
getScopedFullConfig,
|
||||||
getAllApps,
|
getAllApps,
|
||||||
} = require("@budibase/backend-core/db")
|
} = require("@budibase/backend-core/db")
|
||||||
|
@ -20,6 +19,7 @@ const {
|
||||||
bustCache,
|
bustCache,
|
||||||
} = require("@budibase/backend-core/cache")
|
} = require("@budibase/backend-core/cache")
|
||||||
const { events } = require("@budibase/backend-core")
|
const { events } = require("@budibase/backend-core")
|
||||||
|
const { checkAnyUserExists } = require("../../../utilities/users")
|
||||||
|
|
||||||
const BB_TENANT_CDN = "https://tenants.cdn.budi.live"
|
const BB_TENANT_CDN = "https://tenants.cdn.budi.live"
|
||||||
|
|
||||||
|
@ -405,12 +405,7 @@ exports.configChecklist = async function (ctx) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// They have set up an global user
|
// They have set up an global user
|
||||||
const users = await db.allDocs(
|
const userExists = await checkAnyUserExists()
|
||||||
getGlobalUserParams(null, {
|
|
||||||
include_docs: true,
|
|
||||||
limit: 1,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
return {
|
return {
|
||||||
apps: {
|
apps: {
|
||||||
checked: apps.length > 0,
|
checked: apps.length > 0,
|
||||||
|
@ -423,7 +418,7 @@ exports.configChecklist = async function (ctx) {
|
||||||
link: "/builder/portal/manage/email",
|
link: "/builder/portal/manage/email",
|
||||||
},
|
},
|
||||||
adminUser: {
|
adminUser: {
|
||||||
checked: users && users.rows.length >= 1,
|
checked: userExists,
|
||||||
label: "Create your first user",
|
label: "Create your first user",
|
||||||
link: "/builder/portal/manage/users",
|
link: "/builder/portal/manage/users",
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,7 +7,7 @@ const {
|
||||||
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
||||||
const { user: userCache } = require("@budibase/backend-core/cache")
|
const { user: userCache } = require("@budibase/backend-core/cache")
|
||||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
||||||
const { users } = require("../../../sdk")
|
const { allUsers } = require("../../../sdk/users")
|
||||||
|
|
||||||
exports.fetch = async ctx => {
|
exports.fetch = async ctx => {
|
||||||
const tenantId = ctx.user.tenantId
|
const tenantId = ctx.user.tenantId
|
||||||
|
@ -49,10 +49,10 @@ exports.find = async ctx => {
|
||||||
exports.removeAppRole = async ctx => {
|
exports.removeAppRole = async ctx => {
|
||||||
const { appId } = ctx.params
|
const { appId } = ctx.params
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
const allUsers = await users.allUsers(ctx)
|
const users = await allUsers(ctx)
|
||||||
const bulk = []
|
const bulk = []
|
||||||
const cacheInvalidations = []
|
const cacheInvalidations = []
|
||||||
for (let user of allUsers) {
|
for (let user of users) {
|
||||||
if (user.roles[appId]) {
|
if (user.roles[appId]) {
|
||||||
cacheInvalidations.push(userCache.invalidateUser(user._id))
|
cacheInvalidations.push(userCache.invalidateUser(user._id))
|
||||||
delete user.roles[appId]
|
delete user.roles[appId]
|
||||||
|
|
|
@ -8,16 +8,15 @@ import {
|
||||||
events,
|
events,
|
||||||
errors,
|
errors,
|
||||||
accounts,
|
accounts,
|
||||||
db as dbUtils,
|
|
||||||
users as usersCore,
|
users as usersCore,
|
||||||
tenancy,
|
tenancy,
|
||||||
cache,
|
cache,
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
|
import { checkAnyUserExists } from "../../../utilities/users"
|
||||||
|
|
||||||
export const save = async (ctx: any) => {
|
export const save = async (ctx: any) => {
|
||||||
try {
|
try {
|
||||||
const user = await users.save(ctx.request.body)
|
ctx.body = await users.save(ctx.request.body)
|
||||||
ctx.body = user
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status || 400, err)
|
ctx.throw(err.status || 400, err)
|
||||||
}
|
}
|
||||||
|
@ -39,15 +38,8 @@ export const adminUser = async (ctx: any) => {
|
||||||
ctx.throw(403, "Organisation already exists.")
|
ctx.throw(403, "Organisation already exists.")
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await tenancy.doWithGlobalDB(tenantId, async (db: any) => {
|
const userExists = await checkAnyUserExists()
|
||||||
return db.allDocs(
|
if (userExists) {
|
||||||
dbUtils.getGlobalUserParams(null, {
|
|
||||||
include_docs: true,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (response.rows.some((row: any) => row.doc.admin)) {
|
|
||||||
ctx.throw(
|
ctx.throw(
|
||||||
403,
|
403,
|
||||||
"You cannot initialise once an global user has been created."
|
"You cannot initialise once an global user has been created."
|
||||||
|
@ -96,6 +88,17 @@ export const destroy = async (ctx: any) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const search = async (ctx: any) => {
|
||||||
|
const paginated = await users.paginatedUsers(ctx.request.body)
|
||||||
|
// user hashed password shouldn't ever be returned
|
||||||
|
for (let user of paginated.data) {
|
||||||
|
if (user) {
|
||||||
|
delete user.password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.body = paginated
|
||||||
|
}
|
||||||
|
|
||||||
// called internally by app server user fetch
|
// called internally by app server user fetch
|
||||||
export const fetch = async (ctx: any) => {
|
export const fetch = async (ctx: any) => {
|
||||||
const all = await users.allUsers()
|
const all = await users.allUsers()
|
||||||
|
|
|
@ -46,6 +46,7 @@ router
|
||||||
controller.save
|
controller.save
|
||||||
)
|
)
|
||||||
.get("/api/global/users", builderOrAdmin, controller.fetch)
|
.get("/api/global/users", builderOrAdmin, controller.fetch)
|
||||||
|
.post("/api/global/users/search", builderOrAdmin, controller.search)
|
||||||
.delete("/api/global/users/:id", adminOnly, controller.destroy)
|
.delete("/api/global/users/:id", adminOnly, controller.destroy)
|
||||||
.get("/api/global/roles/:appId")
|
.get("/api/global/roles/:appId")
|
||||||
.post(
|
.post(
|
||||||
|
|
|
@ -17,9 +17,8 @@ import {
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
import { MigrationType } from "@budibase/types"
|
import { MigrationType } from "@budibase/types"
|
||||||
|
|
||||||
/**
|
const PAGE_LIMIT = 8
|
||||||
* Retrieves all users from the current tenancy.
|
|
||||||
*/
|
|
||||||
export const allUsers = async () => {
|
export const allUsers = async () => {
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const response = await db.allDocs(
|
const response = await db.allDocs(
|
||||||
|
@ -30,6 +29,37 @@ export const allUsers = async () => {
|
||||||
return response.rows.map((row: any) => row.doc)
|
return response.rows.map((row: any) => row.doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const paginatedUsers = async ({
|
||||||
|
page,
|
||||||
|
search,
|
||||||
|
}: { page?: string; search?: string } = {}) => {
|
||||||
|
const db = tenancy.getGlobalDB()
|
||||||
|
// get one extra document, to have the next page
|
||||||
|
const opts: any = {
|
||||||
|
include_docs: true,
|
||||||
|
limit: PAGE_LIMIT + 1,
|
||||||
|
}
|
||||||
|
// add a startkey if the page was specified (anchor)
|
||||||
|
if (page) {
|
||||||
|
opts.startkey = page
|
||||||
|
}
|
||||||
|
// property specifies what to use for the page/anchor
|
||||||
|
let userList, property
|
||||||
|
// no search, query allDocs
|
||||||
|
if (!search) {
|
||||||
|
const response = await db.allDocs(dbUtils.getGlobalUserParams(null, opts))
|
||||||
|
userList = response.rows.map((row: any) => row.doc)
|
||||||
|
property = "_id"
|
||||||
|
} else {
|
||||||
|
userList = await usersCore.searchGlobalUsersByEmail(search, opts)
|
||||||
|
property = "email"
|
||||||
|
}
|
||||||
|
return dbUtils.pagination(userList, PAGE_LIMIT, {
|
||||||
|
paginate: true,
|
||||||
|
property,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a user by ID from the global database, based on the current tenancy.
|
* Gets a user by ID from the global database, based on the current tenancy.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
||||||
|
const { getGlobalUserParams } = require("@budibase/backend-core/db")
|
||||||
|
|
||||||
|
exports.checkAnyUserExists = async () => {
|
||||||
|
try {
|
||||||
|
const db = getGlobalDB()
|
||||||
|
const users = await db.allDocs(
|
||||||
|
getGlobalUserParams(null, {
|
||||||
|
include_docs: true,
|
||||||
|
limit: 1,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return users && users.rows.length >= 1
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error("Unable to retrieve user list")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue