Merge branch 'appbuilder/sprint-12' into fix/codehinter-btns

This commit is contained in:
devanshu052000 2025-05-15 19:01:09 +05:30
commit af97aaaf74
524 changed files with 15028 additions and 21315 deletions

View file

@ -2,8 +2,7 @@ name: Cypress App-Builder
on:
pull_request_target:
types: [labeled, unlabeled, closed]
types: [labeled]
workflow_dispatch:
env:
@ -13,22 +12,20 @@ env:
jobs:
Cypress-App-Builder:
runs-on: ubuntu-22.04
if: |
github.event.action == 'labeled' &&
(
github.event.label.name == 'run-cypress' ||
github.event.label.name == 'run-ce-app-builder' ||
github.event.label.name == 'run-ee-app-builder'
)
contains(github.event.pull_request.labels.*.name, 'run-cypress-app-builder-ce') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-app-builder-ee') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-ce')
strategy:
matrix:
edition: >-
${{
contains(github.event.pull_request.labels.*.name, 'run-cypress-app-builder-ce') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-ce') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-app-builder-ee') && fromJson('["ee"]') ||
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-ee-app-builder') && fromJson('["ee"]') ||
fromJson('[]')
}}
@ -54,20 +51,9 @@ jobs:
git submodule foreach --recursive '
git checkout ${{ env.BRANCH_NAME }} 2>/dev/null || git checkout main'
- name: Set up Docker
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
run: |
npm cache clean --force
@ -76,50 +62,59 @@ jobs:
npm install --prefix frontend
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
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 "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env
echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env
echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env
echo "PG_DB=tooljet_development" >> .env
echo "PG_USER=postgres" >> .env
echo "PG_HOST=localhost" >> .env
echo "PG_PASS=postgres" >> .env
echo "PG_PORT=5432" >> .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_HOST=localhost" >> .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_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
run: |
npm run --prefix server db:create
npm run --prefix server db:reset
npm run --prefix server db:seed
- name: sleep 5
run: sleep 5
- name: Run PostgREST Docker Container
- name: Start services
run: |
sudo docker run -d --name postgrest --network tooljet -p 3001:3000 \
-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 \
postgrest/postgrest:v12.2.0
- 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 &
cd plugins && npm start &
cd server && npm run start:dev &
cd frontend && npm start &
- name: Wait for the server to be ready
run: |
@ -128,6 +123,18 @@ jobs:
sleep 5
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
run: sudo docker logs postgrest
@ -140,7 +147,7 @@ jobs:
dir: "./cypress-tests"
- name: App builder
uses: cypress-io/github-action@v5
uses: cypress-io/github-action@v6
with:
working-directory: ./cypress-tests
config: "baseUrl=http://localhost:8082"
@ -150,105 +157,38 @@ jobs:
uses: actions/upload-artifact@v4
if: always()
with:
name: screenshots
name: screenshots-appbuilder-${{ matrix.edition }}
path: cypress-tests/cypress/screenshots
Cypress-App-builder-Subpath:
runs-on: ubuntu-22.04
# Cypress-App-builder-Subpath:
# runs-on: ubuntu-22.04
# if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
# contains(github.event.pull_request.labels.*.name, 'run-cypress-app-builder-subpath')
if: ${{ github.event.action == 'labeled' && github.event.label.name == 'run-cypress-app-builder-subpath' }}
# steps:
# - name: Checkout
# uses: actions/checkout@v3
# with:
# ref: ${{ github.event.pull_request.head.ref }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
# - name: Create Cypress environment file
# id: create-json
# uses: jsdaniell/create-json@1.1.2
# with:
# name: "cypress.env.json"
# json: ${{ secrets.CYPRESS_SECRETS }}
# dir: "./cypress-tests"
# 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: App Builder subpath
# uses: cypress-io/github-action@v5
# with:
# working-directory: ./cypress-tests
# config: "baseUrl=http://localhost:80/apps/tooljet/"
# config-file: cypress-app-builder.config.js
- 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
id: create-json
uses: jsdaniell/create-json@1.1.2
with:
name: "cypress.env.json"
json: ${{ secrets.CYPRESS_SECRETS }}
dir: "./cypress-tests"
- name: App Builder subpath
uses: cypress-io/github-action@v5
with:
working-directory: ./cypress-tests
config: "baseUrl=http://localhost:80/apps/tooljet/"
config-file: cypress-app-builder.config.js
- name: Capture Screenshots
uses: actions/upload-artifact@v4
if: always()
with:
name: screenshots
path: cypress-tests/cypress/screenshots
# - name: Capture Screenshots
# uses: actions/upload-artifact@v4
# if: always()
# with:
# name: screenshots
# path: cypress-tests/cypress/screenshots

View file

@ -2,7 +2,7 @@ name: Cypress Marketplace
on:
pull_request_target:
types: [labeled, unlabeled, closed]
types: [labeled]
workflow_dispatch:
@ -14,21 +14,19 @@ jobs:
Cypress-Marketplace:
runs-on: ubuntu-22.04
if: |
github.event.action == 'labeled' &&
(
github.event.label.name == 'run-cypress' ||
github.event.label.name == 'run-ce-cypress-marketplace' ||
github.event.label.name == 'run-ee-cypress-marketplace'
)
if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-marketplace-ce') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-marketplace-ee') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-ce')
strategy:
matrix:
edition: >-
${{
contains(github.event.pull_request.labels.*.name, 'run-cypress') && fromJson('["ce", "ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ce-cypress-marketplace') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ee-cypress-marketplace') && fromJson('["ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-ce') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-marketplace-ce') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-marketplace-ee') && fromJson('["ee"]') ||
fromJson('[]')
}}
@ -44,7 +42,7 @@ jobs:
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 create --name mybuilder --platform linux/arm64,linux/amd64
docker buildx use mybuilder
- name: Set DOCKER_CLI_EXPERIMENTAL
@ -67,8 +65,8 @@ jobs:
with:
context: .
file: docker/ce-production.Dockerfile
push: false
tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}
push: true
tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}-ce
platforms: linux/amd64
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
@ -80,8 +78,8 @@ jobs:
with:
context: .
file: docker/ee/ee-production.Dockerfile
push: false
tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}
push: true
tags: tooljet/tj-osv:${{ env.SAFE_BRANCH_NAME }}-ee
platforms: linux/amd64
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
@ -116,10 +114,16 @@ jobs:
- 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: Update docker-compose file
- name: Update docker-compose file for CE
run: |
# 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
run: |
@ -132,6 +136,9 @@ jobs:
- name: Checking containers
run: docker ps -a
- name: Checking containers
run: docker ps -a
- name: docker logs
run: sudo docker logs Tooljet-app
@ -142,15 +149,24 @@ jobs:
sleep 5
done'
- name: Seeding
run: docker exec Tooljet-app npm run db:seed:prod
- 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: Create Cypress environment file
id: create-json
uses: jsdaniell/create-json@1.1.2
with:
name: "cypress.env.json"
json: ${{ secrets.CYPRESS_SECRETS }}
json: ${{ secrets.CYPRESS_SECRETS_MARKETPLACE }}
dir: "./cypress-tests"
- name: Marketplace
@ -170,7 +186,8 @@ jobs:
Cypress-Marketplace-Subpath:
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:
- name: Checkout

View file

@ -2,7 +2,7 @@ name: Cypress Platform
on:
pull_request_target:
types: [labeled, unlabeled, closed]
types: [labeled]
workflow_dispatch:
env:
@ -12,21 +12,19 @@ env:
jobs:
Cypress-Platform:
runs-on: ubuntu-22.04
if: |
github.event.action == 'labeled' &&
(
github.event.label.name == 'run-cypress' ||
github.event.label.name == 'run-ce-cypress-platform' ||
github.event.label.name == 'run-ee-cypress-platform'
)
if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-platform-ce') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-platform-ee') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-ce')
strategy:
matrix:
edition: >-
${{
contains(github.event.pull_request.labels.*.name, 'run-cypress') && fromJson('["ce", "ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ce-cypress-platform') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-ee-cypress-platform') && fromJson('["ee"]') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-ce') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-platform-ce') && fromJson('["ce"]') ||
contains(github.event.pull_request.labels.*.name, 'run-cypress-platform-ee') && fromJson('["ee"]') ||
fromJson('[]')
}}
@ -102,6 +100,10 @@ jobs:
echo "ENABLE_MARKETPLACE_FEATURE=true" >> .env
echo "ENABLE_MARKETPLACE_DEV_MODE=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
run: |

View file

