Merge remote-tracking branch 'origin/appbuilder/sprint-12' into feat/inspector-revamp

This commit is contained in:
Shaurya Sharma 2025-05-02 14:04:06 +05:30
commit e6ee4e5bd8
421 changed files with 11229 additions and 19794 deletions

View file

@ -2,8 +2,7 @@ name: Cypress App-Builder
on: on:
pull_request_target: pull_request_target:
types: [labeled, unlabeled, closed] types: [labeled]
workflow_dispatch: workflow_dispatch:
env: env:
@ -13,22 +12,18 @@ env:
jobs: jobs:
Cypress-App-Builder: Cypress-App-Builder:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
if: | if: |
github.event.action == 'labeled' && contains(github.event.pull_request.labels.*.name, 'run-ce-app-builder') ||
( contains(github.event.pull_request.labels.*.name, 'run-ee-app-builder') ||
github.event.label.name == 'run-cypress' || contains(github.event.pull_request.labels.*.name, 'run-cypress')
github.event.label.name == 'run-ce-app-builder' ||
github.event.label.name == 'run-ee-app-builder'
)
strategy: strategy:
matrix: matrix:
edition: >- edition: >-
${{ ${{
contains(github.event.pull_request.labels.*.name, 'run-cypress') && fromJson('["ce", "ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ce-app-builder') && fromJson('["ce"]') || contains(github.event.pull_request.labels.*.name, 'run-ce-app-builder') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ee-app-builder') && fromJson('["ee"]') || contains(github.event.pull_request.labels.*.name, 'run-ee-app-builder') && fromJson('["ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress') && fromJson('["ce", "ee"]') ||
fromJson('[]') fromJson('[]')
}} }}
@ -54,20 +49,9 @@ jobs:
git submodule foreach --recursive ' git submodule foreach --recursive '
git checkout ${{ env.BRANCH_NAME }} 2>/dev/null || git checkout main' git checkout ${{ env.BRANCH_NAME }} 2>/dev/null || git checkout main'
- name: Set up Docker - name: Set up Docker
uses: docker-practice/actions-setup-docker@master uses: docker-practice/actions-setup-docker@master
- name: Run PosgtreSQL Database Docker Container
run: |
sudo docker network create tooljet
sudo docker run -d --name postgres --network tooljet -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres -e POSTGRES_PORT=5432 -d postgres:13
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Install and build dependencies - name: Install and build dependencies
run: | run: |
npm cache clean --force npm cache clean --force
@ -76,9 +60,23 @@ jobs:
npm install --prefix frontend npm install --prefix frontend
npm run build:plugins npm run build:plugins
- name: Local development setup
run: |
sudo docker network create tooljet
sudo docker run -d --name postgres -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres -e POSTGRES_PORT=5432 -d postgres:13
- name: Run PostgREST Docker Container
run: |
sudo docker run -d --name postgrest --network tooljet -p 3001:3000 \
-e PGRST_DB_URI="postgres://postgres:postgres@localhost:5432/tooljet" \
-e PGRST_DB_ANON_ROLE="postgres" \
-e PGRST_JWT_SECRET="r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj" \
-e PGRST_DB_PRE_CONFIG=postgrest.pre_config \
postgrest/postgrest:v12.2.0
- 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
@ -88,38 +86,33 @@ jobs:
echo "PG_PASS=postgres" >> .env echo "PG_PASS=postgres" >> .env
echo "PG_PORT=5432" >> .env echo "PG_PORT=5432" >> .env
echo "ENABLE_TOOLJET_DB=true" >> .env echo "ENABLE_TOOLJET_DB=true" >> .env
echo "TOOLJET_DB=tooljet" >> .env echo "TOOLJET_DB=tooljet_db" >> .env
echo "TOOLJET_DB_USER=postgres" >> .env echo "TOOLJET_DB_USER=postgres" >> .env
echo "TOOLJET_DB_HOST=localhost" >> .env echo "TOOLJET_DB_HOST=localhost" >> .env
echo "TOOLJET_DB_PASS=postgres" >> .env echo "TOOLJET_DB_PASS=postgres" >> .env
echo "PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj" >> .env
echo "PGRST_HOST=localhost:3001" >> .env
echo "TOOLJET_DB_STATEMENT_TIMEOUT=60000" >> .env echo "TOOLJET_DB_STATEMENT_TIMEOUT=60000" >> .env
echo "TOOLJET_DB_RECONFIG=true" >> .env echo "TOOLJET_DB_RECONFIG=true" >> .env
echo "PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj" >> .env
echo "PGRST_HOST=localhost:3001" >> .env
echo "PGRST_DB_PRE_CONFIG=postgrest.pre_config" >> .env
echo "PGRST_DB_URI=postgres://postgres:postgres@localhost:5432/tooljet" >> .env
echo "ENABLE_MARKETPLACE_FEATURE=true" >> .env
echo "ENABLE_MARKETPLACE_DEV_MODE=true" >> .env
echo "ENABLE_PRIVATE_APP_EMBED=true" >> .env
- name: Set up database - name: Set up database
run: | run: |
npm run --prefix server db:create npm run --prefix server db:create
npm run --prefix server db:reset npm run --prefix server db:reset
npm run --prefix server db:seed
- name: sleep 5 - name: sleep 5
run: sleep 5 run: sleep 5
- name: Run PostgREST Docker Container - name: Start services
run: | run: |
sudo docker run -d --name postgrest --network tooljet -p 3001:3000 \ cd plugins && npm start &
-e PGRST_DB_URI="postgres://postgres:postgres@postgres:5432/tooljet" -e PGRST_DB_ANON_ROLE="postgres" -e PGRST_JWT_SECRET="r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj" -e PGRST_DB_PRE_CONFIG=postgrest.pre_config \ cd server && npm run start:dev &
postgrest/postgrest:v12.2.0 cd frontend && npm start &
- name: Run plugins compilation in watch mode
run: cd plugins && npm start &
- name: Run the server
run: cd server && npm run start:dev &
- name: Run the client
run: cd frontend && npm start &
- name: Wait for the server to be ready - name: Wait for the server to be ready
run: | run: |
@ -128,6 +121,18 @@ jobs:
sleep 5 sleep 5
done' done'
- name: Seeding (Setup Super Admin)
run: |
curl 'http://localhost:3000/api/onboarding/setup-super-admin' \
-H 'Content-Type: application/json' \
--data-raw '{
"companyName": "ToolJet",
"name": "The Developer",
"workspaceName": "Tooljet'\''s workspace",
"email": "dev@tooljet.io",
"password": "password"
}'
- name: docker logs - name: docker logs
run: sudo docker logs postgrest run: sudo docker logs postgrest
@ -140,7 +145,7 @@ jobs:
dir: "./cypress-tests" dir: "./cypress-tests"
- name: App builder - name: App builder
uses: cypress-io/github-action@v5 uses: cypress-io/github-action@v6
with: with:
working-directory: ./cypress-tests working-directory: ./cypress-tests
config: "baseUrl=http://localhost:8082" config: "baseUrl=http://localhost:8082"
@ -150,13 +155,13 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: screenshots name: screenshots-appbuilder-${{ matrix.edition }}
path: cypress-tests/cypress/screenshots path: cypress-tests/cypress/screenshots
Cypress-App-builder-Subpath: Cypress-App-builder-Subpath:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
if: ${{ github.event.action == 'labeled' && github.event.label.name == 'run-cypress-app-builder-subpath' }} contains(github.event.pull_request.labels.*.name, 'run-cypress-app-builder-subpath')
steps: steps:
- name: Checkout - name: Checkout
@ -164,73 +169,6 @@ jobs:
with: with:
ref: ${{ github.event.pull_request.head.ref }} ref: ${{ github.event.pull_request.head.ref }}
# Create Docker Buildx builder with platform configuration
- name: Set up Docker Buildx
run: |
mkdir -p ~/.docker/cli-plugins
curl -SL https://github.com/docker/buildx/releases/download/v0.11.0/buildx-v0.11.0.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx
chmod a+x ~/.docker/cli-plugins/docker-buildx
docker buildx create --name mybuilder --platform linux/arm64,linux/amd64,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: Build docker image
run: docker buildx build --platform=linux/amd64 -f docker/production.Dockerfile . -t tooljet/tj-osv:cypressplaform
- name: Set up environment variables
run: |
echo "TOOLJET_HOST=http://localhost:3000" >> .env
echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env
echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env
echo "PG_DB=tooljet_development" >> .env
echo "PG_USER=postgres" >> .env
echo "PG_HOST=postgres" >> .env
echo "PG_PASS=postgres" >> .env
echo "PG_PORT=5432" >> .env
echo "ENABLE_TOOLJET_DB=true" >> .env
echo "TOOLJET_DB=tooljet_db" >> .env
echo "TOOLJET_DB_USER=postgres" >> .env
echo "TOOLJET_DB_HOST=postgres" >> .env
echo "TOOLJET_DB_PASS=postgres" >> .env
echo "PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj" >> .env
echo "PGRST_HOST=postgrest" >> .env
echo "PGRST_DB_URI=postgres://postgres:postgres@postgres/tooljet_db" >> .env
echo "SSO_GIT_OAUTH2_CLIENT_ID=dummy" >> .env
echo "SSO_GIT_OAUTH2_CLIENT_SECRET=dummy" >> .env
echo "SSO_GIT_OAUTH2_HOST=dummy" >> .env
echo "SSO_GOOGLE_OAUTH2_CLIENT_ID=dummy" >> .env
echo "SUB_PATH=/apps/tooljet/" >> .env
echo "NODE_ENV=production" >> .env
echo "SERVE_CLIENT=true" >> .env
echo "ENABLE_PRIVATE_APP_EMBED=true" >> .env
- name: Pulling the docker-compose file
run: curl -LO https://tooljet-test.s3.us-west-1.amazonaws.com/docker-compose.yaml && mkdir postgres_data
- name: Run docker-compose file
run: docker-compose up -d
- name: Checking containers
run: docker ps -a
- name: docker logs
run: sudo docker logs Tooljet-app
- name: Wait for the server to be ready
run: |
timeout 1500 bash -c '
until curl --silent --fail http://localhost:80/apps/tooljet/; do
sleep 5
done'
- name: Seeding
run: docker exec Tooljet-app npm run db:seed:prod
- name: Create Cypress environment file - name: Create Cypress environment file
id: create-json id: create-json
uses: jsdaniell/create-json@1.1.2 uses: jsdaniell/create-json@1.1.2

View file

@ -2,7 +2,7 @@ name: Cypress Marketplace
on: on:
pull_request_target: pull_request_target:
types: [labeled, unlabeled, closed] types: [labeled]
workflow_dispatch: workflow_dispatch:
@ -14,13 +14,9 @@ jobs:
Cypress-Marketplace: Cypress-Marketplace:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
if: | if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
github.event.action == 'labeled' && contains(github.event.pull_request.labels.*.name, 'run-ce-cypress-marketplace') ||
( contains(github.event.pull_request.labels.*.name, 'run-ee-cypress-marketplace')
github.event.label.name == 'run-cypress' ||
github.event.label.name == 'run-ce-cypress-marketplace' ||
github.event.label.name == 'run-ee-cypress-marketplace'
)
strategy: strategy:
matrix: matrix:
@ -44,7 +40,7 @@ jobs:
mkdir -p ~/.docker/cli-plugins 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 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 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 create --name mybuilder --platform linux/arm64,linux/amd64
docker buildx use mybuilder docker buildx use mybuilder
- name: Set DOCKER_CLI_EXPERIMENTAL - name: Set DOCKER_CLI_EXPERIMENTAL
@ -67,8 +63,8 @@ jobs:
with: with:
context: . context: .
file: docker/ce-production.Dockerfile file: docker/ce-production.Dockerfile
push: false push: true
tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }} tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}-ce
platforms: linux/amd64 platforms: linux/amd64
env: env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
@ -80,8 +76,8 @@ jobs:
with: with:
context: . context: .
file: docker/ee/ee-production.Dockerfile file: docker/ee/ee-production.Dockerfile
push: false push: true
tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }} tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}-ee
platforms: linux/amd64 platforms: linux/amd64
env: env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
@ -116,10 +112,16 @@ jobs:
- name: Pulling the docker-compose file - name: Pulling the docker-compose file
run: curl -LO https://tooljet-test.s3.us-west-1.amazonaws.com/docker-compose.yaml && mkdir postgres_data run: curl -LO https://tooljet-test.s3.us-west-1.amazonaws.com/docker-compose.yaml && mkdir postgres_data
- name: Update docker-compose file - name: Update docker-compose file for CE
run: | run: |
# Update docker-compose.yaml with the new image # Update docker-compose.yaml with the new image
sed -i '/^[[:space:]]*tooljet:/,/^$/ s|^\([[:space:]]*image:[[:space:]]*\).*|\1tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}|' docker-compose.yaml sed -i '/^[[:space:]]*tooljet:/,/^$/ s|^\([[:space:]]*image:[[:space:]]*\).*|\1tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}-ce|' docker-compose.yaml
- name: Update docker-compose file for CE
if: matrix.edition == 'ee'
run: |
# Update docker-compose.yaml with the new image
sed -i '/^[[:space:]]*tooljet:/,/^$/ s|^\([[:space:]]*image:[[:space:]]*\).*|\1tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}-ee|' docker-compose.yaml
- name: Install Docker Compose - name: Install Docker Compose
run: | run: |
@ -132,6 +134,9 @@ jobs:
- name: Checking containers - name: Checking containers
run: docker ps -a run: docker ps -a
- name: Checking containers
run: docker ps -a
- name: docker logs - name: docker logs
run: sudo docker logs Tooljet-app run: sudo docker logs Tooljet-app
@ -142,8 +147,18 @@ jobs:
sleep 5 sleep 5
done' done'
- name: Seeding - name: Seeding (Setup Super Admin)
run: docker exec Tooljet-app npm run db:seed:prod run: |
curl 'http://localhost:3000/api/onboarding/setup-super-admin' \
-H 'Content-Type: application/json' \
--data-raw '{
"companyName": "ToolJet",
"name": "The Developer",
"workspaceName": "Tooljet'\''s workspace",
"email": "dev@tooljet.io",
"password": "password"
}'
- name: Create Cypress environment file - name: Create Cypress environment file
id: create-json id: create-json
@ -170,7 +185,8 @@ jobs:
Cypress-Marketplace-Subpath: Cypress-Marketplace-Subpath:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
if: ${{ github.event.action == 'labeled' && github.event.label.name == 'run-cypress-marketplace-subpath' }} if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-marketplace-subpath')
steps: steps:
- name: Checkout - name: Checkout

View file

@ -2,7 +2,7 @@ name: Cypress Platform
on: on:
pull_request_target: pull_request_target:
types: [labeled, unlabeled, closed] types: [labeled]
workflow_dispatch: workflow_dispatch:
env: env:
@ -12,14 +12,9 @@ env:
jobs: jobs:
Cypress-Platform: Cypress-Platform:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
if: | if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
github.event.action == 'labeled' && contains(github.event.pull_request.labels.*.name, 'run-ce-cypress-platform') ||
( contains(github.event.pull_request.labels.*.name, 'run-ee-cypress-platform')
github.event.label.name == 'run-cypress' ||
github.event.label.name == 'run-ce-cypress-platform' ||
github.event.label.name == 'run-ee-cypress-platform'
)
strategy: strategy:
matrix: matrix:
edition: >- edition: >-
@ -102,6 +97,10 @@ jobs:
echo "ENABLE_MARKETPLACE_FEATURE=true" >> .env echo "ENABLE_MARKETPLACE_FEATURE=true" >> .env
echo "ENABLE_MARKETPLACE_DEV_MODE=true" >> .env echo "ENABLE_MARKETPLACE_DEV_MODE=true" >> .env
echo "ENABLE_PRIVATE_APP_EMBED=true" >> .env echo "ENABLE_PRIVATE_APP_EMBED=true" >> .env
echo "SSO_GOOGLE_OAUTH2_CLIENT_ID=123456789.apps.googleusercontent.com" >> .env
echo "SSO_GOOGLE_OAUTH2_CLIENT_SECRET=ABCGFDNF-FHSDVFY-bskfh6234" >> .env
echo "SSO_GIT_OAUTH2_CLIENT_ID=1234567890" >> .env
echo "SSO_GIT_OAUTH2_CLIENT_SECRET=3346shfvkdjjsfkvxce32854e026a4531ed" >> .env
- name: Set up database - name: Set up database
run: | run: |
@ -147,13 +146,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 +174,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 +210,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 +279,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 +310,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 +346,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 +427,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 +458,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 +494,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 +576,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

@ -137,7 +137,8 @@ jobs:
uses: docker/build-push-action@v4 uses: docker/build-push-action@v4
with: with:
context: . context: .
args: ${{ secrets.CUSTOM_GITHUB_TOKEN }} build-args: |
CUSTOM_GITHUB_TOKEN=${{ secrets.CUSTOM_GITHUB_TOKEN }}
file: docker/ee/ee-production.Dockerfile 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 }}
@ -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
@ -230,3 +232,95 @@ jobs:
# fi # fi
# 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 }}
try-tooljet-image-build:
runs-on: ubuntu-latest
needs: build-tooljet-image-for-ee-edtion
if: ${{ needs.build-tooljet-image-for-ee-edtion.result == 'success' }}
steps:
- name: Checkout code to develop
if: "!contains(github.event.release.tag_name, 'ee-lts')"
uses: actions/checkout@v2
with:
ref: refs/heads/main
- name: Checkout code to lts-3.0
if: contains(github.event.release.tag_name, '-ee-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@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Check if Docker image is present
id: check-image-presence
run: |
response=$(curl -s "https://hub.docker.com/v2/repositories/tooljet/tooljet/tags/${{ github.event.release.tag_name }}")
if [[ $? -ne 0 ]]; then
echo "Failed to fetch JSON response. Stopping workflow execution."
exit 1
fi
if [[ $response == *"tag '${{ github.event.release.tag_name }}' not found"* ]]; then
echo "Docker image tag '${{ github.event.release.tag_name }}' not present."
exit 1
else
echo "Docker image tag '${{ github.event.release.tag_name }}' is present."
fi
- name: Build and Push Docker image for non-EE-LTS
if: "!contains(github.event.release.tag_name, '-ee-lts')"
uses: docker/build-push-action@v4
with:
context: .
file: docker/ee/ee-try-tooljet.Dockerfile
push: true
tags: tooljet/try:${{ github.event.release.tag_name }},tooljet/try:ee-latest
platforms: linux/amd64
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker image for EE-LTS-3.0
if: contains(github.event.release.tag_name, '-ee-lts')
uses: docker/build-push-action@v4
with:
context: .
file: docker/ee/ee-try-tooljet-lts.Dockerfile
push: true
tags: tooljet/try:${{ github.event.release.tag_name }},tooljet/try:ee-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="Try-ToolJet image published:\\n\`tooljet/try:${{ github.event.release.tag_name }}\`"
else
message="Job '${{ env.JOB_NAME }}' failed! tooljet/try:${{ github.event.release.tag_name }}"
fi
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL }}

View file

