Merge branch 'main' into release/marketplace-sprint-12
6
.github/workflows/cypress-appbuilder.yml
vendored
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Set up Git authentication for private submodules
|
||||
run: |
|
||||
|
|
@ -160,9 +160,9 @@ jobs:
|
|||
name: screenshots-appbuilder-${{ matrix.edition }}
|
||||
path: cypress-tests/cypress/screenshots
|
||||
|
||||
# Cypress-App-builder-Subpath:
|
||||
# Cypress-App-builder-Subpath:
|
||||
# runs-on: ubuntu-22.04
|
||||
# if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
|
||||
# if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
|
||||
# contains(github.event.pull_request.labels.*.name, 'run-cypress-app-builder-subpath')
|
||||
|
||||
# steps:
|
||||
|
|
|
|||
18
.github/workflows/cypress-platform.yml
vendored
|
|
@ -37,21 +37,9 @@ jobs:
|
|||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
# Create Docker Buildx builder with platform configuration
|
||||
- name: Set up Docker Buildx
|
||||
run: |
|
||||
mkdir -p ~/.docker/cli-plugins
|
||||
curl -SL https://github.com/docker/buildx/releases/download/v0.11.0/buildx-v0.11.0.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx
|
||||
chmod a+x ~/.docker/cli-plugins/docker-buildx
|
||||
docker buildx create --name mybuilder --platform linux/arm64,linux/amd64
|
||||
docker buildx use mybuilder
|
||||
|
||||
- name: Set DOCKER_CLI_EXPERIMENTAL
|
||||
run: echo "DOCKER_CLI_EXPERIMENTAL=enabled" >> $GITHUB_ENV
|
||||
|
||||
- name: use mybuilder buildx
|
||||
run: docker buildx use mybuilder
|
||||
|
||||
- name: Docker Login
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
|
|
@ -228,7 +216,7 @@ jobs:
|
|||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Set up Git authentication for private submodules
|
||||
run: |
|
||||
|
|
@ -364,7 +352,7 @@ jobs:
|
|||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Set up Git authentication for private submodules
|
||||
run: |
|
||||
|
|
@ -512,7 +500,7 @@ jobs:
|
|||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Set up Git authentication for private submodules
|
||||
run: |
|
||||
|
|
|
|||
109
.github/workflows/merging-pr.yml
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
name: Merge Submodule PRs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed, labeled]
|
||||
|
||||
jobs:
|
||||
merge-submodules:
|
||||
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Extract Branch Name
|
||||
run: echo "BRANCH_NAME=${{ github.event.pull_request.head.ref }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Merge PR in ee-server (if exists)
|
||||
run: |
|
||||
PR=$(gh pr list -R ToolJet/ee-server --head "$BRANCH_NAME" --state open --json number -q '.[0].number')
|
||||
if [ -n "$PR" ]; then
|
||||
echo "Found ee-server PR: #$PR"
|
||||
gh pr merge -R ToolJet/ee-server "$PR" --merge --admin
|
||||
else
|
||||
echo "No open ee-server PR for branch $BRANCH_NAME"
|
||||
fi
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.TOKEN_PR }}
|
||||
|
||||
- name: Merge PR in ee-frontend (if exists)
|
||||
run: |
|
||||
PR=$(gh pr list -R ToolJet/ee-frontend --head "$BRANCH_NAME" --state open --json number -q '.[0].number')
|
||||
if [ -n "$PR" ]; then
|
||||
echo "Found ee-frontend PR: #$PR"
|
||||
gh pr merge -R ToolJet/ee-frontend "$PR" --merge --admin
|
||||
else
|
||||
echo "No open ee-frontend PR for branch $BRANCH_NAME"
|
||||
fi
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.TOKEN_PR }}
|
||||
|
||||
|
||||
update-submodule-sha:
|
||||
needs: merge-submodules
|
||||
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout base repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ToolJet/ToolJet
|
||||
token: ${{ secrets.TOKEN_PR }}
|
||||
ref: main
|
||||
submodules: recursive
|
||||
|
||||
- name: Update submodules to latest main
|
||||
run: |
|
||||
git config user.name "adishM98 Bot"
|
||||
git config user.email "adish.madhu@gmail.com"
|
||||
|
||||
git submodule update --remote frontend/ee
|
||||
git submodule update --remote server/ee
|
||||
|
||||
git add frontend/ee server/ee
|
||||
|
||||
if git diff --cached --quiet; then
|
||||
echo "No submodule updates found."
|
||||
else
|
||||
git commit -m "🔄 chore: update submodules to latest main after auto-merge"
|
||||
git push origin main
|
||||
fi
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.TOKEN_PR }}
|
||||
|
||||
check-submodule-prs:
|
||||
if: github.event.action == 'labeled' && github.event.label.name == 'ready-to-merge'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Extract Branch Name
|
||||
run: echo "BRANCH_NAME=${{ github.event.pull_request.head.ref }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Check and Comment Linked Submodule PRs
|
||||
run: |
|
||||
echo "🔍 Checking linked submodule PRs for \`$BRANCH_NAME\`:" > comment.md
|
||||
echo "" >> comment.md
|
||||
|
||||
SERVER_URL=$(gh pr list -R ToolJet/ee-server --head "$BRANCH_NAME" --state open --json url -q '.[0].url')
|
||||
FRONTEND_URL=$(gh pr list -R ToolJet/ee-frontend --head "$BRANCH_NAME" --state open --json url -q '.[0].url')
|
||||
|
||||
if [ -n "$SERVER_URL" ]; then
|
||||
echo "✅ ee-server PR - $SERVER_URL" >> comment.md
|
||||
else
|
||||
echo "❌ No open PR in ee-server" >> comment.md
|
||||
fi
|
||||
|
||||
if [ -n "$FRONTEND_URL" ]; then
|
||||
echo "✅ ee-frontend PR - $FRONTEND_URL" >> comment.md
|
||||
else
|
||||
echo "❌ No open PR in ee-frontend" >> comment.md
|
||||
fi
|
||||
|
||||
echo "" >> comment.md
|
||||
echo "📝 **Note**: The submodule PRs will be auto-merged once you merge this base PR-$PR_NUMBER into \`main\`." >> comment.md
|
||||
|
||||
gh pr comment "$PR_NUMBER" --repo ToolJet/ToolJet --body-file comment.md
|
||||
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.TOKEN_PR }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
52
.github/workflows/vulnerability-ci.yml
vendored
|
|
@ -24,10 +24,10 @@ jobs:
|
|||
with:
|
||||
ref: refs/heads/main
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix frontend install
|
||||
|
|
@ -75,10 +75,10 @@ jobs:
|
|||
with:
|
||||
ref: refs/heads/main
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix server install
|
||||
|
|
@ -106,7 +106,7 @@ jobs:
|
|||
|
||||
- name: Send Slack Notification
|
||||
run: |
|
||||
message="### Periodic Security Audit Report Of Server directory\n
|
||||
message="Periodic Security Audit Report Of Server directory\n
|
||||
Node module vulnerabilities summary:\n
|
||||
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}\n
|
||||
🟠 High: ${{ steps.parse-audit.outputs.high }}\n
|
||||
|
|
@ -126,10 +126,10 @@ jobs:
|
|||
with:
|
||||
ref: refs/heads/main
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix marketplace install
|
||||
|
|
@ -177,10 +177,10 @@ jobs:
|
|||
with:
|
||||
ref: refs/heads/main
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix plugins install
|
||||
|
|
@ -228,10 +228,10 @@ jobs:
|
|||
with:
|
||||
ref: refs/heads/main
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix cypress-tests install
|
||||
|
|
@ -279,10 +279,10 @@ jobs:
|
|||
with:
|
||||
ref: refs/heads/main
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
|
@ -330,10 +330,10 @@ jobs:
|
|||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix frontend install
|
||||
|
|
@ -385,10 +385,10 @@ jobs:
|
|||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix server install
|
||||
|
|
@ -440,10 +440,10 @@ jobs:
|
|||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix marketplace install
|
||||
|
|
@ -494,10 +494,10 @@ jobs:
|
|||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix plugins install
|
||||
|
|
@ -550,10 +550,10 @@ jobs:
|
|||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm --prefix cypress-tests install
|
||||
|
|
@ -606,10 +606,10 @@ jobs:
|
|||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
- name: Use Node.js 18.18.2
|
||||
- name: Use Node.js 22.15.1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.18.2
|
||||
node-version: 22.15.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
|
@ -648,4 +648,4 @@ jobs:
|
|||
🟠 High: ${{ steps.parse-audit.outputs.high }}
|
||||
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}
|
||||
|
||||
Please find the JSON file in the [summary page](${{ github.root_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
|
||||
Please find the JSON file in the [summary page](${{ github.root_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
|
||||
|
|
|
|||
2
.version
|
|
@ -1 +1 @@
|
|||
3.14.0
|
||||
3.15.1
|
||||
|
|
|
|||
4
.vscode/settings.json
vendored
|
|
@ -8,8 +8,8 @@
|
|||
"typescript",
|
||||
"typescriptreact"
|
||||
],
|
||||
"eslint.format.enable": true,
|
||||
"editor.formatOnSave": true,
|
||||
"eslint.format.enable": false,
|
||||
"editor.formatOnSave": false,
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": [
|
||||
|
|
|
|||
|
|
@ -76,8 +76,9 @@ module.exports = defineConfig({
|
|||
experimentalRunAllSpecs: true,
|
||||
baseUrl: "http://localhost:8082",
|
||||
specPattern: [
|
||||
"cypress/e2e/happyPath/appbuilder/commonTestcases/newSuits/**/*.cy.js",
|
||||
// "cypress/e2e/happyPath/appbuilder/ceTestcases/**/*.cy.js"
|
||||
// "cypress/e2e/happyPath/appbuilder/commonTestcases/newSuits/**/*.cy.js",
|
||||
// "cypress/e2e/happyPath/appbuilder/ceTestcases/**/*.cy.js",
|
||||
"cypress/e2e/happyPath/appbuilder/commonTestcases/newSuits/globalSetingsHappyPath.cy.js"
|
||||
],
|
||||
numTestsKeptInMemory: 1,
|
||||
redirectionLimit: 7,
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ module.exports = defineConfig({
|
|||
configFile: environment.configFile,
|
||||
specPattern: [
|
||||
"cypress/e2e/happyPath/platform/firstUser/firstUserOnboarding.cy.js",
|
||||
"cypress/e2e/happyPath/platform/commonTestcases/**/*.cy.js",
|
||||
"cypress/e2e/happyPath/platform/commonTestcases/userManagment/*.cy.js",
|
||||
"cypress/e2e/happyPath/platform/eeTestcases/**/*.cy.js",
|
||||
],
|
||||
numTestsKeptInMemory: 1,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:18.18.2-buster AS builder
|
||||
FROM node:22.15.1 AS builder
|
||||
# Fix for JS heap limit allocation issue
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
|
|
@ -50,10 +50,11 @@ ENV TOOLJET_EDITION=ee
|
|||
COPY ./server/package.json ./server/package-lock.json ./server/
|
||||
RUN npm --prefix server install
|
||||
COPY ./server/ ./server/
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm install -g copyfiles
|
||||
RUN npm --prefix server run build
|
||||
|
||||
FROM node:18.18.2-bullseye
|
||||
FROM node:22.15.1
|
||||
|
||||
RUN apt-get update -yq \
|
||||
&& apt-get install curl wget gnupg zip -yq \
|
||||
|
|
|
|||
|
|
@ -221,21 +221,21 @@ Cypress.Commands.add(
|
|||
const requestBody =
|
||||
envVar === "Enterprise"
|
||||
? {
|
||||
email: userEmail,
|
||||
firstName: userName,
|
||||
groups: [],
|
||||
lastName: "",
|
||||
role: userRole,
|
||||
userMetadata: metaData,
|
||||
}
|
||||
email: userEmail,
|
||||
firstName: userName,
|
||||
groups: [],
|
||||
lastName: "",
|
||||
role: userRole,
|
||||
userMetadata: metaData,
|
||||
}
|
||||
: {
|
||||
email: userEmail,
|
||||
firstName: userName,
|
||||
groups: [],
|
||||
lastName: "",
|
||||
role: userRole,
|
||||
userMetadata: metaData,
|
||||
};
|
||||
email: userEmail,
|
||||
firstName: userName,
|
||||
groups: [],
|
||||
lastName: "",
|
||||
role: userRole,
|
||||
userMetadata: metaData,
|
||||
};
|
||||
|
||||
cy.getCookie("tj_auth_token").then((cookie) => {
|
||||
cy.request(
|
||||
|
|
@ -509,7 +509,7 @@ Cypress.Commands.add("apiDeleteGranularPermission", (groupName) => {
|
|||
// Delete the granular permission
|
||||
cy.request({
|
||||
method: "DELETE",
|
||||
url: `${Cypress.env("server_host")}/api/v2/group-permissions/granular-permissions/${granularPermissionId}`,
|
||||
url: `${Cypress.env("server_host")}/api/v2/group-permissions/granular-permissions/app/${granularPermissionId}`,
|
||||
headers,
|
||||
log: false,
|
||||
}).then((deleteResponse) => {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { selectAppCardOption } from "Support/utils/common";
|
|||
const API_ENDPOINT =
|
||||
Cypress.env("environment") === "Community"
|
||||
? "/api/library_apps"
|
||||
: "/api/library_apps/";
|
||||
: "/api/library_apps";
|
||||
|
||||
Cypress.Commands.add(
|
||||
"appUILogin",
|
||||
|
|
@ -226,9 +226,9 @@ Cypress.Commands.add(
|
|||
.invoke("text")
|
||||
.then((text) => {
|
||||
cy.wrap(subject).realType(createBackspaceText(text)),
|
||||
{
|
||||
delay: 0,
|
||||
};
|
||||
{
|
||||
delay: 0,
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
@ -548,7 +548,7 @@ Cypress.Commands.add("installMarketplacePlugin", (pluginName) => {
|
|||
}
|
||||
});
|
||||
|
||||
function installPlugin(pluginName) {
|
||||
function installPlugin (pluginName) {
|
||||
cy.get('[data-cy="-list-item"]').eq(1).click();
|
||||
cy.wait(1000);
|
||||
|
||||
|
|
@ -621,3 +621,12 @@ Cypress.Commands.add(
|
|||
.and("have.text", `${fieldName} is required`);
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add('ifEnv', (expectedEnvs, callback) => {
|
||||
const actualEnv = Cypress.env("environment");
|
||||
const envArray = Array.isArray(expectedEnvs) ? expectedEnvs : [expectedEnvs];
|
||||
|
||||
if (envArray.includes(actualEnv)) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
|
@ -18,7 +18,7 @@ export const commonSelectors = {
|
|||
canvas: "[data-cy=real-canvas]",
|
||||
appCardOptionsButton: "[data-cy=app-card-menu-icon]",
|
||||
autoSave: "[data-cy=autosave-indicator]",
|
||||
nameInputFieldd: "[data-cy=name-input-field]",
|
||||
inputFieldName: "[data-cy=name-input-field]",
|
||||
valueInputFieldd: "[data-cy=value-input-field]",
|
||||
skipButton: ".driver-close-btn",
|
||||
skipInstallationModal: "[data-cy=skip-button]",
|
||||
|
|
@ -353,7 +353,7 @@ export const commonWidgetSelector = {
|
|||
buttonCloseEditorSideBar: "[data-cy='inspector-close-icon']",
|
||||
buttonStylesEditorSideBar: "#inspector-tab-styles",
|
||||
WidgetNameInputField: "[data-cy=edit-widget-name]",
|
||||
constantInspectorIcon: '[data-cy="inspector-node-constants"] > .node-key',
|
||||
constantInspectorIcon: '[data-cy="inspector-constants-expand-button"]',
|
||||
inspectorIcon: '[data-cy="left-sidebar-inspect-button"]',
|
||||
tooltipInputField: "[data-cy='tooltip-input-field']",
|
||||
tooltipLabel: "[id=button-tooltip]",
|
||||
|
|
|
|||
202
cypress-tests/cypress/constants/selectors/eeCommon.js
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
import { cyParamName } from "./common";
|
||||
|
||||
export const commonEeSelectors = {
|
||||
instanceSettingIcon: '[data-cy="instance-settings-option"]',
|
||||
auditLogIcon: '[data-cy="audit-log-option"]',
|
||||
cancelButton: '[data-cy="cancel-button"]',
|
||||
saveButton: '[data-cy="save-button"]',
|
||||
pageTitle: '[data-cy="dashboard-section-header"]',
|
||||
modalTitle: '[data-cy="modal-title"]',
|
||||
modalCloseButton: '[data-cy="modal-close-button"]',
|
||||
saveButton: '[data-cy="save-button"]',
|
||||
cardTitle: '[data-cy="card-title"]',
|
||||
AddQueryButton: '[data-cy="show-ds-popover-button"]',
|
||||
promoteButton: '[data-cy="promote-button"]',
|
||||
settingsIcon: '[data-cy="icon-settings"]',
|
||||
gitSyncIcon: '[data-cy="git-sync-icon"]',
|
||||
confirmButton: '[data-cy="confirm-button"]',
|
||||
importFromGit: '[data-cy="import-from-git-button"]',
|
||||
searchBar: '[data-cy="query-manager-search-bar"]',
|
||||
nameHeader: '[data-cy="name-header"]',
|
||||
modalMessage: '[data-cy="modal-message"]',
|
||||
paginationSection: '[data-cy="pagination-section"]',
|
||||
|
||||
};
|
||||
|
||||
export const ssoEeSelector = {
|
||||
oidc: '[data-cy="openid-connect-sso-card"]',
|
||||
statusLabel: '[data-cy="status-label"]',
|
||||
oidcToggle: '[data-cy="openid-toggle-input"] > .slider',
|
||||
oidcPageElements: {
|
||||
oidcToggleLabel: '[data-cy="openid-toggle-label"]',
|
||||
nameLabel: '[data-cy="name-label"]',
|
||||
clientIdLabel: '[data-cy="client-id-label"]',
|
||||
clientSecretLabel: '[data-cy="client-secret-label"]',
|
||||
encryptedLabel: '[data-cy="encripted-label"]',
|
||||
WellKnownUrlLabel: '[data-cy="well-known-url-label"]',
|
||||
// redirectUrlLabel: '[data-cy="redirect-url-label"]',
|
||||
},
|
||||
nameInput: '[data-cy="name-input"]',
|
||||
clientIdInput: '[data-cy="client-id-input"]',
|
||||
clientSecretInput: '[data-cy="client-secret-input"]',
|
||||
WellKnownUrlInput: '[data-cy="well-known-url-input"]',
|
||||
redirectUrl: '[data-cy="redirect-url"]',
|
||||
copyIcon: '[data-cy="copy-icon]',
|
||||
oidcSSOText: '[data-cy="oidc-sso-button-text"]',
|
||||
oidcSSOIcon: '[data-cy="oidc-so-icon"]',
|
||||
ldapPageElements: {
|
||||
ldapToggleLabel: '[data-cy="ldap-toggle-label"]',
|
||||
nameLabel: '[data-cy="name-label"]',
|
||||
hostLabel: '[data-cy="host-label"]',
|
||||
portLabel: '[data-cy="port-label"]',
|
||||
baseDnLabel: '[data-cy="base-dn-label"]',
|
||||
baseDnHelperText: '[data-cy="base-dn-helper-text"]',
|
||||
sslLabel: '[data-cy="ssl-label"]',
|
||||
},
|
||||
ldapToggle: '[data-cy="ldap-toggle-input"] > .slider',
|
||||
hostInput: '[data-cy="host-input"]',
|
||||
portInput: '[data-cy="port-input"]',
|
||||
baseDnInput: '[data-cy="base-dn-input"]',
|
||||
sslToggleInput: '[data-cy="ssl-toggle-input"]',
|
||||
ldapSSOText: '[data-cy="ldap-sso-button-text"]',
|
||||
userNameInputLabel: '[data-cy="user-name-input-label"]',
|
||||
passwordInputLabel: '[data-cy="password-label"]',
|
||||
passwordInputField: '[data-cy="password-input-field"]',
|
||||
|
||||
samlModalElements: {
|
||||
toggleLabel: '[data-cy="saml-toggle-label"]',
|
||||
NameLabel: '[data-cy="name-label"]',
|
||||
metaDataLabel: '[data-cy="idp-metadata-label"]',
|
||||
baseDNHelperText: '[data-cy="base-dn-helper-text"]',
|
||||
groupAttributeLabel: '[data-cy="group-attribute-label"]',
|
||||
groupAttributeHelperText: '[data-cy="group-attribute-helper-text"]',
|
||||
}
|
||||
};
|
||||
|
||||
export const eeGroupsSelector = {
|
||||
resourceDs: '[data-cy="resource-datasources"]',
|
||||
dsCreateCheck: '[data-cy="checkbox-create-ds"]',
|
||||
dsDeleteCheck: '[data-cy="checkbox-delete-ds"]',
|
||||
datasourceLink: '[data-cy="datasource-link"]',
|
||||
dsSearch: '[data-cy="datasource-select-search"]',
|
||||
AddDsButton: '[data-cy="datasource-add-button"]',
|
||||
dsNameHeader: '[data-cy="datasource-name-header"]',
|
||||
};
|
||||
|
||||
export const instanceSettingsSelector = {
|
||||
allUsersTab: '[data-cy="all-users-list-item"]',
|
||||
manageInstanceSettings: '[data-cy="manage-instance-settings-list-item"]',
|
||||
typeColumnHeader: '[data-cy="users-table-type-column-header"]',
|
||||
workspaceColumnHeader: '[data-cy="users-table-workspaces-column-header"]',
|
||||
userName: (userName) => {
|
||||
return `[data-cy="${cyParamName(userName)}-user-name"]`;
|
||||
},
|
||||
userEmail: (userName) => {
|
||||
return `[data-cy="${cyParamName(userName)}-user-email"]`;
|
||||
},
|
||||
userType: (userName) => {
|
||||
return `[data-cy="${cyParamName(userName)}-user-type"]`;
|
||||
},
|
||||
userStatus: (userName) => {
|
||||
return `[data-cy="${cyParamName(userName)}-user-status"]`;
|
||||
},
|
||||
viewButton: (userName) => {
|
||||
return `[data-cy="${cyParamName(userName)}-user-view-button"]`;
|
||||
},
|
||||
editButton: (userName) => {
|
||||
return `[data-cy="${cyParamName(userName)}-user-edit-button"]`;
|
||||
},
|
||||
viewModalNoColumnHeader: '[data-cy="number-column-header"]',
|
||||
viewModalNameColumnHeader: '[data-cy="name-column-header"]',
|
||||
viewModalStatusColumnHeader: '[data-cy="status-column-header"]',
|
||||
archiveAllButton: '[data-cy="archive-all-button"]',
|
||||
viewModalRow: (workspaceName) => {
|
||||
return `[data-cy="${cyParamName(workspaceName)}-workspace-row"]>`;
|
||||
},
|
||||
|
||||
workspaceName: (workspaceName) => {
|
||||
return `[data-cy="${cyParamName(workspaceName)}-workspace-name"]`;
|
||||
},
|
||||
userStatusChangeButton: '[data-cy="user-state-change-button"]',
|
||||
superAdminToggle: '[data-cy="super-admin-form-check-input"]',
|
||||
superAdminToggleLabel: '[data-cy="super-admin-form-check-label"]',
|
||||
allowWorkspaceToggle: '[data-cy="form-check-input"]',
|
||||
allowWorkspaceToggleLabel: '[data-cy="form-check-label"]',
|
||||
allowWorkspaceHelperText: '[data-cy="instance-settings-help-text"]',
|
||||
allWorkspaceTab: '[data-cy="all-workspaces-list-item"]',
|
||||
};
|
||||
|
||||
|
||||
export const multiEnvSelector = {
|
||||
envContainer: '[data-cy="env-container"]',
|
||||
currentEnvName: '[data-cy="list-current-env-name"]',
|
||||
envArrow: '[data-cy="env-arrow"]',
|
||||
selectedEnvName: '[data-cy="selected-current-env-name"]',
|
||||
envNameList: '[data-cy="env-name-list"]',
|
||||
appVersionLabel: '[data-cy="app-version-label"]',
|
||||
currentVersion: '[data-cy="current-version"]',
|
||||
createNewVersionButton: '[data-cy="create-new-version-button"]',
|
||||
fromLabel: '[data-cy="from-label"]',
|
||||
toLabel: '[data-cy="to-label"]',
|
||||
currEnvName: '[data-cy="current-env-name"]',
|
||||
targetEnvName: '[data-cy="target-env-name"]',
|
||||
stagingLabel: '[data-cy="staging-label"]',
|
||||
productionLabel: '[data-cy="production-label"]',
|
||||
};
|
||||
|
||||
export const whiteLabellingSelectors = {
|
||||
whiteLabelList: '[data-cy="white-labelling-list-item"]',
|
||||
appLogoLabel: '[data-cy="app-logo-label"]',
|
||||
appLogoInput: '[data-cy="input-field-app-logo"]',
|
||||
appLogoHelpText: '[data-cy="app-logo-help-text"]',
|
||||
pageTitleLabel: '[data-cy="page-title-label"]',
|
||||
pageTitleInput: '[data-cy="input-field-page-title"]',
|
||||
pageTitleHelpText: '[data-cy="page-title-help-text"]',
|
||||
favIconLabel: '[data-cy="fav-icon-label"]',
|
||||
favIconInput: '[data-cy="input-field-fav-icon"]',
|
||||
favIconHelpText: '[data-cy="fav-icon-help-text"]',
|
||||
};
|
||||
|
||||
export const gitSyncSelector = {
|
||||
gitCommitInput: '[data-cy="git-commit-input"]',
|
||||
commitHelperText: '[data-cy="commit-helper-text"]',
|
||||
gitRepoInput: '[data-cy="git-repo-input"]',
|
||||
commitMessageInput: '[data-cy="commit-message-input"]',
|
||||
lastCommitInput: '[data-cy="las-commit-message"]',
|
||||
lastCommitVersion: '[data-cy="last-commit-version"]',
|
||||
autherInfo: '[data-cy="auther-info"]',
|
||||
commitButton: '[data-cy="commit-button"]',
|
||||
gitSyncToggleInput: '[data-cy="git-sync-toggle-input"]',
|
||||
gitSyncApphelperText: '[data-cy="sync-app-helper-text"]',
|
||||
connectRepoButton: '[data-cy="connect-repo-button"]',
|
||||
toggleMessage: '[data-cy="toggle-message"]',
|
||||
sshInput: '[data-cy="git-ssh-input"]',
|
||||
generateSshButton: '[data-cy="generate-ssh-key-button"',
|
||||
sshInputHelperText: '[data-cy="git-ssh-input-helper-text"]',
|
||||
configDeleteButton: '[data-cy="button-config-delete"]',
|
||||
testConnectionButton: '[data-cy="test-connection-button"]',
|
||||
sshKey: '[data-cy="ssh-key"]',
|
||||
deployKeyHelperText: '[data-cy="deploy-key-helper-text"]',
|
||||
gitRepoLink: '[data-cy="git-repo-link"]',
|
||||
appNameField: '[data-cy="app-name-field"]',
|
||||
gitRepoInfo: '[data-cy="git-repo-info"]',
|
||||
pullButton: '[data-cy="pull-button"]'
|
||||
|
||||
|
||||
}
|
||||
|
||||
export const workspaceSelector = {
|
||||
activelink: '[data-cy="active-link"]',
|
||||
archivedLik: '[data-cy="archived-link"]',
|
||||
userStatusChange: '[data-cy="button-user-status-change"]',
|
||||
workspaceStatusChange: '[data-cy="button-ws-status-change"]',
|
||||
switchWsModalTitle: '[data-cy="switch-modal-title"]',
|
||||
switchWsModalMessage: '[data-cy="switch-modal-message"]',
|
||||
workspaceName: (workspaceName) => {
|
||||
return `[data-cy="${workspaceName}-workspace-name"]`
|
||||
},
|
||||
workspaceInput: (workspaceName) => {
|
||||
return `[data-cy="${workspaceName}-workspace-input"]`
|
||||
},
|
||||
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ export const groupsSelector = {
|
|||
resourceLabel: '[data-cy="resource-label"]',
|
||||
allAppsRadio: '[data-cy="all-apps-radio"]',
|
||||
allAppsLabel: '[data-cy="all-apps-label"]',
|
||||
allAppsHelperText: '[data-cy="all-apps-info-text"]',
|
||||
allAppsHelperText: '[data-cy="this-will-select-all-apps-in-the-workspace-including-any-new-apps-created-info-text"]',
|
||||
customradio: '[data-cy="custom-radio"]',
|
||||
customLabel: '[data-cy="custom-label"]',
|
||||
customHelperText: '[data-cy="custom-info-text"]',
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ export const onboardingSelectors = {
|
|||
basicPlanTitle: '[data-cy="basic-plan-title"]',
|
||||
planPrice: '[data-cy="plan-price"]',
|
||||
pricePeriod: '[data-cy="price-period"]',
|
||||
flexibleTitle: '[data-cy="flexible-title"]',
|
||||
businessTitle: '[data-cy="business-title"]',
|
||||
flexibleTitle: '[data-cy="pro-title"]',
|
||||
businessTitle: '[data-cy="team-title"]',
|
||||
enterpriseTitle: '[data-cy="enterprise-title"]',
|
||||
customPricingHeader: '[data-cy="custom-pricing-header"]',
|
||||
noCreditCardBanner: '[data-cy="no-credit-card-banner"]',
|
||||
|
|
|
|||
75
cypress-tests/cypress/constants/texts/eeCommon.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
export const commonEeText = {
|
||||
cancelButton: "Cancel",
|
||||
saveButton: "Save changes",
|
||||
closeButton: "Close",
|
||||
defaultWorkspace: "My workspace",
|
||||
};
|
||||
|
||||
export const ssoEeText = {
|
||||
statusLabel: "Disabled",
|
||||
enabledLabel: "Enabled",
|
||||
disabledLabel: "Disabled",
|
||||
oidcPageElements: {
|
||||
oidcToggleLabel: "OpenID Connect",
|
||||
nameLabel: "Name",
|
||||
clientIdLabel: "Client ID",
|
||||
clientSecretLabel: "Client secretEncrypted",
|
||||
encryptedLabel: "Encrypted",
|
||||
WellKnownUrlLabel: "Well known URL",
|
||||
// redirectUrlLabel: "Redirect URL",
|
||||
},
|
||||
oidcEnabledToast: "Enabled OpenId SSO",
|
||||
oidcDisabledToast: "Disabled OpenId SSO",
|
||||
oidcUpdatedToast: "updated SSO configurations",
|
||||
testName: "Tooljet OIDC",
|
||||
testclientId: "24567098-mklj8t20za1smb2if.apps.googleusercontent.com",
|
||||
testclientSecret: "2345-client-id-.apps.googleusercontent.com",
|
||||
testWellknownUrl: "google.com",
|
||||
oidcSSOText: "Sign in with Tooljet OIDC",
|
||||
|
||||
ldapPageElements: {
|
||||
ldapToggleLabel: "LDAP",
|
||||
nameLabel: "Name",
|
||||
hostLabel: "Host name",
|
||||
portLabel: "Port",
|
||||
baseDnLabel: "Base DN",
|
||||
baseDnHelperText: "Location without UID or CN",
|
||||
sslLabel: "SSL",
|
||||
},
|
||||
ldapSSOText: "Sign in with Tooljet LDAP Auth",
|
||||
userNameInputLabel: "Username",
|
||||
samlModalElements: {
|
||||
toggleLabel: "SAML",
|
||||
NameLabel: "Name",
|
||||
metaDataLabel: "Identity provider metadata",
|
||||
baseDNHelperText:
|
||||
"Ensure the Identity provider metadata is in XML format. You can download it from your IdP's site",
|
||||
groupAttributeLabel: "Group attribute",
|
||||
groupAttributeHelperText:
|
||||
"Define attribute for user-to-group mapping based on the IdP",
|
||||
},
|
||||
};
|
||||
export const eeGroupsText = {
|
||||
resourceDs: "Datasources",
|
||||
AddDsButton: "Add",
|
||||
dsNameHeader: "Datasource name",
|
||||
};
|
||||
|
||||
export const instanceSettingsText = {
|
||||
pageTitle: "Settings",
|
||||
allUsersTab: "All users",
|
||||
manageInstanceSettings: "Manage instance settings",
|
||||
typeColumnHeader: "Type",
|
||||
workspaceColumnHeader: "Workspaces",
|
||||
superAdminType: "instance",
|
||||
viewModalTitle: "Workspaces of The Developer",
|
||||
archiveAllButton: "Archive All",
|
||||
archiveState: "Archive",
|
||||
editModalTitle: "Edit user details",
|
||||
superAdminToggleLabel: "Super admin",
|
||||
allowWorkspaceToggleLabel: "Allow personal workspace",
|
||||
allowWorkspaceHelperText:
|
||||
"This feature will enable users to create their own workspace",
|
||||
saveButton: "Save",
|
||||
untitledWorkspace: "Untitled workspace",
|
||||
};
|
||||
|
|
@ -78,7 +78,7 @@ export const groupsText = {
|
|||
allAppsLabel: 'All apps',
|
||||
allAppsHelperText: 'This will select all apps in the workspace including any new apps created',
|
||||
customLabel: 'Custom',
|
||||
customHelperText: 'Select specific applications you want to add to the group',
|
||||
customHelperText: 'Select specific apps you want to add to the group',
|
||||
updateButtonText: 'Update',
|
||||
addButtonText: 'Add',
|
||||
userRole: 'User role',
|
||||
|
|
|
|||
|
|
@ -59,4 +59,9 @@ export const ssoText = {
|
|||
alertText: "Danger zone",
|
||||
disablePasswordHelperText:
|
||||
"Disable password login only if your SSO is configured otherwise you will get locked out",
|
||||
disablePasswordHelperText:
|
||||
"Disable password login only if your SSO is configured otherwise you will get locked out",
|
||||
toggleUpdateToast: (toggle) => {
|
||||
return `Saved ${toggle} SSO configurations`
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ export const onboardingText = {
|
|||
endUserPriceText: "$10",
|
||||
comparePlansText: "Compare plans",
|
||||
basicPlanText: "Basic Plan",
|
||||
flexibleText: "Flexible",
|
||||
businessText: "Business",
|
||||
flexibleText: "Pro",
|
||||
businessText: "Team",
|
||||
enterpriseText: "Enterprise",
|
||||
customPricingText: "Custom pricing",
|
||||
noCreditCardText: "No credit card required!",
|
||||
|
|
|
|||
|
|
@ -1,34 +1,5 @@
|
|||
import { fake } from "Fixtures/fake";
|
||||
import { textInputText } from "Texts/textInput";
|
||||
import { commonWidgetText, widgetValue, customValidation } from "Texts/common";
|
||||
import { commonSelectors, commonWidgetSelector } from "Selectors/common";
|
||||
import { buttonText } from "Texts/button";
|
||||
import {
|
||||
verifyControlComponentAction,
|
||||
randomString,
|
||||
} from "Support/utils/editor/textInput";
|
||||
import {
|
||||
openAccordion,
|
||||
verifyAndModifyParameter,
|
||||
openEditorSidebar,
|
||||
verifyAndModifyToggleFx,
|
||||
addDefaultEventHandler,
|
||||
verifyComponentValueFromInspector,
|
||||
selectColourFromColourPicker,
|
||||
verifyBoxShadowCss,
|
||||
verifyLayout,
|
||||
verifyTooltip,
|
||||
editAndVerifyWidgetName,
|
||||
verifyPropertiesGeneralAccordion,
|
||||
verifyStylesGeneralAccordion,
|
||||
randomNumber,
|
||||
closeAccordions,
|
||||
} from "Support/utils/commonWidget";
|
||||
import {
|
||||
selectCSA,
|
||||
selectEvent,
|
||||
addSupportCSAData,
|
||||
} from "Support/utils/events";
|
||||
import { commonWidgetSelector } from "Selectors/common";
|
||||
|
||||
describe("Editor title", () => {
|
||||
const data = {};
|
||||
|
|
@ -42,10 +13,10 @@ describe("Editor title", () => {
|
|||
afterEach(() => {
|
||||
cy.apiDeleteApp();
|
||||
});
|
||||
it("should verify titles", () => {
|
||||
it.skip("should verify titles", () => {
|
||||
cy.url().should("include", "/tooljets-workspace");
|
||||
// cy.title().should("eq", "Dashboard | ToolJet");
|
||||
cy.title().should("eq", "ToolJet");
|
||||
cy.title().should("eq", "Dashboard | ToolJet");
|
||||
// cy.title().should("eq", "ToolJet");
|
||||
|
||||
cy.log(data.appName);
|
||||
|
||||
|
|
@ -57,7 +28,7 @@ describe("Editor title", () => {
|
|||
|
||||
cy.url().should("include", `/applications/${Cypress.env("appId")}`);
|
||||
// cy.title().should("eq", `${data.appName} | ToolJet`);
|
||||
// cy.title().should("eq", `Preview - ${data.appName} | ToolJet`);
|
||||
cy.title().should("eq", `Preview - ${data.appName} | ToolJet`);
|
||||
|
||||
cy.go("back");
|
||||
cy.releaseApp();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
verifyCSA
|
||||
} from "Support/utils/editor/textInput";
|
||||
import { addMultiEventsWithAlert } from "Support/utils/events";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyValue } from "Support/utils/inspector";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyNodeData } from "Support/utils/inspector";
|
||||
|
||||
|
||||
describe('Button Component Tests', () => {
|
||||
|
|
@ -75,22 +75,21 @@ describe('Button Component Tests', () => {
|
|||
cy.apiLogin();
|
||||
cy.apiCreateApp(`${fake.companyName}-Button-App`);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Button", 50, 50);
|
||||
cy.dragAndDropWidget("Button", 500, 500);
|
||||
cy.get('[data-cy="query-manager-toggle-button"]').click();
|
||||
});
|
||||
|
||||
it('should verify all the exposed values on inspector', () => {
|
||||
cy.get(commonWidgetSelector.sidebarinspector).click();
|
||||
cy.get(".tooltip-inner").invoke("hide");
|
||||
|
||||
openNode("components");
|
||||
openAndVerifyNode("button1", exposedValues, verifyValue);
|
||||
verifyNodes(functions, verifyfunctions);
|
||||
openAndVerifyNode("button1", exposedValues, verifyNodeData);
|
||||
verifyNodes(functions, verifyNodeData);
|
||||
//id is pending
|
||||
|
||||
});
|
||||
|
||||
it.skip('should verify all the events from the button', () => {
|
||||
it('should verify all the events from the button', () => {
|
||||
const events = [
|
||||
{ event: "On hover", message: "On hover Event" },
|
||||
{ event: "On Click", message: "On Click Event" },
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
verifyCSA
|
||||
} from "Support/utils/editor/textInput";
|
||||
import { addMultiEventsWithAlert } from "Support/utils/events";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyValue } from "Support/utils/inspector";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyNodeData } from "Support/utils/inspector";
|
||||
|
||||
|
||||
describe('Checkbox Component Tests', () => {
|
||||
|
|
@ -83,7 +83,7 @@ describe('Checkbox Component Tests', () => {
|
|||
cy.apiLogin();
|
||||
cy.apiCreateApp(`${fake.companyName}-Checkbox-App`);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Checkbox", 50, 50);
|
||||
cy.dragAndDropWidget("Checkbox", 500, 500);
|
||||
cy.get('[data-cy="query-manager-toggle-button"]').click();
|
||||
});
|
||||
|
||||
|
|
@ -92,8 +92,8 @@ describe('Checkbox Component Tests', () => {
|
|||
cy.get(".tooltip-inner").invoke("hide");
|
||||
|
||||
openNode("components");
|
||||
openAndVerifyNode("checkbox1", exposedValues, verifyValue);
|
||||
verifyNodes(functions, verifyfunctions);
|
||||
openAndVerifyNode("checkbox1", exposedValues, verifyNodeData);
|
||||
verifyNodes(functions, verifyNodeData);
|
||||
//id is pending
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
verifyCSA
|
||||
} from "Support/utils/editor/textInput";
|
||||
import { addMultiEventsWithAlert } from "Support/utils/events";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyValue } from "Support/utils/inspector";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyNodeData } from "Support/utils/inspector";
|
||||
|
||||
|
||||
describe('Dropdown Component Tests', () => {
|
||||
|
|
@ -101,7 +101,7 @@ describe('Dropdown Component Tests', () => {
|
|||
cy.get(".tooltip-inner").invoke("hide");
|
||||
|
||||
openNode("components");
|
||||
openAndVerifyNode("dropdown1", exposedValues, verifyValue);
|
||||
openAndVerifyNode("dropdown1", exposedValues, verifyNodeData);
|
||||
verifyNodes(functions, verifyfunctions);
|
||||
//id is pending
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { deleteDownloadsFolder } from "Support/utils/common";
|
|||
import {
|
||||
resizeQueryPanel
|
||||
} from "Support/utils/dataSource";
|
||||
import { openNode, verifyNodeData, verifyValue } from "Support/utils/inspector";
|
||||
import { openNode, verifyNodeData } from "Support/utils/inspector";
|
||||
import {
|
||||
addNewPage
|
||||
} from "Support/utils/multipage";
|
||||
|
|
@ -49,11 +49,11 @@ describe("Global Actions", () => {
|
|||
verifyNodeData("variables", "Object", "1 entry ");
|
||||
openNode("variables", 0);
|
||||
|
||||
verifyValue("var", "String", `"test"`);
|
||||
verifyNodeData("var", "String", `"test"`);
|
||||
|
||||
openNode("page");
|
||||
openNode("variables", 1);
|
||||
verifyValue("pageVar", "String", `"pageTest"`);
|
||||
verifyNodeData("pageVar", "String", `"pageTest"`);
|
||||
|
||||
addInputOnQueryField(
|
||||
"runjs",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
verifyCSA
|
||||
} from "Support/utils/editor/textInput";
|
||||
import { addMultiEventsWithAlert } from "Support/utils/events";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyValue } from "Support/utils/inspector";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyNodeData } from "Support/utils/inspector";
|
||||
|
||||
|
||||
describe('Multiselect Component Tests', () => {
|
||||
|
|
@ -104,7 +104,7 @@ describe('Multiselect Component Tests', () => {
|
|||
cy.get(".tooltip-inner").invoke("hide");
|
||||
|
||||
openNode("components");
|
||||
openAndVerifyNode("multiselect1", exposedValues, verifyValue);
|
||||
openAndVerifyNode("multiselect1", exposedValues, verifyNodeData);
|
||||
verifyNodes(functions, verifyfunctions);
|
||||
//id is pending
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
verifyCSA
|
||||
} from "Support/utils/editor/textInput";
|
||||
import { addMultiEventsWithAlert } from "Support/utils/events";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyValue } from "Support/utils/inspector";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyNodeData } from "Support/utils/inspector";
|
||||
|
||||
|
||||
describe('Number Input Component Tests', () => {
|
||||
|
|
@ -86,7 +86,7 @@ describe('Number Input Component Tests', () => {
|
|||
cy.apiLogin();
|
||||
cy.apiCreateApp(`${fake.companyName}-Numberinput-App`);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Number Input", 50, 50);
|
||||
cy.dragAndDropWidget("Number Input", 500, 500);
|
||||
cy.get('[data-cy="query-manager-toggle-button"]').click();
|
||||
});
|
||||
|
||||
|
|
@ -95,8 +95,8 @@ describe('Number Input Component Tests', () => {
|
|||
cy.get(".tooltip-inner").invoke("hide");
|
||||
|
||||
openNode("components");
|
||||
openAndVerifyNode("numberinput1", exposedValues, verifyValue);
|
||||
verifyNodes(functions, verifyfunctions);
|
||||
openAndVerifyNode("numberinput1", exposedValues, verifyNodeData);
|
||||
verifyNodes(functions, verifyNodeData);
|
||||
//id is pending
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
verifyCSA
|
||||
} from "Support/utils/editor/textInput";
|
||||
import { addMultiEventsWithAlert } from "Support/utils/events";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyValue } from "Support/utils/inspector";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyNodeData } from "Support/utils/inspector";
|
||||
|
||||
|
||||
describe('Password Input Component Tests', () => {
|
||||
|
|
@ -95,7 +95,7 @@ describe('Password Input Component Tests', () => {
|
|||
cy.get(".tooltip-inner").invoke("hide");
|
||||
|
||||
openNode("components");
|
||||
openAndVerifyNode("passwordinput1", exposedValues, verifyValue);
|
||||
openAndVerifyNode("passwordinput1", exposedValues, verifyNodeData);
|
||||
verifyNodes(functions, verifyfunctions);
|
||||
//id is pending
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
verifyCSA
|
||||
} from "Support/utils/editor/textInput";
|
||||
import { addMultiEventsWithAlert } from "Support/utils/events";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyValue } from "Support/utils/inspector";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyNodeData } from "Support/utils/inspector";
|
||||
|
||||
|
||||
describe('Text Input Component Tests', () => {
|
||||
|
|
@ -27,14 +27,14 @@ describe('Text Input Component Tests', () => {
|
|||
"key": "setBlur",
|
||||
"type": "Function"
|
||||
},
|
||||
{
|
||||
"key": "disable",
|
||||
"type": "Function"
|
||||
},
|
||||
{
|
||||
"key": "visibility",
|
||||
"type": "Function"
|
||||
},
|
||||
// {
|
||||
// "key": "disable",
|
||||
// "type": "Function"
|
||||
// },
|
||||
// {
|
||||
// "key": "visibility",
|
||||
// "type": "Function"
|
||||
// },
|
||||
{
|
||||
"key": "setVisibility",
|
||||
"type": "Function"
|
||||
|
|
@ -94,17 +94,17 @@ describe('Text Input Component Tests', () => {
|
|||
cy.apiLogin();
|
||||
cy.apiCreateApp(`${fake.companyName}-Textinput-App`);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Text Input", 50, 50);
|
||||
cy.dragAndDropWidget("Text Input", 500, 500);
|
||||
cy.get('[data-cy="query-manager-toggle-button"]').click();
|
||||
});
|
||||
|
||||
it.skip('should verify all the exposed values on inspector', () => {
|
||||
it('should verify all the exposed values on inspector', () => {
|
||||
cy.get(commonWidgetSelector.sidebarinspector).click();
|
||||
cy.get(".tooltip-inner").invoke("hide");
|
||||
|
||||
openNode("components");
|
||||
openAndVerifyNode("textinput1", exposedValues, verifyValue);
|
||||
verifyNodes(functions, verifyfunctions);
|
||||
openAndVerifyNode("textinput1", exposedValues, verifyNodeData);
|
||||
verifyNodes(functions, verifyNodeData);
|
||||
//id is pending
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
verifyCSA
|
||||
} from "Support/utils/editor/textInput";
|
||||
import { addMultiEventsWithAlert } from "Support/utils/events";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyValue } from "Support/utils/inspector";
|
||||
import { openAndVerifyNode, openNode, verifyfunctions, verifyNodes, verifyNodeData } from "Support/utils/inspector";
|
||||
|
||||
|
||||
describe('ToggleSwitch Component Tests', () => {
|
||||
|
|
@ -88,7 +88,7 @@ describe('ToggleSwitch Component Tests', () => {
|
|||
cy.get(".tooltip-inner").invoke("hide");
|
||||
|
||||
openNode("components");
|
||||
openAndVerifyNode("toggleswitch1", exposedValues, verifyValue);
|
||||
openAndVerifyNode("toggleswitch1", exposedValues, verifyNodeData);
|
||||
verifyNodes(functions, verifyfunctions);
|
||||
//id is pending
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
selectColourFromColourPicker,
|
||||
verifyWidgetColorCss,
|
||||
} from "Support/utils/commonWidget";
|
||||
import { verifyNodeData, openNode, verifyValue } from "Support/utils/inspector";
|
||||
// import { verifyNodeData, openNode, verifyNodeData } from "Support/utils/inspector";
|
||||
import { commonSelectors, commonWidgetSelector } from "Selectors/common";
|
||||
import {
|
||||
commonText,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { commonWidgetSelector } from "Selectors/common";
|
|||
import { multipageSelector } from "Selectors/multipage";
|
||||
import { addSupportCSAData, selectEvent } from "Support/utils/events";
|
||||
import { createNewVersion } from "Support/utils/exportImport";
|
||||
import { deleteComponentFromInspector, openNode, verifyNodeData, verifyValue, verifyNodes, openAndVerifyNode } from "Support/utils/inspector";
|
||||
import { deleteComponentFromInspector, openNode, verifyNodeData, verifyNodes, openAndVerifyNode } from "Support/utils/inspector";
|
||||
import { addNewPage } from "Support/utils/multipage";
|
||||
import { navigateToCreateNewVersionModal } from "Support/utils/version";
|
||||
import testData from "Fixtures/inspectorItems.json";
|
||||
|
|
@ -20,15 +20,15 @@ describe("Editor- Inspector", () => {
|
|||
cy.viewport(1800, 1800);
|
||||
});
|
||||
|
||||
it("should verify the values of inspector", () => {
|
||||
it.skip("should verify the values of inspector", () => {
|
||||
cy.get(commonWidgetSelector.sidebarinspector).click();
|
||||
cy.get(".tooltip-inner").invoke("hide");
|
||||
|
||||
openAndVerifyNode("globals", testData.globalsNodes, verifyNodeData);
|
||||
openAndVerifyNode("currentUser", testData.currentUserNodes, verifyValue);
|
||||
openAndVerifyNode("theme", testData.themeNodes, verifyValue);
|
||||
openAndVerifyNode("mode", testData.modeNodes, verifyValue);
|
||||
openAndVerifyNode("urlparams", testData.urlparamsNode, verifyValue);
|
||||
openAndVerifyNode("currentUser", testData.currentUserNodes, verifyNodeData);
|
||||
openAndVerifyNode("theme", testData.themeNodes, verifyNodeData);
|
||||
openAndVerifyNode("mode", testData.modeNodes, verifyNodeData);
|
||||
openAndVerifyNode("urlparams", testData.urlparamsNode, verifyNodeData);
|
||||
|
||||
if (Cypress.env("environment") !== "Community") {
|
||||
const ssoUserInfoNode = '[data-cy="inspector-node-ssouserinfo"]';
|
||||
|
|
@ -39,7 +39,7 @@ describe("Editor- Inspector", () => {
|
|||
|
||||
openNode("theme");
|
||||
openNode("environment");
|
||||
verifyValue("name", "String", `"development"`);
|
||||
verifyNodeData("name", "String", `"development"`);
|
||||
cy.get(`${inspectorNodeId} > .node-key`).should("have.text", "id");
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ describe("Editor- Inspector", () => {
|
|||
cy.get(commonWidgetSelector.draggableWidget("button3")).click();
|
||||
|
||||
cy.get(commonWidgetSelector.sidebarinspector).click();
|
||||
openAndVerifyNode("variables", testData.variablesNodes, verifyValue);
|
||||
openAndVerifyNode("variables", testData.variablesNodes, verifyNodeData);
|
||||
|
||||
cy.forceClickOnCanvas()
|
||||
cy.wait(500)
|
||||
|
|
@ -101,9 +101,9 @@ describe("Editor- Inspector", () => {
|
|||
|
||||
// openNode("page");
|
||||
|
||||
openAndVerifyNode("page", testData.testPageNodes, verifyValue);
|
||||
openAndVerifyNode("page", testData.testPageNodes, verifyNodeData);
|
||||
openNode("variables", 1);
|
||||
verifyValue("pageVar", "String", `"pageVar"`);
|
||||
verifyNodeData("pageVar", "String", `"pageVar"`);
|
||||
|
||||
openAndVerifyNode("components", testData.componentsNodes, verifyNodeData);
|
||||
|
||||
|
|
@ -111,10 +111,10 @@ describe("Editor- Inspector", () => {
|
|||
cy.get(commonWidgetSelector.draggableWidget("button1")).click();
|
||||
cy.get(commonWidgetSelector.sidebarinspector).click();
|
||||
|
||||
openAndVerifyNode("page", testData.pageNodes, verifyValue);
|
||||
openAndVerifyNode("page", testData.pageNodes, verifyNodeData);
|
||||
openNode("globals");
|
||||
openNode("urlparams");
|
||||
verifyValue("key", "String", `"value"`);
|
||||
verifyNodeData("key", "String", `"value"`);
|
||||
|
||||
cy.get(`[data-cy="inspector-node-key"] > .mx-1`)
|
||||
.realHover()
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ describe("Chaining of queries", () => {
|
|||
cy.wait(1000)
|
||||
cy.get('[data-cy="query-tab-setup"]').click();
|
||||
|
||||
cy.wait(1500);
|
||||
openEditorSidebar(buttonText.defaultWidgetName);
|
||||
selectEvent("On Click", "Run Query", 0, `[data-cy="add-event-handler"]`, 0);
|
||||
cy.wait(500);
|
||||
|
|
@ -122,7 +123,7 @@ describe("Chaining of queries", () => {
|
|||
// cy.verifyToastMessage(commonSelectors.toastMessage, "Hello World");
|
||||
});
|
||||
|
||||
it.skip("should verify query duplication", () => {
|
||||
it("should verify query duplication", () => {
|
||||
|
||||
const data = {};
|
||||
let dsName = fake.companyName;
|
||||
|
|
@ -146,6 +147,7 @@ describe("Chaining of queries", () => {
|
|||
chainQuery("runjs", "runpy");
|
||||
addSuccessNotification("runjs");
|
||||
|
||||
cy.wait(1500);
|
||||
openEditorSidebar(buttonText.defaultWidgetName);
|
||||
selectEvent("On Click", "Run Query", 0, `[data-cy="add-event-handler"]`, 0);
|
||||
cy.wait(500);
|
||||
|
|
@ -170,6 +172,8 @@ describe("Chaining of queries", () => {
|
|||
"have.text",
|
||||
"runjs_copy "
|
||||
);
|
||||
|
||||
cy.get('[data-cy="query-tab-settings"]').click();
|
||||
cy.get('[data-cy="notification-on-success-toggle-switch"]').should(
|
||||
"have.value",
|
||||
"on"
|
||||
|
|
@ -184,7 +188,7 @@ describe("Chaining of queries", () => {
|
|||
});
|
||||
cy.get(
|
||||
`[data-cy="action-selection"] > .select-search > .react-select__control > .react-select__value-container > `
|
||||
).should("have.text", "Run Query");
|
||||
).should("have.text", "Run query");
|
||||
cy.get('[data-cy="query-selection-field"]').should("have.text", "runpy");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import {
|
|||
resizeQueryPanel,
|
||||
verifypreview
|
||||
} from "Support/utils/dataSource";
|
||||
import { openNode, verifyValue } from "Support/utils/inspector";
|
||||
import { openNode, verifyNodeData } from "Support/utils/inspector";
|
||||
|
||||
describe("RunJS", () => {
|
||||
beforeEach(() => {
|
||||
|
|
@ -42,15 +42,15 @@ describe("RunJS", () => {
|
|||
|
||||
selectQueryFromLandingPage("runjs", "JavaScript");
|
||||
addInputOnQueryField("runjs", "return true");
|
||||
query("preview");
|
||||
query("run");
|
||||
verifypreview("raw", "true");
|
||||
query("run");
|
||||
cy.get(commonWidgetSelector.sidebarinspector).click();
|
||||
cy.get(".tooltip-inner").invoke("hide");
|
||||
openNode("queries");
|
||||
openNode("runjs1");
|
||||
verifyValue("data", "Boolean", "true");
|
||||
verifyValue("rawData", "Boolean", "true");
|
||||
verifyNodeData("data", "Boolean", "true");
|
||||
verifyNodeData("rawData", "Boolean", "true");
|
||||
cy.apiDeleteApp();
|
||||
});
|
||||
|
||||
|
|
@ -60,11 +60,11 @@ describe("RunJS", () => {
|
|||
|
||||
selectQueryFromLandingPage("runjs", "JavaScript");
|
||||
addInputOnQueryField("runjs", "return [page.handle,page.name]");
|
||||
query("preview");
|
||||
query("run");
|
||||
verifypreview("raw", `["home","Home"]`);
|
||||
|
||||
addInputOnQueryField("runjs", "return globals.theme");
|
||||
query("preview");
|
||||
query("run");
|
||||
verifypreview("raw", `{"name":"light"}`);
|
||||
|
||||
// addInputOnQueryField("runjs", "return globals.currentUser");
|
||||
|
|
@ -24,7 +24,7 @@ import {
|
|||
resizeQueryPanel,
|
||||
verifypreview
|
||||
} from "Support/utils/dataSource";
|
||||
import { openNode, verifyNodeData, verifyValue } from "Support/utils/inspector";
|
||||
import { openNode, verifyNodeData } from "Support/utils/inspector";
|
||||
import {
|
||||
addNewPage
|
||||
} from "Support/utils/multipage";
|
||||
|
|
@ -54,8 +54,8 @@ describe("runpy", () => {
|
|||
cy.get(".tooltip-inner").invoke("hide");
|
||||
openNode("queries");
|
||||
openNode("runpy1");
|
||||
verifyValue("data", "Boolean", "true");
|
||||
verifyValue("rawData", "Boolean", "true");
|
||||
verifyNodeData("data", "Boolean", "true");
|
||||
verifyNodeData("rawData", "Boolean", "true");
|
||||
cy.apiDeleteApp();
|
||||
});
|
||||
|
||||
|
|
@ -76,11 +76,11 @@ actions.setPageVariable('pageVar', 'pageTest')`
|
|||
verifyNodeData("variables", "Object", "1 entry ");
|
||||
openNode("variables", 0);
|
||||
|
||||
verifyValue("var", "String", `"test"`);
|
||||
verifyNodeData("var", "String", `"test"`);
|
||||
|
||||
openNode("page");
|
||||
openNode("variables", 1);
|
||||
verifyValue("pageVar", "String", `"pageTest"`);
|
||||
verifyNodeData("pageVar", "String", `"pageTest"`);
|
||||
|
||||
addInputOnQueryField(
|
||||
"runpy",
|
||||
|
|
@ -337,7 +337,7 @@ describe("Data source Rest API", () => {
|
|||
`cypress-${data.dataSourceName}-restapi`,
|
||||
"restapi",
|
||||
[
|
||||
{ key: "url", value: Cypress.env("restAPI_BaseURL") },
|
||||
{ key: "url", value: "https://jsonplaceholder.typicode.com" },
|
||||
{ key: "auth_type", value: "none" },
|
||||
{ key: "grant_type", value: "authorization_code" },
|
||||
{ key: "add_token_to", value: "header" },
|
||||
|
|
@ -370,62 +370,100 @@ describe("Data source Rest API", () => {
|
|||
cy.apiCreateApp(`${fake.companyName}-restAPI-CURD-App`);
|
||||
cy.openApp();
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "get_beeceptor_data",
|
||||
queryName: "get_all_users",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "GET",
|
||||
urlSuffix: "/api/users",
|
||||
urlSuffix: "/users",
|
||||
run: true,
|
||||
expectedResponseShape: {
|
||||
"0.id": true,
|
||||
"0.name": true,
|
||||
"0.email": true,
|
||||
},
|
||||
});
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "post_restapi",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "POST",
|
||||
headersList: [["Content-Type", "application/json"]],
|
||||
rawBody: '{"price": 200,"name": "Violin"}',
|
||||
urlSuffix: "/api/users",
|
||||
expectedResponseShape: { price: 200, name: "Violin", id: true },
|
||||
rawBody: `{
|
||||
"name": "Test User",
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"address": {
|
||||
"street": "123 Test St",
|
||||
"city": "Testville",
|
||||
"zipcode": "12345"
|
||||
}
|
||||
}`,
|
||||
urlSuffix: "/users",
|
||||
run: true,
|
||||
expectedResponseShape: {
|
||||
id: true,
|
||||
name: "Test User",
|
||||
email: "test@example.com",
|
||||
},
|
||||
});
|
||||
cy.readFile("cypress/fixtures/restAPI/storedId.json").then(
|
||||
(postResponseID) => {
|
||||
const id1 = postResponseID.id;
|
||||
const id1 = 1;
|
||||
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "put_restapi_id",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "PUT",
|
||||
headersList: [["Content-Type", "application/json"]],
|
||||
rawBody: '{"price": 500,"name": "Guitar"}',
|
||||
urlSuffix: `/api/users/${id1}`,
|
||||
expectedResponseShape: { price: 500, name: "Guitar", id: id1 },
|
||||
});
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "patch_restapi_id",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "PATCH",
|
||||
headersList: [["Content-Type", "application/json"]],
|
||||
rawBody: '{"price": 999 }',
|
||||
urlSuffix: `/api/users/${id1}`,
|
||||
run: true,
|
||||
expectedResponseShape: { price: 999, id: id1 },
|
||||
});
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "get_restapi_id",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "GET",
|
||||
urlSuffix: `/api/users/${id1}`,
|
||||
run: true,
|
||||
expectedResponseShape: { price: 999, name: "Guitar", id: id1 },
|
||||
});
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "delete_restapi_id",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "DELETE",
|
||||
urlSuffix: `/api/users/${id1}`,
|
||||
run: true,
|
||||
expectedResponseShape: { success: true },
|
||||
});
|
||||
}
|
||||
);
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "put_restapi_id",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "PUT",
|
||||
headersList: [["Content-Type", "application/json"]],
|
||||
rawBody: `{
|
||||
"id": 1,
|
||||
"name": "Fully Updated User",
|
||||
"username": "updateduser",
|
||||
"email": "updated@example.com",
|
||||
"address": {
|
||||
"street": "456 Updated St",
|
||||
"city": "Updatedville",
|
||||
"zipcode": "54321"
|
||||
}
|
||||
}`,
|
||||
urlSuffix: `/users/${id1}`,
|
||||
run: true,
|
||||
expectedResponseShape: {
|
||||
id: id1,
|
||||
name: "Fully Updated User",
|
||||
email: "updated@example.com",
|
||||
},
|
||||
});
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "patch_restapi_id",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "PATCH",
|
||||
headersList: [["Content-Type", "application/json"]],
|
||||
rawBody: `{
|
||||
"email": "partially.updated@example.com"
|
||||
}`,
|
||||
urlSuffix: `/users/${id1}`,
|
||||
run: true,
|
||||
expectedResponseShape: {
|
||||
id: id1,
|
||||
email: "partially.updated@example.com",
|
||||
},
|
||||
});
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "get_restapi_id",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "GET",
|
||||
urlSuffix: `/users/${id1}`,
|
||||
run: true,
|
||||
expectedResponseShape: {
|
||||
id: id1,
|
||||
email: "Sincere@april.biz",
|
||||
},
|
||||
});
|
||||
createAndRunRestAPIQuery({
|
||||
queryName: "delete_restapi_id",
|
||||
dsName: `cypress-${data.dataSourceName}-restapi`,
|
||||
method: "DELETE",
|
||||
urlSuffix: `/users/${id1}`,
|
||||
run: true,
|
||||
expectedResponseShape: {},
|
||||
});
|
||||
cy.apiDeleteApp(`${fake.companyName}-restAPI-CURD-App`);
|
||||
cy.apiDeleteGDS(`cypress-${data.dataSourceName}-restapi`);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,213 +5,214 @@ import { commonText } from "Texts/common";
|
|||
|
||||
import { exportAppModalText } from "Texts/exportImport";
|
||||
import {
|
||||
clickOnExportButtonAndVerify,
|
||||
exportAllVersionsAndVerify,
|
||||
verifyElementsOfExportModal,
|
||||
clickOnExportButtonAndVerify,
|
||||
exportAllVersionsAndVerify,
|
||||
verifyElementsOfExportModal,
|
||||
} from "Support/utils/exportImport";
|
||||
import { selectAppCardOption, closeModal } from "Support/utils/common";
|
||||
|
||||
describe("App Export", () => {
|
||||
const TEST_DATA = {
|
||||
appFiles: {
|
||||
multiVersion: "cypress/fixtures/templates/three-versions.json",
|
||||
singleVersion: "cypress/fixtures/templates/one_version.json",
|
||||
},
|
||||
};
|
||||
const TEST_DATA = {
|
||||
appFiles: {
|
||||
multiVersion: "cypress/fixtures/templates/three-versions.json",
|
||||
singleVersion: "cypress/fixtures/templates/one_version.json",
|
||||
},
|
||||
};
|
||||
|
||||
let data;
|
||||
let data;
|
||||
|
||||
data = {
|
||||
workspaceName: fake.firstName,
|
||||
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
|
||||
appName: `${fake.companyName}-IE-App`,
|
||||
appReName: `${fake.companyName}-${fake.companyName}-IE-App`,
|
||||
dsName: fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
data = {
|
||||
workspaceName: fake.firstName,
|
||||
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
|
||||
appName: `${fake.companyName}-IE-App`,
|
||||
appReName: `${fake.companyName}-${fake.companyName}-IE-App`,
|
||||
dsName: fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""),
|
||||
workspaceName: fake.firstName,
|
||||
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
|
||||
appName: `${fake.companyName}-IE-App`,
|
||||
appReName: `${fake.companyName}-${fake.companyName}-IE-App`,
|
||||
dsName: fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""),
|
||||
};
|
||||
cy.exec("mkdir -p ./cypress/downloads/");
|
||||
cy.exec("cd ./cypress/downloads/ && rm -rf *");
|
||||
cy.exec("mkdir -p ./cypress/downloads/");
|
||||
cy.wait(3000);
|
||||
|
||||
beforeEach(() => {
|
||||
data = {
|
||||
workspaceName: fake.firstName,
|
||||
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
|
||||
appName: `${fake.companyName}-IE-App`,
|
||||
appReName: `${fake.companyName}-${fake.companyName}-IE-App`,
|
||||
dsName: fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""),
|
||||
};
|
||||
cy.exec("mkdir -p ./cypress/downloads/");
|
||||
cy.wait(3000);
|
||||
cy.apiLogin();
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
|
||||
cy.apiLogout();
|
||||
});
|
||||
|
||||
cy.apiLogin();
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
|
||||
cy.apiLogout();
|
||||
});
|
||||
it("Verify the elements of export dialog box", () => {
|
||||
cy.skipWalkthrough();
|
||||
|
||||
it("Verify the elements of export dialog box", () => {
|
||||
cy.skipWalkthrough()
|
||||
cy.apiLogin();
|
||||
cy.visit(`${data.workspaceSlug}`);
|
||||
cy.get(importSelectors.importOptionInput)
|
||||
.eq(0)
|
||||
.selectFile(TEST_DATA.appFiles.multiVersion, { force: true });
|
||||
cy.wait(2000);
|
||||
cy.clearAndType(commonSelectors.appNameInput, data.appName);
|
||||
cy.get(importSelectors.importAppButton).click();
|
||||
cy.wait(3000);
|
||||
cy.backToApps();
|
||||
|
||||
cy.apiLogin();
|
||||
cy.visit(`${data.workspaceSlug}`);
|
||||
cy.get(importSelectors.importOptionInput)
|
||||
.eq(0)
|
||||
.selectFile(TEST_DATA.appFiles.multiVersion, {
|
||||
force: true,
|
||||
});
|
||||
cy.wait(1500);
|
||||
cy.clearAndType(commonSelectors.appNameInput, data.appName);
|
||||
cy.get(importSelectors.importAppButton).click();
|
||||
cy.wait(3000);
|
||||
cy.backToApps();
|
||||
// Select the app card option to export the app
|
||||
selectAppCardOption(
|
||||
data.appName,
|
||||
commonSelectors.appCardOptions(commonText.exportAppOption)
|
||||
);
|
||||
|
||||
// Select the app card option to export the app
|
||||
selectAppCardOption(
|
||||
data.appName,
|
||||
commonSelectors.appCardOptions(commonText.exportAppOption)
|
||||
// Verify the elements of the export modal
|
||||
verifyElementsOfExportModal("v3", ["v2", "v1"], [true, false, false]);
|
||||
|
||||
// Close the modal
|
||||
closeModal(exportAppModalText.modalCloseButton);
|
||||
|
||||
// Ensure the modal title is no longer visible
|
||||
cy.get(
|
||||
commonSelectors.modalTitle(exportAppModalText.selectVersionTitle)
|
||||
).should("not.exist");
|
||||
|
||||
// Re-open the export modal and click the export button
|
||||
cy.wait(2000);
|
||||
selectAppCardOption(
|
||||
data.appName,
|
||||
commonSelectors.appCardOptions(commonText.exportAppOption)
|
||||
);
|
||||
clickOnExportButtonAndVerify(exportAppModalText.exportAll, data.appName);
|
||||
|
||||
cy.exec("ls ./cypress/downloads/").then((result) => {
|
||||
const downloadedAppExportFileName = result.stdout.split("\n")[0];
|
||||
const filePath = `./cypress/downloads/${downloadedAppExportFileName}`;
|
||||
|
||||
// Ensure the file name contains the expected app export name
|
||||
expect(downloadedAppExportFileName).to.contain(
|
||||
data.appName.toLowerCase()
|
||||
);
|
||||
|
||||
// Read and validate the exported JSON file
|
||||
cy.readFile(filePath).then((appData) => {
|
||||
// Validate the app name
|
||||
const appNameFromFile = appData.app[0].definition.appV2.name;
|
||||
expect(appNameFromFile).to.equal(data.appName);
|
||||
|
||||
// Validate the schema for the student table in tooljetdb
|
||||
const tooljetDatabase = appData.tooljet_database.find(
|
||||
(db) => db.table_name === "student"
|
||||
);
|
||||
expect(tooljetDatabase).to.exist;
|
||||
expect(tooljetDatabase.schema).to.exist;
|
||||
|
||||
// Validate components and queries
|
||||
const components = appData.app[0].definition.appV2.components;
|
||||
|
||||
const text2Component = components.find(
|
||||
(component) => component.name === "text2"
|
||||
);
|
||||
expect(text2Component).to.exist;
|
||||
expect(text2Component.properties.text.value).to.equal(
|
||||
"{{constants.pageHeader}}"
|
||||
);
|
||||
|
||||
// Verify the elements of the export modal
|
||||
verifyElementsOfExportModal("v3", ["v2", "v1"], [true, false, false]);
|
||||
|
||||
// Close the modal
|
||||
closeModal(exportAppModalText.modalCloseButton);
|
||||
|
||||
// Ensure the modal title is no longer visible
|
||||
cy.get(
|
||||
commonSelectors.modalTitle(exportAppModalText.selectVersionTitle)
|
||||
).should("not.exist");
|
||||
|
||||
// Re-open the export modal and click the export button
|
||||
selectAppCardOption(
|
||||
data.appName,
|
||||
commonSelectors.appCardOptions(commonText.exportAppOption)
|
||||
const textinput1 = components.find(
|
||||
(component) => component.name === "textinput1"
|
||||
);
|
||||
clickOnExportButtonAndVerify(exportAppModalText.exportAll, data.appName);
|
||||
expect(textinput1).to.exist;
|
||||
expect(textinput1.properties.value.value).to.include("queries");
|
||||
|
||||
cy.exec("ls ./cypress/downloads/").then((result) => {
|
||||
const downloadedAppExportFileName = result.stdout.split("\n")[0];
|
||||
const filePath = `./cypress/downloads/${downloadedAppExportFileName}`;
|
||||
|
||||
// Ensure the file name contains the expected app export name
|
||||
expect(downloadedAppExportFileName).to.contain(
|
||||
data.appName.toLowerCase()
|
||||
);
|
||||
|
||||
// Read and validate the exported JSON file
|
||||
cy.readFile(filePath).then((appData) => {
|
||||
// Validate the app name
|
||||
const appNameFromFile = appData.app[0].definition.appV2.name;
|
||||
expect(appNameFromFile).to.equal(data.appName);
|
||||
|
||||
// Validate the schema for the student table in tooljetdb
|
||||
const tooljetDatabase = appData.tooljet_database.find(
|
||||
(db) => db.table_name === "student"
|
||||
);
|
||||
expect(tooljetDatabase).to.exist;
|
||||
expect(tooljetDatabase.schema).to.exist;
|
||||
|
||||
// Validate components and queries
|
||||
const components = appData.app[0].definition.appV2.components;
|
||||
|
||||
const text2Component = components.find(
|
||||
(component) => component.name === "text2"
|
||||
);
|
||||
expect(text2Component).to.exist;
|
||||
expect(text2Component.properties.text.value).to.equal(
|
||||
"{{constants.pageHeader}}"
|
||||
);
|
||||
|
||||
const textinput1 = components.find(
|
||||
(component) => component.name === "textinput1"
|
||||
);
|
||||
expect(textinput1).to.exist;
|
||||
expect(textinput1.properties.value.value).to.include("queries");
|
||||
|
||||
const textinput2 = components.find(
|
||||
(component) => component.name === "textinput2"
|
||||
);
|
||||
expect(textinput2).to.exist;
|
||||
expect(textinput2.properties.value.value).to.include("queries");
|
||||
|
||||
const textinput3 = components.find(
|
||||
(component) => component.name === "textinput3"
|
||||
);
|
||||
expect(textinput3).to.exist;
|
||||
expect(textinput3.properties.value.value).to.include("queries");
|
||||
|
||||
// Validate the data queries
|
||||
const dataQueries = appData.app[0].definition.appV2.dataQueries;
|
||||
|
||||
const postgresqlQuery = dataQueries.find(
|
||||
(query) => query.name === "postgresql1"
|
||||
);
|
||||
expect(postgresqlQuery).to.exist;
|
||||
expect(postgresqlQuery.options.query).to.include(
|
||||
"Select * from {{secrets.db_name}}"
|
||||
);
|
||||
|
||||
const restapiQuery = dataQueries.find(
|
||||
(query) => query.name === "restapi1"
|
||||
);
|
||||
expect(restapiQuery).to.exist;
|
||||
expect(restapiQuery.options.url).to.equal(
|
||||
"https://jsonplaceholder.typicode.com/users/1"
|
||||
);
|
||||
|
||||
const tooljetdbQuery = dataQueries.find(
|
||||
(query) => query.name === "tooljetdb1"
|
||||
);
|
||||
expect(tooljetdbQuery).to.exist;
|
||||
expect(tooljetdbQuery.options.operation).to.equal("list_rows");
|
||||
|
||||
// Ensure appVersions exists
|
||||
const appVersions = appData.app[0].definition.appV2.appVersions;
|
||||
expect(appVersions).to.exist;
|
||||
|
||||
// Map and verify app version names
|
||||
const versionNames = appVersions.map((version) => version.name);
|
||||
expect(versionNames).to.include.members(["v1", "v2", "v3"]);
|
||||
});
|
||||
});
|
||||
|
||||
cy.exec("cd ./cypress/downloads/ && rm -rf *");
|
||||
|
||||
selectAppCardOption(
|
||||
data.appName,
|
||||
commonSelectors.appCardOptions(commonText.exportAppOption)
|
||||
const textinput2 = components.find(
|
||||
(component) => component.name === "textinput2"
|
||||
);
|
||||
cy.get(`[data-cy="v1-radio-button"]`).check();
|
||||
cy.get(
|
||||
commonSelectors.buttonSelector(exportAppModalText.exportSelectedVersion)
|
||||
).click();
|
||||
expect(textinput2).to.exist;
|
||||
expect(textinput2.properties.value.value).to.include("queries");
|
||||
|
||||
cy.exec("ls ./cypress/downloads/").then((result) => {
|
||||
const downloadedAppExportFileName = result.stdout.split("\n")[0];
|
||||
const filePath = `./cypress/downloads/${downloadedAppExportFileName}`;
|
||||
const textinput3 = components.find(
|
||||
(component) => component.name === "textinput3"
|
||||
);
|
||||
expect(textinput3).to.exist;
|
||||
expect(textinput3.properties.value.value).to.include("queries");
|
||||
|
||||
// Ensure the file name contains the expected app export name
|
||||
expect(downloadedAppExportFileName).to.contain(
|
||||
data.appName.toLowerCase()
|
||||
);
|
||||
// Validate the data queries
|
||||
const dataQueries = appData.app[0].definition.appV2.dataQueries;
|
||||
|
||||
// Read and validate the exported JSON file
|
||||
cy.readFile(filePath).then((appData) => {
|
||||
// Validate the app name
|
||||
const appNameFromFile = appData.app[0].definition.appV2.name;
|
||||
expect(appNameFromFile).to.equal(data.appName);
|
||||
});
|
||||
});
|
||||
const postgresqlQuery = dataQueries.find(
|
||||
(query) => query.name === "postgresql1"
|
||||
);
|
||||
expect(postgresqlQuery).to.exist;
|
||||
expect(postgresqlQuery.options.query).to.include(
|
||||
"Select * from {{secrets.db_name}}"
|
||||
);
|
||||
|
||||
const restapiQuery = dataQueries.find(
|
||||
(query) => query.name === "restapi1"
|
||||
);
|
||||
expect(restapiQuery).to.exist;
|
||||
expect(restapiQuery.options.url).to.equal(
|
||||
"https://jsonplaceholder.typicode.com/users/1"
|
||||
);
|
||||
|
||||
const tooljetdbQuery = dataQueries.find(
|
||||
(query) => query.name === "tooljetdb1"
|
||||
);
|
||||
expect(tooljetdbQuery).to.exist;
|
||||
expect(tooljetdbQuery.options.operation).to.equal("list_rows");
|
||||
|
||||
// Ensure appVersions exists
|
||||
const appVersions = appData.app[0].definition.appV2.appVersions;
|
||||
expect(appVersions).to.exist;
|
||||
|
||||
// Map and verify app version names
|
||||
const versionNames = appVersions.map((version) => version.name);
|
||||
expect(versionNames).to.include.members(["v1", "v2", "v3"]);
|
||||
});
|
||||
});
|
||||
|
||||
it.skip("Verify 'Export app' functionality of an application inside app editor", () => {
|
||||
data.appName2 = `${fake.companyName}-App`;
|
||||
cy.apiCreateApp(data.appName2);
|
||||
cy.openApp(data.appName2);
|
||||
cy.exec("cd ./cypress/downloads/ && rm -rf *");
|
||||
|
||||
cy.dragAndDropWidget("Text Input", 50, 50);
|
||||
selectAppCardOption(
|
||||
data.appName,
|
||||
commonSelectors.appCardOptions(commonText.exportAppOption)
|
||||
);
|
||||
cy.get(`[data-cy="v1-radio-button"]`).check();
|
||||
cy.get(
|
||||
commonSelectors.buttonSelector(exportAppModalText.exportSelectedVersion)
|
||||
).click();
|
||||
|
||||
cy.get('[data-cy="left-sidebar-settings-button"]').click();
|
||||
cy.get('[data-cy="button-user-status-change"]').click();
|
||||
cy.exec("ls ./cypress/downloads/").then((result) => {
|
||||
const downloadedAppExportFileName = result.stdout.split("\n")[0];
|
||||
const filePath = `./cypress/downloads/${downloadedAppExportFileName}`;
|
||||
|
||||
verifyElementsOfExportModal("v1");
|
||||
// Ensure the file name contains the expected app export name
|
||||
expect(downloadedAppExportFileName).to.contain(
|
||||
data.appName.toLowerCase()
|
||||
);
|
||||
|
||||
exportAllVersionsAndVerify(data.appName1, "v1");
|
||||
// Read and validate the exported JSON file
|
||||
cy.readFile(filePath).then((appData) => {
|
||||
// Validate the app name
|
||||
const appNameFromFile = appData.app[0].definition.appV2.name;
|
||||
expect(appNameFromFile).to.equal(data.appName);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it.skip("Verify 'Export app' functionality of an application inside app editor", () => {
|
||||
data.appName2 = `${fake.companyName}-App`;
|
||||
cy.apiCreateApp(data.appName2);
|
||||
cy.openApp(data.appName2);
|
||||
|
||||
cy.dragAndDropWidget("Text Input", 50, 50);
|
||||
|
||||
cy.get('[data-cy="left-sidebar-settings-button"]').click();
|
||||
cy.get('[data-cy="button-user-status-change"]').click();
|
||||
|
||||
verifyElementsOfExportModal("v1");
|
||||
|
||||
exportAllVersionsAndVerify(data.appName1, "v1");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ describe("App Slug", () => {
|
|||
|
||||
// Release and verify URLs
|
||||
releaseApp();
|
||||
verifyURLs(workspaceId, data.slug, false);
|
||||
verifyURLs(workspaceId, data.slug, true);
|
||||
|
||||
// Verify duplicate slug validation
|
||||
cy.visit("/my-workspace");
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@ import { inviteUserToWorkspace } from "Support/utils/manageUsers";
|
|||
import { setSignupStatus } from "Support/utils/manageSSO";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
import { commonText } from "Texts/common";
|
||||
import {
|
||||
userSignUp,
|
||||
addNewUser,
|
||||
} from "Support/utils/onboarding";
|
||||
import { userSignUp, addNewUser } from "Support/utils/onboarding";
|
||||
import {
|
||||
setUpSlug,
|
||||
setupAppWithSlug,
|
||||
|
|
@ -16,347 +13,371 @@ import {
|
|||
onboardUserFromAppLink,
|
||||
} from "Support/utils/apps";
|
||||
|
||||
describe(
|
||||
"Private and Public apps",
|
||||
{
|
||||
retries: { runMode: 2 },
|
||||
},
|
||||
() => {
|
||||
let data;
|
||||
|
||||
describe("Private and Public apps", {
|
||||
retries: { runMode: 2 },
|
||||
}, () => {
|
||||
let data;
|
||||
beforeEach(() => {
|
||||
data = {
|
||||
appName: `${fake.companyName} P P App`,
|
||||
slug: `${fake.companyName} P P App`.toLowerCase().replace(/\s+/g, "-"),
|
||||
firstName: fake.firstName,
|
||||
email: fake.email.toLowerCase(),
|
||||
workspaceName: fake.firstName,
|
||||
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
data = {
|
||||
appName: `${fake.companyName} P P App`,
|
||||
slug: `${fake.companyName} P P App`.toLowerCase().replace(/\s+/g, "-"),
|
||||
firstName: fake.firstName,
|
||||
email: fake.email.toLowerCase(),
|
||||
workspaceName: fake.firstName,
|
||||
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
|
||||
}
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.skipWalkthrough();
|
||||
});
|
||||
|
||||
it("Verify private and public app share functionality", () => {
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.openApp();
|
||||
cy.apiAddComponentToApp(data.appName, "text1");
|
||||
|
||||
// Check unreleased version state
|
||||
cy.get('[data-cy="share-button-link"]>span').should("be.visible").click();
|
||||
cy.contains("This version has not been released yet").should("be.visible");
|
||||
cy.get(commonWidgetSelector.modalCloseButton).click();
|
||||
|
||||
// Release and verify share modal
|
||||
releaseApp();
|
||||
cy.get(commonWidgetSelector.shareAppButton).click();
|
||||
for (const elements in commonWidgetSelector.shareModalElements) {
|
||||
cy.get(commonWidgetSelector.shareModalElements[elements])
|
||||
.verifyVisibleElement("have.text", commonText.shareModalElements[elements]);
|
||||
}
|
||||
|
||||
// Verify share modal elements
|
||||
const shareModalSelectors = [
|
||||
'copyAppLinkButton',
|
||||
'makePublicAppToggle',
|
||||
'appLink',
|
||||
'appNameSlugInput',
|
||||
'modalCloseButton'
|
||||
];
|
||||
shareModalSelectors.forEach(selector => {
|
||||
cy.get(commonWidgetSelector[selector]).should("be.visible");
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.skipWalkthrough();
|
||||
});
|
||||
|
||||
// Configure and verify slug
|
||||
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
|
||||
cy.get('[data-cy="app-slug-accepted-label"]')
|
||||
.should("be.visible")
|
||||
.and("have.text", "Slug accepted!");
|
||||
it("Verify private and public app share functionality", () => {
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.openApp();
|
||||
cy.apiAddComponentToApp(data.appName, "text1");
|
||||
|
||||
cy.get(commonWidgetSelector.modalCloseButton).click();
|
||||
cy.forceClickOnCanvas();
|
||||
cy.backToApps();
|
||||
// Check unreleased version state
|
||||
cy.get('[data-cy="share-button-link"]>span').should("be.visible").click();
|
||||
cy.contains("This version has not been released yet").should(
|
||||
"be.visible"
|
||||
);
|
||||
cy.get(commonWidgetSelector.modalCloseButton).click();
|
||||
|
||||
// Test private access
|
||||
logout();
|
||||
// Release and verify share modal
|
||||
releaseApp();
|
||||
cy.get(commonWidgetSelector.shareAppButton).click();
|
||||
for (const elements in commonWidgetSelector.shareModalElements) {
|
||||
cy.get(
|
||||
commonWidgetSelector.shareModalElements[elements]
|
||||
).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.shareModalElements[elements]
|
||||
);
|
||||
}
|
||||
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
// Verify share modal elements
|
||||
const shareModalSelectors = [
|
||||
"copyAppLinkButton",
|
||||
"makePublicAppToggle",
|
||||
"appLink",
|
||||
"appNameSlugInput",
|
||||
"modalCloseButton",
|
||||
];
|
||||
shareModalSelectors.forEach((selector) => {
|
||||
cy.get(commonWidgetSelector[selector]).should("be.visible");
|
||||
});
|
||||
|
||||
// Configure and verify slug
|
||||
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
|
||||
cy.get('[data-cy="app-slug-accepted-label"]')
|
||||
.should("be.visible")
|
||||
.and("have.text", "Slug accepted!");
|
||||
|
||||
cy.get(commonWidgetSelector.modalCloseButton).click();
|
||||
cy.forceClickOnCanvas();
|
||||
cy.backToApps();
|
||||
|
||||
// Test private access
|
||||
logout();
|
||||
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
cy.wait(2000);
|
||||
cy.appUILogin();
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
// Test public access
|
||||
cy.get(commonSelectors.viewerPageLogo).click();
|
||||
cy.openApp(
|
||||
"appSlug",
|
||||
Cypress.env("workspaceId"),
|
||||
Cypress.env("appId"),
|
||||
commonWidgetSelector.draggableWidget("text1")
|
||||
);
|
||||
cy.get(commonWidgetSelector.shareAppButton).click();
|
||||
cy.get(commonWidgetSelector.makePublicAppToggle).check();
|
||||
cy.get(commonWidgetSelector.modalCloseButton).click();
|
||||
cy.backToApps();
|
||||
|
||||
logout();
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
});
|
||||
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
|
||||
cy.wait(2000);
|
||||
cy.appUILogin();
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
it("Verify app private and public app visibility for the same workspace user", () => {
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
|
||||
inviteUserToWorkspace(data.firstName, data.email);
|
||||
logout();
|
||||
cy.visit("/");
|
||||
cy.wait(2000);
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
// Test public access
|
||||
cy.get(commonSelectors.viewerPageLogo).click();
|
||||
cy.openApp(
|
||||
"appSlug",
|
||||
Cypress.env("workspaceId"),
|
||||
Cypress.env("appId"),
|
||||
commonWidgetSelector.draggableWidget("text1")
|
||||
);
|
||||
cy.get(commonWidgetSelector.shareAppButton).click();
|
||||
cy.get(commonWidgetSelector.makePublicAppToggle).check();
|
||||
cy.get(commonWidgetSelector.modalCloseButton).click();
|
||||
cy.backToApps();
|
||||
// Test private access
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
|
||||
logout();
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
cy.wait(2000);
|
||||
cy.appUILogin(data.email, "password");
|
||||
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
});
|
||||
// Test with private app valid session
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
it("Verify app private and public app visibility for the same workspace user", () => {
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
cy.get(commonSelectors.viewerPageLogo).click();
|
||||
|
||||
inviteUserToWorkspace(data.firstName, data.email);
|
||||
logout();
|
||||
cy.visit("/");
|
||||
cy.wait(2000);
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
|
||||
// Test public access
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.wait(1000);
|
||||
cy.apiMakeAppPublic();
|
||||
logout();
|
||||
cy.wait(1000);
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
// Test private access
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
// Test with public app with valid session
|
||||
cy.apiLogin(data.email, "password");
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
});
|
||||
|
||||
cy.wait(2000);
|
||||
cy.appUILogin(data.email, "password");
|
||||
it("Verify app private and public app visibility for the same instance user", () => {
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
cy.apiLogout();
|
||||
userSignUp(data.firstName, data.email, data.workspaceName);
|
||||
cy.wait(1000);
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
|
||||
// Test with private app valid session
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
cy.visit("/");
|
||||
logout();
|
||||
|
||||
// Test public access
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.apiMakeAppPublic();
|
||||
logout();
|
||||
|
||||
cy.get(commonSelectors.viewerPageLogo).click();
|
||||
cy.wait(1000);
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
// Test public access
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.wait(1000);
|
||||
cy.apiMakeAppPublic();
|
||||
logout();
|
||||
cy.wait(1000);
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
|
||||
|
||||
|
||||
// Test with public app with valid session
|
||||
cy.apiLogin(data.email, "password");
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
|
||||
|
||||
});
|
||||
|
||||
it("Verify app private and public app visibility for the same instance user", () => {
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
|
||||
cy.apiLogout();
|
||||
userSignUp(data.firstName, data.email, data.workspaceName);
|
||||
cy.wait(1000);
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
// Verify public app with valid session
|
||||
cy.apiLogin(data.email, "password");
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
});
|
||||
|
||||
cy.visit("/");
|
||||
logout();
|
||||
it("Should redirect to workspace login and handle signup flow of existing and non-existing user", () => {
|
||||
setSignupStatus(true);
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
|
||||
// Test public access
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.apiMakeAppPublic();
|
||||
logout();
|
||||
cy.apiLogout();
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
|
||||
cy.wait(1000);
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
"have.text",
|
||||
"My workspace"
|
||||
);
|
||||
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
// Test signup flow
|
||||
cy.intercept("POST", "/api/onboarding/signup").as("signup");
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(commonSelectors.inputFieldFullName, data.firstName);
|
||||
cy.clearAndType(commonSelectors.inputFieldEmailAddress, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
|
||||
cy.wait("@signup").then((interception) => {
|
||||
expect(interception.response.statusCode).to.eq(201);
|
||||
});
|
||||
|
||||
// Process invitation
|
||||
onboardUserFromAppLink(data.email, data.slug);
|
||||
|
||||
// Verify public app with valid session
|
||||
cy.apiLogin(data.email, "password");
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
cy.get('[data-cy="viewer-page-logo"]').click();
|
||||
logout();
|
||||
cy.wait(1000);
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
});
|
||||
// Setup new workspace and app
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
|
||||
cy.apiLogout();
|
||||
cy.apiLogin();
|
||||
cy.visit(`${data.workspaceSlug}`);
|
||||
setSignupStatus(true, data.workspaceName);
|
||||
|
||||
it("Should redirect to workspace login and handle signup flow of existing and non-existing user", () => {
|
||||
setSignupStatus(true);
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
data.slug = fake.firstName.toLowerCase().replace(/\s+/g, "-");
|
||||
|
||||
cy.apiLogout();
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
cy.createApp(data.appName);
|
||||
cy.dragAndDropWidget("Text", 500, 500);
|
||||
releaseApp();
|
||||
setUpSlug(data.slug);
|
||||
cy.forceClickOnCanvas();
|
||||
cy.backToApps();
|
||||
|
||||
// Test signup flow in new workspace
|
||||
cy.apiLogout();
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
"have.text",
|
||||
data.workspaceName
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(commonSelectors.inputFieldFullName, data.firstName);
|
||||
cy.clearAndType(commonSelectors.inputFieldEmailAddress, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait("@signup").then((interception) => {
|
||||
expect(interception.response.statusCode).to.eq(201);
|
||||
});
|
||||
|
||||
onboardUserFromAppLink(data.email, data.slug, data.workspaceName, false);
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should(
|
||||
"be.visible"
|
||||
);
|
||||
});
|
||||
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
"have.text",
|
||||
"My workspace"
|
||||
);
|
||||
it("Should verify restricted app access", () => {
|
||||
data.workspaceName = fake.firstName;
|
||||
data.workspaceSlug = fake.firstName.toLowerCase().replace(/\s+/g, "-");
|
||||
|
||||
// Test signup flow
|
||||
cy.intercept("POST", "/api/onboarding/signup").as("signup");
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(commonSelectors.inputFieldFullName, data.firstName);
|
||||
cy.clearAndType(commonSelectors.inputFieldEmailAddress, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
|
||||
cy.apiLogout();
|
||||
cy.apiLogin();
|
||||
cy.visit(`${data.workspaceSlug}`);
|
||||
cy.apiDeleteGranularPermission("end-user");
|
||||
setSignupStatus(true, data.workspaceName);
|
||||
|
||||
cy.wait('@signup').then((interception) => {
|
||||
expect(interception.response.statusCode).to.eq(201);
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
|
||||
inviteUserToWorkspace(data.firstName, data.email);
|
||||
|
||||
// Verify restricted access
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
verifyRestrictedAccess();
|
||||
cy.get('[data-cy="back-to-home-button"]').click();
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
|
||||
cy.apiLogout();
|
||||
});
|
||||
|
||||
// Process invitation
|
||||
onboardUserFromAppLink(data.email, data.slug);
|
||||
it.skip("Should verify private app access for different workspace users", () => {
|
||||
const firstName1 = fake.firstName;
|
||||
const email1 = fake.email.toLowerCase();
|
||||
const permissionName = fake.firstName.toLowerCase(); // Defined but not used in original
|
||||
const urls = {
|
||||
editor: `${Cypress.config("baseUrl")}/my-workspace/apps/${data.slug}/home`,
|
||||
preview: `${Cypress.config("baseUrl")}/applications/${data.slug}/home?version=v1`,
|
||||
released: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
};
|
||||
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
// Setup workspace and app
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
|
||||
cy.apiLogout();
|
||||
cy.apiLogin();
|
||||
cy.visit(`${data.workspaceSlug}`);
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
|
||||
// Invite workspace user
|
||||
addNewUser(data.firstName, data.email);
|
||||
cy.wait(500);
|
||||
|
||||
cy.get('[data-cy="viewer-page-logo"]').click();
|
||||
logout();
|
||||
cy.wait(1000);
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
|
||||
// Verify access restrictions
|
||||
cy.visitSlug({ actualUrl: urls.editor });
|
||||
verifyRestrictedAccess();
|
||||
cy.get('[data-cy="back-to-home-button"]').click();
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
|
||||
// Setup new workspace and app
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
|
||||
cy.apiLogout();
|
||||
cy.apiLogin();
|
||||
cy.visit(`${data.workspaceSlug}`);
|
||||
setSignupStatus(true, data.workspaceName);
|
||||
cy.visitSlug({ actualUrl: urls.preview });
|
||||
|
||||
data.slug = fake.firstName.toLowerCase().replace(/\s+/g, "-");
|
||||
// Switch users and verify access
|
||||
cy.apiLogout();
|
||||
cy.apiLogin();
|
||||
cy.apiDeleteGranularPermission("end-user");
|
||||
|
||||
cy.createApp(data.appName);
|
||||
cy.dragAndDropWidget("Text", 500, 500);
|
||||
releaseApp();
|
||||
setUpSlug(data.slug);
|
||||
cy.forceClickOnCanvas();
|
||||
cy.backToApps();
|
||||
cy.apiLogin(data.email, "password");
|
||||
cy.visitSlug({ actualUrl: urls.editor });
|
||||
verifyRestrictedAccess();
|
||||
cy.get('[data-cy="back-to-home-button"]').click();
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
cy.visitSlug({ actualUrl: urls.preview });
|
||||
|
||||
// Test signup flow in new workspace
|
||||
cy.apiLogout();
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
cy.apiLogout();
|
||||
|
||||
// Test with new user
|
||||
userSignUp(firstName1, email1, data.workspaceName);
|
||||
cy.visitSlug({ actualUrl: urls.editor });
|
||||
cy.visitSlug({ actualUrl: urls.preview });
|
||||
cy.visitSlug({ actualUrl: urls.released });
|
||||
});
|
||||
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
"have.text",
|
||||
data.workspaceName
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(commonSelectors.inputFieldFullName, data.firstName);
|
||||
cy.clearAndType(commonSelectors.inputFieldEmailAddress, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait('@signup').then((interception) => {
|
||||
expect(interception.response.statusCode).to.eq(201);
|
||||
});
|
||||
|
||||
onboardUserFromAppLink(data.email, data.slug, data.workspaceName, false);
|
||||
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
|
||||
|
||||
|
||||
});
|
||||
|
||||
it("Should verify restricted app access", () => {
|
||||
data.workspaceName = fake.firstName;
|
||||
data.workspaceSlug = fake.firstName.toLowerCase().replace(/\s+/g, "-");
|
||||
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
|
||||
cy.apiLogout();
|
||||
cy.apiLogin();
|
||||
cy.visit(`${data.workspaceSlug}`);
|
||||
cy.apiDeleteGranularPermission("end-user");
|
||||
setSignupStatus(true, data.workspaceName);
|
||||
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
|
||||
inviteUserToWorkspace(data.firstName, data.email);
|
||||
|
||||
// Verify restricted access
|
||||
cy.visitSlug({
|
||||
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
|
||||
});
|
||||
verifyRestrictedAccess();
|
||||
cy.get('[data-cy="back-to-home-button"]').click();
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
|
||||
cy.apiLogout();
|
||||
});
|
||||
|
||||
it.skip("Should verify private app access for different workspace users", () => {
|
||||
const firstName1 = fake.firstName;
|
||||
const email1 = fake.email.toLowerCase();
|
||||
const permissionName = fake.firstName.toLowerCase(); // Defined but not used in original
|
||||
const urls = {
|
||||
editor: `${Cypress.config("baseUrl")}/my-workspace/apps/${data.slug}/home`,
|
||||
preview: `${Cypress.config("baseUrl")}/applications/${data.slug}/home?version=v1`,
|
||||
released: `${Cypress.config("baseUrl")}/applications/${data.slug}`
|
||||
};
|
||||
|
||||
// Setup workspace and app
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
|
||||
cy.apiLogout();
|
||||
cy.apiLogin();
|
||||
cy.visit(`${data.workspaceSlug}`);
|
||||
setupAppWithSlug(data.appName, data.slug);
|
||||
|
||||
// Invite workspace user
|
||||
addNewUser(data.firstName, data.email);
|
||||
cy.wait(500);
|
||||
|
||||
// Verify access restrictions
|
||||
cy.visitSlug({ actualUrl: urls.editor });
|
||||
verifyRestrictedAccess();
|
||||
cy.get('[data-cy="back-to-home-button"]').click();
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
|
||||
cy.visitSlug({ actualUrl: urls.preview });
|
||||
|
||||
// Switch users and verify access
|
||||
cy.apiLogout();
|
||||
cy.apiLogin();
|
||||
cy.apiDeleteGranularPermission("end-user");
|
||||
|
||||
cy.apiLogin(data.email, "password");
|
||||
cy.visitSlug({ actualUrl: urls.editor });
|
||||
verifyRestrictedAccess();
|
||||
cy.get('[data-cy="back-to-home-button"]').click();
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
cy.visitSlug({ actualUrl: urls.preview });
|
||||
|
||||
cy.apiLogout();
|
||||
|
||||
// Test with new user
|
||||
userSignUp(firstName1, email1, data.workspaceName);
|
||||
cy.visitSlug({ actualUrl: urls.editor });
|
||||
cy.visitSlug({ actualUrl: urls.preview });
|
||||
cy.visitSlug({ actualUrl: urls.released });
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import {
|
|||
} from "Support/utils/common";
|
||||
import { inviteUserBasedOnRole } from "Support/utils/manageGroups";
|
||||
import { resolveHost } from "Support/utils/apps";
|
||||
import { addSuccessNotification } from "Support/utils/queries";
|
||||
|
||||
const data = {};
|
||||
data.firstName = fake.firstName.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
|
|
@ -32,7 +33,7 @@ describe("Datasource Manager", () => {
|
|||
beforeEach(() => {
|
||||
cy.apiLogin();
|
||||
cy.visit(`${workspaceSlug}`);
|
||||
cy.viewport(1200, 1300);
|
||||
cy.viewport(1800, 1800);
|
||||
cy.skipWalkthrough();
|
||||
});
|
||||
|
||||
|
|
@ -199,7 +200,7 @@ describe("Datasource Manager", () => {
|
|||
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.openApp();
|
||||
pinInspector();
|
||||
// pinInspector();
|
||||
|
||||
addQuery(
|
||||
"table_preview",
|
||||
|
|
@ -212,9 +213,11 @@ describe("Datasource Manager", () => {
|
|||
"table_preview "
|
||||
);
|
||||
|
||||
cy.get(commonWidgetSelector.sidebarinspector).click();
|
||||
cy.get('[data-cy="query-tab-settings"]').click();
|
||||
addSuccessNotification("table_preview");
|
||||
cy.get(dataSourceSelector.queryCreateAndRunButton).click();
|
||||
verifyValueOnInspector("table_preview", "10 items ");
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, "table_preview");
|
||||
|
||||
cy.get('[data-cy="show-ds-popover-button"]').click();
|
||||
|
||||
cy.get(".p-2 > .tj-base-btn")
|
||||
|
|
@ -247,9 +250,13 @@ describe("Datasource Manager", () => {
|
|||
cy.get("#react-select-4-listbox")
|
||||
.contains(`cypress-${data.dsName2}-postgresql`)
|
||||
.click();
|
||||
|
||||
cy.get('[data-cy="query-tab-settings"]').click();
|
||||
addSuccessNotification("postgresql");
|
||||
cy.waitForAutoSave();
|
||||
cy.get(dataSourceSelector.queryCreateAndRunButton).click();
|
||||
verifyValueOnInspector("table_preview", "4 items ");
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, "postgresql");
|
||||
|
||||
});
|
||||
|
||||
it.skip("Should verify the query creation and scope changing functionality.", () => {
|
||||
|
|
|
|||
|
|
@ -143,11 +143,11 @@ describe("Workspace constants", () => {
|
|||
cy.get(dataSourceSelector.previewTabRawContainer).contains("secrets is not defined");
|
||||
|
||||
//verify global const should be visible, secrets and deleted const are not in Inspector
|
||||
cy.get(commonWidgetSelector.inspectorIcon).click();
|
||||
cy.get(commonWidgetSelector.constantInspectorIcon).click();
|
||||
cy.get('[data-cy="inspector-node-restapiheaderkey"]').should('exist');
|
||||
cy.get('[data-cy="inspector-node-deleteconst"]').should('not.exist');
|
||||
cy.get('[data-cy="inspector-node-sconst"]').should('not.exist');
|
||||
// cy.get(commonWidgetSelector.sidebarinspector).click();
|
||||
// cy.get(commonWidgetSelector.constantInspectorIcon).click();
|
||||
// cy.get('[data-cy="inspector-node-restapiheaderkey"]').should('exist');
|
||||
// cy.get('[data-cy="inspector-node-deleteconst"]').should('not.exist');
|
||||
// cy.get('[data-cy="inspector-node-sconst"]').should('not.exist');
|
||||
|
||||
//Preview app and verify components
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
|
|
|
|||
|
|
@ -50,9 +50,6 @@ describe("Login functionality", () => {
|
|||
|
||||
it("Should be able to login with valid credentials", () => {
|
||||
cy.appUILogin(user.email, user.password);
|
||||
if (envVar === "Enterprise") {
|
||||
cy.get(".btn-close").click();
|
||||
}
|
||||
cy.get(commonSelectors.settingsIcon).click();
|
||||
cy.get(dashboardSelector.logoutLink);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,11 +15,19 @@ import {
|
|||
} from "Support/utils/selfHostSignUp";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
import { logout } from "Support/utils/common";
|
||||
import { enableInstanceSignup } from "Support/utils/manageSSO";
|
||||
|
||||
describe("User signup", () => {
|
||||
const data = {};
|
||||
let invitationLink = "";
|
||||
|
||||
before(() => {
|
||||
cy.ifEnv("Enterprise", () => {
|
||||
enableInstanceSignup()
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("Verify the signup flow and UI elements", () => {
|
||||
data.fullName = fake.fullName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ import {
|
|||
import { groupsSelector } from "Selectors/manageGroups";
|
||||
import { groupsText } from "Texts/manageGroups";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
import { enableInstanceSignup } from "Support/utils/manageSSO";
|
||||
|
||||
|
||||
let invitationToken,
|
||||
organizationToken,
|
||||
|
|
@ -36,9 +38,9 @@ const envVar = Cypress.env("environment");
|
|||
describe("user invite flow cases", () => {
|
||||
beforeEach(() => {
|
||||
cy.defaultWorkspaceLogin();
|
||||
if (envVar === "Enterprise") {
|
||||
cy.get(".btn-close").click();
|
||||
}
|
||||
cy.ifEnv("Enterprise", () => {
|
||||
enableInstanceSignup()
|
||||
});
|
||||
});
|
||||
|
||||
it("Should verify the Manage users page", () => {
|
||||
|
|
|
|||
|
|
@ -1,59 +1,126 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { usersText } from "Texts/manageUsers";
|
||||
import { usersSelector } from "Selectors/manageUsers";
|
||||
import { groupsSelector } from "Selectors/manageGroups";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import * as common from "Support/utils/common";
|
||||
import { bulkUserUpload } from "Support/utils/manageUsers";
|
||||
|
||||
// Helper to resolve correct test data based on env
|
||||
const getFile = (fileGroup) => {
|
||||
const env = Cypress.env("environment");
|
||||
return env === "Community" ? fileGroup.default : fileGroup.alt;
|
||||
};
|
||||
|
||||
|
||||
describe("Bulk User Upload", () => {
|
||||
// Test data configuration
|
||||
const TEST_FILES = {
|
||||
MISSING_NAME: {
|
||||
path: "cypress/fixtures/bulkUser/without_name.csv",
|
||||
fileName: "without_name",
|
||||
error:
|
||||
"Missing first_name,last_name,groups information in 2 row(s);. No users were uploaded, please update and try again.",
|
||||
default: {
|
||||
path: "cypress/fixtures/bulkUser/missing_name.csv",
|
||||
fileName: "missing_name",
|
||||
error:
|
||||
"Missing first_name,last_name,groups information in 2 row(s);. No users were uploaded, please update and try again.",
|
||||
},
|
||||
alt: {
|
||||
path: "cypress/fixtures/bulkUser/missing_name_ee.csv",
|
||||
fileName: "missing_name_ee",
|
||||
error:
|
||||
"Missing first_name,last_name,groups,metadata,userMetadata information in 2 row(s);. No users were uploaded, please update and try again.",
|
||||
},
|
||||
},
|
||||
MISSING_EMAIL: {
|
||||
path: "cypress/fixtures/bulkUser/without_email.csv",
|
||||
fileName: "without_email",
|
||||
error:
|
||||
"Missing email,groups information in 2 row(s);. No users were uploaded, please update and try again.",
|
||||
default: {
|
||||
path: "cypress/fixtures/bulkUser/missing_email.csv",
|
||||
fileName: "missing_email",
|
||||
error:
|
||||
"Missing email,groups information in 2 row(s);. No users were uploaded, please update and try again.",
|
||||
},
|
||||
alt: {
|
||||
path: "cypress/fixtures/bulkUser/missing_email_ee.csv",
|
||||
fileName: "missing_email_ee",
|
||||
error:
|
||||
"Missing first_name,last_name,groups,metadata,userMetadata information in 2 row(s);. No users were uploaded, please update and try again.",
|
||||
},
|
||||
},
|
||||
DUPLICATE_EMAIL: {
|
||||
path: "cypress/fixtures/bulkUser/same_email.csv",
|
||||
fileName: "same_email",
|
||||
error: "Duplicate email found. Please provide a unique email address.",
|
||||
isDuplicate: true,
|
||||
default: {
|
||||
path: "cypress/fixtures/bulkUser/same_email.csv",
|
||||
fileName: "same_email",
|
||||
error: "Duplicate email found. Please provide a unique email address.",
|
||||
isDuplicate: true,
|
||||
},
|
||||
alt: {
|
||||
path: "cypress/fixtures/bulkUser/same_email_ee.csv",
|
||||
fileName: "same_email_ee",
|
||||
error: "Duplicate email found. Please provide a unique email address.",
|
||||
isDuplicate: true,
|
||||
},
|
||||
},
|
||||
EMPTY_NAMES: {
|
||||
path: "cypress/fixtures/bulkUser/empty_first_and_last_name.csv",
|
||||
fileName: "empty_first_and_last_name",
|
||||
error:
|
||||
"Missing first_name,last_name,groups information in 1 row(s);. No users were uploaded, please update and try again.",
|
||||
default: {
|
||||
path: "cypress/fixtures/bulkUser/empty_names.csv",
|
||||
fileName: "empty_names",
|
||||
error:
|
||||
"Missing first_name,last_name,groups information in 1 row(s);. No users were uploaded, please update and try again.",
|
||||
},
|
||||
alt: {
|
||||
path: "cypress/fixtures/bulkUser/empty_names_ee.csv",
|
||||
fileName: "empty_names_ee",
|
||||
error:
|
||||
"Missing first_name,last_name,groups,metadata,userMetadata information in 1 row(s);. No users were uploaded, please update and try again.",
|
||||
},
|
||||
},
|
||||
LIMIT_EXCEEDED: {
|
||||
path: "cypress/fixtures/bulkUser/500_invite_users.csv",
|
||||
fileName: "500_invite_users",
|
||||
error: "You can only invite 250 users at a time",
|
||||
default: {
|
||||
path: "cypress/fixtures/bulkUser/limit_exceeded.csv",
|
||||
fileName: "limit_exceeded",
|
||||
error: "You can only invite 250 users at a time",
|
||||
},
|
||||
alt: {
|
||||
path: "cypress/fixtures/bulkUser/limit_exceeded_ee.csv",
|
||||
fileName: "limit_exceeded_ee",
|
||||
error: "You can only invite 250 users at a time",
|
||||
},
|
||||
},
|
||||
MISSING_ROLE: {
|
||||
path: "cypress/fixtures/bulkUser/without_role.csv",
|
||||
fileName: "without_role",
|
||||
error:
|
||||
"Missing user_role,groups information in 2 row(s);. No users were uploaded, please update and try again.",
|
||||
default: {
|
||||
path: "cypress/fixtures/bulkUser/missing_role.csv",
|
||||
fileName: "missing_role",
|
||||
error:
|
||||
"Missing user_role,groups information in 2 row(s);. No users were uploaded, please update and try again.",
|
||||
},
|
||||
alt: {
|
||||
path: "cypress/fixtures/bulkUser/missing_role_ee.csv",
|
||||
fileName: "missing_role_ee",
|
||||
error:
|
||||
"Missing user_role,groups,metadata,userMetadata information in 2 row(s);. No users were uploaded, please update and try again.",
|
||||
},
|
||||
},
|
||||
NONEXISTENT_GROUP: {
|
||||
path: "cypress/fixtures/bulkUser/non_existing_group.csv",
|
||||
fileName: "non_existing_group",
|
||||
error: "2 groups doesn't exist. No users were uploaded",
|
||||
default: {
|
||||
path: "cypress/fixtures/bulkUser/non_existing_group.csv",
|
||||
fileName: "non_existing_group",
|
||||
error: "2 groups doesn't exist. No users were uploaded",
|
||||
},
|
||||
alt: {
|
||||
path: "cypress/fixtures/bulkUser/non_existing_group_ee.csv",
|
||||
fileName: "non_existing_group_ee",
|
||||
error: "2 groups doesn't exist. No users were uploaded",
|
||||
},
|
||||
},
|
||||
VALID_USERS: {
|
||||
path: "cypress/fixtures/bulkUser/3usersupload.csv",
|
||||
fileName: "3usersupload",
|
||||
testEmail: "test12@gmail.com",
|
||||
successMessage: "3 users are being added",
|
||||
default: {
|
||||
path: "cypress/fixtures/bulkUser/3_users_upload.csv",
|
||||
fileName: "3_users_upload",
|
||||
successMessage: "3 users are being added",
|
||||
email: "test12@gmail.com",
|
||||
},
|
||||
alt: {
|
||||
path: "cypress/fixtures/bulkUser/3_users_upload_ee.csv",
|
||||
fileName: "3_users_upload_ee",
|
||||
successMessage: "3 users are being added",
|
||||
email: "test12@gmail.com",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -70,7 +137,6 @@ describe("Bulk User Upload", () => {
|
|||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get(usersSelector.buttonUploadCsvFile).click();
|
||||
|
||||
// Test all error cases
|
||||
[
|
||||
TEST_FILES.MISSING_ROLE,
|
||||
TEST_FILES.MISSING_NAME,
|
||||
|
|
@ -79,7 +145,8 @@ describe("Bulk User Upload", () => {
|
|||
TEST_FILES.EMPTY_NAMES,
|
||||
TEST_FILES.NONEXISTENT_GROUP,
|
||||
TEST_FILES.LIMIT_EXCEEDED,
|
||||
].forEach((testCase) => {
|
||||
].forEach((testCaseGroup) => {
|
||||
const testCase = getFile(testCaseGroup);
|
||||
bulkUserUpload(
|
||||
testCase.path,
|
||||
testCase.fileName,
|
||||
|
|
@ -90,32 +157,30 @@ describe("Bulk User Upload", () => {
|
|||
});
|
||||
|
||||
it("Should successfully upload valid users", () => {
|
||||
const file = getFile(TEST_FILES.VALID_USERS);
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get(usersSelector.buttonUploadCsvFile).click();
|
||||
|
||||
cy.get(usersSelector.inputFieldBulkUpload).selectFile(
|
||||
TEST_FILES.VALID_USERS.path,
|
||||
{
|
||||
force: true,
|
||||
}
|
||||
);
|
||||
cy.get(commonSelectors.fileSelector).should(
|
||||
"contain",
|
||||
TEST_FILES.VALID_USERS.fileName
|
||||
);
|
||||
cy.get(usersSelector.inputFieldBulkUpload).selectFile(file.path, {
|
||||
force: true,
|
||||
});
|
||||
|
||||
cy.get(commonSelectors.fileSelector).should("contain", file.fileName);
|
||||
cy.get(usersSelector.buttonUploadUsers).click();
|
||||
cy.get(".go2072408551")
|
||||
.should("be.visible")
|
||||
.and("have.text", TEST_FILES.VALID_USERS.successMessage);
|
||||
common.searchUser("test12@gmail.com");
|
||||
cy.contains("td", "test12@gmail.com")
|
||||
.and("have.text", file.successMessage);
|
||||
|
||||
common.searchUser(file.email);
|
||||
cy.contains("td", file.email)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get("td small").should("have.text", "invited");
|
||||
});
|
||||
|
||||
common.navigateToManageGroups();
|
||||
cy.get(groupsSelector.groupLink("Admin")).click();
|
||||
cy.get(groupsSelector.usersLink).click();
|
||||
cy.contains("test12@gmail.com").should("be.visible");
|
||||
cy.contains(file.email).should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import {
|
|||
} from "Support/utils/common";
|
||||
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
import { enableInstanceSignup } from "Support/utils/manageSSO";
|
||||
|
||||
const data = {};
|
||||
const envVar = Cypress.env("environment");
|
||||
|
|
@ -28,9 +29,9 @@ const envVar = Cypress.env("environment");
|
|||
describe("inviteflow edge cases", () => {
|
||||
beforeEach(() => {
|
||||
cy.defaultWorkspaceLogin();
|
||||
if (envVar === "Enterprise") {
|
||||
cy.get(".btn-close").click();
|
||||
}
|
||||
cy.ifEnv("Enterprise", () => {
|
||||
enableInstanceSignup();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should verify exisiting user invite flow", () => {
|
||||
|
|
@ -69,55 +70,6 @@ describe("inviteflow edge cases", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("should verify the user signup after invited in a workspace", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.signUpName = fake.firstName;
|
||||
data.workspaceName = fake.companyName;
|
||||
|
||||
enableInstanceSignUp();
|
||||
setSignupStatus(true);
|
||||
navigateToManageUsers();
|
||||
fillUserInviteForm(data.firstName, data.email);
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
cy.apiLogout();
|
||||
|
||||
cy.visit("/");
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
SignUpPageElements();
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(onboardingSelectors.nameInput, data.signUpName);
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(
|
||||
onboardingSelectors.loginPasswordInput,
|
||||
commonText.password
|
||||
);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait(1000);
|
||||
signUpLink(data.email);
|
||||
if (envVar === "Enterprise") {
|
||||
verifyOnboardingQuestions(data.workspaceName);
|
||||
cy.wait(1000);
|
||||
cy.get(commonSelectors.skipbutton).click();
|
||||
cy.backToApps();
|
||||
}
|
||||
cy.wait(1000);
|
||||
visitWorkspaceInvitation(data.email, "My workspace");
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, usersText.password);
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.wait(3000);
|
||||
cy.get(commonSelectors.invitedUserName).verifyVisibleElement(
|
||||
"have.text",
|
||||
data.signUpName
|
||||
);
|
||||
cy.get(commonSelectors.acceptInviteButton).click();
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
"have.text",
|
||||
"My workspace"
|
||||
);
|
||||
});
|
||||
|
||||
it("should verify the user signup with same creds after invited in a workspace", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,250 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { commonEeSelectors, ssoEeSelector } from "Selectors/eeCommon";
|
||||
import { ssoEeText } from "Texts/eeCommon";
|
||||
import { setSSOStatus, setSignupStatus } from "Support/utils/manageSSO";
|
||||
import { usersText } from "Texts/manageUsers";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import {
|
||||
logout,
|
||||
navigateToManageSSO,
|
||||
navigateToManageUsers,
|
||||
searchUser,
|
||||
pinInspector,
|
||||
navigateToAppEditor,
|
||||
navigateToManageGroups,
|
||||
} from "Support/utils/common";
|
||||
import { ssoText } from "Texts/manageSSO";
|
||||
import { enableToggle, disableToggle } from "Support/utils/platform/eeCommon";
|
||||
import { setupAndUpdateRole } from "Support/utils/manageGroups";
|
||||
|
||||
describe("LDAP flow", () => {
|
||||
const TEST_DATA = {
|
||||
appName: `${fake.companyName} App`,
|
||||
ldapUser: {
|
||||
username: "Hubert J. Farnsworth",
|
||||
password: "professor",
|
||||
email: "professor@planetexpress.com",
|
||||
},
|
||||
ldapConfig: {
|
||||
name: "Tooljet LDAP Auth",
|
||||
host: Cypress.env("ldap_host"),
|
||||
port: "10389",
|
||||
baseDn: Cypress.env("ldap_base_dn"),
|
||||
},
|
||||
};
|
||||
|
||||
const ldapLogin = (
|
||||
username = TEST_DATA.ldapUser.username,
|
||||
password = TEST_DATA.ldapUser.password
|
||||
) => {
|
||||
cy.get(ssoEeSelector.ldapSSOText).click();
|
||||
cy.clearAndType(commonSelectors.inputFieldName, username);
|
||||
cy.clearAndType(ssoEeSelector.passwordInputField, password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
};
|
||||
|
||||
const toggleUserArchiveStatus = (shouldArchive = true) => {
|
||||
navigateToManageUsers();
|
||||
searchUser(TEST_DATA.ldapUser.email);
|
||||
cy.get('[data-cy="user-actions-button"]').click();
|
||||
cy.get('[data-cy="archive-button"]').click();
|
||||
|
||||
const expectedToast = shouldArchive
|
||||
? usersText.archivedToast
|
||||
: usersText.unarchivedToast;
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, expectedToast);
|
||||
|
||||
if (shouldArchive) {
|
||||
cy.contains("td", TEST_DATA.ldapUser.email)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get("td small").should("have.text", usersText.archivedStatus);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit("/");
|
||||
cy.appUILogin();
|
||||
});
|
||||
|
||||
it("Verify complete LDAP flow: UI, user onboarding, inspector SSO info, and archive functionality", () => {
|
||||
cy.intercept("GET", "api/library_apps").as("apps");
|
||||
|
||||
// ========== SECTION 1: LDAP Configuration and UI Verification ==========
|
||||
setSSOStatus("My workspace", "ldap", false);
|
||||
navigateToManageSSO();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('[data-cy="ldap-sso-card"]')
|
||||
.verifyVisibleElement("have.text", "LDAP")
|
||||
.click();
|
||||
|
||||
cy.get(ssoEeSelector.ldapToggle).should("be.visible");
|
||||
|
||||
for (const element in ssoEeSelector.ldapPageElements) {
|
||||
cy.get(ssoEeSelector.ldapPageElements[element]).verifyVisibleElement(
|
||||
"have.text",
|
||||
ssoEeText.ldapPageElements[element]
|
||||
);
|
||||
}
|
||||
|
||||
const formElements = [
|
||||
ssoEeSelector.statusLabel,
|
||||
ssoEeSelector.nameInput,
|
||||
ssoEeSelector.hostInput,
|
||||
ssoEeSelector.portInput,
|
||||
ssoEeSelector.baseDnInput,
|
||||
ssoEeSelector.sslToggleInput,
|
||||
];
|
||||
|
||||
formElements.forEach((selector) => {
|
||||
cy.get(selector).should("be.visible");
|
||||
});
|
||||
|
||||
cy.get(commonSelectors.cancelButton)
|
||||
.eq(1)
|
||||
.verifyVisibleElement("have.text", "Cancel");
|
||||
cy.get(commonEeSelectors.saveButton)
|
||||
.eq(1)
|
||||
.verifyVisibleElement("have.text", "Save changes");
|
||||
|
||||
enableToggle(ssoEeSelector.sslToggleInput);
|
||||
cy.get(ssoEeSelector.ldapPageElements.sslLabel)
|
||||
.eq(1)
|
||||
.verifyVisibleElement("have.text", "SSL certificate");
|
||||
cy.get(".css-1x65k0v-control").should("be.visible");
|
||||
|
||||
cy.clearAndType(ssoEeSelector.nameInput, TEST_DATA.ldapConfig.name);
|
||||
cy.clearAndType(ssoEeSelector.hostInput, TEST_DATA.ldapConfig.host);
|
||||
cy.clearAndType(ssoEeSelector.portInput, TEST_DATA.ldapConfig.port);
|
||||
cy.clearAndType(ssoEeSelector.baseDnInput, TEST_DATA.ldapConfig.baseDn);
|
||||
|
||||
cy.get(ssoEeSelector.sslToggleInput).uncheck();
|
||||
cy.get(ssoEeSelector.ldapToggle).click();
|
||||
disableToggle(ssoEeSelector.sslToggleInput);
|
||||
|
||||
cy.get(commonEeSelectors.saveButton).eq(1).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
ssoText.toggleUpdateToast("LDAP")
|
||||
);
|
||||
cy.get(commonSelectors.cancelButton).eq(1).click();
|
||||
logout();
|
||||
|
||||
// ========== SECTION 2: LDAP Login Page and User Onboarding ==========
|
||||
cy.get(ssoEeSelector.ldapSSOText).verifyVisibleElement(
|
||||
"have.text",
|
||||
ssoEeText.ldapSSOText
|
||||
);
|
||||
|
||||
cy.get(ssoEeSelector.ldapSSOText).click();
|
||||
|
||||
const loginPageElements = [
|
||||
{ selector: '[data-cy="key-logo"]', assertion: "be.visible" },
|
||||
{
|
||||
selector: ssoEeSelector.userNameInputLabel,
|
||||
text: ssoEeText.userNameInputLabel,
|
||||
},
|
||||
{ selector: commonSelectors.inputFieldName, assertion: "be.visible" },
|
||||
{ selector: ssoEeSelector.passwordInputLabel, text: "Password" },
|
||||
{ selector: ssoEeSelector.passwordInputField, assertion: "be.visible" },
|
||||
{ selector: commonSelectors.signUpButton, text: "Sign in" },
|
||||
];
|
||||
|
||||
loginPageElements.forEach((element) => {
|
||||
if (element.text) {
|
||||
cy.get(element.selector).verifyVisibleElement(
|
||||
"have.text",
|
||||
element.text
|
||||
);
|
||||
} else {
|
||||
cy.get(element.selector).should(element.assertion);
|
||||
}
|
||||
});
|
||||
|
||||
// Test failed login (user doesn't exist in workspace)
|
||||
cy.clearAndType(
|
||||
commonSelectors.inputFieldName,
|
||||
TEST_DATA.ldapUser.username
|
||||
);
|
||||
cy.clearAndType(
|
||||
ssoEeSelector.passwordInputField,
|
||||
TEST_DATA.ldapUser.password
|
||||
);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"LDAP login failed - User does not exist in the workspace"
|
||||
);
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
setSignupStatus(true);
|
||||
logout();
|
||||
|
||||
ldapLogin();
|
||||
cy.get(commonSelectors.pageSectionHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Applications"
|
||||
);
|
||||
logout();
|
||||
|
||||
// ========== SECTION 3: Setup App and User Permissions for Inspector Test ==========
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.apiCreateApp(TEST_DATA.appName);
|
||||
|
||||
navigateToManageGroups();
|
||||
setupAndUpdateRole("End-user", "Builder", TEST_DATA.ldapUser.email);
|
||||
logout();
|
||||
|
||||
// ========== SECTION 4: Verify SSO User Info in Inspector ==========
|
||||
ldapLogin();
|
||||
|
||||
cy.wait("@apps");
|
||||
cy.wait(1000);
|
||||
|
||||
navigateToAppEditor(TEST_DATA.appName);
|
||||
pinInspector();
|
||||
|
||||
const inspectorPath = [
|
||||
'[data-cy="inspector-node-globals"] > .node-key',
|
||||
'[data-cy="inspector-node-currentuser"] > .node-key',
|
||||
'[data-cy="inspector-node-ssouserinfo"] > .node-key',
|
||||
'[data-cy="inspector-node-mail"] > .node-key',
|
||||
];
|
||||
|
||||
inspectorPath.forEach((selector) => cy.get(selector).click());
|
||||
|
||||
cy.get('[data-cy="inspector-node-0"] > .mx-2').verifyVisibleElement(
|
||||
"have.text",
|
||||
`"${TEST_DATA.ldapUser.email}"`
|
||||
);
|
||||
cy.backToApps();
|
||||
logout();
|
||||
|
||||
// ========== SECTION 5: Archive/Unarchive Functionality ==========
|
||||
cy.defaultWorkspaceLogin();
|
||||
|
||||
// Archive user and verify status
|
||||
toggleUserArchiveStatus(true);
|
||||
logout();
|
||||
|
||||
ldapLogin();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"LDAP login failed - User is archived in the workspace"
|
||||
);
|
||||
|
||||
// Unarchive user
|
||||
cy.go("back");
|
||||
cy.appUILogin();
|
||||
toggleUserArchiveStatus(false);
|
||||
logout();
|
||||
|
||||
ldapLogin();
|
||||
cy.get(commonSelectors.pageSectionHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Applications"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
import * as common from "Support/utils/common";
|
||||
import { ssoText } from "Texts/manageSSO";
|
||||
import {
|
||||
inviteUser,
|
||||
WorkspaceInvitationLink,
|
||||
} from "Support/utils/platform/eeCommon.js";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
commonEeSelectors,
|
||||
ssoEeSelector,
|
||||
instanceSettingsSelector,
|
||||
} from "Selectors/eeCommon";
|
||||
import { commonEeText } from "Texts/eeCommon";
|
||||
import {
|
||||
setSignupStatus,
|
||||
defaultSSO,
|
||||
deleteOrganisationSSO,
|
||||
} from "Support/utils/manageSSO";
|
||||
import { confirmInviteElements } from "Support/utils/manageUsers";
|
||||
import { usersText } from "Texts/manageUsers";
|
||||
import { usersSelector } from "Selectors/manageUsers";
|
||||
|
||||
import { fetchAndVisitInviteLink } from "Support/utils/manageUsers";
|
||||
import { enableInstanceSignup } from "Support/utils/manageSSO";
|
||||
|
||||
describe("Verify OIDC user onboarding", () => {
|
||||
const envVar = Cypress.env("environment");
|
||||
|
||||
beforeEach(() => {
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.intercept("GET", "api/library_apps").as("apps");
|
||||
cy.wait(2000);
|
||||
defaultSSO(true);
|
||||
});
|
||||
|
||||
it("Verify user onboarding using workspace OIDC", () => {
|
||||
deleteOrganisationSSO("My workspace", ["openid"]);
|
||||
common.navigateToManageSSO();
|
||||
defaultSSO(false);
|
||||
setSignupStatus(false);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get(ssoEeSelector.oidc).click();
|
||||
cy.get(ssoEeSelector.oidcToggle).click();
|
||||
cy.clearAndType(ssoEeSelector.nameInput, "Tooljet OIDC");
|
||||
cy.clearAndType(
|
||||
ssoEeSelector.clientIdInput,
|
||||
Cypress.env("SSO_OPENID_CLIENT_ID")
|
||||
);
|
||||
cy.clearAndType(
|
||||
ssoEeSelector.clientSecretInput,
|
||||
Cypress.env("SSO_OPENID_CLIENT_SECRET")
|
||||
);
|
||||
cy.clearAndType(
|
||||
ssoEeSelector.WellKnownUrlInput,
|
||||
Cypress.env("SSO_OPENID_WELL_KNOWN_URL")
|
||||
);
|
||||
cy.get(commonEeSelectors.saveButton).eq(1).click();
|
||||
cy.get('[data-cy="enable-button"]').click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
ssoText.toggleUpdateToast("OpenID")
|
||||
);
|
||||
|
||||
cy.apiLogout();
|
||||
cy.visit("/login/my-workspace");
|
||||
cy.get(ssoEeSelector.oidcSSOText).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Sign in with Tooljet OIDC"
|
||||
);
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".superadmin-button").click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"Open ID login failed - User does not exist in the workspace"
|
||||
);
|
||||
|
||||
cy.apiLogin();
|
||||
setSignupStatus(true);
|
||||
cy.apiLogout();
|
||||
|
||||
cy.visit("/login/my-workspace");
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".superadmin-button").click();
|
||||
|
||||
common.logout();
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
common.navigateToManageUsers();
|
||||
common.searchUser("superadmin@tooljet.com");
|
||||
|
||||
cy.contains("td", "superadmin@tooljet.com")
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get("td small").should("have.text", usersText.activeStatus);
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
cy.visit("/my-workspace");
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".superadmin-button").click();
|
||||
});
|
||||
|
||||
it("Verify invited user onboarding using instance level OIDC", () => {
|
||||
setSignupStatus(true);
|
||||
|
||||
cy.ifEnv("Enterprise", () => {
|
||||
enableInstanceSignup();
|
||||
});
|
||||
|
||||
common.navigateToManageUsers();
|
||||
inviteUser("user", "user@tooljet.com");
|
||||
confirmInviteElements("user@tooljet.com");
|
||||
cy.wait(2000);
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".user-button").click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get(commonSelectors.acceptInviteButton).click();
|
||||
cy.wait("@apps");
|
||||
cy.contains("My workspace").should("be.visible");
|
||||
common.logout();
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
setSignupStatus(false);
|
||||
|
||||
common.navigateToManageUsers();
|
||||
cy.wait(500);
|
||||
inviteUser("user", "userthree@tooljet.com");
|
||||
cy.wait(2000);
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".user-four-button").click();
|
||||
|
||||
cy.get(commonSelectors.toastMessage)
|
||||
.should("be.visible")
|
||||
.and(
|
||||
"have.text",
|
||||
"Open ID login failed - Invalid Email: Please use the email address provided in the invitation."
|
||||
);
|
||||
cy.wait(500);
|
||||
cy.defaultWorkspaceLogin();
|
||||
|
||||
setSignupStatus(true);
|
||||
fetchAndVisitInviteLink("userthree@tooljet.com");
|
||||
cy.wait(2000);
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".user-four-button").click();
|
||||
cy.get(commonSelectors.toastMessage)
|
||||
.should("be.visible")
|
||||
.and(
|
||||
"have.text",
|
||||
"Open ID login failed - Invalid Email: Please use the email address provided in the invitation."
|
||||
);
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".superadmin-button").click();
|
||||
cy.get(commonSelectors.toastMessage)
|
||||
.should("be.visible")
|
||||
.and(
|
||||
"have.text",
|
||||
"Open ID login failed - Invalid Email: Please use the email address provided in the invitation."
|
||||
);
|
||||
});
|
||||
|
||||
if (envVar === "Enterprise") {
|
||||
it("Verify user onboarding using instance level OIDC", () => {
|
||||
enableInstanceSignup();
|
||||
cy.apiLogout();
|
||||
|
||||
cy.visit("/");
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".admin-button").click();
|
||||
cy.wait(3000);
|
||||
common.logout();
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.get(commonSelectors.settingsIcon).click();
|
||||
cy.get(commonEeSelectors.instanceSettingIcon).click();
|
||||
cy.clearAndType(commonSelectors.inputUserSearch, "admin@tooljet.com");
|
||||
|
||||
cy.get(instanceSettingsSelector.userStatus("admin")).verifyVisibleElement(
|
||||
"have.text",
|
||||
usersText.activeStatus
|
||||
);
|
||||
|
||||
cy.apiLogout();
|
||||
cy.visit("/");
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".admin-button").click();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
it("Verify archived user login using OIDC", () => {
|
||||
setSignupStatus(true);
|
||||
cy.ifEnv("Enterprise", () => {
|
||||
enableInstanceSignup();
|
||||
});
|
||||
common.navigateToManageUsers();
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get(commonSelectors.inputFieldFullName).type("user two");
|
||||
cy.get(commonSelectors.inputFieldEmailAddress).type("usertwo@tooljet.com");
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
WorkspaceInvitationLink("usertwo@tooljet.com");
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".user-two-button").click();
|
||||
|
||||
cy.get(commonSelectors.acceptInviteButton).click();
|
||||
cy.wait("@apps");
|
||||
cy.contains("My workspace").should("be.visible");
|
||||
common.logout();
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
common.navigateToManageUsers();
|
||||
common.searchUser("usertwo@tooljet.com");
|
||||
cy.get('[data-cy="user-actions-button"]').click();
|
||||
cy.get('[data-cy="archive-button"]').click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
usersText.archivedToast
|
||||
);
|
||||
cy.get(instanceSettingsSelector.userStatus("user two"), {
|
||||
timeout: 9000,
|
||||
}).should("have.text", usersText.archivedStatus);
|
||||
cy.apiLogout();
|
||||
cy.visit("/my-workspace");
|
||||
cy.wait(2000);
|
||||
cy.get(ssoEeSelector.oidcSSOText).realClick();
|
||||
cy.get(".user-two-button").click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"Open ID login failed - User is archived in the workspace"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -18,7 +18,7 @@ describe("Self host onboarding", () => {
|
|||
});
|
||||
|
||||
it("verify elements on self host onboarding page", () => {
|
||||
if (envVar === "Enterprise") {
|
||||
cy.ifEnv("Enterprise", () => {
|
||||
cy.get(commonSelectors.HostBanner).should("be.visible");
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get('[data-cy="welcome-to-tooljet!-header"]').verifyVisibleElement(
|
||||
|
|
@ -34,7 +34,7 @@ describe("Self host onboarding", () => {
|
|||
"Set up ToolJet"
|
||||
);
|
||||
cy.get('[data-cy="set-up-tooljet-button"]').click();
|
||||
}
|
||||
});
|
||||
|
||||
const commonElements = [
|
||||
{ selector: commonSelectors.HostBanner },
|
||||
|
|
@ -76,20 +76,22 @@ describe("Self host onboarding", () => {
|
|||
cy.get(check.selector).verifyVisibleElement("have.text", check.text);
|
||||
});
|
||||
|
||||
if (envVar === "Community") {
|
||||
cy.ifEnv("Community", () => {
|
||||
cy.get(commonSelectors.signUpTermsHelperText).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
// commonText.selfHostSignUpTermsHelperText
|
||||
"By signing up you are agreeing to the"
|
||||
);
|
||||
});
|
||||
} else if (envVar === "Enterprise") {
|
||||
});
|
||||
|
||||
cy.ifEnv("Enterprise", () => {
|
||||
cy.get(commonSelectors.signUpTermsHelperText).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
"By signing up you are agreeing to the"
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const links = [
|
||||
{
|
||||
|
|
@ -116,20 +118,15 @@ describe("Self host onboarding", () => {
|
|||
cy.get(onboardingSelectors.passwordInput).type("password");
|
||||
cy.get(commonSelectors.continueButton).click();
|
||||
|
||||
if (envVar === "Enterprise") {
|
||||
cy.ifEnv("Enterprise", () => {
|
||||
bannerElementsVerification();
|
||||
onboardingStepOne();
|
||||
}
|
||||
});
|
||||
|
||||
bannerElementsVerification();
|
||||
onboardingStepTwo();
|
||||
|
||||
// if (envVar === "Enterprise") {
|
||||
// bannerElementsVerification();
|
||||
// onboardingStepTwo();
|
||||
// }
|
||||
|
||||
if (envVar === "Enterprise") {
|
||||
cy.ifEnv("Enterprise", () => {
|
||||
bannerElementsVerification();
|
||||
|
||||
const trialPageTexts = [
|
||||
|
|
@ -173,7 +170,7 @@ describe("Self host onboarding", () => {
|
|||
cy.get(onboardingSelectors.onPremiseLink)
|
||||
.verifyVisibleElement("have.text", "Click here")
|
||||
.and("have.attr", "href")
|
||||
.and("equal", "https://www.tooljet.com/pricing?payment=onpremise");
|
||||
.and("equal", "https://tooljet.ai/pricing?payment=onpremise");
|
||||
|
||||
const planTitles = [
|
||||
{
|
||||
|
|
@ -196,66 +193,59 @@ describe("Self host onboarding", () => {
|
|||
|
||||
const prices = [
|
||||
{ selector: `${onboardingSelectors.planPrice}:eq(0)`, text: "$0" },
|
||||
{ selector: `${onboardingSelectors.planPrice}:eq(1)`, text: "$30" },
|
||||
{
|
||||
selector: '[data-cy="pro-plan-price"]:eq(0)',
|
||||
text: "$79/monthper builder",
|
||||
},
|
||||
{
|
||||
selector: '[data-cy="pro-plan-price"]:eq(1)',
|
||||
text: "$199/monthper builder",
|
||||
},
|
||||
{
|
||||
selector: `${onboardingSelectors.planToggleLabel}:eq(0)`,
|
||||
text: "Yearly20% off",
|
||||
},
|
||||
{
|
||||
selector: `${onboardingSelectors.planToggleLabel}:eq(1)`,
|
||||
text: "Yearly20% off",
|
||||
},
|
||||
];
|
||||
|
||||
prices.forEach((item) => {
|
||||
cy.get(item.selector).should("be.visible").and("have.text", item.text);
|
||||
});
|
||||
|
||||
cy.get(onboardingSelectors.planToggleInput).should("be.visible");
|
||||
cy.get(onboardingSelectors.planToggleLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Yearly20% off"
|
||||
);
|
||||
cy.get(onboardingSelectors.discountDetails).verifyVisibleElement(
|
||||
"have.text",
|
||||
"20% off"
|
||||
);
|
||||
cy.get(onboardingSelectors.planToggleInput).eq(0).should("be.visible");
|
||||
cy.get(onboardingSelectors.planToggleInput).eq(1).should("be.visible");
|
||||
|
||||
cy.get(onboardingSelectors.builderPrice).verifyVisibleElement(
|
||||
"have.text",
|
||||
"$24"
|
||||
);
|
||||
cy.get('[data-cy="builder-price-period"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
onboardingText.priceMonthlyText
|
||||
);
|
||||
cy.get('[data-cy="builder-price-description"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"per builder"
|
||||
);
|
||||
|
||||
cy.get(onboardingSelectors.endUserPrice).verifyVisibleElement(
|
||||
"have.text",
|
||||
"$8"
|
||||
);
|
||||
cy.get('[data-cy="enduser-price-period"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
onboardingText.priceMonthlyText
|
||||
);
|
||||
cy.get('[data-cy="enduser-price-description"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"per end user"
|
||||
);
|
||||
|
||||
cy.get(onboardingSelectors.pricingPlanToggle).uncheck({ force: true });
|
||||
cy.get(onboardingSelectors.pricingPlanToggle)
|
||||
.eq(0)
|
||||
.uncheck({ force: true });
|
||||
|
||||
cy.get(onboardingSelectors.planToggleLabel)
|
||||
.first()
|
||||
.eq(0)
|
||||
.verifyVisibleElement("have.text", "Monthly20% off");
|
||||
cy.get(onboardingSelectors.discountDetails)
|
||||
.should("have.css", "text-decoration")
|
||||
.and("include", "line-through");
|
||||
|
||||
cy.get(onboardingSelectors.builderPrice).verifyVisibleElement(
|
||||
"have.text",
|
||||
"$30"
|
||||
);
|
||||
cy.get(onboardingSelectors.endUserPrice).verifyVisibleElement(
|
||||
"have.text",
|
||||
"$10"
|
||||
);
|
||||
cy.get('[data-cy="pro-plan-price"]')
|
||||
.eq(0)
|
||||
.verifyVisibleElement("have.text", "$99/monthper builder");
|
||||
|
||||
cy.get(onboardingSelectors.pricingPlanToggle)
|
||||
.eq(1)
|
||||
.uncheck({ force: true });
|
||||
cy.get(onboardingSelectors.planToggleLabel)
|
||||
.eq(1)
|
||||
.verifyVisibleElement("have.text", "Monthly20% off");
|
||||
cy.get(onboardingSelectors.discountDetails)
|
||||
.should("have.css", "text-decoration")
|
||||
.and("include", "line-through");
|
||||
|
||||
cy.get('[data-cy="pro-plan-price"]')
|
||||
.eq(1)
|
||||
.verifyVisibleElement("have.text", "$249/monthper builder");
|
||||
|
||||
cy.get(onboardingSelectors.enterpriseTitle).verifyVisibleElement(
|
||||
"have.text",
|
||||
|
|
@ -274,19 +264,11 @@ describe("Self host onboarding", () => {
|
|||
|
||||
bannerElementsVerification();
|
||||
onboardingStepThree();
|
||||
}
|
||||
});
|
||||
|
||||
cy.get(commonSelectors.skipbutton).click();
|
||||
cy.backToApps();
|
||||
|
||||
if (envVar === "Enterprise") {
|
||||
cy.get(".btn-close").click();
|
||||
}
|
||||
|
||||
if (envVar === "Enterprise") {
|
||||
cy.get(".btn-close").click();
|
||||
}
|
||||
|
||||
logout();
|
||||
cy.appUILogin();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
First Name,Last Name,Email,User Role,Group
|
||||
test1,user,test1@gmail.com,Builder,
|
||||
test2,user,test3@gmail.com,End User,
|
||||
Test3,Example,test12@gmail.com,Admin,
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
First Name,Last Name,Email,User Role,Group,Metadata
|
||||
test1,user,test1@gmail.com,Builder,,
|
||||
test2,user,test3@gmail.com,End User,,
|
||||
Test3,Example,test12@gmail.com,Admin,,
|
||||
|
3
cypress-tests/cypress/fixtures/bulkUser/empty_names.csv
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
First Name,Last Name,Email,User Role,Group
|
||||
,,test12empty@gmail.com,Admin,Admin
|
||||
Test,Example,test12empty@gmail.com,Builder,Builder
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
First Name,Last Name,Email,User Role,Group,Metadata
|
||||
,,test12empty@gmail.com,Admin,Admin,
|
||||
Test,Example,test12empty@gmail.com,Builder,Builder,
|
||||
|
252
cypress-tests/cypress/fixtures/bulkUser/limit_exceeded.csv
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
First Name,Last Name,Email,User Role,Group
|
||||
Vijay,Yadav,vjyaav1@gmail.com,Admin,
|
||||
Vijay,Yadav,vjyaav2@gmail.com,Builder,
|
||||
Vijay,Yadav,vjyaav3@gmail.com,Builder,
|
||||
Vijay,Yadav,vjyaav4@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav5@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav6@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav7@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav8@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav9@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav10@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav11@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav12@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav13@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav14@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav15@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav16@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav17@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav18@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav19@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav20@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav21@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav22@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav23@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav24@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav25@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav26@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav27@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav28@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav29@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav30@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav31@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav32@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav33@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav34@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav35@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav36@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav37@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav38@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav39@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav40@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav41@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav42@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav43@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav44@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav45@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav46@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav47@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav48@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav49@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav50@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav51@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav52@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav53@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav54@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav55@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav56@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav57@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav58@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav59@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav60@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav61@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav62@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav63@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav64@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav65@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav66@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav67@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav68@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav69@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav70@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav71@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav72@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav73@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav74@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav75@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav76@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav77@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav78@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav79@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav80@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav81@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav82@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav83@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav84@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav85@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav86@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav87@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav88@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav89@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav90@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav91@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav92@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav93@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav94@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav95@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav96@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav97@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav98@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav99@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav100@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav101@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav102@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav103@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav104@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav105@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav106@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav107@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav108@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav109@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav110@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav111@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav112@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav113@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav114@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav115@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav116@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav117@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav118@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav119@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav120@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav121@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav122@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav123@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav124@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav125@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav126@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav127@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav128@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav129@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav130@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav131@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav132@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav133@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav134@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav135@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav136@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav137@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav138@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav139@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav140@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav141@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav142@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav143@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav144@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav145@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav146@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav147@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav148@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav149@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav150@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav151@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav152@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav153@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav154@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav155@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav156@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav157@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav158@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav159@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav160@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav161@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav162@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav163@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav164@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav165@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav166@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav167@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav168@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav169@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav170@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav171@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav172@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav173@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav174@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav175@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav176@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav177@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav178@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav179@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav180@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav181@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav182@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav183@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav184@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav185@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav186@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav187@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav188@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav189@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav190@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav191@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav192@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav193@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav194@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav195@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav196@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav197@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav198@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav199@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav200@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav201@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav202@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav203@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav204@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav205@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav206@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav207@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav208@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav209@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav210@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav211@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav212@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav213@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav214@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav215@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav216@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav217@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav218@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav219@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav220@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav221@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav222@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav223@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav224@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav225@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav226@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav227@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav228@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav229@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav230@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav231@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav232@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav233@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav234@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav235@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav236@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav237@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav238@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav239@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav240@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav241@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav242@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav243@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav244@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav245@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav246@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav247@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav248@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav249@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav250@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav251@gmail.com,End User,
|
||||
|
252
cypress-tests/cypress/fixtures/bulkUser/limit_exceeded_ee.csv
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
First Name,Last Name,Email,User Role,Group,Metadata
|
||||
Vijay,Yadav,vjyaav1@gmail.com,Admin,,
|
||||
Vijay,Yadav,vjyaav2@gmail.com,Builder,,
|
||||
Vijay,Yadav,vjyaav3@gmail.com,Builder,,
|
||||
Vijay,Yadav,vjyaav4@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav5@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav6@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav7@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav8@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav9@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav10@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav11@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav12@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav13@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav14@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav15@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav16@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav17@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav18@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav19@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav20@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav21@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav22@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav23@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav24@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav25@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav26@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav27@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav28@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav29@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav30@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav31@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav32@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav33@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav34@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav35@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav36@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav37@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav38@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav39@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav40@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav41@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav42@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav43@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav44@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav45@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav46@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav47@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav48@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav49@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav50@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav51@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav52@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav53@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav54@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav55@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav56@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav57@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav58@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav59@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav60@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav61@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav62@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav63@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav64@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav65@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav66@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav67@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav68@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav69@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav70@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav71@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav72@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav73@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav74@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav75@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav76@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav77@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav78@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav79@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav80@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav81@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav82@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav83@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav84@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav85@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav86@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav87@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav88@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav89@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav90@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav91@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav92@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav93@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav94@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav95@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav96@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav97@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav98@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav99@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav100@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav101@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav102@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav103@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav104@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav105@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav106@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav107@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav108@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav109@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav110@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav111@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav112@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav113@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav114@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav115@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav116@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav117@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav118@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav119@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav120@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav121@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav122@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav123@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav124@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav125@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav126@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav127@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav128@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav129@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav130@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav131@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav132@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav133@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav134@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav135@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav136@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav137@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav138@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav139@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav140@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav141@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav142@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav143@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav144@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav145@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav146@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav147@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav148@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav149@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav150@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav151@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav152@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav153@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav154@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav155@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav156@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav157@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav158@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav159@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav160@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav161@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav162@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav163@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav164@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav165@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav166@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav167@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav168@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav169@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav170@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav171@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav172@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav173@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav174@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav175@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav176@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav177@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav178@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav179@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav180@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav181@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav182@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav183@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav184@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav185@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav186@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav187@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav188@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav189@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav190@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav191@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav192@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav193@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav194@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav195@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav196@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav197@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav198@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav199@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav200@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav201@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav202@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav203@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav204@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav205@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav206@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav207@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav208@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav209@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav210@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav211@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav212@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav213@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav214@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav215@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav216@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav217@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav218@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav219@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav220@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav221@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav222@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav223@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav224@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav225@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav226@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav227@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav228@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav229@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav230@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav231@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav232@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav233@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav234@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav235@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav236@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav237@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav238@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav239@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav240@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav241@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav242@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav243@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav244@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav245@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav246@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav247@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav248@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav249@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav250@gmail.com,End User,,
|
||||
Vijay,Yadav,vjyaav251@gmail.com,End User,,
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
First Name,Last Name,Email,User Role,Group
|
||||
test,test,,Admin,Admin
|
||||
test,test,,Builder,Builder
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
First Name,Last Name,Email,User Role,Group,Metadata
|
||||
,,withoutname1@gmail.com,Admin,Admin,
|
||||
,,withoutname2@gmail.com,Builder,Builder,
|
||||
|
3
cypress-tests/cypress/fixtures/bulkUser/missing_name.csv
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
First Name,Last Name,Email,User Role,Group
|
||||
,,withoutname1@gmail.com,Admin,Admin
|
||||
,,withoutname2@gmail.com,Builder,Builder
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
First Name,Last Name,Email,User Role,Group,Metadata
|
||||
,,withoutname1@gmail.com,Admin,Admin,
|
||||
,,withoutname2@gmail.com,Builder,Builder,
|
||||
|
3
cypress-tests/cypress/fixtures/bulkUser/missing_role.csv
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
First Name,Last Name,Email,User Role,Group
|
||||
Test,Example,test12@gmail.com,,
|
||||
Test,Example,test13@gmail.com,,
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
First Name,Last Name,Email,User Role,Group,Metadata
|
||||
Test,Example,test12@gmail.com,,,
|
||||
Test,Example,test13@gmail.com,,,
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
First Name,Last Name,Email,User Role,Group,Metadata
|
||||
test,test,demo1@gmail.com,Admin,test,
|
||||
test,test,demo2@gmail.com,Builder,abc,
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
First Name,Last Name,Email,User Role,Group,Metadata
|
||||
test,test,demo11@gmail.com,Admin,,
|
||||
test,test,demo11@gmail.com,Builder,,
|
||||
|
||||
|
|
|
@ -135,6 +135,7 @@ export const resolveHost = () => {
|
|||
const baseUrl = Cypress.config("baseUrl");
|
||||
|
||||
const urlMapping = {
|
||||
"http://localhost:8082": "http://localhost:8082",
|
||||
"http://localhost:3000": "http://localhost:3000",
|
||||
"http://localhost:3000/apps": "http://localhost:3000/apps",
|
||||
"http://localhost:4001": "http://localhost:3000",
|
||||
|
|
|
|||
|
|
@ -31,8 +31,11 @@ export const verifyAndModifyParameter = (paramName, value) => {
|
|||
export const openEditorSidebar = (widgetName = "") => {
|
||||
cy.hideTooltip();
|
||||
|
||||
cy.get(`${commonWidgetSelector.draggableWidget(widgetName)}:eq(0)`).realHover()
|
||||
cy.get(commonWidgetSelector.widgetConfigHandle(widgetName)).click();
|
||||
|
||||
cy.get(`${commonWidgetSelector.draggableWidget(widgetName)}:eq(0)`).realHover().then(() => {
|
||||
cy.wait(1000);
|
||||
cy.get(commonWidgetSelector.widgetConfigHandle(widgetName)).click();
|
||||
})
|
||||
};
|
||||
|
||||
export const verifyAndModifyToggleFx = (
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export const query = (operation) => {
|
|||
};
|
||||
|
||||
export const verifypreview = (type, data) => {
|
||||
cy.get(`[data-cy="preview-tab-${type}"]`).click();
|
||||
cy.get(`[data-cy="preview-tab-${type}"]`, { timeout: 15000 }).click();
|
||||
cy.get(`[data-cy="preview-${type}-data-container"]`).verifyVisibleElement(
|
||||
"contain.text",
|
||||
data,
|
||||
|
|
|
|||
|
|
@ -1,60 +1,49 @@
|
|||
export const verifyNodeData = (node, type, children, index = 0) => {
|
||||
cy.get(
|
||||
`[data-cy="inspector-node-${node.toLowerCase()}"] > .node-length-color`
|
||||
)
|
||||
.eq(index)
|
||||
.realHover()
|
||||
.verifyVisibleElement("have.text", `${children}`);
|
||||
cy.get(`[data-cy="inspector-node-${node.toLowerCase()}"] > .node-key`)
|
||||
.eq(index)
|
||||
.verifyVisibleElement("have.text", node);
|
||||
cy.get(`[data-cy="inspector-node-${node.toLowerCase()}"] > .node-type`)
|
||||
.eq(index)
|
||||
.verifyVisibleElement("have.text", type);
|
||||
};
|
||||
import { commonWidgetSelector } from "Selectors/common";
|
||||
|
||||
export const openNode = (node, index = 0, time = 1000) => {
|
||||
cy.get(`[data-cy="inspector-node-${node.toLowerCase()}"] > .node-key`)
|
||||
.eq(index)
|
||||
.click();
|
||||
cy.wait(time);
|
||||
};
|
||||
|
||||
export const verifyValue = (node, type, children, index = 0) => {
|
||||
cy.get(`[data-cy="inspector-node-${node.toLowerCase()}"] > .mx-2`)
|
||||
.eq(index)
|
||||
.realHover()
|
||||
.verifyVisibleElement("contain.text", `${children}`);
|
||||
cy.get(`[data-cy="inspector-node-${node.toLowerCase()}"] > .node-key`)
|
||||
.eq(index)
|
||||
.verifyVisibleElement("contain.text", node);
|
||||
cy.get(`[data-cy="inspector-node-${node.toLowerCase()}"] > .mx-1`)
|
||||
.eq(index)
|
||||
.verifyVisibleElement("contain.text", type);
|
||||
};
|
||||
export const deleteComponentFromInspector = (node) => {
|
||||
cy.get('[data-cy="inspector-node-components"] > .node-key').click();
|
||||
cy.get(`[data-cy="inspector-node-${node}"] > .node-key`).realHover().parent().find('[style="height: 13px; width: 13px;"] > img').last().click();
|
||||
};
|
||||
|
||||
export const verifyfunctions = (node, type, index = 0) => {
|
||||
cy.get(`[data-cy="inspector-node-${node.toLowerCase()}"] > .fs-10`)
|
||||
.eq(index)
|
||||
.realHover()
|
||||
.verifyVisibleElement("contain.text", `${type}`);
|
||||
cy.get(`[data-cy="inspector-node-${node.toLowerCase()}"] > .node-key`)
|
||||
.eq(index)
|
||||
.verifyVisibleElement("contain.text", node);
|
||||
// cy.get(`[data-cy="inspector-node-${node.toLowerCase()}"] > .mx-1`)
|
||||
// .eq(index)
|
||||
// .verifyVisibleElement("contain.text", type);
|
||||
export const openAndVerifyNode = (nodeName, nodes, verificationFunction) => {
|
||||
openStateFromComponent(nodeName);
|
||||
verifyNodes(nodes, verificationFunction);
|
||||
};
|
||||
|
||||
export const verifyNodes = (nodes, verificationFunction) => {
|
||||
nodes.forEach(node => verificationFunction(node.key, node.type, node.value));
|
||||
};
|
||||
|
||||
export const openAndVerifyNode = (nodeName, nodes, verificationFunction) => {
|
||||
openNode(nodeName);
|
||||
verifyNodes(nodes, verificationFunction);
|
||||
export const openNode = (node, index = 0, time = 1000) => {
|
||||
cy.get(`[data-cy="inspector-${node.toLowerCase()}-expand-button"]`, { timeout: time })
|
||||
.eq(index)
|
||||
.click();
|
||||
};
|
||||
|
||||
export const openStateFromComponent = (widgetName) => {
|
||||
cy.get(commonWidgetSelector.draggableWidget(widgetName))
|
||||
.realHover()
|
||||
.realHover();
|
||||
|
||||
cy.get(commonWidgetSelector.draggableWidget(widgetName))
|
||||
.realHover()
|
||||
.then(() => {
|
||||
cy.get(`[data-cy="${widgetName}-inspect-button"]`)
|
||||
.realHover({ position: "topRight" })
|
||||
.last()
|
||||
.realClick();
|
||||
});
|
||||
}
|
||||
|
||||
export const verifyNodeData = (node, type, value, index = 0) => {
|
||||
cy.get(
|
||||
`[data-cy="inspector-${node.toLowerCase()}-label"]`
|
||||
)
|
||||
.eq(index)
|
||||
.realHover()
|
||||
.verifyVisibleElement("have.text", `${node}`);
|
||||
|
||||
cy.get(`[data-cy="inspector-${node.toLowerCase()}-value"]`)
|
||||
.eq(index)
|
||||
.verifyVisibleElement("have.text", type == 'Function' ? 'function' : value);
|
||||
};
|
||||
|
||||
export const deleteComponentFromInspector = (node) => {
|
||||
cy.get('[data-cy="inspector-menu-icon"]').click();
|
||||
cy.get(`[data-cy="inspector-delete-component-action"`).realHover().parent().find('[style="height: 13px; width: 13px;"] > img').last().click();
|
||||
};
|
||||
|
|
@ -658,7 +658,7 @@ export const createGroupAddAppAndUserToGroup = (groupName, email) => {
|
|||
|
||||
cy.request({
|
||||
method: "POST",
|
||||
url: `${Cypress.env("server_host")}/api/v2/group-permissions/${groupId}/granular-permissions`,
|
||||
url: `${Cypress.env("server_host")}/api/v2/group-permissions/${groupId}/granular-permissions/app`,
|
||||
headers: headers,
|
||||
body: {
|
||||
name: "Apps",
|
||||
|
|
@ -676,7 +676,6 @@ export const createGroupAddAppAndUserToGroup = (groupName, email) => {
|
|||
],
|
||||
},
|
||||
},
|
||||
|
||||
}).then((response) => {
|
||||
expect(response.status).to.equal(201);
|
||||
});
|
||||
|
|
@ -727,7 +726,7 @@ export const duplicateMultipleGroups = (groupNames) => {
|
|||
cy.get(commonSelectors.duplicateOption).click(); // Click on the duplicate option
|
||||
cy.get(commonSelectors.confirmDuplicateButton).click(); // Confirm duplication if needed
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const verifyGroupCardOptions = (groupName) => {
|
||||
cy.get(groupsSelector.groupLink(groupName)).click();
|
||||
|
|
@ -865,7 +864,7 @@ export const addUserInGroup = (groupName, email) => {
|
|||
commonSelectors.toastMessage,
|
||||
groupsText.userAddedToast
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const inviteUserBasedOnRole = (firstName, email, role = "end-user") => {
|
||||
fillUserInviteForm(firstName, email);
|
||||
|
|
@ -891,7 +890,13 @@ export const verifyBasicPermissions = (canCreate = true) => {
|
|||
);
|
||||
};
|
||||
|
||||
export const setupWorkspaceAndInviteUser = (workspaceName, workspaceSlug, firstName, email, role = "end-user") => {
|
||||
export const setupWorkspaceAndInviteUser = (
|
||||
workspaceName,
|
||||
workspaceSlug,
|
||||
firstName,
|
||||
email,
|
||||
role = "end-user"
|
||||
) => {
|
||||
cy.apiCreateWorkspace(workspaceName, workspaceSlug);
|
||||
cy.visit(workspaceSlug);
|
||||
cy.wait(1000);
|
||||
|
|
@ -907,7 +912,10 @@ export const verifySettingsAccess = (shouldExist = true) => {
|
|||
);
|
||||
};
|
||||
|
||||
export const verifyUserPrivileges = (expectedButtonState, shouldHaveWorkspaceSettings) => {
|
||||
export const verifyUserPrivileges = (
|
||||
expectedButtonState,
|
||||
shouldHaveWorkspaceSettings
|
||||
) => {
|
||||
cy.get(commonSelectors.dashboardAppCreateButton).should(expectedButtonState);
|
||||
cy.get(commonSelectors.settingsIcon).click();
|
||||
|
||||
|
|
@ -923,4 +931,4 @@ export const setupAndUpdateRole = (currentRole, endRole, email) => {
|
|||
updateRole(currentRole, endRole, email);
|
||||
cy.wait(1000);
|
||||
cy.apiLogout();
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ export const defaultSSO = (enable) => {
|
|||
});
|
||||
};
|
||||
|
||||
export const setSignupStatus = (enable, workspaceName = 'My workspace') => {
|
||||
export const setSignupStatus = (enable, workspaceName = "My workspace") => {
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `SELECT id FROM organizations WHERE name = '${workspaceName}'`,
|
||||
|
|
@ -429,3 +429,23 @@ export const resetDomain = () => {
|
|||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const enableInstanceSignup = (
|
||||
allowPersonalWorkspace = true,
|
||||
enableLoginConfig = true,
|
||||
allowedDomains = ""
|
||||
) => {
|
||||
const allowValue = allowPersonalWorkspace ? "true" : "false";
|
||||
const loginConfigValue = enableLoginConfig ? "true" : "false";
|
||||
|
||||
const sql = `
|
||||
UPDATE instance_settings SET value = '${allowValue}' WHERE key = 'ALLOW_PERSONAL_WORKSPACE';
|
||||
UPDATE instance_settings SET value = '${loginConfigValue}' WHERE key = 'ENABLE_SIGNUP';
|
||||
UPDATE instance_settings SET value = '${allowedDomains}' WHERE key = 'ALLOWED_DOMAINS';
|
||||
`;
|
||||
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql,
|
||||
});
|
||||
};
|
||||
|
|
|
|||
591
cypress-tests/cypress/support/utils/platform/eeCommon.js
Normal file
|
|
@ -0,0 +1,591 @@
|
|||
import {
|
||||
commonEeSelectors,
|
||||
ssoEeSelector,
|
||||
instanceSettingsSelector,
|
||||
multiEnvSelector,
|
||||
workspaceSelector,
|
||||
} from "Selectors/eeCommon";
|
||||
import { ssoEeText } from "Texts/eeCommon";
|
||||
import { commonSelectors, commonWidgetSelector } from "Selectors/common";
|
||||
import * as common from "Support/utils/common";
|
||||
import { groupsSelector } from "Selectors/manageGroups";
|
||||
import { groupsText } from "Texts/manageGroups";
|
||||
import { eeGroupsSelector } from "Selectors/eeCommon";
|
||||
import { eeGroupsText } from "Texts/eeCommon";
|
||||
import {
|
||||
// verifyOnboardingQuestions,
|
||||
// verifyCloudOnboardingQuestions,
|
||||
fetchAndVisitInviteLink,
|
||||
} from "Support/utils/manageUsers";
|
||||
import { commonText } from "Texts/common";
|
||||
import { dashboardText } from "Texts/dashboard";
|
||||
import { usersText } from "Texts/manageUsers";
|
||||
import { usersSelector } from "Selectors/manageUsers";
|
||||
import { ssoSelector } from "Selectors/manageSSO";
|
||||
import { ssoText } from "Texts/manageSSO";
|
||||
// import { appPromote } from "Support/utils/multiEnv";
|
||||
|
||||
export const oidcSSOPageElements = () => {
|
||||
cy.get(ssoEeSelector.oidcToggle).click();
|
||||
cy.get(ssoSelector.saveButton).eq(1).click();
|
||||
cy.get('[data-cy="modal-title"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Enable OpenID Connect"
|
||||
);
|
||||
cy.get('[data-cy="modal-close-button"]').should("be.visible");
|
||||
cy.get('[data-cy="modal-message"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Enabling OpenID Connect at the workspace level will override any OpenID Connect configurations set at the instance level."
|
||||
);
|
||||
cy.get('[data-cy="confirmation-text"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Are you sure you want to continue?"
|
||||
);
|
||||
cy.get('[data-cy="cancel-button"]')
|
||||
.eq(2)
|
||||
.verifyVisibleElement("have.text", "Cancel");
|
||||
cy.get('[data-cy="enable-button"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Enable"
|
||||
);
|
||||
|
||||
cy.get('[data-cy="cancel-button"]').eq(2).click();
|
||||
cy.get('[data-cy="status-label"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
ssoText.disabledLabel
|
||||
);
|
||||
|
||||
cy.get(ssoEeSelector.oidcToggle).click();
|
||||
cy.get(ssoSelector.saveButton).eq(1).click();
|
||||
cy.get('[data-cy="enable-button"]').click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
ssoText.toggleUpdateToast("OpenID")
|
||||
);
|
||||
|
||||
cy.get(ssoEeSelector.statusLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
ssoEeText.enabledLabel
|
||||
);
|
||||
|
||||
cy.get('[data-cy="redirect-url-label"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
ssoText.redirectUrlLabel
|
||||
);
|
||||
cy.get('[data-cy="redirect-url"]').should("be.visible");
|
||||
cy.get('[data-cy="copy-icon"]').should("be.visible");
|
||||
|
||||
cy.get(ssoEeSelector.oidcToggle).click();
|
||||
cy.get(ssoSelector.saveButton).eq(1).click();
|
||||
// cy.get('[data-cy="enable-button"]').click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
ssoText.toggleUpdateToast("OpenID")
|
||||
);
|
||||
cy.get(ssoSelector.statusLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
ssoText.disabledLabel
|
||||
);
|
||||
|
||||
cy.get(ssoEeSelector.oidcToggle).click();
|
||||
cy.clearAndType(ssoEeSelector.nameInput, ssoEeText.testName);
|
||||
cy.clearAndType(ssoEeSelector.clientIdInput, ssoEeText.testclientId);
|
||||
cy.clearAndType(ssoEeSelector.clientSecretInput, ssoEeText.testclientSecret);
|
||||
cy.clearAndType(ssoEeSelector.WellKnownUrlInput, ssoEeText.testWellknownUrl);
|
||||
cy.get(ssoSelector.saveButton).eq(1).click();
|
||||
cy.get('[data-cy="enable-button"]').click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
ssoText.toggleUpdateToast("OpenID")
|
||||
);
|
||||
cy.get(ssoEeSelector.nameInput).should("have.value", ssoEeText.testName);
|
||||
cy.get(ssoEeSelector.clientIdInput).should(
|
||||
"have.value",
|
||||
ssoEeText.testclientId
|
||||
);
|
||||
cy.get(ssoEeSelector.clientSecretInput).should(
|
||||
"have.value",
|
||||
ssoEeText.testclientSecret
|
||||
);
|
||||
cy.get(ssoEeSelector.WellKnownUrlInput).should(
|
||||
"have.value",
|
||||
ssoEeText.testWellknownUrl
|
||||
);
|
||||
};
|
||||
|
||||
export const resetDsPermissions = () => {
|
||||
common.navigateToManageGroups();
|
||||
cy.wait(200);
|
||||
cy.get(groupsSelector.permissionsLink).click();
|
||||
|
||||
cy.get(groupsSelector.appsCreateCheck).then(($el) => {
|
||||
if ($el.is(":checked")) {
|
||||
cy.get(groupsSelector.appsCreateCheck).uncheck();
|
||||
}
|
||||
});
|
||||
cy.get(eeGroupsSelector.dsCreateCheck).then(($el) => {
|
||||
if ($el.is(":checked")) {
|
||||
cy.get(eeGroupsSelector.dsCreateCheck).uncheck();
|
||||
}
|
||||
});
|
||||
cy.get(eeGroupsSelector.dsDeleteCheck).then(($el) => {
|
||||
if ($el.is(":checked")) {
|
||||
cy.get(eeGroupsSelector.dsDeleteCheck).uncheck();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteAssignedDatasources = () => {
|
||||
common.navigateToManageGroups();
|
||||
cy.get('[data-cy="datasource-link"]').click();
|
||||
cy.get("body").then(($body) => {
|
||||
const removeAllButtons = $body.find('[data-cy="remove-button"]');
|
||||
if (removeAllButtons.length > 0) {
|
||||
cy.get('[data-cy="remove-button"]').click({ multiple: true });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const userSignUp = (fullName, email, workspaceName) => {
|
||||
const verificationFunction =
|
||||
Cypress.env("environment") === "Enterprise"
|
||||
? verifyOnboardingQuestions
|
||||
: verifyCloudOnboardingQuestions;
|
||||
|
||||
let invitationLink = "";
|
||||
cy.visit("/");
|
||||
cy.wait(500);
|
||||
cy.get(commonSelectors.createAnAccountLink).realClick();
|
||||
cy.clearAndType(commonSelectors.nameInputField, fullName);
|
||||
cy.clearAndType(commonSelectors.emailInputField, email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
|
||||
cy.wait(500);
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select invitation_token from users where email='${email}';`,
|
||||
}).then((resp) => {
|
||||
invitationLink = `/invitations/${resp.rows[0].invitation_token}`;
|
||||
cy.visit(invitationLink);
|
||||
cy.get(commonSelectors.setUpToolJetButton).click();
|
||||
cy.wait(4000);
|
||||
|
||||
verificationFunction(fullName, workspaceName);
|
||||
});
|
||||
};
|
||||
|
||||
export const allowPersonalWorkspace = (allow = true) => {
|
||||
const value = allow ? "true" : "false";
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `UPDATE instance_settings SET value = '${value}' WHERE key = 'ALLOW_PERSONAL_WORKSPACE';`,
|
||||
});
|
||||
};
|
||||
|
||||
export const addNewUserEE = (firstName, email) => {
|
||||
common.navigateToManageUsers();
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get(commonSelectors.inputFieldFullName).type(firstName);
|
||||
cy.get(commonSelectors.inputFieldEmailAddress).type(email);
|
||||
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
usersText.userCreatedToast
|
||||
);
|
||||
WorkspaceInvitationLink(email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, usersText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait(2000);
|
||||
cy.get(commonSelectors.acceptInviteButton).click();
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
"have.text",
|
||||
"My workspace"
|
||||
);
|
||||
};
|
||||
|
||||
export const inviteUser = (firstName, email) => {
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get(commonSelectors.inputFieldFullName).type(firstName);
|
||||
cy.get(commonSelectors.inputFieldEmailAddress).type(email);
|
||||
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
usersText.userCreatedToast
|
||||
);
|
||||
fetchAndVisitInviteLink(email);
|
||||
};
|
||||
|
||||
export const defaultWorkspace = () => {
|
||||
cy.get(".org-select-container").then(($title) => {
|
||||
if (!$title.text().includes("My workspace")) {
|
||||
cy.get(commonSelectors.workspaceName).realClick();
|
||||
cy.contains("My workspace").realClick();
|
||||
cy.wait(2000);
|
||||
defaultWorkspace();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const trunOffAllowPersonalWorkspace = () => {
|
||||
cy.get(commonSelectors.settingsIcon).click();
|
||||
cy.get(commonEeSelectors.instanceSettingIcon).click();
|
||||
cy.get(instanceSettingsSelector.manageInstanceSettings).click();
|
||||
cy.get(instanceSettingsSelector.allowWorkspaceToggle)
|
||||
.eq(0)
|
||||
.then(($el) => {
|
||||
if ($el.is(":checked")) {
|
||||
cy.get(instanceSettingsSelector.allowWorkspaceToggle).eq(0).uncheck();
|
||||
cy.get(commonEeSelectors.saveButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"Instance settings have been updated"
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const verifySSOSignUpPageElements = () => {
|
||||
cy.get(commonSelectors.invitePageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Join ToolJet"
|
||||
);
|
||||
cy.get(commonSelectors.invitePageSubHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"You are invited to ToolJet."
|
||||
);
|
||||
cy.get(commonSelectors.userNameInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.userNameInputLabel
|
||||
);
|
||||
cy.get(commonSelectors.invitedUserName).should("be.visible");
|
||||
cy.get(commonSelectors.emailInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailInputLabel
|
||||
);
|
||||
cy.get(commonSelectors.invitedUserEmail).should("be.visible");
|
||||
cy.get(commonSelectors.acceptInviteButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.acceptInviteButton
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.signUpTermsHelperText).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
commonText.signUpTermsHelperText
|
||||
);
|
||||
});
|
||||
cy.get(commonSelectors.termsOfServiceLink)
|
||||
.verifyVisibleElement("have.text", commonText.termsOfServiceLink)
|
||||
.and("have.attr", "href")
|
||||
.and("equal", "https://www.tooljet.com/terms");
|
||||
cy.get(commonSelectors.privacyPolicyLink)
|
||||
.verifyVisibleElement("have.text", commonText.privacyPolicyLink)
|
||||
.and("have.attr", "href")
|
||||
.and("equal", "https://www.tooljet.com/privacy");
|
||||
};
|
||||
|
||||
export const VerifyWorkspaceInvitePageElements = () => {
|
||||
cy.get(commonSelectors.invitePageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.invitePageHeader
|
||||
);
|
||||
cy.get(commonSelectors.invitePageSubHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.invitePageSubHeader
|
||||
);
|
||||
cy.verifyLabel(commonText.userNameInputLabel);
|
||||
cy.get(commonSelectors.invitedUserName).should("be.visible");
|
||||
cy.verifyLabel(commonText.emailInputLabel);
|
||||
cy.get(commonSelectors.invitedUserEmail).should("be.visible");
|
||||
cy.get(commonSelectors.acceptInviteButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.acceptInviteButton
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.signUpTermsHelperText).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
commonText.signUpTermsHelperText
|
||||
);
|
||||
});
|
||||
cy.get(commonSelectors.termsOfServiceLink)
|
||||
.verifyVisibleElement("have.text", commonText.termsOfServiceLink)
|
||||
.and("have.attr", "href")
|
||||
.and("equal", "https://www.tooljet.com/terms");
|
||||
cy.get(commonSelectors.privacyPolicyLink)
|
||||
.verifyVisibleElement("have.text", commonText.privacyPolicyLink)
|
||||
.and("have.attr", "href")
|
||||
.and("equal", "https://www.tooljet.com/privacy");
|
||||
|
||||
cy.get("body").then(($el) => {
|
||||
if ($el.text().includes("Google")) {
|
||||
cy.get(ssoSelector.googleSSOText).verifyVisibleElement(
|
||||
"have.text",
|
||||
ssoText.googleSignUpText
|
||||
);
|
||||
cy.get(ssoSelector.gitSSOText).verifyVisibleElement(
|
||||
"have.text",
|
||||
ssoText.gitSignUpText
|
||||
);
|
||||
cy.get(commonSelectors.onboardingSeperator).should("be.visible");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const WorkspaceInvitationLink = (email) => {
|
||||
let invitationToken,
|
||||
organizationToken,
|
||||
workspaceId,
|
||||
userId,
|
||||
url = "";
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select invitation_token from users where email='${email}';`,
|
||||
}).then((resp) => {
|
||||
invitationToken = resp.rows[0].invitation_token;
|
||||
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: "select id from organizations where name='My workspace';",
|
||||
}).then((resp) => {
|
||||
workspaceId = resp.rows[0].id;
|
||||
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select id from users where email='${email}';`,
|
||||
}).then((resp) => {
|
||||
userId = resp.rows[0].id;
|
||||
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select invitation_token from organization_users where user_id='${userId}';`,
|
||||
}).then((resp) => {
|
||||
organizationToken = resp.rows[0].invitation_token;
|
||||
|
||||
url = `/invitations/${invitationToken}/workspaces/${organizationToken}?oid=${workspaceId}`;
|
||||
common.logout();
|
||||
cy.visit(url);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const enableDefaultSSO = () => {
|
||||
common.navigateToManageSSO();
|
||||
cy.get("body").then(($el) => {
|
||||
if (!$el.text().includes("Allowed domains")) {
|
||||
cy.get(ssoSelector.generalSettingsElements.generalSettings).click();
|
||||
}
|
||||
});
|
||||
cy.get(ssoSelector.allowDefaultSSOToggle).then(($el) => {
|
||||
if (!$el.is(":checked")) {
|
||||
cy.get(ssoSelector.allowDefaultSSOToggle).check();
|
||||
cy.get(ssoSelector.saveButton).click();
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, ssoText.ssoToast);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const disableSSO = (ssoSelector, toggleSelector) => {
|
||||
cy.wait(1000);
|
||||
cy.get(ssoSelector).click();
|
||||
cy.get(toggleSelector).then(($el) => {
|
||||
if ($el.is(":checked")) {
|
||||
cy.get(toggleSelector).uncheck();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const AddDataSourceToGroup = (groupName, dsName) => {
|
||||
common.navigateToManageGroups();
|
||||
cy.get(groupsSelector.groupLink(groupName)).click();
|
||||
cy.get(eeGroupsSelector.datasourceLink).click();
|
||||
cy.wait(500);
|
||||
cy.get(
|
||||
'[data-cy="datasource-select-search"] >> .rmsc > .dropdown-container > .dropdown-heading > .dropdown-heading-value > .gray'
|
||||
).click();
|
||||
cy.contains(dsName).realClick();
|
||||
|
||||
cy.get(eeGroupsSelector.AddDsButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"Datasources added to the group"
|
||||
);
|
||||
};
|
||||
|
||||
export const enableToggle = (toggleSelector) => {
|
||||
cy.get(toggleSelector).then(($el) => {
|
||||
if (!$el.is(":checked")) {
|
||||
cy.get(toggleSelector).check();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const disableToggle = (toggleSelector) => {
|
||||
cy.get(toggleSelector).then(($el) => {
|
||||
if ($el.is(":checked")) {
|
||||
cy.get(toggleSelector).uncheck();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const verifyPromoteModalUI = (versionName, currEnv, targetEnv) => {
|
||||
cy.get(commonEeSelectors.promoteButton)
|
||||
.verifyVisibleElement("have.text", " Promote ")
|
||||
.click();
|
||||
cy.get(commonEeSelectors.modalTitle).verifyVisibleElement(
|
||||
"have.text",
|
||||
`Promote ${versionName}`
|
||||
);
|
||||
cy.get(commonSelectors.closeButton).should("be.visible");
|
||||
cy.get(multiEnvSelector.fromLabel).verifyVisibleElement("have.text", "FROM");
|
||||
cy.get(multiEnvSelector.toLabel).verifyVisibleElement("have.text", "TO");
|
||||
cy.get(multiEnvSelector.currEnvName).verifyVisibleElement(
|
||||
"have.text",
|
||||
currEnv
|
||||
);
|
||||
cy.get('[data-cy="target-env-name"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
targetEnv
|
||||
);
|
||||
cy.get('[data-cy="cancel-button"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Cancel"
|
||||
);
|
||||
cy.get(commonEeSelectors.promoteButton)
|
||||
.eq(1)
|
||||
.verifyVisibleElement("have.text", "Promote ");
|
||||
};
|
||||
|
||||
export const resetPassword = (email) => {
|
||||
cy.visit("/");
|
||||
cy.get(commonSelectors.forgotPasswordLink).click();
|
||||
cy.clearAndType(commonSelectors.emailInputField, email);
|
||||
cy.get(commonSelectors.resetPasswordLinkButton).click();
|
||||
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select forgot_password_token from users where email='${email}';`,
|
||||
}).then((resp) => {
|
||||
const passwordResetLink = `/reset-password/${resp.rows[0].forgot_password_token}`;
|
||||
cy.visit(passwordResetLink);
|
||||
});
|
||||
cy.wait(500);
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "Password");
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "Password");
|
||||
cy.wait(4000);
|
||||
cy.get(commonSelectors.resetPasswordButton).click();
|
||||
cy.get(commonSelectors.backToLoginButton).click();
|
||||
};
|
||||
|
||||
export const verifyTooltipDisabled = (selector, message) => {
|
||||
cy.get(selector)
|
||||
.trigger("mouseover", { force: true })
|
||||
.then(() => {
|
||||
cy.get(".tooltip-inner").last().should("have.text", message);
|
||||
});
|
||||
};
|
||||
|
||||
export const createAnAppWithSlug = (appName, slug) => {
|
||||
cy.apiCreateApp(appName);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Table", 250, 250);
|
||||
appPromote("development", "release");
|
||||
cy.get(commonWidgetSelector.shareAppButton).click();
|
||||
cy.clearAndType(commonWidgetSelector.appNameSlugInput, `${slug}`);
|
||||
cy.wait(2000);
|
||||
cy.get(commonWidgetSelector.modalCloseButton).click();
|
||||
};
|
||||
|
||||
export const updateLicense = (key) => {
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `update instance_settings set value='${key}', updated_at= NOW() where key='LICENSE_KEY';`,
|
||||
});
|
||||
};
|
||||
|
||||
export const openInstanceSettings = () => {
|
||||
cy.get(commonSelectors.settingsIcon).click();
|
||||
cy.get(commonEeSelectors.instanceSettingIcon).click();
|
||||
};
|
||||
|
||||
export const openUserActionMenu = (email) => {
|
||||
cy.clearAndType(commonSelectors.inputUserSearch, email);
|
||||
cy.wait(1000);
|
||||
cy.get('[data-cy="user-actions-button"]').eq(0).click();
|
||||
cy.wait(2000);
|
||||
};
|
||||
|
||||
export const archiveWorkspace = (workspaceName) => {
|
||||
cy.get(instanceSettingsSelector.allWorkspaceTab).click();
|
||||
cy.clearAndType(commonEeSelectors.searchBar, workspaceName);
|
||||
cy.get(workspaceSelector.workspaceStatusChange).eq(0).click();
|
||||
cy.get(commonEeSelectors.confirmButton).click();
|
||||
};
|
||||
|
||||
export const passwordToggle = (enable) => {
|
||||
cy.getCookie("tj_auth_token").then((cookie) => {
|
||||
cy.request(
|
||||
{
|
||||
method: "PATCH",
|
||||
url: "http://localhost:3000/api/organizations/configs",
|
||||
headers: {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token=${cookie.value}`,
|
||||
},
|
||||
body: { type: "form", enabled: enable },
|
||||
},
|
||||
{ log: false }
|
||||
).then((response) => {
|
||||
expect(response.status).to.equal(200);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const InstanceSSO = (personalWorkspace, enableSignup, workspaceSSO) => {
|
||||
allowPersonalWorkspace(personalWorkspace);
|
||||
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `UPDATE instance_settings SET value = '${enableSignup}' WHERE key = 'ENABLE_SIGNUP';UPDATE instance_settings SET value = '${workspaceSSO}' WHERE key = 'ENABLE_WORKSPACE_LOGIN_CONFIGURATION';`,
|
||||
});
|
||||
};
|
||||
|
||||
export const resetInstanceDomain = () => {
|
||||
cy.getCookie("tj_auth_token").then((cookie) => {
|
||||
cy.request(
|
||||
{
|
||||
method: "PATCH",
|
||||
url: "http://localhost:3000/api/instance-login-configs",
|
||||
headers: {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token=${cookie.value}`,
|
||||
},
|
||||
body: { allowedDomains: "" },
|
||||
},
|
||||
{ log: false }
|
||||
).then((response) => {
|
||||
expect(response.status).to.equal(200);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const instanceSSOConfig = (allow = true) => {
|
||||
const value = allow ? "true" : "false";
|
||||
|
||||
cy.task("dbConnection", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `UPDATE sso_configs SET enabled = ${allow} WHERE sso IN ('google', 'git', 'openid')AND organization_id IS NULL;`,
|
||||
});
|
||||
};
|
||||
|
||||
export const updateInstanceSettings = (key, value) => {
|
||||
cy.task("updateSetting", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `UPDATE instance_settings SET value = ${value} WHERE key = ${key};`,
|
||||
});
|
||||
};
|
||||
|
|
@ -122,10 +122,11 @@ export const createAndRunRestAPIQuery = ({
|
|||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
responseData.forEach((item) => {
|
||||
expect(item).to.have.any.keys("id", "name", "price");
|
||||
expect(item).to.have.any.keys("id", "name", "username", "email", "address");
|
||||
});
|
||||
}
|
||||
if (responseData?.id) {
|
||||
cy.log(responseData.id)
|
||||
cy.writeFile("cypress/fixtures/restAPI/storedId.json", {
|
||||
id: responseData.id,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ sudo apt-get -y install --no-install-recommends wget gnupg ca-certificates apt-u
|
|||
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
nvm install 18.18.2
|
||||
nvm install 22.15.1
|
||||
sudo ln -s "$(which node)" /usr/bin/node
|
||||
sudo ln -s "$(which npm)" /usr/bin/npm
|
||||
|
||||
sudo npm i -g npm@10.9.2
|
||||
|
||||
# Setup openresty
|
||||
wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
|
||||
echo "deb http://openresty.org/package/ubuntu bionic main" > openresty.list
|
||||
|
|
@ -56,10 +58,10 @@ envsubst "${VARS_TO_SUBSTITUTE}" < /tmp/nginx.conf > /tmp/nginx-substituted.conf
|
|||
sudo cp /tmp/nginx-substituted.conf /usr/local/openresty/nginx/conf/nginx.conf
|
||||
|
||||
# Download and setup postgrest binary
|
||||
curl -OL https://github.com/PostgREST/postgrest/releases/download/v10.1.1/postgrest-v10.1.1-linux-static-x64.tar.xz
|
||||
tar xJf postgrest-v10.1.1-linux-static-x64.tar.xz
|
||||
curl -OL https://github.com/PostgREST/postgrest/releases/download/v12.2.0/postgrest-v12.2.0-linux-static-x64.tar.xz
|
||||
tar xJf postgrest-v12.2.0-linux-static-x64.tar.xz
|
||||
sudo mv ./postgrest /bin/postgrest
|
||||
sudo rm postgrest-v10.1.1-linux-static-x64.tar.xz
|
||||
sudo rm postgrest-v12.2.0-linux-static-x64.tar.xz
|
||||
|
||||
# Setup app and postgrest as systemd service
|
||||
sudo cp /tmp/nest.service /lib/systemd/system/nest.service
|
||||
|
|
@ -74,7 +76,7 @@ mv /tmp/.env ~/app/.env
|
|||
mv /tmp/setup_app ~/app/setup_app
|
||||
sudo chmod +x ~/app/setup_app
|
||||
|
||||
npm install -g npm@9.8.1
|
||||
npm install -g npm@10.9.2
|
||||
|
||||
# Building ToolJet app
|
||||
npm install -g @nestjs/cli
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ sudo apt-get -y install --no-install-recommends wget gnupg ca-certificates apt-u
|
|||
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
nvm install 18.18.2
|
||||
nvm install 22.15.1
|
||||
sudo ln -s "$(which node)" /usr/bin/node
|
||||
sudo ln -s "$(which npm)" /usr/bin/npm
|
||||
|
||||
sudo npm i -g npm@9.8.1
|
||||
sudo npm i -g npm@10.9.2
|
||||
|
||||
# Setup openresty
|
||||
wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
|
||||
|
|
@ -58,10 +58,10 @@ envsubst "${VARS_TO_SUBSTITUTE}" < /tmp/nginx.conf > /tmp/nginx-substituted.conf
|
|||
sudo cp /tmp/nginx-substituted.conf /usr/local/openresty/nginx/conf/nginx.conf
|
||||
|
||||
# Download and setup postgrest binary
|
||||
curl -OL https://github.com/PostgREST/postgrest/releases/download/v12.0.2/postgrest-v12.0.2-linux-static-x64.tar.xz
|
||||
tar xJf postgrest-v12.0.2-linux-static-x64.tar.xz
|
||||
curl -OL https://github.com/PostgREST/postgrest/releases/download/v12.2.0/postgrest-v12.2.0-linux-static-x64.tar.xz
|
||||
tar xJf postgrest-v12.2.0-linux-static-x64.tar.xz
|
||||
sudo mv ./postgrest /bin/postgrest
|
||||
sudo rm postgrest-v12.0.2-linux-static-x64.tar.xz
|
||||
sudo rm postgrest-v12.2.0-linux-static-x64.tar.xz
|
||||
|
||||
# Add the Redis APT repository
|
||||
sudo add-apt-repository ppa:redislabs/redis -y
|
||||
|
|
@ -92,7 +92,7 @@ mv /tmp/.env ~/app/.env
|
|||
mv /tmp/setup_app ~/app/setup_app
|
||||
sudo chmod +x ~/app/setup_app
|
||||
|
||||
npm install -g npm@9.8.1
|
||||
npm install -g npm@10.9.2
|
||||
|
||||
# Building ToolJet app
|
||||
npm install -g @nestjs/cli
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:18.18.2-buster AS builder
|
||||
FROM node:22.15.1 AS builder
|
||||
# Fix for JS heap limit allocation issue
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
|
|
@ -30,9 +30,10 @@ COPY ./server/package.json ./server/package-lock.json ./server/
|
|||
RUN npm --prefix server install
|
||||
COPY ./server/ ./server/
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm install -g copyfiles
|
||||
RUN npm --prefix server run build
|
||||
|
||||
FROM node:18.18.2-bullseye
|
||||
FROM node:22.15.1-bullseye
|
||||
# copy postgrest executable
|
||||
COPY --from=postgrest/postgrest:v12.2.0 /bin/postgrest /bin
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
FROM node:18.18.2-buster AS builder
|
||||
FROM node:22.15.1 AS builder
|
||||
|
||||
# Fix for JS heap limit allocation issue
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
ENV NODE_OPTIONS="--max-old-space-size=8096"
|
||||
|
||||
RUN npm i -g npm@9.8.1
|
||||
RUN npm i -g npm@10.9.2
|
||||
RUN mkdir -p /app
|
||||
|
||||
WORKDIR /app
|
||||
|
|
@ -31,10 +31,11 @@ ENV NODE_ENV=production
|
|||
COPY ./server/package.json ./server/package-lock.json ./server/
|
||||
RUN npm --prefix server install
|
||||
COPY ./server/ ./server/
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm install -g copyfiles
|
||||
RUN npm --prefix server run build
|
||||
|
||||
FROM debian:11
|
||||
FROM debian:12
|
||||
|
||||
RUN apt-get update -yq \
|
||||
&& apt-get install curl gnupg zip -yq \
|
||||
|
|
@ -42,12 +43,12 @@ RUN apt-get update -yq \
|
|||
&& apt-get clean -y
|
||||
|
||||
|
||||
RUN curl -O https://nodejs.org/dist/v18.18.2/node-v18.18.2-linux-x64.tar.xz \
|
||||
&& tar -xf node-v18.18.2-linux-x64.tar.xz \
|
||||
&& mv node-v18.18.2-linux-x64 /usr/local/lib/nodejs \
|
||||
RUN curl -O https://nodejs.org/dist/v22.15.1/node-v22.15.1-linux-x64.tar.xz \
|
||||
&& tar -xf node-v22.15.1-linux-x64.tar.xz \
|
||||
&& mv node-v22.15.1-linux-x64 /usr/local/lib/nodejs \
|
||||
&& echo 'export PATH="/usr/local/lib/nodejs/bin:$PATH"' >> /etc/profile.d/nodejs.sh \
|
||||
&& /bin/bash -c "source /etc/profile.d/nodejs.sh" \
|
||||
&& rm node-v18.18.2-linux-x64.tar.xz
|
||||
&& rm node-v22.15.1-linux-x64.tar.xz
|
||||
ENV PATH=/usr/local/lib/nodejs/bin:$PATH
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
|
|
|||
31
docker/cloud/cloud-entrypoint.sh
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
npm cache clean --force
|
||||
|
||||
if [ -d "./server/dist" ]; then
|
||||
SETUP_CMD='npm run cloud:setup:prod'
|
||||
else
|
||||
SETUP_CMD='npm run cloud:setup'
|
||||
fi
|
||||
|
||||
npm cache clean --force
|
||||
|
||||
if [ -f "./.env" ]; then
|
||||
declare $(grep -v '^#' ./.env | xargs)
|
||||
fi
|
||||
|
||||
if [ -z "$DATABASE_URL" ]; then
|
||||
./server/scripts/wait-for-it.sh $PG_HOST:${PG_PORT:-5432} --strict --timeout=300 -- $SETUP_CMD
|
||||
else
|
||||
PG_HOST=$(echo "$DATABASE_URL" | awk -F'[/:@?]' '{print $6}')
|
||||
PG_PORT=$(echo "$DATABASE_URL" | awk -F'[/:@?]' '{print $7}')
|
||||
|
||||
if [ -z "$DATABASE_PORT" ]; then
|
||||
DATABASE_PORT="5432"
|
||||
fi
|
||||
|
||||
./server/scripts/wait-for-it.sh "$PG_HOST:$PG_PORT" --strict --timeout=300 -- $SETUP_CMD
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
121
docker/cloud/cloud-production.Dockerfile
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
FROM node:18.18.2-buster AS builder
|
||||
|
||||
# Fix for JS heap limit allocation issue
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
RUN npm i -g npm@9.8.1
|
||||
RUN mkdir -p /app
|
||||
# RUN npm cache clean --force
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Scripts for building
|
||||
COPY ./package.json ./package.json
|
||||
|
||||
# Build plugins
|
||||
COPY ./plugins/package.json ./plugins/package-lock.json ./plugins/
|
||||
RUN npm --prefix plugins install
|
||||
COPY ./plugins/ ./plugins/
|
||||
RUN NODE_ENV=production npm --prefix plugins run build
|
||||
RUN npm --prefix plugins prune --production
|
||||
|
||||
# Build frontend
|
||||
COPY ./frontend/package.json ./frontend/package-lock.json ./frontend/
|
||||
RUN npm --prefix frontend install
|
||||
COPY ./frontend/ ./frontend/
|
||||
RUN npm --prefix frontend run build --production
|
||||
RUN npm --prefix frontend prune --production
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# Build server
|
||||
COPY ./server/package.json ./server/package-lock.json ./server/
|
||||
RUN npm --prefix server install
|
||||
COPY ./server/ ./server/
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm --prefix server run build
|
||||
|
||||
FROM debian:11
|
||||
|
||||
RUN apt-get update -yq \
|
||||
&& apt-get install curl gnupg zip -yq \
|
||||
&& apt-get install -yq build-essential \
|
||||
&& apt-get clean -y
|
||||
|
||||
|
||||
RUN curl -O https://nodejs.org/dist/v18.18.2/node-v18.18.2-linux-x64.tar.xz \
|
||||
&& tar -xf node-v18.18.2-linux-x64.tar.xz \
|
||||
&& mv node-v18.18.2-linux-x64 /usr/local/lib/nodejs \
|
||||
&& echo 'export PATH="/usr/local/lib/nodejs/bin:$PATH"' >> /etc/profile.d/nodejs.sh \
|
||||
&& /bin/bash -c "source /etc/profile.d/nodejs.sh" \
|
||||
&& rm node-v18.18.2-linux-x64.tar.xz
|
||||
ENV PATH=/usr/local/lib/nodejs/bin:$PATH
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
RUN apt-get update && \
|
||||
apt-get install -y postgresql-client freetds-dev libaio1 wget && \
|
||||
apt-get -o Dpkg::Options::="--force-confold" upgrade -q -y --force-yes && \
|
||||
apt-get -y autoremove && \
|
||||
apt-get -y autoclean
|
||||
|
||||
# Install Instantclient Basic Light Oracle and Dependencies
|
||||
WORKDIR /opt/oracle
|
||||
|
||||
RUN wget https://tooljet-plugins-production.s3.us-east-2.amazonaws.com/marketplace-assets/oracledb/instantclients/instantclient-basiclite-linuxx64.zip && \
|
||||
wget https://tooljet-plugins-production.s3.us-east-2.amazonaws.com/marketplace-assets/oracledb/instantclients/instantclient-basiclite-linux.x64-11.2.0.4.0.zip && \
|
||||
unzip instantclient-basiclite-linuxx64.zip && rm -f instantclient-basiclite-linuxx64.zip && \
|
||||
unzip instantclient-basiclite-linux.x64-11.2.0.4.0.zip && rm -f instantclient-basiclite-linux.x64-11.2.0.4.0.zip && \
|
||||
cd /opt/oracle/instantclient_21_10 && rm -f *jdbc* *occi* *mysql* *mql1* *ipc1* *jar uidrvci genezi adrci && \
|
||||
cd /opt/oracle/instantclient_11_2 && rm -f *jdbc* *occi* *mysql* *mql1* *ipc1* *jar uidrvci genezi adrci && \
|
||||
echo /opt/oracle/instantclient* > /etc/ld.so.conf.d/oracle-instantclient.conf && ldconfig
|
||||
# Set the Instant Client library paths
|
||||
ENV LD_LIBRARY_PATH="/opt/oracle/instantclient_11_2:/opt/oracle/instantclient_21_10:${LD_LIBRARY_PATH}"
|
||||
|
||||
|
||||
WORKDIR /
|
||||
|
||||
RUN mkdir -p /app
|
||||
|
||||
# copy npm scripts
|
||||
COPY --from=builder /app/package.json ./app/package.json
|
||||
|
||||
# copy plugins dependencies
|
||||
COPY --from=builder /app/plugins/dist ./app/plugins/dist
|
||||
COPY --from=builder /app/plugins/client.js ./app/plugins/client.js
|
||||
COPY --from=builder /app/plugins/node_modules ./app/plugins/node_modules
|
||||
COPY --from=builder /app/plugins/packages/common ./app/plugins/packages/common
|
||||
COPY --from=builder /app/plugins/package.json ./app/plugins/package.json
|
||||
|
||||
# copy server build
|
||||
COPY --from=builder /app/server/package.json ./app/server/package.json
|
||||
COPY --from=builder /app/server/.version ./app/server/.version
|
||||
COPY --from=builder /app/server/node_modules ./app/server/node_modules
|
||||
COPY --from=builder /app/server/templates ./app/server/templates
|
||||
COPY --from=builder /app/server/scripts ./app/server/scripts
|
||||
COPY --from=builder /app/server/dist ./app/server/dist
|
||||
|
||||
COPY ./docker/cloud/cloud-entrypoint.sh ./app/server/cloud-entrypoint.sh
|
||||
|
||||
# Define non-sudo user
|
||||
RUN useradd --create-home --home-dir /home/appuser appuser \
|
||||
&& chown -R appuser:0 /app \
|
||||
&& chown -R appuser:0 /home/appuser \
|
||||
&& chmod u+x /app \
|
||||
&& chmod -R g=u /app
|
||||
|
||||
# Set npm cache directory
|
||||
ENV npm_config_cache /home/appuser/.npm
|
||||
|
||||
ENV HOME=/home/appuser
|
||||
|
||||
# Installing git for simple git commands
|
||||
RUN apt-get update && apt-get install -y git && apt-get clean
|
||||
|
||||
USER appuser
|
||||
|
||||
WORKDIR /app
|
||||
# Dependencies for scripts outside nestjs
|
||||
RUN npm install dotenv@10.0.0 joi@17.4.1
|
||||
|
||||
ENTRYPOINT ["./server/cloud-entrypoint.sh"]
|
||||
|
|
@ -91,12 +91,13 @@ COPY --from=builder /app/plugins/package.json ./app/plugins/package.json
|
|||
# copy server build
|
||||
COPY --from=builder /app/server/package.json ./app/server/package.json
|
||||
COPY --from=builder /app/server/.version ./app/server/.version
|
||||
COPY --from=builder /app/server/entrypoint.sh ./app/server/entrypoint.sh
|
||||
COPY --from=builder /app/server/node_modules ./app/server/node_modules
|
||||
COPY --from=builder /app/server/templates ./app/server/templates
|
||||
COPY --from=builder /app/server/scripts ./app/server/scripts
|
||||
COPY --from=builder /app/server/dist ./app/server/dist
|
||||
|
||||
COPY ./docker/cloud/cloud-entrypoint.sh ./app/server/cloud-entrypoint.sh
|
||||
|
||||
# Define non-sudo user
|
||||
RUN useradd --create-home --home-dir /home/appuser appuser \
|
||||
&& chown -R appuser:0 /app \
|
||||
|
|
@ -108,10 +109,14 @@ RUN useradd --create-home --home-dir /home/appuser appuser \
|
|||
ENV npm_config_cache /home/appuser/.npm
|
||||
|
||||
ENV HOME=/home/appuser
|
||||
|
||||
# Installing git for simple git commands
|
||||
RUN apt-get update && apt-get install -y git && apt-get clean
|
||||
|
||||
USER appuser
|
||||
|
||||
WORKDIR /app
|
||||
# Dependencies for scripts outside nestjs
|
||||
RUN npm install dotenv@10.0.0 joi@17.4.1
|
||||
|
||||
ENTRYPOINT ["./server/entrypoint.sh"]
|
||||
ENTRYPOINT ["./server/cloud-entrypoint.sh"]
|
||||
|
|
|
|||
|
|
@ -42,6 +42,115 @@ else
|
|||
echo "Using external PostgREST at $PGRST_HOST."
|
||||
fi
|
||||
|
||||
# Neo4j configuration
|
||||
# ----------------------------------
|
||||
# Default Neo4j environment values
|
||||
# ----------------------------------
|
||||
export NEO4J_USER=${NEO4J_USER:-"neo4j"}
|
||||
export NEO4J_PASSWORD=${NEO4J_PASSWORD:-"appaqvyvRLbeukhFE"}
|
||||
export NEO4J_AUTH=${NEO4J_AUTH:-"neo4j/appaqvyvRLbeukhFE"}
|
||||
export NEO4J_URI=${NEO4J_URI:-"bolt://localhost:7687"}
|
||||
export NEO4J_PLUGINS=${NEO4J_PLUGINS:-'["apoc"]'}
|
||||
export NEO4J_AUTH
|
||||
|
||||
# Extract username and password from NEO4J_AUTH if set
|
||||
if [ -n "$NEO4J_AUTH" ]; then
|
||||
# Extract username and password from NEO4J_AUTH (format: username/password)
|
||||
NEO4J_USERNAME=$(echo "$NEO4J_AUTH" | cut -d'/' -f1)
|
||||
NEO4J_PASSWORD=$(echo "$NEO4J_AUTH" | cut -d'/' -f2)
|
||||
|
||||
# Export these for application use
|
||||
export NEO4J_USERNAME
|
||||
export NEO4J_PASSWORD
|
||||
|
||||
echo "Neo4j authentication configured with username: $NEO4J_USERNAME"
|
||||
else
|
||||
echo "NEO4J_AUTH not set, using default authentication"
|
||||
fi
|
||||
|
||||
# Check if Neo4j is already initialized and set password if necessary
|
||||
if [ "$NEO4J_AUTH" != "none" ] && [ -n "$NEO4J_PASSWORD" ]; then
|
||||
echo "Setting Neo4j initial password..."
|
||||
|
||||
# Ensure Neo4j is not running before setting the initial password
|
||||
neo4j stop || true
|
||||
|
||||
# Set the initial password using the correct command format for Neo4j 5.x
|
||||
NEO4J_ADMIN_CMD=$(which neo4j-admin)
|
||||
NEO4J_VERSION=$(neo4j --version | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+" | head -n 1)
|
||||
echo "Detected Neo4j version: $NEO4J_VERSION"
|
||||
|
||||
# Use version-specific command format
|
||||
MAJOR_VERSION=$(echo $NEO4J_VERSION | cut -d. -f1)
|
||||
if [ "$MAJOR_VERSION" -ge "5" ]; then
|
||||
# For Neo4j 5.x and higher
|
||||
echo "Using Neo4j 5.x+ password command format"
|
||||
$NEO4J_ADMIN_CMD dbms set-initial-password "$NEO4J_PASSWORD" --require-password-change=false >/dev/null 2>&1 || {
|
||||
echo "Warning: Could not set Neo4j password, it may already be set"
|
||||
}
|
||||
else
|
||||
# For Neo4j 4.x and lower
|
||||
echo "Using Neo4j 4.x password command format" >/dev/null 2>&1
|
||||
$NEO4J_ADMIN_CMD set-initial-password "$NEO4J_PASSWORD" >/dev/null 2>&1 || {
|
||||
echo "Warning: Could not set Neo4j password, it may already be set"
|
||||
}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update Neo4j configuration
|
||||
echo "Configuring Neo4j..."
|
||||
cat > /etc/neo4j/neo4j.conf << EOF
|
||||
# Neo4j configuration
|
||||
dbms.security.auth_enabled=true
|
||||
server.bolt.enabled=true
|
||||
server.bolt.listen_address=0.0.0.0:7687
|
||||
server.directories.data=/var/lib/neo4j/data
|
||||
server.directories.logs=/var/log/neo4j
|
||||
initial.dbms.default_database=neo4j
|
||||
server.directories.plugins=/var/lib/neo4j/plugins
|
||||
server.directories.import=/var/lib/neo4j/import
|
||||
|
||||
# APOC Settings
|
||||
dbms.security.procedures.unrestricted=apoc.*
|
||||
dbms.security.procedures.allowlist=apoc.*,algo.*,gds.*
|
||||
EOF
|
||||
|
||||
if [ -w "$NEO4J_LOG_DIR" ]; then
|
||||
chmod -R 770 "$NEO4J_LOG_DIR" || echo "Warning: Could not set log directory permissions" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Start Neo4j
|
||||
echo "Starting Neo4j service..."
|
||||
neo4j console >/dev/null 2>&1 &
|
||||
|
||||
# Add a wait for Neo4j to be ready with more robust checking
|
||||
echo "Waiting for Neo4j to be ready..."
|
||||
NEO4J_READY=false
|
||||
for i in {1..60}; do
|
||||
# First try standard status check
|
||||
if neo4j status >/dev/null 2>&1; then
|
||||
echo "Neo4j is ready (via status check)"
|
||||
NEO4J_READY=true
|
||||
break
|
||||
fi
|
||||
|
||||
# Also try connecting to the bolt port as a fallback
|
||||
if command -v nc >/dev/null 2>&1; then
|
||||
if nc -z localhost 7687 >/dev/null 2>&1; then
|
||||
echo "Neo4j is ready (port 7687 is open)"
|
||||
NEO4J_READY=true
|
||||
break
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Waiting for Neo4j to start... ($i/60)"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ "$NEO4J_READY" = false ]; then
|
||||
echo "WARNING: Neo4j may not be fully started yet, but continuing..."
|
||||
fi
|
||||
|
||||
# Check WORKLOW_WORKER and skip SETUP_CMD if true
|
||||
if [ "${WORKFLOW_WORKER}" == "true" ]; then
|
||||
echo "WORKFLOW_WORKER is set to true. Running worker process."
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:18.18.2-buster AS builder
|
||||
FROM node:22.15.1 AS builder
|
||||
# Fix for JS heap limit allocation issue
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
|
|
@ -50,10 +50,11 @@ ENV TOOLJET_EDITION=ee
|
|||
COPY ./server/package.json ./server/package-lock.json ./server/
|
||||
RUN npm --prefix server install
|
||||
COPY ./server/ ./server/
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm install -g copyfiles
|
||||
RUN npm --prefix server run build
|
||||
|
||||
FROM node:18.18.2-bullseye
|
||||
FROM node:22.15.1-bullseye
|
||||
|
||||
RUN apt-get update -yq \
|
||||
&& apt-get install curl gnupg zip -yq \
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
FROM node:18.18.2-buster AS builder
|
||||
FROM node:22.15.1 AS builder
|
||||
|
||||
# Fix for JS heap limit allocation issue
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
RUN npm i -g npm@9.8.1
|
||||
RUN npm i -g npm@10.9.2
|
||||
RUN mkdir -p /app
|
||||
# RUN npm cache clean --force
|
||||
RUN npm cache clean --force
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
|
@ -54,13 +54,14 @@ ENV TOOLJET_EDITION=ee
|
|||
COPY ./server/package.json ./server/package-lock.json ./server/
|
||||
RUN npm --prefix server install
|
||||
COPY ./server/ ./server/
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm install -g @nestjs/cli
|
||||
RUN npm install -g copyfiles
|
||||
RUN npm --prefix server run build
|
||||
|
||||
FROM debian:11
|
||||
FROM debian:12
|
||||
|
||||
RUN apt-get update -yq \
|
||||
&& apt-get install curl gnupg zip -yq \
|
||||
&& apt-get install curl wget gnupg zip -yq \
|
||||
&& apt-get install -yq build-essential \
|
||||
&& apt -y install redis \
|
||||
&& apt-get clean -y
|
||||
|
|
@ -80,13 +81,29 @@ RUN echo "[supervisord]\n" \
|
|||
"nodaemon=true\n" \
|
||||
"\n" \
|
||||
"[program:postgrest]\n" \
|
||||
"command=/bin/postgrest \n" \
|
||||
"command=/bin/postgrest\n" \
|
||||
"autostart=true\n" \
|
||||
"autorestart=true\n" \
|
||||
"stdout_logfile=/dev/stdout\n" \
|
||||
"stderr_logfile=/dev/stderr\n" \
|
||||
"stdout_logfile_maxbytes=0\n" \
|
||||
"stderr_logfile_maxbytes=0\n" \
|
||||
"\n" \
|
||||
"[program:neo4j]\n" \
|
||||
"command=neo4j console\n" \
|
||||
"autostart=true\n" \
|
||||
"autorestart=unexpected\n" \
|
||||
"startsecs=30\n" \
|
||||
"startretries=999\n" \
|
||||
"priority=90\n" \
|
||||
"exitcodes=0,1,2\n" \
|
||||
"stopsignal=SIGTERM\n" \
|
||||
"stopasgroup=true\n" \
|
||||
"killasgroup=true\n" \
|
||||
"redirect_stderr=true\n" \
|
||||
"stdout_logfile=/var/log/neo4j/neo4j.log\n" \
|
||||
"stdout_logfile_backups=10\n" \
|
||||
"stderr_capture_maxbytes=20MB\n" \
|
||||
"\n" | sed 's/ //' > /etc/supervisor/conf.d/supervisord.conf
|
||||
|
||||
# Create a wrapper for PostgREST to prefix its logs
|
||||
|
|
@ -97,12 +114,12 @@ exec /bin/postgrest-original "$@" 2>&1 | sed "s/^/[PostgREST] /"\n\
|
|||
chmod +x /bin/postgrest
|
||||
|
||||
|
||||
RUN curl -O https://nodejs.org/dist/v18.18.2/node-v18.18.2-linux-x64.tar.xz \
|
||||
&& tar -xf node-v18.18.2-linux-x64.tar.xz \
|
||||
&& mv node-v18.18.2-linux-x64 /usr/local/lib/nodejs \
|
||||
RUN curl -O https://nodejs.org/dist/v22.15.1/node-v22.15.1-linux-x64.tar.xz \
|
||||
&& tar -xf node-v22.15.1-linux-x64.tar.xz \
|
||||
&& mv node-v22.15.1-linux-x64 /usr/local/lib/nodejs \
|
||||
&& echo 'export PATH="/usr/local/lib/nodejs/bin:$PATH"' >> /etc/profile.d/nodejs.sh \
|
||||
&& /bin/bash -c "source /etc/profile.d/nodejs.sh" \
|
||||
&& rm node-v18.18.2-linux-x64.tar.xz
|
||||
&& rm node-v22.15.1-linux-x64.tar.xz
|
||||
ENV PATH=/usr/local/lib/nodejs/bin:$PATH
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
|
@ -114,6 +131,48 @@ RUN apt-get update && \
|
|||
apt-get -y autoremove && \
|
||||
apt-get -y autoclean
|
||||
|
||||
# Install Neo4j
|
||||
RUN wget -O - https://debian.neo4j.com/neotechnology.gpg.key | apt-key add - && \
|
||||
echo "deb https://debian.neo4j.com stable 5" > /etc/apt/sources.list.d/neo4j.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y neo4j=1:5.26.6 && \
|
||||
apt-mark hold neo4j && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set the necessary Neo4j environment variables
|
||||
ENV NEO4J_HOME=/opt/neo4j
|
||||
ENV NEO4J_CONF=/etc/neo4j
|
||||
ENV NEO4J_DATA=/var/lib/neo4j/data
|
||||
ENV NEO4J_LOG=/var/log/neo4j
|
||||
ENV NEO4J_PLUGIN=/var/lib/neo4j/plugins
|
||||
ENV NEO4J_IMPORT=/var/lib/neo4j/import
|
||||
|
||||
# Create the necessary directories for Neo4j
|
||||
RUN mkdir -p /data/db /data/logs /data/plugins
|
||||
RUN mkdir -p /opt/neo4j/plugins
|
||||
|
||||
# Configure APOC plugin for Neo4j
|
||||
ENV NEO4J_dbms_active_plugins=apoc
|
||||
|
||||
# Download and install APOC plugin for Neo4j 5.x (BEFORE creating user)
|
||||
RUN mkdir -p /var/lib/neo4j/plugins && \
|
||||
wget -P /var/lib/neo4j/plugins https://github.com/neo4j/apoc/releases/download/5.26.6/apoc-5.26.6-core.jar && \
|
||||
# Try to download extended version
|
||||
(wget -P /var/lib/neo4j/plugins https://github.com/neo4j/apoc/releases/download/5.26.6/apoc-5.26.6-extended.jar || \
|
||||
wget -P /var/lib/neo4j/plugins https://neo4j-contrib.github.io/neo4j-apoc-procedures/5.26.6/apoc-5.26.6-extended.jar || \
|
||||
echo "Extended JAR not available, continuing with core only")
|
||||
|
||||
# Configure Neo4j with APOC
|
||||
RUN echo "dbms.security.procedures.unrestricted=apoc.*" >> /etc/neo4j/neo4j.conf && \
|
||||
echo "dbms.security.procedures.allowlist=apoc.*,algo.*,gds.*" >> /etc/neo4j/neo4j.conf && \
|
||||
echo "dbms.directories.plugins=/var/lib/neo4j/plugins" >> /etc/neo4j/neo4j.conf
|
||||
|
||||
# Configure Neo4j to use authentication
|
||||
RUN if [ -f "/etc/neo4j/neo4j.conf" ]; then \
|
||||
sed -i '/dbms.security.auth_enabled/d' /etc/neo4j/neo4j.conf && \
|
||||
echo "dbms.security.auth_enabled=true" >> /etc/neo4j/neo4j.conf; \
|
||||
fi
|
||||
|
||||
# Install Instantclient Basic Light Oracle and Dependencies
|
||||
WORKDIR /opt/oracle
|
||||
|
||||
|
|
@ -149,6 +208,7 @@ COPY --from=builder /app/server/node_modules ./app/server/node_modules
|
|||
COPY --from=builder /app/server/templates ./app/server/templates
|
||||
COPY --from=builder /app/server/scripts ./app/server/scripts
|
||||
COPY --from=builder /app/server/dist ./app/server/dist
|
||||
COPY --from=builder /app/server/src/assets ./app/server/src/assets
|
||||
|
||||
COPY ./docker/ee/ee-entrypoint.sh ./app/server/ee-entrypoint.sh
|
||||
|
||||
|
|
@ -161,14 +221,21 @@ RUN useradd --create-home --home-dir /home/appuser appuser \
|
|||
&& chmod -R g=u /app \
|
||||
&& chmod -R g=u /home
|
||||
|
||||
# Create directory /home/appuser and set ownership to appuser (Refer doc for understanding the changes https://app.clickup.com/37484951/v/dc/13qycq-4081)
|
||||
RUN mkdir -p /var/lib/neo4j/data/databases /var/lib/neo4j/data/transactions /var/log/neo4j /opt/neo4j/run && \
|
||||
chown -R appuser:0 /var/lib/neo4j /var/log/neo4j /etc/neo4j /opt/neo4j/run && \
|
||||
chmod -R 770 /var/lib/neo4j /var/log/neo4j /etc/neo4j /opt/neo4j/run && \
|
||||
chmod -R 644 /var/lib/neo4j/plugins/*.jar && \
|
||||
chown -R appuser:0 /var/lib/neo4j/plugins && \
|
||||
chmod 755 /var/lib/neo4j/plugins
|
||||
|
||||
# Create directory /home/appuser and set ownership to appuser
|
||||
RUN mkdir -p /home/appuser \
|
||||
&& chown -R appuser:0 /home/appuser \
|
||||
&& chmod g+s /home/appuser \
|
||||
&& chmod -R g=u /home/appuser \
|
||||
&& npm cache clean --force
|
||||
|
||||
# Create directory /tmp/.npm/npm-cache/ and set ownership to appuser (Refer doc for understanding the changes https://app.clickup.com/37484951/v/dc/13qycq-4081)
|
||||
# Create directory /tmp/.npm/npm-cache/ and set ownership to appuser
|
||||
RUN mkdir -p /tmp/.npm/npm-cache/ \
|
||||
&& chown -R appuser:0 /tmp/.npm/npm-cache/ \
|
||||
&& chmod g+s /tmp/.npm/npm-cache/ \
|
||||
|
|
@ -206,6 +273,9 @@ RUN mkdir -p /var/lib/postgrest /var/log/postgrest /etc/postgrest \
|
|||
|
||||
ENV HOME=/home/appuser
|
||||
|
||||
# Installing git for simple git commands
|
||||
RUN apt-get update && apt-get install -y git && apt-get clean
|
||||
|
||||
# Switch back to appuser
|
||||
USER appuser
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.14.0
|
||||
3.15.1
|
||||
|
|
|
|||
BIN
frontend/assets/images/GitSSH.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
frontend/assets/images/GithubDarkMode.png
Normal file
|
After Width: | Height: | Size: 446 B |
BIN
frontend/assets/images/GithubLightMode.png
Normal file
|
After Width: | Height: | Size: 675 B |
BIN
frontend/assets/images/Gitlab.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
frontend/assets/images/SSHDarkMode.png
Normal file
|
After Width: | Height: | Size: 417 B |
BIN
frontend/assets/images/SSHLightMode.png
Normal file
|
After Width: | Height: | Size: 405 B |
3
frontend/assets/images/icons/editor/file-code.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.02811 1.31381C2.22904 1.11288 2.50157 1 2.78572 1H7.07144C7.16616 1 7.257 1.03763 7.32397 1.10461L10.1812 3.96175C10.2481 4.02872 10.2857 4.11956 10.2857 4.21429V9.92857C10.2857 10.2127 10.1729 10.4853 9.97194 10.6862C9.77101 10.8871 9.49844 11 9.21429 11H2.78572C2.50156 11 2.22904 10.8871 2.02811 10.6862C1.82718 10.4853 1.71429 10.2127 1.71429 9.92857V2.07143C1.71429 1.78727 1.82718 1.51475 2.02811 1.31381ZM5.30739 5.26405C5.51659 5.47326 5.51659 5.81246 5.30739 6.02166L4.25762 7.07143L5.30739 8.12119C5.51659 8.33043 5.51659 8.66957 5.30739 8.87879C5.09818 9.088 4.75898 9.088 4.54977 8.87879L3.1212 7.45024C2.91199 7.24103 2.91199 6.90183 3.1212 6.69262L4.54977 5.26405C4.75898 5.05484 5.09818 5.05484 5.30739 5.26405ZM6.69263 6.02166C6.48342 5.81246 6.48342 5.47326 6.69263 5.26405C6.90184 5.05484 7.24104 5.05484 7.45024 5.26405L8.87879 6.69262C9.08801 6.90183 9.08801 7.24103 8.87879 7.45024L7.45024 8.87879C7.24104 9.088 6.90184 9.088 6.69263 8.87879C6.48342 8.66957 6.48342 8.33043 6.69263 8.12119L7.74239 7.07143L6.69263 6.02166Z" fill="#6A727C"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
3
frontend/assets/images/icons/module-editor.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.75815 0.483576C6.95842 0.283307 7.28312 0.283307 7.48338 0.483576L9.79108 2.79127C9.99135 2.99154 9.99135 3.31624 9.79108 3.5165L7.48338 5.8242C7.28312 6.02447 6.95842 6.02447 6.75815 5.8242L4.45046 3.5165C4.25018 3.31624 4.25018 2.99154 4.45046 2.79127L6.75815 0.483576ZM2.912 4.32973C3.11227 4.12946 3.43696 4.12946 3.63723 4.32973L5.94492 6.63743C6.1452 6.83769 6.1452 7.16239 5.94492 7.36266L3.63723 9.67035C3.43696 9.87063 3.11227 9.87063 2.912 9.67035L0.604304 7.36266C0.404034 7.16239 0.404034 6.83769 0.604304 6.63743L2.912 4.32973ZM11.3296 4.32973C11.1293 4.12946 10.8046 4.12946 10.6043 4.32973L8.29662 6.63743C8.09634 6.83769 8.09634 7.16239 8.29662 7.36266L10.6043 9.67035C10.8046 9.87063 11.1293 9.87063 11.3296 9.67035L13.6373 7.36266C13.8375 7.16239 13.8375 6.83769 13.6373 6.63743L11.3296 4.32973ZM7.48338 8.17589C7.28312 7.97561 6.95842 7.97561 6.75815 8.17589L4.45046 10.4835C4.25018 10.6838 4.25018 11.0086 4.45046 11.2089L6.75815 13.5166C6.95842 13.7168 7.28312 13.7168 7.48338 13.5166L9.79108 11.2089C9.99135 11.0086 9.99135 10.6838 9.79108 10.4835L7.48338 8.17589Z" fill="#1E823B"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="20" height="25" viewBox="0 0 20 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.60152 6.16675C2.53311 6.16675 1.66699 7.03286 1.66699 8.10128C1.66699 8.5122 2.00011 8.84532 2.41104 8.84532C2.82197 8.84532 3.15509 8.5122 3.15509 8.10128C3.15509 7.85472 3.35496 7.65485 3.60152 7.65485C4.01245 7.65485 4.34557 7.32172 4.34557 6.9108C4.34557 6.49987 4.01245 6.16675 3.60152 6.16675ZM5.98248 6.16675C5.57155 6.16675 5.23843 6.49987 5.23843 6.9108C5.23843 7.32172 5.57155 7.65485 5.98248 7.65485H7.7682C8.17912 7.65485 8.51224 7.32172 8.51224 6.9108C8.51224 6.49987 8.17912 6.16675 7.7682 6.16675H5.98248ZM9.4051 6.9108C9.4051 6.49987 9.73822 6.16675 10.1492 6.16675C11.2176 6.16675 12.0837 7.03286 12.0837 8.10128C12.0837 8.5122 11.7506 8.84532 11.3396 8.84532C10.9287 8.84532 10.5956 8.5122 10.5956 8.10128C10.5956 7.85472 10.3957 7.65485 10.1492 7.65485C9.73822 7.65485 9.4051 7.32172 9.4051 6.9108ZM3.15509 10.4822C3.15509 10.0713 2.82197 9.73818 2.41104 9.73818C2.00011 9.73818 1.66699 10.0713 1.66699 10.4822V12.2679C1.66699 12.6789 2.00011 13.012 2.41104 13.012C2.82197 13.012 3.15509 12.6789 3.15509 12.2679V10.4822ZM2.41104 13.9049C2.82197 13.9049 3.15509 14.238 3.15509 14.6489C3.15509 14.8955 3.35496 15.0953 3.60152 15.0953C4.01245 15.0953 4.34557 15.4285 4.34557 15.8394C4.34557 16.2503 4.01245 16.5834 3.60152 16.5834C2.53311 16.5834 1.66699 15.7173 1.66699 14.6489C1.66699 14.238 2.00011 13.9049 2.41104 13.9049ZM5.23843 11.5239C5.23843 10.5377 6.03792 9.73818 7.02415 9.73818H13.5718C14.558 9.73818 15.3575 10.5377 15.3575 11.5239V14.9372L12.1665 14.1394C10.6407 13.758 9.25865 15.14 9.6401 16.6658L10.438 19.8572H7.02415C6.03792 19.8572 5.23843 19.0577 5.23843 18.0715V11.5239ZM18.1596 21.7151L17.2157 22.659C16.9832 22.8915 16.6063 22.8915 16.3739 22.659L14.4138 20.699L13.3715 21.7413C13.0443 22.0684 12.4853 21.9137 12.3731 21.4648L11.083 16.3043C10.974 15.8683 11.3689 15.4735 11.8048 15.5825L16.9654 16.8726C17.4142 16.9848 17.569 17.5438 17.2419 17.8709L16.1995 18.9133L18.1596 20.8733C18.392 21.1058 18.392 21.4827 18.1596 21.7151Z" fill="#CCD1D5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="20" height="25" viewBox="0 0 20 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.91058 8.08983C3.73357 8.08983 3.59007 8.23333 3.59007 8.41034V9.05136C3.59007 9.5824 3.15957 10.0129 2.62853 10.0129C2.09749 10.0129 1.66699 9.5824 1.66699 9.05136V8.41034C1.66699 7.17124 2.67148 6.16675 3.91058 6.16675H4.55161C5.08265 6.16675 5.51315 6.59724 5.51315 7.12829C5.51315 7.65933 5.08265 8.08983 4.55161 8.08983H3.91058ZM14.4875 7.12829C14.4875 6.59724 14.918 6.16675 15.449 6.16675H16.0901C17.3292 6.16675 18.3337 7.17124 18.3337 8.41034V9.05136C18.3337 9.5824 17.9031 10.0129 17.3721 10.0129C16.8411 10.0129 16.4106 9.5824 16.4106 9.05136V8.41034C16.4106 8.23333 16.2671 8.08983 16.0901 8.08983H15.449C14.918 8.08983 14.4875 7.65933 14.4875 7.12829ZM18.3337 19.9488C18.3337 19.4178 17.9031 18.9873 17.3721 18.9873C16.8411 18.9873 16.4106 19.4178 16.4106 19.9488V20.5898C16.4106 20.7669 16.2671 20.9103 16.0901 20.9103H15.449C14.918 20.9103 14.4875 21.3409 14.4875 21.8719C14.4875 22.4029 14.918 22.8334 15.449 22.8334H16.0901C17.3292 22.8334 18.3337 21.8289 18.3337 20.5898V19.9488ZM2.62853 18.9873C3.15957 18.9873 3.59007 19.4178 3.59007 19.9488V20.5898C3.59007 20.7669 3.73357 20.9103 3.91058 20.9103H4.55161C5.08265 20.9103 5.51315 21.3409 5.51315 21.8719C5.51315 22.4029 5.08265 22.8334 4.55161 22.8334H3.91058C2.67148 22.8334 1.66699 21.8289 1.66699 20.5898V19.9488C1.66699 19.4178 2.09749 18.9873 2.62853 18.9873ZM8.39776 20.9103C7.86672 20.9103 7.43622 21.3409 7.43622 21.8719C7.43622 22.4029 7.86672 22.8334 8.39776 22.8334H11.6029C12.1339 22.8334 12.5644 22.4029 12.5644 21.8719C12.5644 21.3409 12.1339 20.9103 11.6029 20.9103H8.39776ZM7.43622 7.12829C7.43622 6.59724 7.86672 6.16675 8.39776 6.16675H11.6029C12.1339 6.16675 12.5644 6.59724 12.5644 7.12829C12.5644 7.65933 12.1339 8.08983 11.6029 8.08983H8.39776C7.86672 8.08983 7.43622 7.65933 7.43622 7.12829ZM3.59007 12.8975C3.59007 12.3665 3.15957 11.936 2.62853 11.936C2.09749 11.936 1.66699 12.3665 1.66699 12.8975V16.1026C1.66699 16.6337 2.09749 17.0642 2.62853 17.0642C3.15957 17.0642 3.59007 16.6337 3.59007 16.1026V12.8975ZM17.3721 11.936C17.9031 11.936 18.3337 12.3665 18.3337 12.8975V16.1026C18.3337 16.6337 17.9031 17.0642 17.3721 17.0642C16.8411 17.0642 16.4106 16.6337 16.4106 16.1026V12.8975C16.4106 12.3665 16.8411 11.936 17.3721 11.936ZM7.43622 10.0123C6.37413 10.0123 5.51315 10.8733 5.51315 11.9354V17.0636C5.51315 18.1256 6.37413 18.9866 7.43622 18.9866H12.5644C13.6265 18.9866 14.4875 18.1256 14.4875 17.0636V11.9354C14.4875 10.8733 13.6265 10.0123 12.5644 10.0123H7.43622Z" fill="#CCD1D5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
3
frontend/assets/images/modules/blank-module.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="103" height="42" viewBox="0 0 103 42" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M36.8298 0.809768C39.1863 -0.0104135 41.9933 -0.35598 44.1701 0.486052C45.5729 1.02867 46.4514 2.04627 46.896 3.25806C47.3183 4.40936 47.3337 5.68124 47.1897 6.83915C46.9018 9.15345 45.9098 11.5232 45.1884 12.8463C42.2889 18.1639 38.4247 22.5794 33.9787 26.2876C34.5399 26.5461 35.1642 26.7825 35.8578 26.9918C41.9402 28.8269 49.132 29.0238 56.4351 28.3262C63.7231 27.6301 71.0241 26.0534 77.2795 24.4159C82.4789 23.0549 88.4083 21.1217 93.2877 18.5872H89.6629V15.5872C92.9426 15.5872 96.5411 15.0656 99.4739 14.2229C99.907 14.0984 100.423 13.9818 100.902 14.0288C101.15 14.0531 101.586 14.1389 101.965 14.489C102.401 14.8919 102.519 15.4129 102.498 15.8141C102.48 16.1636 102.362 16.4455 102.281 16.6106C102.192 16.7928 102.085 16.9574 101.986 17.0947C101.788 17.3689 101.541 17.6478 101.3 17.9028C100.838 18.3892 100.271 18.9171 99.8104 19.3451L99.7374 19.4131C99.4924 19.6411 99.2855 19.8344 99.1255 19.9913C98.9808 20.1332 98.9314 20.1911 98.9302 20.1901C98.9301 20.19 98.9304 20.1894 98.931 20.1883C98.2154 21.2383 97.4441 22.6219 96.8553 24.0608C96.2546 25.5287 95.8916 26.9391 95.8916 28.062C95.8916 28.8904 95.22 29.562 94.3916 29.562C93.5632 29.562 92.8916 28.8904 92.8916 28.062C92.8916 26.3835 93.4101 24.5588 94.0788 22.9247C94.3303 22.3099 94.6099 21.7058 94.9046 21.1268C89.6711 23.8822 83.3845 25.9189 78.0392 27.3182C71.7006 28.9774 64.229 30.5954 56.7204 31.3126C49.227 32.0284 41.5983 31.8574 34.9912 29.8639C33.6317 29.4537 32.4359 28.9358 31.3973 28.3162C22.759 34.7179 12.321 38.8406 2.44859 41.9316C1.65801 42.1791 0.816456 41.7389 0.568925 40.9483C0.321395 40.1577 0.761626 39.3162 1.55221 39.0687C11.0603 36.0917 20.8465 32.2185 28.9544 26.3854C26.3865 23.6838 25.8234 20.144 26.3038 16.6476C26.8596 12.6029 28.8172 8.40718 30.9138 5.00092C32.0894 3.09103 34.4739 1.6298 36.8298 0.809768ZM31.3635 24.5523C35.8622 20.9286 39.7152 16.6174 42.5545 11.4101C43.1627 10.2948 43.9859 8.29206 44.2126 6.46889C44.3259 5.55807 44.2734 4.81998 44.0795 4.29123C43.9077 3.82297 43.6215 3.49045 43.0878 3.28402C41.8659 2.81135 39.8705 2.92794 37.816 3.64305C35.761 4.35831 34.126 5.50551 33.4687 6.57347C31.4736 9.81466 29.7509 13.5989 29.2759 17.056C28.8625 20.0646 29.3991 22.6539 31.3635 24.5523Z" fill="#ACB2B9"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
|
@ -4,6 +4,8 @@
|
|||
"cancel": "Cancel",
|
||||
"save": "Save",
|
||||
"savechanges": "Save changes",
|
||||
"execute": "Execute",
|
||||
"Build": "Build",
|
||||
"back": "Back",
|
||||
"edit": "Edit",
|
||||
"search": "Search",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 4ca98b6bb66d1d9845f8b326100945a969488f94
|
||||
Subproject commit 961eee83206a2ad6492aba5782b381aeb7c238f7
|
||||
33256
frontend/package-lock.json
generated
|
|
@ -85,6 +85,7 @@
|
|||
"query-string": "^8.1.0",
|
||||
"rc-slider": "^10.1.1",
|
||||
"react": "^18.2.0",
|
||||
"react-accessible-treeview": "^2.11.1",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-big-calendar": "^1.6.5",
|
||||
"react-bootstrap": "^2.7.2",
|
||||
|
|
@ -101,6 +102,7 @@
|
|||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dropzone": "^14.2.3",
|
||||
"react-highlight-words": "^0.21.0",
|
||||
"react-hot-toast": "^2.4.0",
|
||||
"react-hotkeys-hook": "^4.3.5",
|
||||
"react-i18next": "^12.1.5",
|
||||
|
|
@ -185,11 +187,11 @@
|
|||
"html-loader": "^4.2.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"jest": "^29.4.2",
|
||||
"node-sass": "^8.0.0",
|
||||
"path": "^0.12.7",
|
||||
"postcss": "^8.4.35",
|
||||
"postcss-loader": "^8.1.0",
|
||||
"prettier": "^2.8.4",
|
||||
"sass": "^1.78.0",
|
||||
"sass-loader": "^13.2.0",
|
||||
"storybook": "^7.2.1",
|
||||
"style-loader": "^3.3.1",
|
||||
|
|
@ -264,4 +266,4 @@
|
|||
"jsx"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React, { Suspense } from 'react';
|
|||
// eslint-disable-next-line no-unused-vars
|
||||
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
|
||||
import { authorizeWorkspace, updateCurrentSession } from '@/_helpers/authorizeWorkspace';
|
||||
import { authenticationService, tooljetService } from '@/_services';
|
||||
import { authenticationService, tooljetService, licenseService } from '@/_services';
|
||||
import { withRouter } from '@/_hoc/withRouter';
|
||||
import { PrivateRoute, AdminRoute, AppsRoute, SwitchWorkspaceRoute } from '@/Routes';
|
||||
import { HomePage } from '@/HomePage';
|
||||
|
|
@ -42,7 +42,6 @@ import { shallow } from 'zustand/shallow';
|
|||
import useStore from '@/AppBuilder/_stores/store';
|
||||
import { checkIfToolJetCloud } from '@/_helpers/utils';
|
||||
import { BasicPlanMigrationBanner } from '@/HomePage/BasicPlanMigrationBanner/BasicPlanMigrationBanner';
|
||||
import { licenseService } from '@/_services';
|
||||
|
||||
const AppWrapper = (props) => {
|
||||
const { isAppDarkMode } = useAppDarkMode();
|
||||
|
|
@ -283,9 +282,9 @@ class AppComponent extends React.Component {
|
|||
exact
|
||||
path="/:workspaceId/workflows/*"
|
||||
element={
|
||||
<AdminRoute {...this.props}>
|
||||
<PrivateRoute>
|
||||
<Workflows switchDarkMode={this.switchDarkMode} darkMode={this.darkMode} />
|
||||
</AdminRoute>
|
||||
</PrivateRoute>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -295,6 +294,15 @@ class AppComponent extends React.Component {
|
|||
></Route>
|
||||
<Route path="settings/*" element={<InstanceSettings {...this.props} />}></Route>
|
||||
<Route path="/:workspaceId/settings/*" element={<Settings {...this.props} />}></Route>
|
||||
<Route
|
||||
exact
|
||||
path="/:workspaceId/modules"
|
||||
element={
|
||||
<PrivateRoute>
|
||||
<HomePage switchDarkMode={this.switchDarkMode} darkMode={darkMode} appType={'module'} />
|
||||
</PrivateRoute>
|
||||
}
|
||||
/>
|
||||
|
||||
{getAuditLogsRoutes(this.props)}
|
||||
<Route
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import EditorHeader from '@/AppBuilder/Header';
|
|||
import LeftSidebar from '@/AppBuilder/LeftSidebar';
|
||||
import Popups from './Popups';
|
||||
import { ModuleProvider } from '@/AppBuilder/_contexts/ModuleContext';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
|
||||
// const EditorHeader = lazy(() => import('@/AppBuilder/Header'));
|
||||
// const LeftSidebar = lazy(() => import('@/AppBuilder/LeftSidebar'));
|
||||
|
|
@ -22,12 +23,13 @@ import { ModuleProvider } from '@/AppBuilder/_contexts/ModuleContext';
|
|||
// const QueryPanel = lazy(() => import('@/AppBuilder/QueryPanel'));
|
||||
|
||||
// TODO: split Loader into separate component and remove editor loading state from Editor
|
||||
export const Editor = ({ id: appId, darkMode, moduleId = 'canvas', switchDarkMode }) => {
|
||||
export const Editor = ({ id: appId, darkMode, moduleId = 'canvas', switchDarkMode, appType = 'front-end' }) => {
|
||||
useAppData(appId, moduleId, darkMode);
|
||||
const isEditorLoading = useStore((state) => state.isEditorLoading);
|
||||
const currentMode = useStore((state) => state.currentMode);
|
||||
const isEditorLoading = useStore((state) => state.loaderStore.modules[moduleId].isEditorLoading, shallow);
|
||||
const currentMode = useStore((state) => state.modeStore.modules[moduleId].currentMode, shallow);
|
||||
const isModuleEditor = appType === 'module';
|
||||
|
||||
const updateIsTJDarkMode = useStore((state) => state.updateIsTJDarkMode);
|
||||
const updateIsTJDarkMode = useStore((state) => state.updateIsTJDarkMode, shallow);
|
||||
|
||||
const changeToDarkMode = (newMode) => {
|
||||
updateIsTJDarkMode(newMode);
|
||||
|
|
@ -45,19 +47,19 @@ export const Editor = ({ id: appId, darkMode, moduleId = 'canvas', switchDarkMod
|
|||
return (
|
||||
<div className={cx('wrapper', { editor: currentMode === 'edit' })}>
|
||||
<ErrorBoundary>
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<EditorHeader darkMode={darkMode} />
|
||||
<LeftSidebar switchDarkMode={changeToDarkMode} darkMode={darkMode} />
|
||||
</Suspense>
|
||||
{window?.public_config?.ENABLE_MULTIPLAYER_EDITING === 'true' && <RealtimeCursors />}
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<ModuleProvider moduleId={moduleId}>
|
||||
<AppCanvas moduleId={moduleId} appId={appId} />
|
||||
<ModuleProvider moduleId={moduleId} appType={appType} isModuleMode={false} isModuleEditor={isModuleEditor}>
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<EditorHeader darkMode={darkMode} />
|
||||
<LeftSidebar switchDarkMode={changeToDarkMode} darkMode={darkMode} />
|
||||
</Suspense>
|
||||
{window?.public_config?.ENABLE_MULTIPLAYER_EDITING === 'true' && <RealtimeCursors />}
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<AppCanvas appId={appId} />
|
||||
<QueryPanel darkMode={darkMode} />
|
||||
<RightSideBar darkMode={darkMode} />
|
||||
</ModuleProvider>
|
||||
</DndProvider>
|
||||
<Popups darkMode={darkMode} />
|
||||
</DndProvider>
|
||||
<Popups darkMode={darkMode} />
|
||||
</ModuleProvider>
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
||||
import { Container } from './Container';
|
||||
import Grid from './Grid';
|
||||
import { EditorSelecto } from './Selecto';
|
||||
import { ModuleProvider } from '@/AppBuilder/_contexts/ModuleContext';
|
||||
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
|
||||
import { HotkeyProvider } from './HotkeyProvider';
|
||||
import './appCanvas.scss';
|
||||
import useStore from '@/AppBuilder/_stores/store';
|
||||
|
|
@ -17,16 +17,20 @@ import useAppDarkMode from '@/_hooks/useAppDarkMode';
|
|||
import useAppCanvasMaxWidth from './useAppCanvasMaxWidth';
|
||||
import { DeleteWidgetConfirmation } from './DeleteWidgetConfirmation';
|
||||
import useSidebarMargin from './useSidebarMargin';
|
||||
import AppCanvasBanner from '../../AppBuilder/Header/AppCanvasBanner';
|
||||
|
||||
export const AppCanvas = ({ moduleId, appId, isViewerSidebarPinned }) => {
|
||||
export const AppCanvas = ({ appId, isViewerSidebarPinned, isViewer = false }) => {
|
||||
const { moduleId, isModuleMode, appType } = useModuleContext();
|
||||
const canvasContainerRef = useRef();
|
||||
const handleCanvasContainerMouseUp = useStore((state) => state.handleCanvasContainerMouseUp, shallow);
|
||||
const canvasHeight = useStore((state) => state.canvasHeight);
|
||||
const creationMode = useStore((state) => state.app.creationMode);
|
||||
const environmentLoadingState = useStore((state) => state.environmentLoadingState || state.isEditorLoading);
|
||||
const [canvasWidth, setCanvasWidth] = useState(getCanvasWidth());
|
||||
const canvasHeight = useStore((state) => state.appStore.modules[moduleId].canvasHeight);
|
||||
const creationMode = useStore((state) => state.appStore.modules[moduleId].app.creationMode);
|
||||
const environmentLoadingState = useStore(
|
||||
(state) => state.environmentLoadingState || state.loaderStore.modules[moduleId].isEditorLoading
|
||||
);
|
||||
const [canvasWidth, setCanvasWidth] = useState(getCanvasWidth(moduleId));
|
||||
const gridWidth = canvasWidth / NO_OF_GRIDS;
|
||||
const currentMode = useStore((state) => state.currentMode, shallow);
|
||||
const currentMode = useStore((state) => state.modeStore.modules[moduleId].currentMode, shallow);
|
||||
const pageSidebarStyle = useStore((state) => state?.pageSettings?.definition?.properties?.style, shallow);
|
||||
const currentLayout = useStore((state) => state.currentLayout, shallow);
|
||||
const queryPanelHeight = useStore((state) => state?.queryPanel?.queryPanelHeight || 0);
|
||||
|
|
@ -42,23 +46,79 @@ export const AppCanvas = ({ moduleId, appId, isViewerSidebarPinned }) => {
|
|||
const isSidebarOpen = useStore((state) => state.isSidebarOpen, shallow);
|
||||
const getPageId = useStore((state) => state.getCurrentPageId, shallow);
|
||||
|
||||
const hideSidebar = isModuleMode || isPagesSidebarHidden || appType === 'module';
|
||||
|
||||
useEffect(() => {
|
||||
// Need to remove this if we shift setExposedVariable Logic outside of components
|
||||
// Currently present to run onLoadQueries after the component is mounted
|
||||
setIsComponentLayoutReady(true);
|
||||
return () => setIsComponentLayoutReady(false);
|
||||
setIsComponentLayoutReady(true, moduleId);
|
||||
return () => setIsComponentLayoutReady(false, moduleId);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
function handleResize() {
|
||||
const _canvasWidth = document.getElementById('real-canvas')?.getBoundingClientRect()?.width;
|
||||
const _canvasWidth =
|
||||
moduleId === 'canvas'
|
||||
? document.getElementById('real-canvas')?.getBoundingClientRect()?.width
|
||||
: document.getElementById(moduleId)?.getBoundingClientRect()?.width;
|
||||
if (_canvasWidth !== 0) setCanvasWidth(_canvasWidth);
|
||||
}
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
if (moduleId === 'canvas') {
|
||||
window.addEventListener('resize', handleResize);
|
||||
} else {
|
||||
const elem = document.getElementById(moduleId);
|
||||
const resizeObserver = new ResizeObserver(handleResize);
|
||||
if (elem) resizeObserver.observe(elem);
|
||||
|
||||
return () => {
|
||||
if (elem) resizeObserver.unobserve(elem);
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}
|
||||
handleResize();
|
||||
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, [currentLayout, canvasMaxWidth, isViewerSidebarPinned]);
|
||||
}, [currentLayout, canvasMaxWidth, isViewerSidebarPinned, moduleId]);
|
||||
|
||||
const styles = useMemo(() => {
|
||||
const canvasBgColor =
|
||||
currentMode === 'view'
|
||||
? computeViewerBackgroundColor(isAppDarkMode, canvasBgColor)
|
||||
: !isAppDarkMode
|
||||
? '#EBEBEF'
|
||||
: '#2F3C4C';
|
||||
|
||||
if (isModuleMode) {
|
||||
return {
|
||||
borderLeft: 'none',
|
||||
height: '100%',
|
||||
background: canvasBgColor,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
borderLeft: currentMode === 'edit' && editorMarginLeft + 'px solid',
|
||||
height: currentMode === 'edit' ? canvasContainerHeight : '100%',
|
||||
background: canvasBgColor,
|
||||
marginLeft:
|
||||
isViewerSidebarPinned && !hideSidebar && currentLayout !== 'mobile' && currentMode !== 'edit'
|
||||
? pageSidebarStyle === 'icon'
|
||||
? '65px'
|
||||
: '210px'
|
||||
: 'auto',
|
||||
};
|
||||
}, [
|
||||
currentMode,
|
||||
isAppDarkMode,
|
||||
isModuleMode,
|
||||
editorMarginLeft,
|
||||
canvasContainerHeight,
|
||||
isViewerSidebarPinned,
|
||||
hideSidebar,
|
||||
currentLayout,
|
||||
pageSidebarStyle,
|
||||
]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -66,36 +126,20 @@ export const AppCanvas = ({ moduleId, appId, isViewerSidebarPinned }) => {
|
|||
id="main-editor-canvas"
|
||||
onMouseUp={handleCanvasContainerMouseUp}
|
||||
>
|
||||
{creationMode === 'GIT' && <FreezeVersionInfo info={'Apps imported from git repository cannot be edited'} />}
|
||||
{creationMode !== 'GIT' && <FreezeVersionInfo hide={currentMode !== 'edit'} />}
|
||||
<AppCanvasBanner appId={appId} />
|
||||
<div
|
||||
ref={canvasContainerRef}
|
||||
className={cx(
|
||||
'canvas-container align-items-center page-container',
|
||||
{ 'dark-theme theme-dark': isAppDarkMode, close: !isViewerSidebarPinned },
|
||||
{ 'overflow-x-auto': (currentMode === 'edit' && isSidebarOpen) || currentMode === 'view' }
|
||||
{ 'overflow-x-auto': (currentMode === 'edit' && isSidebarOpen) || currentMode === 'view' },
|
||||
{ 'overflow-x-hidden': moduleId !== 'canvas' } // Disbling horizontal scroll for modules in view mode
|
||||
)}
|
||||
style={{
|
||||
// transform: `scale(1)`,
|
||||
borderLeft: currentMode === 'edit' && editorMarginLeft + 'px solid',
|
||||
height: currentMode === 'edit' ? canvasContainerHeight : '100%',
|
||||
background:
|
||||
currentMode === 'view'
|
||||
? computeViewerBackgroundColor(isAppDarkMode, canvasBgColor)
|
||||
: !isAppDarkMode
|
||||
? '#EBEBEF'
|
||||
: '#2F3C4C',
|
||||
marginLeft:
|
||||
isViewerSidebarPinned && !isPagesSidebarHidden && currentLayout !== 'mobile' && currentMode !== 'edit'
|
||||
? pageSidebarStyle === 'icon'
|
||||
? '65px'
|
||||
: '210px'
|
||||
: 'auto',
|
||||
}}
|
||||
style={styles}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
minWidth: `calc((100vw - 300px) - 48px)`,
|
||||
minWidth: isModuleMode ? '100%' : `calc((100vw - 300px) - 48px)`,
|
||||
}}
|
||||
className={`app-${appId} _tooljet-page-${getPageId()}`}
|
||||
>
|
||||
|
|
@ -107,7 +151,7 @@ export const AppCanvas = ({ moduleId, appId, isViewerSidebarPinned }) => {
|
|||
{environmentLoadingState !== 'loading' && (
|
||||
<div>
|
||||
<Container
|
||||
id="canvas"
|
||||
id={moduleId}
|
||||
gridWidth={gridWidth}
|
||||
canvasWidth={canvasWidth}
|
||||
canvasHeight={canvasHeight}
|
||||
|
|
@ -115,8 +159,9 @@ export const AppCanvas = ({ moduleId, appId, isViewerSidebarPinned }) => {
|
|||
canvasMaxWidth={canvasMaxWidth}
|
||||
isViewerSidebarPinned={isViewerSidebarPinned}
|
||||
pageSidebarStyle={pageSidebarStyle}
|
||||
appType={appType}
|
||||
/>
|
||||
<div id="component-portal" />
|
||||
{appType !== 'module' && <div id="component-portal" />}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import './configHandle.scss';
|
|||
import useStore from '@/AppBuilder/_stores/store';
|
||||
import { findHighestLevelofSelection } from '../Grid/gridUtils';
|
||||
import SolidIcon from '@/_ui/Icon/solidIcons/index';
|
||||
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
|
||||
import { DROPPABLE_PARENTS } from '../appCanvasConstants';
|
||||
|
||||
const CONFIG_HANDLE_HEIGHT = 20;
|
||||
const BUFFER_HEIGHT = 1;
|
||||
|
|
@ -18,10 +20,12 @@ export const ConfigHandle = ({
|
|||
showHandle,
|
||||
componentType,
|
||||
visibility,
|
||||
isModuleContainer,
|
||||
subContainerIndex,
|
||||
}) => {
|
||||
const { moduleId } = useModuleContext();
|
||||
const shouldFreeze = useStore((state) => state.getShouldFreeze());
|
||||
const componentName = useStore((state) => state.getComponentDefinition(id)?.component?.name || '', shallow);
|
||||
const componentName = useStore((state) => state.getComponentDefinition(id, moduleId)?.component?.name || '', shallow);
|
||||
const isMultipleComponentsSelected = useStore(
|
||||
(state) => (findHighestLevelofSelection(state?.selectedComponents)?.length > 1 ? true : false),
|
||||
shallow
|
||||
|
|
@ -43,6 +47,7 @@ export const ConfigHandle = ({
|
|||
return (
|
||||
(subContainerIndex === 0 || subContainerIndex === null) &&
|
||||
(isWidgetHovered ||
|
||||
isModuleContainer ||
|
||||
(showHandle && (!isMultipleComponentsSelected || (isModal && isModalOpen)) && !anyComponentHovered))
|
||||
);
|
||||
}, shallow);
|
||||
|
|
@ -67,7 +72,9 @@ export const ConfigHandle = ({
|
|||
if (componentType === 'Tabs') {
|
||||
setFocusedParentId(`${id}-${currentTab}`);
|
||||
} else {
|
||||
setFocusedParentId(id);
|
||||
if (DROPPABLE_PARENTS.has(componentType)) {
|
||||
setFocusedParentId(id);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
|
@ -125,20 +132,22 @@ export const ConfigHandle = ({
|
|||
data-cy={`${componentName.toLowerCase()}-inspect-button`}
|
||||
className="config-handle-inspect"
|
||||
/>
|
||||
<span
|
||||
style={{ cursor: 'pointer', marginLeft: '5px' }}
|
||||
onClick={() => {
|
||||
deleteComponents([id]);
|
||||
}}
|
||||
data-cy={`${componentName.toLowerCase()}-delete-button`}
|
||||
>
|
||||
<SolidIcon
|
||||
name="trash"
|
||||
width="12"
|
||||
height="12"
|
||||
fill={visibility === false ? 'var(--text-placeholder)' : '#fff'}
|
||||
/>
|
||||
</span>
|
||||
{!isModuleContainer && (
|
||||
<span
|
||||
style={{ cursor: 'pointer', marginLeft: '5px' }}
|
||||
onClick={() => {
|
||||
deleteComponents([id]);
|
||||
}}
|
||||
data-cy={`${componentName.toLowerCase()}-delete-button`}
|
||||
>
|
||||
<SolidIcon
|
||||
name="trash"
|
||||
width="12"
|
||||
height="12"
|
||||
fill={visibility === false ? 'var(--text-placeholder)' : '#fff'}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</span>
|
||||
|
|
|
|||