@ -232,3 +232,95 @@ jobs:
# fi
# 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:
# Community Edition
# Community Edition CE
create-ce-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
@ -72,7 +72,7 @@ jobs:
"envVars": [
{
"key": "PG_HOST",
"value": "${{ secrets.RENDER_PG_HOST }}"
"value": "localhost"
},
{
"key": "PG_PORT",
@ -80,11 +80,11 @@ jobs:
},
{
"key": "PG_USER",
"value": "${{ secrets.RENDER_PG_USER }}"
"value": "postgres"
},
{
"key": "PG_PASS",
"value": "${{ secrets.RENDER_PG_PASS }}"
"value": "postgres"
},
{
"key": "PG_DB",
@ -96,15 +96,15 @@ jobs:
},
{
"key": "TOOLJET_DB_HOST",
"value": "${{ secrets.RENDER_PG_HOST }}"
"value": "localhost"
},
{
"key": "TOOLJET_DB_USER",
"value": "${{ secrets.RENDER_PG_USER }}"
"value": "postgres"
},
{
"key": "TOOLJET_DB_PASS",
"value": "${{ secrets.RENDER_PG_PASS }}"
"value": "postgres"
},
{
"key": "TOOLJET_DB_PORT",
@ -116,7 +116,7 @@ jobs:
},
{
"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://postgres:postgres@localhost/${{ env.PR_NUMBER }}-ce-tjdb"
},
{
"key": "PGRST_HOST",
@ -162,25 +162,17 @@ jobs:
"key": "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",
"value": "${{ secrets.MARKETPLACE_BUCKET }}"
}
],
"serviceDetails": {
"disk": null,
"disk": {
"name": "tooljet-ce-pr-${{ env.PR_NUMBER }}-postgresql",
"mountPath": "/var/lib/postgresql/13/main",
"sizeGB": 10
},
"env": "docker",
"envSpecificDetails": {
"dockerCommand": "",
@ -291,35 +283,35 @@ jobs:
console.log(e)
}
- name: Install PostgreSQL client
run: |
sudo apt update
sudo apt install postgresql-client -y
# - name: Install PostgreSQL client
# run: |
# sudo apt update
# sudo apt install postgresql-client -y
- name: Wait after installing PostgreSQL
run: sleep 25
# - name: Wait after installing PostgreSQL
# run: sleep 25
- name: Drop PostgreSQL PR databases
env:
PGHOST: ${{ secrets.RENDER_DS_PG_HOST }}
PGPORT: 5432
PGUSER: ${{ secrets.RENDER_DS_PG_USER }}
PGDATABASE: ${{ env.PR_NUMBER }}-ce
PGTJBDATABASE: ${{ env.PR_NUMBER }}-ce-tjdb
run: |
if PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -lqt | cut -d \| -f 1 | grep -qw $PGDATABASE; then
echo "Database $PGDATABASE exists, deleting..."
PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -d postgres -c "drop database \"$PGDATABASE\" ;"
else
echo "Database $PGDATABASE does not exist."
fi
# - name: Drop PostgreSQL PR databases
# env:
# PGHOST: ${{ secrets.RENDER_DS_PG_HOST }}
# PGPORT: 5432
# PGUSER: ${{ secrets.RENDER_DS_PG_USER }}
# PGDATABASE: ${{ env.PR_NUMBER }}-ce
# PGTJBDATABASE: ${{ env.PR_NUMBER }}-ce-tjdb
# run: |
# if PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -lqt | cut -d \| -f 1 | grep -qw $PGDATABASE; then
# echo "Database $PGDATABASE exists, deleting..."
# PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -d postgres -c "drop database \"$PGDATABASE\" ;"
# else
# echo "Database $PGDATABASE does not exist."
# fi
if PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -lqt | cut -d \| -f 1 | grep -qw $PGTJBDATABASE; then
echo "Database $PGTJBDATABASE exists, deleting..."
PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -d postgres -c "drop database \"$PGTJBDATABASE\" ;"
else
echo "Database $PGTJBDATABASE does not exist."
fi
# if PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -lqt | cut -d \| -f 1 | grep -qw $PGTJBDATABASE; then
# echo "Database $PGTJBDATABASE exists, deleting..."
# PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -d postgres -c "drop database \"$PGTJBDATABASE\" ;"
# else
# echo "Database $PGTJBDATABASE does not exist."
# fi
suspend-ce-review-app:
if: ${{ github.event.action == 'labeled' && github.event.label.name == 'suspend-ce-review-app' }}
@ -329,7 +321,7 @@ jobs:
- name: Suspend service
run: |
export SERVICE_ID=$(curl --request GET \
--url 'https://api.render.com/v1/services?name=ToolJet%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \
--url 'https://api.render.com/v1/services?name=ToolJet%20CE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \
--header 'accept: application/json' \
--header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \
jq -r '.[0].service.id')
@ -361,7 +353,7 @@ jobs:
- name: Resume service
run: |
export SERVICE_ID=$(curl --request GET \
--url 'https://api.render.com/v1/services?name=ToolJet%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \
--url 'https://api.render.com/v1/services?name=ToolJet%20CE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \
--header 'accept: application/json' \
--header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \
jq -r '.[0].service.id')
@ -401,6 +393,39 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Sync repo
uses: actions/checkout@v3
- name: Check if Forked Repository
id: check_repo
run: |
if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then
echo "is_fork=true" >> $GITHUB_ENV
echo "FORKED_OWNER=${{ github.event.pull_request.head.repo.owner.login }}" >> $GITHUB_ENV
else
echo "is_fork=false" >> $GITHUB_ENV
fi
- name: Set Repository URL
run: |
if [[ "$is_fork" == "true" ]]; then
echo "REPO_URL=https://github.com/${FORKED_OWNER}/ToolJet" >> $GITHUB_ENV
else
echo "REPO_URL=https://github.com/ToolJet/ToolJet" >> $GITHUB_ENV
fi
- name: Fetch and Checkout Forked Branch
if: env.is_fork == 'true'
run: |
git fetch origin pull/${{ github.event.number }}/head:${{ env.BRANCH_NAME }}
git checkout ${{ env.BRANCH_NAME }}
- name: Checkout Default Branch
if: env.is_fork == 'false'
uses: actions/checkout@v3
- name: Creating deployment for Enterprise Edition
id: create-ee-deployment
run: |
@ -416,7 +441,7 @@ jobs:
"name": "ToolJet EE PR #${{ env.PR_NUMBER }}",
"notifyOnFail": "default",
"ownerId": "tea-caeo4bj19n072h3dddc0",
"repo": "https://github.com/ToolJet/ToolJet",
"repo": "'"$REPO_URL"'",
"slug": "tooljet-ee-pr-${{ env.PR_NUMBER }}",
"suspended": "not_suspended",
"suspenders": [],
@ -424,7 +449,7 @@ jobs:
"envVars": [
{
"key": "PG_HOST",
"value": "${{ secrets.RENDER_PG_HOST }}"
"value": "localhost"
},
{
"key": "PG_PORT",
@ -432,11 +457,11 @@ jobs:
},
{
"key": "PG_USER",
"value": "${{ secrets.RENDER_PG_USER }}"
"value": "postgres"
},
{
"key": "PG_PASS",
"value": "${{ secrets.RENDER_PG_PASS }}"
"value": "postgres"
},
{
"key": "PG_DB",
@ -448,15 +473,15 @@ jobs:
},
{
"key": "TOOLJET_DB_HOST",
"value": "${{ secrets.RENDER_PG_HOST }}"
"value": "localhost"
},
{
"key": "TOOLJET_DB_USER",
"value": "${{ secrets.RENDER_PG_USER }}"
"value": "postgres"
},
{
"key": "TOOLJET_DB_PASS",
"value": "${{ secrets.RENDER_PG_PASS }}"
"value": "postgres"
},
{
"key": "TOOLJET_DB_PORT",
@ -468,7 +493,7 @@ jobs:
},
{
"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://postgres:postgres@localhost/${{ env.PR_NUMBER }}-ee-tjdb"
},
{
"key": "PGRST_HOST",
@ -548,7 +573,11 @@ jobs:
}
],
"serviceDetails": {
"disk": null,
"disk": {
"name": "tooljet-ee-pr-${{ env.PR_NUMBER }}-postgresql",
"mountPath": "/var/lib/postgresql/13/main",
"sizeGB": 10
},
"env": "docker",
"envSpecificDetails": {
"dockerCommand": "",
@ -561,7 +590,7 @@ jobs:
"port": 80,
"protocol": "TCP"
}],
"plan": "starter",
"plan": "standard",
"pullRequestPreviewsEnabled": "no",
"region": "oregon",
"url": "https://tooljet-ee-pr-${{ env.PR_NUMBER }}.onrender.com"
@ -659,35 +688,35 @@ jobs:
console.log(e)
}
- name: Install PostgreSQL client
run: |
sudo apt update
sudo apt install postgresql-client -y
# - name: Install PostgreSQL client
# run: |
# sudo apt update
# sudo apt install postgresql-client -y
- name: Wait after installing PostgreSQL
run: sleep 25
# - name: Wait after installing PostgreSQL
# run: sleep 25
- name: Drop PostgreSQL PR databases
env:
PGHOST: ${{ secrets.RENDER_DS_PG_HOST }}
PGPORT: 5432
PGUSER: ${{ secrets.RENDER_DS_PG_USER }}
PGDATABASE: ${{ env.PR_NUMBER }}-ee
PGTJBDATABASE: ${{ env.PR_NUMBER }}-ee-tjdb
run: |
if PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -lqt | cut -d \| -f 1 | grep -qw $PGDATABASE; then
echo "Database $PGDATABASE exists, deleting..."
PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -d postgres -c "drop database \"$PGDATABASE\" ;"
else
echo "Database $PGDATABASE does not exist."
fi
# - name: Drop PostgreSQL PR databases
# env:
# PGHOST: ${{ secrets.RENDER_DS_PG_HOST }}
# PGPORT: 5432
# PGUSER: ${{ secrets.RENDER_DS_PG_USER }}
# PGDATABASE: ${{ env.PR_NUMBER }}-ee
# PGTJBDATABASE: ${{ env.PR_NUMBER }}-ee-tjdb
# run: |
# if PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -lqt | cut -d \| -f 1 | grep -qw $PGDATABASE; then
# echo "Database $PGDATABASE exists, deleting..."
# PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -d postgres -c "drop database \"$PGDATABASE\" ;"
# else
# echo "Database $PGDATABASE does not exist."
# fi
if PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -lqt | cut -d \| -f 1 | grep -qw $PGTJBDATABASE; then
echo "Database $PGTJBDATABASE exists, deleting..."
PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -d postgres -c "drop database \"$PGTJBDATABASE\" ;"
else
echo "Database $PGTJBDATABASE does not exist."
fi
# if PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -lqt | cut -d \| -f 1 | grep -qw $PGTJBDATABASE; then
# echo "Database $PGTJBDATABASE exists, deleting..."
# PGPASSWORD=${{ secrets.RENDER_DS_PG_PASS }} psql -h $PGHOST -p $PGPORT -U $PGUSER -d postgres -c "drop database \"$PGTJBDATABASE\" ;"
# else
# echo "Database $PGTJBDATABASE does not exist."
# fi
suspend-ee-review-app:
if: ${{ github.event.action == 'labeled' && github.event.label.name == 'suspend-ee-review-app' }}
@ -697,7 +726,7 @@ jobs:
- name: Suspend service
run: |
export SERVICE_ID=$(curl --request GET \
--url 'https://api.render.com/v1/services?name=ToolJet%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \
--url 'https://api.render.com/v1/services?name=ToolJet%20EE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \
--header 'accept: application/json' \
--header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \
jq -r '.[0].service.id')
@ -729,7 +758,7 @@ jobs:
- name: Resume service
run: |
export SERVICE_ID=$(curl --request GET \
--url 'https://api.render.com/v1/services?name=ToolJet%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \
--url 'https://api.render.com/v1/services?name=ToolJet%20EE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \
--header 'accept: application/json' \
--header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \
jq -r '.[0].service.id')
@ -1124,4 +1153,3 @@ jobs:
# } catch (e) {
# console.log(e)
# }

View file

@ -8,16 +8,16 @@ permissions:
issues: write
jobs:
label-stale-deploys:
label-stale-ce-deploys:
runs-on: ubuntu-latest
permissions:
pull-requests: write
pull-requests: write
steps:
- uses: akshaysasidrn/stale-label-fetch@v1.1
id: stale-label
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
stale-label: 'active-review-app'
stale-label: 'active-ce-review-app'
stale-time: '86400'
type: 'pull_request'
- name: Get stale numbers
@ -40,6 +40,42 @@ jobs:
issue_number: prNumber,
owner: context.repo.owner,
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:
- cron: '30 5 */14 * *'
- cron: '30 5 * * 1'
jobs:
PeriodicVulnerability-CheckOn-frontend-code:

View file

@ -1 +1 @@
3.11.0
3.12.1

View file