@ -12,7 +12,7 @@ permissions:
jobs: jobs:
# Community Edition # Community Edition CE
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
@ -72,7 +72,7 @@ jobs:
"envVars": [ "envVars": [
{ {
"key": "PG_HOST", "key": "PG_HOST",
"value": "${{ secrets.RENDER_PG_HOST }}" "value": "localhost"
}, },
{ {
"key": "PG_PORT", "key": "PG_PORT",
@ -80,11 +80,11 @@ jobs:
}, },
{ {
"key": "PG_USER", "key": "PG_USER",
"value": "${{ secrets.RENDER_PG_USER }}" "value": "tooljet"
}, },
{ {
"key": "PG_PASS", "key": "PG_PASS",
"value": "${{ secrets.RENDER_PG_PASS }}" "value": "postgres"
}, },
{ {
"key": "PG_DB", "key": "PG_DB",
@ -96,15 +96,15 @@ jobs:
}, },
{ {
"key": "TOOLJET_DB_HOST", "key": "TOOLJET_DB_HOST",
"value": "${{ secrets.RENDER_PG_HOST }}" "value": "localhost"
}, },
{ {
"key": "TOOLJET_DB_USER", "key": "TOOLJET_DB_USER",
"value": "${{ secrets.RENDER_PG_USER }}" "value": "tooljet"
}, },
{ {
"key": "TOOLJET_DB_PASS", "key": "TOOLJET_DB_PASS",
"value": "${{ secrets.RENDER_PG_PASS }}" "value": "postgres"
}, },
{ {
"key": "TOOLJET_DB_PORT", "key": "TOOLJET_DB_PORT",
@ -116,7 +116,7 @@ jobs:
}, },
{ {
"key": "PGRST_DB_URI", "key": "PGRST_DB_URI",
"value": "postgres://${{ secrets.RENDER_PG_USER }}:${{ secrets.RENDER_PG_PASS }}@${{ secrets.RENDER_PG_HOST }}/${{ env.PR_NUMBER }}-ce-tjdb" "value": "postgres://tooljet:postgres@localhost/${{ env.PR_NUMBER }}-ce-tjdb"
}, },
{ {
"key": "PGRST_HOST", "key": "PGRST_HOST",
@ -162,18 +162,6 @@ jobs:
"key": "SMTP_PASSWORD", "key": "SMTP_PASSWORD",
"value": "${{ secrets.RENDER_SMTP_PASSWORD }}" "value": "${{ secrets.RENDER_SMTP_PASSWORD }}"
}, },
{
"key": "TEMPORAL_SERVER_ADDRESS",
"value": "https://auto-setup-1-25-1.onrender.com"
},
{
"key": "TEMPORAL_TASK_QUEUE_NAME_FOR_WORKFLOWS",
"value": "tooljet-ce-pr-${{ env.PR_NUMBER }}"
},
{
"key": "TOOLJET_WORKFLOWS_TEMPORAL_NAMESPACE",
"value": "default"
},
{ {
"key": "TOOLJET_MARKETPLACE_URL", "key": "TOOLJET_MARKETPLACE_URL",
"value": "${{ secrets.MARKETPLACE_BUCKET }}" "value": "${{ secrets.MARKETPLACE_BUCKET }}"
@ -424,7 +412,7 @@ jobs:
"envVars": [ "envVars": [
{ {
"key": "PG_HOST", "key": "PG_HOST",
"value": "${{ secrets.RENDER_PG_HOST }}" "value": "localhost"
}, },
{ {
"key": "PG_PORT", "key": "PG_PORT",
@ -432,11 +420,11 @@ jobs:
}, },
{ {
"key": "PG_USER", "key": "PG_USER",
"value": "${{ secrets.RENDER_PG_USER }}" "value": "tooljet"
}, },
{ {
"key": "PG_PASS", "key": "PG_PASS",
"value": "${{ secrets.RENDER_PG_PASS }}" "value": "postgres"
}, },
{ {
"key": "PG_DB", "key": "PG_DB",
@ -448,15 +436,15 @@ jobs:
}, },
{ {
"key": "TOOLJET_DB_HOST", "key": "TOOLJET_DB_HOST",
"value": "${{ secrets.RENDER_PG_HOST }}" "value": "localhost"
}, },
{ {
"key": "TOOLJET_DB_USER", "key": "TOOLJET_DB_USER",
"value": "${{ secrets.RENDER_PG_USER }}" "value": "tooljet"
}, },
{ {
"key": "TOOLJET_DB_PASS", "key": "TOOLJET_DB_PASS",
"value": "${{ secrets.RENDER_PG_PASS }}" "value": "postgres"
}, },
{ {
"key": "TOOLJET_DB_PORT", "key": "TOOLJET_DB_PORT",
@ -468,7 +456,7 @@ jobs:
}, },
{ {
"key": "PGRST_DB_URI", "key": "PGRST_DB_URI",
"value": "postgres://${{ secrets.RENDER_PG_USER }}:${{ secrets.RENDER_PG_PASS }}@${{ secrets.RENDER_PG_HOST }}/${{ env.PR_NUMBER }}-ee-tjdb" "value": "postgres://tooljet:postgres@localhost/${{ env.PR_NUMBER }}-ee-tjdb"
}, },
{ {
"key": "PGRST_HOST", "key": "PGRST_HOST",
@ -1124,4 +1112,3 @@ jobs:
# } catch (e) { # } catch (e) {
# console.log(e) # console.log(e)
# } # }

View file

@ -8,7 +8,7 @@ permissions:
issues: write issues: write
jobs: jobs:
label-stale-deploys: label-stale-ce-deploys:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
pull-requests: write pull-requests: write
@ -17,7 +17,7 @@ jobs:
id: stale-label id: stale-label
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
stale-label: 'active-review-app' stale-label: 'active-ce-review-app'
stale-time: '86400' stale-time: '86400'
type: 'pull_request' type: 'pull_request'
- name: Get stale numbers - name: Get stale numbers
@ -40,6 +40,42 @@ jobs:
issue_number: prNumber, issue_number: prNumber,
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
labels: ['suspend-review-app'] labels: ['suspend-ce-review-app']
})
}
label-stale-ee-deploys:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: akshaysasidrn/stale-label-fetch@v1.1
id: stale-label
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
stale-label: 'active-ee-review-app'
stale-time: '86400'
type: 'pull_request'
- name: Get stale numbers
run: echo "Matched PR numbers - ${{ steps.stale-label.outputs.stale-numbers }}"
- name: Add suspend label
uses: actions/github-script@v6
env:
STALE_NUMBERS: ${{ steps.stale-label.outputs.stale-numbers }}
with:
github-token: ${{ secrets.TJ_BOT_PAT }}
script: |
if (!process.env.STALE_NUMBERS) return
const prNumbers = process.env.STALE_NUMBERS.split(",")
console.log(`Adding suspend labels for: ${prNumbers}`)
for (const prNumber of prNumbers) {
github.rest.issues.addLabels({
issue_number: prNumber,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['suspend-ee-review-app']
}) })
} }

View file

@ -11,7 +11,7 @@ on:
# Schedule the workflow to run every two weeks once # Schedule the workflow to run every two weeks once
schedule: schedule:
- cron: '30 5 */14 * *' - cron: '30 5 * * 1'
jobs: jobs:
PeriodicVulnerability-CheckOn-frontend-code: PeriodicVulnerability-CheckOn-frontend-code:

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", {
dbConnection ({ 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);
}, },
@ -76,8 +76,8 @@ module.exports = defineConfig({
experimentalRunAllSpecs: true, experimentalRunAllSpecs: true,
baseUrl: "http://localhost:8082", baseUrl: "http://localhost:8082",
specPattern: [ specPattern: [
"cypress/e2e/happyPath/appbuilder/commonTestcases/**/*.cy.js", "cypress/e2e/happyPath/appbuilder/commonTestcases/newSuits/**/*.cy.js",
"cypress/e2e/happyPath/appbuilder/ceTestcases/**/*.cy.js" // "cypress/e2e/happyPath/appbuilder/ceTestcases/**/*.cy.js"
], ],
numTestsKeptInMemory: 1, numTestsKeptInMemory: 1,
redirectionLimit: 7, redirectionLimit: 7,

View file

@ -39,11 +39,11 @@ module.exports = defineConfig({
chromeWebSecurity: false, chromeWebSecurity: false,
trashAssetsBeforeRuns: true, trashAssetsBeforeRuns: true,
e2e: { e2e: {
setupNodeEvents (on, config) { setupNodeEvents(on, config) {
config.baseUrl = environment.baseUrl; config.baseUrl = environment.baseUrl;
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);
@ -55,7 +55,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);
@ -69,7 +69,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) {
@ -83,7 +83,7 @@ module.exports = defineConfig({
}); });
on("task", { on("task", {
dbConnection ({ 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);
}, },
@ -98,6 +98,7 @@ module.exports = defineConfig({
configFile: environment.configFile, configFile: environment.configFile,
specPattern: [ specPattern: [
"cypress/e2e/happyPath/platform/ceTestcases/userFlow/firstUserOnboarding.cy.js", "cypress/e2e/happyPath/platform/ceTestcases/userFlow/firstUserOnboarding.cy.js",
"cypress/e2e/happyPath/platform/commonTestcases/workspace/dashboard.cy.js",
"cypress/e2e/happyPath/platform/ceTestcases/!(userFlow)/**/*.cy.js", "cypress/e2e/happyPath/platform/ceTestcases/!(userFlow)/**/*.cy.js",
"cypress/e2e/happyPath/platform/commonTestcases/**/*.cy.js", "cypress/e2e/happyPath/platform/commonTestcases/**/*.cy.js",
], ],

View file

@ -92,11 +92,7 @@ module.exports = defineConfig({
experimentalModfyObstructiveThirdPartyCode: true, experimentalModfyObstructiveThirdPartyCode: true,
experimentalRunAllSpecs: true, experimentalRunAllSpecs: true,
baseUrl: "http://localhost:8082", baseUrl: "http://localhost:8082",
specPattern: [ specPattern: "cypress/e2e/happyPath/**/*.cy.js",
"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

@ -52,7 +52,7 @@ Cypress.Commands.add("apiCreateGDS", (url, name, kind, options) => {
log: false; log: false;
} }
expect(response.status).to.equal(201); expect(response.status).to.equal(201);
Cypress.env(`${name}-id`, response.body.id); Cypress.env(`${kind}`, response.body.id);
Cypress.log({ Cypress.log({
name: "Create Data Source", name: "Create Data Source",
@ -63,6 +63,30 @@ Cypress.Commands.add("apiCreateGDS", (url, name, kind, options) => {
}); });
}); });
Cypress.Commands.add("apiFetchDataSourcesId", () => {
cy.getAuthHeaders().then((headers) => {
cy.request({
method: "GET",
url: `${Cypress.env("server_host")}/api/data-sources/${Cypress.env("workspaceId")}/environments/${Cypress.env("environmentId")}/versions/${Cypress.env("editingVersionId")}`,
headers,
}).then((response) => {
expect(response.status).to.equal(200);
const dataSources = response.body?.data_sources || [];
dataSources.forEach((item) => {
Cypress.env(`${item.kind}`, `${item.id}`);
});
Cypress.log({
name: "DS Fetch",
displayName: "Data Sources Fetched",
message: dataSources.map(ds => `\nKind: '${ds.kind}', Name: '${ds.id}'`).join(','),
});
});
});
});
Cypress.Commands.add("apiCreateApp", (appName = "testApp") => { Cypress.Commands.add("apiCreateApp", (appName = "testApp") => {
cy.window({ log: false }).then((win) => { cy.window({ log: false }).then((win) => {
win.localStorage.setItem("walkthroughCompleted", "true"); win.localStorage.setItem("walkthroughCompleted", "true");
@ -140,14 +164,11 @@ Cypress.Commands.add(
cy.visit(`/${workspaceId}/apps/${appId}/${slug}`); cy.visit(`/${workspaceId}/apps/${appId}/${slug}`);
cy.wait("@getAppData").then((interception) => { cy.wait("@getAppData").then((interception) => {
// Assuming the response body is a JSON object
const responseData = interception.response.body; const responseData = interception.response.body;
// Set the response data as an environment variable Cypress.env("editingVersionId", responseData.editing_version.id);
Cypress.env("apiResponseData", responseData); Cypress.env("environmentId", responseData.editorEnvironment.id);
// You can log it to check if the env var is set correctly
cy.log(Cypress.env("apiResponseData"));
}); });
cy.get(componentSelector, { timeout: 10000 }); cy.get(componentSelector, { timeout: 10000 });
} }
@ -171,6 +192,7 @@ Cypress.Commands.add("apiCreateWorkspace", (workspaceName, workspaceSlug) => {
{ log: false } { log: false }
).then((response) => { ).then((response) => {
expect(response.status).to.equal(201); expect(response.status).to.equal(201);
return response;
}); });
}); });
}); });
@ -267,6 +289,7 @@ Cypress.Commands.add("apiAddQuery", (queryName, query, dataQueryId) => {
Cypress.Commands.add( Cypress.Commands.add(
"apiAddQueryToApp", "apiAddQueryToApp",
(queryName, options, dsName, dsKind) => { (queryName, options, dsName, dsKind) => {
cy.log(`${Cypress.env("server_host")}/api/data-queries/data-sources/${Cypress.env(dsKind)}/versions/${Cypress.env("editingVersionId")}`)
cy.getCookie("tj_auth_token", { log: false }).then((cookie) => { cy.getCookie("tj_auth_token", { log: false }).then((cookie) => {
const authToken = `tj_auth_token=${cookie.value}`; const authToken = `tj_auth_token=${cookie.value}`;
const workspaceId = Cypress.env("workspaceId"); const workspaceId = Cypress.env("workspaceId");
@ -286,7 +309,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/data-sources/${Cypress.env(dsKind)}/versions/${Cypress.env("editingVersionId")}`,
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
Cookie: authToken, Cookie: authToken,
@ -627,10 +650,11 @@ Cypress.Commands.add("apiAddDataToTable", (tableName, data) => {
}); });
Cypress.Commands.add("apiGetDataSourceIdByName", (dataSourceName) => { Cypress.Commands.add("apiGetDataSourceIdByName", (dataSourceName) => {
const workspaceId = Cypress.env("workspaceId");
cy.getAuthHeaders().then((headers) => { cy.getAuthHeaders().then((headers) => {
cy.request({ cy.request({
method: "GET", method: "GET",
url: `${Cypress.env("server_host")}/api/data-sources`, url: `${Cypress.env("server_host")}/api/data-sources/${workspaceId}`,
headers: headers, headers: headers,
}).then((response) => { }).then((response) => {
expect(response.status).to.equal(200); expect(response.status).to.equal(200);
@ -665,7 +689,7 @@ Cypress.Commands.add(
name: dataSourceName, name: dataSourceName,
options: [ options: [
{ key: "connection_type", value: "manual", encrypted: false }, { key: "connection_type", value: "manual", encrypted: false },
{ key: "host", value: "35.202.183.199" }, { key: "host", value: "35.238.9.114" },
{ key: "port", value: 5432 }, { key: "port", value: 5432 },
{ key: "database", value: "student" }, { key: "database", value: "student" },
{ key: "username", value: "postgres" }, { key: "username", value: "postgres" },

View file

@ -15,15 +15,11 @@ const API_ENDPOINT =
Cypress.Commands.add( Cypress.Commands.add(
"appUILogin", "appUILogin",
(email = "dev@tooljet.io", password = "password") => { (email = "dev@tooljet.io", password = "password") => {
cy.visit("/");
cy.wait(1000);
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(2000);
cy.intercept("GET", API_ENDPOINT).as("library_apps"); cy.get('[data-cy="main-wrapper"]', { timeout: 10000 }).should("be.visible");
cy.get(commonSelectors.homePageLogo, { timeout: 10000 });
cy.wait("@library_apps");
} }
); );
@ -400,36 +396,39 @@ Cypress.Commands.add("getPosition", (componentName) => {
Cypress.Commands.add("defaultWorkspaceLogin", () => { Cypress.Commands.add("defaultWorkspaceLogin", () => {
cy.apiLogin(); cy.apiLogin();
// cy.intercept("GET", API_ENDPOINT).as("library_apps");
cy.visit("/my-workspace"); cy.visit("/my-workspace");
cy.intercept("GET", API_ENDPOINT).as("library_apps"); cy.wait(2000)
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(
"visitSlug", "visitSlug",
({ ({
actualUrl, actualUrl,
currentUrl = `${Cypress.config("baseUrl")}/error/unknown`, errorUrls = [
`${Cypress.config("baseUrl")}/error/unknown`,
`${Cypress.config("baseUrl")}/error/restricted`,
],
}) => { }) => {
// Ensure actualUrl is provided
if (!actualUrl) { if (!actualUrl) {
throw new Error("actualUrl is required for visitSlug command."); throw new Error("actualUrl is required for visitSlug command.");
} }
cy.visit(actualUrl); cy.visit(actualUrl);
// Dynamically wait for the correct URL or handle navigation errors
cy.url().then((url) => { cy.url().then((url) => {
if (url === currentUrl) { if (errorUrls.includes(url)) {
cy.log(`Navigation resulted in unexpected URL: ${url}. Retrying...`); cy.log(`Navigation resulted in error URL: ${url}. Retrying...`);
cy.visit(actualUrl); cy.visit(actualUrl);
cy.wait(1000);
} }
}); });
} }
); );
Cypress.Commands.add("releaseApp", () => { Cypress.Commands.add("releaseApp", () => {
if (Cypress.env("environment") !== "Community") { if (Cypress.env("environment") !== "Community") {
cy.get(commonEeSelectors.promoteButton).click(); cy.get(commonEeSelectors.promoteButton).click();
@ -520,16 +519,6 @@ Cypress.Commands.add("verifyElement", (selector, text, eqValue) => {
element.should("be.visible").and("have.text", text); element.should("be.visible").and("have.text", text);
}); });
Cypress.Commands.add("loginWithCredentials", (email, password) => {
cy.get(onboardingSelectors.loginEmailInput, { timeout: 20000 }).should(
"be.visible"
);
cy.clearAndType(onboardingSelectors.loginEmailInput, email);
cy.clearAndType(onboardingSelectors.loginPasswordInput, password);
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("dbConnection", { cy.task("dbConnection", {

View file

@ -259,7 +259,7 @@ export const commonSelectors = {
cloneAppTitle: '[data-cy="clone-app-title"]', cloneAppTitle: '[data-cy="clone-app-title"]',
cloneAppButton: '[data-cy="clone-app"]', cloneAppButton: '[data-cy="clone-app"]',
appNameErrorLabel: '[data-cy="app-name-error-label"]', appNameErrorLabel: '[data-cy="app-name-error-label"]',
importAppTitle: '[data-cy="import-app-title"]', importAppTitle: '[data-cy="import-an-app"]',
importAppButton: '[data-cy="import-app"]', importAppButton: '[data-cy="import-app"]',
chooseFromTemplateButton: '[data-cy="choose-from-template-button"]', chooseFromTemplateButton: '[data-cy="choose-from-template-button"]',
CreateAppFromTemplateButton: '[data-cy="create-new-app-from-template-title"]', CreateAppFromTemplateButton: '[data-cy="create-new-app-from-template-title"]',

View file

@ -1,7 +1,7 @@
export const multipageSelector = { export const multipageSelector = {
sidebarPageButton: '[data-cy="left-sidebar-page-button"]', sidebarPageButton: '[data-cy="left-sidebar-page-button"]',
pagesLabel: '[data-cy="label-pages"]', pagesLabel: '[data-cy="label-pages"]',
addPageIcon: '[title="Add Page"]', addPageIcon: '[data-cy="add-page-button"]',
searchPageIcon: '[title="Search"]', searchPageIcon: '[title="Search"]',
pagesPinIcon: '[title="Pin"]', pagesPinIcon: '[title="Pin"]',

View file

@ -13,7 +13,7 @@ export const dataSourceText = {
? "Databases (20)" ? "Databases (20)"
: "Databases (18)"; : "Databases (18)";
}, },
allApis: "APIs (20)", allApis: "APIs (21)",
allCloudStorage: "Cloud Storages (4)", allCloudStorage: "Cloud Storages (4)",
pluginsLabelAndCount: "Plugins (0)", pluginsLabelAndCount: "Plugins (0)",

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 (45)";
}, },
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

@ -4,7 +4,7 @@ export const workspaceConstantsText = {
secretsConstantInfo: "To resolve a secret workspace constant use {{secrets.access_token}}Read documentation", secretsConstantInfo: "To resolve a secret workspace constant use {{secrets.access_token}}Read documentation",
emptyStateHeader: "No Workspace constants yet", emptyStateHeader: "No Workspace constants yet",
emptyStateText: emptyStateText:
"Use workspace constants seamlessly in both the app builder and data source connections across ToolJet.", "Use workspace constants seamlessly within both the app builder and data source connections across the platform.",
addNewConstantButton: "+ Create new constant", addNewConstantButton: "+ Create new constant",
addConstatntText: "Add new constant in production ", addConstatntText: "Add new constant in production ",
constantCreatedToast: (type) => { return `${type} constant created successfully!` }, constantCreatedToast: (type) => { return `${type} constant created successfully!` },

View file

@ -351,7 +351,7 @@ describe("Text Input", () => {
).should("have.css", "border-radius", "20px"); ).should("have.css", "border-radius", "20px");
}); });
it.skip("should verify the app preview", () => {}); it.skip("should verify the app preview", () => { });
it("should verify CSA", () => { it("should verify CSA", () => {
const data = {}; const data = {};

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", "/tooljets-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

@ -76,7 +76,7 @@ describe('Button Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Button-App`); cy.apiCreateApp(`${fake.companyName}-Button-App`);
cy.openApp(); cy.openApp();
cy.dragAndDropWidget("Button", 50, 50); cy.dragAndDropWidget("Button", 50, 50);
cy.get('[data-cy="query-manager-collapse-button"]').click(); cy.get('[data-cy="query-manager-toggle-button"]').click();
}); });
it('should verify all the exposed values on inspector', () => { it('should verify all the exposed values on inspector', () => {
@ -90,7 +90,7 @@ describe('Button Component Tests', () => {
}); });
it('should verify all the events from the button', () => { it.skip('should verify all the events from the button', () => {
const events = [ const events = [
{ event: "On hover", message: "On hover Event" }, { event: "On hover", message: "On hover Event" },
{ event: "On Click", message: "On Click Event" }, { event: "On Click", message: "On Click Event" },
@ -110,7 +110,7 @@ describe('Button Component Tests', () => {
verifyTextInputEvents(textInputSelector); verifyTextInputEvents(textInputSelector);
}); });
it('should verify all the CSA from button', () => { it.skip('should verify all the CSA from button', () => {
addMultiEventsWithAlert([ addMultiEventsWithAlert([
{ event: "On hover", message: "On hover Event" }, { event: "On hover", message: "On hover Event" },
{ event: "On Click", message: "On Click Event" }, { event: "On Click", message: "On Click Event" },

View file

@ -84,7 +84,7 @@ describe('Checkbox Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Checkbox-App`); cy.apiCreateApp(`${fake.companyName}-Checkbox-App`);
cy.openApp(); cy.openApp();
cy.dragAndDropWidget("Checkbox", 50, 50); cy.dragAndDropWidget("Checkbox", 50, 50);
cy.get('[data-cy="query-manager-collapse-button"]').click(); cy.get('[data-cy="query-manager-toggle-button"]').click();
}); });
it('should verify all the exposed values on inspector', () => { it('should verify all the exposed values on inspector', () => {
@ -98,7 +98,7 @@ describe('Checkbox Component Tests', () => {
}); });
it('should verify all the events from the Checkbox', () => { it.skip('should verify all the events from the Checkbox', () => {
const events = [ const events = [
{ event: "On Change", message: "On Change Event" }, { event: "On Change", message: "On Change Event" },
]; ];
@ -118,7 +118,7 @@ describe('Checkbox Component Tests', () => {
verifyTextInputEvents(textInputSelector); verifyTextInputEvents(textInputSelector);
}); });
it('should verify all the CSA from Checkbox', () => { it.skip('should verify all the CSA from Checkbox', () => {
const events = [ const events = [
{ event: "On Change", message: "On Change Event" }, { event: "On Change", message: "On Change Event" },
]; ];

View file

@ -93,7 +93,7 @@ describe('Dropdown Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Dropdown-App`); cy.apiCreateApp(`${fake.companyName}-Dropdown-App`);
cy.openApp(); cy.openApp();
cy.dragAndDropWidget("Dropdown", 50, 50); cy.dragAndDropWidget("Dropdown", 50, 50);
cy.get('[data-cy="query-manager-collapse-button"]').click(); cy.get('[data-cy="query-manager-toggle-button"]').click();
}); });
it('should verify all the exposed values on inspector', () => { it('should verify all the exposed values on inspector', () => {

View file

@ -91,7 +91,7 @@ describe("Global Actions", () => {
cy.waitForAutoSave(); cy.waitForAutoSave();
addInputOnQueryField("runjs", "actions.showModal('modal1');"); addInputOnQueryField("runjs", "actions.showModal('modal1');");
query("run"); query("run");
cy.get('[data-cy="modal-title"]').should("be.visible"); cy.get('.text-widget-section > div').should("be.visible");
addInputOnQueryField("runjs", "actions.closeModal('modal1');"); addInputOnQueryField("runjs", "actions.closeModal('modal1');");
query("run"); query("run");
@ -114,7 +114,7 @@ describe("Global Actions", () => {
"actions.setLocalStorage('localStorage','data from runjs');" "actions.setLocalStorage('localStorage','data from runjs');"
); );
query("run"); query("run");
cy.wait(500)
cy.getAllLocalStorage().then((result) => { cy.getAllLocalStorage().then((result) => {
expect(result[Cypress.config().baseUrl].localStorage).to.deep.equal( expect(result[Cypress.config().baseUrl].localStorage).to.deep.equal(
"data from runjs" "data from runjs"

View file

@ -96,7 +96,7 @@ describe('Multiselect Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Multiselect-App`); cy.apiCreateApp(`${fake.companyName}-Multiselect-App`);
cy.openApp(); cy.openApp();
cy.dragAndDropWidget("Multiselect", 50, 50); cy.dragAndDropWidget("Multiselect", 50, 50);
cy.get('[data-cy="query-manager-collapse-button"]').click(); cy.get('[data-cy="query-manager-toggle-button"]').click();
}); });
it('should verify all the exposed values on inspector', () => { it('should verify all the exposed values on inspector', () => {

View file

@ -87,7 +87,7 @@ describe('Number Input Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Numberinput-App`); cy.apiCreateApp(`${fake.companyName}-Numberinput-App`);
cy.openApp(); cy.openApp();
cy.dragAndDropWidget("Number Input", 50, 50); cy.dragAndDropWidget("Number Input", 50, 50);
cy.get('[data-cy="query-manager-collapse-button"]').click(); cy.get('[data-cy="query-manager-toggle-button"]').click();
}); });
it('should verify all the exposed values on inspector', () => { it('should verify all the exposed values on inspector', () => {
@ -101,7 +101,7 @@ describe('Number Input Component Tests', () => {
}); });
it('should verify all the events from the number input', () => { it.skip('should verify all the events from the number input', () => {
const events = [ const events = [
{ event: "On Focus", message: "On Focus Event" }, { event: "On Focus", message: "On Focus Event" },
{ event: "On Blur", message: "On Blur Event" }, { event: "On Blur", message: "On Blur Event" },
@ -129,7 +129,7 @@ describe('Number Input Component Tests', () => {
inputEvents(inputSelector); inputEvents(inputSelector);
}); });
it('should verify all the CSA from number input', () => { it.skip('should verify all the CSA from number input', () => {
const actions = [ const actions = [
{ event: "On click", action: "Set visibility", valueToggle: "{{false}}" }, //b1 { event: "On click", action: "Set visibility", valueToggle: "{{false}}" }, //b1
{ event: "On click", action: "Set visibility", valueToggle: "{{true}}" },//b2 { event: "On click", action: "Set visibility", valueToggle: "{{true}}" },//b2

View file

@ -87,7 +87,7 @@ describe('Password Input Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Passwordinput-App`); cy.apiCreateApp(`${fake.companyName}-Passwordinput-App`);
cy.openApp(); cy.openApp();
cy.dragAndDropWidget("Password Input", 50, 50); cy.dragAndDropWidget("Password Input", 50, 50);
cy.get('[data-cy="query-manager-collapse-button"]').click(); cy.get('[data-cy="query-manager-toggle-button"]').click();
}); });
it('should verify all the exposed values on inspector', () => { it('should verify all the exposed values on inspector', () => {
@ -101,7 +101,7 @@ describe('Password Input Component Tests', () => {
}); });
it('should verify all the events from the password input', () => { it.skip('should verify all the events from the password input', () => {
const events = [ const events = [
{ event: "On Focus", message: "On Focus Event" }, { event: "On Focus", message: "On Focus Event" },
{ event: "On Blur", message: "On Blur Event" }, { event: "On Blur", message: "On Blur Event" },

View file

@ -95,10 +95,10 @@ describe('Text Input Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Textinput-App`); cy.apiCreateApp(`${fake.companyName}-Textinput-App`);
cy.openApp(); cy.openApp();
cy.dragAndDropWidget("Text Input", 50, 50); cy.dragAndDropWidget("Text Input", 50, 50);
cy.get('[data-cy="query-manager-collapse-button"]').click(); cy.get('[data-cy="query-manager-toggle-button"]').click();
}); });
it('should verify all the exposed values on inspector', () => { it.skip('should verify all the exposed values on inspector', () => {
cy.get(commonWidgetSelector.sidebarinspector).click(); cy.get(commonWidgetSelector.sidebarinspector).click();
cy.get(".tooltip-inner").invoke("hide"); cy.get(".tooltip-inner").invoke("hide");
@ -109,7 +109,7 @@ describe('Text Input Component Tests', () => {
}); });
it('should verify all the events from the text input', () => { it.skip('should verify all the events from the text input', () => {
const events = [ const events = [
{ event: "On Focus", message: "On Focus Event" }, { event: "On Focus", message: "On Focus Event" },
{ event: "On Blur", message: "On Blur Event" }, { event: "On Blur", message: "On Blur Event" },
@ -137,7 +137,7 @@ describe('Text Input Component Tests', () => {
verifyTextInputEvents(textInputSelector); verifyTextInputEvents(textInputSelector);
}); });
it('should verify all the CSA from text input', () => { it.skip('should verify all the CSA from text input', () => {
const actions = [ const actions = [
{ event: "On click", action: "Set visibility", valueToggle: "{{false}}" }, //b1 { event: "On click", action: "Set visibility", valueToggle: "{{false}}" }, //b1
{ event: "On click", action: "Visibility", valueToggle: "{{true}}" },//b2 { event: "On click", action: "Visibility", valueToggle: "{{true}}" },//b2

View file

@ -80,7 +80,7 @@ describe('ToggleSwitch Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Toggle-App`); cy.apiCreateApp(`${fake.companyName}-Toggle-App`);
cy.openApp(); cy.openApp();
cy.dragAndDropWidget("Toggle Switch", 50, 50); cy.dragAndDropWidget("Toggle Switch", 50, 50);
cy.get('[data-cy="query-manager-collapse-button"]').click(); cy.get('[data-cy="query-manager-toggle-button"]').click();
}); });
it('should verify all the exposed values on inspector', () => { it('should verify all the exposed values on inspector', () => {
@ -137,6 +137,8 @@ describe('ToggleSwitch Component Tests', () => {
cy.get(commonWidgetSelector.draggableWidget(component)).should("not.be.visible"); cy.get(commonWidgetSelector.draggableWidget(component)).should("not.be.visible");
cy.get(commonWidgetSelector.draggableWidget("button2")).click(); cy.get(commonWidgetSelector.draggableWidget("button2")).click();
cy.wait(500);
cy.forceClickOnCanvas();
cy.get(commonWidgetSelector.draggableWidget(component)).should("be.visible"); cy.get(commonWidgetSelector.draggableWidget(component)).should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("button3")).click(); cy.get(commonWidgetSelector.draggableWidget("button3")).click();

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

@ -17,6 +17,7 @@ describe("Editor- Inspector", () => {
cy.apiLogin(); cy.apiLogin();
cy.apiCreateApp(`${fake.companyName}-inspector-App`); cy.apiCreateApp(`${fake.companyName}-inspector-App`);
cy.openApp("?key=value"); cy.openApp("?key=value");
cy.viewport(1800, 1800);
}); });
it("should verify the values of inspector", () => { it("should verify the values of inspector", () => {
@ -45,14 +46,14 @@ describe("Editor- Inspector", () => {
cy.apiDeleteApp(); cy.apiDeleteApp();
}); });
it("should verify dynamic items", () => { it.skip("should verify dynamic items", () => {
cy.get(commonWidgetSelector.sidebarinspector).click(); cy.get(commonWidgetSelector.sidebarinspector).click();
cy.get(".tooltip-inner").invoke("hide"); cy.get(".tooltip-inner").invoke("hide");
cy.get(multipageSelector.sidebarPageButton).click(); cy.get(multipageSelector.sidebarPageButton).click();
addNewPage("test_page"); addNewPage("test_page");
cy.dragAndDropWidget("Button", 500, 500); cy.dragAndDropWidget("Button", 100, 100);
selectEvent("On click", "Switch page"); selectEvent("On click", "Switch page");
cy.get('[data-cy="switch-page-label-and-input"] > .select-search').click().type("home{enter}"); cy.get('[data-cy="switch-page-label-and-input"] > .select-search').click().type("home{enter}");
@ -72,7 +73,9 @@ describe("Editor- Inspector", () => {
cy.dragAndDropWidget("Button", 500, 300); cy.dragAndDropWidget("Button", 500, 300);
selectEvent("On click", "Set variable"); selectEvent("On click", "Set variable");
addSupportCSAData("event-key", "globalVar"); addSupportCSAData("event-key", "globalVar");
cy.wait(500)
addSupportCSAData("variable", "globalVar"); addSupportCSAData("variable", "globalVar");
cy.wait(500)
cy.forceClickOnCanvas(); cy.forceClickOnCanvas();
cy.waitForAutoSave(); cy.waitForAutoSave();
@ -141,17 +144,17 @@ describe("Editor- Inspector", () => {
cy.dragAndDropWidget("Button", 500, 300); cy.dragAndDropWidget("Button", 500, 300);
cy.get(commonWidgetSelector.sidebarinspector).click(); cy.get(commonWidgetSelector.sidebarinspector).click();
openNode("components"); openNode("components");
cy.get(`[data-cy="inspector-node-button1"] > .mx-1`).realHover(); cy.get(`[data-cy="inspector-node-button1"] > .mx-1`).eq(0).realHover();
cy.get('[style="height: 13px; width: 13px;"] > img').click(); cy.get('[style="height: 13px; width: 13px;"] > img').last().click();
cy.notVisible(commonWidgetSelector.draggableWidget("button1")); cy.notVisible(commonWidgetSelector.draggableWidget("button1"));
cy.apiDeleteApp(); cy.apiDeleteApp();
}); });
it("should verify deletion of component from inspector", () => { it.skip("should verify deletion of component from inspector", () => {
cy.dragAndDropWidget("button", 500, 500); cy.dragAndDropWidget("button", 500, 500);
cy.get(commonWidgetSelector.sidebarinspector).click(); cy.get(commonWidgetSelector.sidebarinspector).click();
deleteComponentFromInspector("button1"); deleteComponentFromInspector("button1");
cy.verifyToastMessage(`[class=go3958317564]`, "Component deleted! ( + Z to undo)"); cy.verifyToastMessage(`[class=go3958317564]`, "Component deleted! (ctrl + Z to undo)");
navigateToCreateNewVersionModal((currentVersion = "v1")); navigateToCreateNewVersionModal((currentVersion = "v1"));
createNewVersion((newVersion = ["v2"]), (versionFrom = "v1")); createNewVersion((newVersion = ["v2"]), (versionFrom = "v1"));

View file

@ -14,6 +14,7 @@ describe("Chaining of queries", () => {
cy.apiLogin(); cy.apiLogin();
cy.apiCreateApp(`${fake.companyName}-chaining-App`); cy.apiCreateApp(`${fake.companyName}-chaining-App`);
cy.openApp(); cy.openApp();
cy.apiFetchDataSourcesId()
cy.viewport(1800, 1800); cy.viewport(1800, 1800);
cy.dragAndDropWidget("Button"); cy.dragAndDropWidget("Button");
resizeQueryPanel("80"); resizeQueryPanel("80");
@ -57,7 +58,7 @@ describe("Chaining of queries", () => {
); );
cy.apiCreateGDS( cy.apiCreateGDS(
"http://localhost:3000/api/v2/data_sources", `http://localhost:3000/api/data-sources`,
`cypress-${dsName}-qc-postgresql`, `cypress-${dsName}-qc-postgresql`,
"postgresql", "postgresql",
[ [
@ -68,8 +69,10 @@ describe("Chaining of queries", () => {
{ key: "password", value: Cypress.env("pg_password"), encrypted: true }, { key: "password", value: Cypress.env("pg_password"), encrypted: true },
{ key: "ssl_enabled", value: false, encrypted: false }, { key: "ssl_enabled", value: false, encrypted: false },
{ key: "ssl_certificate", value: "none", encrypted: false }, { key: "ssl_certificate", value: "none", encrypted: false },
{ key: "connection_type", value: "manual", encrypted: false }
] ]
); );
cy.log("Data source created");
cy.apiAddQueryToApp( cy.apiAddQueryToApp(
"psql", "psql",
{ {
@ -92,8 +95,17 @@ describe("Chaining of queries", () => {
chainQuery("restapi", "tjdb"); chainQuery("restapi", "tjdb");
addSuccessNotification("restapi"); addSuccessNotification("restapi");
cy.get(`[data-cy="list-query-tjdb"]`).click();
cy.get('[data-cy="query-tab-settings"]').click();
selectEvent("Query Failure", "Show Alert");
cy.get('[data-cy="debounce-input-field"]')
.click()
.type(`{selectAll}{backspace}2000{enter}`);
cy.wait(1000)
cy.get('[data-cy="query-tab-setup"]').click();
openEditorSidebar(buttonText.defaultWidgetName); openEditorSidebar(buttonText.defaultWidgetName);
selectEvent("On Click", "Run Query", 1, `[data-cy="add-event-handler"]`, 1); selectEvent("On Click", "Run Query", 0, `[data-cy="add-event-handler"]`, 0);
cy.wait(500); cy.wait(500);
cy.get('[data-cy="query-selection-field"]') cy.get('[data-cy="query-selection-field"]')
.click() .click()
@ -105,11 +117,13 @@ describe("Chaining of queries", () => {
cy.verifyToastMessage(commonSelectors.toastMessage, "psql"); cy.verifyToastMessage(commonSelectors.toastMessage, "psql");
cy.verifyToastMessage(commonSelectors.toastMessage, "runjs"); cy.verifyToastMessage(commonSelectors.toastMessage, "runjs");
cy.verifyToastMessage(commonSelectors.toastMessage, "runpy"); cy.verifyToastMessage(commonSelectors.toastMessage, "runpy");
cy.wait(500);
cy.verifyToastMessage(commonSelectors.toastMessage, "restapi"); cy.verifyToastMessage(commonSelectors.toastMessage, "restapi");
cy.verifyToastMessage(commonSelectors.toastMessage, "Invalid operation"); // cy.verifyToastMessage(commonSelectors.toastMessage, "Hello World");
}); });
it("should verify query duplication", () => { it.skip("should verify query duplication", () => {
const data = {}; const data = {};
let dsName = fake.companyName; let dsName = fake.companyName;
data.customText = randomString(12); data.customText = randomString(12);
@ -133,7 +147,7 @@ describe("Chaining of queries", () => {
addSuccessNotification("runjs"); addSuccessNotification("runjs");
openEditorSidebar(buttonText.defaultWidgetName); openEditorSidebar(buttonText.defaultWidgetName);
selectEvent("On Click", "Run Query", 1, `[data-cy="add-event-handler"]`, 1); selectEvent("On Click", "Run Query", 0, `[data-cy="add-event-handler"]`, 0);
cy.wait(500); cy.wait(500);
cy.get('[data-cy="query-selection-field"]') cy.get('[data-cy="query-selection-field"]')
.click() .click()

View file

@ -54,7 +54,7 @@ describe("RunJS", () => {
cy.apiDeleteApp(); cy.apiDeleteApp();
}); });
it("should verify global and page data", () => { it.skip("should verify global and page data", () => {
const data = {}; const data = {};
data.customText = randomString(12); data.customText = randomString(12);
@ -147,9 +147,9 @@ describe("RunJS", () => {
"runjs", "runjs",
"actions.showAlert('success', 'alert from runjs');" "actions.showAlert('success', 'alert from runjs');"
); );
cy.get('[data-cy="query-tab-Settings"]').click(); cy.get('[data-cy="query-tab-settings"]').click();
changeQueryToggles("run-on-app-load"); changeQueryToggles("run-on-app-load");
cy.wait(`@editQuery`); // cy.wait(`@editQuery`);
cy.waitForAutoSave(); cy.waitForAutoSave();
cy.waitForAutoSave(); cy.waitForAutoSave();
cy.reload(); cy.reload();
@ -159,9 +159,9 @@ describe("RunJS", () => {
"alert from runjs", "alert from runjs",
false false
); );
cy.get('[data-cy="query-tab-Settings"]').click(); cy.get('[data-cy="query-tab-settings"]').click();
changeQueryToggles("confirmation-before-run"); changeQueryToggles("confirmation-before-run");
cy.wait(`@editQuery`); // cy.wait(`@editQuery`);
cy.waitForAutoSave(); cy.waitForAutoSave();
cy.reload(); cy.reload();
cy.get('[data-cy="modal-message"]').verifyVisibleElement( cy.get('[data-cy="modal-message"]').verifyVisibleElement(
@ -172,12 +172,12 @@ describe("RunJS", () => {
cy.verifyToastMessage(commonSelectors.toastMessage, "alert from runjs"); cy.verifyToastMessage(commonSelectors.toastMessage, "alert from runjs");
resizeQueryPanel("80"); resizeQueryPanel("80");
cy.get('[data-cy="query-tab-Settings"]').click(); cy.get('[data-cy="query-tab-settings"]').click();
changeQueryToggles("notification-on-success"); changeQueryToggles("notification-on-success");
cy.get('[data-cy="success-message-input-field"]').clearAndTypeOnCodeMirror( cy.get('[data-cy="success-message-input-field"]').clearAndTypeOnCodeMirror(
"Success alert" "Success alert"
); );
cy.get('[data-cy="query-tab-Setup"]').click(); cy.get('[data-cy="query-tab-setup"]').click();
cy.get('[data-cy="runjs-input-field"]').realClick(); cy.get('[data-cy="runjs-input-field"]').realClick();
cy.wait(1000); cy.wait(1000);
cy.waitForAutoSave(); cy.waitForAutoSave();

View file

@ -59,7 +59,7 @@ describe("runpy", () => {
cy.apiDeleteApp(); cy.apiDeleteApp();
}); });
it.only("should verify actions", () => { it.skip("should verify actions", () => {
const data = {}; const data = {};
data.customText = randomString(12); data.customText = randomString(12);
@ -120,18 +120,18 @@ actions.unsetPageVariable('pageVar')`
cy.waitForAutoSave(); cy.waitForAutoSave();
addInputOnQueryField("runpy", "actions.showModal('modal1')"); addInputOnQueryField("runpy", "actions.showModal('modal1')");
query("run"); query("run");
cy.get('[data-cy="modal-title"]').should("be.visible"); cy.get('.text-widget-section > div').should("be.visible");
cy.get('[data-cy="runpy-input-field"]').click({ force: true }); cy.get('[data-cy="runpy-input-field"]').click({ force: true });
addInputOnQueryField("runpy", "actions.closeModal('modal1')"); addInputOnQueryField("runpy", "actions.closeModal('modal1')");
cy.wait(`@editQuery`); // cy.wait(`@editQuery`);
cy.waitForAutoSave(); cy.waitForAutoSave();
query("run"); query("run");
waitForQueryAction("run"); waitForQueryAction("run");
cy.notVisible('[data-cy="modal-title"]'); cy.notVisible('[data-cy="modal-title"]');
addInputOnQueryField("runpy", "actions.copyToClipboard('data from runpy')"); addInputOnQueryField("runpy", "actions.copyToClipboard('data from runpy')");
cy.wait(`@editQuery`); // cy.wait(`@editQuery`);
cy.waitForAutoSave(); cy.waitForAutoSave();
query("run"); query("run");
waitForQueryAction("run"); waitForQueryAction("run");
@ -144,7 +144,7 @@ actions.unsetPageVariable('pageVar')`
"runpy", "runpy",
"actions.setLocalStorage('localStorage','data from runpy')" "actions.setLocalStorage('localStorage','data from runpy')"
); );
cy.wait(`@editQuery`); // cy.wait(`@editQuery`);
cy.waitForAutoSave(); cy.waitForAutoSave();
query("run"); query("run");
waitForQueryAction("run"); waitForQueryAction("run");
@ -155,17 +155,17 @@ actions.unsetPageVariable('pageVar')`
); );
}); });
addInputOnQueryField( // addInputOnQueryField( //Need fix asap
"runpy", // "runpy",
"actions.generateFile('runpycsv', 'csv', [{ 'name': 'John', 'email': 'john@tooljet.com' }])" // "actions.generateFile('runpycsv', 'csv', [{ 'name': 'John', 'email': 'john@tooljet.com' }])"
); // );
query("run"); // query("run");
cy.wait(3000); // cy.wait(3000);
cy.readFile("cypress/downloads/runpycsv.csv", "utf-8") // cy.readFile("cypress/downloads/runpycsv.csv", "utf-8")
.should("contain", "name,email") // .should("contain", "name,email")
.and("contain", "John,john@tooljet.com"); // .and("contain", "John,john@tooljet.com");
// addInputOnQueryField( // addInputOnQueryField(
// "runpy", // "runpy",
@ -174,7 +174,7 @@ actions.unsetPageVariable('pageVar')`
// query("run"); // query("run");
addInputOnQueryField("runpy", "actions.logout()"); addInputOnQueryField("runpy", "actions.logout()");
cy.wait(`@editQuery`); // cy.wait(`@editQuery`);
cy.wait(200); cy.wait(200);
cy.waitForAutoSave(); cy.waitForAutoSave();
query("run"); query("run");
@ -184,7 +184,7 @@ actions.unsetPageVariable('pageVar')`
); );
}); });
it("should verify global and page data", () => { it.skip("should verify global and page data", () => {
const data = {}; const data = {};
data.customText = randomString(12); data.customText = randomString(12);
@ -273,20 +273,20 @@ actions.unsetPageVariable('pageVar')`
"runpy", "runpy",
"actions.showAlert('success', 'alert from runpy');" "actions.showAlert('success', 'alert from runpy');"
); );
cy.get('[data-cy="query-tab-Settings"]').click(); cy.get('[data-cy="query-tab-settings"]').click();
cy.wait("@editQuery"); // cy.wait("@editQuery");
cy.wait(200); cy.wait(200);
cy.waitForAutoSave(); cy.waitForAutoSave();
changeQueryToggles("run-on-app-load"); changeQueryToggles("run-on-app-load");
cy.wait("@editQuery"); // cy.wait("@editQuery");
cy.waitForAutoSave(); cy.waitForAutoSave();
cy.reload(); cy.reload();
cy.verifyToastMessage(commonSelectors.toastMessage, "alert from runpy"); cy.verifyToastMessage(commonSelectors.toastMessage, "alert from runpy");
cy.get('[data-cy="query-tab-Settings"]').click(); cy.get('[data-cy="query-tab-settings"]').click();
changeQueryToggles("confirmation-before-run"); changeQueryToggles("confirmation-before-run");
cy.wait("@editQuery"); // cy.wait("@editQuery");
cy.wait(200); cy.wait(200);
cy.waitForAutoSave(); cy.waitForAutoSave();
cy.reload(); cy.reload();
@ -297,13 +297,13 @@ actions.unsetPageVariable('pageVar')`
cy.get('[data-cy="modal-confirm-button"]').realClick(); cy.get('[data-cy="modal-confirm-button"]').realClick();
cy.verifyToastMessage(commonSelectors.toastMessage, "alert from runpy"); cy.verifyToastMessage(commonSelectors.toastMessage, "alert from runpy");
cy.get('[data-cy="query-tab-Settings"]').click(); cy.get('[data-cy="query-tab-settings"]').click();
changeQueryToggles("notification-on-success"); changeQueryToggles("notification-on-success");
cy.get('[data-cy="success-message-input-field"]').clearAndTypeOnCodeMirror( cy.get('[data-cy="success-message-input-field"]').clearAndTypeOnCodeMirror(
"Success alert" "Success alert"
); );
cy.forceClickOnCanvas(); cy.forceClickOnCanvas();
cy.wait("@editQuery"); // cy.wait("@editQuery");
cy.wait(200); cy.wait(200);
cy.waitForAutoSave(); cy.waitForAutoSave();
cy.reload(); cy.reload();

View file

@ -26,7 +26,6 @@ describe("Data source amazon athena", () => {
beforeEach(() => { beforeEach(() => {
cy.apiLogin(); cy.apiLogin();
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
}); });
it("Should verify elements on amazon athena connection form", () => { it("Should verify elements on amazon athena connection form", () => {

View file

@ -26,7 +26,6 @@ describe("Data source amazon ses", () => {
beforeEach(() => { beforeEach(() => {
cy.apiLogin(); cy.apiLogin();
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
}); });
it("Should verify elements on amazonses connection form", () => { it("Should verify elements on amazonses connection form", () => {

View file

@ -26,7 +26,6 @@ describe("Data source AppWrite", () => {
beforeEach(() => { beforeEach(() => {
cy.apiLogin(); cy.apiLogin();
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
}); });
it("Should verify elements on appwrite connection form", () => { it("Should verify elements on appwrite connection form", () => {

View file

@ -26,7 +26,6 @@ describe("Data source AWS Lambda", () => {
beforeEach(() => { beforeEach(() => {
cy.apiLogin(); cy.apiLogin();
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
}); });
it("Should verify elements on AWS Lambda connection form", () => { it("Should verify elements on AWS Lambda connection form", () => {

View file

@ -27,7 +27,6 @@ describe("Data source AWS Textract", () => {
beforeEach(() => { beforeEach(() => {
cy.apiLogin(); cy.apiLogin();
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
}); });
it("Should verify elements on AWS Textract connection form", () => { it("Should verify elements on AWS Textract connection form", () => {

View file

@ -18,7 +18,7 @@ data.customText = fake.randomSentence;
describe("Data source Azure Blob Storage", () => { describe("Data source Azure Blob Storage", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.intercept("GET", "/api/v2/data_sources"); cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");

View file

@ -26,7 +26,6 @@ describe("Data source baserow", () => {
beforeEach(() => { beforeEach(() => {
cy.apiLogin(); cy.apiLogin();
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
}); });
it("Should verify elements on baserow connection form", () => { it("Should verify elements on baserow connection form", () => {

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,7 +17,7 @@ const data = {};
describe("Data source BigQuery", () => { describe("Data source BigQuery", () => {
beforeEach(() => { beforeEach(() => {
cy.appUILogin(); cy.appUILogin();
cy.intercept("GET", "/api/v2/data_sources"); cy.defaultWorkspaceLogin();
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -50,10 +51,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

@ -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

@ -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

@ -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

@ -5,7 +5,7 @@ import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql"; import { postgreSqlText } from "Texts/postgreSql";
import { restAPISelector } from "Selectors/restAPI"; import { restAPISelector } from "Selectors/restAPI";
import { restAPIText } from "Texts/restAPI"; import { restAPIText } from "Texts/restAPI";
import { fillDataSourceTextField } from "Support/utils/postgreSql"; import { createAndRunRestAPIQuery } from "Support/utils/restAPI";
const data = {}; const data = {};
const authenticationDropdownSelector = const authenticationDropdownSelector =
@ -19,8 +19,8 @@ const clientAuthenticationDropdown =
describe("Data source Rest API", () => { describe("Data source Rest API", () => {
beforeEach(() => { beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.intercept("GET", "/api/v2/data_sources");
data.dataSourceName = fake.lastName data.dataSourceName = fake.lastName
.toLowerCase() .toLowerCase()
.replaceAll("[^A-Za-z]", ""); .replaceAll("[^A-Za-z]", "");
@ -331,7 +331,8 @@ describe("Data source Rest API", () => {
cy.verifyToastMessage(commonSelectors.toastMessage, "Data Source Saved"); cy.verifyToastMessage(commonSelectors.toastMessage, "Data Source Saved");
deleteDatasource(`cypress-${data.dataSourceName}-restapi`); deleteDatasource(`cypress-${data.dataSourceName}-restapi`);
}); });
it("Should verify connection for Rest API", () => { it("Should verify basic connection for Rest API", () => {
const storedId = Cypress.env("storedId");
cy.apiCreateGDS( cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`, `${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-restapi`, `cypress-${data.dataSourceName}-restapi`,
@ -366,18 +367,89 @@ describe("Data source Rest API", () => {
] ]
); );
cy.reload(); cy.reload();
// cy.apiCreateApp(`${fake.companyName}-restAPI-App`);
// cy.apiAddQueryToApp( cy.apiCreateApp(`${fake.companyName}-restAPI-App`);
// "restapi1", cy.openApp();
// { createAndRunRestAPIQuery(
// method: "get", "get_restapi",
// url: "", `cypress-${data.dataSourceName}-restapi`,
// url_params: [["", ""]], "GET",
// headers: [["", ""]], "/api/users"
// cookies: [["", ""]], );
// }, createAndRunRestAPIQuery(
// `cypress-${data.dataSourceName}-restapi`, "post_restapi",
// "restapi" `cypress-${data.dataSourceName}-restapi`,
// ); "POST",
"",
[["Content-Type", "application/json"]],
[],
{
price: 200,
name: "Violin",
},
true,
"/api/users"
);
cy.readFile("cypress/fixtures/restAPI/storedId.json").then(
(postResponseID) => {
const id1 = postResponseID.id;
createAndRunRestAPIQuery(
"put_restapi_id",
`cypress-${data.dataSourceName}-restapi`,
"PUT",
"",
[["Content-Type", "application/json"]],
[],
{
price: 500,
name: "Guitar",
},
true,
`/api/users/${id1}`
);
}
);
cy.readFile("cypress/fixtures/restAPI/storedId.json").then(
(putResponseID) => {
const id2 = putResponseID.id;
createAndRunRestAPIQuery(
"patch_restapi_id",
`cypress-${data.dataSourceName}-restapi`,
"PATCH",
"",
[["Content-Type", "application/json"]],
[],
{ price: 999 },
true,
`/api/users/${id2}`
);
}
);
cy.readFile("cypress/fixtures/restAPI/storedId.json").then(
(patchResponseID) => {
const id3 = patchResponseID.id;
createAndRunRestAPIQuery(
"get_restapi_id",
`cypress-${data.dataSourceName}-restapi`,
"GET",
"",
[],
[],
true,
`/api/users/${id3}`
);
createAndRunRestAPIQuery(
"delete_restapi_id",
`cypress-${data.dataSourceName}-restapi`,
"DELETE",
"",
[],
[],
true,
`/api/users/${id3}`
);
}
);
}); });
}); });

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,
@ -51,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

@ -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,219 @@
import { fake } from "Fixtures/fake";
import { commonSelectors } from "Selectors/common";
import { importSelectors } from "Selectors/exportImport";
import { commonText } from "Texts/common";
import { exportAppModalText } from "Texts/exportImport";
import {
clickOnExportButtonAndVerify,
exportAllVersionsAndVerify,
verifyElementsOfExportModal,
} from "Support/utils/exportImport";
import { selectAppCardOption, closeModal } from "Support/utils/common";
describe("App Export", () => {
const TEST_DATA = {
appFiles: {
multiVersion: "cypress/fixtures/templates/three-versions.json",
singleVersion: "cypress/fixtures/templates/one_version.json",
},
};
let data;
data = {
workspaceName: fake.firstName,
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
appName: `${fake.companyName}-IE-App`,
appReName: `${fake.companyName}-${fake.companyName}-IE-App`,
dsName: fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""),
};
beforeEach(() => {
data = {
workspaceName: fake.firstName,
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
appName: `${fake.companyName}-IE-App`,
appReName: `${fake.companyName}-${fake.companyName}-IE-App`,
dsName: fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""),
};
cy.exec("mkdir -p ./cypress/downloads/");
cy.wait(3000);
cy.apiLogin();
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
cy.apiLogout();
});
it("Verify the elements of export dialog box", () => {
cy.window({ log: false }).then((win) => {
win.localStorage.setItem("walkthroughCompleted", "true");
});
cy.apiLogin();
cy.visit(`${data.workspaceSlug}`);
cy.get(importSelectors.importOptionInput)
.eq(0)
.selectFile(TEST_DATA.appFiles.multiVersion, {
force: true,
});
cy.wait(1500);
cy.clearAndType(commonSelectors.appNameInput, data.appName);
cy.get(importSelectors.importAppButton).click();
cy.wait(3000);
cy.backToApps();
// Select the app card option to export the app
selectAppCardOption(
data.appName,
commonSelectors.appCardOptions(commonText.exportAppOption)
);
// Verify the elements of the export modal
verifyElementsOfExportModal("v3", ["v2", "v1"], [true, false, false]);
// Close the modal
closeModal(exportAppModalText.modalCloseButton);
// Ensure the modal title is no longer visible
cy.get(
commonSelectors.modalTitle(exportAppModalText.selectVersionTitle)
).should("not.exist");
// Re-open the export modal and click the export button
selectAppCardOption(
data.appName,
commonSelectors.appCardOptions(commonText.exportAppOption)
);
clickOnExportButtonAndVerify(exportAppModalText.exportAll, data.appName);
cy.exec("ls ./cypress/downloads/").then((result) => {
const downloadedAppExportFileName = result.stdout.split("\n")[0];
const filePath = `./cypress/downloads/${downloadedAppExportFileName}`;
// Ensure the file name contains the expected app export name
expect(downloadedAppExportFileName).to.contain(
data.appName.toLowerCase()
);
// Read and validate the exported JSON file
cy.readFile(filePath).then((appData) => {
// Validate the app name
const appNameFromFile = appData.app[0].definition.appV2.name;
expect(appNameFromFile).to.equal(data.appName);
// Validate the schema for the student table in tooljetdb
const tooljetDatabase = appData.tooljet_database.find(
(db) => db.table_name === "student"
);
expect(tooljetDatabase).to.exist;
expect(tooljetDatabase.schema).to.exist;
// Validate components and queries
const components = appData.app[0].definition.appV2.components;
const text2Component = components.find(
(component) => component.name === "text2"
);
expect(text2Component).to.exist;
expect(text2Component.properties.text.value).to.equal(
"{{constants.pageHeader}}"
);
const textinput1 = components.find(
(component) => component.name === "textinput1"
);
expect(textinput1).to.exist;
expect(textinput1.properties.value.value).to.include("queries");
const textinput2 = components.find(
(component) => component.name === "textinput2"
);
expect(textinput2).to.exist;
expect(textinput2.properties.value.value).to.include("queries");
const textinput3 = components.find(
(component) => component.name === "textinput3"
);
expect(textinput3).to.exist;
expect(textinput3.properties.value.value).to.include("queries");
// Validate the data queries
const dataQueries = appData.app[0].definition.appV2.dataQueries;
const postgresqlQuery = dataQueries.find(
(query) => query.name === "postgresql1"
);
expect(postgresqlQuery).to.exist;
expect(postgresqlQuery.options.query).to.include(
"Select * from {{secrets.db_name}}"
);
const restapiQuery = dataQueries.find(
(query) => query.name === "restapi1"
);
expect(restapiQuery).to.exist;
expect(restapiQuery.options.url).to.equal(
"https://jsonplaceholder.typicode.com/users/1"
);
const tooljetdbQuery = dataQueries.find(
(query) => query.name === "tooljetdb1"
);
expect(tooljetdbQuery).to.exist;
expect(tooljetdbQuery.options.operation).to.equal("list_rows");
// Ensure appVersions exists
const appVersions = appData.app[0].definition.appV2.appVersions;
expect(appVersions).to.exist;
// Map and verify app version names
const versionNames = appVersions.map((version) => version.name);
expect(versionNames).to.include.members(["v1", "v2", "v3"]);
});
});
cy.exec("cd ./cypress/downloads/ && rm -rf *");
selectAppCardOption(
data.appName,
commonSelectors.appCardOptions(commonText.exportAppOption)
);
cy.get(`[data-cy="v1-radio-button"]`).check();
cy.get(
commonSelectors.buttonSelector(exportAppModalText.exportSelectedVersion)
).click();
cy.exec("ls ./cypress/downloads/").then((result) => {
const downloadedAppExportFileName = result.stdout.split("\n")[0];
const filePath = `./cypress/downloads/${downloadedAppExportFileName}`;
// Ensure the file name contains the expected app export name
expect(downloadedAppExportFileName).to.contain(
data.appName.toLowerCase()
);
// Read and validate the exported JSON file
cy.readFile(filePath).then((appData) => {
// Validate the app name
const appNameFromFile = appData.app[0].definition.appV2.name;
expect(appNameFromFile).to.equal(data.appName);
});
});
});
it.skip("Verify 'Export app' functionality of an application inside app editor", () => {
data.appName2 = `${fake.companyName}-App`;
cy.apiCreateApp(data.appName2);
cy.openApp(data.appName2);
cy.dragAndDropWidget("Text Input", 50, 50);
cy.get('[data-cy="left-sidebar-settings-button"]').click();
cy.get('[data-cy="button-user-status-change"]').click();
verifyElementsOfExportModal("v1");
exportAllVersionsAndVerify(data.appName1, "v1");
});
});

View file

@ -0,0 +1,230 @@
import { fake } from "Fixtures/fake";
import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { appVersionSelectors, importSelectors } from "Selectors/exportImport";
import { dashboardSelector } from "Selectors/dashboard";
import { buttonText } from "Texts/button";
import { importText } from "Texts/exportImport";
import { importAndVerifyApp } from "Support/utils/exportImport";
import { switchVersionAndVerify } from "Support/utils/version";
describe("App Import Functionality", () => {
const TEST_DATA = {
toolJetImage: "cypress/fixtures/Image/tooljet.png",
invalidApp: "cypress/fixtures/templates/invalid_app.json",
invalidFile: "cypress/fixtures/templates/invalid_file.json",
appFiles: {
multiVersion: "cypress/fixtures/templates/three-versions.json",
singleVersion: "cypress/fixtures/templates/one_version.json",
},
};
let data;
beforeEach(() => {
cy.viewport(1200, 1300);
data = {
workspaceName: fake.firstName,
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
appName: `${fake.companyName}-IE-App`,
appReName: `${fake.companyName}-${fake.companyName}-IE-App`,
dsName: fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""),
};
cy.apiLogin();
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
cy.apiLogout();
});
it("should verify app import functionality", () => {
cy.apiLogin();
cy.visit(`${data.workspaceSlug}`);
// Test invalid file import
cy.get(dashboardSelector.importAppButton).click();
importAndVerifyApp(
TEST_DATA.toolJetImage,
importText.couldNotImportAppToastMessage
);
cy.wait(500);
cy.get(dashboardSelector.importAppButton).click();
importAndVerifyApp(
TEST_DATA.invalidApp,
"Could not import: SyntaxError: Expected ',' or '}' after property value in JSON at position 246 (line 11 column 13)"
);
cy.wait(500);
// Test valid app import
cy.get(importSelectors.dropDownMenu).should("be.visible").click();
cy.get(importSelectors.importOptionLabel).verifyVisibleElement(
"have.text",
importText.importOption
);
cy.intercept("POST", "/api/v2/resources/import").as("importApp");
cy.get(importSelectors.importOptionInput)
.eq(0)
.selectFile(TEST_DATA.appFiles.multiVersion, {
force: true,
});
cy.wait(1500);
cy.get(importSelectors.importAppTitle).verifyVisibleElement(
"have.text",
"Import app"
);
cy.get(commonSelectors.appNameLabel).verifyVisibleElement(
"have.text",
"App name"
);
cy.get(commonSelectors.appNameInput)
.should("be.visible")
.and("have.value", "three-versions");
cy.get(commonSelectors.appNameInfoLabel).verifyVisibleElement(
"have.text",
"App name must be unique and max 50 characters"
);
cy.get(commonSelectors.cancelButton)
.should("be.visible")
.and("have.text", "Cancel");
cy.get(commonSelectors.importAppButton).verifyVisibleElement(
"have.text",
"Import app"
);
cy.get(importSelectors.importAppButton).click();
cy.get(".go3958317564")
.should("be.visible")
.and("have.text", importText.appImportedToastMessage);
// Verify imported app
cy.get(".driver-close-btn").click();
cy.wait(500);
cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"contain.value",
"three-versions"
);
// Configure app
cy.skipEditorPopover();
cy.dragAndDropWidget(buttonText.defaultWidgetText);
cy.get(appVersionSelectors.appVersionLabel).should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("button1")).should(
"be.visible"
);
cy.renameApp(data.appName);
cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"contain.value",
data.appName
);
cy.waitForAutoSave();
// Verify initial widget states
verifyCommonData({
text2: "",
textInput1: "",
textInput2: "Leanne Graham",
});
// cy.get(
// commonWidgetSelector.draggableWidget("textInput3")
// ).verifyVisibleElement("have.value", "");
// Setup database and data sources
cy.visit(`${data.workspaceSlug}/database`);
cy.get('[data-cy="student-table"]').verifyVisibleElement(
"have.text",
"student"
);
// cy.apiAddDataToTable("student", {
// name: "Paramu",
// country: "India",
// state: "Kerala",
// });
cy.visit(`${data.workspaceSlug}/data-sources`);
cy.get('[data-cy="postgresql-button"]').should("be.visible");
cy.apiUpdateDataSource("postgresql", "production", {
options: [
{
key: "password",
value: `${Cypress.env("pg_password")}`,
encrypted: true,
},
],
});
cy.apiCreateWsConstant(
"pageHeader",
"Import and Export",
["Global"],
["production"]
);
cy.apiCreateWsConstant("db_name", "persons", ["Secret"], ["production"]);
// Verify app after setup
cy.wait("@importApp").then((interception) => {
const appId = interception.response.body.imports.app[0].id;
cy.openApp(
"",
Cypress.env("workspaceId"),
appId,
commonWidgetSelector.draggableWidget("text2")
);
});
verifyCommonData({
text2: "Import and Export",
textInput1: "John",
textInput2: "Leanne Graham",
});
// cy.get(
// commonWidgetSelector.draggableWidget("textInput3")
// ).verifyVisibleElement("have.value", "India");
switchVersionAndVerify("v3", "v1");
verifyCommonData({
text2: "Import and Export",
textInput1: "John",
textInput2: "Leanne Graham",
});
cy.wait(1000);
cy.backToApps();
// Test single version import
cy.get(importSelectors.dropDownMenu).click();
importAndVerifyApp(TEST_DATA.appFiles.singleVersion);
// Verify final state
cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"contain.value",
"one_version"
);
verifyCommonData({
text2: "Import and Export",
textInput1: "John",
textInput2: "Leanne Graham",
});
});
});
const verifyCommonData = (values) => {
cy.get(commonWidgetSelector.draggableWidget("text2")).verifyVisibleElement(
"have.text",
values.text2
);
cy.get(
commonWidgetSelector.draggableWidget("textInput1")
).verifyVisibleElement("have.value", values.textInput1);
cy.get(
commonWidgetSelector.draggableWidget("textInput2")
).verifyVisibleElement("have.value", values.textInput2);
};

View file

@ -1,419 +0,0 @@
import { fake } from "Fixtures/fake";
import { commonSelectors, commonWidgetSelector } from "Selectors/common";
import { appVersionSelectors, importSelectors } from "Selectors/exportImport";
import { commonText } from "Texts/common";
import { dashboardSelector } from "Selectors/dashboard";
import { buttonText } from "Texts/button";
import { exportAppModalText, importText } from "Texts/exportImport";
import {
clickOnExportButtonAndVerify,
exportAllVersionsAndVerify,
verifyElementsOfExportModal,
importAndVerifyApp,
} from "Support/utils/exportImport";
import { selectAppCardOption, closeModal } from "Support/utils/common";
import { switchVersionAndVerify } from "Support/utils/version";
describe("App Import Functionality", () => {
const TEST_DATA = {
toolJetImage: "cypress/fixtures/Image/tooljet.png",
invalidApp: "cypress/fixtures/templates/invalid_app.json",
invalidFile: "cypress/fixtures/templates/invalid_file.json",
appFiles: {
multiVersion: "cypress/fixtures/templates/three-versions.json",
singleVersion: "cypress/fixtures/templates/one_version.json",
},
};
let data;
const initializeData = () => {
const firstName = fake.firstName;
return {
workspaceName: firstName,
workspaceSlug: firstName.toLowerCase().replace(/\s+/g, "-"),
appName: `${fake.companyName}-IE-App`,
appReName: `${fake.companyName}-${fake.companyName}-IE-App`,
dsName: fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""),
};
};
data = initializeData();
before(() => {
cy.exec("mkdir -p ./cypress/downloads/");
cy.wait(3000);
});
beforeEach(() => {
cy.viewport(1200, 1300);
cy.apiLogin();
});
it("should verify app import functionality", () => {
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
cy.apiLogout();
cy.apiLogin();
cy.visit(`${data.workspaceSlug}`);
// Test invalid file import
cy.get(dashboardSelector.importAppButton).click();
importAndVerifyApp(
TEST_DATA.toolJetImage,
importText.couldNotImportAppToastMessage
);
cy.wait(500);
cy.get(dashboardSelector.importAppButton).click();
importAndVerifyApp(
TEST_DATA.invalidApp,
"Could not import: SyntaxError: Expected ',' or '}' after property value in JSON at position 246 (line 11 column 13)"
);
cy.wait(500);
cy.get(dashboardSelector.importAppButton).click();
cy.get(importSelectors.importOptionInput)
.eq(0)
.selectFile(TEST_DATA.invalidFile, {
force: true,
});
cy.get(importSelectors.importAppTitle).should("be.visible");
cy.get(importSelectors.importAppButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
"tooljet_version must be a string"
);
cy.wait(500);
// Test valid app import
cy.get(importSelectors.dropDownMenu).should("be.visible").click();
cy.get(importSelectors.importOptionLabel).verifyVisibleElement(
"have.text",
importText.importOption
);
cy.intercept("POST", "/api/v2/resources/import").as("importApp");
cy.get(importSelectors.importOptionInput)
.eq(0)
.selectFile(TEST_DATA.appFiles.multiVersion, {
force: true,
});
cy.wait(1500);
cy.get(importSelectors.importAppTitle).verifyVisibleElement(
"have.text",
"Import app"
);
cy.get(commonSelectors.appNameLabel).verifyVisibleElement(
"have.text",
"App name"
);
cy.get(commonSelectors.appNameInput)
.should("be.visible")
.and("have.value", "three-versions");
cy.get(commonSelectors.appNameInfoLabel).verifyVisibleElement(
"have.text",
"App name must be unique and max 50 characters"
);
cy.get(commonSelectors.cancelButton)
.should("be.visible")
.and("have.text", "Cancel");
cy.get(commonSelectors.importAppButton).verifyVisibleElement(
"have.text",
"Import app"
);
cy.get(importSelectors.importAppButton).click();
cy.get(".go3958317564")
.should("be.visible")
.and("have.text", importText.appImportedToastMessage);
// Verify imported app
cy.get(".driver-close-btn").click();
cy.wait(500);
cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"contain.value",
"three-versions"
);
// Configure app
cy.skipEditorPopover();
cy.dragAndDropWidget(buttonText.defaultWidgetText);
cy.get(appVersionSelectors.appVersionLabel).should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("button1")).should(
"be.visible"
);
cy.renameApp(data.appName);
cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"contain.value",
data.appName
);
cy.waitForAutoSave();
// Verify initial widget states
verifyCommonData({
text2: "",
textInput1: "",
textInput2: "Leanne Graham",
});
cy.get(
commonWidgetSelector.draggableWidget("textInput3")
).verifyVisibleElement("have.value", "");
// Setup database and data sources
cy.visit(`${data.workspaceSlug}/database`);
cy.get('[data-cy="student-table"]').verifyVisibleElement(
"have.text",
"student"
);
cy.apiAddDataToTable("student", {
name: "Paramu",
country: "India",
state: "Kerala",
});
cy.visit(`${data.workspaceSlug}/data-sources`);
cy.get('[data-cy="postgresql-button"]').should("be.visible");
cy.apiUpdateDataSource("postgresql", "production", {
options: [
{
key: "password",
value: `${Cypress.env("pg_password")}`,
encrypted: true,
},
],
});
cy.apiCreateWsConstant(
"pageHeader",
"Import and Export",
["Global"],
["production"]
);
cy.apiCreateWsConstant("db_name", "persons", ["Secret"], ["production"]);
// Verify app after setup
cy.wait("@importApp").then((interception) => {
const appId = interception.response.body.imports.app[0].id;
cy.openApp(
"",
Cypress.env("workspaceId"),
appId,
commonWidgetSelector.draggableWidget("text2")
);
});
verifyCommonData({
text2: "Import and Export",
textInput1: "John",
textInput2: "Leanne Graham",
});
cy.get(
commonWidgetSelector.draggableWidget("textInput3")
).verifyVisibleElement("have.value", "India");
switchVersionAndVerify("v3", "v1");
verifyCommonData({
text2: "Import and Export",
textInput1: "John",
textInput2: "Leanne Graham",
});
cy.wait(1000);
cy.backToApps();
// Test single version import
cy.get(importSelectors.dropDownMenu).click();
importAndVerifyApp(TEST_DATA.appFiles.singleVersion);
// Verify final state
cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"contain.value",
"one_version"
);
verifyCommonData({
text2: "Import and Export",
textInput1: "John",
textInput2: "Leanne Graham",
});
});
it("Verify the elements of export dialog box", () => {
cy.exec("cd ./cypress/downloads/ && rm -rf *");
cy.visit(`${data.workspaceSlug}`);
// Select the app card option to export the app
selectAppCardOption(
data.appName,
commonSelectors.appCardOptions(commonText.exportAppOption)
);
// Verify the elements of the export modal
verifyElementsOfExportModal("v3", ["v2", "v1"], [true, false, false]);
// Close the modal
closeModal(exportAppModalText.modalCloseButton);
// Ensure the modal title is no longer visible
cy.get(
commonSelectors.modalTitle(exportAppModalText.selectVersionTitle)
).should("not.exist");
// Re-open the export modal and click the export button
selectAppCardOption(
data.appName,
commonSelectors.appCardOptions(commonText.exportAppOption)
);
clickOnExportButtonAndVerify(exportAppModalText.exportAll, data.appName);
cy.exec("ls ./cypress/downloads/").then((result) => {
const downloadedAppExportFileName = result.stdout.split("\n")[0];
const filePath = `./cypress/downloads/${downloadedAppExportFileName}`;
// Ensure the file name contains the expected app export name
expect(downloadedAppExportFileName).to.contain(
data.appName.toLowerCase()
);
// Read and validate the exported JSON file
cy.readFile(filePath).then((appData) => {
// Validate the app name
const appNameFromFile = appData.app[0].definition.appV2.name;
expect(appNameFromFile).to.equal(data.appName);
// Validate the schema for the student table in tooljetdb
const tooljetDatabase = appData.tooljet_database.find(
(db) => db.table_name === "student"
);
expect(tooljetDatabase).to.exist;
expect(tooljetDatabase.schema).to.exist;
// Validate components and queries
const components = appData.app[0].definition.appV2.components;
const text2Component = components.find(
(component) => component.name === "text2"
);
expect(text2Component).to.exist;
expect(text2Component.properties.text.value).to.equal(
"{{constants.pageHeader}}"
);
const textinput1 = components.find(
(component) => component.name === "textinput1"
);
expect(textinput1).to.exist;
expect(textinput1.properties.value.value).to.include("queries");
const textinput2 = components.find(
(component) => component.name === "textinput2"
);
expect(textinput2).to.exist;
expect(textinput2.properties.value.value).to.include("queries");
const textinput3 = components.find(
(component) => component.name === "textinput3"
);
expect(textinput3).to.exist;
expect(textinput3.properties.value.value).to.include("queries");
// Validate the data queries
const dataQueries = appData.app[0].definition.appV2.dataQueries;
const postgresqlQuery = dataQueries.find(
(query) => query.name === "postgresql1"
);
expect(postgresqlQuery).to.exist;
expect(postgresqlQuery.options.query).to.include(
"Select * from {{secrets.db_name}}"
);
const restapiQuery = dataQueries.find(
(query) => query.name === "restapi1"
);
expect(restapiQuery).to.exist;
expect(restapiQuery.options.url).to.equal(
"https://jsonplaceholder.typicode.com/users/1"
);
const tooljetdbQuery = dataQueries.find(
(query) => query.name === "tooljetdb1"
);
expect(tooljetdbQuery).to.exist;
expect(tooljetdbQuery.options.operation).to.equal("list_rows");
// Ensure appVersions exists
const appVersions = appData.app[0].definition.appV2.appVersions;
expect(appVersions).to.exist;
// Map and verify app version names
const versionNames = appVersions.map((version) => version.name);
expect(versionNames).to.include.members(["v1", "v2", "v3"]);
});
});
cy.exec("cd ./cypress/downloads/ && rm -rf *");
selectAppCardOption(
data.appName,
commonSelectors.appCardOptions(commonText.exportAppOption)
);
cy.get(`[data-cy="v1-radio-button"]`).check();
cy.get(
commonSelectors.buttonSelector(exportAppModalText.exportSelectedVersion)
).click();
cy.exec("ls ./cypress/downloads/").then((result) => {
const downloadedAppExportFileName = result.stdout.split("\n")[0];
const filePath = `./cypress/downloads/${downloadedAppExportFileName}`;
// Ensure the file name contains the expected app export name
expect(downloadedAppExportFileName).to.contain(
data.appName.toLowerCase()
);
// Read and validate the exported JSON file
cy.readFile(filePath).then((appData) => {
// Validate the app name
const appNameFromFile = appData.app[0].definition.appV2.name;
expect(appNameFromFile).to.equal(data.appName);
});
});
});
it.skip("Verify 'Export app' functionality of an application inside app editor", () => {
data.appName2 = `${fake.companyName}-App`;
cy.apiCreateApp(data.appName2);
cy.openApp(data.appName2);
cy.dragAndDropWidget("Text Input", 50, 50);
cy.get('[data-cy="left-sidebar-settings-button"]').click();
cy.get('[data-cy="button-user-status-change"]').click();
verifyElementsOfExportModal("v1");
exportAllVersionsAndVerify(data.appName1, "v1");
});
});
const verifyCommonData = (values) => {
cy.get(commonWidgetSelector.draggableWidget("text2")).verifyVisibleElement(
"have.text",
values.text2
);
cy.get(
commonWidgetSelector.draggableWidget("textInput1")
).verifyVisibleElement("have.value", values.textInput1);
cy.get(
commonWidgetSelector.draggableWidget("textInput2")
).verifyVisibleElement("have.value", values.textInput2);
};

View file

@ -15,7 +15,6 @@ 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();
}); });
@ -25,133 +24,137 @@ 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", () => {
cy.apiLogin("dev@tooljet.io", "password").then(() => { cy.apiLogin();
const workspaceId = Cypress.env("workspaceId"); const workspaceId = Cypress.env("workspaceId");
const appId = Cypress.env("appId"); const appId = Cypress.env("appId");
cy.openApp("my-workspace"); cy.visit("/my-workspace");
cy.get(commonSelectors.leftSideBarSettingsButton).click(); cy.wait(1000);
// Verify initial state cy.window({ log: false }).then((win) => {
cy.get(commonWidgetSelector.appSlugLabel).verifyVisibleElement( win.localStorage.setItem("walkthroughCompleted", "true");
"have.text",
"Unique app slug"
);
cy.get(commonWidgetSelector.appSlugInput).verifyVisibleElement(
"have.value",
Cypress.env("appId")
);
cy.get(commonWidgetSelector.appSlugInfoLabel).verifyVisibleElement(
"have.text",
"URL-friendly 'slug' consists of lowercase letters, numbers, and hyphens"
);
cy.get(commonWidgetSelector.appLinkLabel).verifyVisibleElement(
"have.text",
"App link"
);
cy.get(commonWidgetSelector.appLinkField).verifyVisibleElement(
"have.text",
`${host}/${workspaceId}/apps/${appId}`
);
// Validate all error cases
verifySlugValidations(commonWidgetSelector.appSlugInput);
// Verify successful slug update
cy.clearAndType(commonWidgetSelector.appSlugInput, data.slug);
verifySuccessfulSlugUpdate(workspaceId, data.slug);
// Verify persistence
cy.get('[data-cy="left-sidebar-debugger-button"]').click();
cy.get(commonSelectors.leftSideBarSettingsButton).click();
cy.get(commonWidgetSelector.appSlugInput).should("have.value", data.slug);
// Release and verify URLs
releaseApp();
verifyURLs(workspaceId, data.slug, false);
// Verify duplicate slug validation
cy.visit("/my-workspace");
cy.apiCreateApp(data.slug);
cy.openApp("my-workspace");
cy.get(commonSelectors.leftSideBarSettingsButton).click();
cy.get(commonWidgetSelector.appSlugInput).clear();
cy.clearAndType(commonWidgetSelector.appSlugInput, data.slug);
cy.get(commonWidgetSelector.appSlugErrorLabel).verifyVisibleElement(
"have.text",
"This app slug is already taken."
);
}); });
cy.visit(`/${Cypress.env("workspaceId")}/apps/${Cypress.env("appId")}/`);
cy.wait(1000);
cy.get(commonSelectors.leftSideBarSettingsButton).click();
// Verify initial state
cy.get(commonWidgetSelector.appSlugLabel).verifyVisibleElement(
"have.text",
"Unique app slug"
);
cy.get(commonWidgetSelector.appSlugInput).verifyVisibleElement(
"have.value",
Cypress.env("appId")
);
cy.get(commonWidgetSelector.appSlugInfoLabel).verifyVisibleElement(
"have.text",
"URL-friendly 'slug' consists of lowercase letters, numbers, and hyphens"
);
cy.get(commonWidgetSelector.appLinkLabel).verifyVisibleElement(
"have.text",
"App link"
);
cy.get(commonWidgetSelector.appLinkField).verifyVisibleElement(
"have.text",
`${host}/${workspaceId}/apps/${appId}`
);
// Validate all error cases
verifySlugValidations(commonWidgetSelector.appSlugInput);
// Verify successful slug update
cy.clearAndType(commonWidgetSelector.appSlugInput, data.slug);
verifySuccessfulSlugUpdate(workspaceId, data.slug);
// Verify persistence
cy.get('[data-cy="left-sidebar-debugger-button"]').click();
cy.get(commonSelectors.leftSideBarSettingsButton).click();
cy.get(commonWidgetSelector.appSlugInput).should("have.value", data.slug);
// Release and verify URLs
releaseApp();
verifyURLs(workspaceId, data.slug, false);
// Verify duplicate slug validation
cy.visit("/my-workspace");
cy.apiCreateApp(data.slug);
cy.openApp("my-workspace");
cy.get(commonSelectors.leftSideBarSettingsButton).click();
cy.get(commonWidgetSelector.appSlugInput).clear();
cy.clearAndType(commonWidgetSelector.appSlugInput, data.slug);
cy.get(commonWidgetSelector.appSlugErrorLabel).verifyVisibleElement(
"have.text",
"This app slug is already taken."
);
}); });
it("Verify app slug cases in share modal", () => { it("Verify app slug cases in share modal", () => {
cy.apiLogin("dev@tooljet.io", "password").then(() => { cy.apiLogin();
const workspaceId = Cypress.env("workspaceId"); const workspaceId = Cypress.env("workspaceId");
cy.apiCreateApp(data.appName); cy.apiCreateApp(data.appName);
cy.openApp("my-workspace"); cy.openApp("my-workspace");
// Set up initial slug // Set up initial slug
cy.get(commonSelectors.leftSideBarSettingsButton).click(); cy.get(commonSelectors.leftSideBarSettingsButton).click();
cy.get(commonWidgetSelector.appSlugInput).clear(); cy.get(commonWidgetSelector.appSlugInput).clear();
cy.clearAndType(commonWidgetSelector.appSlugInput, data.slug); cy.clearAndType(commonWidgetSelector.appSlugInput, data.slug);
releaseApp(); releaseApp();
// Verify share modal // Verify share modal
cy.get(commonWidgetSelector.shareAppButton).click(); cy.get(commonWidgetSelector.shareAppButton).click();
cy.get(commonWidgetSelector.appLink).verifyVisibleElement( cy.get(commonWidgetSelector.appLink).verifyVisibleElement(
"have.text", "have.text",
`${host}/applications/` `${host}/applications/`
); );
cy.get(commonWidgetSelector.appNameSlugInput).should( cy.get(commonWidgetSelector.appNameSlugInput).should(
"have.value", "have.value",
data.slug data.slug
); );
// Validate all error cases in share modal // Validate all error cases in share modal
verifySlugValidations(commonWidgetSelector.appNameSlugInput); verifySlugValidations(commonWidgetSelector.appNameSlugInput);
cy.wait(500); cy.wait(500);
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug); cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
cy.get('[data-cy="app-slug-info-label"]') cy.get('[data-cy="app-slug-info-label"]')
.invoke("text") .invoke("text")
.then((text) => { .then((text) => {
expect(text.trim()).to.eq( expect(text.trim()).to.eq(
"URL-friendly 'slug' consists of lowercase letters, numbers, and hyphens" "URL-friendly 'slug' consists of lowercase letters, numbers, and hyphens"
); );
}); });
// Verify successful slug update in share modal // Verify successful slug update in share modal
data.slug = `${fake.companyName.toLowerCase()}-app`; data.slug = `${fake.companyName.toLowerCase()}-app`;
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug); cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
cy.get('[data-cy="app-slug-accepted-label"]').verifyVisibleElement( cy.get('[data-cy="app-slug-accepted-label"]').verifyVisibleElement(
"have.text", "have.text",
"Slug accepted!" "Slug accepted!"
); );
// Close modal and verify URLs // Close modal and verify URLs
cy.get(commonWidgetSelector.modalCloseButton).click(); cy.get(commonWidgetSelector.modalCloseButton).click();
verifyURLs(workspaceId, data.slug, true); verifyURLs(workspaceId, data.slug, true);
// Verify duplicate slug validation in share modal // Verify duplicate slug validation in share modal
cy.visit("/my-workspace"); cy.visit("/my-workspace");
cy.apiCreateApp(data.slug); cy.apiCreateApp(data.slug);
cy.openApp("my-workspace"); cy.openApp("my-workspace");
releaseApp(); releaseApp();
cy.get(commonWidgetSelector.shareAppButton).click(); cy.get(commonWidgetSelector.shareAppButton).click();
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug); cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
cy.get(commonWidgetSelector.appSlugErrorLabel).verifyVisibleElement( cy.get(commonWidgetSelector.appSlugErrorLabel).verifyVisibleElement(
"have.text", "have.text",
"This app slug is already taken." "This app slug is already taken."
); );
});
}); });
}); });

View file

@ -20,20 +20,20 @@ import {
describe("Private and Public apps", { describe("Private and Public apps", {
retries: { runMode: 2 }, retries: { runMode: 2 },
}, () => { }, () => {
const data = {}; let data;
beforeEach(() => { beforeEach(() => {
data.appName = `${fake.companyName} P P App`; data = {
data.slug = data.appName.toLowerCase().replace(/\s+/g, "-"); appName: `${fake.companyName} P P App`,
data.firstName = fake.firstName; slug: `${fake.companyName} P P App`.toLowerCase().replace(/\s+/g, "-"),
data.email = fake.email.toLowerCase(); firstName: fake.firstName,
data.workspaceName = fake.firstName; email: fake.email.toLowerCase(),
data.workspaceSlug = fake.firstName.toLowerCase().replace(/\s+/g, "-"); workspaceName: fake.firstName,
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
}
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,9 +85,9 @@ 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.appUILogin();
// 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();
@ -106,8 +106,8 @@ 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");
}); });
@ -123,30 +123,30 @@ describe("Private and Public apps", {
}); });
cy.wait(2000); cy.wait(2000);
cy.loginWithCredentials(data.email, "password"); cy.appUILogin(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
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.wait(1000);
cy.apiMakeAppPublic(); cy.apiMakeAppPublic();
logout(); logout();
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
@ -154,8 +154,8 @@ 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");
}); });
@ -180,8 +180,8 @@ 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
@ -189,8 +189,8 @@ 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");
}); });
@ -224,8 +224,8 @@ describe("Private and Public apps", {
// 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();
@ -269,8 +269,8 @@ describe("Private and Public apps", {
}); });
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");
}); });

View file

@ -114,7 +114,7 @@ describe("App Version", () => {
cy.wait(3000); cy.wait(3000);
// cy.reload(); // cy.reload();
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible", { timeout: 10000 }); 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);

View file

@ -46,7 +46,7 @@ describe("Datasource Manager", () => {
data.dsName1 = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""); data.dsName1 = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
data.dsName2 = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""); data.dsName2 = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
const allDataSources = host.includes("8082") ? "All data sources (42)" : "All data sources (44)"; const allDataSources = host.includes("8082") ? "All data sources (43)" : "All data sources (45)";
const allDatabase = host.includes("8082") ? "Databases (18)" : "Databases (20)"; const allDatabase = host.includes("8082") ? "Databases (18)" : "Databases (20)";
cy.get(commonSelectors.globalDataSourceIcon).click(); cy.get(commonSelectors.globalDataSourceIcon).click();
@ -214,7 +214,7 @@ describe("Datasource Manager", () => {
cy.get(commonWidgetSelector.sidebarinspector).click(); cy.get(commonWidgetSelector.sidebarinspector).click();
cy.get(dataSourceSelector.queryCreateAndRunButton).click(); cy.get(dataSourceSelector.queryCreateAndRunButton).click();
verifyValueOnInspector("table_preview", "7 items "); verifyValueOnInspector("table_preview", "10 items ");
cy.get('[data-cy="show-ds-popover-button"]').click(); cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".p-2 > .tj-base-btn") cy.get(".p-2 > .tj-base-btn")
@ -275,7 +275,7 @@ describe("Datasource Manager", () => {
pinInspector(); pinInspector();
cy.get(dataSourceSelector.queryCreateAndRunButton).click(); cy.get(dataSourceSelector.queryCreateAndRunButton).click();
verifyValueOnInspector("table_preview", "7 items "); verifyValueOnInspector("table_preview", "10 items ");
//scope changing is pending //scope changing is pending
}); });

View file

@ -18,10 +18,17 @@ import { roleBasedOnboarding } from "Support/utils/onboarding";
const data = {}; const data = {};
data.groupName = fake.firstName.replaceAll("[^A-Za-z]", ""); data.groupName = fake.firstName.replaceAll("[^A-Za-z]", "");
data.appName = `${fake.companyName}-App`; data.appName = `${fake.companyName}-App`;
const workspaceName = fake.firstName;
const workspaceSlug = fake.firstName.toLowerCase().replace(/[^A-Za-z]/g, "");
describe("Groups duplication", () => { describe("Groups duplication", () => {
beforeEach(() => { beforeEach(() => {
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
cy.apiCreateWorkspace(workspaceName, workspaceSlug);
cy.visit(`${workspaceSlug}`);
cy.apiLogout();
cy.apiLogin();
cy.visit(`${workspaceSlug}`);
groupPermission( groupPermission(
[ [
"appsCreateCheck", "appsCreateCheck",
@ -32,15 +39,18 @@ describe("Groups duplication", () => {
"Admin" "Admin"
); );
cy.apiCreateApp(data.appName); cy.apiCreateApp(data.appName);
}); });
it("Should verify the group duplication feature", () => { it("Should verify the group duplication feature", () => {
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]", "");
cy.visit(`${workspaceSlug}`);
roleBasedOnboarding(data.firstName, data.email, "builder"); roleBasedOnboarding(data.firstName, data.email, "builder");
cy.apiLogout(); cy.apiLogout();
cy.defaultWorkspaceLogin(); cy.apiLogin();
cy.visit(`${workspaceSlug}`);
navigateToManageGroups(); navigateToManageGroups();
verifyGroupCardOptions("Admin"); verifyGroupCardOptions("Admin");
cy.wait(3000); cy.wait(3000);
@ -105,15 +115,19 @@ describe("Groups duplication", () => {
cy.apiLogout(); cy.apiLogout();
cy.apiLogin(data.email, "password"); cy.apiLogin(data.email, "password");
cy.visit("/my-workspace"); cy.visit(`${workspaceSlug}`);
cy.wait(2000);
cy.get(commonSelectors.appCreateButton).should("be.visible"); cy.get(commonSelectors.appCreateButton).should("be.visible");
cy.get(commonSelectors.createNewFolderButton).should("be.visible"); cy.get(commonSelectors.createNewFolderButton).should("be.visible");
cy.wait(2000);
cy.reload();
viewAppCardOptions(data.appName); viewAppCardOptions(data.appName);
cy.contains("Delete app").should("exist"); cy.contains("Delete app").should("exist");
cy.get(commonSelectors.workspaceConstantsIcon).should("be.visible"); cy.get(commonSelectors.workspaceConstantsIcon).should("be.visible");
cy.apiLogout(); cy.apiLogout();
cy.defaultWorkspaceLogin(); cy.apiLogin();
cy.visit(`${workspaceSlug}`);
navigateToManageGroups(); navigateToManageGroups();
OpenGroupCardOption(`${data.groupName}_copy`); OpenGroupCardOption(`${data.groupName}_copy`);
cy.get(groupsSelector.deleteGroupOption).click(); cy.get(groupsSelector.deleteGroupOption).click();
@ -121,7 +135,7 @@ describe("Groups duplication", () => {
cy.apiLogout(); cy.apiLogout();
cy.apiLogin(data.email, "password"); cy.apiLogin(data.email, "password");
cy.visit("/my-workspace"); cy.visit(`${workspaceSlug}`);
cy.get(commonSelectors.appCreateButton).should("not.exist"); cy.get(commonSelectors.appCreateButton).should("not.exist");
cy.get(commonSelectors.createNewFolderButton).should("not.exist"); cy.get(commonSelectors.createNewFolderButton).should("not.exist");
cy.get(commonSelectors.workspaceConstantsIcon).should("not.exist"); cy.get(commonSelectors.workspaceConstantsIcon).should("not.exist");

View file

@ -124,7 +124,8 @@ describe("Workspace constants", () => {
//verify global constant is resolved in static query url //verify global constant is resolved in static query url
cy.get('[data-cy="list-query-restapistaticg"]').click(); cy.get('[data-cy="list-query-restapistaticg"]').click();
cy.get('.rest-api-methods-select-element-container .codehinter-container').click(); cy.get('.rest-api-methods-select-element-container .codehinter-container').eq(0).click();
cy.wait(500)
cy.get('.text-secondary').should('have.text', Cypress.env("constants_host")); cy.get('.text-secondary').should('have.text', Cypress.env("constants_host"));
//Verify global constant is resolved in static query preview //Verify global constant is resolved in static query preview

View file

@ -200,7 +200,7 @@ describe("user invite flow cases", () => {
}); });
}); });
it.skip("Should verify the user onboarding with groups", () => { it("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]", "");

View file

@ -58,7 +58,8 @@ describe("inviteflow edge cases", () => {
cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast); cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast);
logout(); logout();
cy.defaultWorkspaceLogin(); cy.apiLogin();
cy.visit(workspaceName);
navigateToManageUsers(); navigateToManageUsers();
searchUser(data.email); searchUser(data.email);
cy.contains("td", data.email) cy.contains("td", data.email)

View file

@ -8,7 +8,7 @@ import { importText } from "Texts/exportImport";
describe("App creation", () => { describe("App creation", () => {
const data = {}; const data = {};
const appFile = "cypress/fixtures/templates/test-app.json"; const appFile = "cypress/fixtures/templates/one_version.json";
beforeEach(() => { beforeEach(() => {
cy.defaultWorkspaceLogin(); cy.defaultWorkspaceLogin();
@ -200,7 +200,7 @@ describe("App creation", () => {
force: true, force: true,
}); });
cy.get(commonSelectors.importAppTitle).verifyVisibleElement( cy.get(importSelectors.importAppTitle).verifyVisibleElement(
"have.text", "have.text",
"Import app" "Import app"
); );
@ -210,7 +210,7 @@ describe("App creation", () => {
); );
cy.get(commonSelectors.appNameInput).verifyVisibleElement( cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"have.value", "have.value",
"test-app" "one_version"
); );
cy.get(commonSelectors.appNameInfoLabel).verifyVisibleElement( cy.get(commonSelectors.appNameInfoLabel).verifyVisibleElement(
"have.text", "have.text",
@ -236,7 +236,7 @@ describe("App creation", () => {
}); });
cy.get(commonSelectors.appNameInput).verifyVisibleElement( cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"have.value", "have.value",
"test-app" "one_version"
); );
cy.clearAndType(commonSelectors.appNameInput, data.appName); cy.clearAndType(commonSelectors.appNameInput, data.appName);
cy.get(commonSelectors.cancelButton).click(); cy.get(commonSelectors.cancelButton).click();
@ -247,7 +247,7 @@ describe("App creation", () => {
}); });
cy.get(commonSelectors.appNameInput).verifyVisibleElement( cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"have.value", "have.value",
"test-app" "one_version"
); );
cy.clearAndType(commonSelectors.appNameInput, data.appName); cy.clearAndType(commonSelectors.appNameInput, data.appName);
cy.get(commonSelectors.importAppButton).should("be.enabled").click(); cy.get(commonSelectors.importAppButton).should("be.enabled").click();

View file

@ -2,7 +2,6 @@ import { fake } from "Fixtures/fake";
import { import {
createFolder, createFolder,
deleteFolder, deleteFolder,
deleteDownloadsFolder,
navigateToAppEditor, navigateToAppEditor,
viewAppCardOptions, viewAppCardOptions,
verifyModal, verifyModal,
@ -14,49 +13,38 @@ import {
} from "Support/utils/common"; } from "Support/utils/common";
import { import {
modifyAndVerifyAppCardIcon, modifyAndVerifyAppCardIcon,
login,
verifyAppDelete, verifyAppDelete,
} from "Support/utils/dashboard"; } from "Support/utils/dashboard";
import { profileSelector } from "Selectors/profile";
import { profileText } from "Texts/profile";
import { commonSelectors } from "Selectors/common"; import { commonSelectors } from "Selectors/common";
import { dashboardSelector } from "Selectors/dashboard"; import { dashboardSelector } from "Selectors/dashboard";
import { commonText } from "Texts/common"; import { commonText } from "Texts/common";
import { dashboardText } from "Texts/dashboard"; import { dashboardText } from "Texts/dashboard";
import { import { logout } from "Support/utils/common";
navigateToManageUsers,
logout,
searchUser,
navigateToManageGroups,
} from "Support/utils/common";
import { roleBasedOnboarding } from "Support/utils/onboarding";
describe("dashboard", () => { describe("dashboard", () => {
const data = {}; let data = {};
data.appName = `${fake.companyName}-App`;
data.folderName = `${fake.companyName.toLowerCase()}-folder`;
data.cloneAppName = `cloned-${data.appName}`;
data.updatedFolderName = `new-${data.folderName}`;
data.firstName = fake.firstName;
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
data.workspaceName = fake.firstName;
data.workspaceSlug = fake.firstName.toLowerCase().replaceAll("[^A-Za-z]", "");
beforeEach(() => { beforeEach(() => {
data = {
appName: `${fake.companyName}-App`,
folderName: `${fake.companyName.toLowerCase()}-folder`,
cloneAppName: `cloned-${fake.companyName}-App`,
updatedFolderName: `new-${fake.companyName.toLowerCase()}-folder`,
workspaceName: fake.firstName,
workspaceSlug: fake.firstName.toLowerCase().replaceAll("[^A-Za-z]", ""),
};
cy.intercept("GET", "/api/library_apps").as("appLibrary"); cy.intercept("GET", "/api/library_apps").as("appLibrary");
cy.intercept("DELETE", "/api/folders/*").as("folderDeleted"); cy.intercept("DELETE", "/api/folders/*").as("folderDeleted");
cy.skipWalkthrough(); cy.skipWalkthrough();
cy.apiLogin();
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
cy.apiLogout();
cy.apiLogin();
cy.visit(`${data.workspaceSlug}`);
}); });
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=&type=front-end", {
fixture: "intercept/emptyDashboard.json",
}).as("emptyDashboard");
cy.intercept("GET", "/api/folder-apps?searchKey=&type=front-end", {
body: { folders: [] },
}).as("folders");
cy.intercept("GET", "/api/metadata", { cy.intercept("GET", "/api/metadata", {
body: { body: {
installed_version: "2.9.2", installed_version: "2.9.2",
@ -64,15 +52,10 @@ describe("dashboard", () => {
}, },
}).as("version"); }).as("version");
cy.defaultWorkspaceLogin();
cy.wait("@emptyDashboard");
cy.wait("@folders");
cy.wait("@version");
cy.get(commonSelectors.homePageLogo).should("be.visible"); cy.get(commonSelectors.homePageLogo).should("be.visible");
cy.get(commonSelectors.workspaceName).verifyVisibleElement( cy.get(commonSelectors.workspaceName).verifyVisibleElement(
"have.text", "have.text",
"My workspace" data.workspaceName
); );
cy.get(commonSelectors.workspaceName).click(); cy.get(commonSelectors.workspaceName).click();
// cy.get(commonSelectors.editRectangleIcon).should("be.visible"); // cy.get(commonSelectors.editRectangleIcon).should("be.visible");
@ -188,12 +171,12 @@ describe("dashboard", () => {
verifyTooltip(dashboardSelector.modeToggle, "Mode"); verifyTooltip(dashboardSelector.modeToggle, "Mode");
}); });
it("Should verify app card elements and app card operations", () => { it.skip("Should verify app card elements and app card operations", () => {
const customLayout = { const customLayout = {
desktop: { top: 100, left: 20 }, desktop: { top: 100, left: 20 },
mobile: { width: 8, height: 50 }, mobile: { width: 8, height: 50 },
}; };
cy.apiLogin();
cy.apiCreateApp(data.appName); cy.apiCreateApp(data.appName);
cy.openApp(); cy.openApp();
cy.apiAddComponentToApp(data.appName, "text1", customLayout); cy.apiAddComponentToApp(data.appName, "text1", customLayout);
@ -276,6 +259,7 @@ describe("dashboard", () => {
cancelModal(commonText.cancelButton); cancelModal(commonText.cancelButton);
cy.wait(3000);
viewAppCardOptions(data.appName); viewAppCardOptions(data.appName);
cy.get( cy.get(
commonSelectors.appCardOptions(commonText.removeFromFolderOption) commonSelectors.appCardOptions(commonText.removeFromFolderOption)
@ -296,6 +280,7 @@ describe("dashboard", () => {
cy.get(commonSelectors.allApplicationsLink).click(); cy.get(commonSelectors.allApplicationsLink).click();
cy.wait(3000);
viewAppCardOptions(data.appName); viewAppCardOptions(data.appName);
cy.get(commonSelectors.appCardOptions(commonText.cloneAppOption)).click(); cy.get(commonSelectors.appCardOptions(commonText.cloneAppOption)).click();
cy.get('[data-cy="clone-app"]').click(); cy.get('[data-cy="clone-app"]').click();
@ -312,7 +297,10 @@ describe("dashboard", () => {
cy.get(commonSelectors.appCard(data.cloneAppName)).should("be.visible"); cy.get(commonSelectors.appCard(data.cloneAppName)).should("be.visible");
cy.wait(3000) cy.get(commonSelectors.globalDataSourceIcon).click();
cy.get(commonSelectors.dashboardIcon).click();
cy.wait(3000);
cy.reloadAppForTheElement(data.cloneAppName);
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();
@ -322,6 +310,7 @@ describe("dashboard", () => {
expect(downloadedAppExportFileName).to.contain.string("app"); expect(downloadedAppExportFileName).to.contain.string("app");
}); });
cy.wait(3000);
cy.reloadAppForTheElement(data.cloneAppName); cy.reloadAppForTheElement(data.cloneAppName);
viewAppCardOptions(data.cloneAppName); viewAppCardOptions(data.cloneAppName);
cy.get(commonSelectors.deleteAppOption).click(); cy.get(commonSelectors.deleteAppOption).click();
@ -337,6 +326,7 @@ describe("dashboard", () => {
).verifyVisibleElement("have.text", commonText.modalYesButton); ).verifyVisibleElement("have.text", commonText.modalYesButton);
cancelModal(commonText.cancelButton); cancelModal(commonText.cancelButton);
cy.wait(3000);
cy.reloadAppForTheElement(data.cloneAppName); cy.reloadAppForTheElement(data.cloneAppName);
viewAppCardOptions(data.cloneAppName); viewAppCardOptions(data.cloneAppName);
cy.get(commonSelectors.deleteAppOption).click(); cy.get(commonSelectors.deleteAppOption).click();
@ -362,9 +352,6 @@ describe("dashboard", () => {
mobile: { width: 8, height: 50 }, mobile: { width: 8, height: 50 },
}; };
cy.skipWalkthrough();
data.appName = `${fake.companyName}-App`;
cy.defaultWorkspaceLogin();
cy.createApp(data.appName); cy.createApp(data.appName);
cy.apiAddComponentToApp(data.appName, "text1", customLayout); cy.apiAddComponentToApp(data.appName, "text1", customLayout);
@ -395,12 +382,8 @@ describe("dashboard", () => {
mobile: { width: 8, height: 50 }, mobile: { width: 8, height: 50 },
}; };
data.appName = `${fake.companyName}-App`;
cy.defaultWorkspaceLogin();
cy.createApp(data.appName); cy.createApp(data.appName);
cy.apiAddComponentToApp(data.appName, "text1", customLayout); cy.apiAddComponentToApp(data.appName, "text1", customLayout);
cy.backToApps(); cy.backToApps();
cy.get(commonSelectors.createNewFolderButton).click(); cy.get(commonSelectors.createNewFolderButton).click();
@ -517,13 +500,4 @@ describe("dashboard", () => {
verifyAppDelete(data.appName); verifyAppDelete(data.appName);
logout(); logout();
}); });
it("should verify the elements on empty dashboard for end user", () => {
cy.defaultWorkspaceLogin();
cy.intercept("GET", "/api/apps?page=1&folder=&searchKey=&type=front-end", {
fixture: "intercept/emptyDashboard.json",
}).as("emptyDashboard")
roleBasedOnboarding(data.firstName, data.email, "end-user");
cy.get(commonSelectors.dashboardAppCreateButton).should("be.disabled");
});
}); });

View file

@ -522,10 +522,8 @@ describe("Manage Groups", () => {
commonSelectors.buttonSelector(exportAppModalText.exportSelectedVersion) commonSelectors.buttonSelector(exportAppModalText.exportSelectedVersion)
).click(); ).click();
cy.exec("ls ./cypress/downloads/").then((result) => { cy.exec("ls ./cypress/downloads/").then((result) => {
cy.log(result);
const downloadedAppExportFileName = result.stdout.split("\n")[0]; const downloadedAppExportFileName = result.stdout.split("\n")[0];
exportedFilePath = `cypress/downloads/${downloadedAppExportFileName}`; exportedFilePath = `cypress/downloads/${downloadedAppExportFileName}`;
cy.log(exportedFilePath);
cy.get(importSelectors.dropDownMenu).should("be.visible").click(); cy.get(importSelectors.dropDownMenu).should("be.visible").click();
cy.get(importSelectors.importOptionInput).selectFile(exportedFilePath, { cy.get(importSelectors.importOptionInput).selectFile(exportedFilePath, {
force: true, force: true,

View file

@ -0,0 +1,382 @@
import { fake } from "Fixtures/fake";
import {
createUser, getAllUsers, getUser, updateUser, createGroup, validateUserInGroup, updateUserRole,
getAllWorkspaces, replaceUserWorkspace, replaceUserWorkspacesRelations
} from 'Support/utils/api';
import { groupsSelector } from "Selectors/manageGroups";
import { commonSelectors } from 'Selectors/common';
import { searchUser, navigateToManageUsers, logout, navigateToManageGroups } from 'Support/utils/common';
describe("API Test", () => {
const sanitize = (str) => str.toLowerCase().replace(/[^A-Za-z]/g, "");
let userId;
let workspaceId;
const data = {
firstName: fake.firstName,
lastName: fake.lastName,
firstName1: fake.firstName,
lastName1: fake.lastName,
firstName2: fake.firstName,
lastName2: fake.lastName,
email: fake.email.toLowerCase().replaceAll("[^A-Za-z]", ""),
email1: fake.email.toLowerCase().replaceAll("[^A-Za-z]", ""),
email2: fake.email.toLowerCase().replaceAll("[^A-Za-z]", ""),
workspaceName: sanitize(fake.lastName),
workspaceSlug: sanitize(fake.lastName),
workspaceName1: sanitize(fake.firstName),
workspaceSlug1: sanitize(fake.firstName),
group1: sanitize(fake.firstName),
group2: sanitize(fake.firstName),
group3: sanitize(fake.firstName),
group4: sanitize(fake.firstName),
group5: sanitize(fake.firstName),
appName: fake.companyName
};
//user with all valid details
const userData = {
name: `${data.firstName} ${data.lastName}`,
email: data.email,
password: "password",
status: "active",
workspaces: [
{
name: "My workspace",
status: "active",
groups: [
{ name: data.group1 },
{ name: data.group2 }
]
},
{
name: data.workspaceName,
status: "active",
role: "builder",
groups: [{ name: data.group3 }]
},
{
name: data.workspaceName1,
status: "archived",
role: "admin",
groups: [{ name: data.group4 }]
}
]
};
beforeEach(() => {
cy.defaultWorkspaceLogin();
});
it("Create user with valid details", () => {
// create multiple groups in different workspaces
navigateToManageGroups();
[data.group1, data.group2, data.group5].forEach(createGroup);
//builder group
cy.get(groupsSelector.groupLink(data.group5)).click();
cy.get(groupsSelector.permissionsLink).click();
cy.get(groupsSelector.appsCreateCheck).check();
[
{ name: data.workspaceName, slug: data.workspaceSlug, group: data.group3 },
{ name: data.workspaceName1, slug: data.workspaceSlug1, group: data.group4 }
].forEach(({ name, slug, group }) => {
cy.apiCreateWorkspace(name, slug);
cy.visit(slug);
navigateToManageGroups();
createGroup(group);
});
// Added valid user and logged-in in the workpsace
cy.visit("/my-workspace");
cy.wait(500);
createUser(userData).then((response) => {
expect(response.status).to.eq(201);
userId = response.body.id;
workspaceId = response.body.workspaces[0].id;
navigateToManageUsers();
searchUser(data.email);
cy.contains("td", data.email)
.parent()
.within(() => {
cy.get("td small").should("have.text", "active");
});
validateUserInGroup(data.email, "my-workspace", "end-user");
validateUserInGroup(data.email, data.workspaceSlug, "builder");
validateUserInGroup(data.email, data.workspaceSlug1, "admin", false);
cy.apiLogout();
cy.apiLogin(data.email, "password");
cy.visit("/my-workspace");
cy.get(commonSelectors.workspaceName).should("have.text", "My workspace");
logout();
//Retrieve all users, a specific user by ID, and all workspaces
cy.defaultWorkspaceLogin();
navigateToManageUsers();
let number = 0;
cy.get('[data-cy="title-users-page"]').invoke('text').then((text) => {
number = parseInt(text.match(/\d+/)[0], 10);
});
getAllUsers().then((response) => {
expect(response.status).to.eq(200);
//expect(response.body.length).to.eq(number); //error due to removal of user from instance
});
getUser(userId).then((response) => {
expect(response.status).to.eq(200);
expect(response.body.name).to.eq(`${data.firstName} ${data.lastName}`);
});
getAllWorkspaces().then((response) => {
expect(response.status).to.eq(200);
});
});
});
it('Handles user creation errors', () => {
const invalidUserData = [
{ // Duplicate user
data: { ...userData },
expectedStatus: 422,
expectedMessage: 'Already exists!'
},
{ // Invalid email and long password
data: {
...userData,
name: `${data.firstName1} ${data.lastName1}`,
email: 'invalid-email',
password: 'a'.repeat(101)
},
expectedStatus: 400,
expectedMessages: ['email must be an email', 'password must be shorter than or equal to 100 characters']
},
{ // Non-existing group
data: {
...userData,
name: `${data.firstName1} ${data.lastName1}`,
email: `${data.email1}`,
workspaces: [{ name: 'My workspace', status: 'active', groups: [{ name: 'NonExistingGroup' }] }]
},
expectedStatus: 400,
expectedMessage: 'Group permission id or name not found:'
},
{ // Non-existing workspace
data: {
...userData,
name: `${data.firstName1} ${data.lastName1}`,
email: `${data.email1}`,
workspaces: [{ name: 'NonExistingWorkspace', status: 'active' }]
},
expectedStatus: 400,
expectedMessage: 'The workspaces id or name do not exist:'
}
];
invalidUserData.forEach(({ data, expectedStatus, expectedMessages, expectedMessage }) => {
createUser(data).then((response) => {
expect(response.status).to.eq(expectedStatus);
if (expectedMessages) {
expectedMessages.forEach(msg => expect(response.body.message).to.include(msg));
} else {
expect(response.body.message).to.include(expectedMessage);
}
});
});
//Conflict permission
const enduserData = {
...userData,
name: `${data.firstName1} ${data.lastName1}`,
email: `${data.email1}`,
workspaces: [{ name: 'My workspace', status: 'active', groups: [{ name: data.group5 }] }]
}
createUser(enduserData).then((response) => {
expect(response.status).to.eq(400);
expect(response.body.message.title).to.include("Conflicting permissions");
})
});
it("Update user details and workspaces relations", () => {
const updatedUserData = {
name: `${data.firstName1} ${data.lastName1}`,
email: data.email1,
password: "updatedpassword"
}
updateUser(userId, updatedUserData).then((response) => {
expect(response.status).to.eq(200);
})
cy.apiLogout();
cy.apiLogin(updatedUserData.email, updatedUserData.password);
cy.apiLogout();
// Replace user workspaces relations
cy.apiLogin();
validateUserInGroup(updatedUserData.email, "my-workspace", data.group2);
validateUserInGroup(updatedUserData.email, data.workspaceSlug, data.group3);
cy.visit(data.workspaceSlug1);
navigateToManageUsers();
searchUser(updatedUserData.email);
cy.contains("td", updatedUserData.email);
replaceUserWorkspacesRelations(userId, [
{ name: "My workspace", status: "active", role: "end-user", groups: [{ name: data.group1 }] },
{ name: data.workspaceName, status: "active", role: "builder", groups: [] }
]).then((response) => {
expect(response.status).to.eq(200);
});
navigateToManageUsers();
validateUserInGroup(updatedUserData.email, "my-workspace", data.group2, false);
validateUserInGroup(updatedUserData.email, data.workspaceSlug, data.group3, false);
cy.visit(data.workspaceSlug1);
navigateToManageUsers();
searchUser(updatedUserData.email);
cy.get('[data-cy="text-no-result-found"]').contains("No result found");
replaceUserWorkspacesRelations(userId, []).then((response) => {
expect(response.status).to.eq(200);
});
cy.visit("my-workspace");
navigateToManageUsers();
searchUser(updatedUserData.email);
cy.get('[data-cy="text-no-result-found"]').contains("No result found");
});
it("update user role", () => {
const userData2 = {
name: `${data.firstName} ${data.lastName}`,
email: data.email,
password: "password",
status: "active",
workspaces: [
{
name: "My workspace",
status: "active"
}
]
}
let userId1;
let workspaceId1;
createUser(userData2).then((response) => {
expect(response.status).to.eq(201);
userId1 = response.body.id;
workspaceId1 = response.body.workspaces[0].id;
//update role to builder and validate user in builder's group
updateUserRole(workspaceId1, { newRole: "builder", userId: userId1 })
.then((response) => {
expect(response.status).to.eq(200);
});
validateUserInGroup(userData2.email, "my-workspace", "builder");
//update role to end-user and validate user is removed from builder's group
updateUserRole(workspaceId1, { newRole: "end-user", userId: userId1 })
.then((response) => {
expect(response.status).to.eq(200);
});
validateUserInGroup(userData2.email, "my-workspace", data.group5, false);
// update role to builders and validate app's owner role can't be updated
updateUserRole(workspaceId1, { newRole: "builder", userId: userId1 })
.then((response) => {
expect(response.status).to.eq(200);
});
cy.apiLogout();
cy.apiLogin(userData2.email, userData2.password);
cy.apiCreateApp(data.appName);
cy.apiLogout();
cy.defaultWorkspaceLogin();
updateUserRole(workspaceId1, { newRole: "end-user", userId: userId1 })
.then((response) => {
expect(response.status).to.eq(400);
expect(response.body.message.title).to.include("Can not change user role");
});
});
});
const userData3 = {
name: `${data.firstName2} ${data.lastName2}`,
email: data.email2,
password: "password",
status: "active",
workspaces: [
{
name: "My workspace",
status: "active",
groups: [
{ name: data.group1 },
{ name: data.group2 }
]
},
{
name: data.workspaceName,
status: "active",
role: "builder",
groups: [{ name: data.group3 }]
},
{
name: data.workspaceName1,
status: "archived",
role: "admin",
groups: [{ name: data.group4 }]
}
]
};
it("Replace user workspace", () => {
let userId1, workspaceId1;
createUser(userData3).then((response) => {
expect(response.status).to.eq(201);
userId1 = response.body.id;
workspaceId1 = response.body.workspaces[0].id;
// Helper function to replace user workspace and validate response
const replaceAndValidate = (payload, expectedStatus = 200) => {
return replaceUserWorkspace(userId1, workspaceId1, payload).then((response) => {
expect(response.status).to.eq(expectedStatus);
});
};
// No change if empty request body
replaceAndValidate({}).then(() => {
validateUserInGroup(userData3.email, "my-workspace", data.group1);
validateUserInGroup(userData3.email, "my-workspace", data.group2);
});
// Archive the user and verify status
replaceAndValidate({ status: "archived" }).then(() => {
navigateToManageUsers();
searchUser(userData3.email);
cy.contains("td", userData3.email)
.parent()
.within(() => {
cy.get("td small").should("have.text", "archived");
});
});
// Reactivate user and validate groups
replaceAndValidate({ status: "active" }).then(() => {
validateUserInGroup(userData3.email, "my-workspace", data.group1);
validateUserInGroup(userData3.email, "my-workspace", data.group2);
});
// Update groups and validate removal
replaceAndValidate({ groups: [{ name: data.group1 }] }).then(() => {
validateUserInGroup(userData3.email, "my-workspace", data.group2, false);
});
//Empty group array, user removed from groups
replaceAndValidate({ groups: [] }).then(() => {
validateUserInGroup(userData3.email, "my-workspace", data.group1, false);
});
//Conflict permission
replaceAndValidate({ groups: [{ name: data.group5 }] }, 400);
//Add user in groups and validate
replaceAndValidate({ groups: [{ name: data.group1 }, { name: data.group2 }] });
validateUserInGroup(userData3.email, "my-workspace", data.group1);
validateUserInGroup(userData3.email, "my-workspace", data.group2);
});
});
});

View file

@ -0,0 +1,160 @@
import { importApp, exportApp, allAppsDetails } from 'Support/utils/api';
import { fake } from "Fixtures/fake";
describe("Export and Import API ", () => {
const sanitize = (str) => str.toLowerCase().replace(/[^A-Za-z]/g, "");
const data = {
workspaceName: sanitize(fake.lastName),
workspaceSlug: sanitize(fake.lastName),
}
const fixtureFiles = {
requestData: "templates/import_unnamed_file.json",
requestData2: "templates/import_named_file.json",
requestData3: "templates/three-versions.json",
};
let requestData, requestData2, requestData3;
beforeEach(() => {
cy.defaultWorkspaceLogin();
const fixturePromises = Object.entries(fixtureFiles).map(([key, file]) =>
cy.fixture(file).then((data) => ({ key, data }))
);
// Assign loaded data to respective variables
return Promise.all(fixturePromises).then((results) => {
results.forEach(({ key, data }) => {
({ requestData, requestData2, requestData3 }[key] = data);
});
});
});
it("Import App API", () => {
const workspaceId = Cypress.env("workspaceId");
importApp(workspaceId, requestData).then((response) => {
expect(response.status).to.eq(201);
expect(response.body.message).to.include("App imported successfully into workspace");
});
//Invalid access token and workspace
importApp(workspaceId, requestData, {
Authorization: "Basic xyz",
"Content-Type": "application/json"
}).then((response) => {
expect(response.status).to.eq(403);
});
importApp(workspaceId, requestData, {
Authorization: "",
"Content-Type": "application/json"
}).then((response) => {
expect(response.status).to.eq(403);
});
importApp(`${workspaceId}ee`, requestData).then((response) => {
expect(response.status).to.eq(400);
});
//Import named file
importApp(workspaceId, requestData2).then((response) => {
expect(response.status).to.eq(201);
expect(response.body.message).to.include("App imported successfully into workspace");
});
cy.reload();
cy.get('[data-cy="app_json-title"]').should("exist");
//duplicate app
importApp(workspaceId, requestData2).then((response) => {
expect(response.status).to.eq(409);
expect(response.body.message).to.include("App with app_json already exists in the workspace");
});
cy.deleteApp("app_json");
cy.get('[data-cy="app_json-title"]').should("not.exist");
//Import app in another workpsace
let newWorkspaceId;
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug).then((res) => {
newWorkspaceId = res.body.organization_id;
cy.visit(data.workspaceSlug);
importApp(newWorkspaceId, requestData).then((response) => {
expect(response.status).to.eq(201);
expect(response.body.message).to.include("App imported successfully into workspace");
});
});
});
it("Export App API", () => {
const workspaceId = Cypress.env("workspaceId");
let appId;
importApp(workspaceId, requestData3).then((response) => {
expect(response.status).to.eq(201);
expect(response.body.message).to.include("App imported successfully into workspace");
}).then(() => {
cy.get('[data-cy^="import-export-app"]')
.first()
.find('[data-cy="edit-button"]')
.click({ force: true });
cy.skipWalkthrough();
});
cy.get('[data-cy="left-sidebar-settings-button"]').click();
cy.get('[data-cy="app-slug-input-field"]').invoke('val').then((value) => {
appId = value;
//export last created version
exportApp(workspaceId, appId, "").then((response) => {
expect(response.status).to.eq(201);
expect(response.body.app[0].definition.appV2.appVersions.length).to.eq(1);
expect(response.body.app[0].definition.appV2.appVersions[0].name).to.eq("v3");
});
//export specific versions
exportApp(workspaceId, appId, "?appVersion=v2").then((response) => {
expect(response.status).to.eq(201);
expect(response.body.app[0].definition.appV2.appVersions.length).to.eq(1);
expect(response.body.app[0].definition.appV2.appVersions[0].name).to.eq("v2");
});
//export all versions
exportApp(workspaceId, appId, "?exportAllVersions=true").then((response) => {
expect(response.status).to.eq(201);
expect(response.body.app[0].definition.appV2.appVersions.length).to.eq(3);
});
//Invalid access token and workspace
/* exportApp(workspaceId, appId, "", {
Authorization: "",
"Content-Type": "application/json"
}).then((response) => {
expect(response.status).to.eq(403);
});
exportApp(workspaceId, appId, "", {
Authorization: "",
"Content-Type": "application/json"
}).then((response) => {
expect(response.status).to.eq(403);
});
exportApp(`${workspaceId}ee`, appId, "").then((response) => {
expect(response.status).to.eq(400);
});
*/
//with and without TJDB -x.tooljet_database
exportApp(workspaceId, appId, "?exportTJDB=false").then((response) => {
expect(response.status).to.eq(201);
expect(response.body).not.to.have.property("tooljet_database");
});
exportApp(workspaceId, appId, "?exportTJDB=true").then((response) => {
expect(response.status).to.eq(201);
expect(response.body).to.have.property("tooljet_database");
});
});
//All Apps details
allAppsDetails(workspaceId).then((response) => {
expect(response.status).to.eq(200);
});
});
});

View file

@ -0,0 +1,3 @@
{
"id": "bff6583db942c77249ba"
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2127,7 +2127,7 @@
"encrypted": false "encrypted": false
}, },
"host": { "host": {
"value": "35.202.183.199", "value": "35.238.9.114",
"encrypted": false "encrypted": false
}, },
"port": { "port": {

View file

@ -585,7 +585,7 @@
"encrypted": false "encrypted": false
}, },
"host": { "host": {
"value": "35.202.183.199", "value": "35.238.9.114",
"encrypted": false "encrypted": false
}, },
"port": { "port": {

View file

@ -1701,7 +1701,7 @@
] ]
}, },
"list_rows": {}, "list_rows": {},
"runOnPageLoad": true "runOnPageLoad": false
}, },
"dataSourceId": "f4cf0089-aec2-4713-800e-3560e678220b", "dataSourceId": "f4cf0089-aec2-4713-800e-3560e678220b",
"appVersionId": "b74fcff1-8cf1-40f8-a13d-c2d2a0b1ebf1", "appVersionId": "b74fcff1-8cf1-40f8-a13d-c2d2a0b1ebf1",
@ -1862,7 +1862,7 @@
"encrypted": false "encrypted": false
}, },
"host": { "host": {
"value": "35.202.183.199", "value": "35.238.9.114",
"encrypted": false "encrypted": false
}, },
"port": { "port": {

View file

@ -0,0 +1,72 @@
import { groupsSelector } from "Selectors/manageGroups";
import { navigateToManageGroups } from 'Support/utils/common';
export const apiRequest = (method, url, body = {}, headers = {}) => {
return cy.request({
method,
url,
body,
headers: {
Authorization: Cypress.env('AUTH_TOKEN'),
"Content-Type": "application/json",
...headers,
},
failOnStatusCode: false
});
};
export const createUser = (userData) => {
return apiRequest("POST", `${Cypress.env('API_URL')}/ext/users`, userData);
};
export const getUser = (userId) => {
return apiRequest("GET", `${Cypress.env('API_URL')}/ext/user/${userId}`);
};
export const getAllUsers = () => {
return apiRequest("GET", `${Cypress.env('API_URL')}/ext/users`);
};
export const updateUser = (userId, userData) => {
return apiRequest("PATCH", `${Cypress.env('API_URL')}/ext/user/${userId}`, userData);
};
export const updateUserRole = (workspaceId, userData) => {
return apiRequest("PUT", `${Cypress.env('API_URL')}/ext/update-user-role/workspace/${workspaceId}`, userData);
}
export const replaceUserWorkspace = (userId, workspaceId, userData) => {
return apiRequest("PATCH", `${Cypress.env('API_URL')}/ext/user/${userId}/workspace/${workspaceId}`, userData);
}
export const replaceUserWorkspacesRelations = (userId, userData) => {
return apiRequest("PUT", `${Cypress.env('API_URL')}/ext/user/${userId}/workspaces`, userData);
}
export const getAllWorkspaces = () => {
return apiRequest("GET", `${Cypress.env('API_URL')}/ext/workspaces`);
}
export const importApp = (workspaceId, appData, headers) => {
return apiRequest("POST", `${Cypress.env('API_URL')}/ext/import/workspace/${workspaceId}/apps`, appData, headers);
}
export const exportApp = (workspaceId, appId, endpoint, headers) => {
return apiRequest("POST", `${Cypress.env('API_URL')}/ext/export/workspace/${workspaceId}/apps/${appId}${endpoint}`, headers);
}
export const allAppsDetails = (workspaceIds) => {
return apiRequest("GET", `${Cypress.env('API_URL')}/ext/workspace/${workspaceIds}/apps`);
}
export const createGroup = (groupName) => {
cy.get(groupsSelector.createNewGroupButton).click();
cy.clearAndType(groupsSelector.groupNameInput, groupName);
cy.get(groupsSelector.createGroupButton).click();
}
export const validateUserInGroup = (email, workspaceSlug, groupName, shouldExist = true) => {
if (workspaceSlug) cy.visit(workspaceSlug);
navigateToManageGroups();
cy.get(groupsSelector.groupLink(groupName)).click();
cy.get(groupsSelector.usersLink).click();
const userRow = `[data-cy="${email}-user-row"]`;
cy.get(userRow).should(shouldExist ? "exist" : "not.exist");
};

View file

@ -25,7 +25,10 @@ export const verifySuccessfulSlugUpdate = (workspaceId, slug) => {
"have.text", "have.text",
"Slug accepted!" "Slug accepted!"
); );
cy.get(commonWidgetSelector.appLinkSucessLabel).verifyVisibleElement(
cy.wait(500);
// cy.get(commonWidgetSelector.appLinkSucessLabel).should('be.visible');
cy.get(commonWidgetSelector.appLinkSucessLabel).should(
"have.text", "have.text",
"Link updated successfully!" "Link updated successfully!"
); );

View file

@ -32,10 +32,10 @@ export const deleteComponentAndVerify = (widgetName) => {
.last() .last()
.realClick(); .realClick();
}); });
cy.verifyToastMessage( // cy.verifyToastMessage(
`[class=go3958317564]`, // `[class=go3958317564]`,
"Component deleted! (Ctrl + Z to undo)" // "Component deleted! (Ctrl + Z to undo)"
); // );
cy.notVisible(commonWidgetSelector.draggableWidget(widgetName)); cy.notVisible(commonWidgetSelector.draggableWidget(widgetName));
}; };

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

@ -16,9 +16,7 @@ export const navigateToProfile = () => {
export const logout = () => { export const logout = () => {
cy.get(commonSelectors.settingsIcon).click(); cy.get(commonSelectors.settingsIcon).click();
cy.get(commonSelectors.logoutLink).click(); cy.get(commonSelectors.logoutLink).click();
cy.intercept("GET", "/api/metadata").as("publicConfig"); cy.wait(1000);
cy.wait("@publicConfig");
cy.wait(500);
}; };
export const navigateToManageUsers = () => { export const navigateToManageUsers = () => {
@ -183,10 +181,9 @@ export const manageUsersPagination = (email) => {
export const searchUser = (email) => { export const searchUser = (email) => {
cy.clearAndType(commonSelectors.inputUserSearch, email); cy.clearAndType(commonSelectors.inputUserSearch, email);
cy.wait(1000) cy.wait(1000);
}; };
export const selectAppCardOption = (appName, appCardOption) => { export const selectAppCardOption = (appName, appCardOption) => {
viewAppCardOptions(appName); viewAppCardOptions(appName);
cy.get(appCardOption).should("be.visible").click({ force: true }); cy.get(appCardOption).should("be.visible").click({ force: true });
@ -221,7 +218,6 @@ export const pinInspector = () => {
} }
}); });
cy.hideTooltip(); cy.hideTooltip();
}; };
export const navigateToworkspaceConstants = () => { export const navigateToworkspaceConstants = () => {
@ -243,24 +239,3 @@ export const verifyTooltipDisabled = (selector, message) => {
cy.get(".tooltip-inner").last().should("have.text", message); cy.get(".tooltip-inner").last().should("have.text", message);
}); });
}; };
export const deleteAllGroupChips = () => {
cy.get('body').then(($body) => {
if ($body.find('[data-cy="group-chip"]').length > 0) {
cy.get('[data-cy="group-chip"]').then(($groupChip) => {
if ($groupChip.is(':visible')) {
cy.get('[data-cy="group-chip"]').first().click();
cy.get('[data-cy="delete-button"]').click();
cy.get('[data-cy="yes-button"]').click();
cy.wait(2000);
deleteAllGroupChips(); // Recursive call to delete next chip
} else {
cy.log("Group chip is present but not visible, skipping deletion");
}
});
} else {
cy.log("No group chips left to delete");
}
});
}

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) => {
@ -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);
@ -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"),

View file

@ -34,7 +34,7 @@ export const verifyValue = (node, type, children, index = 0) => {
}; };
export const deleteComponentFromInspector = (node) => { export const deleteComponentFromInspector = (node) => {
cy.get('[data-cy="inspector-node-components"] > .node-key').click(); cy.get('[data-cy="inspector-node-components"] > .node-key').click();
cy.get(`[data-cy="inspector-node-${node}"] > .node-key`).realHover().parent().find('[style="height: 13px; width: 13px;"] > img').click(); cy.get(`[data-cy="inspector-node-${node}"] > .node-key`).realHover().parent().find('[style="height: 13px; width: 13px;"] > img').last().click();
}; };
export const verifyfunctions = (node, type, index = 0) => { export const verifyfunctions = (node, type, index = 0) => {

View file

@ -646,7 +646,7 @@ export const createGroupAddAppAndUserToGroup = (groupName, email) => {
cy.request({ cy.request({
method: "POST", method: "POST",
url: `${Cypress.env("server_host")}/api/v2/group_permissions`, url: `${Cypress.env("server_host")}/api/v2/group-permissions`,
headers: headers, headers: headers,
body: { body: {
name: groupName, name: groupName,
@ -658,14 +658,14 @@ export const createGroupAddAppAndUserToGroup = (groupName, email) => {
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/${groupId}/granular-permissions`,
headers: headers, headers: headers,
body: { body: {
name: "Apps", name: "Apps",
type: "app", type: "app",
groupId: groupId, groupId: groupId,
isAll: false, isAll: false,
createAppsPermissionsObject: { createResourcePermissionObject: {
canEdit: true, canEdit: true,
canView: false, canView: false,
hideFromDashboard: false, hideFromDashboard: false,
@ -676,19 +676,22 @@ export const createGroupAddAppAndUserToGroup = (groupName, email) => {
], ],
}, },
}, },
}).then((response) => { }).then((response) => {
expect(response.status).to.equal(201); expect(response.status).to.equal(201);
}); });
cy.wait(2000);
cy.task("dbConnection", { 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) => {
const userId = resp.rows[0].id; const userId = resp.rows[0].id;
cy.log(userId);
cy.request({ cy.request({
method: "POST", method: "POST",
url: `${Cypress.env("server_host")}/api/v2/group_permissions/group-user`, url: `${Cypress.env("server_host")}/api/v2/group-permissions/${groupId}/users`,
headers: headers, headers: headers,
body: { body: {
userIds: [userId], userIds: [userId],
@ -720,7 +723,7 @@ export const OpenGroupCardOption = (groupName) => {
export const duplicateMultipleGroups = (groupNames) => { export const duplicateMultipleGroups = (groupNames) => {
groupNames.forEach((groupName) => { groupNames.forEach((groupName) => {
OpenGroupCardOption(groupName); OpenGroupCardOption(groupName);
cy.wait(3000); cy.wait(2000);
cy.get(commonSelectors.duplicateOption).click(); // Click on the duplicate option cy.get(commonSelectors.duplicateOption).click(); // Click on the duplicate option
cy.get(commonSelectors.confirmDuplicateButton).click(); // Confirm duplication if needed cy.get(commonSelectors.confirmDuplicateButton).click(); // Confirm duplication if needed
}); });
@ -850,6 +853,9 @@ export const createGroupsAndAddUserInGroup = (groupName, email) => {
commonSelectors.toastMessage, commonSelectors.toastMessage,
groupsText.groupCreatedToast groupsText.groupCreatedToast
); );
addUserInGroup(groupName, email);
};
export const addUserInGroup = (groupName, email) => {
cy.get(groupsSelector.groupLink(groupName)).click(); cy.get(groupsSelector.groupLink(groupName)).click();
cy.clearAndType(groupsSelector.multiSelectSearchInput, email); cy.clearAndType(groupsSelector.multiSelectSearchInput, email);
cy.wait(2000); cy.wait(2000);
@ -859,7 +865,7 @@ export const createGroupsAndAddUserInGroup = (groupName, email) => {
commonSelectors.toastMessage, commonSelectors.toastMessage,
groupsText.userAddedToast groupsText.userAddedToast
); );
}; }
export const inviteUserBasedOnRole = (firstName, email, role = "end-user") => { export const inviteUserBasedOnRole = (firstName, email, role = "end-user") => {
fillUserInviteForm(firstName, email); fillUserInviteForm(firstName, email);

View file

@ -18,7 +18,7 @@ export const generalSettings = () => {
cy.get(ssoSelector.workspaceLoginPage.defaultSSO).click(); cy.get(ssoSelector.workspaceLoginPage.defaultSSO).click();
cy.get(ssoSelector.defaultGoogle).verifyVisibleElement("have.text", "Google"); cy.get(ssoSelector.defaultGoogle).verifyVisibleElement("have.text", "Google");
cy.get(ssoSelector.defaultGithub).verifyVisibleElement("have.text", "Github"); cy.get(ssoSelector.defaultGithub).verifyVisibleElement("have.text", "Git");
cy.clearAndType(ssoSelector.allowedDomainInput, ssoText.allowedDomain); cy.clearAndType(ssoSelector.allowedDomainInput, ssoText.allowedDomain);
cy.get(ssoSelector.saveButton).click(); cy.get(ssoSelector.saveButton).click();
@ -416,7 +416,7 @@ export const resetDomain = () => {
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": Cypress.env("workspaceId"), "Tj-Workspace-Id": Cypress.env("workspaceId"),
Cookie: `tj_auth_token=${cookie.value}`, Cookie: `tj_auth_token=${cookie.value}`,

View file

@ -57,7 +57,7 @@ export const setHomePage = (pageName) => {
export const addNewPage = (pageName) => { export const addNewPage = (pageName) => {
cy.get(multipageSelector.addPageIcon).click(); cy.get(multipageSelector.addPageIcon).click();
cy.get(".col-12 > .form-control").type(`{selectAll}{backspace}${pageName}`); cy.get('[role="button"] > div > .form-control').type(`{selectAll}{backspace}${pageName}`);
cy.get(multipageSelector.addPageIcon).click(); cy.get(multipageSelector.addPageIcon).click();
cy.get(`[data-cy="pages-name-${pageName.toLowerCase()}"]`).click(); cy.get(`[data-cy="pages-name-${pageName.toLowerCase()}"]`).click();
}; };

View file

@ -47,6 +47,8 @@ export const waitForQueryAction = (action) => {
export const chainQuery = (currentQuery, trigger) => { export const chainQuery = (currentQuery, trigger) => {
cy.get(`[data-cy="list-query-${currentQuery}"]`).click(); cy.get(`[data-cy="list-query-${currentQuery}"]`).click();
cy.wait(1000);
cy.get('[data-cy="query-tab-settings"]').click();
selectEvent("Query Success", "Run Query"); selectEvent("Query Success", "Run Query");
cy.get('[data-cy="query-selection-field"]') cy.get('[data-cy="query-selection-field"]')
.click() .click()
@ -55,8 +57,16 @@ export const chainQuery = (currentQuery, trigger) => {
}; };
export const addSuccessNotification = (notification) => { export const addSuccessNotification = (notification) => {
changeQueryToggles("notification-on-success"); cy.get('[data-cy="query-tab-settings"]').click();
cy.get('[data-cy="success-message-input-field"]').clearAndTypeOnCodeMirror( cy.get('body').then(($body) => {
notification if (!$body.find('[data-cy="success-message-input-field"]').is(':visible')) {
); changeQueryToggles("notification-on-success");
// cy.get('[data-cy="success-message-input-field"]').then(($input) => {
// cy.wrap($input).clearAndTypeOnCodeMirror(notification);
// });
}
});
cy.get('[data-cy="success-message-input-field"]').clearAndTypeOnCodeMirror(notification);
cy.get('[data-cy="query-tab-setup"]').click();
cy.wait(300);
}; };

View file

@ -0,0 +1,97 @@
export const createAndRunRestAPIQuery = (
queryName,
dsName,
method = "GET",
url = "",
headersList = [],
bodyList = [],
jsonBody = null,
run = true,
urlSuffix = ""
) => {
cy.getCookie("tj_auth_token").then((cookie) => {
const headers = {
"Tj-Workspace-Id": Cypress.env("workspaceId"),
Cookie: `tj_auth_token=${cookie.value}`,
};
cy.request({
method: "GET",
url: `${Cypress.env("server_host")}/api/apps/${Cypress.env("appId")}`,
headers,
}).then((response) => {
const editingVersionId = response.body.editing_version.id;
const data_source_id = Cypress.env(`${dsName}-id`);
const useJsonBody =
["POST", "PATCH", "PUT"].includes(method.toUpperCase()) &&
jsonBody !== null;
const queryOptions = {
method: method.toLowerCase(),
url: url + urlSuffix,
url_params: [["", ""]],
headers: headersList.length ? headersList : [["", ""]],
body: !useJsonBody && bodyList.length ? bodyList : [["", ""]],
json_body: useJsonBody ? jsonBody : null,
body_toggle: useJsonBody,
runOnPageLoad: run,
transformationLanguage: "javascript",
enableTransformation: false,
};
const requestBody = {
app_id: Cypress.env("appId"),
app_version_id: editingVersionId,
name: queryName,
kind: "restapi",
options: queryOptions,
data_source_id,
plugin_id: null,
};
cy.request({
method: "POST",
url: `${Cypress.env("server_host")}/api/data-queries/data-sources/${data_source_id}/versions/${editingVersionId}`,
headers,
body: requestBody,
}).then((createResponse) => {
expect(createResponse.status).to.equal(201);
const queryId = createResponse.body.id;
cy.log("Query created successfully:", queryId);
const createdOptions = createResponse.body.options;
expect(createdOptions.method).to.equal(queryOptions.method);
expect(createdOptions.url).to.equal(queryOptions.url);
expect(createdOptions.headers).to.deep.equal(queryOptions.headers);
if (useJsonBody) {
expect(createdOptions.json_body).to.deep.equal(
queryOptions.json_body
);
expect(createdOptions.body_toggle).to.equal(true);
} else {
expect(createdOptions.body).to.deep.equal(queryOptions.body);
expect(createdOptions.body_toggle).to.equal(false);
}
expect(createdOptions.runOnPageLoad).to.equal(run);
cy.log("Metadata verified successfully");
if (run) {
cy.request({
method: "POST",
url: `${Cypress.env("server_host")}/api/data-queries/${queryId}/run`,
headers,
}).then((runResponse) => {
expect([200, 201]).to.include(runResponse.status);
cy.log("Query executed successfully:", runResponse.body);
if (runResponse.body?.data.id) {
cy.writeFile("cypress/fixtures/restAPI/storedId.json", {
id: runResponse.body.data.id,
});
cy.log("Stored ID:", runResponse.body.data.id);
}
});
}
});
});
});
};

31
docker/ce-entrypoint.sh Executable file
View file

@ -0,0 +1,31 @@
#!/bin/bash
set -e
if [ -f "./.env" ]; then
export $(grep -v '^#' ./.env | xargs -d '\n') || true
fi
if [ -d "./server/dist" ]; then
SETUP_CMD='npm run db:setup:prod'
else
SETUP_CMD='npm run db:setup'
fi
if [ -f "./.env" ]; then
declare $(grep -v '^#' ./.env | xargs)
fi
if [ -z "$DATABASE_URL" ]; then
./server/scripts/wait-for-it.sh $PG_HOST:${PG_PORT:-5432} --strict --timeout=300 -- $SETUP_CMD
else
PG_HOST=$(echo "$DATABASE_URL" | awk -F'[/:@?]' '{print $6}')
PG_PORT=$(echo "$DATABASE_URL" | awk -F'[/:@?]' '{print $7}')
if [ -z "$DATABASE_PORT" ]; then
DATABASE_PORT="5432"
fi
./server/scripts/wait-for-it.sh "$PG_HOST:$PG_PORT" --strict --timeout=300 -- $SETUP_CMD
fi
exec "$@"

View file

@ -70,7 +70,6 @@ COPY --from=builder /app/frontend/build ./app/frontend/build
# copy server build # copy server build
COPY --from=builder /app/server/package.json ./app/server/package.json COPY --from=builder /app/server/package.json ./app/server/package.json
COPY --from=builder /app/server/.version ./app/server/.version COPY --from=builder /app/server/.version ./app/server/.version
COPY --from=builder /app/server/entrypoint.sh ./app/server/entrypoint.sh
COPY --from=builder /app/server/node_modules ./app/server/node_modules COPY --from=builder /app/server/node_modules ./app/server/node_modules
COPY --from=builder /app/server/templates ./app/server/templates COPY --from=builder /app/server/templates ./app/server/templates
COPY --from=builder /app/server/scripts ./app/server/scripts COPY --from=builder /app/server/scripts ./app/server/scripts
@ -78,16 +77,37 @@ COPY --from=builder /app/server/dist ./app/server/dist
WORKDIR /app WORKDIR /app
USER root
RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list
RUN echo "deb http://deb.debian.org/debian"
RUN apt update && apt -y install postgresql-13 postgresql-client-13 supervisor
USER postgres
RUN service postgresql start && \
psql -c "create role tooljet with login superuser password 'postgres';"
USER root
# ENV defaults # ENV defaults
ENV TOOLJET_HOST=http://localhost:80 \ ENV TOOLJET_HOST=http://localhost \
PGRST_HOST=http://localhost:3000 \ NODE_ENV=production \
PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj \
TOOLJET_DB=tooljet_db \
ENABLE_TOOLJET_DB=true \
PORT=80 \
LOCKBOX_MASTER_KEY=replace_with_lockbox_master_key \ LOCKBOX_MASTER_KEY=replace_with_lockbox_master_key \
SECRET_KEY_BASE=replace_with_secret_key_base \ SECRET_KEY_BASE=replace_with_secret_key_base \
ORM_LOGGING=all \ PG_DB=tooljet_production \
PG_USER=tooljet \
PG_PASS=postgres \
PG_HOST=localhost \
ENABLE_TOOLJET_DB=true \
TOOLJET_DB_HOST=localhost \
TOOLJET_DB_USER=tooljet \
TOOLJET_DB_PASS=postgres \
TOOLJET_DB=tooljet_db \
PGRST_HOST=http://localhost:3000 \
PGRST_DB_URI=postgres://tooljet:postgres@localhost/tooljet_db \
PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj \
PGRST_DB_PRE_CONFIG=postgrest.pre_config \
ORM_LOGGING=true \
DEPLOYMENT_PLATFORM=docker:local \
HOME=/home/appuser \
TERM=xterm TERM=xterm
CMD ["/usr/bin/supervisord"] CMD ["/usr/bin/supervisord"]

View file

@ -88,12 +88,13 @@ COPY --from=builder /app/frontend/build ./app/frontend/build
# copy server build # copy server build
COPY --from=builder /app/server/package.json ./app/server/package.json COPY --from=builder /app/server/package.json ./app/server/package.json
COPY --from=builder /app/server/.version ./app/server/.version COPY --from=builder /app/server/.version ./app/server/.version
COPY --from=builder /app/server/entrypoint.sh ./app/server/entrypoint.sh
COPY --from=builder /app/server/node_modules ./app/server/node_modules COPY --from=builder /app/server/node_modules ./app/server/node_modules
COPY --from=builder /app/server/templates ./app/server/templates COPY --from=builder /app/server/templates ./app/server/templates
COPY --from=builder /app/server/scripts ./app/server/scripts COPY --from=builder /app/server/scripts ./app/server/scripts
COPY --from=builder /app/server/dist ./app/server/dist COPY --from=builder /app/server/dist ./app/server/dist
COPY ./docker/ce-entrypoint.sh ./app/server/entrypoint.sh
# Define non-sudo user # Define non-sudo user
RUN useradd --create-home --home-dir /home/appuser appuser \ RUN useradd --create-home --home-dir /home/appuser appuser \
&& chown -R appuser:0 /app \ && chown -R appuser:0 /app \
@ -111,5 +112,4 @@ WORKDIR /app
# Dependencies for scripts outside nestjs # Dependencies for scripts outside nestjs
RUN npm install dotenv@10.0.0 joi@17.4.1 RUN npm install dotenv@10.0.0 joi@17.4.1
ENTRYPOINT ["./server/entrypoint.sh"] ENTRYPOINT ["./server/entrypoint.sh"]

View file

@ -99,7 +99,6 @@ COPY --from=builder /app/frontend/build ./app/frontend/build
COPY --from=builder /app/server/package.json ./app/server/package.json COPY --from=builder /app/server/package.json ./app/server/package.json
COPY --from=builder /app/server/.version ./app/server/.version COPY --from=builder /app/server/.version ./app/server/.version
COPY --from=builder /app/server/ee/keys ./app/server/ee/keys COPY --from=builder /app/server/ee/keys ./app/server/ee/keys
COPY --from=builder /app/server/entrypoint.sh ./app/server/entrypoint.sh
COPY --from=builder /app/server/node_modules ./app/server/node_modules COPY --from=builder /app/server/node_modules ./app/server/node_modules
COPY --from=builder /app/server/templates ./app/server/templates COPY --from=builder /app/server/templates ./app/server/templates
COPY --from=builder /app/server/scripts ./app/server/scripts COPY --from=builder /app/server/scripts ./app/server/scripts
@ -108,15 +107,37 @@ COPY --from=builder /app/server/dist ./app/server/dist
WORKDIR /app WORKDIR /app
# ENV defaults # ENV defaults
ENV TOOLJET_HOST=http://localhost:80 \ USER root
PGRST_HOST=http://localhost:3000 \ RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj \ RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list
TOOLJET_DB=tooljet_db \ RUN echo "deb http://deb.debian.org/debian"
ENABLE_TOOLJET_DB=true \ RUN apt update && apt -y install postgresql-13 postgresql-client-13 supervisor
PORT=80 \ USER postgres
RUN service postgresql start && \
psql -c "create role tooljet with login superuser password 'postgres';"
USER root
# ENV defaults
ENV TOOLJET_HOST=http://localhost \
NODE_ENV=production \
LOCKBOX_MASTER_KEY=replace_with_lockbox_master_key \ LOCKBOX_MASTER_KEY=replace_with_lockbox_master_key \
SECRET_KEY_BASE=replace_with_secret_key_base \ SECRET_KEY_BASE=replace_with_secret_key_base \
ORM_LOGGING=all \ PG_DB=tooljet_production \
PG_USER=tooljet \
PG_PASS=postgres \
PG_HOST=localhost \
ENABLE_TOOLJET_DB=true \
TOOLJET_DB_HOST=localhost \
TOOLJET_DB_USER=tooljet \
TOOLJET_DB_PASS=postgres \
TOOLJET_DB=tooljet_db \
PGRST_HOST=http://localhost:3000 \
PGRST_DB_URI=postgres://tooljet:postgres@localhost/tooljet_db \
PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj \
PGRST_DB_PRE_CONFIG=postgrest.pre_config \
ORM_LOGGING=true \
DEPLOYMENT_PLATFORM=docker:local \
REDIS_PASS= \
TERM=xterm TERM=xterm
CMD ["/usr/bin/supervisord"] CMD ["/usr/bin/supervisord"]

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