Merge branch 'appbuilder/sprint-11' into link-comp-bugs

This commit is contained in:
johnsoncherian 2025-04-11 10:30:42 +05:30
commit 880fc16688
1847 changed files with 122239 additions and 16836 deletions

View file

@ -79,7 +79,7 @@ jobs:
- name: Set up environment variables - name: Set up environment variables
run: | run: |
echo "TOOLJET_EDITION=${{ matrix.edition == 'ee' && 'EE' || 'CE' }}" >> .env echo "TOOLJET_EDITION=${{ matrix.edition == 'ee' && 'ee' || 'ce' }}" >> .env
echo "TOOLJET_HOST=http://localhost:8082" >> .env echo "TOOLJET_HOST=http://localhost:8082" >> .env
echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env
echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env
@ -147,13 +147,27 @@ jobs:
name: screenshots-${{ matrix.edition }} name: screenshots-${{ matrix.edition }}
path: cypress-tests/cypress/screenshots path: cypress-tests/cypress/screenshots
Cypress-Platform-Subpath: Cypress-Platform-Subpath:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
if: | if: |
github.event.action == 'labeled' && github.event.action == 'labeled' &&
(github.event.label.name == 'run-cypress-platform-subpath' || (
github.event.label.name == 'run-proxy-platform') github.event.label.name == 'run-cypress-platform-subpath' ||
github.event.label.name == 'run-proxy-platform' ||
github.event.label.name == 'run-ce-cypress-platform-subpath' ||
github.event.label.name == 'run-ee-cypress-platform-subpath'
)
strategy:
matrix:
edition: >-
${{
contains(github.event.pull_request.labels.*.name, 'run-cypress-platform-subpath') && fromJson('["ce", "ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-proxy-platform') && fromJson('["ce", "ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ce-cypress-platform-subpath') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ee-cypress-platform-subpath') && fromJson('["ee"]') ||
fromJson('[]')
}}
steps: steps:
- name: Setup Node.js - name: Setup Node.js
@ -161,11 +175,22 @@ jobs:
with: with:
node-version: 18.18.2 node-version: 18.18.2
- name: Checkout - name: Set up Git authentication for private submodules
run: |
git config --global url."https://x-access-token:${{ secrets.CUSTOM_GITHUB_TOKEN }}@github.com/".insteadOf "https://github.com/"
- name: Checkout with Submodules
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
ref: ${{ github.event.pull_request.head.ref }} ref: ${{ github.event.pull_request.head.ref }}
- name: Checking out the correct branch for submodules EE
if: matrix.edition == 'ee'
run: |
git submodule update --init --recursive
git submodule foreach --recursive '
git checkout ${{ env.BRANCH_NAME }} 2>/dev/null || git checkout main'
- name: Set up Docker configuration - name: Set up Docker configuration
run: | run: |
mkdir -p ~/.docker/cli-plugins mkdir -p ~/.docker/cli-plugins
@ -186,13 +211,14 @@ jobs:
uses: docker/build-push-action@v4 uses: docker/build-push-action@v4
with: with:
context: . context: .
file: docker/production.Dockerfile file: ${{ matrix.edition == 'ee' && 'docker/ee/ee-production.Dockerfile' || 'docker/ce-production.Dockerfile' }}
push: true push: true
tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }} tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}
platforms: linux/amd64 platforms: linux/amd64
- name: Set up environment variables - name: Set up environment variables
run: | run: |
echo "TOOLJET_EDITION=${{ matrix.edition == 'ee' && 'ee' || 'ce' }}" >> .env
echo "TOOLJET_HOST=http://localhost:3000" >> .env echo "TOOLJET_HOST=http://localhost:3000" >> .env
echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env
echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env
@ -254,15 +280,30 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: screenshots name: screenshots-${{ matrix.edition }}
path: cypress-tests/cypress/screenshots path: cypress-tests/cypress/screenshots
Cypress-Platform-Proxy: Cypress-Platform-Proxy:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
if: | if: |
github.event.action == 'labeled' && github.event.action == 'labeled' &&
(github.event.label.name == 'run-cypress-platform-proxy' || (
github.event.label.name == 'run-proxy-platform') github.event.label.name == 'run-cypress-platform-proxy' ||
github.event.label.name == 'run-proxy-platform' ||
github.event.label.name == 'run-ce-cypress-platform-proxy' ||
github.event.label.name == 'run-ee-cypress-platform-proxy'
)
strategy:
matrix:
edition: >-
${{
contains(github.event.pull_request.labels.*.name, 'run-cypress-platform-proxy') && fromJson('["ce", "ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-proxy-platform') && fromJson('["ce", "ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ce-cypress-platform-proxy') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ee-cypress-platform-proxy') && fromJson('["ee"]') ||
fromJson('[]')
}}
steps: steps:
- name: Setup Node.js - name: Setup Node.js
@ -270,11 +311,22 @@ jobs:
with: with:
node-version: 18.18.2 node-version: 18.18.2
- name: Checkout - name: Set up Git authentication for private submodules
run: |
git config --global url."https://x-access-token:${{ secrets.CUSTOM_GITHUB_TOKEN }}@github.com/".insteadOf "https://github.com/"
- name: Checkout with Submodules
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
ref: ${{ github.event.pull_request.head.ref }} ref: ${{ github.event.pull_request.head.ref }}
- name: Checking out the correct branch for submodules EE
if: matrix.edition == 'ee'
run: |
git submodule update --init --recursive
git submodule foreach --recursive '
git checkout ${{ env.BRANCH_NAME }} 2>/dev/null || git checkout main'
- name: Set up Docker configuration - name: Set up Docker configuration
run: | run: |
mkdir -p ~/.docker/cli-plugins mkdir -p ~/.docker/cli-plugins
@ -295,13 +347,14 @@ jobs:
uses: docker/build-push-action@v4 uses: docker/build-push-action@v4
with: with:
context: . context: .
file: docker/production.Dockerfile file: ${{ matrix.edition == 'ee' && 'docker/ee/ee-production.Dockerfile' || 'docker/ce-production.Dockerfile' }}
push: true push: true
tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }} tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}
platforms: linux/amd64 platforms: linux/amd64
- name: Set up environment variables - name: Set up environment variables
run: | run: |
echo "TOOLJET_EDITION=${{ matrix.edition == 'ee' && 'ee' || 'ce' }}" >> .env
echo "TOOLJET_HOST=http://localhost:3000" >> .env echo "TOOLJET_HOST=http://localhost:3000" >> .env
echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env
echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env
@ -375,15 +428,30 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: screenshots name: screenshots-${{ matrix.edition }}
path: cypress-tests/cypress/screenshots path: cypress-tests/cypress/screenshots
Cypress-Platform-Proxy-Subpath: Cypress-Platform-Proxy-Subpath:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
if: | if: |
github.event.action == 'labeled' && github.event.action == 'labeled' &&
(github.event.label.name == 'run-cypress-platform-proxy-subpath' || (
github.event.label.name == 'run-proxy-platform') github.event.label.name == 'run-cypress-platform-proxy-subpath' ||
github.event.label.name == 'run-proxy-platform' ||
github.event.label.name == 'run-ce-cypress-platform-proxy-subpath' ||
github.event.label.name == 'run-ee-cypress-platform-proxy-subpath'
)
strategy:
matrix:
edition: >-
${{
contains(github.event.pull_request.labels.*.name, 'run-cypress-platform-proxy-subpath') && fromJson('["ce", "ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-proxy-platform') && fromJson('["ce", "ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ce-cypress-platform-proxy-subpath') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ee-cypress-platform-proxy-subpath') && fromJson('["ee"]') ||
fromJson('[]')
}}
steps: steps:
- name: Setup Node.js - name: Setup Node.js
@ -391,11 +459,22 @@ jobs:
with: with:
node-version: 18.18.2 node-version: 18.18.2
- name: Checkout - name: Set up Git authentication for private submodules
run: |
git config --global url."https://x-access-token:${{ secrets.CUSTOM_GITHUB_TOKEN }}@github.com/".insteadOf "https://github.com/"
- name: Checkout with Submodules
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
ref: ${{ github.event.pull_request.head.ref }} ref: ${{ github.event.pull_request.head.ref }}
- name: Checking out the correct branch for submodules EE
if: matrix.edition == 'ee'
run: |
git submodule update --init --recursive
git submodule foreach --recursive '
git checkout ${{ env.BRANCH_NAME }} 2>/dev/null || git checkout main'
- name: Set up Docker configuration - name: Set up Docker configuration
run: | run: |
mkdir -p ~/.docker/cli-plugins mkdir -p ~/.docker/cli-plugins
@ -416,13 +495,14 @@ jobs:
uses: docker/build-push-action@v4 uses: docker/build-push-action@v4
with: with:
context: . context: .
file: docker/production.Dockerfile file: ${{ matrix.edition == 'ee' && 'docker/ee/ee-production.Dockerfile' || 'docker/ce-production.Dockerfile' }}
push: true push: true
tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }} tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}
platforms: linux/amd64 platforms: linux/amd64
- name: Set up environment variables - name: Set up environment variables
run: | run: |
echo "TOOLJET_EDITION=${{ matrix.edition == 'ee' && 'ee' || 'ce' }}" >> .env
echo "TOOLJET_HOST=http://localhost:3000" >> .env echo "TOOLJET_HOST=http://localhost:3000" >> .env
echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env
echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env
@ -497,5 +577,5 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: screenshots name: screenshots-${{ matrix.edition }}
path: cypress-tests/cypress/screenshots path: cypress-tests/cypress/screenshots

View file

@ -11,7 +11,7 @@ jobs:
steps: steps:
- name: Checkout code to main for Beta CE edition - name: Checkout code to main for pre-release CE edition
if: "!contains(github.event.release.tag_name, 'ce-lts')" if: "!contains(github.event.release.tag_name, 'ce-lts')"
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
@ -44,7 +44,7 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image for Beta tag - name: Build and Push Docker image for pre-release tag
if: "!contains(github.event.release.tag_name, '-ce-lts')" if: "!contains(github.event.release.tag_name, '-ce-lts')"
uses: docker/build-push-action@v4 uses: docker/build-push-action@v4
with: with:
@ -98,7 +98,7 @@ jobs:
if: "${{ github.event.release }}" if: "${{ github.event.release }}"
steps: steps:
- name: Checkout code to main for Beta EE edition - name: Checkout code to main for pre-release EE edition
if: "!contains(github.event.release.tag_name, 'ee-lts')" if: "!contains(github.event.release.tag_name, 'ee-lts')"
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
@ -132,13 +132,14 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image for Beta tag - name: Build and Push Docker image for pre-release tag
if: "!contains(github.event.release.tag_name, '-ee-lts')" if: "!contains(github.event.release.tag_name, '-ee-lts')"
uses: docker/build-push-action@v4 uses: docker/build-push-action@v4
with: with:
context: . context: .
args: ${{ secrets.CUSTOM_GITHUB_TOKEN }} build-args: |
file: docker/ee-production.Dockerfile CUSTOM_GITHUB_TOKEN=${{ secrets.CUSTOM_GITHUB_TOKEN }}
file: docker/ee/ee-production.Dockerfile
push: true push: true
tags: tooljet/tooljet-ee:${{ github.event.release.tag_name }},tooljet/tooljet-ee:ee-lts-latest,tooljet/tooljet:ee-lts-latest,tooljet/tooljet:${{ github.event.release.tag_name }} tags: tooljet/tooljet-ee:${{ github.event.release.tag_name }},tooljet/tooljet-ee:ee-lts-latest,tooljet/tooljet:ee-lts-latest,tooljet/tooljet:${{ github.event.release.tag_name }}
platforms: linux/amd64 platforms: linux/amd64
@ -152,8 +153,9 @@ jobs:
uses: docker/build-push-action@v4 uses: docker/build-push-action@v4
with: with:
context: . context: .
args: ${{ secrets.CUSTOM_GITHUB_TOKEN }} build-args: |
file: docker/ee-production.Dockerfile CUSTOM_GITHUB_TOKEN=${{ secrets.CUSTOM_GITHUB_TOKEN }}
file: docker/ee/ee-production.Dockerfile
push: true push: true
tags: tooljet/tooljet-ee:${{ github.event.release.tag_name }},tooljet/tooljet-ee:ee-lts-latest,tooljet/tooljet:ee-lts-latest,tooljet/tooljet:${{ github.event.release.tag_name }} tags: tooljet/tooljet-ee:${{ github.event.release.tag_name }},tooljet/tooljet-ee:ee-lts-latest,tooljet/tooljet:ee-lts-latest,tooljet/tooljet:${{ github.event.release.tag_name }}
platforms: linux/amd64 platforms: linux/amd64
@ -172,61 +174,61 @@ jobs:
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL }} curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL }}
build-tooljet-image-for-cloud-edtion: # commented out for now, since cloud modularisation is not yet ready
runs-on: ubuntu-latest # build-tooljet-image-for-cloud-edtion:
if: "${{ github.event.release }}"
steps: # runs-on: ubuntu-latest
- name: Checkout code to LTS for Cloud LTS edition # if: "${{ github.event.release }}"
if: "contains(github.event.release.tag_name, '-cloud-lts')"
uses: actions/checkout@v2
with:
ref: refs/heads/lts-4.0
# Create Docker Buildx builder with platform configuration # steps:
- name: Set up Docker Buildx # - name: Checkout code to LTS for Cloud LTS edition
run: | # if: "contains(github.event.release.tag_name, '-cloud-lts')"
mkdir -p ~/.docker/cli-plugins # uses: actions/checkout@v2
curl -SL https://github.com/docker/buildx/releases/download/v0.11.0/buildx-v0.11.0.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx # with:
chmod a+x ~/.docker/cli-plugins/docker-buildx # ref: refs/heads/lts-4.0
docker buildx create --name mybuilder --platform linux/arm64,linux/amd64,linux/amd64/v2,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
docker buildx use mybuilder
- name: Set DOCKER_CLI_EXPERIMENTAL # # Create Docker Buildx builder with platform configuration
run: echo "DOCKER_CLI_EXPERIMENTAL=enabled" >> $GITHUB_ENV # - 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,linux/amd64/v2,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
# docker buildx use mybuilder
- name: use mybuilder buildx # - name: Set DOCKER_CLI_EXPERIMENTAL
run: docker buildx use mybuilder # run: echo "DOCKER_CLI_EXPERIMENTAL=enabled" >> $GITHUB_ENV
- name: Docker Login # - name: use mybuilder buildx
uses: docker/login-action@v2 # run: docker buildx use mybuilder
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image for LTS tag # - name: Docker Login
if: "contains(github.event.release.tag_name, '-cloud-lts')" # uses: docker/login-action@v2
uses: docker/build-push-action@v4 # with:
with: # username: ${{ secrets.DOCKER_USERNAME }}
context: . # password: ${{ secrets.DOCKER_PASSWORD }}
args: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
file: docker/cloud/cloud-server.Dockerfile
push: true
tags: tooljet/saas:${{ github.event.release.tag_name }}
platforms: linux/amd64
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- name: Send Slack Notification # - name: Build and Push Docker image for LTS tag
run: | # if: "contains(github.event.release.tag_name, '-cloud-lts')"
if [[ "${{ job.status }}" == "success" ]]; then # uses: docker/build-push-action@v4
message="ToolJet cloud image published:\n\`tooljet/saas:${{ github.event.release.tag_name }}\`" # with:
else # context: .
message="Job '${{ env.JOB_NAME }}' failed! Image built:\n\`tooljet/saas:${{ github.event.release.tag_name }}\`" # args: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
fi # file: docker/cloud/cloud-server.Dockerfile
# push: true
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL }} # tags: tooljet/saas:${{ github.event.release.tag_name }}
# platforms: linux/amd64
# env:
# DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
# DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
# - name: Send Slack Notification
# run: |
# if [[ "${{ job.status }}" == "success" ]]; then
# message="ToolJet cloud image published:\n\`tooljet/saas:${{ github.event.release.tag_name }}\`"
# else
# message="Job '${{ env.JOB_NAME }}' failed! Image built:\n\`tooljet/saas:${{ github.event.release.tag_name }}\`"
# fi
# curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL }}

37
.github/workflows/docs-netlify.yml vendored Normal file
View file

@ -0,0 +1,37 @@
name: Deploy to Netlify
on:
workflow_dispatch:
push:
branches:
- develop
paths:
- docs/**
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: 18.18.2
- name: Install dependencies
run: npm install
working-directory: docs
- name: Build the project
run: GTM=${{ secrets.GTM }} ALGOLIA_API_KEY=${{ secrets.ALGOLIA_API_KEY }} npm run build
working-directory: docs
- name: Deploy to Netlify
run: |
npm install -g netlify-cli
netlify deploy --prod --dir=docs/build --auth=$NETLIFY_AUTH_TOKEN --site=${{ secrets.NETLIFY_SITE_ID }}
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}

View file

@ -53,7 +53,7 @@ jobs:
], ],
"serviceDetails": { "serviceDetails": {
"pullRequestPreviewsEnabled": "no", "pullRequestPreviewsEnabled": "no",
"buildCommand": "bash build-latest-version.sh", "buildCommand": "npm i && npm run build",
"publishPath": "build/", "publishPath": "build/",
"url": "https://tooljet-pr-${{ env.PR_NUMBER }}.onrender.com" "url": "https://tooljet-pr-${{ env.PR_NUMBER }}.onrender.com"
} }

View file

@ -1,16 +0,0 @@
name: Deploy docs to Netlify
on:
workflow_dispatch:
push:
branches:
- develop
paths:
- docs/**
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Trigger hook to deploy docs on Netlify
run: curl -X POST -d {} ${{ secrets.NETLIFY_HOOK }}

View file

@ -13,12 +13,42 @@ permissions:
jobs: jobs:
# Community Edition # Community Edition
create-ce-review-app: create-ce-review-app:
if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'create-ce-review-app' || github.event.label.name == 'review-app') }} if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'create-ce-review-app' || github.event.label.name == 'review-app') }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Sync repo
uses: actions/checkout@v3
- name: Check if Forked Repository
id: check_repo
run: |
if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then
echo "is_fork=true" >> $GITHUB_ENV
echo "FORKED_OWNER=${{ github.event.pull_request.head.repo.owner.login }}" >> $GITHUB_ENV
else
echo "is_fork=false" >> $GITHUB_ENV
fi
- name: Set Repository URL
run: |
if [[ "$is_fork" == "true" ]]; then
echo "REPO_URL=https://github.com/${FORKED_OWNER}/ToolJet" >> $GITHUB_ENV
else
echo "REPO_URL=https://github.com/ToolJet/ToolJet" >> $GITHUB_ENV
fi
- name: Fetch and Checkout Forked Branch
if: env.is_fork == 'true'
run: |
git fetch origin pull/${{ github.event.number }}/head:${{ env.BRANCH_NAME }}
git checkout ${{ env.BRANCH_NAME }}
- name: Checkout Default Branch
if: env.is_fork == 'false'
uses: actions/checkout@v3
- name: Creating deployment for CE - name: Creating deployment for CE
id: create-ce-deployment id: create-ce-deployment
run: | run: |
@ -34,7 +64,7 @@ jobs:
"name": "ToolJet CE PR #${{ env.PR_NUMBER }}", "name": "ToolJet CE PR #${{ env.PR_NUMBER }}",
"notifyOnFail": "default", "notifyOnFail": "default",
"ownerId": "tea-caeo4bj19n072h3dddc0", "ownerId": "tea-caeo4bj19n072h3dddc0",
"repo": "https://github.com/ToolJet/ToolJet", "repo": "'"$REPO_URL"'",
"slug": "tooljet-ce-pr-${{ env.PR_NUMBER }}", "slug": "tooljet-ce-pr-${{ env.PR_NUMBER }}",
"suspended": "not_suspended", "suspended": "not_suspended",
"suspenders": [], "suspenders": [],

View file

@ -1,217 +0,0 @@
name: Tooljet release docker images build
on:
release:
types: [published]
workflow_dispatch:
inputs:
job-to-run:
description: Enter the job name (tooljet-ce)
options: ["tooljet-ce"]
required: true
image:
description: "Enter the latest image tag"
required: true
jobs:
build-tooljet-ce-image:
runs-on: ubuntu-latest
if: "${{ github.event.release }}"
steps:
- name: Checkout code to main
if: "!contains(github.event.release.tag_name, 'ce-lts')"
uses: actions/checkout@v2
with:
ref: refs/heads/main
- name: Checkout code to LTS-2.50
if: "contains(github.event.release.tag_name, '2.50')"
uses: actions/checkout@v2
with:
ref: refs/heads/lts-2.50
- name: Checkout code to LTS-3.0
if: "contains(github.event.release.tag_name, '-ce-lts')"
uses: actions/checkout@v2
with:
ref: refs/heads/lts-3.0
# 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,linux/amd64/v2,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
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:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image for beta tag
if: "!contains(github.event.release.tag_name, '-ce-lts')"
uses: docker/build-push-action@v4
with:
context: .
file: docker/production.Dockerfile
push: true
tags: tooljet/tooljet-ce:${{ github.event.release.tag_name }},tooljet/tooljet-ce:ce-latest
platforms: linux/amd64
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image for LTS 2.50 tag
if: "contains(github.event.release.tag_name, '2.50')"
uses: docker/build-push-action@v4
with:
context: .
file: docker/production.Dockerfile
push: true
tags: tooljet/tooljet-ce:${{ github.event.release.tag_name }}
platforms: linux/amd64
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image for LTS 3.0 tag
if: "contains(github.event.release.tag_name, '-ce-lts')"
uses: docker/build-push-action@v4
with:
context: .
file: docker/production.Dockerfile
push: true
tags: tooljet/tooljet-ce:${{ github.event.release.tag_name }},tooljet/tooljet-ce:ce-lts-latest
platforms: linux/amd64
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- name: Send Slack Notification
run: |
if [[ "${{ job.status }}" == "success" ]]; then
message="ToolJet community image published:\n\`tooljet/tooljet-ce:${{ github.event.release.tag_name }}\`"
else
message="Job '${{ env.JOB_NAME }}' failed! tooljet/tooljet-ce:${{ github.event.release.tag_name }}"
fi
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL }}
# #Below code helps to trigger the workflow separately
tooljet-ce:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.job-to-run == 'tooljet-ce' }}
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: main
# 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,linux/amd64/v2,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
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:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image
if: "!contains(github.event.release.tag_name, 'CE-LTS')"
uses: docker/build-push-action@v4
with:
context: .
file: docker/production.Dockerfile
push: true
tags: tooljet/tooljet-ce:${{ github.event.inputs.image }},tooljet/tooljet-ce:latest
platforms: linux/amd64
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image
if: "contains(github.event.release.tag_name, 'CE-LTS')"
uses: docker/build-push-action@v4
with:
context: .
file: docker/production.Dockerfile
push: true
tags: tooljet/tooljet-ce:${{ github.event.inputs.image }},tooljet/tooljet-ce:CE-LTS-latest
platforms: linux/amd64
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- name: Send Slack Notification
run: |
if [[ "${{ job.status }}" == "success" ]]; then
message="ToolJet community image published:\n\`tooljet/tooljet-ce:${{ github.event.inputs.image }}\`"
else
message="Job '${{ env.JOB_NAME }}' failed! tooljet/tooljet-ce:${{ github.event.inputs.image }}"
fi
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL }}
update-lts-machine:
runs-on: ubuntu-latest
needs: build-tooljet-ce-image
if: "contains(github.event.release.tag_name, 'CE-LTS')"
steps:
- name: SSH into GCP VM instance
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.GCP_CE_LTS_INSTANCE_IP }}
username: ${{ secrets.GCP_USERNAME }}
key: ${{ secrets.EC2_INSTANCE_SSH_KEY }}
script: |
ls -lah
# Stop the Docker containers
sudo docker-compose down
# Check remaining images
sudo docker images
# Remove the existing tooljet/* images
sudo docker images -a | grep 'tooljet/' | awk '{print $3}' | xargs sudo docker rmi -f
# Check remaining images
sudo docker images
# Update docker-compose.yml with the new image for tooljet service
sed -i '/^[[:space:]]*tooljet:/,/^[[:space:]]*[^[:space:]]/ { /^[[:space:]]*image:/s|image:.*|image: tooljet/tooljet-ce:'"${{ github.event.release.tag_name }}"'| }' docker-compose.yml
# check the updated docker-compose.yml file
cat docker-compose.yml
# Start the Docker containers
sudo docker-compose up -d
#View containers
sudo docker ps

651
.github/workflows/vulnerability-ci.yml vendored Normal file
View file

@ -0,0 +1,651 @@
name: Vulnerability CI
# Controls when the workflow will run
on:
pull_request:
types: [labeled, unlabeled, closed]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Schedule the workflow to run every two weeks once
schedule:
- cron: '30 5 */14 * *'
jobs:
PeriodicVulnerability-CheckOn-frontend-code:
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: refs/heads/main
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix frontend install
- name: Running security audit
run: npm --prefix server audit --json > Periodic-frontend-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' Periodic-frontend-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: Periodic-frontend-audit-report
path: Periodic-frontend-audit.json
- name: Send Slack Notification
run: |
message="Periodic Security Audit Report Of Frontend directory\n
Node module vulnerabilities summary:\n
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}\n
🟠 High: ${{ steps.parse-audit.outputs.high }}\n
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}\n
\nDownload Audit Report: http://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL_VUR }}
PeriodicVulnerability-CheckOn-server-code:
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: refs/heads/main
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix server install
- name: Running security audit
run: npm --prefix server audit --json > Periodic-server-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' Periodic-server-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: Periodic-server-audit-report
path: Periodic-server-audit.json
- name: Send Slack Notification
run: |
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
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}\n
\nDownload Audit Report: http://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL_VUR }}
PeriodicVulnerability-CheckOn-marketplace-code:
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: refs/heads/main
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix marketplace install
- name: Running security audit
run: npm --prefix marketplace audit --json > Periodic-marketplace-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' Periodic-marketplace-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: Periodic-marketplace-audit-report
path: Periodic-marketplace-audit.json
- name: Send Slack Notification
run: |
message="Periodic Security Audit Report Of Marketplace directory\n
Node module vulnerabilities summary:\n
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}\n
🟠 High: ${{ steps.parse-audit.outputs.high }}\n
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}\n
\nDownload Audit Report: http://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL_VUR }}
PeriodicVulnerability-CheckOn-plugins-code:
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: refs/heads/main
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix plugins install
- name: Running security audit
run: npm --prefix plugins audit --json > Periodic-plugins-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' Periodic-plugins-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: Periodic-plugins-audit-report
path: Periodic-plugins-audit.json
- name: Send Slack Notification
run: |
message="Periodic Security Audit Report Of Plugins directory\n
Node module vulnerabilities summary:\n
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}\n
🟠 High: ${{ steps.parse-audit.outputs.high }}\n
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}\n
\nDownload Audit Report: http://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL_VUR }}
PeriodicVulnerability-CheckOn-cypress-code:
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: refs/heads/main
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix cypress-tests install
- name: Running security audit
run: npm --prefix cypress-tests audit --json > Periodic-cypress-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' Periodic-cypress-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: Periodic-cypress-audit-report
path: Periodic-cypress-audit.json
- name: Send Slack Notification
run: |
message="Periodic Security Audit Report Of Cypress directory\n
Node module vulnerabilities summary:\n
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}\n
🟠 High: ${{ steps.parse-audit.outputs.high }}\n
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}\n
\nDownload Audit Report: http://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL_VUR }}
PeriodicVulnerability-CheckOn-root-code:
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: refs/heads/main
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm install
- name: Running security audit
run: npm audit --json > Periodic-root-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' Periodic-root-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: Periodic-root-audit-report
path: Periodic-root-audit.json
- name: Send Slack Notification
run: |
message="Periodic Security Audit Report Of Root directory\n
Node module vulnerabilities summary:\n
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}\n
🟠 High: ${{ steps.parse-audit.outputs.high }}\n
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}\n
\nDownload Audit Report: http://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL_VUR }}
ManualVulnerability-CheckOn-frontend-code:
if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'frontend-vulnerability' || github.event.label.name == 'check-vulnerability') }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix frontend install
- name: Running security audit
run: npm --prefix frontend audit --json > frontend-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' frontend-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: frontend-audit-report
path: frontend-audit.json
- name: Create or update PR comment
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### Security Audit Report Of Frontend directory
**Node module vulnerabilities summary:**
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}
🟠 High: ${{ steps.parse-audit.outputs.high }}
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}
Please find the JSON file in the [summary page](${{ github.frontend_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
ManualVulnerability-CheckOn-server-code:
if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'server-vulnerability' || github.event.label.name == 'check-vulnerability') }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix server install
- name: Running security audit
run: npm --prefix server audit --json > server-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' server-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: server-audit-report
path: server-audit.json
- name: Create or update PR comment
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### Security Audit Report Of Server directory
**Node module vulnerabilities summary:**
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}
🟠 High: ${{ steps.parse-audit.outputs.high }}
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}
Please find the JSON file in the [summary page](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
ManualVulnerability-CheckOn-marketplace-code:
if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'marketplace-vulnerability' || github.event.label.name == 'check-vulnerability') }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix marketplace install
- name: Running security audit
run: npm --prefix marketplace audit --json > marketplace-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' marketplace-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: marketplace-audit-report
path: marketplace-audit.json
- name: Create or update PR comment
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### Security Audit Report Of Marketplace directory
**Node module vulnerabilities summary:**
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}
🟠 High: ${{ steps.parse-audit.outputs.high }}
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}
Please find the JSON file in the [summary page](${{ github.marketplace_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
ManualVulnerability-CheckOn-plugins-code:
if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'plugins-vulnerability' || github.event.label.name == 'check-vulnerability') }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix plugins install
- name: Running security audit
run: npm --prefix plugins audit --json > plugins-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' plugins-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: plugins-audit-report
path: plugins-audit.json
- name: Create or update PR comment
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### Security Audit Report Of Plugins directory
**Node module vulnerabilities summary:**
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}
🟠 High: ${{ steps.parse-audit.outputs.high }}
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}
Please find the JSON file in the [summary page](${{ github.plugins_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
ManualVulnerability-CheckOn-cypress-code:
if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'cypress-vulnerability' || github.event.label.name == 'check-vulnerability') }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm --prefix cypress-tests install
- name: Running security audit
run: npm --prefix cypress-tests audit --json > cypress-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' cypress-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: cypress-audit-report
path: cypress-audit.json
- name: Create or update PR comment
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### Security Audit Report Of Cypress directory
**Node module vulnerabilities summary:**
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}
🟠 High: ${{ steps.parse-audit.outputs.high }}
🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}
Please find the JSON file in the [summary page](${{ github.cypress_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
ManualVulnerability-CheckOn-root-code:
if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'root-vulnerability' || github.event.label.name == 'check-vulnerability') }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Use Node.js 18.18.2
uses: actions/setup-node@v3
with:
node-version: 18.18.2
- name: Install dependencies
run: npm install
- name: Running security audit
run: npm audit --json > root-audit.json
continue-on-error: true
- name: Parse audit summary
id: parse-audit
run: |
vulnerabilities=$(jq '.metadata.vulnerabilities' root-audit.json)
moderate=$(echo $vulnerabilities | jq '.moderate')
high=$(echo $vulnerabilities | jq '.high')
critical=$(echo $vulnerabilities | jq '.critical')
echo "::set-output name=moderate::$moderate"
echo "::set-output name=high::$high"
echo "::set-output name=critical::$critical"
- name: Upload audit report
uses: actions/upload-artifact@v4
with:
name: root-audit-report
path: root-audit.json
- name: Create or update PR comment
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### Security Audit Report Of Root directory
**Node module vulnerabilities summary:**
🔴 Critical: ${{ steps.parse-audit.outputs.critical }}
🟠 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 }}).