@ -19,9 +19,9 @@ module.exports = defineConfig({
trashAssetsBeforeRuns: true,
e2e: {
setupNodeEvents (on, config) {
setupNodeEvents(on, config) {
on("task", {
readPdf (pathToPdf) {
readPdf(pathToPdf) {
return new Promise((resolve) => {
const pdfPath = path.resolve(pathToPdf);
let dataBuffer = fs.readFileSync(pdfPath);
@ -33,7 +33,7 @@ module.exports = defineConfig({
});
on("task", {
readXlsx (filePath) {
readXlsx(filePath) {
return new Promise((resolve, reject) => {
try {
let dataBuffer = fs.readFileSync(filePath);
@ -48,7 +48,7 @@ module.exports = defineConfig({
});
on("task", {
deleteFolder (folderName) {
deleteFolder(folderName) {
return new Promise((resolve, reject) => {
rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => {
if (err) {
@ -62,7 +62,7 @@ module.exports = defineConfig({
});
on("task", {
dbConnection ({ dbconfig, sql }) {
dbConnection({ dbconfig, sql }) {
const client = new pg.Pool(dbconfig);
return client.query(sql);
},
@ -76,8 +76,8 @@ module.exports = defineConfig({
experimentalRunAllSpecs: true,
baseUrl: "http://localhost:8082",
specPattern: [
"cypress/e2e/happyPath/appbuilder/commonTestcases/**/*.cy.js",
"cypress/e2e/happyPath/appbuilder/ceTestcases/**/*.cy.js"
"cypress/e2e/happyPath/appbuilder/commonTestcases/newSuits/**/*.cy.js",
// "cypress/e2e/happyPath/appbuilder/ceTestcases/**/*.cy.js"
],
numTestsKeptInMemory: 1,
redirectionLimit: 7,

View file

@ -97,8 +97,9 @@ module.exports = defineConfig({
baseUrl: environment.baseUrl,
configFile: environment.configFile,
specPattern: [
"cypress/e2e/happyPath/platform/ceTestcases/userFlow/firstUserOnboarding.cy.js",
"cypress/e2e/happyPath/platform/ceTestcases/!(userFlow)/**/*.cy.js",
"cypress/e2e/happyPath/platform/firstUser/firstUserOnboarding.cy.js",
"cypress/e2e/happyPath/platform/ceTestcases/apps/appSlug.cy.js",
"cypress/e2e/happyPath/platform/ceTestcases/**/!(*appSlug).cy.js",
"cypress/e2e/happyPath/platform/commonTestcases/**/*.cy.js",
],
numTestsKeptInMemory: 1,

View file

@ -92,11 +92,7 @@ module.exports = defineConfig({
experimentalModfyObstructiveThirdPartyCode: true,
experimentalRunAllSpecs: true,
baseUrl: "http://localhost:8082",
specPattern: [
"cypress/e2e/happyPath/platform/ceTestcases/userFlow/firstUserOnboarding.cy.js",
"cypress/e2e/happyPath/platform/ceTestcases/!(userFlow)/**/*.cy.js",
"cypress/e2e/happyPath/platform/commonTestcases/**/*.cy.js",
],
specPattern: "cypress/e2e/happyPath/**/*.cy.js",
downloadsFolder: "cypress/downloads",
numTestsKeptInMemory: 0,
redirectionLimit: 10,

View file

@ -52,7 +52,7 @@ Cypress.Commands.add("apiCreateGDS", (url, name, kind, options) => {
log: false;
}
expect(response.status).to.equal(201);
Cypress.env(`${name}-id`, response.body.id);
Cypress.env(`${kind}`, response.body.id);
Cypress.log({
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") => {
cy.window({ log: false }).then((win) => {
win.localStorage.setItem("walkthroughCompleted", "true");
@ -140,14 +164,11 @@ Cypress.Commands.add(
cy.visit(`/${workspaceId}/apps/${appId}/${slug}`);
cy.wait("@getAppData").then((interception) => {
// Assuming the response body is a JSON object
const responseData = interception.response.body;
// Set the response data as an environment variable
Cypress.env("apiResponseData", responseData);
Cypress.env("editingVersionId", responseData.editing_version.id);
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 });
}
@ -171,6 +192,7 @@ Cypress.Commands.add("apiCreateWorkspace", (workspaceName, workspaceSlug) => {
{ log: false }
).then((response) => {
expect(response.status).to.equal(201);
return response;
});
});
});
@ -267,6 +289,7 @@ Cypress.Commands.add("apiAddQuery", (queryName, query, dataQueryId) => {
Cypress.Commands.add(
"apiAddQueryToApp",
(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) => {
const authToken = `tj_auth_token=${cookie.value}`;
const workspaceId = Cypress.env("workspaceId");
@ -286,7 +309,7 @@ Cypress.Commands.add(
cy.request({
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: {
"Content-Type": "application/json",
Cookie: authToken,
@ -627,10 +650,11 @@ Cypress.Commands.add("apiAddDataToTable", (tableName, data) => {
});
Cypress.Commands.add("apiGetDataSourceIdByName", (dataSourceName) => {
const workspaceId = Cypress.env("workspaceId");
cy.getAuthHeaders().then((headers) => {
cy.request({
method: "GET",
url: `${Cypress.env("server_host")}/api/data-sources`,
url: `${Cypress.env("server_host")}/api/data-sources/${workspaceId}`,
headers: headers,
}).then((response) => {
expect(response.status).to.equal(200);
@ -665,7 +689,7 @@ Cypress.Commands.add(
name: dataSourceName,
options: [
{ key: "connection_type", value: "manual", encrypted: false },
{ key: "host", value: "35.202.183.199" },
{ key: "host", value: "9.234.17.31" },
{ key: "port", value: 5432 },
{ key: "database", value: "student" },
{ key: "username", value: "postgres" },

View file

@ -6,6 +6,7 @@ import { passwordInputText } from "Texts/passwordInput";
import { importSelectors } from "Selectors/exportImport";
import { importText } from "Texts/exportImport";
import { onboardingSelectors } from "Selectors/onboarding";
import { selectAppCardOption } from "Support/utils/common";
const API_ENDPOINT =
Cypress.env("environment") === "Community"
@ -15,15 +16,11 @@ const API_ENDPOINT =
Cypress.Commands.add(
"appUILogin",
(email = "dev@tooljet.io", password = "password") => {
cy.visit("/");
cy.wait(1000);
cy.clearAndType(onboardingSelectors.loginEmailInput, email);
cy.clearAndType(onboardingSelectors.loginPasswordInput, password);
cy.get(onboardingSelectors.signInButton).click();
cy.intercept("GET", API_ENDPOINT).as("library_apps");
cy.get(commonSelectors.homePageLogo, { timeout: 10000 });
cy.wait("@library_apps");
cy.wait(2000);
cy.get('[data-cy="main-wrapper"]', { timeout: 10000 }).should("be.visible");
}
);
@ -164,13 +161,15 @@ Cypress.Commands.add(
Cypress.Commands.add("deleteApp", (appName) => {
cy.intercept("DELETE", "/api/apps/*").as("appDeleted");
cy.get(commonSelectors.appCard(appName))
.realHover()
.find(commonSelectors.appCardOptionsButton)
.realHover()
.click();
cy.get(commonSelectors.deleteAppOption).click();
selectAppCardOption(
appName,
commonSelectors.appCardOptions(commonText.deleteAppOption)
);
cy.get(commonSelectors.buttonSelector(commonText.modalYesButton)).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appDeletedToast
);
cy.wait("@appDeleted");
});
@ -398,37 +397,38 @@ Cypress.Commands.add("getPosition", (componentName) => {
});
Cypress.Commands.add("defaultWorkspaceLogin", () => {
cy.apiLogin();
cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"),
sql: `
SELECT id FROM organizations WHERE name = 'My workspace';`,
}).then((resp) => {
const workspaceId = resp.rows[0].id;
cy.visit("/my-workspace");
cy.intercept("GET", API_ENDPOINT).as("library_apps");
cy.get(commonSelectors.homePageLogo, { timeout: 10000 });
cy.wait("@library_apps");
// });
cy.apiLogin(
"dev@tooljet.io",
"password",
workspaceId,
"/my-workspace"
).then(() => {
cy.visit("/");
cy.wait(2000);
cy.get(commonSelectors.homePageLogo, { timeout: 10000 });
});
});
});
Cypress.Commands.add(
"visitSlug",
({
actualUrl,
currentUrl = `${Cypress.config("baseUrl")}/error/unknown`,
}) => {
// Ensure actualUrl is provided
if (!actualUrl) {
throw new Error("actualUrl is required for visitSlug command.");
Cypress.Commands.add("visitSlug", ({ actualUrl }) => {
cy.visit(actualUrl);
cy.wait(1000);
cy.url().then((currentUrl) => {
if (currentUrl !== actualUrl) {
cy.visit(actualUrl);
cy.wait(1000);
}
});
});
cy.visit(actualUrl);
// Dynamically wait for the correct URL or handle navigation errors
cy.url().then((url) => {
if (url === currentUrl) {
cy.log(`Navigation resulted in unexpected URL: ${url}. Retrying...`);
cy.visit(actualUrl);
}
});
}
);
Cypress.Commands.add("releaseApp", () => {
if (Cypress.env("environment") !== "Community") {
@ -514,23 +514,58 @@ Cypress.Commands.overwrite(
}
);
Cypress.Commands.add("installMarketplacePlugin", (pluginName) => {
const MARKETPLACE_URL = `${Cypress.config("baseUrl")}/integrations/marketplace`;
cy.visit(MARKETPLACE_URL);
cy.wait(1000);
cy.get('[data-cy="-list-item"]').eq(0).click();
cy.wait(1000);
cy.get("body").then(($body) => {
if ($body.find(".plugins-card").length === 0) {
cy.log("No plugins found, proceeding to install...");
installPlugin(pluginName);
} else {
cy.get(".plugins-card").then(($cards) => {
const isInstalled = $cards.toArray().some((card) => {
return (
Cypress.$(card)
.find(".font-weight-medium.text-capitalize")
.text()
.trim() === pluginName
);
});
if (isInstalled) {
cy.log(`${pluginName} is already installed. Skipping installation.`);
cy.get(commonSelectors.globalDataSourceIcon).click();
} else {
installPlugin(pluginName);
cy.get(commonSelectors.globalDataSourceIcon).click();
}
});
}
});
function installPlugin (pluginName) {
cy.get('[data-cy="-list-item"]').eq(1).click();
cy.wait(1000);
cy.contains(".plugins-card", pluginName).within(() => {
cy.get(".marketplace-install").click();
cy.wait(1000);
});
}
});
Cypress.Commands.add("verifyElement", (selector, text, eqValue) => {
const element =
eqValue !== undefined ? cy.get(selector).eq(eqValue) : cy.get(selector);
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) => {
cy.task("dbConnection", {
dbconfig: Cypress.env("app_db"),
@ -540,3 +575,33 @@ Cypress.Commands.add("getAppId", (appName) => {
return appId;
});
});
Cypress.Commands.add("uninstallMarketplacePlugin", (pluginName) => {
const MARKETPLACE_URL = `${Cypress.config("baseUrl")}/integrations/marketplace`;
cy.visit(MARKETPLACE_URL);
cy.wait(1000);
cy.get('[data-cy="-list-item"]').eq(0).click();
cy.wait(1000);
cy.get(".plugins-card").each(($card) => {
cy.wrap($card)
.find(".font-weight-medium.text-capitalize")
.invoke("text")
.then((text) => {
if (text.trim() === pluginName) {
cy.wrap($card).find(".link-primary").contains("Remove").click();
cy.wait(1000);
cy.get('[data-cy="delete-plugin-title"]').should("be.visible");
cy.get('[data-cy="yes-button"]').click();
cy.wait(2000);
cy.log(`${pluginName} has been successfully uninstalled.`);
} else {
cy.log(`${pluginName} is not installed. Skipping uninstallation.`);
}
});
});
});

View file

@ -6,7 +6,8 @@ export const commonSelectors = {
toastMessage: ".go3958317564",
oldToastMessage: ".go318386747",
appSlugAccept: '[data-cy="app-slug-accepted-label"]',
newToastMessage: '.drawer-container > [style="position: fixed; z-index: 9999; inset: 16px; pointer-events: none;"] > .go4109123758 > .go2072408551 > .go3958317564',
newToastMessage:
'.drawer-container > [style="position: fixed; z-index: 9999; inset: 16px; pointer-events: none;"] > .go4109123758 > .go2072408551 > .go3958317564',
toastCloseButton: '[data-cy="toast-close-button"]',
editButton: "[data-cy=edit-button]",
workspaceConstantNameInput: '[data-cy="name-input-field"]',
@ -18,7 +19,7 @@ export const commonSelectors = {
appCardOptionsButton: "[data-cy=app-card-menu-icon]",
autoSave: "[data-cy=autosave-indicator]",
nameInputFieldd: "[data-cy=name-input-field]",
valueInputFieldd: '[data-cy=value-input-field]',
valueInputFieldd: "[data-cy=value-input-field]",
skipButton: ".driver-close-btn",
skipInstallationModal: "[data-cy=skip-button]",
homePageLogo: "[data-cy=home-page-logo]",
@ -259,7 +260,7 @@ export const commonSelectors = {
cloneAppTitle: '[data-cy="clone-app-title"]',
cloneAppButton: '[data-cy="clone-app"]',
appNameErrorLabel: '[data-cy="app-name-error-label"]',
importAppTitle: '[data-cy="import-app-title"]',
importAppTitle: '[data-cy="import-an-app"]',
importAppButton: '[data-cy="import-app"]',
chooseFromTemplateButton: '[data-cy="choose-from-template-button"]',
CreateAppFromTemplateButton: '[data-cy="create-new-app-from-template-title"]',
@ -395,7 +396,7 @@ export const commonWidgetSelector = {
modalCloseButton: '[data-cy="modal-close-button"]',
iframeLinkLabel: '[data-cy="iframe-link-label"]',
ifameLinkCopyButton: '[data-cy="iframe-link-copy-button"]',
appSlugLabel: '[data-cy="input-field-label"]',
appSlugLabel: '[data-cy="unique-app-slug-field-label"]',
appSlugInput: '[data-cy="app-slug-input-field"]',
appSlugInfoLabel: '[data-cy="helper-text"]',
appLinkLabel: '[data-cy="app-link-label"]',

View file

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

View file

@ -24,7 +24,7 @@ export const restAPISelector = {
return `[data-cy="${cyParamName(header)}-delete-button-${cyParamName(index)}"]`;
},
addMoreButton: (header) => {
return `[data-cy="${cyParamName(header)}-add-more-button"]`;
return `[data-cy="${cyParamName(header)}-add-button"]`;
},
dropdownLabel: (label) => {
return `[data-cy="${cyParamName(label)}-dropdown-label"]`;

View file

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

View file

@ -4,7 +4,7 @@ export const postgreSqlText = {
allDataSources: () => {
return Cypress.env("marketplace_action")
? "All data sources (44)"
? "All data sources (45)"
: "All data sources (43)";
},
commonlyUsed: "Commonly used (5)",

View file

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

View file

@ -4,7 +4,7 @@ export const workspaceConstantsText = {
secretsConstantInfo: "To resolve a secret workspace constant use {{secrets.access_token}}Read documentation",
emptyStateHeader: "No Workspace constants yet",
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",
addConstatntText: "Add new constant in production ",
constantCreatedToast: (type) => { return `${type} constant created successfully!` },

View file

@ -32,7 +32,7 @@ import {
addSupportCSAData,
} from "Support/utils/events";
describe("Editor- Test Button widget", () => {
describe("Editor- Test Button widget ", () => {
beforeEach(() => {
cy.apiLogin();
cy.apiCreateApp(`${fake.companyName}-button-App`);

View file

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

View file

@ -43,7 +43,7 @@ describe("Editor title", () => {
cy.apiDeleteApp();
});
it("should verify titles", () => {
cy.url().should("include", "/tjs-workspace");
cy.url().should("include", "/tooljets-workspace");
// cy.title().should("eq", "Dashboard | ToolJet");
cy.title().should("eq", "ToolJet");
@ -56,7 +56,7 @@ describe("Editor title", () => {
cy.openInCurrentTab(commonWidgetSelector.previewButton);
cy.url().should("include", `/applications/${Cypress.env("appId")}`);
cy.title().should("eq", `${data.appName} | ToolJet`);
// cy.title().should("eq", `${data.appName} | ToolJet`);
// cy.title().should("eq", `Preview - ${data.appName} | ToolJet`);
cy.go("back");

View file

@ -76,7 +76,7 @@ describe('Button Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Button-App`);
cy.openApp();
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', () => {
@ -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 = [
{ event: "On hover", message: "On hover Event" },
{ event: "On Click", message: "On Click Event" },
@ -110,7 +110,7 @@ describe('Button Component Tests', () => {
verifyTextInputEvents(textInputSelector);
});
it('should verify all the CSA from button', () => {
it.skip('should verify all the CSA from button', () => {
addMultiEventsWithAlert([
{ event: "On hover", message: "On hover 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.openApp();
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', () => {
@ -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 = [
{ event: "On Change", message: "On Change Event" },
];
@ -118,7 +118,7 @@ describe('Checkbox Component Tests', () => {
verifyTextInputEvents(textInputSelector);
});
it('should verify all the CSA from Checkbox', () => {
it.skip('should verify all the CSA from Checkbox', () => {
const events = [
{ event: "On Change", message: "On Change Event" },
];

View file

@ -93,7 +93,7 @@ describe('Dropdown Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Dropdown-App`);
cy.openApp();
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', () => {

View file

@ -91,7 +91,7 @@ describe("Global Actions", () => {
cy.waitForAutoSave();
addInputOnQueryField("runjs", "actions.showModal('modal1');");
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');");
query("run");
@ -114,7 +114,7 @@ describe("Global Actions", () => {
"actions.setLocalStorage('localStorage','data from runjs');"
);
query("run");
cy.wait(500)
cy.getAllLocalStorage().then((result) => {
expect(result[Cypress.config().baseUrl].localStorage).to.deep.equal(
"data from runjs"

View file

@ -96,7 +96,7 @@ describe('Multiselect Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Multiselect-App`);
cy.openApp();
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', () => {

View file

@ -87,7 +87,7 @@ describe('Number Input Component Tests', () => {
cy.apiCreateApp(`${fake.companyName}-Numberinput-App`);
cy.openApp();
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', () => {
@ -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 = [
{ event: "On Focus", message: "On Focus Event" },
{ event: "On Blur", message: "On Blur Event" },
@ -129,7 +129,7 @@ describe('Number Input Component Tests', () => {
inputEvents(inputSelector);
});
it('should verify all the CSA from number input', () => {
it.skip('should verify all the CSA from number input', () => {
const actions = [
{ event: "On click", action: "Set visibility", valueToggle: "{{false}}" }, //b1
{ 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.openApp();
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', () => {
@ -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 = [
{ event: "On Focus", message: "On Focus 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.openApp();
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(".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 = [
{ event: "On Focus", message: "On Focus Event" },
{ event: "On Blur", message: "On Blur Event" },
@ -137,7 +137,7 @@ describe('Text Input Component Tests', () => {
verifyTextInputEvents(textInputSelector);
});
it('should verify all the CSA from text input', () => {
it.skip('should verify all the CSA from text input', () => {
const actions = [
{ event: "On click", action: "Set visibility", valueToggle: "{{false}}" }, //b1
{ 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.openApp();
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', () => {
@ -137,6 +137,8 @@ describe('ToggleSwitch Component Tests', () => {
cy.get(commonWidgetSelector.draggableWidget(component)).should("not.be.visible");
cy.get(commonWidgetSelector.draggableWidget("button2")).click();
cy.wait(500);
cy.forceClickOnCanvas();
cy.get(commonWidgetSelector.draggableWidget(component)).should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("button3")).click();

View file

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

View file

@ -14,6 +14,7 @@ describe("Chaining of queries", () => {
cy.apiLogin();
cy.apiCreateApp(`${fake.companyName}-chaining-App`);
cy.openApp();
cy.apiFetchDataSourcesId()
cy.viewport(1800, 1800);
cy.dragAndDropWidget("Button");
resizeQueryPanel("80");
@ -57,7 +58,7 @@ describe("Chaining of queries", () => {
);
cy.apiCreateGDS(
"http://localhost:3000/api/v2/data_sources",
`http://localhost:3000/api/data-sources`,
`cypress-${dsName}-qc-postgresql`,
"postgresql",
[
@ -68,8 +69,10 @@ describe("Chaining of queries", () => {
{ key: "password", value: Cypress.env("pg_password"), encrypted: true },
{ key: "ssl_enabled", value: false, encrypted: false },
{ key: "ssl_certificate", value: "none", encrypted: false },
{ key: "connection_type", value: "manual", encrypted: false }
]
);
cy.log("Data source created");
cy.apiAddQueryToApp(
"psql",
{
@ -92,8 +95,17 @@ describe("Chaining of queries", () => {
chainQuery("restapi", "tjdb");
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);
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.get('[data-cy="query-selection-field"]')
.click()
@ -105,11 +117,13 @@ describe("Chaining of queries", () => {
cy.verifyToastMessage(commonSelectors.toastMessage, "psql");
cy.verifyToastMessage(commonSelectors.toastMessage, "runjs");
cy.verifyToastMessage(commonSelectors.toastMessage, "runpy");
cy.wait(500);
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 = {};
let dsName = fake.companyName;
data.customText = randomString(12);
@ -133,7 +147,7 @@ describe("Chaining of queries", () => {
addSuccessNotification("runjs");
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.get('[data-cy="query-selection-field"]')
.click()

View file

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

View file

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

View file

@ -66,7 +66,7 @@ describe("Add all Data sources to app", () => {
cy.apiLogin();
});
it("Should verify global data source page", () => {
it.skip("Should verify global data source page", () => {
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
cy.visit(`${data.workspaceSlug}`);
@ -87,7 +87,7 @@ describe("Add all Data sources to app", () => {
);
});
it("Should add all data sources in data source page", () => {
it.skip("Should add all data sources in data source page", () => {
cy.visit(`${data.workspaceSlug}`);
dataSources.forEach((dsName) => {
@ -109,7 +109,7 @@ describe("Add all Data sources to app", () => {
});
});
it("Should add all data sources in the app", () => {
it.skip("Should add all data sources in the app", () => {
cy.visit(`${data.workspaceSlug}`);
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
@ -135,7 +135,7 @@ describe("Add all Data sources to app", () => {
});
});
it("Should install all makretplace plugins and add them into the app", () => {
it.skip("Should install all makretplace plugins and add them into the app", () => {
cy.visit(`${data.workspaceSlug}`);
const dataSourcesMarketplace = [
"Plivo",
@ -189,12 +189,15 @@ describe("Add all Data sources to app", () => {
cy.wrap(dataSourcesMarketplace).each((dsName) => {
cy.get(commonSelectors.globalDataSourceIcon).click();
selectAndAddDataSource("databases", dsName, dsName);
cy.wait(500);
cy.wait(1000);
});
cy.get(commonSelectors.dashboardIcon).click();
cy.get(commonSelectors.appCreateButton).click();
cy.get(commonSelectors.appNameInput).click().type(data.dsNamefake1);
cy.get(commonSelectors.dashboardIcon).should("be.visible").click();
cy.get(commonSelectors.appCreateButton).should("be.visible").click();
cy.get(commonSelectors.appNameInput)
.should("be.visible")
.click()
.type(data.dsNamefake1);
cy.get(commonSelectors.createAppButton).click();
cy.skipWalkthrough();
@ -203,7 +206,7 @@ describe("Add all Data sources to app", () => {
cy.get(".css-4e90k9").type(
`cypress-${cyParamName(dsName)}-${cyParamName(dsName)}`
);
cy.wait(500);
cy.wait(1000);
cy.contains(
`[id*="react-select-"]`,
@ -212,7 +215,7 @@ describe("Add all Data sources to app", () => {
.should("be.visible")
.click();
cy.wait(500);
cy.wait(1000);
});
});
});

View file

@ -19,13 +19,14 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
data.dsName1 = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
data.queryName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source Airtable", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on connection AirTable form", () => {
@ -199,7 +200,7 @@ describe("Data source Airtable", () => {
cy.get('[data-cy="show-ds-popover-button"]').click();
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName1);
cy.get('[data-cy="query-rename-input"]').clear().type(data.queryName);
cy.get(airTableSelector.operationSelectDropdown)
.click()
@ -225,7 +226,7 @@ describe("Data source Airtable", () => {
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName1}) completed.`
`Query (${data.queryName}) completed.`
);
// Verify Delete record operation
@ -277,7 +278,7 @@ describe("Data source Airtable", () => {
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
`Query (${data.dsName1}) completed.`
`Query (${data.queryName}) completed.`
);
deleteAppandDatasourceAfterExecution(
data.dsName,

View file

@ -20,16 +20,15 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source amazon athena", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on amazon athena connection form", () => {
it.skip("Should verify elements on amazon athena connection form", () => {
const Accesskey = Cypress.env("amazonathena_accessKey");
const Secretkey = Cypress.env("amazonathena_secretKey");
const DbName = Cypress.env("amazonathena_DbName");
@ -98,7 +97,7 @@ describe("Data source amazon athena", () => {
deleteDatasource(`cypress-${data.dsName}-Amazon-Athena`);
});
it("Should verify the functionality of amazon athena connection form.", () => {
it.skip("Should verify the functionality of amazon athena connection form.", () => {
const Accesskey = Cypress.env("amazonathena_accessKey");
const Secretkey = Cypress.env("amazonathena_secretKey");
const DbName = Cypress.env("amazonathena_DbName");
@ -135,7 +134,7 @@ describe("Data source amazon athena", () => {
deleteDatasource(`cypress-${data.dsName}-amazon-Athena`);
});
it("Should able to run the query with valid conection", () => {
it.skip("Should able to run the query with valid conection", () => {
const Accesskey = Cypress.env("amazonathena_accessKey");
const Secretkey = Cypress.env("amazonathena_secretKey");
const DbName = Cypress.env("amazonathena_DbName");
@ -189,11 +188,13 @@ describe("Data source amazon athena", () => {
cy.get(".css-4e90k9").type(`${data.dsName}`);
cy.contains(`[id*="react-select-"]`, data.dsName).click();
cy.get('[data-cy="query-rename-input"]').clear().type(data.dsName);
cy.get(`[data-cy="list-query-${data.dsName}"]`).should("be.visible");
cy.get('[data-cy="query-input-field"]').clearAndTypeOnCodeMirror(
"SHOW DATABASES;"
);
cy.get(
'[data-cy="query-input-field"] >>> .cm-editor >> .cm-content > .cm-line'
).should("have.text", "SHOW DATABASES;");
cy.get(dataSourceSelector.queryPreviewButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,

View file

@ -20,16 +20,15 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source amazon ses", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on amazonses connection form", () => {
it.skip("Should verify elements on amazonses connection form", () => {
const Accesskey = Cypress.env("amazonSes_accessKey");
const Secretkey = Cypress.env("amazonSes_secretKey");
@ -81,7 +80,7 @@ describe("Data source amazon ses", () => {
deleteDatasource(`cypress-${data.dsName}-Amazon-ses`);
});
it("Should verify the functionality of amazonses connection form.", () => {
it.skip("Should verify the functionality of amazonses connection form.", () => {
selectAndAddDataSource("databases", amazonSesText.AmazonSES, data.dsName);
cy.get(".react-select__dropdown-indicator").eq(1).click();
@ -113,7 +112,7 @@ describe("Data source amazon ses", () => {
deleteDatasource(`cypress-${data.dsName}-amazon-ses`);
});
it("Should able to run the query with valid conection", () => {
it.skip("Should able to run the query with valid conection", () => {
const email = "adish" + "@" + "tooljet.com";
selectAndAddDataSource("databases", amazonSesText.AmazonSES, data.dsName);

View file

@ -20,16 +20,15 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source AppWrite", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on appwrite connection form", () => {
it.skip("Should verify elements on appwrite connection form", () => {
const Host = Cypress.env("appwrite_host");
const ProjectID = Cypress.env("appwrite_projectID");
const DatabaseID = Cypress.env("appwrite_databaseID");
@ -101,7 +100,7 @@ describe("Data source AppWrite", () => {
deleteDatasource(`cypress-${data.dsName}-Appwrite`);
});
it("Should verify the functionality of appwrite connection form.", () => {
it.skip("Should verify the functionality of appwrite connection form.", () => {
const Host = Cypress.env("appwrite_host");
const ProjectID = Cypress.env("appwrite_projectID");
const DatabaseID = Cypress.env("appwrite_databaseID");
@ -151,7 +150,7 @@ describe("Data source AppWrite", () => {
deleteDatasource(`cypress-${data.dsName}-Appwrite`);
});
it("Should be able to run the query with a valid connection", () => {
it.skip("Should be able to run the query with a valid connection", () => {
const Host = Cypress.env("appwrite_host");
const ProjectID = Cypress.env("appwrite_projectID");
const DatabaseID = Cypress.env("appwrite_databaseID");

View file

@ -20,16 +20,15 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source AWS Lambda", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on AWS Lambda connection form", () => {
it.skip("Should verify elements on AWS Lambda connection form", () => {
const Accesskey = Cypress.env("awslamda_access");
const Secretkey = Cypress.env("awslamda_secret");
@ -81,9 +80,10 @@ describe("Data source AWS Lambda", () => {
);
deleteDatasource(`cypress-${data.dsName}-aws-lambda`);
cy.uninstallMarketplacePlugin("AWS Lambda");
});
it("Should verify the functionality of AWS Lambda connection form", () => {
it.skip("Should verify the functionality of AWS Lambda connection form", () => {
const Accesskey = Cypress.env("awslamda_access");
const Secretkey = Cypress.env("awslamda_secret");
@ -114,9 +114,10 @@ describe("Data source AWS Lambda", () => {
);
deleteDatasource(`cypress-${data.dsName}-aws-lambda`);
cy.uninstallMarketplacePlugin("AWS Lambda");
});
it("Should able to run the query with valid conection", () => {
it.skip("Should able to run the query with valid conection", () => {
const Accesskey = Cypress.env("awslamda_access");
const Secretkey = Cypress.env("awslamda_secret");

View file

@ -21,16 +21,15 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source AWS Textract", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on AWS Textract connection form", () => {
it.skip("Should verify elements on AWS Textract connection form", () => {
const Accesskey = Cypress.env("awstextract_access");
const Secretkey = Cypress.env("awstextract_secret");
@ -88,7 +87,7 @@ describe("Data source AWS Textract", () => {
deleteDatasource(`cypress-${data.dsName}-aws-textract`);
});
it("Should verify functionality of AWS Textract connection form", () => {
it.skip("Should verify functionality of AWS Textract connection form", () => {
const Accesskey = Cypress.env("awstextract_access");
const Secretkey = Cypress.env("awstextract_secret");
@ -123,9 +122,10 @@ describe("Data source AWS Textract", () => {
);
deleteDatasource(`cypress-${data.dsName}-aws-textract`);
cy.uninstallMarketplacePlugin("AWS Textract");
});
it("Should able to run the query with valid conection", () => {
it.skip("Should able to run the query with valid conection", () => {
const Accesskey = Cypress.env("awstextract_access");
const Secretkey = Cypress.env("awstextract_secret");

View file

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

View file

@ -20,16 +20,15 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source baserow", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.intercept("POST", "/api/data_queries").as("createQuery");
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on baserow connection form", () => {
it.skip("Should verify elements on baserow connection form", () => {
const Apikey = Cypress.env("baserow_apikey");
cy.get(commonSelectors.globalDataSourceIcon).click();
@ -79,7 +78,7 @@ describe("Data source baserow", () => {
deleteDatasource(`cypress-${data.dsName}-baserow`);
});
it("Should verify the functionality of baserow connection form.", () => {
it.skip("Should verify the functionality of baserow connection form.", () => {
const Apikey = Cypress.env("baserow_apikey");
selectAndAddDataSource("databases", baseRowText.baserow, data.dsName);
@ -104,7 +103,7 @@ describe("Data source baserow", () => {
deleteDatasource(`cypress-${data.dsName}-baserow`);
});
it("Should be able to run the query with a valid connection", () => {
it.skip("Should be able to run the query with a valid connection", () => {
const baserowTableID = Cypress.env("baserow_tableid");
const baserowRowID = Cypress.env("baserow_rowid");
const Apikey = Cypress.env("baserow_apikey");

View file

@ -16,9 +16,8 @@ const data = {};
describe("Data source BigQuery", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.intercept("GET", "/api/v2/data_sources");
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -19,8 +19,8 @@ const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -19,8 +19,8 @@ const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -21,8 +21,8 @@ const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -19,8 +19,8 @@ const data = {};
describe("Data source DynamoDB", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -17,9 +17,12 @@ import {
const data = {};
describe("Data source Elasticsearch", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
data.lastName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on Elasticsearch connection form", () => {
@ -123,14 +126,14 @@ describe("Data source Elasticsearch", () => {
"have.text",
elasticsearchText.errorConnectionRefused
);
deleteDatasource(`cypress-${data.lastName}-elasticsearch`);
deleteDatasource(`cypress-${data.dataSourceName}-elasticsearch`);
});
it("Should verify the functionality of Elasticsearch connection form.", () => {
selectAndAddDataSource(
"databases",
elasticsearchText.elasticSearch,
data.lastName
data.dataSourceName
);
fillDataSourceTextField(
@ -210,12 +213,12 @@ describe("Data source Elasticsearch", () => {
);
cy.get(
`[data-cy="cypress-${data.lastName}-elasticsearch-button"]`
`[data-cy="cypress-${data.dataSourceName}-elasticsearch-button"]`
).verifyVisibleElement(
"have.text",
`cypress-${data.lastName}-elasticsearch`
`cypress-${data.dataSourceName}-elasticsearch`
);
deleteDatasource(`cypress-${data.lastName}-elasticsearch`);
deleteDatasource(`cypress-${data.dataSourceName}-elasticsearch`);
});
});

View file

@ -17,8 +17,8 @@ const data = {};
describe("Data source Firestore", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -19,12 +19,12 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source GraphQL", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on GraphQL connection form", () => {

View file

@ -20,13 +20,13 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
data.dsName1 = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source HarperDB", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on HarperDB connection form", () => {
@ -102,6 +102,7 @@ describe("Data source HarperDB", () => {
);
deleteDatasource(`cypress-${data.dsName}-HarperDB`);
cy.uninstallMarketplacePlugin("HarperDB");
});
it("Should verify functionality of HarperDB connection form", () => {
@ -156,9 +157,10 @@ describe("Data source HarperDB", () => {
);
deleteDatasource(`cypress-${data.dsName}-HarperDB`);
cy.uninstallMarketplacePlugin("HarperDB");
});
it("Should be able to run the query with a valid connection", () => {
it.skip("Should be able to run the query with a valid connection", () => {
const Host = Cypress.env("harperdb_host");
const Port = Cypress.env("harperdb_port");
const Username = Cypress.env("harperdb_username");

View file

@ -23,8 +23,8 @@ const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -19,8 +19,8 @@ const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -20,12 +20,12 @@ import {
import { dataSourceSelector } from "../../../../../constants/selectors/dataSource";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source minio", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on minio connection form", () => {
@ -157,7 +157,7 @@ describe("Data source minio", () => {
deleteDatasource(`cypress-${data.dsName}-minio`);
});
it("Should be able to run the query with a valid connection", () => {
it.skip("Should be able to run the query with a valid connection", () => {
const Host = Cypress.env("minio_host");
const Port = Cypress.env("minio_port");
const AccessKey = Cypress.env("minio_accesskey");

View file

@ -27,8 +27,8 @@ const data = {};
describe("Data source MongoDB", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");
@ -133,7 +133,7 @@ describe("Data source MongoDB", () => {
"have.text",
mongoDbText.errorConnectionRefused
);
cy.get('[data-cy="query-select-dropdown"]').type(
cy.get('[data-cy="connection-type-select-dropdown"]').type(
mongoDbText.optionConnectUsingConnectionString
);
cy.get('[data-cy="label-connection-string"]').verifyVisibleElement(

View file

@ -26,8 +26,8 @@ const data = {};
describe("Data sources MySql", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -15,7 +15,7 @@ import {
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.apiLogin();
// cy.createApp();
});

View file

@ -20,14 +20,14 @@ const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on connection form", () => {
it.skip("Should verify elements on connection form", () => {
cy.log(process.env.NODE_ENV);
cy.log(postgreSqlText.allDatabase());
cy.get(commonSelectors.globalDataSourceIcon).click();
@ -140,7 +140,7 @@ describe("Data sources", () => {
deleteDatasource(`cypress-${data.dataSourceName}-postgresql`);
});
it("Should verify the functionality of PostgreSQL connection form.", () => {
it.skip("Should verify the functionality of PostgreSQL connection form.", () => {
selectAndAddDataSource(
"databases",
postgreSqlText.postgreSQL,

View file

@ -23,7 +23,7 @@ data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source Redis", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.visit("/");
});
it("Should verify elements on connection Redis form", () => {
@ -215,7 +215,7 @@ describe("Data source Redis", () => {
deleteDatasource(`cypress-${data.dsName}-redis`);
});
it("Should able to run the query with valid conection", () => {
it.skip("Should able to run the query with valid conection", () => {
selectAndAddDataSource("databases", redisText.redis, data.dsName);
fillDataSourceTextField(

View file

@ -5,7 +5,7 @@ import { postgreSqlSelector } from "Selectors/postgreSql";
import { postgreSqlText } from "Texts/postgreSql";
import { restAPISelector } from "Selectors/restAPI";
import { restAPIText } from "Texts/restAPI";
import { fillDataSourceTextField } from "Support/utils/postgreSql";
import { createAndRunRestAPIQuery } from "Support/utils/restAPI";
const data = {};
const authenticationDropdownSelector =
@ -19,8 +19,8 @@ const clientAuthenticationDropdown =
describe("Data source Rest API", () => {
beforeEach(() => {
cy.defaultWorkspaceLogin();
cy.intercept("GET", "/api/v2/data_sources");
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");
@ -331,7 +331,7 @@ describe("Data source Rest API", () => {
cy.verifyToastMessage(commonSelectors.toastMessage, "Data Source Saved");
deleteDatasource(`cypress-${data.dataSourceName}-restapi`);
});
it("Should verify connection for Rest API", () => {
it("Should verify basic connection for Rest API", () => {
cy.apiCreateGDS(
`${Cypress.env("server_host")}/api/data-sources`,
`cypress-${data.dataSourceName}-restapi`,
@ -366,18 +366,89 @@ describe("Data source Rest API", () => {
]
);
cy.reload();
// cy.apiCreateApp(`${fake.companyName}-restAPI-App`);
// cy.apiAddQueryToApp(
// "restapi1",
// {
// method: "get",
// url: "",
// url_params: [["", ""]],
// headers: [["", ""]],
// cookies: [["", ""]],
// },
// `cypress-${data.dataSourceName}-restapi`,
// "restapi"
// );
cy.apiCreateApp(`${fake.companyName}-restAPI-App`);
cy.openApp();
createAndRunRestAPIQuery(
"get_restapi",
`cypress-${data.dataSourceName}-restapi`,
"GET",
"/api/users"
);
createAndRunRestAPIQuery(
"post_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

@ -19,8 +19,8 @@ const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -20,7 +20,7 @@ const data = {};
describe("Data sources AWS S3", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -15,7 +15,7 @@ import {
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.apiLogin();
// cy.createApp();
});

View file

@ -13,8 +13,8 @@ const data = {};
describe("Data source SMTP", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -20,8 +20,8 @@ import {
const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -21,8 +21,8 @@ const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit("/");
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -21,15 +21,15 @@ import { dataSourceSelector } from "../../../../../constants/selectors/dataSourc
import { pluginSelectors } from "Selectors/plugins";
const data = {};
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
describe("Data source Twilio", () => {
beforeEach(() => {
cy.apiLogin();
cy.defaultWorkspaceLogin();
cy.visit("/");
data.dsName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", "");
});
it("Should verify elements on Twilio connection form", () => {
it.skip("Should verify elements on Twilio connection form", () => {
const AuthToken = Cypress.env("twilio_auth_token");
const AccountSID = Cypress.env("twilio_account_SID");
const MessageSID = Cypress.env("twilio_messaging_service_SID");
@ -89,7 +89,7 @@ describe("Data source Twilio", () => {
deleteDatasource(`cypress-${data.dsName}-twilio`);
});
it("Should verify functionality of Twilio connection form", () => {
it.skip("Should verify functionality of Twilio connection form", () => {
const AuthToken = Cypress.env("twilio_auth_token");
const AccountSID = Cypress.env("twilio_account_SID");
const MessageSID = Cypress.env("twilio_messaging_service_SID");
@ -128,7 +128,7 @@ describe("Data source Twilio", () => {
deleteDatasource(`cypress-${data.dsName}-twilio`);
});
it("Should be able to run the query with a valid connection", () => {
it.skip("Should be able to run the query with a valid connection", () => {
const AuthToken = Cypress.env("twilio_auth_token");
const AccountSID = Cypress.env("twilio_account_SID");
const MessageSID = Cypress.env("twilio_messaging_service_SID");

View file

@ -20,7 +20,7 @@ const data = {};
describe("Data sources", () => {
beforeEach(() => {
cy.appUILogin();
cy.apiLogin();
data.dataSourceName = fake.lastName
.toLowerCase()
.replaceAll("[^A-Za-z]", "");

View file

@ -0,0 +1,217 @@
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.skipWalkthrough()
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,232 @@
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();
cy.skipWalkthrough()
});
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(commonSelectors.toastCloseButton).click();
cy.wait(500);
cy.get(commonSelectors.appNameInput).verifyVisibleElement(
"contain.value",
"three-versions"
);
cy.get(appVersionSelectors.currentVersionField("v3")).should("be.visible");
// 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(() => {
data.slug = `${fake.companyName.toLowerCase()}-app`;
data.appName = `${fake.companyName} App`;
cy.log(Cypress.env("workspaceId"));
cy.defaultWorkspaceLogin();
});
@ -25,133 +24,141 @@ describe("App Slug", () => {
cy.apiCreateApp(data.appName);
cy.wait(1000);
cy.apiLogout();
cy.log(Cypress.env("workspaceId"));
});
it("Verify app slug cases in global settings", () => {
cy.apiLogin("dev@tooljet.io", "password").then(() => {
const workspaceId = Cypress.env("workspaceId");
const appId = Cypress.env("appId");
const workspaceId = Cypress.env("workspaceId");
const appId = Cypress.env("appId");
const appUrl = `${host}/${Cypress.env("workspaceId")}/apps/${Cypress.env("appId")}/`;
cy.openApp("my-workspace");
cy.get(commonSelectors.leftSideBarSettingsButton).click();
cy.apiLogin();
cy.skipWalkthrough();
// 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."
);
cy.visit(appUrl);
cy.url().then((url) => {
if (url !== appUrl) {
cy.visit(appUrl);
}
});
cy.url().should("eq", appUrl);
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", () => {
cy.apiLogin("dev@tooljet.io", "password").then(() => {
const workspaceId = Cypress.env("workspaceId");
cy.apiLogin();
const workspaceId = Cypress.env("workspaceId");
cy.apiCreateApp(data.appName);
cy.openApp("my-workspace");
cy.apiCreateApp(data.appName);
cy.openApp("my-workspace");
// Set up initial slug
cy.get(commonSelectors.leftSideBarSettingsButton).click();
cy.get(commonWidgetSelector.appSlugInput).clear();
cy.clearAndType(commonWidgetSelector.appSlugInput, data.slug);
// Set up initial slug
cy.get(commonSelectors.leftSideBarSettingsButton).click();
cy.get(commonWidgetSelector.appSlugInput).clear();
cy.clearAndType(commonWidgetSelector.appSlugInput, data.slug);
releaseApp();
releaseApp();
// Verify share modal
cy.get(commonWidgetSelector.shareAppButton).click();
cy.get(commonWidgetSelector.appLink).verifyVisibleElement(
"have.text",
`${host}/applications/`
);
cy.get(commonWidgetSelector.appNameSlugInput).should(
"have.value",
data.slug
);
// Verify share modal
cy.get(commonWidgetSelector.shareAppButton).click();
cy.get(commonWidgetSelector.appLink).verifyVisibleElement(
"have.text",
`${host}/applications/`
);
cy.get(commonWidgetSelector.appNameSlugInput).should(
"have.value",
data.slug
);
// Validate all error cases in share modal
verifySlugValidations(commonWidgetSelector.appNameSlugInput);
// Validate all error cases in share modal
verifySlugValidations(commonWidgetSelector.appNameSlugInput);
cy.wait(500);
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
cy.get('[data-cy="app-slug-info-label"]')
.invoke("text")
.then((text) => {
expect(text.trim()).to.eq(
"URL-friendly 'slug' consists of lowercase letters, numbers, and hyphens"
);
});
cy.wait(500);
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
cy.get('[data-cy="app-slug-info-label"]')
.invoke("text")
.then((text) => {
expect(text.trim()).to.eq(
"URL-friendly 'slug' consists of lowercase letters, numbers, and hyphens"
);
});
// Verify successful slug update in share modal
data.slug = `${fake.companyName.toLowerCase()}-app`;
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
cy.get('[data-cy="app-slug-accepted-label"]').verifyVisibleElement(
"have.text",
"Slug accepted!"
);
// Verify successful slug update in share modal
data.slug = `${fake.companyName.toLowerCase()}-app`;
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
cy.get('[data-cy="app-slug-accepted-label"]').verifyVisibleElement(
"have.text",
"Slug accepted!"
);
// Close modal and verify URLs
cy.get(commonWidgetSelector.modalCloseButton).click();
verifyURLs(workspaceId, data.slug, true);
// Close modal and verify URLs
cy.get(commonWidgetSelector.modalCloseButton).click();
verifyURLs(workspaceId, data.slug, true);
// Verify duplicate slug validation in share modal
cy.visit("/my-workspace");
cy.apiCreateApp(data.slug);
cy.openApp("my-workspace");
releaseApp();
cy.get(commonWidgetSelector.shareAppButton).click();
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
cy.get(commonWidgetSelector.appSlugErrorLabel).verifyVisibleElement(
"have.text",
"This app slug is already taken."
);
});
// Verify duplicate slug validation in share modal
cy.visit("/my-workspace");
cy.apiCreateApp(data.slug);
cy.openApp("my-workspace");
releaseApp();
cy.get(commonWidgetSelector.shareAppButton).click();
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
cy.get(commonWidgetSelector.appSlugErrorLabel).verifyVisibleElement(
"have.text",
"This app slug is already taken."
);
});
});

View file

@ -20,20 +20,20 @@ import {
describe("Private and Public apps", {
retries: { runMode: 2 },
}, () => {
const data = {};
let data;
beforeEach(() => {
data.appName = `${fake.companyName} P P App`;
data.slug = data.appName.toLowerCase().replace(/\s+/g, "-");
data.firstName = fake.firstName;
data.email = fake.email.toLowerCase();
data.workspaceName = fake.firstName;
data.workspaceSlug = fake.firstName.toLowerCase().replace(/\s+/g, "-");
data = {
appName: `${fake.companyName} P P App`,
slug: `${fake.companyName} P P App`.toLowerCase().replace(/\s+/g, "-"),
firstName: fake.firstName,
email: fake.email.toLowerCase(),
workspaceName: fake.firstName,
workspaceSlug: fake.firstName.toLowerCase().replace(/\s+/g, "-"),
}
cy.defaultWorkspaceLogin();
cy.skipWalkthrough();
cy.log(data.appName, "text1")
});
it("Verify private and public app share functionality", () => {
@ -78,16 +78,16 @@ describe("Private and Public apps", {
// Test private access
logout();
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
});
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
cy.wait(2000);
cy.loginWithCredentials("dev@tooljet.io", "password");
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.appUILogin();
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
// Test public access
cy.get(commonSelectors.viewerPageLogo).click();
@ -106,8 +106,8 @@ describe("Private and Public apps", {
cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
});
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
});
@ -116,6 +116,9 @@ describe("Private and Public apps", {
inviteUserToWorkspace(data.firstName, data.email);
logout();
cy.visit("/");
cy.wait(2000);
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
// Test private access
cy.visitSlug({
@ -123,30 +126,32 @@ describe("Private and Public apps", {
});
cy.wait(2000);
cy.loginWithCredentials(data.email, "password");
cy.appUILogin(data.email, "password");
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible", { timeout: 20000 });
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
// Test with private app valid session
cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
});
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get(commonSelectors.viewerPageLogo).click();
// Test public access
cy.defaultWorkspaceLogin();
cy.wait(1000);
cy.apiMakeAppPublic();
logout();
cy.wait(1000);
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
});
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
// Test with public app with valid session
@ -154,8 +159,8 @@ describe("Private and Public apps", {
cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
});
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
});
@ -177,11 +182,14 @@ describe("Private and Public apps", {
cy.apiMakeAppPublic();
logout();
cy.wait(1000);
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
});
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
// Verify public app with valid session
@ -189,8 +197,8 @@ describe("Private and Public apps", {
cy.visitSlug({
actualUrl: `${Cypress.config("baseUrl")}/applications/${data.slug}`,
});
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
});
@ -224,11 +232,13 @@ describe("Private and Public apps", {
// Process invitation
onboardUserFromAppLink(data.email, data.slug);
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('[data-cy="viewer-page-logo"]').click();
logout();
cy.wait(1000);
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should("be.visible");
// Setup new workspace and app
cy.defaultWorkspaceLogin();
@ -269,8 +279,8 @@ describe("Private and Public apps", {
});
onboardUserFromAppLink(data.email, data.slug, data.workspaceName, false);
// cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
cy.get('.text-widget-section > div').should("be.visible");
cy.get(commonWidgetSelector.draggableWidget("text1")).should("be.visible");
});

View file

@ -114,7 +114,7 @@ describe("App Version", () => {
cy.wait(3000);
// 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
cy.openInCurrentTab(commonWidgetSelector.previewButton);
@ -123,7 +123,7 @@ describe("App Version", () => {
releasedVersionAndVerify("v2");
});
it.only("should verify version management with components and queries", () => {
it("should verify version management with components and queries", () => {
// Initial setup with component and datasource
cy.apiAddComponentToApp(
data.appName,

View file

@ -46,7 +46,7 @@ describe("Datasource Manager", () => {
data.dsName1 = 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)";
cy.get(commonSelectors.globalDataSourceIcon).click();
@ -214,7 +214,7 @@ describe("Datasource Manager", () => {
cy.get(commonWidgetSelector.sidebarinspector).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(".p-2 > .tj-base-btn")
@ -275,7 +275,7 @@ describe("Datasource Manager", () => {
pinInspector();
cy.get(dataSourceSelector.queryCreateAndRunButton).click();
verifyValueOnInspector("table_preview", "7 items ");
verifyValueOnInspector("table_preview", "10 items ");
//scope changing is pending
});

View file

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

View file

@ -80,8 +80,8 @@ describe("Workspace constants", () => {
addNewconstants("restapiHeaderKey", "customHeader");
addNewconstants("restapiHeaderValue", "key=value");
addNewconstants("deleteConst", "deleteconst");
addNewconstants("gconst", "236");
addNewconstants("gconstUrl", "http://34.66.166.236:4000/");
addNewconstants("gconst", "108");
addNewconstants("gconstUrl", "http://20.29.40.108:4000/");
addNewconstants("gconstEndpoint", "production");
// create secret constants
@ -118,13 +118,15 @@ describe("Workspace constants", () => {
//Verify all static and datasource queries output in components
for (let i = 3; i <= 16; i++) {
cy.log("Verifying textinput" + i);
cy.get(commonWidgetSelector.draggableWidget(`textinput${i}`))
.verifyVisibleElement("have.value", "Production environment testing");
}
//verify global constant is resolved in static query url
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"));
//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.email = fake.email.toLowerCase().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);
logout();
cy.defaultWorkspaceLogin();
cy.apiLogin();
cy.visit(workspaceName);
navigateToManageUsers();
searchUser(data.email);
cy.contains("td", data.email)

View file

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

View file

@ -2,7 +2,6 @@ import { fake } from "Fixtures/fake";
import {
createFolder,
deleteFolder,
deleteDownloadsFolder,
navigateToAppEditor,
viewAppCardOptions,
verifyModal,
@ -14,49 +13,196 @@ import {
} from "Support/utils/common";
import {
modifyAndVerifyAppCardIcon,
login,
verifyAppDelete,
} from "Support/utils/dashboard";
import { profileSelector } from "Selectors/profile";
import { profileText } from "Texts/profile";
import { commonSelectors } from "Selectors/common";
import { dashboardSelector } from "Selectors/dashboard";
import { commonText } from "Texts/common";
import { dashboardText } from "Texts/dashboard";
import {
navigateToManageUsers,
logout,
searchUser,
navigateToManageGroups,
} from "Support/utils/common";
import { roleBasedOnboarding } from "Support/utils/onboarding";
import { logout } from "Support/utils/common";
describe("dashboard", () => {
const 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]", "");
let data = {};
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("DELETE", "/api/folders/*").as("folderDeleted");
cy.skipWalkthrough();
cy.apiLogin();
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug);
cy.apiLogout();
cy.apiLogin();
cy.visit(`${data.workspaceSlug}`);
});
// it("Should verify app card elements and app card operations", () => {
// const customLayout = {
// desktop: { top: 100, left: 20 },
// mobile: { width: 8, height: 50 },
// };
// cy.apiCreateApp(data.appName);
// cy.visit(`${data.workspaceSlug}`);
// cy.wait(2000);
// cy.get(commonSelectors.appCreationDetails).should("be.visible");
// cy.get(commonSelectors.appCard(data.appName)).should("be.visible");
// cy.get(commonSelectors.appTitle(data.appName)).verifyVisibleElement(
// "have.text",
// data.appName
// );
// viewAppCardOptions(data.appName);
// cy.get(
// commonSelectors.appCardOptions(commonText.changeIconOption)
// ).verifyVisibleElement("have.text", commonText.changeIconOption);
// cy.get(
// commonSelectors.appCardOptions(commonText.addToFolderOption)
// ).verifyVisibleElement("have.text", commonText.addToFolderOption);
// cy.get(
// commonSelectors.appCardOptions(commonText.cloneAppOption)
// ).verifyVisibleElement("have.text", commonText.cloneAppOption);
// cy.get(
// commonSelectors.appCardOptions(commonText.exportAppOption)
// ).verifyVisibleElement("have.text", commonText.exportAppOption);
// cy.get(
// commonSelectors.appCardOptions(commonText.deleteAppOption)
// ).verifyVisibleElement("have.text", commonText.deleteAppOption);
// modifyAndVerifyAppCardIcon(data.appName);
// createFolder(data.folderName);
// viewAppCardOptions(data.appName);
// cy.get(
// commonSelectors.appCardOptions(commonText.addToFolderOption)
// ).click();
// verifyModal(
// dashboardText.addToFolderTitle,
// dashboardText.addToFolderButton,
// dashboardSelector.selectFolder
// );
// cy.get(dashboardSelector.moveAppText).verifyVisibleElement(
// "have.text",
// dashboardText.moveAppText(data.appName)
// );
// cy.get(dashboardSelector.selectFolder).click();
// cy.get(commonSelectors.folderList).contains(data.folderName).click();
// cy.get(dashboardSelector.addToFolderButton).click();
// cy.verifyToastMessage(
// commonSelectors.toastMessage,
// commonText.AddedToFolderToast,
// false
// );
// cy.get(dashboardSelector.folderName(data.folderName)).verifyVisibleElement(
// "have.text",
// dashboardText.folderName(`${data.folderName} (1)`)
// );
// cy.get(dashboardSelector.folderName(data.folderName)).click();
// cy.get(commonSelectors.appCard(data.appName))
// .contains(data.appName)
// .should("be.visible");
// viewAppCardOptions(data.appName);
// cy.get(commonSelectors.appCardOptions(commonText.removeFromFolderOption))
// .verifyVisibleElement("have.text", commonText.removeFromFolderOption)
// .click();
// verifyConfirmationModal(commonText.appRemovedFromFolderMessage);
// cancelModal(commonText.cancelButton);
// viewAppCardOptions(data.appName);
// cy.get(
// commonSelectors.appCardOptions(commonText.removeFromFolderOption)
// ).click();
// cy.get(commonSelectors.buttonSelector(commonText.modalYesButton)).click();
// cy.verifyToastMessage(
// commonSelectors.toastMessage,
// commonText.appRemovedFromFolderTaost,
// false
// );
// cy.get(commonSelectors.modalComponent).should("not.exist");
// cy.get(commonSelectors.empytyFolderImage).should("be.visible");
// cy.get(commonSelectors.emptyFolderText).verifyVisibleElement(
// "have.text",
// commonText.emptyFolderText
// );
// cy.get(commonSelectors.allApplicationsLink).click();
// deleteFolder(data.folderName);
// cy.get(commonSelectors.allApplicationsLink).click();
// cy.wait(1000);
// viewAppCardOptions(data.appName);
// cy.wait(2000);
// cy.get(commonSelectors.appCardOptions(commonText.exportAppOption)).click();
// cy.get(commonSelectors.exportAllButton).click();
// cy.exec("ls ./cypress/downloads/").then((result) => {
// const downloadedAppExportFileName = result.stdout.split("\n")[0];
// expect(downloadedAppExportFileName).to.contain.string("app");
// });
// viewAppCardOptions(data.appName);
// cy.get(commonSelectors.appCardOptions(commonText.cloneAppOption)).click();
// cy.get('[data-cy="clone-app"]').click();
// cy.get(".go3958317564")
// .should("be.visible")
// .and("have.text", dashboardText.appClonedToast);
// cy.wait(3000);
// cy.renameApp(data.cloneAppName);
// cy.apiAddComponentToApp(data.cloneAppName, "button", 25, 25);
// cy.backToApps();
// cy.wait("@appLibrary");
// cy.wait(1000);
// cy.get(commonSelectors.appCard(data.cloneAppName)).should("be.visible");
// cy.wait(1000);
// viewAppCardOptions(data.cloneAppName);
// cy.get(commonSelectors.deleteAppOption).click();
// cy.get(commonSelectors.modalMessage).verifyVisibleElement(
// "have.text",
// commonText.deleteAppModalMessage(data.cloneAppName)
// );
// cy.get(
// commonSelectors.buttonSelector(commonText.cancelButton)
// ).verifyVisibleElement("have.text", commonText.cancelButton);
// cy.get(
// commonSelectors.buttonSelector(commonText.modalYesButton)
// ).verifyVisibleElement("have.text", commonText.modalYesButton);
// cancelModal(commonText.cancelButton);
// viewAppCardOptions(data.cloneAppName);
// cy.get(commonSelectors.deleteAppOption).click();
// cy.get(commonSelectors.buttonSelector(commonText.modalYesButton)).click();
// cy.verifyToastMessage(
// commonSelectors.toastMessage,
// commonText.appDeletedToast,
// false
// );
// verifyAppDelete(data.cloneAppName);
// cy.wait("@appLibrary");
// cy.deleteApp(data.appName);
// verifyAppDelete(data.appName);
// });
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", {
body: {
installed_version: "2.9.2",
@ -64,15 +210,10 @@ describe("dashboard", () => {
},
}).as("version");
cy.defaultWorkspaceLogin();
cy.wait("@emptyDashboard");
cy.wait("@folders");
cy.wait("@version");
cy.get(commonSelectors.homePageLogo).should("be.visible");
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
"have.text",
"My workspace"
data.workspaceName
);
cy.get(commonSelectors.workspaceName).click();
// cy.get(commonSelectors.editRectangleIcon).should("be.visible");
@ -188,183 +329,12 @@ describe("dashboard", () => {
verifyTooltip(dashboardSelector.modeToggle, "Mode");
});
it("Should verify app card elements and app card operations", () => {
const customLayout = {
desktop: { top: 100, left: 20 },
mobile: { width: 8, height: 50 },
};
cy.apiLogin();
cy.apiCreateApp(data.appName);
cy.openApp();
cy.apiAddComponentToApp(data.appName, "text1", customLayout);
cy.backToApps();
cy.wait(500);
cy.get(commonSelectors.appCard(data.appName))
.parent()
.within(() => {
cy.get(commonSelectors.appCard(data.appName)).should("be.visible");
cy.get(commonSelectors.appTitle(data.appName)).verifyVisibleElement(
"have.text",
data.appName
);
cy.get(commonSelectors.appCreationDetails).should("be.visible");
//Add the edited details
});
viewAppCardOptions(data.appName);
cy.get(
commonSelectors.appCardOptions(commonText.changeIconOption)
).verifyVisibleElement("have.text", commonText.changeIconOption);
cy.get(
commonSelectors.appCardOptions(commonText.addToFolderOption)
).verifyVisibleElement("have.text", commonText.addToFolderOption);
cy.get(
commonSelectors.appCardOptions(commonText.cloneAppOption)
).verifyVisibleElement("have.text", commonText.cloneAppOption);
cy.get(
commonSelectors.appCardOptions(commonText.exportAppOption)
).verifyVisibleElement("have.text", commonText.exportAppOption);
cy.get(
commonSelectors.appCardOptions(commonText.deleteAppOption)
).verifyVisibleElement("have.text", commonText.deleteAppOption);
modifyAndVerifyAppCardIcon(data.appName);
createFolder(data.folderName);
viewAppCardOptions(data.appName);
cy.get(
commonSelectors.appCardOptions(commonText.addToFolderOption)
).click();
verifyModal(
dashboardText.addToFolderTitle,
dashboardText.addToFolderButton,
dashboardSelector.selectFolder
);
cy.get(dashboardSelector.moveAppText).verifyVisibleElement(
"have.text",
dashboardText.moveAppText(data.appName)
);
cy.get(dashboardSelector.selectFolder).click();
cy.get(commonSelectors.folderList).contains(data.folderName).click();
cy.get(dashboardSelector.addToFolderButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.AddedToFolderToast
);
cy.get(dashboardSelector.folderName(data.folderName)).verifyVisibleElement(
"have.text",
dashboardText.folderName(`${data.folderName} (1)`)
);
cy.get(dashboardSelector.folderName(data.folderName)).click();
cy.get(commonSelectors.appCard(data.appName))
.contains(data.appName)
.should("be.visible");
cy.wait(2000);
viewAppCardOptions(data.appName);
cy.get(commonSelectors.appCardOptions(commonText.removeFromFolderOption))
.verifyVisibleElement("have.text", commonText.removeFromFolderOption)
.click();
verifyConfirmationModal(commonText.appRemovedFromFolderMessage);
cancelModal(commonText.cancelButton);
viewAppCardOptions(data.appName);
cy.get(
commonSelectors.appCardOptions(commonText.removeFromFolderOption)
).click();
cy.get(commonSelectors.buttonSelector(commonText.modalYesButton)).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appRemovedFromFolderTaost
);
cy.get(commonSelectors.modalComponent).should("not.exist");
cy.get(commonSelectors.empytyFolderImage).should("be.visible");
cy.get(commonSelectors.emptyFolderText).verifyVisibleElement(
"have.text",
commonText.emptyFolderText
);
cy.get(commonSelectors.allApplicationsLink).click();
deleteFolder(data.folderName);
cy.get(commonSelectors.allApplicationsLink).click();
viewAppCardOptions(data.appName);
cy.get(commonSelectors.appCardOptions(commonText.cloneAppOption)).click();
cy.get('[data-cy="clone-app"]').click();
cy.get(".go3958317564")
.should("be.visible")
.and("have.text", dashboardText.appClonedToast);
cy.wait(3000);
cy.renameApp(data.cloneAppName);
cy.apiAddComponentToApp(data.cloneAppName, "button", 25, 25);
cy.backToApps();
cy.wait("@appLibrary");
cy.wait(1000);
cy.reloadAppForTheElement(data.cloneAppName);
cy.get(commonSelectors.appCard(data.cloneAppName)).should("be.visible");
cy.wait(3000)
viewAppCardOptions(data.cloneAppName);
cy.get(commonSelectors.appCardOptions(commonText.exportAppOption)).click();
cy.get(commonSelectors.exportAllButton).click();
cy.exec("ls ./cypress/downloads/").then((result) => {
const downloadedAppExportFileName = result.stdout.split("\n")[0];
expect(downloadedAppExportFileName).to.contain.string("app");
});
cy.reloadAppForTheElement(data.cloneAppName);
viewAppCardOptions(data.cloneAppName);
cy.get(commonSelectors.deleteAppOption).click();
cy.get(commonSelectors.modalMessage).verifyVisibleElement(
"have.text",
commonText.deleteAppModalMessage(data.cloneAppName)
);
cy.get(
commonSelectors.buttonSelector(commonText.cancelButton)
).verifyVisibleElement("have.text", commonText.cancelButton);
cy.get(
commonSelectors.buttonSelector(commonText.modalYesButton)
).verifyVisibleElement("have.text", commonText.modalYesButton);
cancelModal(commonText.cancelButton);
cy.reloadAppForTheElement(data.cloneAppName);
viewAppCardOptions(data.cloneAppName);
cy.get(commonSelectors.deleteAppOption).click();
cy.get(commonSelectors.buttonSelector(commonText.modalYesButton)).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appDeletedToast
);
verifyAppDelete(data.cloneAppName);
cy.wait("@appLibrary");
cy.deleteApp(data.appName);
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appDeletedToast
);
verifyAppDelete(data.appName);
});
it("Should verify the app CRUD operation", () => {
const customLayout = {
desktop: { top: 100, left: 20 },
mobile: { width: 8, height: 50 },
};
cy.skipWalkthrough();
data.appName = `${fake.companyName}-App`;
cy.defaultWorkspaceLogin();
cy.createApp(data.appName);
cy.apiAddComponentToApp(data.appName, "text1", customLayout);
@ -382,10 +352,7 @@ describe("dashboard", () => {
cy.wait("@appLibrary");
cy.deleteApp(data.appName);
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appDeletedToast
);
verifyAppDelete(data.appName);
});
@ -395,12 +362,8 @@ describe("dashboard", () => {
mobile: { width: 8, height: 50 },
};
data.appName = `${fake.companyName}-App`;
cy.defaultWorkspaceLogin();
cy.createApp(data.appName);
cy.apiAddComponentToApp(data.appName, "text1", customLayout);
cy.backToApps();
cy.get(commonSelectors.createNewFolderButton).click();
@ -510,20 +473,8 @@ describe("dashboard", () => {
cy.get(commonSelectors.allApplicationsLink).click();
cy.deleteApp(data.appName);
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appDeletedToast
);
verifyAppDelete(data.appName);
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

@ -78,14 +78,16 @@ describe("Manage Groups", () => {
cy.createApp(data.appName);
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appCreatedToast
commonText.appCreatedToast,
false
);
cy.backToApps();
cy.deleteApp(data.appName);
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appDeletedToast
commonText.appDeletedToast,
false
);
// Folder operations
@ -115,7 +117,8 @@ describe("Manage Groups", () => {
cy.get(commonSelectors.cloneAppButton).click();
cy.verifyToastMessage(
commonSelectors.toastMessage,
dashboardText.appClonedToast
dashboardText.appClonedToast,
false
);
// cy.get(commonSelectors.cancelButton).click();
cy.apiLogout();
@ -177,14 +180,16 @@ describe("Manage Groups", () => {
cy.createApp(data.appName);
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appCreatedToast
commonText.appCreatedToast,
false
);
cy.backToApps();
cy.deleteApp(data.appName);
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appDeletedToast
commonText.appDeletedToast,
false
);
// Folder operations

View file

@ -204,10 +204,7 @@ describe("Manage Groups", () => {
cy.wait(2500);
cy.deleteApp(data.appName);
cy.verifyToastMessage(
commonSelectors.toastMessage,
commonText.appDeletedToast
);
// Folder operations
createFolder(data.folderName);
@ -522,10 +519,8 @@ describe("Manage Groups", () => {
commonSelectors.buttonSelector(exportAppModalText.exportSelectedVersion)
).click();
cy.exec("ls ./cypress/downloads/").then((result) => {
cy.log(result);
const downloadedAppExportFileName = result.stdout.split("\n")[0];
exportedFilePath = `cypress/downloads/${downloadedAppExportFileName}`;
cy.log(exportedFilePath);
cy.get(importSelectors.dropDownMenu).should("be.visible").click();
cy.get(importSelectors.importOptionInput).selectFile(exportedFilePath, {
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
},
"host": {
"value": "35.202.183.199",
"value": "9.234.17.31",
"encrypted": false
},
"port": {

View file

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

View file

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

View file

@ -2766,7 +2766,7 @@
"name": "restapiStaticUrlG",
"options": {
"method": "get",
"url": "http://34.66.166.236:4000/{{constants.gconstEndpoint}}",
"url": "http://20.29.40.108:4000/{{constants.gconstEndpoint}}",
"url_params": [
[
"",
@ -2814,7 +2814,7 @@
"name": "restapiUrlS",
"options": {
"method": "get",
"url": "http://34.66.166.236:4000/{{secrets.sconstEndpoint}}",
"url": "http://20.29.40.108:4000/{{secrets.sconstEndpoint}}",
"url_params": [
[
"",
@ -2908,7 +2908,7 @@
"name": "restapiUrlGS",
"options": {
"method": "get",
"url": "http://34.66.166.{{constants.gconst}}{{secrets.sconst}}/production",
"url": "http://20.29.40.{{constants.gconst}}{{secrets.sconst}}/production",
"url_params": [
[
"",
@ -3419,7 +3419,7 @@
"environmentId": "dab04b8d-7d1a-468a-b219-b2e1d0169d8c",
"options": {
"url": {
"value": "http://34.66.166.236:4000/{{constants.gconstEndpoint}}",
"value": "http://20.29.40.108:4000/{{constants.gconstEndpoint}}",
"encrypted": false
},
"auth_type": {
@ -3540,7 +3540,7 @@
"environmentId": "dab04b8d-7d1a-468a-b219-b2e1d0169d8c",
"options": {
"url": {
"value": "http://34.66.166.236:4000/{{secrets.sconstEndpoint}}",
"value": "http://20.29.40.108:4000/{{secrets.sconstEndpoint}}",
"encrypted": false
},
"auth_type": {
@ -3782,7 +3782,7 @@
"environmentId": "dab04b8d-7d1a-468a-b219-b2e1d0169d8c",
"options": {
"url": {
"value": "http://34.66.166.{{constants.gconst}}{{secrets.sconst}}/production",
"value": "http://20.29.40.{{constants.gconst}}{{secrets.sconst}}/production",
"encrypted": false
},
"auth_type": {

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