View file

@ -1 +1 @@
3.7.0 3.11.0

View file

@ -46,13 +46,7 @@ ToolJet is an **open-source low-code framework** to build and deploy internal to
<hr> <hr>
## Quickstart ## Quickstart
The easiest way to get started with ToolJet is by creating a [ToolJet Cloud](https://tooljet.com) account. ToolJet Cloud offers a hosted solution of ToolJet. If you want to self-host ToolJet, kindly proceed to [deployment documentation](https://docs.tooljet.com/docs/setup/). The easiest way to get started with ToolJet is by creating a [ToolJet Cloud](https://tooljet.ai) account. ToolJet Cloud offers a hosted solution of ToolJet. If you want to self-host ToolJet, kindly proceed to [deployment documentation](https://docs.tooljet.ai/docs/setup/).
You can deploy ToolJet on DigitalOcean using one-click-deployment.
<p align="center">
<a href="https://cloud.digitalocean.com/apps/new?repo=https://github.com/ToolJet/ToolJet/tree/main"><img src="https://www.deploytodo.com/do-btn-blue.svg" alt="Deploy to DigitalOcean" height=32></a>
</p>
### Try using Docker ### Try using Docker
Want to give ToolJet a quick spin on your local machine? You can run the following command from your terminal to have ToolJet up and running right away. Want to give ToolJet a quick spin on your local machine? You can run the following command from your terminal to have ToolJet up and running right away.
@ -65,42 +59,42 @@ docker run \
-p 80:80 \ -p 80:80 \
--platform linux/amd64 \ --platform linux/amd64 \
-v tooljet_data:/var/lib/postgresql/13/main \ -v tooljet_data:/var/lib/postgresql/13/main \
tooljet/try:EE-LTS-latest tooljet/try:ee-lts-latest
``` ```
*For users upgrading their ToolJet version, we recommend choosing the LTS version over the latest version. The LTS version ensures stability with production bug fixes, security patches, and performance enhancements.* *For users upgrading their ToolJet version, we recommend choosing the LTS version over the latest version. The LTS version ensures stability with production bug fixes, security patches, and performance enhancements.*
## Tutorials and examples ## Tutorials and examples
[Time Tracker Application](https://docs.tooljet.com/docs/#quickstart-guide)<br> [Time Tracker Application](https://docs.tooljet.ai/docs/#quickstart-guide)<br>
[Build your own CMS using low-code](https://blog.tooljet.com/build-cms-using-lowcode-and-mongodb/)<br> [Build your own CMS using low-code](https://blog.tooljet.ai/build-cms-using-lowcode-and-mongodb/)<br>
[AWS S3 Browser](https://blog.tooljet.com/build-an-aws-s3-broswer-with-tooljet/)<br> [AWS S3 Browser](https://blog.tooljet.ai/build-an-aws-s3-broswer-with-tooljet/)<br>
## Documentation ## Documentation
Documentation is available at https://docs.tooljet.com. Documentation is available at https://docs.tooljet.ai.
- [Getting Started](https://docs.tooljet.com)<br> - [Getting Started](https://docs.tooljet.ai)<br>
- [Data source Reference](https://docs.tooljet.com/docs/data-sources/airtable/)<br> - [Data source Reference](https://docs.tooljet.ai/docs/data-sources/airtable/)<br>
- [Component Reference](https://docs.tooljet.com/docs/widgets/button) - [Component Reference](https://docs.tooljet.ai/docs/widgets/button)
## Self-hosted ## Self-hosted
You can use ToolJet Cloud for a fully managed solution. If you want to self-host ToolJet, we have guides on deploying ToolJet on Kubernetes, AWS EC2, Docker, and more. You can use ToolJet Cloud for a fully managed solution. If you want to self-host ToolJet, we have guides on deploying ToolJet on Kubernetes, AWS EC2, Docker, and more.
| Provider | Documentation | | Provider | Documentation |
| :------------- | :------------- | | :------------- | :------------- |
| Digital Ocean | [Link](https://docs.tooljet.com/docs/setup/digitalocean) | | Digital Ocean | [Link](https://docs.tooljet.ai/docs/setup/digitalocean) |
| Docker | [Link](https://docs.tooljet.com/docs/setup/docker) | | Docker | [Link](https://docs.tooljet.ai/docs/setup/docker) |
| AWS EC2 | [Link](https://docs.tooljet.com/docs/setup/ec2) | | AWS EC2 | [Link](https://docs.tooljet.ai/docs/setup/ec2) |
| AWS ECS | [Link](https://docs.tooljet.com/docs/setup/ecs) | | AWS ECS | [Link](https://docs.tooljet.ai/docs/setup/ecs) |
| OpenShift | [Link](https://docs.tooljet.com/docs/setup/openshift) | | OpenShift | [Link](https://docs.tooljet.ai/docs/setup/openshift) |
| Helm | [Link](https://docs.tooljet.com/docs/setup/helm) | | Helm | [Link](https://docs.tooljet.ai/docs/setup/helm) |
| AWS EKS (Kubernetes) | [Link](https://docs.tooljet.com/docs/setup/kubernetes) | | AWS EKS (Kubernetes) | [Link](https://docs.tooljet.ai/docs/setup/kubernetes) |
| GCP GKE (Kubernetes) | [Link](https://docs.tooljet.com/docs/setup/kubernetes-gke) | | GCP GKE (Kubernetes) | [Link](https://docs.tooljet.ai/docs/setup/kubernetes-gke) |
| Azure AKS (Kubernetes) | [Link](https://docs.tooljet.com/docs/setup/kubernetes-aks) | | Azure AKS (Kubernetes) | [Link](https://docs.tooljet.ai/docs/setup/kubernetes-aks) |
| Azure Container | [Link](https://docs.tooljet.com/docs/setup/azure-container) | | Azure Container | [Link](https://docs.tooljet.ai/docs/setup/azure-container) |
| Google Cloud Run | [Link](https://docs.tooljet.com/docs/setup/google-cloud-run) | | Google Cloud Run | [Link](https://docs.tooljet.ai/docs/setup/google-cloud-run) |
| Deploying ToolJet client | [Link](https://docs.tooljet.com/docs/setup/client) | | Deploying ToolJet client | [Link](https://docs.tooljet.ai/docs/setup/client) |
| Deploying ToolJet on a Subpath | [Link](https://docs.tooljet.com/docs/setup/tooljet-subpath/) | | Deploying ToolJet on a Subpath | [Link](https://docs.tooljet.ai/docs/setup/tooljet-subpath/) |
## Marketplace ## Marketplace
ToolJet can now be found on both AWS and Azure Marketplaces, making it simpler than ever to access and deploy our app-building platform. ToolJet can now be found on both AWS and Azure Marketplaces, making it simpler than ever to access and deploy our app-building platform.
@ -108,9 +102,9 @@ ToolJet can now be found on both AWS and Azure Marketplaces, making it simpler t
Find ToolJet on AWS Marketplace [here](https://aws.amazon.com/marketplace/pp/prodview-fxjto27jkpqfg?sr=0-1&ref_=beagle&applicationId=AWSMPContessa) and explore seamless integration on Azure Marketplace [here](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/tooljetsolutioninc1679496832216.tooljet?tab=Overview). Find ToolJet on AWS Marketplace [here](https://aws.amazon.com/marketplace/pp/prodview-fxjto27jkpqfg?sr=0-1&ref_=beagle&applicationId=AWSMPContessa) and explore seamless integration on Azure Marketplace [here](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/tooljetsolutioninc1679496832216.tooljet?tab=Overview).
## Community support ## Community support
For general help using ToolJet, please refer to the official [documentation](https://docs.tooljet.com/docs/). For additional help, you can use one of these channels to ask a question: For general help using ToolJet, please refer to the official [documentation](https://docs.tooljet.ai/docs/). For additional help, you can use one of these channels to ask a question:
- [Slack](https://tooljet.com/slack) - Discussions with the community and the team. - [Slack](https://tooljet.ai/slack) - Discussions with the community and the team.
- [GitHub](https://github.com/ToolJet/ToolJet/issues) - For bug reports and feature requests. - [GitHub](https://github.com/ToolJet/ToolJet/issues) - For bug reports and feature requests.
- [𝕏 (Twitter)](https://twitter.com/ToolJet) - Get the product updates quickly. - [𝕏 (Twitter)](https://twitter.com/ToolJet) - Get the product updates quickly.

View file

@ -19,9 +19,9 @@ module.exports = defineConfig({
trashAssetsBeforeRuns: true, trashAssetsBeforeRuns: true,
e2e: { e2e: {
setupNodeEvents(on, config) { setupNodeEvents (on, config) {
on("task", { on("task", {
readPdf(pathToPdf) { readPdf (pathToPdf) {
return new Promise((resolve) => { return new Promise((resolve) => {
const pdfPath = path.resolve(pathToPdf); const pdfPath = path.resolve(pathToPdf);
let dataBuffer = fs.readFileSync(pdfPath); let dataBuffer = fs.readFileSync(pdfPath);
@ -33,7 +33,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
readXlsx(filePath) { readXlsx (filePath) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
let dataBuffer = fs.readFileSync(filePath); let dataBuffer = fs.readFileSync(filePath);
@ -48,7 +48,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
deleteFolder(folderName) { deleteFolder (folderName) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => { rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => {
if (err) { if (err) {
@ -62,7 +62,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
updateId({ dbconfig, sql }) { dbConnection ({ dbconfig, sql }) {
const client = new pg.Pool(dbconfig); const client = new pg.Pool(dbconfig);
return client.query(sql); return client.query(sql);
}, },

View file

@ -19,9 +19,9 @@ module.exports = defineConfig({
trashAssetsBeforeRuns: true, trashAssetsBeforeRuns: true,
e2e: { e2e: {
setupNodeEvents(on, config) { setupNodeEvents (on, config) {
on("task", { on("task", {
readPdf(pathToPdf) { readPdf (pathToPdf) {
return new Promise((resolve) => { return new Promise((resolve) => {
const pdfPath = path.resolve(pathToPdf); const pdfPath = path.resolve(pathToPdf);
let dataBuffer = fs.readFileSync(pdfPath); let dataBuffer = fs.readFileSync(pdfPath);
@ -33,7 +33,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
readXlsx(filePath) { readXlsx (filePath) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
let dataBuffer = fs.readFileSync(filePath); let dataBuffer = fs.readFileSync(filePath);
@ -48,7 +48,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
deleteFolder(folderName) { deleteFolder (folderName) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => { rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => {
if (err) { if (err) {
@ -62,7 +62,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
updateId({ dbconfig, sql }) { dbConnection ({ dbconfig, sql }) {
const client = new pg.Pool(dbconfig); const client = new pg.Pool(dbconfig);
return client.query(sql); return client.query(sql);
}, },

View file

@ -83,7 +83,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
updateId ({ dbconfig, sql }) { dbConnection ({ dbconfig, sql }) {
const client = new pg.Pool(dbconfig); const client = new pg.Pool(dbconfig);
return client.query(sql); return client.query(sql);
}, },

View file

@ -19,9 +19,9 @@ module.exports = defineConfig({
trashAssetsBeforeRuns: true, trashAssetsBeforeRuns: true,
e2e: { e2e: {
setupNodeEvents(on, config) { setupNodeEvents (on, config) {
on("task", { on("task", {
readPdf(pathToPdf) { readPdf (pathToPdf) {
return new Promise((resolve) => { return new Promise((resolve) => {
const pdfPath = path.resolve(pathToPdf); const pdfPath = path.resolve(pathToPdf);
let dataBuffer = fs.readFileSync(pdfPath); let dataBuffer = fs.readFileSync(pdfPath);
@ -33,7 +33,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
readXlsx(filePath) { readXlsx (filePath) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
let dataBuffer = fs.readFileSync(filePath); let dataBuffer = fs.readFileSync(filePath);
@ -48,7 +48,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
deleteFolder(folderName) { deleteFolder (folderName) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => { rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => {
if (err) { if (err) {
@ -62,7 +62,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
updateId({ dbconfig, sql }) { dbConnection ({ dbconfig, sql }) {
const client = new pg.Pool(dbconfig); const client = new pg.Pool(dbconfig);
return client.query(sql); return client.query(sql);
}, },

View file

@ -66,7 +66,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
updateId ({ dbconfig, sql }) { dbConnection ({ dbconfig, sql }) {
const client = new pg.Pool(dbconfig); const client = new pg.Pool(dbconfig);
return client.query(sql); return client.query(sql);
}, },
@ -92,7 +92,11 @@ module.exports = defineConfig({
experimentalModfyObstructiveThirdPartyCode: true, experimentalModfyObstructiveThirdPartyCode: true,
experimentalRunAllSpecs: true, experimentalRunAllSpecs: true,
baseUrl: "http://localhost:8082", baseUrl: "http://localhost:8082",
specPattern: "cypress/e2e/happyPath/**/*.cy.js", specPattern: [
"cypress/e2e/happyPath/platform/ceTestcases/userFlow/firstUserOnboarding.cy.js",
"cypress/e2e/happyPath/platform/ceTestcases/!(userFlow)/**/*.cy.js",
"cypress/e2e/happyPath/platform/commonTestcases/**/*.cy.js",
],
downloadsFolder: "cypress/downloads", downloadsFolder: "cypress/downloads",
numTestsKeptInMemory: 0, numTestsKeptInMemory: 0,
redirectionLimit: 10, redirectionLimit: 10,

View file

@ -1,3 +1,5 @@
const envVar = Cypress.env("environment");
Cypress.Commands.add( Cypress.Commands.add(
"apiLogin", "apiLogin",
( (
@ -75,14 +77,17 @@ Cypress.Commands.add("apiCreateApp", (appName = "testApp") => {
Cookie: `tj_auth_token = ${cookie.value}`, Cookie: `tj_auth_token = ${cookie.value}`,
}, },
body: { body: {
created_at: "", type: "front-end",
id: "",
is_maintenance_on: false,
is_public: null,
name: appName, name: appName,
is_maintenance_on: false,
organization_id: "", organization_id: "",
updated_at: "",
user_id: "", user_id: "",
created_at: "",
updated_at: "",
id: "",
is_public: null,
workflow_enabled: false,
creation_mode: "DEFAULT",
}, },
}).then((response) => { }).then((response) => {
{ {
@ -128,7 +133,7 @@ Cypress.Commands.add(
appId = Cypress.env("appId"), appId = Cypress.env("appId"),
componentSelector = "[data-cy='empty-editor-text']" componentSelector = "[data-cy='empty-editor-text']"
) => { ) => {
cy.intercept("GET", "/api/v2/apps/*").as("getAppData"); cy.intercept("GET", "/api/apps/*").as("getAppData");
cy.window({ log: false }).then((win) => { cy.window({ log: false }).then((win) => {
win.localStorage.setItem("walkthroughCompleted", "true"); win.localStorage.setItem("walkthroughCompleted", "true");
}); });
@ -175,7 +180,7 @@ Cypress.Commands.add("apiLogout", () => {
cy.request( cy.request(
{ {
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/logout`, url: `${Cypress.env("server_host")}/api/session/logout`,
headers: { headers: {
"Tj-Workspace-Id": Cypress.env("workspaceId"), "Tj-Workspace-Id": Cypress.env("workspaceId"),
Cookie: `tj_auth_token=${cookie.value}`, Cookie: `tj_auth_token=${cookie.value}`,
@ -190,22 +195,36 @@ Cypress.Commands.add("apiLogout", () => {
Cypress.Commands.add( Cypress.Commands.add(
"apiUserInvite", "apiUserInvite",
(userName, userEmail, userRole = "end-user") => { (userName, userEmail, userRole = "end-user", metaData = {}) => {
const requestBody =
envVar === "Enterprise"
? {
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.getCookie("tj_auth_token").then((cookie) => {
cy.request( cy.request(
{ {
method: "POST", method: "POST",
url: `${Cypress.env("server_host")}/api/organization_users`, url: `${Cypress.env("server_host")}/api/organization-users`,
headers: { headers: {
"Tj-Workspace-Id": Cypress.env("workspaceId"), "Tj-Workspace-Id": Cypress.env("workspaceId"),
Cookie: `tj_auth_token=${cookie.value}`, Cookie: `tj_auth_token=${cookie.value}`,
}, },
body: { body: requestBody,
first_name: userName,
email: userEmail,
groups: [],
role: userRole,
},
}, },
{ log: false } { log: false }
).then((response) => { ).then((response) => {
@ -221,21 +240,26 @@ Cypress.Commands.add("apiAddQuery", (queryName, query, dataQueryId) => {
"Tj-Workspace-Id": Cypress.env("workspaceId"), "Tj-Workspace-Id": Cypress.env("workspaceId"),
Cookie: `tj_auth_token=${cookie.value}`, Cookie: `tj_auth_token=${cookie.value}`,
}; };
cy.request({
method: "PATCH", cy.apiGetAppData(Cypress.env("appId")).then((appData) => {
url: `${Cypress.env("server_host")}/api/data_queries/${dataQueryId}`, const editingVersionId = appData.editing_version.id;
headers: headers,
body: { cy.request({
name: queryName, method: "PATCH",
options: { url: `${Cypress.env("server_host")}/api/data-queries/${dataQueryId}/versions/${editingVersionId}`,
mode: "sql", headers: headers,
transformationLanguage: "javascript", body: {
enableTransformation: false, name: queryName,
query: query, options: {
mode: "sql",
transformationLanguage: "javascript",
enableTransformation: false,
query: query,
},
}, },
}, }).then((patchResponse) => {
}).then((patchResponse) => { expect(patchResponse.status).to.equal(200);
expect(patchResponse.status).to.equal(200); });
}); });
}); });
}); });
@ -262,7 +286,7 @@ Cypress.Commands.add(
cy.request({ cy.request({
method: "POST", method: "POST",
url: `${Cypress.env("server_host")}/api/data_queries`, url: `${Cypress.env("server_host")}/api/data-queries`,
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
Cookie: authToken, Cookie: authToken,
@ -315,7 +339,7 @@ Cypress.Commands.add(
cy.request({ cy.request({
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/v2/apps/${appId}`, url: `${Cypress.env("server_host")}/api/apps/${appId}`,
headers: { headers: {
"Tj-Workspace-Id": Cypress.env("workspaceId"), "Tj-Workspace-Id": Cypress.env("workspaceId"),
Cookie: `tj_auth_token=${cookie.value}`, Cookie: `tj_auth_token=${cookie.value}`,
@ -432,11 +456,10 @@ Cypress.Commands.add("apiMakeAppPublic", (appId = Cypress.env("appId")) => {
Cypress.Commands.add("apiDeleteGranularPermission", (groupName) => { Cypress.Commands.add("apiDeleteGranularPermission", (groupName) => {
cy.getAuthHeaders().then((headers) => { cy.getAuthHeaders().then((headers) => {
// Fetch group permissions // Fetch group permissions
cy.request({ cy.request({
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/v2/group_permissions`, url: `${Cypress.env("server_host")}/api/v2/group-permissions`,
headers: headers, headers: headers,
log: false, log: false,
}).then((response) => { }).then((response) => {
@ -451,7 +474,7 @@ Cypress.Commands.add("apiDeleteGranularPermission", (groupName) => {
// Fetch granular permissions for the specific group // Fetch granular permissions for the specific group
cy.request({ cy.request({
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/v2/group_permissions/${groupId}/granular-permissions`, url: `${Cypress.env("server_host")}/api/v2/group-permissions/${groupId}/granular-permissions`,
headers, headers,
log: false, log: false,
}).then((granularResponse) => { }).then((granularResponse) => {
@ -461,7 +484,7 @@ Cypress.Commands.add("apiDeleteGranularPermission", (groupName) => {
// Delete the granular permission // Delete the granular permission
cy.request({ cy.request({
method: "DELETE", 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/${granularPermissionId}`,
headers, headers,
log: false, log: false,
}).then((deleteResponse) => { }).then((deleteResponse) => {
@ -483,11 +506,10 @@ Cypress.Commands.add(
resourcesToAdd = [] resourcesToAdd = []
) => { ) => {
cy.getAuthHeaders().then((headers) => { cy.getAuthHeaders().then((headers) => {
// Fetch group permissions // Fetch group permissions
cy.request({ cy.request({
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/v2/group_permissions`, url: `${Cypress.env("server_host")}/api/v2/group-permissions`,
headers: headers, headers: headers,
log: false, log: false,
}).then((response) => { }).then((response) => {
@ -502,7 +524,7 @@ Cypress.Commands.add(
// Create granular permission // Create granular permission
cy.request({ cy.request({
method: "POST", method: "POST",
url: `${Cypress.env("server_host")}/api/v2/group_permissions/granular-permissions`, url: `${Cypress.env("server_host")}/api/v2/group-permissions/granular-permissions`,
headers: headers, headers: headers,
body: { body: {
name, name,
@ -528,10 +550,9 @@ Cypress.Commands.add(
Cypress.Commands.add("apiReleaseApp", (appName) => { Cypress.Commands.add("apiReleaseApp", (appName) => {
cy.getAppId(appName).then((appId) => { cy.getAppId(appName).then((appId) => {
cy.getAuthHeaders().then((headers) => { cy.getAuthHeaders().then((headers) => {
cy.request({ cy.request({
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/v2/apps/${appId}`, url: `${Cypress.env("server_host")}/api/apps/${appId}`,
headers, headers,
}) })
.then((response) => { .then((response) => {
@ -539,7 +560,7 @@ Cypress.Commands.add("apiReleaseApp", (appName) => {
const editingVersionId = response.body.editing_version.id; const editingVersionId = response.body.editing_version.id;
cy.request({ cy.request({
method: "PUT", method: "PUT",
url: `${Cypress.env("server_host")}/api/v2/apps/${appId}/release`, url: `${Cypress.env("server_host")}/api/apps/${appId}/release`,
headers: headers, headers: headers,
body: { body: {
versionToBeReleased: editingVersionId, versionToBeReleased: editingVersionId,
@ -556,7 +577,6 @@ Cypress.Commands.add("apiReleaseApp", (appName) => {
Cypress.Commands.add("apiAddAppSlug", (appName, slug) => { Cypress.Commands.add("apiAddAppSlug", (appName, slug) => {
cy.getAppId(appName).then((appId) => { cy.getAppId(appName).then((appId) => {
cy.getAuthHeaders().then((headers) => { cy.getAuthHeaders().then((headers) => {
cy.request({ cy.request({
method: "PUT", method: "PUT",
url: `${Cypress.env("server_host")}/api/apps/${appId}`, url: `${Cypress.env("server_host")}/api/apps/${appId}`,
@ -576,7 +596,6 @@ Cypress.Commands.add("apiAddAppSlug", (appName, slug) => {
Cypress.Commands.add("apiGetTableIdByName", (tableName) => { Cypress.Commands.add("apiGetTableIdByName", (tableName) => {
cy.getAuthHeaders().then((headers) => { cy.getAuthHeaders().then((headers) => {
cy.request({ cy.request({
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/tooljet-db/organizations/${Cypress.env("workspaceId")}/tables`, url: `${Cypress.env("server_host")}/api/tooljet-db/organizations/${Cypress.env("workspaceId")}/tables`,
@ -594,7 +613,6 @@ Cypress.Commands.add("apiGetTableIdByName", (tableName) => {
Cypress.Commands.add("apiAddDataToTable", (tableName, data) => { Cypress.Commands.add("apiAddDataToTable", (tableName, data) => {
cy.apiGetTableIdByName(tableName).then((tableId) => { cy.apiGetTableIdByName(tableName).then((tableId) => {
cy.getAuthHeaders().then((headers) => { cy.getAuthHeaders().then((headers) => {
cy.request({ cy.request({
method: "POST", method: "POST",
url: `${Cypress.env("server_host")}/api/tooljet-db/proxy/${tableId}`, url: `${Cypress.env("server_host")}/api/tooljet-db/proxy/${tableId}`,
@ -612,7 +630,7 @@ Cypress.Commands.add("apiGetDataSourceIdByName", (dataSourceName) => {
cy.getAuthHeaders().then((headers) => { cy.getAuthHeaders().then((headers) => {
cy.request({ cy.request({
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/v2/data_sources`, url: `${Cypress.env("server_host")}/api/data-sources`,
headers: headers, headers: headers,
}).then((response) => { }).then((response) => {
expect(response.status).to.equal(200); expect(response.status).to.equal(200);
@ -670,7 +688,7 @@ Cypress.Commands.add(
cy.request({ cy.request({
method: "PUT", method: "PUT",
url: `${Cypress.env("server_host")}/api/v2/data_sources/${dataSourceId}?environment_id=${environmentId}`, url: `${Cypress.env("server_host")}/api/data-sources/${dataSourceId}?environment_id=${environmentId}`,
headers: headers, headers: headers,
body: mergedData, body: mergedData,
}).then((updateResponse) => { }).then((updateResponse) => {
@ -683,3 +701,15 @@ Cypress.Commands.add(
} }
); );
Cypress.Commands.add("apiGetAppData", (appId = Cypress.env("appId")) => {
cy.getAuthHeaders().then((headers) => {
cy.request({
method: "GET",
url: `${Cypress.env("server_host")}/api/apps/${appId}`,
headers: headers,
}).then((response) => {
expect(response.status).to.equal(200);
return response.body;
});
});
});

View file

@ -7,13 +7,14 @@ import { importSelectors } from "Selectors/exportImport";
import { importText } from "Texts/exportImport"; import { importText } from "Texts/exportImport";
import { onboardingSelectors } from "Selectors/onboarding"; import { onboardingSelectors } from "Selectors/onboarding";
const API_ENDPOINT =
Cypress.env("environment") === "Community"
? "/api/library_apps"
: "/api/library_apps/";
Cypress.Commands.add( Cypress.Commands.add(
"appUILogin", "appUILogin",
(email = "dev@tooljet.io", password = "password") => { (email = "dev@tooljet.io", password = "password") => {
const API_ENDPOINT =
Cypress.env("environment") === "Community"
? "/api/library_apps/"
: "/api/library_apps";
cy.visit("/"); cy.visit("/");
cy.wait(1000); cy.wait(1000);
cy.clearAndType(onboardingSelectors.loginEmailInput, email); cy.clearAndType(onboardingSelectors.loginEmailInput, email);
@ -142,13 +143,11 @@ Cypress.Commands.add(
}; };
if (Array.isArray(value)) { if (Array.isArray(value)) {
cy.wrap(subject) cy.wrap(subject).last().realType(value, {
.last() parseSpecialCharSequences: false,
.realType(value, { delay: 0,
parseSpecialCharSequences: false, force: true,
delay: 0, });
force: true,
});
} else { } else {
splitIntoFlatArray(value).forEach((i) => { splitIntoFlatArray(value).forEach((i) => {
cy.wrap(subject) cy.wrap(subject)
@ -305,19 +304,19 @@ Cypress.Commands.add("skipEditorPopover", () => {
}); });
Cypress.Commands.add("waitForAppLoad", () => { Cypress.Commands.add("waitForAppLoad", () => {
const API_ENDPOINT = // const API_ENDPOINT =
Cypress.env("environment") === "Community" // Cypress.env("environment") === "Community"
? "/api/v2/data_sources" // ? "/api/v2/data_sources"
: "/api/app-environments**"; // : "/api/app-environments**";
const TIMEOUT = 15000; // const TIMEOUT = 15000;
cy.intercept("GET", API_ENDPOINT).as("appDs"); cy.intercept("GET", "/api/data-queries/**").as("appDs");
cy.wait("@appDs", { timeout: TIMEOUT }); cy.wait("@appDs", { timeout: 15000 });
}); });
Cypress.Commands.add("visitTheWorkspace", (workspaceName) => { Cypress.Commands.add("visitTheWorkspace", (workspaceName) => {
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `select id from organizations where name='${workspaceName}';`, sql: `select id from organizations where name='${workspaceName}';`,
}).then((resp) => { }).then((resp) => {
@ -399,20 +398,13 @@ Cypress.Commands.add("getPosition", (componentName) => {
}); });
Cypress.Commands.add("defaultWorkspaceLogin", () => { Cypress.Commands.add("defaultWorkspaceLogin", () => {
cy.task("updateId", { cy.apiLogin();
dbconfig: Cypress.env("app_db"),
sql: `
SELECT id FROM organizations WHERE name = 'My workspace';
`,
}).then((resp) => {
const workspaceId = resp.rows[0].id;
cy.apiLogin("dev@tooljet.io", "password", workspaceId, "/my-workspace");
cy.visit("/"); cy.visit("/my-workspace");
cy.intercept("GET", "/api/library_apps").as("library_apps"); cy.intercept("GET", API_ENDPOINT).as("library_apps");
cy.get(commonSelectors.homePageLogo, { timeout: 10000 }); cy.get(commonSelectors.homePageLogo, { timeout: 10000 });
cy.wait("@library_apps"); cy.wait("@library_apps");
}); // });
}); });
Cypress.Commands.add( Cypress.Commands.add(
@ -458,13 +450,13 @@ Cypress.Commands.add("releaseApp", () => {
Cypress.Commands.add("backToApps", () => { Cypress.Commands.add("backToApps", () => {
cy.get(commonSelectors.editorPageLogo).click(); cy.get(commonSelectors.editorPageLogo).click();
cy.get(commonSelectors.backToAppOption).click(); cy.get(commonSelectors.backToAppOption).click();
cy.intercept("GET", "/api/library_apps/").as("library_apps"); cy.intercept("GET", API_ENDPOINT).as("library_apps");
cy.get(commonSelectors.homePageLogo, { timeout: 10000 }); cy.get(commonSelectors.homePageLogo, { timeout: 10000 });
cy.wait("@library_apps"); cy.wait("@library_apps");
}); });
Cypress.Commands.add("removeAssignedApps", () => { Cypress.Commands.add("removeAssignedApps", () => {
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `DELETE FROM app_group_permissions;`, sql: `DELETE FROM app_group_permissions;`,
}); });
@ -503,7 +495,7 @@ Cypress.Commands.add("skipWalkthrough", () => {
Cypress.Commands.add("appPrivacy", (appName, isPublic) => { Cypress.Commands.add("appPrivacy", (appName, isPublic) => {
const isPublicValue = isPublic ? "true" : "false"; const isPublicValue = isPublic ? "true" : "false";
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `UPDATE apps SET is_public = ${isPublicValue} WHERE name = '${appName}';`, sql: `UPDATE apps SET is_public = ${isPublicValue} WHERE name = '${appName}';`,
}); });
@ -535,10 +527,12 @@ Cypress.Commands.add("loginWithCredentials", (email, password) => {
cy.clearAndType(onboardingSelectors.loginEmailInput, email); cy.clearAndType(onboardingSelectors.loginEmailInput, email);
cy.clearAndType(onboardingSelectors.loginPasswordInput, password); cy.clearAndType(onboardingSelectors.loginPasswordInput, password);
cy.get(onboardingSelectors.signInButton).click(); cy.get(onboardingSelectors.signInButton).click();
cy.wait(3000);
cy.get(commonSelectors.pageLogo).should("be.visible");
}); });
Cypress.Commands.add("getAppId", (appName) => { Cypress.Commands.add("getAppId", (appName) => {
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `select id from apps where name='${appName}';`, sql: `select id from apps where name='${appName}';`,
}).then((resp) => { }).then((resp) => {

View file

@ -0,0 +1,62 @@
export const pluginSelectors = {
regionField: '[data-cy="region-section"] .react-select__control',
regionFieldValue: '[data-cy="region-section"] .react-select__single-value',
amazonsesAccesKey: '[data-cy="access-key-text-field"]',
operationDropdown: '[data-cy="operation-select-dropdown"]',
sendEmailInputField: '[data-cy="send-mail-to-input-field"]',
ccEmailInputField: '[data-cy="cc-to-input-field"]',
bccEmailInputField: '[data-cy="bcc-to-input-field"]',
sendEmailFromInputField: '[data-cy="send-mail-from-input-field"]',
emailSubjetInputField: '[data-cy="subject-input-field"]',
emailbodyInputField: '[data-cy="body-input-field"]',
amazonAthenaDbName: '[data-cy="database-text-field"]',
};
export const baserowSelectors = {
hostField: '[data-cy="host-select-dropdown"]',
baserowApiKey: '[data-cy="api-token-text-field"]',
table: '[data-cy="table-id-input-field"]',
rowIdinputfield: '[data-cy="row-id-input-field"]',
};
export const appWriteSelectors = {
projectID: '[data-cy="project-id-text-field"]',
collectionId: '[data-cy="collectionid-input-field"]',
documentId: '[data-cy="documentid-input-field"]',
bodyInput: '[data-cy="body-input-field"]',
};
export const twilioSelectors = {
toNumberInputField: '[data-cy="to-number-input-field"]',
bodyInput: '[data-cy="body-input-field"]',
};
export const minioSelectors = {
sslToggle: 'data-cy="ssl-enabled-toggle-input"',
bucketNameInputField: '[data-cy="bucket-input-field"]',
objectNameInputField: '[data-cy="objectname-input-field"]',
contentTypeInputField: '[data-cy="contenttype-input-field"]',
dataInput: '[data-cy="data-input-field"]',
};
export const harperDbSelectors = {
recordsInputField: '[data-cy="records-input-field"]',
hashValueInputField: '[data-cy="hash-values-input-field"]',
attributesInputField: '[data-cy="attributes-input-field"]',
searchValueInputField: '[data-cy="search-value-input-field"]',
searchAttributeInputField: '[data-cy="search-attribute-input-field"]',
conditionInputField: '[data-cy="conditions-input-field"]',
sqlQueryInputField: '[data-cy="sql-query-input-field"]',
schemaInputField: '[data-cy="schema-input-field"]',
TableInputField: '[data-cy="table-input-field"]',
};
export const awsTextractSelectors = {
documentInputField: '[data-cy="document-input-field"]',
bucketNameInputField: '[data-cy="bucket-input-field"]',
keyNameInputField: '[data-cy="key-input-field"]',
};
export const graphQLSelectors = {
urlInputField: '[data-cy="url-text-field"]',
};

View file

@ -5,5 +5,5 @@ export const s3Selector = {
regionLabel: '[data-cy="label-region"]', regionLabel: '[data-cy="label-region"]',
customEndpointLabel: '[data-cy="label-custom-endpoint"]', customEndpointLabel: '[data-cy="label-custom-endpoint"]',
customEndpointInput: '[data-cy="undefined-text-field"]', customEndpointInput: '[data-cy="undefined-text-field"]',
dataSourceNameInput: '[data-cy="data-source-name-input-filed"]', dataSourceNameInput: '[data-cy="data-source-name-input-field"]',
}; };

View file

@ -14,7 +14,7 @@ export const dataSourceSelector = {
dataSourceSearchInputField: '[data-cy="home-page-search-bar"]', dataSourceSearchInputField: '[data-cy="home-page-search-bar"]',
postgresDataSource: "[data-cy='data-source-postgresql']", postgresDataSource: "[data-cy='data-source-postgresql']",
dataSourceNameInputField: '[data-cy="data-source-name-input-filed"]', dataSourceNameInputField: '[data-cy="added-ds-search-bar"]',
labelHost: '[data-cy="label-host"]', labelHost: '[data-cy="label-host"]',
labelPort: '[data-cy="label-port"]', labelPort: '[data-cy="label-port"]',
labelSsl: '[data-cy="label-ssl"]', labelSsl: '[data-cy="label-ssl"]',
@ -97,7 +97,7 @@ export const dataSourceSelector = {
eventQuerySelectionField: '[data-cy="query-selection-field"]', eventQuerySelectionField: '[data-cy="query-selection-field"]',
addedDsSearchIcon: '[data-cy="added-ds-search-icon"]', addedDsSearchIcon: '[data-cy="added-ds-search-icon"]',
AddedDsSearchBar: '[data-cy="added-ds-search-bar"]', AddedDsSearchBar: '[data-cy="added-ds-search-bar"]',
dsNameInputField: '[data-cy="data-source-name-input-filed"]', dsNameInputField: '[data-cy="data-source-name-input-field"]',
unSavedModalTitle: '[data-cy="unsaved-changes-title"]', unSavedModalTitle: '[data-cy="unsaved-changes-title"]',
eventQuerySelectionField: '[data-cy="query-selection-field"]', eventQuerySelectionField: '[data-cy="query-selection-field"]',
connectionAlertText: '[data-cy="connection-alert-text"]', connectionAlertText: '[data-cy="connection-alert-text"]',

View file

@ -6,7 +6,7 @@ export const groupsSelector = {
createNewGroupButton: "[data-cy=create-new-group-button]", createNewGroupButton: "[data-cy=create-new-group-button]",
tableHeader: "[data-cy=table-header]", tableHeader: "[data-cy=table-header]",
groupName: "[data-cy=group-name]", groupName: "[data-cy=group-name]",
addNewGroupModalTitle: '[data-cy="create-new-group-title"]', addNewGroupModalTitle: '[data-cy="add-new-group-title"]',
groupNameInput: "[data-cy=group-name-input]", groupNameInput: "[data-cy=group-name-input]",
cancelButton: "[data-cy=cancel-button]", cancelButton: "[data-cy=cancel-button]",
workspaceVarCreateLabel: '[data-cy="workspace-variable-create-label"]', workspaceVarCreateLabel: '[data-cy="workspace-variable-create-label"]',

View file

@ -12,7 +12,7 @@ export const postgreSqlSelector = {
dataSourceSearchInputField: '[data-cy="home-page-search-bar"]', dataSourceSearchInputField: '[data-cy="home-page-search-bar"]',
postgresDataSource: "[data-cy='data-source-postgresql']", postgresDataSource: "[data-cy='data-source-postgresql']",
dataSourceNameInputField: '[data-cy="data-source-name-input-filed"]', dataSourceNameInputField: '[data-cy="data-source-name-input-field"]',
labelHost: '[data-cy="label-host"]', labelHost: '[data-cy="label-host"]',
labelPort: '[data-cy="label-port"]', labelPort: '[data-cy="label-port"]',
labelSsl: '[data-cy="label-ssl"]', labelSsl: '[data-cy="label-ssl"]',
@ -88,3 +88,11 @@ export const postgreSqlSelector = {
eventQuerySelectionField: '[data-cy="query-selection-field"]', eventQuerySelectionField: '[data-cy="query-selection-field"]',
}; };
export const airTableSelector = {
operationSelectDropdown: '[data-cy="operation-select-dropdown"]',
baseIdInputField: '[data-cy="base-id-input-field"]',
tableNameInputField: '[data-cy="table-name-input-field"]',
recordIdInputField: '[data-cy="record-id-input-field"]',
bodyInputField: '[data-cy="body-input-field"]',
};

View file

@ -0,0 +1,44 @@
export const cyParamName = (paramName = "") => {
return String(paramName)
.toLowerCase()
.replace(/\(s\)/g, "")
.replace(/\s+/g, "-");
};
export const restAPISelector = {
accordionHeader: (header) => {
return `[data-cy="widget-accordion-${cyParamName(header)}"]`;
},
subHeaderLabel: (header) => {
return `[data-cy="label-${cyParamName(header)}"]`;
},
subSection: (header) => {
return `[data-cy="${cyParamName(header)}-section"]`;
},
keyInputField: (header, index) => {
return `[data-cy="${cyParamName(header)}-key-input-field-${cyParamName(index)}"]`;
},
valueInputField: (header, index) => {
return `[data-cy="${cyParamName(header)}-value-input-field-${cyParamName(index)}"]`;
},
deleteButton: (header, index) => {
return `[data-cy="${cyParamName(header)}-delete-button-${cyParamName(index)}"]`;
},
addMoreButton: (header) => {
return `[data-cy="${cyParamName(header)}-add-more-button"]`;
},
dropdownLabel: (label) => {
return `[data-cy="${cyParamName(label)}-dropdown-label"]`;
},
inputField: (fieldName) => {
return `[data-cy="${cyParamName(fieldName)}-input-field"]`;
},
button: (buttonName) => {
return `[data-cy="button-${cyParamName(buttonName)}"]`;
},
authenticationAllUsersToggleSwitch:
'[data-cy="authentication-required-for-all-users-toggle-switch"]',
retryNetworkToggleSwitch: '[data-cy="retry-network-errors-toggle-input"]',
retryNetworkToggleText: '[data-cy="retry-network-errors-toggle-text"]',
retryNetworkToggleSubtext: '[data-cy="retry-network-errors-toggle-subtext"]',
readDocumentationLinkText: '[data-cy="link-read-documentation"]',
};

View file

@ -0,0 +1,6 @@
export const airtableText = {
airtable: "Airtable",
cypressairtable: "cypress-Airtable",
ApiKey: "Personal access token",
apikeyPlaceholder: "**************",
};

View file

@ -0,0 +1,8 @@
export const amazonAthenaText = {
AmazonAthena: "Amazon Athena",
cypressAmazonAthena: "cypress-Amazon Athena",
labelAccesskey: "Access key",
labelSecretKey: "Secret key",
placeholderEnteraAccessKey: "Enter access key",
placeholderSecretKey:"**************",
};

View file

@ -0,0 +1,8 @@
export const amazonSesText = {
AmazonSES: "Amazon SES",
cypressAmazonSES: "cypress-Amazon SES",
labelAccesskey: "Access key",
labelSecretKey: "Secret key",
placeholderAccessKey: "Enter access key",
placeholderSecretKey:"**************",
};

View file

@ -0,0 +1,12 @@
export const appwriteText = {
appwrite: "Appwrite",
cypressAppwrite: "cypress-Appwrite",
host: "Host",
ProjectID: "Project ID",
DatabaseID: "Database ID",
SecretKey: "Secret Key",
SecretKeyPlaceholder: "**************",
hostPlaceholder: "Appwrite database host/endpoint",
projectIdPlaceholder: "Appwrite project id",
databaseIdPlaceholder: "Appwrite Database id",
};

View file

@ -0,0 +1,8 @@
export const awsLambdaText = {
awsLambda: "AWS Lambda",
cypressawsLambda: "cypress-aws-lambda",
labelAccesskey: "Access key",
labelSecretKey: "Secret key",
placeholderAccessKey: "Enter access key",
placeholderSecretKey: "**************",
};

View file

@ -0,0 +1,12 @@
export const awsTextractText = {
awsTextract: "AWS Textract",
cypressawsLambda: "cypress-aws-textract",
labelAccesskey: "Access key",
labelSecretKey: "Secret key",
placeholderAccessKey: "Enter access key",
placeholderSecretKey: "**************",
documentName:
"JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA0IDAgUiA+PiA+PiAvQ29udGVudHMgNSAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhLUJvbGQgPj4KZW5kb2JqCjUgMCBvYmoKPDwgL0xlbmd0aCAxMjUgPj4Kc3RyZWFtCkJUIC9GMSAxMiBUZiAxMDAgNzAwIFRkICgoSGVsbG8sIEFtYXpvbiBUZXh0cmFjdCEpIFRqIEVUCmVuZHN0cmVhbQplbmRvYmoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDExIDAwMDAwIG4gCjAwMDAwMDAwNTQgMDAwMDAgbgAKMDAwMDAwMDEwMyAwMDAwMCBuIAowMDAwMDAwMTcyIDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNiAvUm9vdCAxIDAgUiA+PgpzdGFydHhyZWYKMjIzCiUlRU9G",
bucketName: "reimbursement-receipt-files",
keyName: "reimbursement_receipt_1718364944018.png",
};

View file

@ -0,0 +1,6 @@
export const baseRowText = {
baserow: "baserow",
cypressBaseRow: "cypress-baserow",
lableApiToken: "API token",
placeholderApiToken:"**************",
};

View file

@ -173,7 +173,7 @@ export const commonText = {
// iframeLinkLabel: "Get embeddable link for this application", // iframeLinkLabel: "Get embeddable link for this application",
// ifameLinkCopyButton: "copy", // ifameLinkCopyButton: "copy",
}, },
groupInputFieldLabel: "Select Group", groupInputFieldLabel: "Select groups",
documentationLink: "Read Documentation", documentationLink: "Read Documentation",
constantsNameError: constantsNameError:
"Constant name should start with a letter or underscore and can only contain letters, numbers and underscores", "Constant name should start with a letter or underscore and can only contain letters, numbers and underscores",
@ -181,7 +181,7 @@ export const commonText = {
"Value should be less than 10000 characters and cannot be empty", "Value should be less than 10000 characters and cannot be empty",
createApp: "Create app", createApp: "Create app",
appName: "App Name", appName: "App name",
enterAppName: "Enter app name", enterAppName: "Enter app name",
appNameInfoLabel: "App name must be unique and max 50 characters", appNameInfoLabel: "App name must be unique and max 50 characters",
renameApp: "Rename app", renameApp: "Rename app",

View file

@ -80,4 +80,11 @@ export const dataSourceText = {
labelNoEventhandler: "No event handlers", labelNoEventhandler: "No event handlers",
toastDSSaved: "Data Source Saved", toastDSSaved: "Data Source Saved",
unSavedModalTitle: "Unsaved Changes", unSavedModalTitle: "Unsaved Changes",
sslCertificateLabel: "SSL Certificate",
caCertificateOption: "CA certificate",
clientCertificateOption: "Client certificate",
clientKeyLabel: "Client Key",
clientCertLabel: "Client Cert",
caCertLabel: "CA Cert",
}; };

View file

@ -1,7 +1,7 @@
export const appVersionText = { export const appVersionText = {
createNewVersion: "Create new version", createNewVersion: "Create new version",
createVersion: "Create Version", createVersion: "Create Version",
versionNameLabel: "Version Name", versionNameLabel: "Version name",
createVersionFromLabel: "Create version from", createVersionFromLabel: "Create version from",
emptyToastMessage: "Version name should not be empty", emptyToastMessage: "Version name should not be empty",
createdToastMessage: "Version Created", createdToastMessage: "Version Created",

View file

@ -0,0 +1,6 @@
export const GraphQLText = {
GraphQL: "GraphQL",
cypressGraphQL: "cypress-GraphQL",
urlInputLabel: "URL",
urlInputPlaceholder: "https://api.example.com/v1/graphql",
};

View file

@ -0,0 +1,21 @@
export const harperDbText = {
harperDb: "HarperDB",
cypressHarperDB: "cypressHarperDB",
hostLabel: "Host",
hostInputPlaceholder: "Enter host",
portLabel: "Port",
portPlaceholder: "Enter port",
userNameLabel: "Username",
passwordlabel: "Password",
userNamePlaceholder: "Enter username",
passwordPlaceholder: "**************",
recordsValue: `[{id: 10, name: 'QA', age: 24}]`,
hashValue: "[10]",
attributesValue: "['name']",
searchAttributeValue: "name",
searchValue: "QA",
condtionValue: `[{'search_attribute': 'name', 'search_type': 'between', 'search_value': [1, 5]}, {'search_attribute': 'name', 'search_type': 'equals', 'search_value': 'QA'}]`,
sqlValue: "SELECT * FROM test_schema.test_table",
schemaValue: "test_schema",
tableValue: "test_table",
};

View file

@ -1,10 +1,10 @@
export const groupsText = { export const groupsText = {
pageTitle: "User Groups", pageTitle: "User Groups",
createNewGroupButton: "Create new group", createNewGroupButton: "Add new group",
tableHeader: "Name", tableHeader: "Name",
allUsers: "All users", allUsers: "All users",
admin: "Admin", admin: "Admin",
cardTitle: "Create new group", cardTitle: "Add new group",
cancelButton: "Cancel", cancelButton: "Cancel",
createGroupButton: "Create Group", createGroupButton: "Create Group",
groupNameExistToast: "Group name already exist", groupNameExistToast: "Group name already exist",
@ -52,7 +52,7 @@ export const groupsText = {
editGroupNameButton: "Rename", editGroupNameButton: "Rename",
deleteGroupButton: "Delete group", deleteGroupButton: "Delete group",
editPermissionModalTitle: "Edit app permissions", editPermissionModalTitle: "Edit app permissions",
addPermissionModalTitle: "Add app permissions", addPermissionModalTitle: "Add apps permissions",
appCreateHelperText: 'Create apps in this workspace', appCreateHelperText: 'Create apps in this workspace',
appDeleteHelperText: 'Delete any app in this workspace', appDeleteHelperText: 'Delete any app in this workspace',
appEditLabelText: 'Edit', appEditLabelText: 'Edit',
@ -63,7 +63,7 @@ export const groupsText = {
appHideLabel: "Hide from dashboard", appHideLabel: "Hide from dashboard",
appHideLabelPermissionModal: "Hide from dashbaord", appHideLabelPermissionModal: "Hide from dashbaord",
groupChipText: 'All apps', groupChipText: 'All apps',
adminAccessHelperText: " Admin has edit access to all apps. These are not editableread documentation to know more !", adminAccessHelperText: " Admin has all permissions. This is not editableread documentation to know more !",
enduserAccessHelperText: " End-user can only have permission to view appsread documentation to know more !", enduserAccessHelperText: " End-user can only have permission to view appsread documentation to know more !",
nameTableHeader: 'Name', nameTableHeader: 'Name',
permissionTableHeader: 'Permission', permissionTableHeader: 'Permission',
@ -85,19 +85,19 @@ export const groupsText = {
warningText: "Users must be always be part of one default group. This will define the user count in your plan.", warningText: "Users must be always be part of one default group. This will define the user count in your plan.",
continueButtonText: "Continue", continueButtonText: "Continue",
roleUpdateToastMessage: "Role updated successfully", roleUpdateToastMessage: "Role updated successfully",
endUserToBuilderMessage: "Updating the user's details will change their role from end-user to builder. Are you sure you want to continue?", endUserToBuilderMessage: "Changing the user role from end-user to builder will grant access the user access to all resources.Are you sure you want to continue?",
endUserToAdminMessage: "Updating the user's details will change their role from end-user to admin. Are you sure you want to continue?", endUserToAdminMessage: "Changing the user role from end-user to admin will grant the user access to all resources and settings.Are you sure you want to continue?",
builderToEnduserMessage: "This will also remove the user from any custom groups with builder-like permissions.Are you sure you want to continue?", builderToEnduserMessage: "Changing the user role from builder to end-user will revoke their access to edit all resources.Are you sure you want to continue?",
builderToAdminMessage: "Changing user role from builder to admin will grant access to all resources and settings.Are you sure you want to continue?", builderToAdminMessage: "Changing user role from builder to admin will grant access to all resources and settings.Are you sure you want to continue?",
adminToBuilderMessage: "Changing your user default group from admin to builder will revoke your access to settings.Are you sure you want to continue?", adminToBuilderMessage: "Changing your user default group from admin to builder will revoke your access to settings.Are you sure you want to continue?",
adminToEnduserMessage: "Changing your user group from admin to end-user will revoke your access to settings.Are you sure you want to continue?", adminToEnduserMessage: "Changing the user role from admin to end-user will revoke their access to edit all resources and settings.Are you sure you want to continue?",
modalHeader: "Can not remove last active admin", modalHeader: "Can not remove last active admin",
modalMessage: "Cannot change role of last present admin, please add another admin and change the role", modalMessage: "Cannot change role of last present admin, please add another admin and change the role",
userAddedToast: "Users added to the group", userAddedToast: "Users added to the group",
changeUserRoleHeader: " Change in user role", changeUserRoleHeader: " Change in user role",
changeUserRoleMessage: "Granting this permission to the user group will result in a role change for the following user(s) from end-users to builders. Are you sure you want to continue?", changeUserRoleMessage: "Granting this permission to the user group will result in a role change for the following user(s) from end-users to builders. Are you sure you want to continue?",
cantCreatePermissionModalHeader: "Cannot create permissions", cantCreatePermissionModalHeader: "Cannot create permissions",
cantCreatePermissionModalMessage: "Cannot assign builder level permission to end users", cantCreatePermissionModalMessage: "End-users can only be granted permission to view apps. If you wish to add this permission, kindly change the following users role from end-user to builder",
deletePermissionToast: "Deleted permission successfully", deletePermissionToast: "Deleted permission successfully",
createPermissionToast: "Permission created successfully!", createPermissionToast: "Permission created successfully!",
userEmptyPageTitle: "No users added yet", userEmptyPageTitle: "No users added yet",

View file

@ -57,7 +57,7 @@ export const usersText = {
buttonUploadCsvFile: "Upload CSV file", buttonUploadCsvFile: "Upload CSV file",
helperTextBulkUpload: helperTextBulkUpload:
"Download the ToolJet template to add user details or format your file in the same as the template. ToolJet wont be able to recognise files in any other format. ", "Download the template to add user details or format your file in the same way as the template. Files in any other format may not be recognized. ",
helperTextSelectFile: "Select a CSV file to upload", helperTextSelectFile: "Select a CSV file to upload",
helperTextDropFile: "Or drag and drop it here", helperTextDropFile: "Or drag and drop it here",
}; };

View file

@ -0,0 +1,14 @@
export const minioText = {
minio: "Minio",
cypressMinio: "cypressMinio",
hostLabel: "Host",
hostInputPlaceholder: "Enter host",
portLabel: "Port",
portPlaceholder: "Enter port",
labelAccesskey: "Access key",
labelSecretKey: "Secret key",
placeholderAccessKey: "Enter access key",
placeholderSecretKey: "**************",
bucketName: `my-second-bucket`,
objectName: `mybucket`,
};

View file

@ -5,7 +5,7 @@ export const postgreSqlText = {
allDataSources: () => { allDataSources: () => {
return Cypress.env("marketplace_action") return Cypress.env("marketplace_action")
? "All data sources (44)" ? "All data sources (44)"
: "All data sources (42)"; : "All data sources (43)";
}, },
commonlyUsed: "Commonly used (5)", commonlyUsed: "Commonly used (5)",
allDatabase: () => { allDatabase: () => {
@ -13,7 +13,7 @@ export const postgreSqlText = {
? "Databases (20)" ? "Databases (20)"
: "Databases (18)"; : "Databases (18)";
}, },
allApis: "APIs (20)", allApis: "APIs (21)",
allCloudStorage: "Cloud Storages (4)", allCloudStorage: "Cloud Storages (4)",
postgreSQL: "PostgreSQL", postgreSQL: "PostgreSQL",

View file

@ -2,8 +2,7 @@ export const redisText = {
redis: "Redis", redis: "Redis",
cypressRedis: "cypress-redis", cypressRedis: "cypress-redis",
errorMaxRetries: errorMaxRetries: "Connection could not be established",
'Reached the max retries per request limit (which is 1). Refer to "maxRetriesPerRequest" option for details.', errorPort: "Connection could not be established",
errorPort: "Port should be >= 0 and < 65536. Received type number (108299).", errorInvalidUserOrPassword: "Connection could not be established",
errorInvalidUserOrPassword: "WRONGPASS invalid username-password pair",
}; };

View file

@ -0,0 +1,58 @@
export const restAPIText = {
restAPI: "REST API",
credentialsText: "CREDENTIALS",
baseUrlLabel: "Base URL",
headersLabel: "Headers",
urlParametesLabel: "URL parameters",
bodyLabel: "Body",
cookiesLabel: "Cookies",
authenticationText: "AUTHENTICATION",
authenticationTypeLabel: "Authentication type",
noneText: "None",
editButtonText: "Edit",
basicAuth: {
basicText: "Basic",
usernameLabel: "Username",
passwordLabel: "Password",
},
bearerAuth: {
bearerText: "Bearer",
tokenLabel: "Token",
},
oAuthText: "OAuth 2.0",
grantTypeLabel: "Grant type",
authorizationCode: {
authorizationCodeLabel: "Authorization code",
addAccessTokenLabel: "Add access token to",
headerPrefixLabel: "Header prefix",
requestHeader: "Request header",
accessTokenURLLabel: "Access token URL",
accessTokenURLCustomHeadersLabel: "Access token URL custom headers",
clientIDLabel: "Client ID",
clientSecretLabel: "Client secret",
scopeLabel: "Scope(s)",
customQueryParametersLabel: "Custom query parameters",
authorizationURLLabel: "Authorization URL",
customAuthenticationParametersLabel: "Custom authentication parameters",
clientAuthentication: "Client authentication",
sendBasicAuthheaderOption: "Send as basic auth header",
sendClientCredentialsBodyOption: "Send client credentials in body",
authenticationRequiredUsersToggle: "Authentication required for all users",
},
clientCredentials: {
clientCredentialsLabel: "Client credentials",
accessTokenURLLabel: "Access token URL",
accessTokenURLCustomHeadersLabel: "Access token URL custom headers",
clientIDLabel: "Client ID",
clientSecretLabel: "Client secret",
scopeLabel: "Scope(s)",
audiencelabel: "Audience",
},
authenticationHeader: "Authentication",
secureSocketsLayerText: "SECURE SOCKETS LAYER",
generalSettingsText: "GENERAL SETTINGS",
retryNetworkErrorsToggleLabel: "Retry on network errors",
retryToggleHelperText:
"By default, ToolJet tries to hit API endpoint 3 times before declaring query failed as server did not respond",
};

View file

@ -0,0 +1,11 @@
export const twilioText = {
twilio: "Twilio",
cypresstwilio: "cypress-Twilio",
authTokenLabel: "Auth Token",
authTokenPlaceholder: "**************",
accountSidLabel: "Account SID",
accountSidPlaceholder: "Account SID for Twilio",
messagingSIDLabel: "Messaging Service SID",
messagingSIDPalceholder: "Messaging Service SID for Twilio",
messageText: "Sending test message to check twilio",
};

View file

@ -8,7 +8,11 @@ export const editVersionText = {
export const deleteVersionText = { export const deleteVersionText = {
deleteModalText: (text) => { deleteModalText: (text) => {
return `Are you sure you want to delete this version - ${cyParamName( // return `Are you sure you want to delete this version - ${cyParamName(
// text
// )}?`;
return `Deleting a version will permanently remove it from all environments.Are you sure you want to delete this version - ${cyParamName(
text text
)}?`; )}?`;
}, },
@ -19,9 +23,13 @@ export const deleteVersionText = {
export const onlydeleteVersionText = { export const onlydeleteVersionText = {
deleteModalText: (text) => { deleteModalText: (text) => {
return `Are you sure you want to delete this version - ${cyParamName( return `Deleting a version will permanently remove it from all environments.Are you sure you want to delete this version - ${cyParamName(
text text
)}?`; )}?`;
// `Are you sure you want to delete this version - ${cyParamName(
// text
// )}?`;
}, },
deleteToastMessage: (version) => { deleteToastMessage: (version) => {
return `Cannot delete only version of app`; return `Cannot delete only version of app`;

View file

@ -43,8 +43,10 @@ describe("Editor title", () => {
cy.apiDeleteApp(); cy.apiDeleteApp();
}); });
it("should verify titles", () => { it("should verify titles", () => {
cy.url().should("include", "/my-workspace"); cy.url().should("include", "/tjs-workspace");
cy.title().should("eq", "Dashboard | ToolJet"); // cy.title().should("eq", "Dashboard | ToolJet");
cy.title().should("eq", "ToolJet");
cy.log(data.appName); cy.log(data.appName);
cy.openApp(); cy.openApp();
@ -54,12 +56,20 @@ describe("Editor title", () => {
cy.openInCurrentTab(commonWidgetSelector.previewButton); cy.openInCurrentTab(commonWidgetSelector.previewButton);
cy.url().should("include", `/applications/${Cypress.env("appId")}`); cy.url().should("include", `/applications/${Cypress.env("appId")}`);
cy.title().should("eq", `Preview - ${data.appName} | ToolJet`); cy.title().should("eq", `${data.appName} | ToolJet`);
// cy.title().should("eq", `Preview - ${data.appName} | ToolJet`);
cy.go("back"); cy.go("back");
cy.releaseApp(); cy.releaseApp();
cy.url().then((url) => cy.visit(`/applications/${url.split("/").pop()}`)); cy.url().then((url) => {
const appId = url.split("/").filter(Boolean).pop();
cy.log(appId);
cy.visit(`/applications/${appId}`);
});
cy.url().should("include", `/applications/${Cypress.env("appId")}`); cy.url().should("include", `/applications/${Cypress.env("appId")}`);
cy.title().should("eq", `${data.appName}`); cy.title().should("eq", `${data.appName} | ToolJet`);
// cy.title().should("eq", `${data.appName}`);
}); });
}); });

View file

@ -35,13 +35,13 @@ describe("Editor- Global Settings", () => {
"have.text", "have.text",
"Global settings" "Global settings"
); );
cy.get( // cy.get(
'[data-cy="label-hide-header-for-launched-apps"]' // '[data-cy="label-hide-header-for-launched-apps"]'
).verifyVisibleElement("have.text", "Hide header for launched apps"); // ).verifyVisibleElement("have.text", "Hide header for launched apps");
cy.get('[data-cy="label-maintenance-mode"]').verifyVisibleElement( // cy.get('[data-cy="label-maintenance-mode"]').verifyVisibleElement(
"have.text", // "have.text",
"Maintenance mode" // "Maintenance mode"
); // );
cy.hideTooltip(); cy.hideTooltip();
cy.get('[data-cy="label-max-canvas-width"]').verifyVisibleElement( cy.get('[data-cy="label-max-canvas-width"]').verifyVisibleElement(
"have.text", "have.text",
@ -60,7 +60,7 @@ describe("Editor- Global Settings", () => {
); );
verifyWidgetColorCss( verifyWidgetColorCss(
".canvas-area", '[data-cy="real-canvas"]',
"background-color", "background-color",
data.backgroundColor, data.backgroundColor,
true true
@ -87,24 +87,25 @@ describe("Editor- Global Settings", () => {
cy.get("[data-cy='left-sidebar-settings-button']").click(); cy.get("[data-cy='left-sidebar-settings-button']").click();
cy.get('[data-cy="toggle-maintenance-mode"]').realClick(); cy.get('[data-cy="toggle-maintenance-mode"]').realClick();
cy.get('[data-cy="modal-confirm-button"]').click(); cy.get('[data-cy="modal-confirm-button"]').click();
cy.verifyToastMessage( // cy.verifyToastMessage(
commonSelectors.toastMessage, // commonSelectors.toastMessage,
"Application is on maintenance.", // "Application is on maintenance.",
false // false
); // );
cy.forceClickOnCanvas(); cy.forceClickOnCanvas();
cy.wait(500); cy.wait(500);
cy.waitForAutoSave(); cy.waitForAutoSave();
//Fix this after the release. 2.9.0 // Fix this after the release. 2.9.0
// cy.get('[data-cy="button-release"]').click(); cy.get('[data-cy="button-release"]').click();
// cy.get('[data-cy="yes-button"]').click(); cy.get('[data-cy="yes-button"]').click();
// cy.get('[data-cy="editor-page-logo"]').click(); cy.get('[data-cy="editor-page-logo"]').click();
// cy.get(`[data-cy="${data.appName.toLowerCase()}-card"]`) cy.get('[data-cy="back-to-app-option"]').click();
// .realHover() cy.get(`[data-cy="${data.appName.toLowerCase()}-card"]`)
// .find('[data-cy="launch-button"]') .realHover().within(() => {
// .invoke("attr", "class") cy.get('[data-cy="launch-button"]').should('have.text', 'Maintenance')
// .should("contains", "disabled-btn"); .invoke("attr", "class")
.should("contains", "disabled-btn");
})
cy.apiDeleteApp(); cy.apiDeleteApp();
}); });
}); });

View file

@ -0,0 +1,218 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql";
import { commonSelectors } from "Selectors/common";
import { selectAndAddDataSource } from "Support/utils/postgreSql";
import { closeDSModal } from "Support/utils/dataSource";
const data = {};
data.dsNamefake = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
data.dsNamefake1 = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
const cyParamName = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, "-");
data.workspaceName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
data.workspaceSlug = fake.lastName.toLowerCase().replace(/\s+/g, "-");
const dataSources = [
"BigQuery",
"ClickHouse",
"CosmosDB",
"CouchDB",
"Databricks",
"DynamoDB",
"Elasticsearch",
"Firestore",
"InfluxDB",
"MariaDB",
"MongoDB",
"SQL Server",
"MySQL",
"Oracle DB",
"PostgreSQL",
"Redis",
"RethinkDB",
"SAP HANA",
"Snowflake",
"TypeSense",
"Airtable",
"Amazon SES",
"Appwrite",
"Amazon Athena",
"Baserow",
// "Google Sheets", need to remove
"GraphQL",
// "gRPC", need to remove
"Mailgun",
"n8n",
"Notion",
"OpenAPI",
"REST API",
"SendGrid",
// "Slack", need to remove
"SMTP",
"Stripe",
"Twilio",
"Woocommerce",
//"Zendesk", need to remove
"Azure Blob Storage",
"GCS",
"Minio",
"AWS S3",
];
describe("Add all Data sources to app", () => {
beforeEach(() => {
cy.apiLogin();
});
it("Should verify global data source page", () => {
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
cy.visit(`${data.workspaceSlug}`);
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
});
it("Should add all data sources in data source page", () => {
cy.visit(`${data.workspaceSlug}`);
dataSources.forEach((dsName) => {
cy.get(commonSelectors.globalDataSourceIcon).click();
selectAndAddDataSource("databases", dsName, dsName); // Using the correct fake name
// Test connection
// cy.get(postgreSqlSelector.buttonTestConnection).click();
// cy.get(postgreSqlSelector.textConnectionVerified, {
// timeout: 10000,
// }).should("have.text", postgreSqlText.labelConnectionVerified);
// // Save data source
// cy.get(postgreSqlSelector.buttonSave).click();
// cy.verifyToastMessage(
// commonSelectors.toastMessage,
// `Data Source ${dsName} saved.`
// );
});
});
it("Should add all data sources in the app", () => {
cy.visit(`${data.workspaceSlug}`);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsNamefake);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.wrap(dataSources).each((dsName) => {
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(
`cypress-${cyParamName(dsName)}-${cyParamName(dsName)}`
);
cy.wait(500);
cy.contains(
`[id*="react-select-"]`,
`cypress-${cyParamName(dsName)}-${cyParamName(dsName)}`
)
.should("be.visible")
.click();
cy.wait(500);
});
});
it("Should install all makretplace plugins and add them into the app", () => {
cy.visit(`${data.workspaceSlug}`);
const dataSourcesMarketplace = [
"Plivo",
"GitHub",
"OpenAI",
"AWS Textract",
"HarperDB",
"AWS Redshift",
"PocketBase",
"AWS Lambda",
"Supabase",
"Engagespot",
// "Salesforce", need to remove
"Presto",
"Jira",
// "Sharepoint", need to remove
"Portkey",
"Pinecone",
"Hugging Face",
"Cohere",
"Gemini",
"Mistral",
"Anthropic",
"Qdrant",
"Weaviate DB",
];
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.window().then((win) => {
cy.stub(win, "open").callsFake((url) => {
win.location.href = url;
});
});
cy.get('[data-cy="data-source-add-plugin"]').click();
cy.get(".marketplace-install").each(($el) => {
cy.wrap($el).click();
cy.wait(500);
cy.get(commonSelectors.toastMessage).should("include.text", "installed");
});
cy.wait(1000);
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(commonSelectors.pageSectionHeader).should(
"have.text",
"Data sources"
);
cy.wrap(dataSourcesMarketplace).each((dsName) => {
cy.get(commonSelectors.globalDataSourceIcon).click();
selectAndAddDataSource("databases", dsName, dsName);
cy.wait(500);
});
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsNamefake1);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.wrap(dataSourcesMarketplace).each((dsName) => {
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(
`cypress-${cyParamName(dsName)}-${cyParamName(dsName)}`
);
cy.wait(500);
cy.contains(
`[id*="react-select-"]`,
`cypress-${cyParamName(dsName)}-${cyParamName(dsName)}`
)
.should("be.visible")
.click();
cy.wait(500);
});
});
});

View file

@ -0,0 +1,288 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector, airTableSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql";
import { airtableText } from "Texts/airTable";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
data.dsName1 = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source Airtable", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
});
it("Should verify elements on connection AirTable form", () => {
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
selectAndAddDataSource("databases", airtableText.airtable, data.dsName);
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
"have.text",
postgreSqlText.buttonTextSave
);
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-airtable`);
});
it("Should verify the functionality of AirTable connection form.", () => {
selectAndAddDataSource("databases", airtableText.airtable, data.dsName);
fillDataSourceTextField(
airtableText.ApiKey,
airtableText.apikeyPlaceholder,
Cypress.env("airTable_apikey")
);
cy.get(postgreSqlSelector.buttonSave).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(
`[data-cy="cypress-${data.dsName}-airtable-button"]`
).verifyVisibleElement("have.text", `cypress-${data.dsName}-airtable`);
deleteDatasource(`cypress-${data.dsName}-airtable`);
});
it("Should able to run the query with valid conection", () => {
const airTable_apiKey = Cypress.env("airTable_apikey");
const airTable_baseId = Cypress.env("airtabelbaseId");
const airTable_tableName = Cypress.env("airtable_tableName");
const airTable_recordID = Cypress.env("airtable_recordId");
selectAndAddDataSource("databases", airtableText.airtable, data.dsName);
fillDataSourceTextField(
airtableText.ApiKey,
airtableText.apikeyPlaceholder,
airTable_apiKey
);
cy.wait(1000);
cy.get(postgreSqlSelector.buttonSave).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(
`[data-cy="cypress-${data.dsName}-airtable-button"]`
).verifyVisibleElement("have.text", `cypress-${data.dsName}-airtable`);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
// Verfiy List Recored operation
cy.get(airTableSelector.operationSelectDropdown)
.click()
.type("List records{enter}");
cy.get(airTableSelector.baseIdInputField).clearAndTypeOnCodeMirror(
airTable_baseId
);
cy.get(airTableSelector.tableNameInputField).clearAndTypeOnCodeMirror(
airTable_tableName
);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
// Verfiy Retrieve record operation
cy.get(airTableSelector.operationSelectDropdown)
.click()
.type("Retrieve record{enter}");
cy.get(airTableSelector.baseIdInputField).clearAndTypeOnCodeMirror(
airTable_baseId
);
cy.get(airTableSelector.tableNameInputField).clearAndTypeOnCodeMirror(
airTable_tableName
);
cy.get(airTableSelector.recordIdInputField).clearAndTypeOnCodeMirror(
airTable_recordID
);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
// Verfiy Create record operation
cy.get(airTableSelector.operationSelectDropdown)
.click()
.type("Create record{enter}");
cy.get(airTableSelector.baseIdInputField).clearAndTypeOnCodeMirror(
airTable_baseId
);
cy.get(airTableSelector.tableNameInputField).clearAndTypeOnCodeMirror(
airTable_tableName
);
cy.get(airTableSelector.bodyInputField)
.realClick()
.realType('[{"', { force: true, delay: 0 })
.realType("fields", { force: true, delay: 0 })
.realType('": {}', { force: true, delay: 0 });
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
// Verfiy Update record operation
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName1);
cy.get(airTableSelector.operationSelectDropdown)
.click()
.type("Update record{enter}");
cy.get(airTableSelector.baseIdInputField).clearAndTypeOnCodeMirror(
airTable_baseId
);
cy.get(airTableSelector.tableNameInputField).clearAndTypeOnCodeMirror(
airTable_tableName
);
cy.get(airTableSelector.recordIdInputField).clearAndTypeOnCodeMirror(
airTable_recordID
);
cy.get(airTableSelector.bodyInputField)
.realClick()
.realType("{", { force: true, delay: 0 })
.realType("{enter}", { force: true, delay: 0 })
.realType('"Phone Number": "555_98"', { force: true, delay: 0 });
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName1}) completed.`
);
// Verify Delete record operation
cy.get(airTableSelector.operationSelectDropdown)
.click()
.type("Delete record{enter}");
const recordId = Cypress._.uniqueId("recDummy_");
cy.request({
method: "POST",
url: `https://api.airtable.com/v0/${airTable_baseId}/${airTable_tableName}`,
headers: {
Authorization: `Bearer ${Cypress.env("airTable_apikey")}`,
"Content-Type": "application/json",
},
body: {
records: [
{
fields: {
"Employee ID": "E005",
"First Name": "test",
"Last Name": "abc",
Email: "doe@example.com",
"Phone Number": "555-12",
},
},
],
},
}).then((createResponse) => {
const newRecordId = createResponse.body.records[0].id;
cy.get(airTableSelector.operationSelectDropdown)
.click()
.type("Delete record{enter}");
cy.get(airTableSelector.baseIdInputField).clearAndTypeOnCodeMirror(
airTable_baseId
);
cy.get(airTableSelector.tableNameInputField).clearAndTypeOnCodeMirror(
airTable_tableName
);
cy.get(airTableSelector.recordIdInputField).clearAndTypeOnCodeMirror(
newRecordId
);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName1}) completed.`
);
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-airtable`
);
});
});
});

View file

@ -0,0 +1,207 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { pluginSelectors } from "Selectors/plugins";
import { postgreSqlText } from "Texts/postgreSql";
import { amazonSesText } from "Texts/amazonSes";
import { amazonAthenaText } from "Texts/amazonAthena";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source amazon athena", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
});
it("Should verify elements on amazon athena connection form", () => {
const Accesskey = Cypress.env("amazonathena_accessKey");
const Secretkey = Cypress.env("amazonathena_secretKey");
const DbName = Cypress.env("amazonathena_DbName");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
selectAndAddDataSource(
"databases",
amazonAthenaText.AmazonAthena,
data.dsName
);
cy.get(pluginSelectors.amazonAthenaDbName).click().type(DbName);
cy.get(pluginSelectors.amazonsesAccesKey).click().type(" ");
fillDataSourceTextField(
amazonSesText.labelSecretKey,
amazonAthenaText.placeholderSecretKey,
Secretkey
);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
cy.get(postgreSqlSelector.buttonTestConnection)
.verifyVisibleElement(
"have.text",
postgreSqlText.buttonTextTestConnection
)
.click();
cy.get(postgreSqlSelector.connectionFailedText).verifyVisibleElement(
"have.text",
postgreSqlText.couldNotConnect
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-Amazon-Athena`);
});
it("Should verify the functionality of amazon athena connection form.", () => {
const Accesskey = Cypress.env("amazonathena_accessKey");
const Secretkey = Cypress.env("amazonathena_secretKey");
const DbName = Cypress.env("amazonathena_DbName");
selectAndAddDataSource(
"databases",
amazonAthenaText.AmazonAthena,
data.dsName
);
cy.get(pluginSelectors.amazonAthenaDbName).click().type(DbName);
cy.get(pluginSelectors.amazonsesAccesKey).click().type(Accesskey);
fillDataSourceTextField(
amazonSesText.labelSecretKey,
amazonAthenaText.placeholderSecretKey,
Secretkey
);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-amazon-Athena`);
});
it("Should able to run the query with valid conection", () => {
const Accesskey = Cypress.env("amazonathena_accessKey");
const Secretkey = Cypress.env("amazonathena_secretKey");
const DbName = Cypress.env("amazonathena_DbName");
selectAndAddDataSource(
"databases",
amazonAthenaText.AmazonAthena,
data.dsName
);
cy.get(pluginSelectors.amazonAthenaDbName).click().type(DbName);
fillDataSourceTextField(
amazonAthenaText.labelAccesskey,
amazonAthenaText.placeholderEnteraAccessKey,
Cypress.env("amazonathena_accessKey")
);
fillDataSourceTextField(
amazonAthenaText.labelSecretKey,
amazonAthenaText.placeholderSecretKey,
Cypress.env("amazonathena_secretKey")
);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(
`[data-cy="cypress-${data.dsName}-amazon-athena-button"]`
).verifyVisibleElement("have.text", `cypress-${data.dsName}-amazon-athena`);
cy.wait(1000);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
cy.get('[data-cy="query-input-field"]').clearAndTypeOnCodeMirror(
"SHOW DATABASES;"
);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-amazon-Athena`
);
});
});

View file

@ -0,0 +1,205 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { pluginSelectors } from "Selectors/plugins";
import { postgreSqlText } from "Texts/postgreSql";
import { amazonSesText } from "Texts/amazonSes";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source amazon ses", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
});
it("Should verify elements on amazonses connection form", () => {
const Accesskey = Cypress.env("amazonSes_accessKey");
const Secretkey = Cypress.env("amazonSes_secretKey");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
selectAndAddDataSource("databases", amazonSesText.AmazonSES, data.dsName);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
cy.get(pluginSelectors.amazonsesAccesKey).click().type(Accesskey);
fillDataSourceTextField(
amazonSesText.labelSecretKey,
"**************",
Secretkey
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-Amazon-ses`);
});
it("Should verify the functionality of amazonses connection form.", () => {
selectAndAddDataSource("databases", amazonSesText.AmazonSES, data.dsName);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
fillDataSourceTextField(
amazonSesText.labelAccesskey,
amazonSesText.placeholderAccessKey,
Cypress.env("amazonSes_accessKey")
);
fillDataSourceTextField(
amazonSesText.labelSecretKey,
amazonSesText.placeholderSecretKey,
Cypress.env("amazonSes_secretKey")
);
cy.get(postgreSqlSelector.buttonSave).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(
`[data-cy="cypress-${data.dsName}-amazon-ses-button"]`
).verifyVisibleElement("have.text", `cypress-${data.dsName}-amazon-ses`);
deleteDatasource(`cypress-${data.dsName}-amazon-ses`);
});
it("Should able to run the query with valid conection", () => {
const email = "adish" + "@" + "tooljet.com";
selectAndAddDataSource("databases", amazonSesText.AmazonSES, data.dsName);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
fillDataSourceTextField(
amazonSesText.labelAccesskey,
amazonSesText.placeholderAccessKey,
Cypress.env("amazonSes_accessKey")
);
fillDataSourceTextField(
amazonSesText.labelSecretKey,
amazonSesText.placeholderSecretKey,
Cypress.env("amazonSes_secretKey")
);
cy.get(postgreSqlSelector.buttonSave).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(
`[data-cy="cypress-${data.dsName}-amazon-ses-button"]`
).verifyVisibleElement("have.text", `cypress-${data.dsName}-amazon-ses`);
cy.wait(1000);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
cy.get(pluginSelectors.operationDropdown)
.click()
.type("Email service{enter}");
cy.wait(500);
cy.get(pluginSelectors.sendEmailInputField)
.realClick()
.realType('{{["', { force: true, delay: 0 })
.realType("mekhla@tooljet.com", { force: true, delay: 0 });
cy.get(pluginSelectors.ccEmailInputField)
.realClick()
.realType('{{["', { force: true, delay: 0 })
.realType("mani@tooljet.com", { force: true, delay: 0 });
cy.get(pluginSelectors.bccEmailInputField)
.realClick()
.realType('{{["', { force: true, delay: 0 })
.realType("midhun@tooljet.com", { force: true, delay: 0 });
cy.get(pluginSelectors.sendEmailFromInputField)
.realClick()
.realType("adish", { force: true, delay: 0 })
.realType("@", { force: true, delay: 0 })
.realType("tooljet.com", { force: true, delay: 0 });
cy.get(pluginSelectors.emailSubjetInputField).clearAndTypeOnCodeMirror(
"Testmail for amazon ses"
);
cy.get(pluginSelectors.emailbodyInputField).clearAndTypeOnCodeMirror(
"Body text for amazon ses"
);
cy.wait(1000);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-amazon-ses`
);
});
});

View file

@ -0,0 +1,315 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql";
import { appwriteText } from "Texts/appWrite";
import { appWriteSelectors } from "Selectors/Plugins";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source AppWrite", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
});
it("Should verify elements on appwrite connection form", () => {
const Host = Cypress.env("appwrite_host");
const ProjectID = Cypress.env("appwrite_projectID");
const DatabaseID = Cypress.env("appwrite_databaseID");
const SecretKey = Cypress.env("appwrite_secretkey");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
selectAndAddDataSource("databases", appwriteText.appwrite, data.dsName);
fillDataSourceTextField(
appwriteText.host,
appwriteText.hostPlaceholder,
Host
);
fillDataSourceTextField(
appwriteText.ProjectID,
appwriteText.projectIdPlaceholder,
ProjectID
);
fillDataSourceTextField(
appwriteText.DatabaseID,
appwriteText.databaseIdPlaceholder,
DatabaseID
);
fillDataSourceTextField(
appwriteText.SecretKey,
appwriteText.SecretKeyPlaceholder,
SecretKey
);
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-Appwrite`);
});
it("Should verify the functionality of appwrite connection form.", () => {
const Host = Cypress.env("appwrite_host");
const ProjectID = Cypress.env("appwrite_projectID");
const DatabaseID = Cypress.env("appwrite_databaseID");
const SecretKey = Cypress.env("appwrite_secretkey");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
selectAndAddDataSource("databases", appwriteText.appwrite, data.dsName);
fillDataSourceTextField(
appwriteText.host,
appwriteText.hostPlaceholder,
Host
);
fillDataSourceTextField(
appwriteText.ProjectID,
appwriteText.projectIdPlaceholder,
ProjectID
);
fillDataSourceTextField(
appwriteText.DatabaseID,
appwriteText.databaseIdPlaceholder,
DatabaseID
);
fillDataSourceTextField(
appwriteText.SecretKey,
appwriteText.SecretKeyPlaceholder,
SecretKey
);
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-Appwrite`);
});
it("Should be able to run the query with a valid connection", () => {
const Host = Cypress.env("appwrite_host");
const ProjectID = Cypress.env("appwrite_projectID");
const DatabaseID = Cypress.env("appwrite_databaseID");
const SecretKey = Cypress.env("appwrite_secretkey");
const CollectionID = Cypress.env("appwrite_collectionID");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
selectAndAddDataSource("databases", appwriteText.appwrite, data.dsName);
fillDataSourceTextField(
appwriteText.host,
appwriteText.hostPlaceholder,
Host
);
fillDataSourceTextField(
appwriteText.ProjectID,
appwriteText.projectIdPlaceholder,
ProjectID
);
fillDataSourceTextField(
appwriteText.DatabaseID,
appwriteText.databaseIdPlaceholder,
DatabaseID
);
fillDataSourceTextField(
appwriteText.SecretKey,
appwriteText.SecretKeyPlaceholder,
SecretKey
);
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(
`[data-cy="cypress-${data.dsName}-appwrite-button"]`
).verifyVisibleElement("have.text", `cypress-${data.dsName}-appwrite`);
cy.wait(1000);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
// Create API document for delete operation
cy.request({
method: "POST",
url: `https://cloud.appwrite.io/v1/databases/${DatabaseID}/collections/${CollectionID}/documents`,
headers: {
"X-Appwrite-Project": ProjectID,
"X-Appwrite-Key": SecretKey,
"Content-Type": "application/json",
},
body: {
documentId: "unique()",
data: {
User_name: "test",
User_ID: 30,
},
permissions: ['read("any")'],
},
}).then((response) => {
expect(response.status).to.eq(201);
cy.wrap(response.body.$id).as("documentId");
});
// Verify all operations
const operations = [
"List documents",
"Get document",
"Add Document to Collection",
"Update document",
"Delete document",
];
cy.get("@documentId").then((documentId) => {
operations.forEach((operation) => {
cy.get(".react-select__input")
.eq(1)
.type(`${operation}{enter}`, { force: true });
if (operation === "Get document") {
cy.get(appWriteSelectors.collectionId).clearAndTypeOnCodeMirror(
CollectionID
);
cy.get(appWriteSelectors.documentId).clearAndTypeOnCodeMirror(
Cypress.env("appwrite_documentID")
);
}
if (operation === "Add Document to Collection") {
cy.get(appWriteSelectors.collectionId).clearAndTypeOnCodeMirror(
CollectionID
);
cy.get(appWriteSelectors.bodyInput).clearAndTypeOnCodeMirror(
'{"User_name": "John Updated", "User_ID": 35}'
);
}
if (operation === "Update document") {
cy.get(appWriteSelectors.collectionId).clearAndTypeOnCodeMirror(
CollectionID
);
cy.get(appWriteSelectors.documentId).clearAndTypeOnCodeMirror(
Cypress.env("appwrite_documentID")
);
cy.get(appWriteSelectors.bodyInput).clearAndTypeOnCodeMirror(
'{"User_name": "John Updated", "User_ID": 35}'
);
}
if (operation === "List documents") {
cy.get(appWriteSelectors.collectionId).clearAndTypeOnCodeMirror(
CollectionID
);
}
if (operation === "Delete document") {
cy.get(appWriteSelectors.collectionId).clearAndTypeOnCodeMirror(
CollectionID
);
cy.get(appWriteSelectors.documentId).clearAndTypeOnCodeMirror(
documentId
);
}
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
});
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-Appwrite`
);
});
});
});

View file

@ -0,0 +1,187 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { pluginSelectors } from "Selectors/plugins";
import { postgreSqlText } from "Texts/postgreSql";
import { awsLambdaText } from "Texts/awsLambda";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source AWS Lambda", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
});
it("Should verify elements on AWS Lambda connection form", () => {
const Accesskey = Cypress.env("awslamda_access");
const Secretkey = Cypress.env("awslamda_secret");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
cy.installMarketplacePlugin("AWS Lambda");
selectAndAddDataSource("databases", awsLambdaText.awsLambda, data.dsName);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
cy.get(pluginSelectors.amazonsesAccesKey).click().type(Accesskey);
fillDataSourceTextField(
awsLambdaText.labelSecretKey,
"**************",
Secretkey
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-aws-lambda`);
});
it("Should verify the functionality of AWS Lambda connection form", () => {
const Accesskey = Cypress.env("awslamda_access");
const Secretkey = Cypress.env("awslamda_secret");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.installMarketplacePlugin("AWS Lambda");
selectAndAddDataSource("databases", awsLambdaText.awsLambda, data.dsName);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
cy.get(pluginSelectors.amazonsesAccesKey).click().type(Accesskey);
fillDataSourceTextField(
awsLambdaText.labelSecretKey,
"**************",
Secretkey
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-aws-lambda`);
});
it("Should able to run the query with valid conection", () => {
const Accesskey = Cypress.env("awslamda_access");
const Secretkey = Cypress.env("awslamda_secret");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.installMarketplacePlugin("AWS Lambda");
selectAndAddDataSource("databases", awsLambdaText.awsLambda, data.dsName);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option")
.contains("US West (N. California)")
.wait(500)
.click();
cy.get(pluginSelectors.amazonsesAccesKey).click().type(Accesskey);
fillDataSourceTextField(
awsLambdaText.labelSecretKey,
"**************",
Secretkey
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
cy.get(pluginSelectors.operationDropdown)
.click()
.type("Invoke Lambda Function{enter}");
cy.wait(500);
cy.get(
'[data-cy="function-name-section"] .cm-content'
).clearAndTypeOnCodeMirror("testAwslambdaPlugin");
cy.wait(500);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-aws-lambda`
);
cy.uninstallMarketplacePlugin("AWS Lambda");
});
});

View file

@ -0,0 +1,225 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { pluginSelectors } from "Selectors/plugins";
import { awsTextractSelectors } from "Selectors/Plugins";
import { postgreSqlText } from "Texts/postgreSql";
import { awsTextractText } from "Texts/awsTextract";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source AWS Textract", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
});
it("Should verify elements on AWS Textract connection form", () => {
const Accesskey = Cypress.env("awstextract_access");
const Secretkey = Cypress.env("awstextract_secret");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
cy.installMarketplacePlugin("AWS Textract");
selectAndAddDataSource(
"databases",
awsTextractText.awsTextract,
data.dsName
);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
cy.get(pluginSelectors.amazonsesAccesKey).click().type(Accesskey);
fillDataSourceTextField(
awsTextractText.labelSecretKey,
"**************",
Secretkey
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-aws-textract`);
});
it("Should verify functionality of AWS Textract connection form", () => {
const Accesskey = Cypress.env("awstextract_access");
const Secretkey = Cypress.env("awstextract_secret");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.installMarketplacePlugin("AWS Textract");
selectAndAddDataSource(
"databases",
awsTextractText.awsTextract,
data.dsName
);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option").contains("US West (N. California)").click();
cy.get(pluginSelectors.amazonsesAccesKey).click().type(Accesskey);
fillDataSourceTextField(
awsTextractText.labelSecretKey,
"**************",
Secretkey
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-aws-textract`);
});
it("Should able to run the query with valid conection", () => {
const Accesskey = Cypress.env("awstextract_access");
const Secretkey = Cypress.env("awstextract_secret");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.installMarketplacePlugin("AWS Textract");
selectAndAddDataSource(
"databases",
awsTextractText.awsTextract,
data.dsName
);
cy.get(".react-select__dropdown-indicator").eq(1).click();
cy.get(".react-select__option")
.contains("US West (N. California)")
.wait(500)
.click();
cy.get(pluginSelectors.amazonsesAccesKey).click().type(Accesskey);
fillDataSourceTextField(
awsTextractText.labelSecretKey,
"**************",
Secretkey
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
// Verifying analyze document operation
cy.get(pluginSelectors.operationDropdown)
.click()
.wait(500)
.type("Analyze Document{enter}");
cy.wait(500);
cy.get(awsTextractSelectors.documentInputField).clearAndTypeOnCodeMirror(
awsTextractText.documentName
);
cy.wait(500);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
// Verifying Analyze document stored in AWS S3 operation
cy.get(pluginSelectors.operationDropdown)
.click()
.wait(500)
.type("Analyze document stored in AWS S3{enter}");
cy.wait(500);
cy.get(awsTextractSelectors.bucketNameInputField).clearAndTypeOnCodeMirror(
awsTextractText.bucketName
);
cy.get(awsTextractSelectors.keyNameInputField).clearAndTypeOnCodeMirror(
awsTextractText.keyName
);
cy.wait(500);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-aws-textract`
);
cy.uninstallMarketplacePlugin("AWS Textract");
});
});

View file

@ -0,0 +1,218 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { pluginSelectors, baserowSelectors } from "Selectors/plugins";
import { postgreSqlText } from "Texts/postgreSql";
import { baseRowText } from "Texts/baseRow";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source baserow", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
});
it("Should verify elements on baserow connection form", () => {
const Apikey = Cypress.env("baserow_apikey");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
selectAndAddDataSource("databases", baseRowText.baserow, data.dsName);
fillDataSourceTextField(
baseRowText.lableApiToken,
baseRowText.placeholderApiToken,
Apikey
);
cy.get(".react-select__control").eq(1).click();
cy.get(".react-select__option").contains("Baserow Cloud").click();
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-baserow`);
});
it("Should verify the functionality of baserow connection form.", () => {
const Apikey = Cypress.env("baserow_apikey");
selectAndAddDataSource("databases", baseRowText.baserow, data.dsName);
fillDataSourceTextField(
baseRowText.lableApiToken,
baseRowText.placeholderApiToken,
Apikey
);
cy.get(".react-select__control").eq(1).click();
cy.get(".react-select__option").contains("Baserow Cloud").click();
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-baserow`);
});
it("Should be able to run the query with a valid connection", () => {
const baserowTableID = Cypress.env("baserow_tableid");
const baserowRowID = Cypress.env("baserow_rowid");
const Apikey = Cypress.env("baserow_apikey");
selectAndAddDataSource("databases", baseRowText.baserow, data.dsName);
fillDataSourceTextField(
baseRowText.lableApiToken,
baseRowText.placeholderApiToken,
Apikey
);
cy.get(".react-select__control").eq(1).click();
cy.get(".react-select__option").contains("Baserow Cloud").click();
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(
`[data-cy="cypress-${data.dsName}-baserow-button"]`
).verifyVisibleElement("have.text", `cypress-${data.dsName}-baserow`);
cy.wait(1000);
cy.log("Baserow Table ID:", baserowTableID);
cy.log("Row ID:", baserowRowID);
cy.log("API Key:", Apikey);
if (!baserowTableID || !Apikey) {
throw new Error("Missing required environment variables!");
}
cy.request({
method: "POST",
url: `https://api.baserow.io/api/database/rows/table/${baserowTableID}/`,
headers: { Authorization: `Token ${Apikey}` },
body: {
field_1: "Sample Data",
field_2: "Another Value",
},
}).then((response) => {
expect(response.status).to.eq(200);
const rowId = response.body.id;
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
// Verify delete operation (Need to uncomment after bug fixes)
// cy.get('[data-cy="operation-select-dropdown"]').click();
// cy.get(".react-select__option").contains("Delete row").click();
// cy.get(baserowSelectors.baserowTabelId).clearAndTypeOnCodeMirror(baserowTableID);
// cy.get(baserowSelectors.rowIdinputfield).clearAndTypeOnCodeMirror(rowId.toString());
// cy.get(dataSourceSelector.queryPreviewButton).click();
// cy.verifyToastMessage(commonSelectors.toastMessage, `Query (${data.dsName}) completed.`);
});
// Verify other operations
const operations = [
"List fields",
"List rows",
"Get row",
"Create row",
"Update row",
"Move row",
];
operations.forEach((operation) => {
cy.get(pluginSelectors.operationDropdown).click();
cy.get(".react-select__option").contains(operation).click();
cy.get(baserowSelectors.table).clearAndTypeOnCodeMirror(baserowTableID);
if (operation === "Get row") {
cy.get(baserowSelectors.rowIdinputfield).clearAndTypeOnCodeMirror(
baserowRowID
);
}
if (operation === "Move row") {
cy.get('[data-cy="before-id-input-field"]').clearAndTypeOnCodeMirror(
"1"
);
}
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
});
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-baserow`
);
});
});

View file

@ -4,6 +4,7 @@ import { postgreSqlText } from "Texts/postgreSql";
import { bigqueryText } from "Texts/bigquery"; import { bigqueryText } from "Texts/bigquery";
import { firestoreText } from "Texts/firestore"; import { firestoreText } from "Texts/firestore";
import { commonSelectors } from "Selectors/common"; import { commonSelectors } from "Selectors/common";
import { dataSourceSelector } from "Selectors/dataSource";
import { import {
fillDataSourceTextField, fillDataSourceTextField,
selectAndAddDataSource, selectAndAddDataSource,
@ -16,6 +17,7 @@ const data = {};
describe("Data source BigQuery", () => { describe("Data source BigQuery", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.intercept("GET", "/api/v2/data_sources"); cy.intercept("GET", "/api/v2/data_sources");
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
@ -50,10 +52,19 @@ describe("Data source BigQuery", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource( cy.apiCreateGDS(
"databases", `${Cypress.env("server_host")}/api/data-sources`,
bigqueryText.bigQuery, `cypress-${data.dataSourceName}-bigquery`,
data.dataSourceName "bigquery",
[{ key: "private_key", value: "", encrypted: true }]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-bigquery-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-bigquery`
); );
cy.get('[data-cy="label-private-key"]').verifyVisibleElement( cy.get('[data-cy="label-private-key"]').verifyVisibleElement(

View file

@ -1,9 +1,8 @@
import { fake } from "Fixtures/fake"; import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql"; import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { commonWidgetText } from "Texts/common";
import { commonSelectors, commonWidgetSelector } from "Selectors/common"; import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { closeDSModal, deleteDatasource } from "Support/utils/dataSource"; import { closeDSModal, deleteDatasource } from "Support/utils/dataSource";
import { import {
addQuery, addQuery,
@ -21,6 +20,7 @@ const data = {};
describe("Data sources", () => { describe("Data sources", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -51,13 +51,20 @@ describe("Data sources", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("databases", "ClickHouse", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
// cy.get(postgreSqlSelector.dataSourceNameInputField).should( `cypress-${data.dataSourceName}-clickhouse`,
// //username,password,host,port,protocol,dbname,usepost, trimquery,gzip,debug,raw "clickhouse",
// "have.value", []
// "ClickHouse" );
// ); cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-clickhouse-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-clickhouse`
);
cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement( cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement(
"have.text", "have.text",
postgreSqlText.labelUserName postgreSqlText.labelUserName
@ -78,7 +85,7 @@ describe("Data sources", () => {
cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement( cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement(
"have.text", "have.text",
postgreSqlText.labelDbName "Database Name"
); );
cy.get('[data-cy="label-protocol"]').verifyVisibleElement( cy.get('[data-cy="label-protocol"]').verifyVisibleElement(
"have.text", "have.text",
@ -140,11 +147,7 @@ describe("Data sources", () => {
Cypress.env("pg_host") Cypress.env("pg_host")
); );
fillDataSourceTextField(postgreSqlText.labelPort, "8123", "8123"); fillDataSourceTextField(postgreSqlText.labelPort, "8123", "8123");
fillDataSourceTextField( fillDataSourceTextField("Database Name", "database name", "{del}");
postgreSqlText.labelDbName,
"database name",
"{del}"
);
fillDataSourceTextField( fillDataSourceTextField(
postgreSqlText.labelUserName, postgreSqlText.labelUserName,
postgreSqlText.placeholderEnterUserName, postgreSqlText.placeholderEnterUserName,

View file

@ -1,9 +1,8 @@
import { fake } from "Fixtures/fake"; import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql"; import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { commonWidgetText } from "Texts/common";
import { commonSelectors, commonWidgetSelector } from "Selectors/common"; import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { closeDSModal, deleteDatasource } from "Support/utils/dataSource"; import { closeDSModal, deleteDatasource } from "Support/utils/dataSource";
import { import {
addQuery, addQuery,
@ -21,6 +20,7 @@ const data = {};
describe("Data sources", () => { describe("Data sources", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -50,7 +50,23 @@ describe("Data sources", () => {
"have.text", "have.text",
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("databases", "CosmosDB", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-cosmosdb`,
"cosmosdb",
[
{ key: "endpoint", value: "" },
{ key: "key", value: "", encrypted: true },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-cosmosdb-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-cosmosdb`
);
cy.get('[data-cy="label-end-point"]').verifyVisibleElement( cy.get('[data-cy="label-end-point"]').verifyVisibleElement(
"have.text", "have.text",
@ -92,7 +108,7 @@ describe("Data sources", () => {
deleteDatasource(`cypress-${data.dataSourceName}-cosmosdb`); deleteDatasource(`cypress-${data.dataSourceName}-cosmosdb`);
}); });
it.only("Should verify the functionality of CosmosDB connection form.", () => { it("Should verify the functionality of CosmosDB connection form.", () => {
selectAndAddDataSource("databases", "CosmosDB", data.dataSourceName); selectAndAddDataSource("databases", "CosmosDB", data.dataSourceName);
fillDataSourceTextField( fillDataSourceTextField(

View file

@ -3,7 +3,7 @@ import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { commonWidgetText } from "Texts/common"; import { commonWidgetText } from "Texts/common";
import { commonSelectors, commonWidgetSelector } from "Selectors/common"; import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { closeDSModal, deleteDatasource } from "Support/utils/dataSource"; import { closeDSModal, deleteDatasource } from "Support/utils/dataSource";
import { import {
@ -22,6 +22,7 @@ const data = {};
describe("Data sources", () => { describe("Data sources", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -52,7 +53,27 @@ describe("Data sources", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("databases", "CouchDB", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-couchdb`,
"couchdb",
[
{ key: "username", value: "", encrypted: false },
{ key: "password", value: "", encrypted: true },
{ key: "database", value: "" },
{ key: "port", value: "5984" },
{ key: "host", value: "" },
{ key: "protocol" },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-couchdb-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-couchdb`
);
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement( cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
"have.text", "have.text",
@ -72,7 +93,7 @@ describe("Data sources", () => {
); );
cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement( cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement(
"have.text", "have.text",
postgreSqlText.labelDbName "Database Name"
); );
cy.get('[data-cy="label-protocol"]').verifyVisibleElement( cy.get('[data-cy="label-protocol"]').verifyVisibleElement(
@ -122,11 +143,7 @@ describe("Data sources", () => {
Cypress.env("couchdb_host") Cypress.env("couchdb_host")
); );
fillDataSourceTextField(postgreSqlText.labelPort, "5984 ", "5984"); fillDataSourceTextField(postgreSqlText.labelPort, "5984 ", "5984");
fillDataSourceTextField( fillDataSourceTextField("Database Name", "database name", "{del}");
postgreSqlText.labelDbName,
"database name",
"{del}"
);
fillDataSourceTextField( fillDataSourceTextField(
postgreSqlText.labelUserName, postgreSqlText.labelUserName,
"username for couchDB", "username for couchDB",

View file

@ -3,7 +3,7 @@ import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { dynamoDbText } from "Texts/dynamodb"; import { dynamoDbText } from "Texts/dynamodb";
import { commonSelectors } from "Selectors/common"; import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { import {
fillDataSourceTextField, fillDataSourceTextField,
@ -20,6 +20,7 @@ const data = {};
describe("Data source DynamoDB", () => { describe("Data source DynamoDB", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -50,10 +51,28 @@ describe("Data source DynamoDB", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource( cy.apiCreateGDS(
"databases", `${Cypress.env("server_host")}/api/data-sources`,
dynamoDbText.dynamoDb, `cypress-${data.dataSourceName}-dynamodb`,
data.dataSourceName "dynamodb",
[
{ key: "region", value: "" },
{ key: "access_key", value: "" },
{ key: "secret_key", value: "", encrypted: true },
{
key: "instance_metadata_credentials",
value: "iam_access_keys",
encrypted: false,
},
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-dynamodb-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-dynamodb`
); );
cy.get('[data-cy="label-region"]').verifyVisibleElement( cy.get('[data-cy="label-region"]').verifyVisibleElement(

View file

@ -3,7 +3,7 @@ import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { elasticsearchText } from "Texts/elasticsearch"; import { elasticsearchText } from "Texts/elasticsearch";
import { commonSelectors } from "Selectors/common"; import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { import {
fillDataSourceTextField, fillDataSourceTextField,
selectAndAddDataSource, selectAndAddDataSource,
@ -18,6 +18,7 @@ const data = {};
describe("Data source Elasticsearch", () => { describe("Data source Elasticsearch", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.lastName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""); data.lastName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
}); });
@ -46,12 +47,27 @@ describe("Data source Elasticsearch", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource( cy.apiCreateGDS(
"databases", `${Cypress.env("server_host")}/api/data-sources`,
elasticsearchText.elasticSearch, `cypress-${data.dataSourceName}-elasticsearch`,
data.lastName "elasticsearch",
[
{ key: "host", value: "localhost" },
{ key: "port", value: 9200 },
{ key: "username", value: "" },
{ key: "password", value: "", encrypted: true },
{ key: "ssl_enabled", value: true, encrypted: false },
{ key: "ssl_certificate", value: "none", encrypted: false },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-elasticsearch-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-elasticsearch`
); );
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement( cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
"have.text", "have.text",
postgreSqlText.labelHost postgreSqlText.labelHost
@ -74,7 +90,7 @@ describe("Data source Elasticsearch", () => {
); );
cy.get(postgreSqlSelector.labelSSLCertificate).verifyVisibleElement( cy.get(postgreSqlSelector.labelSSLCertificate).verifyVisibleElement(
"have.text", "have.text",
postgreSqlText.sslCertificate "SSL Certificate"
); );
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement( cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
"have.text", "have.text",

View file

@ -3,7 +3,7 @@ import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { firestoreText } from "Texts/firestore"; import { firestoreText } from "Texts/firestore";
import { commonSelectors } from "Selectors/common"; import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { import {
verifyCouldnotConnectWithAlert, verifyCouldnotConnectWithAlert,
deleteDatasource, deleteDatasource,
@ -18,6 +18,7 @@ const data = {};
describe("Data source Firestore", () => { describe("Data source Firestore", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -47,12 +48,20 @@ describe("Data source Firestore", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource( cy.apiCreateGDS(
"databases", `${Cypress.env("server_host")}/api/data-sources`,
firestoreText.firestore, `cypress-${data.dataSourceName}-firestore`,
data.dataSourceName "firestore",
[{ key: "gcp_key", value: "", encrypted: true }]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-firestore-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-firestore`
); );
cy.get('[data-cy="label-private-key"]').verifyVisibleElement( cy.get('[data-cy="label-private-key"]').verifyVisibleElement(
"have.text", "have.text",
firestoreText.labelPrivateKey firestoreText.labelPrivateKey

View file

@ -0,0 +1,153 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql";
import { GraphQLText } from "Texts/graphQL";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source GraphQL", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
});
it("Should verify elements on GraphQL connection form", () => {
const Url = Cypress.env("GraphQl_Url");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
selectAndAddDataSource("databases", GraphQLText.GraphQL, data.dsName);
fillDataSourceTextField(
GraphQLText.urlInputLabel,
GraphQLText.urlInputPlaceholder,
Url
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-GraphQL`);
});
it("Should verify the functionality of GraphQL connection form", () => {
const Url = Cypress.env("GraphQl_Url");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
selectAndAddDataSource("databases", GraphQLText.GraphQL, data.dsName);
fillDataSourceTextField(
GraphQLText.urlInputLabel,
GraphQLText.urlInputPlaceholder,
Url
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-GraphQL`);
});
it("Should able to run the query with valid conection", () => {
const Url = Cypress.env("GraphQl_Url");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
selectAndAddDataSource("databases", GraphQLText.GraphQL, data.dsName);
fillDataSourceTextField(
GraphQLText.urlInputLabel,
GraphQLText.urlInputPlaceholder,
Url
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
cy.get('[data-cy="query-input-field"]').clearAndTypeOnCodeMirror(
`{
allFilms {
films { title director }
}
}`
);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-GraphQL`
);
});
});

View file

@ -0,0 +1,343 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql";
import { harperDbText } from "Texts/harperDb";
import { harperDbSelectors } from "Selectors/Plugins";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
data.dsName1 = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source HarperDB", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
});
it("Should verify elements on HarperDB connection form", () => {
const Host = Cypress.env("harperdb_host");
const Port = Cypress.env("harperdb_port");
const Username = Cypress.env("harperdb_username");
const Password = Cypress.env("harperdb_password");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
cy.installMarketplacePlugin("HarperDB");
selectAndAddDataSource("databases", harperDbText.harperDb, data.dsName);
fillDataSourceTextField(
harperDbText.hostLabel,
harperDbText.hostInputPlaceholder,
Host
);
fillDataSourceTextField(
harperDbText.portLabel,
harperDbText.portPlaceholder,
Port
);
fillDataSourceTextField(
harperDbText.userNameLabel,
harperDbText.userNamePlaceholder,
Username
);
fillDataSourceTextField(
harperDbText.passwordlabel,
harperDbText.passwordPlaceholder,
Password
);
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-HarperDB`);
});
it("Should verify functionality of HarperDB connection form", () => {
const Host = Cypress.env("harperdb_host");
const Port = Cypress.env("harperdb_port");
const Username = Cypress.env("harperdb_username");
const Password = Cypress.env("harperdb_password");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.installMarketplacePlugin("HarperDB");
selectAndAddDataSource("databases", harperDbText.harperDb, data.dsName);
fillDataSourceTextField(
harperDbText.hostLabel,
harperDbText.hostInputPlaceholder,
Host
);
fillDataSourceTextField(
harperDbText.portLabel,
harperDbText.portPlaceholder,
Port
);
fillDataSourceTextField(
harperDbText.userNameLabel,
harperDbText.userNamePlaceholder,
Username
);
fillDataSourceTextField(
harperDbText.passwordlabel,
harperDbText.passwordPlaceholder,
Password
);
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-HarperDB`);
});
it("Should be able to run the query with a valid connection", () => {
const Host = Cypress.env("harperdb_host");
const Port = Cypress.env("harperdb_port");
const Username = Cypress.env("harperdb_username");
const Password = Cypress.env("harperdb_password");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.installMarketplacePlugin("HarperDB");
selectAndAddDataSource("databases", harperDbText.harperDb, data.dsName);
fillDataSourceTextField(
harperDbText.hostLabel,
harperDbText.hostInputPlaceholder,
Host
);
fillDataSourceTextField(
harperDbText.portLabel,
harperDbText.portPlaceholder,
Port
);
fillDataSourceTextField(
harperDbText.userNameLabel,
harperDbText.userNamePlaceholder,
Username
);
fillDataSourceTextField(
harperDbText.passwordlabel,
harperDbText.passwordPlaceholder,
Password
);
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
// Verifying NoSQL Operation
cy.get(".react-select__input")
.eq(1)
.click({ force: true })
.wait(500)
.type(`NoSQL mode{enter}`, { force: true });
const operationsDB = [
"Insert",
"Update",
"Search By Hash",
"Search By Value",
"Search By Condition",
"Delete",
];
operationsDB.forEach((operation) => {
cy.get(".react-select__input")
.eq(2)
.click({ force: true })
.wait(500)
.type(`${operation}{enter}`, { force: true });
const commonFields = {
"schema-input-field": harperDbText.schemaValue,
"table-input-field": harperDbText.tableValue,
};
Object.entries(commonFields).forEach(([field, value]) => {
cy.get(`[data-cy="${field}"]`).clearAndTypeOnCodeMirror(value);
});
if (["Insert", "Update"].includes(operation)) {
cy.get(harperDbSelectors.recordsInputField).clearAndTypeOnCodeMirror(
harperDbText.recordsValue
);
}
if (operation === "Search By Hash") {
cy.get(harperDbSelectors.hashValueInputField).clearAndTypeOnCodeMirror(
harperDbText.hashValue
);
cy.get(harperDbSelectors.attributesInputField).clearAndTypeOnCodeMirror(
harperDbText.attributesValue
);
}
if (operation === "Search By Value") {
cy.get(
harperDbSelectors.searchAttributeInputField
).clearAndTypeOnCodeMirror(harperDbText.searchAttributeValue);
cy.get(
harperDbSelectors.searchValueInputField
).clearAndTypeOnCodeMirror(harperDbText.searchValue);
cy.get(harperDbSelectors.attributesInputField).clearAndTypeOnCodeMirror(
harperDbText.attributesValue
);
}
if (operation === "Search By Condition") {
cy.get(".react-select__input")
.eq(3)
.click({ force: true })
.wait(500)
.type("Or{enter}", { force: true });
cy.get(harperDbSelectors.attributesInputField).clearAndTypeOnCodeMirror(
harperDbText.attributesValue
);
cy.get(harperDbSelectors.conditionInputField).clearAndTypeOnCodeMirror(
harperDbText.condtionValue
);
}
if (operation === "Delete") {
cy.get(harperDbSelectors.hashValueInputField).clearAndTypeOnCodeMirror(
harperDbText.hashValue
);
}
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
});
// Verifying SQL Operation
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName1);
cy.get(".react-select__input")
.eq(1)
.should("be.visible")
.click({ force: true })
.wait(500)
.type(`SQL mode{enter}`, { force: true });
cy.wait(1000);
cy.get(harperDbSelectors.sqlQueryInputField).clearAndTypeOnCodeMirror(
harperDbText.sqlValue
);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName1}) completed.`
);
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-HarperDB`
);
cy.uninstallMarketplacePlugin("HarperDB");
});
});

View file

@ -1,8 +1,8 @@
import { fake } from "Fixtures/fake"; import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql"; import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { commonWidgetText, commonText } from "Texts/common";
import { commonSelectors, commonWidgetSelector } from "Selectors/common"; import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { dataSourceSelector } from "Selectors/dataSource";
import { import {
addQuery, addQuery,
fillDataSourceTextField, fillDataSourceTextField,
@ -24,6 +24,7 @@ const data = {};
describe("Data sources", () => { describe("Data sources", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -54,7 +55,25 @@ describe("Data sources", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("databases", "InfluxDB", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-influxdb`,
"influxdb",
[
{ key: "api_token", value: "", encrypted: true },
{ key: "port", value: "8086", encrypted: false },
{ key: "host", value: "", encrypted: false },
{ key: "protocol", value: "http", encrypted: false },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-influxdb-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-influxdb`
);
cy.get('[data-cy="label-api-token"]').verifyVisibleElement( cy.get('[data-cy="label-api-token"]').verifyVisibleElement(
"have.text", "have.text",

View file

@ -1,6 +1,6 @@
import { postgreSqlSelector } from "Selectors/postgreSql"; import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { commonWidgetText, commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { commonSelectors, commonWidgetSelector } from "Selectors/common"; import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { import {
addQuery, addQuery,
@ -20,6 +20,7 @@ const data = {};
describe("Data sources", () => { describe("Data sources", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -50,7 +51,20 @@ describe("Data sources", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("databases", "MariaDB", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-mariadb`,
"mariadb",
[{ key: "connectionLimit", value: 5 }]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-mariadb-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-mariadb`
);
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement( cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
"have.text", "have.text",
@ -83,7 +97,7 @@ describe("Data sources", () => {
cy.get(postgreSqlSelector.labelSSLCertificate).verifyVisibleElement( cy.get(postgreSqlSelector.labelSSLCertificate).verifyVisibleElement(
"have.text", "have.text",
postgreSqlText.sslCertificate "SSL Certificate"
); );
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement( cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
"have.text", "have.text",

View file

@ -0,0 +1,285 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql";
import { minioText } from "Texts/minio";
import { minioSelectors } from "Selectors/Plugins";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source minio", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
});
it("Should verify elements on minio connection form", () => {
const Host = Cypress.env("minio_host");
const Port = Cypress.env("minio_port");
const AccessKey = Cypress.env("minio_accesskey");
const SecretKey = Cypress.env("minio_secretkey");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
selectAndAddDataSource("databases", minioText.minio, data.dsName);
fillDataSourceTextField(
minioText.hostLabel,
minioText.hostInputPlaceholder,
Host
);
fillDataSourceTextField(
minioText.portLabel,
minioText.portPlaceholder,
Port
);
cy.get(`[${minioSelectors.sslToggle}]`).click();
fillDataSourceTextField(
minioText.labelAccesskey,
minioText.placeholderAccessKey,
AccessKey
);
fillDataSourceTextField(
minioText.labelSecretKey,
minioText.placeholderSecretKey,
SecretKey
);
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-minio`);
});
it("Should verify functionality of minio connection form", () => {
const Host = Cypress.env("minio_host");
const Port = Cypress.env("minio_port");
const AccessKey = Cypress.env("minio_accesskey");
const SecretKey = Cypress.env("minio_secretkey");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
selectAndAddDataSource("databases", minioText.minio, data.dsName);
fillDataSourceTextField(
minioText.hostLabel,
minioText.hostInputPlaceholder,
Host
);
fillDataSourceTextField(
minioText.portLabel,
minioText.portPlaceholder,
Port
);
cy.get(`[${minioSelectors.sslToggle}]`).click();
fillDataSourceTextField(
minioText.labelAccesskey,
minioText.placeholderAccessKey,
AccessKey
);
fillDataSourceTextField(
minioText.labelSecretKey,
minioText.placeholderSecretKey,
SecretKey
);
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-minio`);
});
it("Should be able to run the query with a valid connection", () => {
const Host = Cypress.env("minio_host");
const Port = Cypress.env("minio_port");
const AccessKey = Cypress.env("minio_accesskey");
const SecretKey = Cypress.env("minio_secretkey");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
selectAndAddDataSource("databases", minioText.minio, data.dsName);
fillDataSourceTextField(
minioText.hostLabel,
minioText.hostInputPlaceholder,
Host
);
fillDataSourceTextField(
minioText.portLabel,
minioText.portPlaceholder,
Port
);
cy.get(`[${minioSelectors.sslToggle}]`).click();
fillDataSourceTextField(
minioText.labelAccesskey,
minioText.placeholderAccessKey,
AccessKey
);
fillDataSourceTextField(
minioText.labelSecretKey,
minioText.placeholderSecretKey,
SecretKey
);
cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get(postgreSqlSelector.textConnectionVerified, {
timeout: 10000,
}).should("have.text", postgreSqlText.labelConnectionVerified);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
const operationsMinio = [
"List buckets",
"Put object",
"List objects in a bucket",
"Read object",
"Presigned url for download",
"Presigned url for upload",
"Remove object",
];
operationsMinio.forEach((operation) => {
cy.get(".react-select__input")
.eq(1)
.type(`${operation}{enter}`, { force: true });
if (operation === "List objects in a bucket") {
cy.get(minioSelectors.bucketNameInputField).clearAndTypeOnCodeMirror(
minioText.bucketName
);
}
if (operation === "Read object" || operation === "Remove object") {
cy.get(minioSelectors.bucketNameInputField).clearAndTypeOnCodeMirror(
minioText.bucketName
);
cy.get(minioSelectors.objectNameInputField).clearAndTypeOnCodeMirror(
minioText.objectName
);
}
if (operation === "Put object") {
cy.get(minioSelectors.bucketNameInputField).clearAndTypeOnCodeMirror(
minioText.bucketName
);
cy.get(minioSelectors.objectNameInputField).clearAndTypeOnCodeMirror(
minioText.objectName
);
cy.get(minioSelectors.contentTypeInputField).clearAndTypeOnCodeMirror(
'"string"'
);
cy.get(minioSelectors.dataInput).clearAndTypeOnCodeMirror(`test`);
}
if (
operation === "Presigned url for download" ||
operation === "Presigned url for upload"
) {
cy.get(minioSelectors.bucketNameInputField).clearAndTypeOnCodeMirror(
minioText.bucketName
);
cy.get(minioSelectors.objectNameInputField).clearAndTypeOnCodeMirror(
minioText.objectName
);
}
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
});
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-minio`
);
});
});

View file

@ -3,7 +3,7 @@ import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { mongoDbText } from "Texts/mongoDb"; import { mongoDbText } from "Texts/mongoDb";
import { commonSelectors } from "Selectors/common"; import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { closeDSModal, deleteDatasource } from "Support/utils/dataSource"; import { closeDSModal, deleteDatasource } from "Support/utils/dataSource";
import { import {
fillDataSourceTextField, fillDataSourceTextField,
@ -28,6 +28,7 @@ const data = {};
describe("Data source MongoDB", () => { describe("Data source MongoDB", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -56,10 +57,28 @@ describe("Data source MongoDB", () => {
"have.text", "have.text",
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource( cy.apiCreateGDS(
"databases", `${Cypress.env("server_host")}/api/data-sources`,
mongoDbText.mongoDb, `cypress-${data.dataSourceName}-mongodb`,
data.dataSourceName "mongodb",
[
{ key: "database", value: "", encrypted: false },
{ key: "host", value: "localhost" },
{ key: "port", value: 27017 },
{ key: "username", value: "" },
{ key: "password", value: "", encrypted: true },
{ key: "connection_type", value: "manual" },
{ key: "connection_string", value: "", encrypted: true },
{ key: "tls_certificate", value: "none", encrypted: false },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-mongodb-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-mongodb`
); );
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement( cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
@ -72,7 +91,7 @@ describe("Data source MongoDB", () => {
); );
cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement( cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement(
"have.text", "have.text",
postgreSqlText.labelDbName "Database Name"
); );
cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement( cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement(
"have.text", "have.text",
@ -168,7 +187,7 @@ describe("Data source MongoDB", () => {
data.dataSourceName data.dataSourceName
); );
cy.get('[data-cy="query-select-dropdown"]').type( cy.get('[data-cy="connection-type-select-dropdown"]').type(
mongoDbText.optionConnectUsingConnectionString mongoDbText.optionConnectUsingConnectionString
); );

View file

@ -19,6 +19,7 @@ import {
deleteDatasource, deleteDatasource,
verifyCouldnotConnectWithAlert, verifyCouldnotConnectWithAlert,
} from "Support/utils/dataSource"; } from "Support/utils/dataSource";
import { dataSourceSelector } from "Selectors/dataSource";
import { realHover } from "cypress-real-events/commands/realHover"; import { realHover } from "cypress-real-events/commands/realHover";
const data = {}; const data = {};
@ -26,6 +27,7 @@ const data = {};
describe("Data sources MySql", () => { describe("Data sources MySql", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -56,7 +58,30 @@ describe("Data sources MySql", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("databases", "MySQL", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-mysql`,
"mysql",
[
{ key: "connection_type", value: "hostname" },
{ key: "host", value: "localhost" },
{ key: "port", value: 3306 },
{ key: "database", value: "" },
{ key: "socket", value: "", encrypted: false },
{ key: "username", value: "" },
{ key: "password", value: "", encrypted: true },
{ key: "ssl_enabled", value: false, encrypted: false },
{ key: "ssl_certificate", value: "none", encrypted: false },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-mysql-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-mysql`
);
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement( cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
"have.text", "have.text",
@ -110,7 +135,7 @@ describe("Data sources MySql", () => {
deleteDatasource(`cypress-${data.dataSourceName}-mysql`); deleteDatasource(`cypress-${data.dataSourceName}-mysql`);
}); });
it.only("Should verify the functionality of MySQL connection form.", () => { it("Should verify the functionality of MySQL connection form.", () => {
selectAndAddDataSource("databases", "MySQL", data.dataSourceName); selectAndAddDataSource("databases", "MySQL", data.dataSourceName);
fillDataSourceTextField( fillDataSourceTextField(
@ -170,9 +195,9 @@ describe("Data sources MySql", () => {
verifyCouldnotConnectWithAlert( verifyCouldnotConnectWithAlert(
"ER_ACCESS_DENIED_ERROR: Access denied for user 'root'@'103.171.99.42' (using password: YES)" "ER_ACCESS_DENIED_ERROR: Access denied for user 'root'@'103.171.99.42' (using password: YES)"
); );
cy.get('[data-cy="-toggle-input"]').then(($el) => { cy.get('[data-cy="ssl-enabled-toggle-input"]').then(($el) => {
if ($el.is(":checked")) { if ($el.is(":checked")) {
cy.get('[data-cy="-toggle-input"]').uncheck(); cy.get('[data-cy="ssl-enabled-toggle-input"]').uncheck();
} }
}); });

View file

@ -123,7 +123,7 @@ describe("Data sources", () => {
); );
cy.clearAndType( cy.clearAndType(
'[data-cy="data-source-name-input-filed"]', '[data-cy="data-source-name-input-field"]',
postgreSqlText.psqlName postgreSqlText.psqlName
); );

View file

@ -3,6 +3,7 @@ import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { commonWidgetText, commonText } from "Texts/common"; import { commonWidgetText, commonText } from "Texts/common";
import { commonSelectors, commonWidgetSelector } from "Selectors/common"; import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { dataSourceSelector } from "Selectors/dataSource";
import { import {
addQuery, addQuery,
fillDataSourceTextField, fillDataSourceTextField,
@ -20,6 +21,7 @@ const data = {};
describe("Data sources", () => { describe("Data sources", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -52,10 +54,31 @@ describe("Data sources", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource( cy.apiCreateGDS(
"databases", `${Cypress.env("server_host")}/api/data-sources`,
postgreSqlText.postgreSQL, `cypress-${data.dataSourceName}-postgresql`,
data.dataSourceName "postgresql",
[
{ key: "connection_type", value: "manual", encrypted: false },
{ key: "host", value: "localhost", encrypted: false },
{ key: "port", value: 5432, encrypted: false },
{ key: "ssl_enabled", value: true, encrypted: false },
{ key: "ssl_certificate", value: "none", encrypted: false },
{ key: "password", value: null, encrypted: true },
{ key: "ca_cert", value: null, encrypted: true },
{ key: "client_key", value: null, encrypted: true },
{ key: "client_cert", value: null, encrypted: true },
{ key: "root_cert", value: null, encrypted: true },
{ key: "connection_string", value: null, encrypted: true },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-postgresql-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-postgresql`
); );
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement( cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(

View file

@ -11,26 +11,22 @@ import {
} from "Support/utils/postgreSql"; } from "Support/utils/postgreSql";
import { import {
verifyCouldnotConnectWithAlert,
deleteDatasource, deleteDatasource,
closeDSModal, closeDSModal,
addQuery,
addDsAndAddQuery, addDsAndAddQuery,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource"; } from "Support/utils/dataSource";
import { openQueryEditor } from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {}; const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""); data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source Redis", () => { describe("Data source Redis", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.apiLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery"); cy.defaultWorkspaceLogin();
}); });
it("Should verify elements on connection Redison form", () => { it("Should verify elements on connection Redis form", () => {
cy.get(commonSelectors.globalDataSourceIcon).click(); cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal(); closeDSModal();
@ -114,7 +110,7 @@ describe("Data source Redis", () => {
deleteDatasource(`cypress-${data.dsName}-redis`); deleteDatasource(`cypress-${data.dsName}-redis`);
}); });
it("Should verify the functionality of Redis connection form.", () => { it("Should verify the functionality of Redis connection form", () => {
selectAndAddDataSource("databases", redisText.redis, data.dsName); selectAndAddDataSource("databases", redisText.redis, data.dsName);
fillDataSourceTextField( fillDataSourceTextField(
@ -143,7 +139,7 @@ describe("Data source Redis", () => {
cy.get(postgreSqlSelector.buttonTestConnection).click(); cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get('[data-cy="connection-alert-text"]').should( cy.get('[data-cy="connection-alert-text"]').should(
"have.text", "have.text",
"WRONGPASS invalid username-password pair or user is disabled." redisText.errorInvalidUserOrPassword
); );
fillDataSourceTextField( fillDataSourceTextField(
postgreSqlText.labelHost, postgreSqlText.labelHost,
@ -176,7 +172,7 @@ describe("Data source Redis", () => {
cy.get(postgreSqlSelector.buttonTestConnection).click(); cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get('[data-cy="connection-alert-text"]').should( cy.get('[data-cy="connection-alert-text"]').should(
"have.text", "have.text",
"WRONGPASS invalid username-password pair or user is disabled." redisText.errorInvalidUserOrPassword
); );
fillDataSourceTextField( fillDataSourceTextField(
@ -193,7 +189,7 @@ describe("Data source Redis", () => {
cy.get(postgreSqlSelector.buttonTestConnection).click(); cy.get(postgreSqlSelector.buttonTestConnection).click();
cy.get('[data-cy="connection-alert-text"]').should( cy.get('[data-cy="connection-alert-text"]').should(
"have.text", "have.text",
"WRONGPASS invalid username-password pair or user is disabled." redisText.errorInvalidUserOrPassword
); );
fillDataSourceTextField( fillDataSourceTextField(
@ -256,5 +252,9 @@ describe("Data source Redis", () => {
cy.skipWalkthrough(); cy.skipWalkthrough();
addDsAndAddQuery("redis", `TIME`, `cypress-${data.dsName}-redis`); addDsAndAddQuery("redis", `TIME`, `cypress-${data.dsName}-redis`);
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-redis`
);
}); });
}); });

View file

@ -0,0 +1,383 @@
import { fake } from "Fixtures/fake";
import { commonSelectors } from "Selectors/common";
import { closeDSModal, deleteDatasource } from "Support/utils/dataSource";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql";
import { restAPISelector } from "Selectors/restAPI";
import { restAPIText } from "Texts/restAPI";
import { fillDataSourceTextField } from "Support/utils/postgreSql";
const data = {};
const authenticationDropdownSelector =
".dynamic-form-element > .css-nwhe5y-container > .react-select__control";
const grantTypeDropdown =
":nth-child(1) > :nth-child(2) > .react-select__control";
const addAccessTokenDropdown =
":nth-child(9) > .css-nwhe5y-container > .react-select__control";
const clientAuthenticationDropdown =
":nth-child(14) > .css-nwhe5y-container > .react-select__control";
describe("Data source Rest API", () => {
beforeEach(() => {
cy.defaultWorkspaceLogin();
cy.intercept("GET", "/api/v2/data_sources");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on Rest API connection form", () => {
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-restapi`,
"restapi",
[
{ key: "url", value: "" },
{ key: "auth_type", value: "none" },
{ key: "grant_type", value: "authorization_code" },
{ key: "add_token_to", value: "header" },
{ key: "header_prefix", value: "Bearer " },
{ key: "access_token_url", value: "" },
{ key: "client_id", value: "" },
{ key: "client_secret", value: "", encrypted: true },
{ key: "audience", value: "" },
{ key: "scopes", value: "read, write" },
{ key: "username", value: "", encrypted: false },
{ key: "password", value: "", encrypted: true },
{ key: "bearer_token", value: "", encrypted: true },
{ key: "auth_url", value: "" },
{ key: "client_auth", value: "header" },
{ key: "headers", value: [["", ""]] },
{ key: "custom_query_params", value: [["", ""]], encrypted: false },
{ key: "custom_auth_params", value: [["", ""]] },
{
key: "access_token_custom_headers",
value: [["", ""]],
encrypted: false,
},
{ key: "multiple_auth_enabled", value: false, encrypted: false },
{ key: "ssl_certificate", value: "none", encrypted: false },
{ key: "retry_network_errors", value: true, encrypted: false },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-restapi-button"]`)
.should("be.visible")
.click();
cy.get(restAPISelector.inputField("data-source-name")).should(
"have.value",
`cypress-${data.dataSourceName}-restapi`
);
cy.get(restAPISelector.subHeaderLabel(restAPIText.credentialsText)).should(
"have.text",
restAPIText.credentialsText
);
const sections = [
restAPIText.baseUrlLabel,
restAPIText.headersLabel,
restAPIText.urlParametesLabel,
restAPIText.bodyLabel,
restAPIText.cookiesLabel,
];
sections.forEach((section) => {
cy.get(restAPISelector.subHeaderLabel(section)).should(
"have.text",
section
);
if (section !== restAPIText.baseUrlLabel) {
cy.get(restAPISelector.keyInputField(section, 0)).should("be.visible");
cy.get(restAPISelector.valueInputField(section, 0)).should(
"be.visible"
);
cy.get(restAPISelector.deleteButton(section, 0)).should("be.visible");
cy.get(restAPISelector.addMoreButton(section)).should("be.visible");
} else {
cy.get('[data-cy="base-url-text-field"]').should("be.visible");
}
});
cy.get(
restAPISelector.subHeaderLabel(restAPIText.authenticationText)
).should("have.text", restAPIText.authenticationText);
cy.get(
restAPISelector.subHeaderLabel(restAPIText.authenticationTypeLabel)
).should("have.text", restAPIText.authenticationTypeLabel);
cy.get(authenticationDropdownSelector).click();
cy.contains(
`[id*="react-select-"]`,
restAPIText.basicAuth.basicText
).click();
cy.get(authenticationDropdownSelector).should(
"have.text",
restAPIText.basicAuth.basicText
);
cy.get(
restAPISelector.subHeaderLabel(restAPIText.basicAuth.usernameLabel)
).should("have.text", restAPIText.basicAuth.usernameLabel);
cy.get(
restAPISelector.inputField(restAPIText.basicAuth.usernameLabel)
).should("be.visible");
cy.get(
restAPISelector.subHeaderLabel(restAPIText.basicAuth.passwordLabel)
).should("have.text", restAPIText.basicAuth.passwordLabel);
cy.get(restAPISelector.button(restAPIText.editButtonText)).should(
"be.visible"
);
cy.get(
restAPISelector.inputField(restAPIText.basicAuth.passwordLabel)
).should("be.visible");
cy.get(authenticationDropdownSelector).click();
cy.contains(`[id*="react-select-"]`, restAPIText.bearerAuth.bearerText)
.should("be.visible")
.click();
cy.get(authenticationDropdownSelector).should(
"have.text",
restAPIText.bearerAuth.bearerText
);
cy.get(
restAPISelector.subHeaderLabel(restAPIText.bearerAuth.tokenLabel)
).should("have.text", restAPIText.bearerAuth.tokenLabel);
cy.get(
restAPISelector.inputField(restAPIText.bearerAuth.tokenLabel)
).should("be.visible");
cy.get(authenticationDropdownSelector).click();
cy.contains(`[id*="react-select-"]`, restAPIText.oAuthText).click();
cy.get(authenticationDropdownSelector).should(
"have.text",
restAPIText.oAuthText
);
cy.get(restAPISelector.subHeaderLabel(restAPIText.grantTypeLabel)).should(
"have.text",
restAPIText.grantTypeLabel
);
cy.get(grantTypeDropdown).click();
cy.contains(
`[id*="react-select-"]`,
restAPIText.authorizationCode.authorizationCodeLabel
)
.should("be.visible")
.click();
cy.get(grantTypeDropdown).should(
"contain",
restAPIText.authorizationCode.authorizationCodeLabel
);
cy.get(
restAPISelector.inputField(
restAPIText.authorizationCode.headerPrefixLabel
)
).should(($input) => {
expect($input.val().trim()).to.equal(restAPIText.bearerAuth.bearerText);
});
cy.get(
restAPISelector.inputField(
restAPIText.authorizationCode.accessTokenURLLabel
)
)
.invoke("attr", "placeholder")
.should("eq", "https://api.example.com/oauth/token");
cy.get(
restAPISelector.inputField(restAPIText.authorizationCode.clientIDLabel)
).should("be.visible");
cy.get(restAPISelector.button(restAPIText.editButtonText)).should(
"be.visible"
);
cy.get(
restAPISelector.inputField(
restAPIText.authorizationCode.clientSecretLabel
)
).should("be.visible");
Object.entries(restAPIText.authorizationCode).forEach(([key, value]) => {
if (
key !== "authorizationCodeLabel" &&
key !== "requestHeader" &&
key !== "sendBasicAuthheaderOption" &&
key !== "sendClientCredentialsBodyOption"
) {
cy.get(
restAPISelector.subHeaderLabel(restAPIText.authorizationCode[key])
).should("have.text", value);
}
});
cy.get(addAccessTokenDropdown)
.should("be.visible")
.and("contain", restAPIText.authorizationCode.requestHeader);
cy.get(
restAPISelector.inputField(restAPIText.authorizationCode.scopeLabel)
).should("be.visible");
const authorizationCodeSections = [
restAPIText.authorizationCode.accessTokenURLCustomHeadersLabel,
restAPIText.authorizationCode.customQueryParametersLabel,
restAPIText.authorizationCode.customAuthenticationParametersLabel,
];
authorizationCodeSections.forEach((authorizationCodeSections) => {
cy.get(
restAPISelector.subHeaderLabel(authorizationCodeSections)
).verifyVisibleElement("have.text", authorizationCodeSections);
if (authorizationCodeSections !== restAPIText.baseUrlLabel) {
cy.get(
restAPISelector.keyInputField(authorizationCodeSections, 0)
).should("be.visible");
cy.get(
restAPISelector.valueInputField(authorizationCodeSections, 0)
).should("be.visible");
cy.get(
restAPISelector.deleteButton(authorizationCodeSections, 0)
).should("be.visible");
cy.get(restAPISelector.addMoreButton(authorizationCodeSections)).should(
"be.visible"
);
} else {
cy.get('[data-cy="base-url-text-field"]').should("be.visible");
}
});
cy.get(clientAuthenticationDropdown).click();
cy.contains(
`[id*="react-select-"]`,
restAPIText.authorizationCode.sendClientCredentialsBodyOption
).should("be.visible");
cy.contains(
`[id*="react-select-"]`,
restAPIText.authorizationCode.sendBasicAuthheaderOption
)
.should("be.visible")
.click();
cy.get(clientAuthenticationDropdown).should(
"have.text",
restAPIText.authorizationCode.sendBasicAuthheaderOption
);
cy.get(
restAPISelector.subHeaderLabel(
restAPIText.authorizationCode.authenticationRequiredUsersToggle
)
).verifyVisibleElement(
"have.text",
restAPIText.authorizationCode.authenticationRequiredUsersToggle
);
cy.get(restAPISelector.authenticationAllUsersToggleSwitch).should(
"be.visible"
);
cy.get(grantTypeDropdown).click();
cy.contains(
`[id*="react-select-"]`,
restAPIText.clientCredentials.clientCredentialsLabel
)
.should("be.visible")
.click();
cy.get(grantTypeDropdown).should(
"contain",
restAPIText.clientCredentials.clientCredentialsLabel
);
Object.entries(restAPIText.clientCredentials).forEach(([key, value]) => {
if (key !== "clientCredentialsLabel") {
cy.get(
restAPISelector.subHeaderLabel(restAPIText.clientCredentials[key])
).should("have.text", value);
}
});
cy.get(
restAPISelector.subHeaderLabel(restAPIText.secureSocketsLayerText)
).should("have.text", restAPIText.secureSocketsLayerText);
cy.get(restAPISelector.dropdownLabel("SSL Certificate")).should(
"have.text",
"SSL Certificate"
);
cy.get(
restAPISelector.subHeaderLabel(restAPIText.generalSettingsText)
).should("have.text", restAPIText.generalSettingsText);
cy.get(restAPISelector.retryNetworkToggleSwitch).should("be.visible");
cy.get(restAPISelector.retryNetworkToggleText).should(
"have.text",
restAPIText.retryNetworkErrorsToggleLabel
);
cy.get(restAPISelector.retryNetworkToggleSubtext).should(
"have.text",
restAPIText.retryToggleHelperText
);
cy.get(restAPISelector.readDocumentationLinkText).should(
"have.text",
postgreSqlText.readDocumentation
);
cy.contains("Save").click();
cy.verifyToastMessage(commonSelectors.toastMessage, "Data Source Saved");
deleteDatasource(`cypress-${data.dataSourceName}-restapi`);
});
it("Should verify connection for Rest API", () => {
cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-restapi`,
"restapi",
[
{ key: "url", value: Cypress.env("restAPI_BaseURL") },
{ key: "auth_type", value: "none" },
{ key: "grant_type", value: "authorization_code" },
{ key: "add_token_to", value: "header" },
{ key: "header_prefix", value: "Bearer " },
{ key: "access_token_url", value: "" },
{ key: "client_id", value: "" },
{ key: "client_secret", value: "", encrypted: true },
{ key: "audience", value: "" },
{ key: "scopes", value: "read, write" },
{ key: "username", value: "", encrypted: false },
{ key: "password", value: "", encrypted: true },
{ key: "bearer_token", value: "", encrypted: true },
{ key: "auth_url", value: "" },
{ key: "client_auth", value: "header" },
{ key: "headers", value: [["", ""]] },
{ key: "custom_query_params", value: [["", ""]], encrypted: false },
{ key: "custom_auth_params", value: [["", ""]] },
{
key: "access_token_custom_headers",
value: [["", ""]],
encrypted: false,
},
{ key: "multiple_auth_enabled", value: false, encrypted: false },
{ key: "ssl_certificate", value: "none", encrypted: false },
{ key: "retry_network_errors", value: true, encrypted: false },
]
);
cy.reload();
// cy.apiCreateApp(`${fake.companyName}-restAPI-App`);
// cy.apiAddQueryToApp(
// "restapi1",
// {
// method: "get",
// url: "",
// url_params: [["", ""]],
// headers: [["", ""]],
// cookies: [["", ""]],
// },
// `cypress-${data.dataSourceName}-restapi`,
// "restapi"
// );
});
});

View file

@ -3,6 +3,7 @@ import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { commonWidgetText, commonText } from "Texts/common"; import { commonWidgetText, commonText } from "Texts/common";
import { commonSelectors, commonWidgetSelector } from "Selectors/common"; import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { dataSourceSelector } from "Selectors/dataSource";
import { import {
addQuery, addQuery,
fillDataSourceTextField, fillDataSourceTextField,
@ -19,6 +20,7 @@ const data = {};
describe("Data sources", () => { describe("Data sources", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -49,7 +51,26 @@ describe("Data sources", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("databases", "RethinkDB", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-rethinkdb`,
"rethinkdb",
[
{ key: "port", value: "28015", encrypted: false },
{ key: "host", value: "", encrypted: false },
{ key: "database", value: "", encrypted: false },
{ key: "username", value: "", encrypted: false },
{ key: "password", value: "", encrypted: true },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-rethinkdb-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-rethinkdb`
);
cy.get('[data-cy="label-database"]').verifyVisibleElement( cy.get('[data-cy="label-database"]').verifyVisibleElement(
"have.text", "have.text",

View file

@ -4,7 +4,7 @@ import { s3Selector } from "Selectors/awss3";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { s3Text } from "Texts/awss3"; import { s3Text } from "Texts/awss3";
import { commonSelectors } from "Selectors/common"; import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { import {
fillDataSourceTextField, fillDataSourceTextField,
selectAndAddDataSource, selectAndAddDataSource,
@ -19,7 +19,8 @@ const data = {};
describe("Data sources AWS S3", () => { describe("Data sources AWS S3", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.apiLogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -50,7 +51,31 @@ describe("Data sources AWS S3", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("cloudstorage", s3Text.awsS3, data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-aws-s3`,
"s3",
[
{ key: "access_key", value: "" },
{ key: "secret_key", value: "", encrypted: true },
{ key: "region", value: "" },
{ key: "endpoint", value: "" },
{ key: "endpoint_enabled", value: false, encrypted: false },
{
key: "instance_metadata_credentials",
value: "iam_access_keys",
encrypted: false,
},
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-aws-s3-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-aws-s3`
);
cy.get(s3Selector.accessKeyLabel).verifyVisibleElement( cy.get(s3Selector.accessKeyLabel).verifyVisibleElement(
"have.text", "have.text",
s3Text.accessKey s3Text.accessKey

View file

@ -108,7 +108,7 @@ describe("Data sources", () => {
selectAndAddDataSource(postgreSqlText.postgreSQL); selectAndAddDataSource(postgreSqlText.postgreSQL);
cy.clearAndType( cy.clearAndType(
'[data-cy="data-source-name-input-filed"]', '[data-cy="data-source-name-input-field"]',
postgreSqlText.psqlName postgreSqlText.psqlName
); );

View file

@ -2,7 +2,7 @@ import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql"; import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { commonSelectors } from "Selectors/common"; import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common"; import { dataSourceSelector } from "Selectors/dataSource";
import { import {
fillDataSourceTextField, fillDataSourceTextField,
selectAndAddDataSource, selectAndAddDataSource,
@ -14,6 +14,7 @@ const data = {};
describe("Data source SMTP", () => { describe("Data source SMTP", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -43,7 +44,25 @@ describe("Data source SMTP", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("apis", "SMTP", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-smtp`,
"smtp",
[
{ key: "host", value: "localhost", encrypted: false },
{ key: "port", value: 465, encrypted: false },
{ key: "user", value: "", encrypted: false },
{ key: "password", value: "", encrypted: true },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-smtp-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-smtp`
);
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement( cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
"have.text", "have.text",

View file

@ -4,6 +4,7 @@ import { postgreSqlText } from "Texts/postgreSql";
import { commonWidgetText, commonText } from "Texts/common"; import { commonWidgetText, commonText } from "Texts/common";
import { commonSelectors, commonWidgetSelector } from "Selectors/common"; import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { closeDSModal, deleteDatasource } from "Support/utils/dataSource"; import { closeDSModal, deleteDatasource } from "Support/utils/dataSource";
import { dataSourceSelector } from "Selectors/dataSource";
import { import {
addQuery, addQuery,
@ -20,6 +21,7 @@ const data = {};
describe("Data sources", () => { describe("Data sources", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -49,8 +51,28 @@ describe("Data sources", () => {
"have.text", "have.text",
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("databases", "Snowflake", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-snowflake`,
"snowflake",
[
{ key: "username", value: "" },
{ key: "account", value: "" },
{ key: "password", value: "", encrypted: true },
{ key: "database", value: "" },
{ key: "schema", value: "" },
{ key: "warehouse", value: "" },
{ key: "role", value: "" },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-snowflake-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-snowflake`
);
cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement( cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement(
"have.text", "have.text",
postgreSqlText.labelUserName postgreSqlText.labelUserName
@ -113,7 +135,7 @@ describe("Data sources", () => {
deleteDatasource(`cypress-${data.dataSourceName}-snowflake`); deleteDatasource(`cypress-${data.dataSourceName}-snowflake`);
}); });
it.skip("Should verify the functionality of PostgreSQL connection form.", () => { it.skip("Should verify the functionality of snowflake connection form.", () => {
selectAndAddDataSource("databases", "Snowflake", data.dataSourceName); selectAndAddDataSource("databases", "Snowflake", data.dataSourceName);
fillDataSourceTextField( fillDataSourceTextField(

View file

@ -4,6 +4,7 @@ import { postgreSqlText } from "Texts/postgreSql";
import { commonWidgetText, commonText } from "Texts/common"; import { commonWidgetText, commonText } from "Texts/common";
import { commonSelectors, commonWidgetSelector } from "Selectors/common"; import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { deleteDatasource, closeDSModal } from "Support/utils/dataSource"; import { deleteDatasource, closeDSModal } from "Support/utils/dataSource";
import { dataSourceSelector } from "Selectors/dataSource";
import { import {
addQuery, addQuery,
@ -21,6 +22,7 @@ const data = {};
describe("Data sources", () => { describe("Data sources", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -51,7 +53,28 @@ describe("Data sources", () => {
postgreSqlText.allCloudStorage postgreSqlText.allCloudStorage
); );
selectAndAddDataSource("databases", "SQL Server", data.dataSourceName); cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-sql-server`,
"mssql",
[
{ key: "host", value: "localhost" },
{ key: "instanceName", value: "" },
{ key: "port", value: 1433 },
{ key: "database", value: "" },
{ key: "username", value: "" },
{ key: "password", value: "", encrypted: true },
{ key: "azure", value: false, encrypted: false },
]
);
cy.reload();
cy.get(`[data-cy="cypress-${data.dataSourceName}-sql-server-button"]`)
.should("be.visible")
.click();
cy.get(dataSourceSelector.dsNameInputField).should(
"have.value",
`cypress-${data.dataSourceName}-sql-server`
);
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement( cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
"have.text", "have.text",
@ -67,7 +90,7 @@ describe("Data sources", () => {
); );
cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement( cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement(
"have.text", "have.text",
postgreSqlText.labelDbName "Database Name"
); );
cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement( cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement(
"have.text", "have.text",
@ -78,8 +101,8 @@ describe("Data sources", () => {
"Password" "Password"
); );
cy.get('[data-cy="label-azure"]').verifyVisibleElement( cy.get('[data-cy^="label-azure-"]').verifyVisibleElement(
"have.text", "contain",
"Azure" "Azure"
); );
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement( cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
@ -135,7 +158,7 @@ describe("Data sources", () => {
"1433" "1433"
); );
fillDataSourceTextField( fillDataSourceTextField(
postgreSqlText.labelDbName, "Database Name",
postgreSqlText.placeholderNameOfDB, postgreSqlText.placeholderNameOfDB,
Cypress.env("sqlserver_db") Cypress.env("sqlserver_db")
); );

View file

@ -0,0 +1,197 @@
import { fake } from "Fixtures/fake";
import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql";
import { twilioText } from "Texts/twilio";
import { twilioSelectors } from "Selectors/Plugins";
import { commonSelectors } from "Selectors/common";
import { commonText } from "Texts/common";
import {
fillDataSourceTextField,
selectAndAddDataSource,
} from "Support/utils/postgreSql";
import {
deleteDatasource,
closeDSModal,
deleteAppandDatasourceAfterExecution,
} from "Support/utils/dataSource";
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
import { pluginSelectors } from "Selectors/plugins";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source Twilio", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
});
it("Should verify elements on Twilio connection form", () => {
const AuthToken = Cypress.env("twilio_auth_token");
const AccountSID = Cypress.env("twilio_account_SID");
const MessageSID = Cypress.env("twilio_messaging_service_SID");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
"have.text",
postgreSqlText.allDataSources()
);
cy.get(postgreSqlSelector.commonlyUsedLabelAndCount).should(
"have.text",
postgreSqlText.commonlyUsed
);
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
"have.text",
postgreSqlText.allDatabase()
);
cy.get(postgreSqlSelector.apiLabelAndCount).should(
"have.text",
postgreSqlText.allApis
);
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
"have.text",
postgreSqlText.allCloudStorage
);
selectAndAddDataSource("databases", twilioText.twilio, data.dsName);
fillDataSourceTextField(
twilioText.authTokenLabel,
twilioText.authTokenPlaceholder,
AuthToken
);
fillDataSourceTextField(
twilioText.accountSidLabel,
twilioText.accountSidPlaceholder,
AccountSID
);
fillDataSourceTextField(
twilioText.messagingSIDLabel,
twilioText.messagingSIDPalceholder,
MessageSID
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-twilio`);
});
it("Should verify functionality of Twilio connection form", () => {
const AuthToken = Cypress.env("twilio_auth_token");
const AccountSID = Cypress.env("twilio_account_SID");
const MessageSID = Cypress.env("twilio_messaging_service_SID");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
selectAndAddDataSource("databases", twilioText.twilio, data.dsName);
fillDataSourceTextField(
twilioText.authTokenLabel,
twilioText.authTokenPlaceholder,
AuthToken
);
fillDataSourceTextField(
twilioText.accountSidLabel,
twilioText.accountSidPlaceholder,
AccountSID
);
fillDataSourceTextField(
twilioText.messagingSIDLabel,
twilioText.messagingSIDPalceholder,
MessageSID
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
deleteDatasource(`cypress-${data.dsName}-twilio`);
});
it("Should be able to run the query with a valid connection", () => {
const AuthToken = Cypress.env("twilio_auth_token");
const AccountSID = Cypress.env("twilio_account_SID");
const MessageSID = Cypress.env("twilio_messaging_service_SID");
const MessageNumber = Cypress.env("twilio_message_number");
cy.get(commonSelectors.globalDataSourceIcon).click();
closeDSModal();
selectAndAddDataSource("databases", twilioText.twilio, data.dsName);
fillDataSourceTextField(
twilioText.authTokenLabel,
twilioText.authTokenPlaceholder,
AuthToken
);
fillDataSourceTextField(
twilioText.accountSidLabel,
twilioText.accountSidPlaceholder,
AccountSID
);
fillDataSourceTextField(
twilioText.messagingSIDLabel,
twilioText.messagingSIDPalceholder,
MessageSID
);
cy.get(postgreSqlSelector.buttonSave)
.verifyVisibleElement("have.text", postgreSqlText.buttonTextSave)
.click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
postgreSqlText.toastDSSaved
);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsName);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
cy.get(pluginSelectors.operationDropdown).click().type("Send SMS{enter}");
cy.get(twilioSelectors.toNumberInputField).clearAndTypeOnCodeMirror(
MessageNumber
);
cy.get(twilioSelectors.bodyInput).clearAndTypeOnCodeMirror(
twilioText.messageText
);
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName}) completed.`
);
deleteAppandDatasourceAfterExecution(
data.dsName,
`cypress-${data.dsName}-twilio`
);
});
});

View file

@ -107,7 +107,7 @@ describe("App Import Functionality", () => {
); );
cy.get(commonSelectors.appNameLabel).verifyVisibleElement( cy.get(commonSelectors.appNameLabel).verifyVisibleElement(
"have.text", "have.text",
"App Name" "App name"
); );
cy.get(commonSelectors.appNameInput) cy.get(commonSelectors.appNameInput)
.should("be.visible") .should("be.visible")

View file

@ -15,6 +15,7 @@ describe("App Slug", () => {
beforeEach(() => { beforeEach(() => {
data.slug = `${fake.companyName.toLowerCase()}-app`; data.slug = `${fake.companyName.toLowerCase()}-app`;
data.appName = `${fake.companyName} App`; data.appName = `${fake.companyName} App`;
cy.log(Cypress.env("workspaceId"));
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
}); });
@ -24,6 +25,8 @@ describe("App Slug", () => {
cy.apiCreateApp(data.appName); cy.apiCreateApp(data.appName);
cy.wait(1000); cy.wait(1000);
cy.apiLogout(); cy.apiLogout();
cy.log(Cypress.env("workspaceId"));
}); });
it("Verify app slug cases in global settings", () => { it("Verify app slug cases in global settings", () => {

View file

@ -6,7 +6,6 @@ import { setSignupStatus } from "Support/utils/manageSSO";
import { onboardingSelectors } from "Selectors/onboarding"; import { onboardingSelectors } from "Selectors/onboarding";
import { commonText } from "Texts/common"; import { commonText } from "Texts/common";
import { import {
verifyConfirmEmailPage,
userSignUp, userSignUp,
addNewUser, addNewUser,
} from "Support/utils/onboarding"; } from "Support/utils/onboarding";
@ -33,6 +32,8 @@ describe("Private and Public apps", {
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.skipWalkthrough(); cy.skipWalkthrough();
cy.log(data.appName, "text1")
}); });
it("Verify private and public app share functionality", () => { it("Verify private and public app share functionality", () => {
@ -85,7 +86,8 @@ describe("Private and Public apps", {
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible"); cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
cy.wait(2000); cy.wait(2000);
cy.loginWithCredentials("dev@tooljet.io", "password"); cy.loginWithCredentials("dev@tooljet.io", "password");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible"); // cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
// Test public access // Test public access
cy.get(commonSelectors.viewerPageLogo).click(); cy.get(commonSelectors.viewerPageLogo).click();
@ -104,7 +106,9 @@ describe("Private and Public apps", {
cy.visitSlug({ cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`, 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('.text-widget-section > div').should("be.visible");
}); });
it("Verify app private and public app visibility for the same workspace user", () => { it("Verify app private and public app visibility for the same workspace user", () => {
@ -120,13 +124,17 @@ describe("Private and Public apps", {
cy.wait(2000); cy.wait(2000);
cy.loginWithCredentials(data.email, "password"); cy.loginWithCredentials(data.email, "password");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible", { timeout: 20000 });
// Test with private app valid session // Test with private app valid session
cy.visitSlug({ cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`, 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('.text-widget-section > div').should("be.visible");
cy.get(commonSelectors.viewerPageLogo).click(); cy.get(commonSelectors.viewerPageLogo).click();
// Test public access // Test public access
@ -137,14 +145,18 @@ describe("Private and Public apps", {
cy.visitSlug({ cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`, 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('.text-widget-section > div').should("be.visible");
// Test with public app with valid session // Test with public app with valid session
cy.apiLogin(data.email, "password"); cy.apiLogin(data.email, "password");
cy.visitSlug({ cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`, 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('.text-widget-section > div').should("be.visible");
}); });
it("Verify app private and public app visibility for the same instance user", () => { it("Verify app private and public app visibility for the same instance user", () => {
@ -168,14 +180,18 @@ describe("Private and Public apps", {
cy.visitSlug({ cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`, 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('.text-widget-section > div').should("be.visible");
// Verify public app with valid session // Verify public app with valid session
cy.apiLogin(data.email, "password"); cy.apiLogin(data.email, "password");
cy.visitSlug({ cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`, 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('.text-widget-section > div').should("be.visible");
}); });
it("Should redirect to workspace login and handle signup flow of existing and non-existing user", () => { it("Should redirect to workspace login and handle signup flow of existing and non-existing user", () => {
@ -193,18 +209,24 @@ describe("Private and Public apps", {
); );
// Test signup flow // Test signup flow
cy.intercept("POST", "/api/onboarding/signup").as("signup");
cy.get(commonSelectors.createAnAccountLink).click(); cy.get(commonSelectors.createAnAccountLink).click();
cy.wait(3000); cy.wait(3000);
cy.clearAndType(commonSelectors.inputFieldFullName, data.firstName); cy.clearAndType(commonSelectors.inputFieldFullName, data.firstName);
cy.clearAndType(commonSelectors.inputFieldEmailAddress, data.email); cy.clearAndType(commonSelectors.inputFieldEmailAddress, data.email);
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password"); cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
cy.get(commonSelectors.signUpButton).click(); cy.get(commonSelectors.signUpButton).click();
verifyConfirmEmailPage(data.email);
cy.wait('@signup').then((interception) => {
expect(interception.response.statusCode).to.eq(201);
});
// Process invitation // Process invitation
onboardUserFromAppLink(data.email, data.slug); onboardUserFromAppLink(data.email, data.slug);
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible"); // cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.get('[data-cy="viewer-page-logo"]').click(); cy.get('[data-cy="viewer-page-logo"]').click();
logout(); logout();
@ -242,10 +264,14 @@ describe("Private and Public apps", {
cy.clearAndType(commonSelectors.inputFieldEmailAddress, data.email); cy.clearAndType(commonSelectors.inputFieldEmailAddress, data.email);
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password"); cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
cy.get(commonSelectors.signUpButton).click(); cy.get(commonSelectors.signUpButton).click();
verifyConfirmEmailPage(data.email); cy.wait('@signup').then((interception) => {
expect(interception.response.statusCode).to.eq(201);
});
onboardUserFromAppLink(data.email, data.slug, data.workspaceName, false); onboardUserFromAppLink(data.email, data.slug, data.workspaceName, false);
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible"); // cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
}); });
it("Should verify restricted app access", () => { it("Should verify restricted app access", () => {

View file

@ -111,7 +111,10 @@ describe("App Version", () => {
onlydeleteVersionText.deleteToastMessage("v3") onlydeleteVersionText.deleteToastMessage("v3")
); );
cy.get(appVersionSelectors.currentVersionField("v2")).should("be.visible"); cy.get(appVersionSelectors.currentVersionField("v2")).should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible"); cy.wait(3000);
// cy.reload();
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible", { timeout: 10000 });
// Preview and release verification // Preview and release verification
cy.openInCurrentTab(commonWidgetSelector.previewButton); cy.openInCurrentTab(commonWidgetSelector.previewButton);
@ -120,7 +123,7 @@ describe("App Version", () => {
releasedVersionAndVerify("v2"); releasedVersionAndVerify("v2");
}); });
it("should verify version management with components and queries", () => { it.only("should verify version management with components and queries", () => {
// Initial setup with component and datasource // Initial setup with component and datasource
cy.apiAddComponentToApp( cy.apiAddComponentToApp(
data.appName, data.appName,
@ -132,7 +135,7 @@ describe("App Version", () => {
cy.waitForAutoSave(); cy.waitForAutoSave();
cy.apiCreateGDS( cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/v2/data_sources`, `${Cypress.env("server_host")}/api/data-sources`,
data.datasourceName, data.datasourceName,
"restapi", "restapi",
[{ key: "url", value: "https://jsonplaceholder.typicode.com/users" }] [{ key: "url", value: "https://jsonplaceholder.typicode.com/users" }]

View file

@ -183,7 +183,7 @@ describe("Datasource Manager", () => {
data.dsName1 data.dsName1
); );
cy.intercept("GET", "/api/v2/data_sources").as("datasource"); // cy.intercept("GET", "/api/v2/data_sources").as("datasource");
fillConnectionForm( fillConnectionForm(
{ {
Host: Cypress.env("pg_host"), Host: Cypress.env("pg_host"),
@ -194,7 +194,8 @@ describe("Datasource Manager", () => {
}, },
".form-switch" ".form-switch"
); );
cy.wait("@datasource"); // cy.wait("@datasource");
cy.wait(1000);
cy.apiCreateApp(data.appName); cy.apiCreateApp(data.appName);
cy.openApp(); cy.openApp();
@ -223,7 +224,7 @@ describe("Datasource Manager", () => {
cy.get('[data-cy="databases-datasource-button"]').should("be.visible"); cy.get('[data-cy="databases-datasource-button"]').should("be.visible");
cy.apiCreateGDS( cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/v2/data_sources`, `${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dsName2}-postgresql`, `cypress-${data.dsName2}-postgresql`,
"postgresql", "postgresql",
[ [

View file

@ -3,7 +3,12 @@ import { commonText } from "Texts/common";
import { onboardingSelectors } from "Selectors/onboarding"; import { onboardingSelectors } from "Selectors/onboarding";
import { onboardingText } from "Texts/onboarding"; import { onboardingText } from "Texts/onboarding";
import { logout } from "Support/utils/common"; import { logout } from "Support/utils/common";
import { bannerElementsVerification } from "Support/utils/onboarding"; import {
bannerElementsVerification,
onboardingStepOne,
onboardingStepTwo,
onboardingStepThree,
} from "Support/utils/onboarding";
describe("Self host onboarding", () => { describe("Self host onboarding", () => {
const envVar = Cypress.env("environment"); const envVar = Cypress.env("environment");
@ -24,9 +29,11 @@ describe("Self host onboarding", () => {
"have.text", "have.text",
"Let's set up your admin account and workspace to get started!" "Let's set up your admin account and workspace to get started!"
); );
cy.get('[data-cy="set-up-tooljet-button"]') cy.get('[data-cy="set-up-tooljet-button"]').verifyVisibleElement(
.verifyVisibleElement("have.text", "Set up ToolJet") "have.text",
.click(); "Set up ToolJet"
);
cy.get('[data-cy="set-up-tooljet-button"]').click();
} }
const commonElements = [ const commonElements = [
@ -72,7 +79,8 @@ describe("Self host onboarding", () => {
if (envVar === "Community") { if (envVar === "Community") {
cy.get(commonSelectors.signUpTermsHelperText).should(($el) => { cy.get(commonSelectors.signUpTermsHelperText).should(($el) => {
expect($el.contents().first().text().trim()).to.eq( expect($el.contents().first().text().trim()).to.eq(
commonText.selfHostSignUpTermsHelperText // commonText.selfHostSignUpTermsHelperText
"By signing up you are agreeing to the"
); );
}); });
} else if (envVar === "Enterprise") { } else if (envVar === "Enterprise") {
@ -110,68 +118,16 @@ describe("Self host onboarding", () => {
if (envVar === "Enterprise") { if (envVar === "Enterprise") {
bannerElementsVerification(); bannerElementsVerification();
onboardingStepOne();
const companyPageTexts = [
{
selector: onboardingSelectors.tellUsAbit,
text: "Tell us a bit about yourself",
},
{
selector: onboardingSelectors.pageDescription,
text: "This information will help us improve ToolJet",
},
{
selector: '[data-cy="onboarding-company-name-label"]',
text: "Company name *",
},
{
selector: '[data-cy="onboarding-build-purpose-label"]',
text: "What would you like to build on ToolJet? *",
},
];
companyPageTexts.forEach((item) => {
cy.get(item.selector).should("be.visible").and("have.text", item.text);
});
cy.get(onboardingSelectors.companyNameInput).should("be.visible");
cy.get(onboardingSelectors.buildPurposeInput).should("be.visible");
cy.get(onboardingSelectors.onboardingSubmitButton).verifyVisibleElement(
"have.attr",
"disabled"
);
cy.get(onboardingSelectors.companyNameInput).type("Tooljet");
cy.get(onboardingSelectors.onboardingSubmitButton).should(
"have.attr",
"disabled"
);
cy.get(onboardingSelectors.buildPurposeInput).type("Exploring");
cy.get(onboardingSelectors.onboardingSubmitButton).verifyVisibleElement(
"have.text",
"Continue"
);
cy.get(onboardingSelectors.onboardingSubmitButton)
.should("be.enabled")
.click();
} }
bannerElementsVerification(); bannerElementsVerification();
cy.get(commonSelectors.setUpworkspaceCheckPoint) onboardingStepTwo();
.should("be.visible")
.and("have.text", "Set up your workspace!");
cy.get(onboardingSelectors.pageDescription).verifyVisibleElement( // if (envVar === "Enterprise") {
"have.text", // bannerElementsVerification();
"Set up workspaces to manage users, applications & resources across various teams" // onboardingStepTwo();
); // }
cy.get(commonSelectors.workspaceNameInputLabel)
.should("be.visible")
.and("have.text", commonText.workspaceNameInputLabel);
cy.clearAndType(commonSelectors.workspaceNameInputField, "My workspace");
cy.get(commonSelectors.OnbordingContinue)
.verifyVisibleElement("have.text", "Continue")
.click();
if (envVar === "Enterprise") { if (envVar === "Enterprise") {
bannerElementsVerification(); bannerElementsVerification();
@ -317,25 +273,15 @@ describe("Self host onboarding", () => {
cy.get(onboardingSelectors.declineButton).click(); cy.get(onboardingSelectors.declineButton).click();
bannerElementsVerification(); bannerElementsVerification();
cy.get( onboardingStepThree();
`[data-cy="we've-created-a-sample-application-for-you!-header"]`
).verifyVisibleElement(
"have.text",
"We've created a sample application for you!"
);
cy.get(onboardingSelectors.pageDescription).verifyVisibleElement(
"have.text",
"The sample application comes with a sample PostgreSQL database for you to play around with. You can also get started quickly with pre-built applications from our template collection!"
);
cy.get(onboardingSelectors.onboardingSubmitButton)
.verifyVisibleElement("have.text", "Continue")
.click();
} }
cy.get(commonSelectors.skipbutton).click(); cy.get(commonSelectors.skipbutton).click();
cy.get(commonSelectors.backLogo).click(); cy.backToApps();
cy.get(commonSelectors.backtoapps).click();
if (envVar === "Enterprise") {
cy.get(".btn-close").click();
}
if (envVar === "Enterprise") { if (envVar === "Enterprise") {
cy.get(".btn-close").click(); cy.get(".btn-close").click();

View file

@ -9,6 +9,7 @@ describe("Login functionality", () => {
let user; let user;
const invalidEmail = fake.email; const invalidEmail = fake.email;
const invalidPassword = fake.password; const invalidPassword = fake.password;
const envVar = Cypress.env("environment");
beforeEach(() => { beforeEach(() => {
cy.fixture("credentials/login.json").then((login) => { cy.fixture("credentials/login.json").then((login) => {
@ -49,6 +50,9 @@ describe("Login functionality", () => {
it("Should be able to login with valid credentials", () => { it("Should be able to login with valid credentials", () => {
cy.appUILogin(user.email, user.password); cy.appUILogin(user.email, user.password);
if (envVar === "Enterprise") {
cy.get(".btn-close").click();
}
cy.get(commonSelectors.settingsIcon).click(); cy.get(commonSelectors.settingsIcon).click();
cy.get(dashboardSelector.logoutLink); cy.get(dashboardSelector.logoutLink);
}); });

View file

@ -41,7 +41,7 @@ describe("User signup", () => {
cy.wait(500); cy.wait(500);
verifyConfirmEmailPage(data.email); verifyConfirmEmailPage(data.email);
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `select invitation_token from users where email='${data.email}';`, sql: `select invitation_token from users where email='${data.email}';`,
}).then((resp) => { }).then((resp) => {
@ -67,9 +67,8 @@ describe("User signup", () => {
data.workspaceName = fake.companyName; data.workspaceName = fake.companyName;
cy.visit("/"); cy.visit("/");
cy.wait(8000);
cy.get(onboardingSelectors.createAnAccountLink).click(); cy.get(onboardingSelectors.createAnAccountLink).click();
cy.wait(6000); cy.wait(2000);
cy.get(onboardingSelectors.nameInput).clear(); cy.get(onboardingSelectors.nameInput).clear();
cy.get(onboardingSelectors.nameInput).type(data.fullName); cy.get(onboardingSelectors.nameInput).type(data.fullName);
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email); cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
@ -77,14 +76,17 @@ describe("User signup", () => {
onboardingSelectors.loginPasswordInput, onboardingSelectors.loginPasswordInput,
commonText.password commonText.password
); );
cy.intercept("POST", "/api/onboarding/signup").as("signup");
cy.get(commonSelectors.signUpButton).click(); cy.get(commonSelectors.signUpButton).click();
cy.wait(8000);
cy.get(commonSelectors.resendEmailButton).click(); cy.wait("@signup")
cy.task("updateId", { cy.get('[data-cy="check-your-mail-header"]').should("be.visible");
cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `select invitation_token from users where email='${data.email}';`, sql: `select invitation_token from users where email='${data.email}';`,
}).then((resp) => { }).then((resp) => {
invitationLink = `/invitations/${resp.rows[0].invitation_token}`; invitationLink = `/invitations/${resp.rows[0].invitation_token}`;
cy.visit(invitationLink);
}); });
}); });
}); });

View file

@ -11,15 +11,8 @@ import {
inviteUserWithUserRole, inviteUserWithUserRole,
fetchAndVisitInviteLink, fetchAndVisitInviteLink,
} from "Support/utils/manageUsers"; } from "Support/utils/manageUsers";
import { addNewUser, visitWorkspaceInvitation, addNewUsertoworkspace } from "Support/utils/onboarding";
import { commonText } from "Texts/common"; import { commonText } from "Texts/common";
import { setSignupStatus } from "Support/utils/manageSSO"; import { visitWorkspaceInvitation, addNewUser } from "Support/utils/onboarding";
import { ssoSelector } from "Selectors/manageSSO";
import {
SignUpPageElements,
signUpLink,
verifyOnboardingQuestions,
} from "Support/utils/onboarding";
import { import {
navigateToManageUsers, navigateToManageUsers,
@ -38,11 +31,16 @@ let invitationToken,
url = ""; url = "";
const data = {}; const data = {};
const envVar = Cypress.env("environment");
describe("user invite flow cases", () => { describe("user invite flow cases", () => {
beforeEach(() => { beforeEach(() => {
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
if (envVar === "Enterprise") {
cy.get(".btn-close").click();
}
}); });
it("Should verify the Manage users page", () => { it("Should verify the Manage users page", () => {
data.firstName = fake.firstName; data.firstName = fake.firstName;
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", ""); data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
@ -202,7 +200,7 @@ describe("user invite flow cases", () => {
}); });
}); });
it("Should verify the user onboarding with groups", () => { it.skip("Should verify the user onboarding with groups", () => {
data.firstName = fake.firstName; data.firstName = fake.firstName;
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", ""); data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
data.groupName1 = fake.firstName.replaceAll("[^A-Za-z]", ""); data.groupName1 = fake.firstName.replaceAll("[^A-Za-z]", "");
@ -264,6 +262,8 @@ describe("user invite flow cases", () => {
cy.wait(1000); cy.wait(1000);
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.get(commonSelectors.homePageLogo, { timeout: 10000 }).should("be.visible");
navigateToManageGroups(); navigateToManageGroups();
cy.get(groupsSelector.groupLink(data.groupName1)).click(); cy.get(groupsSelector.groupLink(data.groupName1)).click();
cy.get(groupsSelector.usersLink).click(); cy.get(groupsSelector.usersLink).click();
@ -350,10 +350,19 @@ describe("user invite flow cases", () => {
"have.text", "have.text",
data.email data.email
); );
cy.get('[data-cy="modal-body"]>').verifyVisibleElement(
"have.text", if (envVar === "Enterprise") {
"Updating the user's details will change their role from end-user to admin. Are you sure you want to continue?" cy.get('[data-cy="modal-body"]>').verifyVisibleElement(
); "have.text",
"Changing user default group from end-user to admin will affect the count of users covered by your plan.Are you sure you want to continue?"
);
} else {
cy.get('[data-cy="modal-body"]>').verifyVisibleElement(
"have.text",
"Changing the user role from end-user to admin will grant the user access to all resources and settings.Are you sure you want to continue?"
);
}
cy.get('.modal-footer > [data-cy="cancel-button"]').verifyVisibleElement( cy.get('.modal-footer > [data-cy="cancel-button"]').verifyVisibleElement(
"have.text", "have.text",
"Cancel" "Cancel"
@ -427,153 +436,4 @@ describe("user invite flow cases", () => {
"Builder" "Builder"
); );
}); });
it("Should verify exisiting user invite flow", () => {
data.firstName = fake.firstName;
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
const workspaceName = data.firstName.toLowerCase();
addNewUser(data.firstName, data.email);
logout();
cy.defaultWorkspaceLogin();
cy.apiCreateWorkspace(workspaceName, workspaceName);
cy.visit(workspaceName);
navigateToManageUsers();
fillUserInviteForm(data.firstName, data.email);
cy.get(usersSelector.buttonInviteUsers).click();
cy.wait(2000);
visitWorkspaceInvitation(data.email, workspaceName);
cy.wait(3000);
cy.clearAndType(onboardingSelectors.loginEmailInput, data.email);
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
cy.get(onboardingSelectors.signInButton).click();
cy.get(usersSelector.acceptInvite).click();
cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast);
logout();
cy.defaultWorkspaceLogin();
navigateToManageUsers();
searchUser(data.email);
cy.contains("td", data.email)
.parent()
.within(() => {
cy.get("td small").should("have.text", usersText.activeStatus);
});
});
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;
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);
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();
});
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]", "");
data.signUpName = fake.firstName;
data.workspaceName = fake.companyName;
setSignupStatus(true);
navigateToManageUsers();
fillUserInviteForm(data.firstName, data.email);
cy.get(usersSelector.buttonInviteUsers).click();
logout();
cy.get(commonSelectors.createAnAccountLink).click();
SignUpPageElements();
cy.wait(5000);
cy.clearAndType(onboardingSelectors.nameInput, data.signUpName);
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
cy.clearAndType(
onboardingSelectors.loginPasswordInput,
commonText.password
);
cy.get(commonSelectors.signUpButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
"The user is already registered. Please check your inbox for the activation link"
);
});
it("should verify exisiting user workspace signup from instance using form", () => {
data.firstName = fake.firstName;
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
data.signUpName = fake.firstName;
data.workspaceName = fake.firstName.toLowerCase();
setSignupStatus(true);
navigateToManageUsers();
addNewUser(data.firstName, data.email);
logout();
cy.wait(3000);
cy.get(commonSelectors.createAnAccountLink).click();
cy.wait(1000);
cy.clearAndType(onboardingSelectors.nameInput, data.firstName);
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
cy.clearAndType(
onboardingSelectors.loginPasswordInput,
commonText.password
);
cy.get(commonSelectors.signUpButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
"User already exists in the workspace."
);
cy.apiLogin();
cy.apiCreateWorkspace(data.workspaceName, data.workspaceName);
cy.visit(`${data.workspaceName}`);
cy.wait(3000);
setSignupStatus(true, data.workspaceName);
logout();
cy.get(commonSelectors.createAnAccountLink).click();
cy.wait(3000);
cy.clearAndType(onboardingSelectors.nameInput, data.firstName);
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
cy.clearAndType(
onboardingSelectors.loginPasswordInput,
commonText.password
);
cy.get(commonSelectors.signUpButton).click();
cy.defaultWorkspaceLogin();
visitWorkspaceInvitation(data.email, data.workspaceName);
cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast);
logout();
});
}); });

View file

@ -82,7 +82,7 @@ describe("Password reset functionality", () => {
}); });
// Get and visit reset password link // Get and visit reset password link
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `select forgot_password_token from users where email='${data.email}';`, sql: `select forgot_password_token from users where email='${data.email}';`,
}).then((resp) => { }).then((resp) => {

View file

@ -0,0 +1,195 @@
import { commonSelectors } from "Selectors/common";
import { fake } from "Fixtures/fake";
import { usersText } from "Texts/manageUsers";
import { usersSelector } from "Selectors/manageUsers";
import { fillUserInviteForm } from "Support/utils/manageUsers";
import { commonText } from "Texts/common";
import { setSignupStatus } from "Support/utils/manageSSO";
import {
SignUpPageElements,
signUpLink,
verifyOnboardingQuestions,
visitWorkspaceInvitation,
addNewUser,
enableInstanceSignUp,
} from "Support/utils/onboarding";
import {
navigateToManageUsers,
logout,
searchUser,
} from "Support/utils/common";
import { onboardingSelectors } from "Selectors/onboarding";
const data = {};
const envVar = Cypress.env("environment");
describe("inviteflow edge cases", () => {
beforeEach(() => {
cy.defaultWorkspaceLogin();
if (envVar === "Enterprise") {
cy.get(".btn-close").click();
}
});
it("Should verify exisiting user invite flow", () => {
data.firstName = fake.firstName;
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
const workspaceName = data.firstName.toLowerCase();
addNewUser(data.firstName, data.email);
logout();
cy.defaultWorkspaceLogin();
cy.apiCreateWorkspace(workspaceName, workspaceName);
cy.visit(workspaceName);
navigateToManageUsers();
fillUserInviteForm(data.firstName, data.email);
cy.get(usersSelector.buttonInviteUsers).click();
cy.wait(2000);
visitWorkspaceInvitation(data.email, workspaceName);
cy.wait(3000);
cy.clearAndType(onboardingSelectors.loginEmailInput, data.email);
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
cy.get(onboardingSelectors.signInButton).click();
cy.get(usersSelector.acceptInvite).click();
cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast);
logout();
cy.defaultWorkspaceLogin();
navigateToManageUsers();
searchUser(data.email);
cy.contains("td", data.email)
.parent()
.within(() => {
cy.get("td small").should("have.text", usersText.activeStatus);
});
});
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]", "");
data.signUpName = fake.firstName;
data.workspaceName = fake.companyName;
setSignupStatus(true);
navigateToManageUsers();
fillUserInviteForm(data.firstName, data.email);
cy.get(usersSelector.buttonInviteUsers).click();
logout();
cy.get(commonSelectors.createAnAccountLink).click();
SignUpPageElements();
cy.wait(5000);
cy.clearAndType(onboardingSelectors.nameInput, data.signUpName);
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
cy.clearAndType(
onboardingSelectors.loginPasswordInput,
commonText.password
);
cy.get(commonSelectors.signUpButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
"The user is already registered. Please check your inbox for the activation link"
);
});
it("should verify exisiting user workspace signup from instance using form", () => {
data.firstName = fake.firstName;
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
data.signUpName = fake.firstName;
data.workspaceName = fake.firstName.toLowerCase();
setSignupStatus(true);
navigateToManageUsers();
addNewUser(data.firstName, data.email);
logout();
cy.wait(3000);
cy.get(commonSelectors.createAnAccountLink).click();
cy.wait(1000);
cy.clearAndType(onboardingSelectors.nameInput, data.firstName);
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
cy.clearAndType(
onboardingSelectors.loginPasswordInput,
commonText.password
);
cy.get(commonSelectors.signUpButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
"User already exists in the workspace."
);
cy.apiLogin();
cy.apiCreateWorkspace(data.workspaceName, data.workspaceName);
cy.visit(`${data.workspaceName}`);
cy.wait(3000);
setSignupStatus(true, data.workspaceName);
logout();
cy.get(commonSelectors.createAnAccountLink).click();
cy.wait(3000);
cy.clearAndType(onboardingSelectors.nameInput, data.firstName);
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
cy.clearAndType(
onboardingSelectors.loginPasswordInput,
commonText.password
);
cy.get(commonSelectors.signUpButton).click();
cy.defaultWorkspaceLogin();
visitWorkspaceInvitation(data.email, data.workspaceName);
cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast);
logout();
});
});

View file

@ -262,8 +262,8 @@ describe("App creation", () => {
cy.get(importSelectors.dropDownMenu).click(); cy.get(importSelectors.dropDownMenu).click();
cy.get(commonSelectors.chooseFromTemplateButton).click(); cy.get(commonSelectors.chooseFromTemplateButton).click();
cy.clearAndType('[data-cy="search-input-field"]', "Admin portal"); cy.clearAndType('[data-cy="search-input-field"]', "Admin panel");
cy.get('[data-cy="admin-portal-list-item"]').click(); cy.get('[data-cy="admin-panel-tooljet-db-list-item"]').click();
cy.get('[data-cy="create-application-from-template-button"]').click() cy.get('[data-cy="create-application-from-template-button"]').click()
cy.wait(1000); cy.wait(1000);
@ -277,7 +277,7 @@ describe("App creation", () => {
); );
cy.get(commonSelectors.appNameInput).verifyVisibleElement( cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"have.value", "have.value",
"Admin portal" "Admin Panel (ToolJet Database)"
); );
cy.get(commonSelectors.appNameInfoLabel).verifyVisibleElement( cy.get(commonSelectors.appNameInfoLabel).verifyVisibleElement(
"have.text", "have.text",

View file

@ -49,11 +49,11 @@ describe("dashboard", () => {
}); });
it("should verify the elements on empty dashboard", () => { it("should verify the elements on empty dashboard", () => {
cy.intercept("GET", "/api/apps?page=1&folder=&searchKey=", { cy.intercept("GET", "/api/apps?page=1&folder=&searchKey=&type=front-end", {
fixture: "intercept/emptyDashboard.json", fixture: "intercept/emptyDashboard.json",
}).as("emptyDashboard"); }).as("emptyDashboard");
cy.intercept("GET", "/api/folders?searchKey=", { cy.intercept("GET", "/api/folder-apps?searchKey=&type=front-end", {
body: { folders: [] }, body: { folders: [] },
}).as("folders"); }).as("folders");
@ -87,7 +87,7 @@ describe("dashboard", () => {
cy.get(commonSelectors.createNewFolderButton).should("be.visible"); cy.get(commonSelectors.createNewFolderButton).should("be.visible");
cy.get(commonSelectors.allApplicationLink).verifyVisibleElement( cy.get(commonSelectors.allApplicationLink).verifyVisibleElement(
"have.text", "have.text",
commonText.allApplicationLink commonText.allApplicationsLink
); );
cy.get(commonSelectors.notificationsIcon).should("be.visible").click(); cy.get(commonSelectors.notificationsIcon).should("be.visible").click();
@ -312,6 +312,7 @@ describe("dashboard", () => {
cy.get(commonSelectors.appCard(data.cloneAppName)).should("be.visible"); cy.get(commonSelectors.appCard(data.cloneAppName)).should("be.visible");
cy.wait(3000)
viewAppCardOptions(data.cloneAppName); viewAppCardOptions(data.cloneAppName);
cy.get(commonSelectors.appCardOptions(commonText.exportAppOption)).click(); cy.get(commonSelectors.appCardOptions(commonText.exportAppOption)).click();
cy.get(commonSelectors.exportAllButton).click(); cy.get(commonSelectors.exportAllButton).click();
@ -519,7 +520,7 @@ describe("dashboard", () => {
it("should verify the elements on empty dashboard for end user", () => { it("should verify the elements on empty dashboard for end user", () => {
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.intercept("GET", "/api/apps?page=1&folder=&searchKey=", { cy.intercept("GET", "/api/apps?page=1&folder=&searchKey=&type=front-end", {
fixture: "intercept/emptyDashboard.json", fixture: "intercept/emptyDashboard.json",
}).as("emptyDashboard") }).as("emptyDashboard")
roleBasedOnboarding(data.firstName, data.email, "end-user"); roleBasedOnboarding(data.firstName, data.email, "end-user");

View file

@ -24,6 +24,7 @@ import {
exportAppModalSelectors, exportAppModalSelectors,
importSelectors, importSelectors,
} from "Selectors/exportImport"; } from "Selectors/exportImport";
import { dashboardText } from "../../../../../../constants/texts/dashboard";
describe("Manage Groups", () => { describe("Manage Groups", () => {
let data = {}; let data = {};
@ -114,9 +115,9 @@ describe("Manage Groups", () => {
cy.get(commonSelectors.cloneAppButton).click(); cy.get(commonSelectors.cloneAppButton).click();
cy.verifyToastMessage( cy.verifyToastMessage(
commonSelectors.toastMessage, commonSelectors.toastMessage,
commonText.cloneAppErrorToast dashboardText.appClonedToast
); );
cy.get(commonSelectors.cancelButton).click(); // cy.get(commonSelectors.cancelButton).click();
cy.apiLogout(); cy.apiLogout();
cy.apiLogin(); cy.apiLogin();

View file

@ -202,7 +202,6 @@ describe("Manage Groups", () => {
testDuplicateGroup(); testDuplicateGroup();
createNewGroup(); createNewGroup();
// Verify permissions section
cy.get(groupsSelector.permissionsLink).click(); cy.get(groupsSelector.permissionsLink).click();
verifyPermissionSection(); verifyPermissionSection();
@ -220,8 +219,8 @@ describe("Manage Groups", () => {
cy.get(`[data-cy="${groupName.toLowerCase()}-text"]`).click(); cy.get(`[data-cy="${groupName.toLowerCase()}-text"]`).click();
cy.get(`${groupsSelector.addEditPermissionModalTitle}:eq(2)`) cy.get(`${groupsSelector.addEditPermissionModalTitle}:eq(2)`)
.verifyVisibleElement("have.text", groupsText.editPermissionModalTitle); .verifyVisibleElement("have.text", groupsText.editPermissionModalTitle);
verifyModalFields(true, groupName);
cy.get(groupsSelector.editPermissionRadio).check(); cy.get(groupsSelector.editPermissionRadio).check();
verifyModalFields(true, groupName);
cy.get(groupsSelector.confimButton).click(); cy.get(groupsSelector.confimButton).click();
}; };

View file

@ -466,7 +466,7 @@ describe("Manage Groups", () => {
cy.wait(500); cy.wait(500);
cy.apiCreateGDS( cy.apiCreateGDS(
`${Cypress.env('server_host')}/api/v2/data_sources`, `${Cypress.env('server_host')}/api/data-sources`,
`cypress-${data.dsName}-qc-postgresql`, `cypress-${data.dsName}-qc-postgresql`,
"postgresql", "postgresql",
[ [

View file

@ -111,24 +111,21 @@ export const onboardUserFromAppLink = (
WHERE u.email = '${email}' AND o.name = '${workspaceName}'; WHERE u.email = '${email}' AND o.name = '${workspaceName}';
`; `;
return cy cy.task("dbConnection", { dbconfig: dbConfig, sql: query }).then((resp) => {
.task("updateId", { dbconfig: dbConfig, sql: query }) if (!resp.rows || resp.rows.length === 0) {
.then((resp) => { throw new Error(
if (!resp.rows || resp.rows.length === 0) { `No records found for email: ${email} and workspace: ${workspaceName}`
throw new Error( );
`No records found for email: ${email} and workspace: ${workspaceName}` }
);
}
const { invitation_token, workspace_id, organization_token } = const { invitation_token, workspace_id, organization_token } = resp.rows[0];
resp.rows[0]; const token = isNonExistingUser ? organization_token : invitation_token;
const token = isNonExistingUser ? organization_token : invitation_token; const url = isNonExistingUser
const url = isNonExistingUser ? `${Cypress.config("baseUrl")}/invitations/${invitation_token}/workspaces/${organization_token}?oid=${workspace_id}&redirectTo=%2Fapplications%2F${slug}`
? `${Cypress.config("baseUrl")}/invitations/${invitation_token}/workspaces/${organization_token}?oid=${workspace_id}&redirectTo=%2Fapplications%2F${slug}` : `${Cypress.config("baseUrl")}/organization-invitations/${token}?oid=${workspace_id}&redirectTo=%2Fapplications%2F${slug}`;
: `${Cypress.config("baseUrl")}/organization-invitations/${token}?oid=${workspace_id}&redirectTo=%2Fapplications%2F${slug}`;
cy.visit(url); cy.visit(url);
}); });
}; };
export const resolveHost = () => { export const resolveHost = () => {
@ -138,9 +135,8 @@ export const resolveHost = () => {
"http://localhost:8082": "http://localhost:8082", "http://localhost:8082": "http://localhost:8082",
"http://localhost:3000/apps": "http://localhost:3000/apps", "http://localhost:3000/apps": "http://localhost:3000/apps",
"http://localhost:4001": "http://localhost:3000", "http://localhost:4001": "http://localhost:3000",
"http://localhost:4001/apps": "http://localhost:3000/apps" "http://localhost:4001/apps": "http://localhost:3000/apps",
}; };
return urlMapping[baseUrl]; return urlMapping[baseUrl];
}; };

View file

@ -40,7 +40,7 @@ export const verifyControlComponentAction = (widgetName, value) => {
export const addBasicData = (data) => { export const addBasicData = (data) => {
openEditorSidebar(buttonText.defaultWidgetName); openEditorSidebar(buttonText.defaultWidgetName);
verifyAndModifyParameter(buttonText.buttonTextLabel, data.widgetName); verifyAndModifyParameter('Label', data.widgetName);
openAccordion(commonWidgetText.accordionEvents); openAccordion(commonWidgetText.accordionEvents);
addDefaultEventHandler(data.alertMessage); addDefaultEventHandler(data.alertMessage);

View file

@ -91,7 +91,7 @@ export const navigateToAppEditor = (appName) => {
.find(commonSelectors.editButton) .find(commonSelectors.editButton)
.click({ force: true }); .click({ force: true });
if (Cypress.env("environment") === "Community") { if (Cypress.env("environment") === "Community") {
cy.intercept("GET", "/api/v2/data_sources").as("appDs"); cy.intercept("GET", "/api/data-sources").as("appDs");
cy.wait("@appDs", { timeout: 15000 }); cy.wait("@appDs", { timeout: 15000 });
cy.skipEditorPopover(); cy.skipEditorPopover();
} else { } else {

View file

@ -6,6 +6,7 @@ import { commonText } from "Texts/common";
import { dataSourceSelector } from "Selectors/dataSource"; import { dataSourceSelector } from "Selectors/dataSource";
import { dataSourceText } from "Texts/dataSource"; import { dataSourceText } from "Texts/dataSource";
import { navigateToAppEditor } from "Support/utils/common"; import { navigateToAppEditor } from "Support/utils/common";
import { verifyAppDelete } from "Support/utils/dashboard";
export const verifyCouldnotConnectWithAlert = (dangerText) => { export const verifyCouldnotConnectWithAlert = (dangerText) => {
cy.get(postgreSqlSelector.connectionFailedText, { cy.get(postgreSqlSelector.connectionFailedText, {
@ -60,6 +61,15 @@ export const deleteDatasource = (datasourceName) => {
// " Databases" // " Databases"
// ); // );
}; };
export const deleteAppandDatasourceAfterExecution = (
appName,
datasourceName
) => {
cy.backToApps();
cy.deleteApp(appName);
verifyAppDelete(appName);
deleteDatasource(datasourceName);
};
export const closeDSModal = () => { export const closeDSModal = () => {
cy.get("body").then(($body) => { cy.get("body").then(($body) => {
@ -79,7 +89,7 @@ export const addQueryN = (queryName, query, dbName) => {
cy.clearAndType('[data-cy="gds-querymanager-search-bar"]', `${dbName}`); cy.clearAndType('[data-cy="gds-querymanager-search-bar"]', `${dbName}`);
} }
}); });
cy.intercept("POST", "/api/data_queries").as("createQuery"); cy.intercept("POST", "/api/data-queries/**").as("createQuery");
cy.get(`[data-cy="${dbName}-add-query-card"] > .text-truncate`).click(); cy.get(`[data-cy="${dbName}-add-query-card"] > .text-truncate`).click();
cy.get('[data-cy="query-rename-input"]').clear().type(queryName); cy.get('[data-cy="query-rename-input"]').clear().type(queryName);
@ -96,9 +106,7 @@ export const addQueryN = (queryName, query, dbName) => {
export const addQuery = (queryName, query, dbName) => { export const addQuery = (queryName, query, dbName) => {
cy.get('[data-cy="show-ds-popover-button"]').click(); cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${dbName}`); cy.get(".css-4e90k9").type(`${dbName}`);
cy.intercept("POST", "/api/data_queries").as( cy.intercept("POST", "/api/data-queries/**").as("createQuery");
"createQuery"
);
cy.contains(`[id*="react-select-"]`, dbName).click(); cy.contains(`[id*="react-select-"]`, dbName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(queryName); cy.get('[data-cy="query-rename-input"]').clear().type(queryName);
@ -132,7 +140,7 @@ export const addQueryAndOpenEditor = (queryName, query, dbName, appName) => {
cy.get('[data-cy="show-ds-popover-button"]').click(); cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${dbName}`); cy.get(".css-4e90k9").type(`${dbName}`);
cy.get(".css-4e90k9").type(`${dbName}`); cy.get(".css-4e90k9").type(`${dbName}`);
cy.intercept("POST", "/api/data_queries").as("createQuery"); cy.intercept("POST", "/api/data-queries").as("createQuery");
cy.contains(`[id*="react-select-"]`, dbName).click(); cy.contains(`[id*="react-select-"]`, dbName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(queryName); cy.get('[data-cy="query-rename-input"]').clear().type(queryName);
@ -177,13 +185,13 @@ export const selectDatasource = (datasourceName) => {
export const createDataQuery = (appName, url, key, value) => { export const createDataQuery = (appName, url, key, value) => {
let appId, versionId; let appId, versionId;
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `select id from apps where name='${appName}';`, sql: `select id from apps where name='${appName}';`,
}).then((resp) => { }).then((resp) => {
appId = resp.rows[0].id; appId = resp.rows[0].id;
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `select id from app_versions where app_id='${appId}';`, sql: `select id from app_versions where app_id='${appId}';`,
}).then((resp) => { }).then((resp) => {
@ -197,7 +205,7 @@ export const createDataQuery = (appName, url, key, value) => {
cy.request({ cy.request({
method: "POST", method: "POST",
url: `${Cypress.env("server_host")}/api/data_queries`, url: `${Cypress.env("server_host")}/api/data-queries`,
headers: headers, headers: headers,
body: { body: {
app_id: appId, app_id: appId,
@ -225,7 +233,14 @@ export const createDataQuery = (appName, url, key, value) => {
}); });
}; };
export const createRestAPIQuery = (queryName, dsName, key = '', value = '', url = "", run = true) => { export const createRestAPIQuery = (
queryName,
dsName,
key = "",
value = "",
url = "",
run = true
) => {
cy.getCookie("tj_auth_token").then((cookie) => { cy.getCookie("tj_auth_token").then((cookie) => {
const headers = { const headers = {
"Tj-Workspace-Id": Cypress.env("workspaceId"), "Tj-Workspace-Id": Cypress.env("workspaceId"),
@ -235,7 +250,7 @@ export const createRestAPIQuery = (queryName, dsName, key = '', value = '', url
cy.log(Cypress.env("appId")); cy.log(Cypress.env("appId"));
cy.request({ cy.request({
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/v2/apps/${Cypress.env("appId")}`, url: `${Cypress.env("server_host")}/api/apps/${Cypress.env("appId")}`,
headers: headers, headers: headers,
}).then((response) => { }).then((response) => {
const editingVersionId = response.body.editing_version.id; const editingVersionId = response.body.editing_version.id;
@ -265,7 +280,7 @@ export const createRestAPIQuery = (queryName, dsName, key = '', value = '', url
cy.request({ cy.request({
method: "POST", method: "POST",
url: `${Cypress.env("server_host")}/api/data_queries`, url: `${Cypress.env("server_host")}/api/data-queries/data-sources/${data_source_id}/versions/${editingVersionId}`,
headers: headers, headers: headers,
body: requestBody, body: requestBody,
}).then((response) => { }).then((response) => {

View file

@ -5,7 +5,7 @@ import { navigateToManageGroups } from "Support/utils/common";
import { cyParamName } from "Selectors/common"; import { cyParamName } from "Selectors/common";
import { fake } from "Fixtures/fake"; import { fake } from "Fixtures/fake";
import { onboardingSelectors } from "Selectors/onboarding"; import { onboardingSelectors } from "Selectors/onboarding";
import { fetchAndVisitInviteLink } from "Support/utils/onboarding"; import { fetchAndVisitInviteLink } from "Support/utils/manageUsers";
import { usersSelector } from "Selectors/manageUsers"; import { usersSelector } from "Selectors/manageUsers";
import { fillUserInviteForm } from "Support/utils/manageUsers"; import { fillUserInviteForm } from "Support/utils/manageUsers";
import { navigateToManageUsers, logout } from "Support/utils/common"; import { navigateToManageUsers, logout } from "Support/utils/common";
@ -335,7 +335,7 @@ export const manageGroupsElements = () => {
); );
cy.verifyElement(groupsSelector.confimButton, groupsText.updateButtonText); cy.verifyElement(groupsSelector.confimButton, groupsText.updateButtonText);
cy.get(groupsSelector.confimButton).should("be.enabled"); cy.get(groupsSelector.confimButton).should("be.disabled");
cy.verifyElement(groupsSelector.cancelButton, groupsText.cancelButton); cy.verifyElement(groupsSelector.cancelButton, groupsText.cancelButton);
cy.get(groupsSelector.cancelButton).click(); cy.get(groupsSelector.cancelButton).click();
@ -542,7 +542,7 @@ export const manageGroupsElements = () => {
); );
cy.verifyElement(groupsSelector.confimButton, groupsText.updateButtonText); cy.verifyElement(groupsSelector.confimButton, groupsText.updateButtonText);
cy.get(groupsSelector.confimButton).should("be.enabled"); cy.get(groupsSelector.confimButton).should("be.disabled");
cy.verifyElement(groupsSelector.cancelButton, groupsText.cancelButton); cy.verifyElement(groupsSelector.cancelButton, groupsText.cancelButton);
cy.get(groupsSelector.cancelButton).click(); cy.get(groupsSelector.cancelButton).click();
//Add Modal //Add Modal
@ -680,7 +680,7 @@ export const createGroupAddAppAndUserToGroup = (groupName, email) => {
expect(response.status).to.equal(201); expect(response.status).to.equal(201);
}); });
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `select id from users where email='${email}';`, sql: `select id from users where email='${email}';`,
}).then((resp) => { }).then((resp) => {
@ -864,7 +864,7 @@ export const createGroupsAndAddUserInGroup = (groupName, email) => {
export const inviteUserBasedOnRole = (firstName, email, role = "end-user") => { export const inviteUserBasedOnRole = (firstName, email, role = "end-user") => {
fillUserInviteForm(firstName, email); fillUserInviteForm(firstName, email);
cy.get(".css-1dyz3mf").type(`${role}{enter}`); cy.get(".css-1mlj61j").type(`${role}{enter}`);
cy.get(usersSelector.buttonInviteUsers).click(); cy.get(usersSelector.buttonInviteUsers).click();
cy.wait(500); cy.wait(500);

View file

@ -317,12 +317,12 @@ export const invitePageElements = () => {
.and("equal", "https://www.tooljet.com/privacy"); .and("equal", "https://www.tooljet.com/privacy");
}; };
export const updateId = () => { export const dbConnection = () => {
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.config("db"), dbconfig: Cypress.config("db"),
sql: "update sso_configs set id='5edf41b2-ff2b-4932-9e2a-08aef4a303cc' where sso='google';", sql: "update sso_configs set id='5edf41b2-ff2b-4932-9e2a-08aef4a303cc' where sso='google';",
}); });
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.config("db"), dbconfig: Cypress.config("db"),
sql: "update sso_configs set id='9628dee2-6fa9-4aca-9c98-ef950601c83e' where sso='git';", sql: "update sso_configs set id='9628dee2-6fa9-4aca-9c98-ef950601c83e' where sso='git';",
}); });
@ -331,18 +331,18 @@ export const updateId = () => {
export const setSSOStatus = (workspaceName, ssoType, enabled) => { export const setSSOStatus = (workspaceName, ssoType, enabled) => {
let workspaceId; let workspaceId;
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `SELECT id FROM organizations WHERE name = '${workspaceName}'`, sql: `SELECT id FROM organizations WHERE name = '${workspaceName}'`,
}).then((resp) => { }).then((resp) => {
workspaceId = resp.rows[0].id; workspaceId = resp.rows[0].id;
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `SELECT * FROM sso_configs WHERE organization_id = '${workspaceId}' AND sso = '${ssoType}'`, sql: `SELECT * FROM sso_configs WHERE organization_id = '${workspaceId}' AND sso = '${ssoType}'`,
}).then((ssoConfigResp) => { }).then((ssoConfigResp) => {
if (ssoConfigResp.rows.length > 0) { if (ssoConfigResp.rows.length > 0) {
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `UPDATE sso_configs SET enabled = ${enabled ? "true" : "false" sql: `UPDATE sso_configs SET enabled = ${enabled ? "true" : "false"
} WHERE organization_id = '${workspaceId}' AND sso = '${ssoType}'`, } WHERE organization_id = '${workspaceId}' AND sso = '${ssoType}'`,
@ -372,7 +372,7 @@ export const defaultSSO = (enable) => {
}; };
export const setSignupStatus = (enable, workspaceName = 'My workspace') => { export const setSignupStatus = (enable, workspaceName = 'My workspace') => {
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `SELECT id FROM organizations WHERE name = '${workspaceName}'`, sql: `SELECT id FROM organizations WHERE name = '${workspaceName}'`,
}).then((resp) => { }).then((resp) => {
@ -381,7 +381,7 @@ export const setSignupStatus = (enable, workspaceName = 'My workspace') => {
cy.getCookie("tj_auth_token").then((cookie) => { cy.getCookie("tj_auth_token").then((cookie) => {
cy.request({ cy.request({
method: "PATCH", method: "PATCH",
url: `${Cypress.env("server_host")}/api/organizations`, url: `${Cypress.env("server_host")}/api/login-configs/organization-general`,
headers: { headers: {
"Tj-Workspace-Id": workspaceId, "Tj-Workspace-Id": workspaceId,
Cookie: `tj_auth_token=${cookie.value}`, Cookie: `tj_auth_token=${cookie.value}`,
@ -396,13 +396,13 @@ export const setSignupStatus = (enable, workspaceName = 'My workspace') => {
export const deleteOrganisationSSO = (workspaceName, services) => { export const deleteOrganisationSSO = (workspaceName, services) => {
let workspaceId; let workspaceId;
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `select id from organizations where name='${workspaceName}';`, sql: `select id from organizations where name='${workspaceName}';`,
}).then((resp) => { }).then((resp) => {
workspaceId = resp.rows[0].id; workspaceId = resp.rows[0].id;
cy.task("updateId", { cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"), dbconfig: Cypress.env("app_db"),
sql: `DELETE FROM sso_configs WHERE organization_id = '${workspaceId}' AND sso IN (${services sql: `DELETE FROM sso_configs WHERE organization_id = '${workspaceId}' AND sso IN (${services
.map((service) => `'${service}'`) .map((service) => `'${service}'`)

Some files were not shown because too many files have changed in this diff Show more