mirror of https://github.com/nocodb/nocodb
89 changed files with 245548 additions and 0 deletions
@ -0,0 +1,638 @@ |
|||||||
|
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node |
||||||
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions |
||||||
|
|
||||||
|
name: "CI/CD" |
||||||
|
on: |
||||||
|
push: |
||||||
|
branches: [develop] |
||||||
|
paths: |
||||||
|
- "packages/nc-gui-v2/**" |
||||||
|
- "scripts/cypress-v2/**" |
||||||
|
- "packages/nocodb/**" |
||||||
|
- ".github/workflows/ci-cd-v2.yml" |
||||||
|
pull_request: |
||||||
|
branches: [develop] |
||||||
|
paths: |
||||||
|
- "packages/nc-gui-v2/**" |
||||||
|
- "scripts/cypress-v2/**" |
||||||
|
- "packages/nocodb/**" |
||||||
|
- ".github/workflows/ci-cd-v2.yml" |
||||||
|
jobs: |
||||||
|
cypress-restTableOps-run-cache: |
||||||
|
runs-on: ubuntu-20.04 |
||||||
|
steps: |
||||||
|
- name: Setup Node |
||||||
|
uses: actions/setup-node@v1 |
||||||
|
with: |
||||||
|
node-version: 16.15.0 |
||||||
|
- name: Checkout |
||||||
|
uses: actions/checkout@v2 |
||||||
|
with: |
||||||
|
fetch-depth: 0 |
||||||
|
- name: Cache node modules |
||||||
|
uses: actions/cache@v2 |
||||||
|
env: |
||||||
|
cache-name: cache-node-modules |
||||||
|
|
||||||
|
with: |
||||||
|
# npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
path: ~/.npm |
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
restore-keys: | |
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
${{ runner.os }}-build- |
||||||
|
${{ runner.os }}- |
||||||
|
- name: Set env |
||||||
|
run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
- name: Cypress run |
||||||
|
uses: cypress-io/github-action@v2 |
||||||
|
with: |
||||||
|
start: | |
||||||
|
npm run start:api:cache |
||||||
|
npm run start:web-v2 |
||||||
|
docker-compose -f ./scripts/docker-compose-cypress.yml up -d |
||||||
|
spec: "./scripts/cypress-v2/integration/test/restTableOps.js" |
||||||
|
wait-on: "http://localhost:8080" |
||||||
|
wait-on-timeout: 1200 |
||||||
|
config-file: scripts/cypress-v2/cypress.json |
||||||
|
- name: Upload screenshots |
||||||
|
if: always() |
||||||
|
uses: actions/upload-artifact@v2 |
||||||
|
with: |
||||||
|
name: cypress-restTableOps-run-cache-snapshots |
||||||
|
path: scripts/cypress-v2/screenshots |
||||||
|
retention-days: 2 |
||||||
|
cypress-restViews-run-cache: |
||||||
|
runs-on: ubuntu-20.04 |
||||||
|
steps: |
||||||
|
- name: Setup Node |
||||||
|
uses: actions/setup-node@v1 |
||||||
|
with: |
||||||
|
node-version: 16.15.0 |
||||||
|
- name: Checkout |
||||||
|
uses: actions/checkout@v2 |
||||||
|
with: |
||||||
|
fetch-depth: 0 |
||||||
|
- name: Cache node modules |
||||||
|
uses: actions/cache@v2 |
||||||
|
env: |
||||||
|
cache-name: cache-node-modules |
||||||
|
|
||||||
|
with: |
||||||
|
# npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
path: ~/.npm |
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
restore-keys: | |
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
${{ runner.os }}-build- |
||||||
|
${{ runner.os }}- |
||||||
|
- name: Set env |
||||||
|
run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
- name: Cypress run |
||||||
|
uses: cypress-io/github-action@v2 |
||||||
|
with: |
||||||
|
start: | |
||||||
|
npm run start:api:cache |
||||||
|
npm run start:web-v2 |
||||||
|
docker-compose -f ./scripts/docker-compose-cypress.yml up -d |
||||||
|
spec: "./scripts/cypress-v2/integration/test/restViews.js" |
||||||
|
wait-on: "http://localhost:8080" |
||||||
|
wait-on-timeout: 1200 |
||||||
|
config-file: scripts/cypress-v2/cypress.json |
||||||
|
- name: Upload screenshots |
||||||
|
if: always() |
||||||
|
uses: actions/upload-artifact@v2 |
||||||
|
with: |
||||||
|
name: cypress-restViews-run-cache-snapshots |
||||||
|
path: scripts/cypress-v2/screenshots |
||||||
|
retention-days: 2 |
||||||
|
cypress-restRoles-run-cache: |
||||||
|
runs-on: ubuntu-20.04 |
||||||
|
steps: |
||||||
|
- name: Setup Node |
||||||
|
uses: actions/setup-node@v1 |
||||||
|
with: |
||||||
|
node-version: 16.15.0 |
||||||
|
- name: Checkout |
||||||
|
uses: actions/checkout@v2 |
||||||
|
with: |
||||||
|
fetch-depth: 0 |
||||||
|
- name: Cache node modules |
||||||
|
uses: actions/cache@v2 |
||||||
|
env: |
||||||
|
cache-name: cache-node-modules |
||||||
|
|
||||||
|
with: |
||||||
|
# npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
path: ~/.npm |
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
restore-keys: | |
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
${{ runner.os }}-build- |
||||||
|
${{ runner.os }}- |
||||||
|
- name: Set env |
||||||
|
run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
- name: Cypress run |
||||||
|
uses: cypress-io/github-action@v2 |
||||||
|
with: |
||||||
|
start: | |
||||||
|
npm run start:api:cache |
||||||
|
npm run start:web-v2 |
||||||
|
docker-compose -f ./scripts/docker-compose-cypress.yml up -d |
||||||
|
spec: "./scripts/cypress-v2/integration/test/restRoles.js" |
||||||
|
wait-on: "http://localhost:8080" |
||||||
|
wait-on-timeout: 1200 |
||||||
|
config-file: scripts/cypress-v2/cypress.json |
||||||
|
- name: Upload screenshots |
||||||
|
if: always() |
||||||
|
uses: actions/upload-artifact@v2 |
||||||
|
with: |
||||||
|
name: cypress-restRoles-run-cache-snapshots |
||||||
|
path: scripts/cypress-v2/screenshots |
||||||
|
retention-days: 2 |
||||||
|
cypress-restMisc-run-cache: |
||||||
|
runs-on: ubuntu-20.04 |
||||||
|
steps: |
||||||
|
- name: Setup Node |
||||||
|
uses: actions/setup-node@v1 |
||||||
|
with: |
||||||
|
node-version: 16.15.0 |
||||||
|
- name: Checkout |
||||||
|
uses: actions/checkout@v2 |
||||||
|
with: |
||||||
|
fetch-depth: 0 |
||||||
|
- name: Cache node modules |
||||||
|
uses: actions/cache@v2 |
||||||
|
env: |
||||||
|
cache-name: cache-node-modules |
||||||
|
|
||||||
|
with: |
||||||
|
# npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
path: ~/.npm |
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
restore-keys: | |
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
${{ runner.os }}-build- |
||||||
|
${{ runner.os }}- |
||||||
|
- name: Set env |
||||||
|
run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
- name: Cypress run |
||||||
|
uses: cypress-io/github-action@v2 |
||||||
|
with: |
||||||
|
start: | |
||||||
|
npm run start:api:cache |
||||||
|
npm run start:web-v2 |
||||||
|
docker-compose -f ./scripts/docker-compose-cypress.yml up -d |
||||||
|
spec: "./scripts/cypress-v2/integration/test/restMisc.js" |
||||||
|
wait-on: "http://localhost:8080" |
||||||
|
wait-on-timeout: 1200 |
||||||
|
config-file: scripts/cypress-v2/cypress.json |
||||||
|
- name: Upload screenshots |
||||||
|
if: always() |
||||||
|
uses: actions/upload-artifact@v2 |
||||||
|
with: |
||||||
|
name: cypress-restMisc-run-cache-snapshots |
||||||
|
path: scripts/cypress-v2/screenshots |
||||||
|
retention-days: 2 |
||||||
|
# cypress-xcdb-restTableOps-run-cache: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# npm run start:xcdb-api:cache |
||||||
|
# npm run start:web-v2 |
||||||
|
# docker-compose -f ./scripts/docker-compose-cypress.yml up -d |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/xcdb-restTableOps.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cypress-xcdb-restTableOps-run-cache-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# cypress-xcdb-restViews-run-cache: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# npm run start:xcdb-api:cache |
||||||
|
# npm run start:web-v2 |
||||||
|
# docker-compose -f ./scripts/docker-compose-cypress.yml up -d |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/xcdb-restViews.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cypress-xcdb-restViews-run-cache-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# cypress-xcdb-restRoles-run-cache: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# npm run start:xcdb-api:cache |
||||||
|
# npm run start:web-v2 |
||||||
|
# docker-compose -f ./scripts/docker-compose-cypress.yml up -d |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/xcdb-restRoles.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cypress-xcdb-restRoles-run-cache-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# cypress-xcdb-restMisc-run-cache: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# npm run start:xcdb-api:cache |
||||||
|
# npm run start:web-v2 |
||||||
|
# docker-compose -f ./scripts/docker-compose-cypress.yml up -d |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/xcdb-restMisc.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cypress-xcdb-restMisc-run-cache-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# cy-quick-sqlite: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# cp ./scripts/cypress/fixtures/quickTest/noco_0_91_7.db ./packages/nocodb/noco.db |
||||||
|
# npm run start:api:cache |
||||||
|
# npm run start:web-v2 |
||||||
|
# docker-compose -f ./scripts/docker-compose-cypress.yml up -d |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/quickTest.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cy-quick-sqlite-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# cy-quick-pg: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# docker-compose -f ./scripts/cypress/docker-compose-pg-cy-quick.yml up -d |
||||||
|
# npm run start:api:cache:pg:cyquick |
||||||
|
# npm run start:web-v2 |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/quickTest.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cy-quick-pg-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# cypress-pg-restTableOps-run-cache: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# npm run start:api:cache |
||||||
|
# npm run start:web-v2 |
||||||
|
# docker-compose -f ./scripts/cypress-v2/docker-compose-pg.yml up -d |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/pg-restTableOps.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cypress-pg-restTableOps-run-cache-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# cypress-pg-restViews-run-cache: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# npm run start:api:cache |
||||||
|
# npm run start:web-v2 |
||||||
|
# docker-compose -f ./scripts/cypress-v2/docker-compose-pg.yml up -d |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/pg-restViews.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cypress-pg-restViews-run-cache-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# cypress-pg-restRoles-run-cache: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# npm run start:api:cache |
||||||
|
# npm run start:web-v2 |
||||||
|
# docker-compose -f ./scripts/cypress-v2/docker-compose-pg.yml up -d |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/pg-restRoles.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cypress-pg-restRoles-run-cache-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# cypress-pg-restMisc-run-cache: |
||||||
|
# runs-on: ubuntu-20.04 |
||||||
|
# steps: |
||||||
|
# - name: Setup Node |
||||||
|
# uses: actions/setup-node@v1 |
||||||
|
# with: |
||||||
|
# node-version: 16.15.0 |
||||||
|
# - name: Checkout |
||||||
|
# uses: actions/checkout@v2 |
||||||
|
# with: |
||||||
|
# fetch-depth: 0 |
||||||
|
# - name: Cache node modules |
||||||
|
# uses: actions/cache@v2 |
||||||
|
# env: |
||||||
|
# cache-name: cache-node-modules |
||||||
|
# |
||||||
|
# with: |
||||||
|
# # npm cache files are stored in `~/.npm` on Linux/macOS |
||||||
|
# path: ~/.npm |
||||||
|
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} |
||||||
|
# restore-keys: | |
||||||
|
# ${{ runner.os }}-build-${{ env.cache-name }}- |
||||||
|
# ${{ runner.os }}-build- |
||||||
|
# ${{ runner.os }}- |
||||||
|
# - name: Set env |
||||||
|
# run: echo "NODE_ENV=test" >> $GITHUB_ENV |
||||||
|
# - name: Cypress run |
||||||
|
# uses: cypress-io/github-action@v2 |
||||||
|
# with: |
||||||
|
# start: | |
||||||
|
# npm run start:api:cache |
||||||
|
# npm run start:web-v2 |
||||||
|
# docker-compose -f ./scripts/cypress-v2/docker-compose-pg.yml up -d |
||||||
|
# spec: "./scripts/cypress-v2/integration/test/pg-restMisc.js" |
||||||
|
# wait-on: "http://localhost:8080, http://localhost:3000/_nuxt/entry.mjs" |
||||||
|
# wait-on-timeout: 1200 |
||||||
|
# config-file: scripts/cypress-v2/cypress.json |
||||||
|
# - name: Upload screenshots |
||||||
|
# if: always() |
||||||
|
# uses: actions/upload-artifact@v2 |
||||||
|
# with: |
||||||
|
# name: cypress-pg-restMisc-run-cache-snapshots |
||||||
|
# path: scripts/cypress-v2/screenshots |
||||||
|
# retention-days: 2 |
||||||
|
# |
@ -0,0 +1,52 @@ |
|||||||
|
{ |
||||||
|
"baseUrl": "http://localhost:3000/", |
||||||
|
"testFiles": [ |
||||||
|
"test/restTableOps.js", |
||||||
|
"test/restViews.js", |
||||||
|
"test/restRoles.js", |
||||||
|
"test/restMisc.js", |
||||||
|
"test/xcdb-restTableOps.js", |
||||||
|
"test/xcdb-restViews.js", |
||||||
|
"test/xcdb-restRoles.js", |
||||||
|
"test/xcdb-restMisc.js", |
||||||
|
"test/pg-restTableOps.js", |
||||||
|
"test/pg-restViews.js", |
||||||
|
"test/pg-restRoles.js", |
||||||
|
"test/pg-restMisc.js", |
||||||
|
"test/quickTest.js" |
||||||
|
], |
||||||
|
"defaultCommandTimeout": 13000, |
||||||
|
"pageLoadTimeout": 600000, |
||||||
|
"viewportWidth": 1980, |
||||||
|
"viewportHeight": 1000, |
||||||
|
"video": false, |
||||||
|
"retries": 0, |
||||||
|
"screenshotOnRunFailure": false, |
||||||
|
"numTestsKeptInMemory": 0, |
||||||
|
"experimentalInteractiveRunEvents": true, |
||||||
|
"env": { |
||||||
|
"testMode": [ |
||||||
|
{ "apiType": "rest", "dbType": "xcdb" }, |
||||||
|
{ "apiType": "rest", "dbType": "mysql" }, |
||||||
|
{ "apiType": "rest", "dbType": "postgres" } |
||||||
|
], |
||||||
|
"db": { |
||||||
|
"host": "127.0.0.1", |
||||||
|
"user": "root", |
||||||
|
"password": "password" |
||||||
|
}, |
||||||
|
"screenshot": false, |
||||||
|
"airtable": { |
||||||
|
"apiKey": "keyn1MR87qgyUsYg4", |
||||||
|
"sharedBase": "https://airtable.com/shr4z0qmh6dg5s3eB" |
||||||
|
} |
||||||
|
}, |
||||||
|
"fixturesFolder": "scripts/cypress-v2/fixtures", |
||||||
|
"integrationFolder": "scripts/cypress-v2/integration", |
||||||
|
"pluginsFile": "scripts/cypress-v2/plugins/index.js", |
||||||
|
"screenshotsFolder": "scripts/cypress-v2/screenshots", |
||||||
|
"videosFolder": "scripts/cypress-v2/videos", |
||||||
|
"downloadsFolder": "scripts/cypress-v2/downloads", |
||||||
|
"supportFile": "scripts/cypress-v2/support/index.js", |
||||||
|
"chromeWebSecurity": false |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
version: "2.1" |
||||||
|
|
||||||
|
services: |
||||||
|
pg96: |
||||||
|
image: postgres:9.6 |
||||||
|
restart: always |
||||||
|
environment: |
||||||
|
POSTGRES_PASSWORD: password |
||||||
|
ports: |
||||||
|
- 5432:5432 |
||||||
|
volumes: |
||||||
|
- ../../packages/nocodb/tests/pg-cy-quick:/docker-entrypoint-initdb.d |
||||||
|
healthcheck: |
||||||
|
test: ["CMD-SHELL", "pg_isready -U postgres"] |
||||||
|
interval: 10s |
||||||
|
timeout: 5s |
||||||
|
retries: 5 |
@ -0,0 +1,17 @@ |
|||||||
|
version: "2.1" |
||||||
|
|
||||||
|
services: |
||||||
|
pg96: |
||||||
|
image: postgres:9.6 |
||||||
|
restart: always |
||||||
|
environment: |
||||||
|
POSTGRES_PASSWORD: password |
||||||
|
ports: |
||||||
|
- 5432:5432 |
||||||
|
volumes: |
||||||
|
- ../../packages/nocodb/tests/pg-sakila-db:/docker-entrypoint-initdb.d |
||||||
|
healthcheck: |
||||||
|
test: ["CMD-SHELL", "pg_isready -U postgres"] |
||||||
|
interval: 10s |
||||||
|
timeout: 5s |
||||||
|
retries: 5 |
@ -0,0 +1,5 @@ |
|||||||
|
{ |
||||||
|
"name": "Using fixtures to represent data", |
||||||
|
"email": "hello@cypress.io", |
||||||
|
"body": "Fixtures are a great way to mock data for responses to routes" |
||||||
|
} |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
@ -0,0 +1,5 @@ |
|||||||
|
{ |
||||||
|
"country": "Afghanistan", |
||||||
|
"city": ["Kabul"] |
||||||
|
} |
||||||
|
|
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"country": "Algeria", |
||||||
|
"city": ["Batna", "Bchar", "Skikda"] |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"country": "Americal Samoa", |
||||||
|
"city": ["Tafuna"] |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"country": "Angola", |
||||||
|
"city": ["Benguela", "Namibe"] |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"country": "Anguilla", |
||||||
|
"city": ["South Hill"] |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"country": "Argentina", |
||||||
|
"city": ["Almirante Brown", "Avellaneda", "Beha Blanca", "Crdoba"] |
||||||
|
} |
Binary file not shown.
@ -0,0 +1,16 @@ |
|||||||
|
|
||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<body> |
||||||
|
|
||||||
|
<iframe |
||||||
|
class="nc-embed" |
||||||
|
src="http://localhost:3000/#/nc/base/7d4b551c-b5e0-41c9-a87b-f3984c21d2c7?embed" |
||||||
|
frameborder="0" |
||||||
|
width="100%" |
||||||
|
height="700" |
||||||
|
style="background: transparent; "></iframe> |
||||||
|
|
||||||
|
</body> |
||||||
|
</html> |
||||||
|
|
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,854 @@ |
|||||||
|
{ |
||||||
|
"name": "nc-xcdb", |
||||||
|
"version": "1.0.0", |
||||||
|
"lockfileVersion": 1, |
||||||
|
"requires": true, |
||||||
|
"dependencies": { |
||||||
|
"@gar/promisify": { |
||||||
|
"version": "1.1.3", |
||||||
|
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", |
||||||
|
"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"@mapbox/node-pre-gyp": { |
||||||
|
"version": "1.0.9", |
||||||
|
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", |
||||||
|
"integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", |
||||||
|
"requires": { |
||||||
|
"detect-libc": "^2.0.0", |
||||||
|
"https-proxy-agent": "^5.0.0", |
||||||
|
"make-dir": "^3.1.0", |
||||||
|
"node-fetch": "^2.6.7", |
||||||
|
"nopt": "^5.0.0", |
||||||
|
"npmlog": "^5.0.1", |
||||||
|
"rimraf": "^3.0.2", |
||||||
|
"semver": "^7.3.5", |
||||||
|
"tar": "^6.1.11" |
||||||
|
} |
||||||
|
}, |
||||||
|
"@npmcli/fs": { |
||||||
|
"version": "1.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", |
||||||
|
"integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"@gar/promisify": "^1.0.1", |
||||||
|
"semver": "^7.3.5" |
||||||
|
} |
||||||
|
}, |
||||||
|
"@npmcli/move-file": { |
||||||
|
"version": "1.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", |
||||||
|
"integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"mkdirp": "^1.0.4", |
||||||
|
"rimraf": "^3.0.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"@tootallnate/once": { |
||||||
|
"version": "1.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", |
||||||
|
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"abbrev": { |
||||||
|
"version": "1.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", |
||||||
|
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" |
||||||
|
}, |
||||||
|
"agent-base": { |
||||||
|
"version": "6.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", |
||||||
|
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", |
||||||
|
"requires": { |
||||||
|
"debug": "4" |
||||||
|
} |
||||||
|
}, |
||||||
|
"agentkeepalive": { |
||||||
|
"version": "4.2.1", |
||||||
|
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", |
||||||
|
"integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"debug": "^4.1.0", |
||||||
|
"depd": "^1.1.2", |
||||||
|
"humanize-ms": "^1.2.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"aggregate-error": { |
||||||
|
"version": "3.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", |
||||||
|
"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"clean-stack": "^2.0.0", |
||||||
|
"indent-string": "^4.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"ansi-regex": { |
||||||
|
"version": "5.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", |
||||||
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" |
||||||
|
}, |
||||||
|
"aproba": { |
||||||
|
"version": "2.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", |
||||||
|
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" |
||||||
|
}, |
||||||
|
"are-we-there-yet": { |
||||||
|
"version": "2.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", |
||||||
|
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", |
||||||
|
"requires": { |
||||||
|
"delegates": "^1.0.0", |
||||||
|
"readable-stream": "^3.6.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"balanced-match": { |
||||||
|
"version": "1.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", |
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" |
||||||
|
}, |
||||||
|
"brace-expansion": { |
||||||
|
"version": "1.1.11", |
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", |
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", |
||||||
|
"requires": { |
||||||
|
"balanced-match": "^1.0.0", |
||||||
|
"concat-map": "0.0.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"cacache": { |
||||||
|
"version": "15.3.0", |
||||||
|
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", |
||||||
|
"integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"@npmcli/fs": "^1.0.0", |
||||||
|
"@npmcli/move-file": "^1.0.1", |
||||||
|
"chownr": "^2.0.0", |
||||||
|
"fs-minipass": "^2.0.0", |
||||||
|
"glob": "^7.1.4", |
||||||
|
"infer-owner": "^1.0.4", |
||||||
|
"lru-cache": "^6.0.0", |
||||||
|
"minipass": "^3.1.1", |
||||||
|
"minipass-collect": "^1.0.2", |
||||||
|
"minipass-flush": "^1.0.5", |
||||||
|
"minipass-pipeline": "^1.2.2", |
||||||
|
"mkdirp": "^1.0.3", |
||||||
|
"p-map": "^4.0.0", |
||||||
|
"promise-inflight": "^1.0.1", |
||||||
|
"rimraf": "^3.0.2", |
||||||
|
"ssri": "^8.0.1", |
||||||
|
"tar": "^6.0.2", |
||||||
|
"unique-filename": "^1.1.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"chownr": { |
||||||
|
"version": "2.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", |
||||||
|
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" |
||||||
|
}, |
||||||
|
"clean-stack": { |
||||||
|
"version": "2.2.0", |
||||||
|
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", |
||||||
|
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"color-support": { |
||||||
|
"version": "1.1.3", |
||||||
|
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", |
||||||
|
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" |
||||||
|
}, |
||||||
|
"concat-map": { |
||||||
|
"version": "0.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", |
||||||
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" |
||||||
|
}, |
||||||
|
"console-control-strings": { |
||||||
|
"version": "1.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", |
||||||
|
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" |
||||||
|
}, |
||||||
|
"debug": { |
||||||
|
"version": "4.3.4", |
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", |
||||||
|
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", |
||||||
|
"requires": { |
||||||
|
"ms": "2.1.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"delegates": { |
||||||
|
"version": "1.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", |
||||||
|
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" |
||||||
|
}, |
||||||
|
"depd": { |
||||||
|
"version": "1.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", |
||||||
|
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"detect-libc": { |
||||||
|
"version": "2.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", |
||||||
|
"integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" |
||||||
|
}, |
||||||
|
"emoji-regex": { |
||||||
|
"version": "8.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", |
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" |
||||||
|
}, |
||||||
|
"encoding": { |
||||||
|
"version": "0.1.13", |
||||||
|
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", |
||||||
|
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"iconv-lite": "^0.6.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"env-paths": { |
||||||
|
"version": "2.2.1", |
||||||
|
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", |
||||||
|
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"err-code": { |
||||||
|
"version": "2.0.3", |
||||||
|
"resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", |
||||||
|
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"fs-minipass": { |
||||||
|
"version": "2.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", |
||||||
|
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", |
||||||
|
"requires": { |
||||||
|
"minipass": "^3.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"fs.realpath": { |
||||||
|
"version": "1.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", |
||||||
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" |
||||||
|
}, |
||||||
|
"gauge": { |
||||||
|
"version": "3.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", |
||||||
|
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", |
||||||
|
"requires": { |
||||||
|
"aproba": "^1.0.3 || ^2.0.0", |
||||||
|
"color-support": "^1.1.2", |
||||||
|
"console-control-strings": "^1.0.0", |
||||||
|
"has-unicode": "^2.0.1", |
||||||
|
"object-assign": "^4.1.1", |
||||||
|
"signal-exit": "^3.0.0", |
||||||
|
"string-width": "^4.2.3", |
||||||
|
"strip-ansi": "^6.0.1", |
||||||
|
"wide-align": "^1.1.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"glob": { |
||||||
|
"version": "7.2.0", |
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", |
||||||
|
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", |
||||||
|
"requires": { |
||||||
|
"fs.realpath": "^1.0.0", |
||||||
|
"inflight": "^1.0.4", |
||||||
|
"inherits": "2", |
||||||
|
"minimatch": "^3.0.4", |
||||||
|
"once": "^1.3.0", |
||||||
|
"path-is-absolute": "^1.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"graceful-fs": { |
||||||
|
"version": "4.2.10", |
||||||
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", |
||||||
|
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"has-unicode": { |
||||||
|
"version": "2.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", |
||||||
|
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" |
||||||
|
}, |
||||||
|
"http-cache-semantics": { |
||||||
|
"version": "4.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", |
||||||
|
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"http-proxy-agent": { |
||||||
|
"version": "4.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", |
||||||
|
"integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"@tootallnate/once": "1", |
||||||
|
"agent-base": "6", |
||||||
|
"debug": "4" |
||||||
|
} |
||||||
|
}, |
||||||
|
"https-proxy-agent": { |
||||||
|
"version": "5.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", |
||||||
|
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", |
||||||
|
"requires": { |
||||||
|
"agent-base": "6", |
||||||
|
"debug": "4" |
||||||
|
} |
||||||
|
}, |
||||||
|
"humanize-ms": { |
||||||
|
"version": "1.2.1", |
||||||
|
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", |
||||||
|
"integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"ms": "^2.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"iconv-lite": { |
||||||
|
"version": "0.6.3", |
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", |
||||||
|
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"imurmurhash": { |
||||||
|
"version": "0.1.4", |
||||||
|
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", |
||||||
|
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"indent-string": { |
||||||
|
"version": "4.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", |
||||||
|
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"infer-owner": { |
||||||
|
"version": "1.0.4", |
||||||
|
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", |
||||||
|
"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"inflight": { |
||||||
|
"version": "1.0.6", |
||||||
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", |
||||||
|
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", |
||||||
|
"requires": { |
||||||
|
"once": "^1.3.0", |
||||||
|
"wrappy": "1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"inherits": { |
||||||
|
"version": "2.0.4", |
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", |
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" |
||||||
|
}, |
||||||
|
"ip": { |
||||||
|
"version": "1.1.5", |
||||||
|
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", |
||||||
|
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"is-fullwidth-code-point": { |
||||||
|
"version": "3.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", |
||||||
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" |
||||||
|
}, |
||||||
|
"is-lambda": { |
||||||
|
"version": "1.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", |
||||||
|
"integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"isexe": { |
||||||
|
"version": "2.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", |
||||||
|
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"lru-cache": { |
||||||
|
"version": "6.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", |
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", |
||||||
|
"requires": { |
||||||
|
"yallist": "^4.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"make-dir": { |
||||||
|
"version": "3.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", |
||||||
|
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", |
||||||
|
"requires": { |
||||||
|
"semver": "^6.0.0" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"semver": { |
||||||
|
"version": "6.3.0", |
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", |
||||||
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"make-fetch-happen": { |
||||||
|
"version": "9.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", |
||||||
|
"integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"agentkeepalive": "^4.1.3", |
||||||
|
"cacache": "^15.2.0", |
||||||
|
"http-cache-semantics": "^4.1.0", |
||||||
|
"http-proxy-agent": "^4.0.1", |
||||||
|
"https-proxy-agent": "^5.0.0", |
||||||
|
"is-lambda": "^1.0.1", |
||||||
|
"lru-cache": "^6.0.0", |
||||||
|
"minipass": "^3.1.3", |
||||||
|
"minipass-collect": "^1.0.2", |
||||||
|
"minipass-fetch": "^1.3.2", |
||||||
|
"minipass-flush": "^1.0.5", |
||||||
|
"minipass-pipeline": "^1.2.4", |
||||||
|
"negotiator": "^0.6.2", |
||||||
|
"promise-retry": "^2.0.1", |
||||||
|
"socks-proxy-agent": "^6.0.0", |
||||||
|
"ssri": "^8.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minimatch": { |
||||||
|
"version": "3.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", |
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", |
||||||
|
"requires": { |
||||||
|
"brace-expansion": "^1.1.7" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minipass": { |
||||||
|
"version": "3.1.6", |
||||||
|
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", |
||||||
|
"integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", |
||||||
|
"requires": { |
||||||
|
"yallist": "^4.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minipass-collect": { |
||||||
|
"version": "1.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", |
||||||
|
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"minipass": "^3.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minipass-fetch": { |
||||||
|
"version": "1.4.1", |
||||||
|
"resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", |
||||||
|
"integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"encoding": "^0.1.12", |
||||||
|
"minipass": "^3.1.0", |
||||||
|
"minipass-sized": "^1.0.3", |
||||||
|
"minizlib": "^2.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minipass-flush": { |
||||||
|
"version": "1.0.5", |
||||||
|
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", |
||||||
|
"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"minipass": "^3.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minipass-pipeline": { |
||||||
|
"version": "1.2.4", |
||||||
|
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", |
||||||
|
"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"minipass": "^3.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minipass-sized": { |
||||||
|
"version": "1.0.3", |
||||||
|
"resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", |
||||||
|
"integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"minipass": "^3.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minizlib": { |
||||||
|
"version": "2.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", |
||||||
|
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", |
||||||
|
"requires": { |
||||||
|
"minipass": "^3.0.0", |
||||||
|
"yallist": "^4.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"mkdirp": { |
||||||
|
"version": "1.0.4", |
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", |
||||||
|
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" |
||||||
|
}, |
||||||
|
"ms": { |
||||||
|
"version": "2.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", |
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" |
||||||
|
}, |
||||||
|
"negotiator": { |
||||||
|
"version": "0.6.3", |
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", |
||||||
|
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"node-addon-api": { |
||||||
|
"version": "4.3.0", |
||||||
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", |
||||||
|
"integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" |
||||||
|
}, |
||||||
|
"node-fetch": { |
||||||
|
"version": "2.6.7", |
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", |
||||||
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", |
||||||
|
"requires": { |
||||||
|
"whatwg-url": "^5.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"node-gyp": { |
||||||
|
"version": "8.4.1", |
||||||
|
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", |
||||||
|
"integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"env-paths": "^2.2.0", |
||||||
|
"glob": "^7.1.4", |
||||||
|
"graceful-fs": "^4.2.6", |
||||||
|
"make-fetch-happen": "^9.1.0", |
||||||
|
"nopt": "^5.0.0", |
||||||
|
"npmlog": "^6.0.0", |
||||||
|
"rimraf": "^3.0.2", |
||||||
|
"semver": "^7.3.5", |
||||||
|
"tar": "^6.1.2", |
||||||
|
"which": "^2.0.2" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"are-we-there-yet": { |
||||||
|
"version": "3.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", |
||||||
|
"integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"delegates": "^1.0.0", |
||||||
|
"readable-stream": "^3.6.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"gauge": { |
||||||
|
"version": "4.0.4", |
||||||
|
"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", |
||||||
|
"integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"aproba": "^1.0.3 || ^2.0.0", |
||||||
|
"color-support": "^1.1.3", |
||||||
|
"console-control-strings": "^1.1.0", |
||||||
|
"has-unicode": "^2.0.1", |
||||||
|
"signal-exit": "^3.0.7", |
||||||
|
"string-width": "^4.2.3", |
||||||
|
"strip-ansi": "^6.0.1", |
||||||
|
"wide-align": "^1.1.5" |
||||||
|
} |
||||||
|
}, |
||||||
|
"npmlog": { |
||||||
|
"version": "6.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", |
||||||
|
"integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"are-we-there-yet": "^3.0.0", |
||||||
|
"console-control-strings": "^1.1.0", |
||||||
|
"gauge": "^4.0.3", |
||||||
|
"set-blocking": "^2.0.0" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"nopt": { |
||||||
|
"version": "5.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", |
||||||
|
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", |
||||||
|
"requires": { |
||||||
|
"abbrev": "1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"npmlog": { |
||||||
|
"version": "5.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", |
||||||
|
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", |
||||||
|
"requires": { |
||||||
|
"are-we-there-yet": "^2.0.0", |
||||||
|
"console-control-strings": "^1.1.0", |
||||||
|
"gauge": "^3.0.0", |
||||||
|
"set-blocking": "^2.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"object-assign": { |
||||||
|
"version": "4.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", |
||||||
|
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" |
||||||
|
}, |
||||||
|
"once": { |
||||||
|
"version": "1.4.0", |
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", |
||||||
|
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", |
||||||
|
"requires": { |
||||||
|
"wrappy": "1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"p-map": { |
||||||
|
"version": "4.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", |
||||||
|
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"aggregate-error": "^3.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"path-is-absolute": { |
||||||
|
"version": "1.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", |
||||||
|
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" |
||||||
|
}, |
||||||
|
"promise-inflight": { |
||||||
|
"version": "1.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", |
||||||
|
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"promise-retry": { |
||||||
|
"version": "2.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", |
||||||
|
"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"err-code": "^2.0.2", |
||||||
|
"retry": "^0.12.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"readable-stream": { |
||||||
|
"version": "3.6.0", |
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", |
||||||
|
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", |
||||||
|
"requires": { |
||||||
|
"inherits": "^2.0.3", |
||||||
|
"string_decoder": "^1.1.1", |
||||||
|
"util-deprecate": "^1.0.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"retry": { |
||||||
|
"version": "0.12.0", |
||||||
|
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", |
||||||
|
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"rimraf": { |
||||||
|
"version": "3.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", |
||||||
|
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", |
||||||
|
"requires": { |
||||||
|
"glob": "^7.1.3" |
||||||
|
} |
||||||
|
}, |
||||||
|
"safe-buffer": { |
||||||
|
"version": "5.2.1", |
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", |
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" |
||||||
|
}, |
||||||
|
"safer-buffer": { |
||||||
|
"version": "2.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", |
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"semver": { |
||||||
|
"version": "7.3.7", |
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", |
||||||
|
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", |
||||||
|
"requires": { |
||||||
|
"lru-cache": "^6.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"set-blocking": { |
||||||
|
"version": "2.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", |
||||||
|
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" |
||||||
|
}, |
||||||
|
"signal-exit": { |
||||||
|
"version": "3.0.7", |
||||||
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", |
||||||
|
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" |
||||||
|
}, |
||||||
|
"smart-buffer": { |
||||||
|
"version": "4.2.0", |
||||||
|
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", |
||||||
|
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"socks": { |
||||||
|
"version": "2.6.2", |
||||||
|
"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", |
||||||
|
"integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"ip": "^1.1.5", |
||||||
|
"smart-buffer": "^4.2.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"socks-proxy-agent": { |
||||||
|
"version": "6.2.0", |
||||||
|
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz", |
||||||
|
"integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"agent-base": "^6.0.2", |
||||||
|
"debug": "^4.3.3", |
||||||
|
"socks": "^2.6.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"sqlite3": { |
||||||
|
"version": "5.0.3", |
||||||
|
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.0.3.tgz", |
||||||
|
"integrity": "sha512-/cDwes7XtTOtKH5zYeJSuiavuaJ6jXxPjebw9lDFxBAwR/DvP0tnJ5MPZQ3zpnNzJBa1G6mPTpB+5O1T+AoSdQ==", |
||||||
|
"requires": { |
||||||
|
"@mapbox/node-pre-gyp": "^1.0.0", |
||||||
|
"node-addon-api": "^4.2.0", |
||||||
|
"node-gyp": "8.x", |
||||||
|
"tar": "^6.1.11" |
||||||
|
} |
||||||
|
}, |
||||||
|
"ssri": { |
||||||
|
"version": "8.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", |
||||||
|
"integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"minipass": "^3.1.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"string-width": { |
||||||
|
"version": "4.2.3", |
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", |
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", |
||||||
|
"requires": { |
||||||
|
"emoji-regex": "^8.0.0", |
||||||
|
"is-fullwidth-code-point": "^3.0.0", |
||||||
|
"strip-ansi": "^6.0.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"string_decoder": { |
||||||
|
"version": "1.3.0", |
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", |
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", |
||||||
|
"requires": { |
||||||
|
"safe-buffer": "~5.2.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"strip-ansi": { |
||||||
|
"version": "6.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", |
||||||
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", |
||||||
|
"requires": { |
||||||
|
"ansi-regex": "^5.0.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"tar": { |
||||||
|
"version": "6.1.11", |
||||||
|
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", |
||||||
|
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", |
||||||
|
"requires": { |
||||||
|
"chownr": "^2.0.0", |
||||||
|
"fs-minipass": "^2.0.0", |
||||||
|
"minipass": "^3.0.0", |
||||||
|
"minizlib": "^2.1.1", |
||||||
|
"mkdirp": "^1.0.3", |
||||||
|
"yallist": "^4.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"tr46": { |
||||||
|
"version": "0.0.3", |
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", |
||||||
|
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" |
||||||
|
}, |
||||||
|
"unique-filename": { |
||||||
|
"version": "1.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", |
||||||
|
"integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"unique-slug": "^2.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"unique-slug": { |
||||||
|
"version": "2.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", |
||||||
|
"integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"imurmurhash": "^0.1.4" |
||||||
|
} |
||||||
|
}, |
||||||
|
"util-deprecate": { |
||||||
|
"version": "1.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", |
||||||
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" |
||||||
|
}, |
||||||
|
"webidl-conversions": { |
||||||
|
"version": "3.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", |
||||||
|
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" |
||||||
|
}, |
||||||
|
"whatwg-url": { |
||||||
|
"version": "5.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", |
||||||
|
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", |
||||||
|
"requires": { |
||||||
|
"tr46": "~0.0.3", |
||||||
|
"webidl-conversions": "^3.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"which": { |
||||||
|
"version": "2.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", |
||||||
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", |
||||||
|
"optional": true, |
||||||
|
"requires": { |
||||||
|
"isexe": "^2.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"wide-align": { |
||||||
|
"version": "1.1.5", |
||||||
|
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", |
||||||
|
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", |
||||||
|
"requires": { |
||||||
|
"string-width": "^1.0.2 || 2 || 3 || 4" |
||||||
|
} |
||||||
|
}, |
||||||
|
"wrappy": { |
||||||
|
"version": "1.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", |
||||||
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" |
||||||
|
}, |
||||||
|
"yallist": { |
||||||
|
"version": "4.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", |
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
{ |
||||||
|
"name": "nc-xcdb", |
||||||
|
"version": "1.0.0", |
||||||
|
"description": "", |
||||||
|
"main": "index.js", |
||||||
|
"scripts": { |
||||||
|
"test": "echo \"Error: no test specified\" && exit 1" |
||||||
|
}, |
||||||
|
"author": "", |
||||||
|
"license": "ISC", |
||||||
|
"dependencies": { |
||||||
|
"sqlite3": "^5.0.3" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
#!/bin/bash |
||||||
|
set -v |
||||||
|
|
||||||
|
rm sakila.db |
||||||
|
sqlite3 sakila.db < ./sqlite-sakila-schema.sql |
||||||
|
sqlite3 sakila.db < ./sqlite-sakila-insert-data.sql |
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
|
||||||
|
Sakila for SQLite is a port of the Sakila example database available for MySQL, which was originally developed by Mike Hillyer of the MySQL AB documentation team. |
||||||
|
This project is designed to help database administrators to decide which database to use for development of new products |
||||||
|
The user can run the same SQL against different kind of databases and compare the performance |
||||||
|
|
||||||
|
License: BSD |
||||||
|
Copyright DB Software Laboratory |
||||||
|
http://www.etl-tools.com |
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
-- Delete data |
||||||
|
DELETE FROM payment |
||||||
|
; |
||||||
|
DELETE FROM rental |
||||||
|
; |
||||||
|
DELETE FROM customer |
||||||
|
; |
||||||
|
DELETE FROM film_category |
||||||
|
; |
||||||
|
DELETE FROM film_text |
||||||
|
; |
||||||
|
DELETE FROM film_actor |
||||||
|
; |
||||||
|
DELETE FROM inventory |
||||||
|
; |
||||||
|
DELETE FROM film |
||||||
|
; |
||||||
|
DELETE FROM category |
||||||
|
; |
||||||
|
DELETE FROM staff |
||||||
|
; |
||||||
|
DELETE FROM store |
||||||
|
; |
||||||
|
DELETE FROM actor |
||||||
|
; |
||||||
|
DELETE FROM address |
||||||
|
; |
||||||
|
DELETE FROM city |
||||||
|
; |
||||||
|
DELETE FROM country |
||||||
|
; |
||||||
|
DELETE FROM language |
||||||
|
; |
@ -0,0 +1,70 @@ |
|||||||
|
/* |
||||||
|
|
||||||
|
Sakila for SQLite is a port of the Sakila example database available for MySQL, which was originally developed by Mike Hillyer of the MySQL AB documentation team. |
||||||
|
This project is designed to help database administrators to decide which database to use for development of new products |
||||||
|
The user can run the same SQL against different kind of databases and compare the performance |
||||||
|
|
||||||
|
License: BSD |
||||||
|
Copyright DB Software Laboratory |
||||||
|
http://www.etl-tools.com |
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
-- Drop Views |
||||||
|
|
||||||
|
DROP VIEW customer_list |
||||||
|
; |
||||||
|
DROP VIEW film_list |
||||||
|
; |
||||||
|
--DROP VIEW nicer_but_slower_film_list; |
||||||
|
DROP VIEW sales_by_film_category |
||||||
|
; |
||||||
|
DROP VIEW sales_by_store |
||||||
|
; |
||||||
|
DROP VIEW staff_list |
||||||
|
; |
||||||
|
|
||||||
|
-- Drop Tables |
||||||
|
|
||||||
|
DROP TABLE payment |
||||||
|
; |
||||||
|
DROP TABLE rental |
||||||
|
; |
||||||
|
DROP TABLE inventory |
||||||
|
; |
||||||
|
DROP TABLE film_text |
||||||
|
; |
||||||
|
DROP TABLE film_category |
||||||
|
; |
||||||
|
DROP TABLE film_actor |
||||||
|
; |
||||||
|
DROP TABLE film |
||||||
|
; |
||||||
|
DROP TABLE language |
||||||
|
; |
||||||
|
DROP TABLE customer |
||||||
|
; |
||||||
|
DROP TABLE actor |
||||||
|
; |
||||||
|
DROP TABLE category |
||||||
|
; |
||||||
|
DROP TABLE store |
||||||
|
; |
||||||
|
DROP TABLE address |
||||||
|
; |
||||||
|
DROP TABLE staff |
||||||
|
; |
||||||
|
DROP TABLE city |
||||||
|
; |
||||||
|
DROP TABLE country |
||||||
|
; |
||||||
|
|
||||||
|
-- Procedures and views |
||||||
|
--drop procedure film_in_stock; |
||||||
|
--drop procedure film_not_in_stock; |
||||||
|
--drop function get_customer_balance; |
||||||
|
--drop function inventory_held_by_customer; |
||||||
|
--drop function inventory_in_stock; |
||||||
|
--drop procedure rewards_report; |
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,647 @@ |
|||||||
|
/* |
||||||
|
|
||||||
|
Sakila for SQLite is a port of the Sakila example database available for MySQL, which was originally developed by Mike Hillyer of the MySQL AB documentation team. |
||||||
|
This project is designed to help database administrators to decide which database to use for development of new products |
||||||
|
The user can run the same SQL against different kind of databases and compare the performance |
||||||
|
|
||||||
|
License: BSD |
||||||
|
Copyright DB Software Laboratory |
||||||
|
http://www.etl-tools.com |
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table actor |
||||||
|
-- |
||||||
|
--DROP TABLE actor; |
||||||
|
|
||||||
|
BEGIN TRANSACTION; |
||||||
|
|
||||||
|
CREATE TABLE actor ( |
||||||
|
actor_id integer PRIMARY KEY AUTOINCREMENT NOT NULL, |
||||||
|
first_name VARCHAR(45) NOT NULL, |
||||||
|
last_name VARCHAR(45) NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_actor_last_name ON actor(last_name) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER actor_trigger_ai AFTER INSERT ON actor |
||||||
|
BEGIN |
||||||
|
UPDATE actor SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER actor_trigger_au AFTER UPDATE ON actor |
||||||
|
BEGIN |
||||||
|
UPDATE actor SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table country |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE country ( |
||||||
|
country_id INTEGER NOT NULL, |
||||||
|
country VARCHAR(50) NOT NULL, |
||||||
|
last_update TIMESTAMP, |
||||||
|
PRIMARY KEY (country_id) |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER country_trigger_ai AFTER INSERT ON country |
||||||
|
BEGIN |
||||||
|
UPDATE country SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER country_trigger_au AFTER UPDATE ON country |
||||||
|
BEGIN |
||||||
|
UPDATE country SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table city |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE city ( |
||||||
|
city_id INTEGER NOT NULL, |
||||||
|
city VARCHAR(50) NOT NULL, |
||||||
|
country_id INTEGER NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (city_id), |
||||||
|
CONSTRAINT fk_city_country FOREIGN KEY (country_id) REFERENCES country (country_id) ON DELETE NO ACTION ON UPDATE CASCADE |
||||||
|
) |
||||||
|
; |
||||||
|
CREATE INDEX idx_fk_country_id ON city(country_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER city_trigger_ai AFTER INSERT ON city |
||||||
|
BEGIN |
||||||
|
UPDATE city SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER city_trigger_au AFTER UPDATE ON city |
||||||
|
BEGIN |
||||||
|
UPDATE city SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table address |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE address ( |
||||||
|
address_id INTEGER NOT NULL, |
||||||
|
address VARCHAR(50) NOT NULL, |
||||||
|
address2 VARCHAR(50) DEFAULT NULL, |
||||||
|
district VARCHAR(20) NOT NULL, |
||||||
|
city_id INTEGER NOT NULL, |
||||||
|
postal_code VARCHAR(10) DEFAULT NULL, |
||||||
|
phone VARCHAR(20) NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (address_id), |
||||||
|
CONSTRAINT fk_address_city FOREIGN KEY (city_id) REFERENCES city (city_id) ON DELETE NO ACTION ON UPDATE CASCADE |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_fk_city_id ON address(city_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER address_trigger_ai AFTER INSERT ON address |
||||||
|
BEGIN |
||||||
|
UPDATE address SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER address_trigger_au AFTER UPDATE ON address |
||||||
|
BEGIN |
||||||
|
UPDATE address SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table language |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE language ( |
||||||
|
language_id INTEGER NOT NULL , |
||||||
|
name CHAR(20) NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (language_id) |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER language_trigger_ai AFTER INSERT ON language |
||||||
|
BEGIN |
||||||
|
UPDATE language SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER language_trigger_au AFTER UPDATE ON language |
||||||
|
BEGIN |
||||||
|
UPDATE language SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table category |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE category ( |
||||||
|
category_id INTEGER NOT NULL, |
||||||
|
name VARCHAR(25) NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (category_id) |
||||||
|
); |
||||||
|
|
||||||
|
CREATE TRIGGER category_trigger_ai AFTER INSERT ON category |
||||||
|
BEGIN |
||||||
|
UPDATE category SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER category_trigger_au AFTER UPDATE ON category |
||||||
|
BEGIN |
||||||
|
UPDATE category SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table customer |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE customer ( |
||||||
|
customer_id INTEGER NOT NULL, |
||||||
|
store_id INTEGER NOT NULL, |
||||||
|
first_name VARCHAR(45) NOT NULL, |
||||||
|
last_name VARCHAR(45) NOT NULL, |
||||||
|
email VARCHAR(50) DEFAULT NULL, |
||||||
|
address_id INTEGER NOT NULL, |
||||||
|
active CHAR(1) DEFAULT 'Y' NOT NULL, |
||||||
|
create_date TIMESTAMP NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (customer_id), |
||||||
|
CONSTRAINT fk_customer_store FOREIGN KEY (store_id) REFERENCES store (store_id) ON DELETE NO ACTION ON UPDATE CASCADE, |
||||||
|
CONSTRAINT fk_customer_address FOREIGN KEY (address_id) REFERENCES address (address_id) ON DELETE NO ACTION ON UPDATE CASCADE |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_customer_fk_store_id ON customer(store_id) |
||||||
|
; |
||||||
|
CREATE INDEX idx_customer_fk_address_id ON customer(address_id) |
||||||
|
; |
||||||
|
CREATE INDEX idx_customer_last_name ON customer(last_name) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER customer_trigger_ai AFTER INSERT ON customer |
||||||
|
BEGIN |
||||||
|
UPDATE customer SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER customer_trigger_au AFTER UPDATE ON customer |
||||||
|
BEGIN |
||||||
|
UPDATE customer SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table film |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE film ( |
||||||
|
film_id INTEGER NOT NULL, |
||||||
|
title VARCHAR(255) NOT NULL, |
||||||
|
description BLOB SUB_TYPE TEXT DEFAULT NULL, |
||||||
|
release_year VARCHAR(4) DEFAULT NULL, |
||||||
|
language_id INTEGER NOT NULL, |
||||||
|
original_language_id INTEGER DEFAULT NULL, |
||||||
|
rental_duration INTEGER DEFAULT 3 NOT NULL, |
||||||
|
rental_rate DECIMAL(4,2) DEFAULT 4.99 NOT NULL, |
||||||
|
length INTEGER DEFAULT NULL, |
||||||
|
replacement_cost DECIMAL(5,2) DEFAULT 19.99 NOT NULL, |
||||||
|
rating VARCHAR(10) DEFAULT 'G', |
||||||
|
special_features VARCHAR(100) DEFAULT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (film_id), |
||||||
|
CONSTRAINT CHECK_special_features CHECK(special_features is null or |
||||||
|
special_features like '%Trailers%' or |
||||||
|
special_features like '%Commentaries%' or |
||||||
|
special_features like '%Deleted Scenes%' or |
||||||
|
special_features like '%Behind the Scenes%'), |
||||||
|
CONSTRAINT CHECK_special_rating CHECK(rating in ('G','PG','PG-13','R','NC-17')), |
||||||
|
CONSTRAINT fk_film_language FOREIGN KEY (language_id) REFERENCES language (language_id) , |
||||||
|
CONSTRAINT fk_film_language_original FOREIGN KEY (original_language_id) REFERENCES language (language_id) |
||||||
|
) |
||||||
|
; |
||||||
|
CREATE INDEX idx_fk_language_id ON film(language_id) |
||||||
|
; |
||||||
|
CREATE INDEX idx_fk_original_language_id ON film(original_language_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER film_trigger_ai AFTER INSERT ON film |
||||||
|
BEGIN |
||||||
|
UPDATE film SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER film_trigger_au AFTER UPDATE ON film |
||||||
|
BEGIN |
||||||
|
UPDATE film SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table film_actor |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE film_actor ( |
||||||
|
actor_id INTEGER NOT NULL, |
||||||
|
film_id INTEGER NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (actor_id,film_id), |
||||||
|
CONSTRAINT fk_film_actor_actor FOREIGN KEY (actor_id) REFERENCES actor (actor_id) ON DELETE NO ACTION ON UPDATE CASCADE, |
||||||
|
CONSTRAINT fk_film_actor_film FOREIGN KEY (film_id) REFERENCES film (film_id) ON DELETE NO ACTION ON UPDATE CASCADE |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_fk_film_actor_film ON film_actor(film_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_fk_film_actor_actor ON film_actor(actor_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER film_actor_trigger_ai AFTER INSERT ON film_actor |
||||||
|
BEGIN |
||||||
|
UPDATE film_actor SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER film_actor_trigger_au AFTER UPDATE ON film_actor |
||||||
|
BEGIN |
||||||
|
UPDATE film_actor SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table film_category |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE film_category ( |
||||||
|
film_id INTEGER NOT NULL, |
||||||
|
category_id INTEGER NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (film_id, category_id), |
||||||
|
CONSTRAINT fk_film_category_film FOREIGN KEY (film_id) REFERENCES film (film_id) ON DELETE NO ACTION ON UPDATE CASCADE, |
||||||
|
CONSTRAINT fk_film_category_category FOREIGN KEY (category_id) REFERENCES category (category_id) ON DELETE NO ACTION ON UPDATE CASCADE |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_fk_film_category_film ON film_category(film_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_fk_film_category_category ON film_category(category_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER film_category_trigger_ai AFTER INSERT ON film_category |
||||||
|
BEGIN |
||||||
|
UPDATE film_category SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER film_category_trigger_au AFTER UPDATE ON film_category |
||||||
|
BEGIN |
||||||
|
UPDATE film_category SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table film_text |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE film_text ( |
||||||
|
film_id INTEGER NOT NULL, |
||||||
|
title VARCHAR(255) NOT NULL, |
||||||
|
description BLOB SUB_TYPE TEXT, |
||||||
|
PRIMARY KEY (film_id) |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table inventory |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE inventory ( |
||||||
|
inventory_id INTEGER NOT NULL, |
||||||
|
film_id INTEGER NOT NULL, |
||||||
|
store_id INTEGER NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (inventory_id), |
||||||
|
CONSTRAINT fk_inventory_store FOREIGN KEY (store_id) REFERENCES store (store_id) ON DELETE NO ACTION ON UPDATE CASCADE, |
||||||
|
CONSTRAINT fk_inventory_film FOREIGN KEY (film_id) REFERENCES film (film_id) ON DELETE NO ACTION ON UPDATE CASCADE |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_fk_film_id ON inventory(film_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_fk_film_id_store_id ON inventory(store_id,film_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER inventory_trigger_ai AFTER INSERT ON inventory |
||||||
|
BEGIN |
||||||
|
UPDATE inventory SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER inventory_trigger_au AFTER UPDATE ON inventory |
||||||
|
BEGIN |
||||||
|
UPDATE inventory SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table staff |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE staff ( |
||||||
|
staff_id INTEGER NOT NULL, |
||||||
|
first_name VARCHAR(45) NOT NULL, |
||||||
|
last_name VARCHAR(45) NOT NULL, |
||||||
|
address_id INTEGER NOT NULL, |
||||||
|
picture BLOB DEFAULT NULL, |
||||||
|
email VARCHAR(50) DEFAULT NULL, |
||||||
|
store_id INTEGER NOT NULL, |
||||||
|
active INTEGER DEFAULT 1 NOT NULL, |
||||||
|
username VARCHAR(16) NOT NULL, |
||||||
|
password VARCHAR(40) DEFAULT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (staff_id), |
||||||
|
CONSTRAINT fk_staff_store FOREIGN KEY (store_id) REFERENCES store (store_id) ON DELETE NO ACTION ON UPDATE CASCADE, |
||||||
|
CONSTRAINT fk_staff_address FOREIGN KEY (address_id) REFERENCES address (address_id) ON DELETE NO ACTION ON UPDATE CASCADE |
||||||
|
) |
||||||
|
; |
||||||
|
CREATE INDEX idx_fk_staff_store_id ON staff(store_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_fk_staff_address_id ON staff(address_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER staff_trigger_ai AFTER INSERT ON staff |
||||||
|
BEGIN |
||||||
|
UPDATE staff SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER staff_trigger_au AFTER UPDATE ON staff |
||||||
|
BEGIN |
||||||
|
UPDATE staff SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table store |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE store ( |
||||||
|
store_id INTEGER NOT NULL, |
||||||
|
manager_staff_id INTEGER NOT NULL, |
||||||
|
address_id INTEGER NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (store_id), |
||||||
|
CONSTRAINT fk_store_staff FOREIGN KEY (manager_staff_id) REFERENCES staff (staff_id) , |
||||||
|
CONSTRAINT fk_store_address FOREIGN KEY (address_id) REFERENCES address (address_id) |
||||||
|
) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_store_fk_manager_staff_id ON store(manager_staff_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE INDEX idx_fk_store_address ON store(address_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER store_trigger_ai AFTER INSERT ON store |
||||||
|
BEGIN |
||||||
|
UPDATE store SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER store_trigger_au AFTER UPDATE ON store |
||||||
|
BEGIN |
||||||
|
UPDATE store SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- Table structure for table payment |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE TABLE payment ( |
||||||
|
payment_id INTEGER NOT NULL, |
||||||
|
customer_id INTEGER NOT NULL, |
||||||
|
staff_id INTEGER NOT NULL, |
||||||
|
rental_id INTEGER DEFAULT NULL, |
||||||
|
amount DECIMAL(5,2) NOT NULL, |
||||||
|
payment_date TIMESTAMP NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (payment_id), |
||||||
|
CONSTRAINT fk_payment_rental FOREIGN KEY (rental_id) REFERENCES rental (rental_id) ON DELETE SET NULL ON UPDATE CASCADE, |
||||||
|
CONSTRAINT fk_payment_customer FOREIGN KEY (customer_id) REFERENCES customer (customer_id) , |
||||||
|
CONSTRAINT fk_payment_staff FOREIGN KEY (staff_id) REFERENCES staff (staff_id) |
||||||
|
) |
||||||
|
; |
||||||
|
CREATE INDEX idx_fk_staff_id ON payment(staff_id) |
||||||
|
; |
||||||
|
CREATE INDEX idx_fk_customer_id ON payment(customer_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER payment_trigger_ai AFTER INSERT ON payment |
||||||
|
BEGIN |
||||||
|
UPDATE payment SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER payment_trigger_au AFTER UPDATE ON payment |
||||||
|
BEGIN |
||||||
|
UPDATE payment SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TABLE rental ( |
||||||
|
rental_id INTEGER NOT NULL, |
||||||
|
rental_date TIMESTAMP NOT NULL, |
||||||
|
inventory_id INTEGER NOT NULL, |
||||||
|
customer_id INTEGER NOT NULL, |
||||||
|
return_date TIMESTAMP DEFAULT NULL, |
||||||
|
staff_id INTEGER NOT NULL, |
||||||
|
last_update TIMESTAMP NOT NULL, |
||||||
|
PRIMARY KEY (rental_id), |
||||||
|
CONSTRAINT fk_rental_staff FOREIGN KEY (staff_id) REFERENCES staff (staff_id) , |
||||||
|
CONSTRAINT fk_rental_inventory FOREIGN KEY (inventory_id) REFERENCES inventory (inventory_id) , |
||||||
|
CONSTRAINT fk_rental_customer FOREIGN KEY (customer_id) REFERENCES customer (customer_id) |
||||||
|
) |
||||||
|
; |
||||||
|
CREATE INDEX idx_rental_fk_inventory_id ON rental(inventory_id) |
||||||
|
; |
||||||
|
CREATE INDEX idx_rental_fk_customer_id ON rental(customer_id) |
||||||
|
; |
||||||
|
CREATE INDEX idx_rental_fk_staff_id ON rental(staff_id) |
||||||
|
; |
||||||
|
CREATE UNIQUE INDEX idx_rental_uq ON rental (rental_date,inventory_id,customer_id) |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER rental_trigger_ai AFTER INSERT ON rental |
||||||
|
BEGIN |
||||||
|
UPDATE rental SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
|
||||||
|
CREATE TRIGGER rental_trigger_au AFTER UPDATE ON rental |
||||||
|
BEGIN |
||||||
|
UPDATE rental SET last_update = DATETIME('NOW') WHERE rowid = new.rowid; |
||||||
|
END |
||||||
|
; |
||||||
|
-- |
||||||
|
-- View structure for view customer_list |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE VIEW customer_list |
||||||
|
AS |
||||||
|
SELECT cu.customer_id AS ID, |
||||||
|
cu.first_name||' '||cu.last_name AS name, |
||||||
|
a.address AS address, |
||||||
|
a.postal_code AS zip_code, |
||||||
|
a.phone AS phone, |
||||||
|
city.city AS city, |
||||||
|
country.country AS country, |
||||||
|
case when cu.active=1 then 'active' else '' end AS notes, |
||||||
|
cu.store_id AS SID |
||||||
|
FROM customer AS cu JOIN address AS a ON cu.address_id = a.address_id JOIN city ON a.city_id = city.city_id |
||||||
|
JOIN country ON city.country_id = country.country_id |
||||||
|
; |
||||||
|
-- |
||||||
|
-- View structure for view film_list |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE VIEW film_list |
||||||
|
AS |
||||||
|
SELECT film.film_id AS FID, |
||||||
|
film.title AS title, |
||||||
|
film.description AS description, |
||||||
|
category.name AS category, |
||||||
|
film.rental_rate AS price, |
||||||
|
film.length AS length, |
||||||
|
film.rating AS rating, |
||||||
|
actor.first_name||' '||actor.last_name AS actors |
||||||
|
FROM category LEFT JOIN film_category ON category.category_id = film_category.category_id LEFT JOIN film ON film_category.film_id = film.film_id |
||||||
|
JOIN film_actor ON film.film_id = film_actor.film_id |
||||||
|
JOIN actor ON film_actor.actor_id = actor.actor_id |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- View structure for view staff_list |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE VIEW staff_list |
||||||
|
AS |
||||||
|
SELECT s.staff_id AS ID, |
||||||
|
s.first_name||' '||s.last_name AS name, |
||||||
|
a.address AS address, |
||||||
|
a.postal_code AS zip_code, |
||||||
|
a.phone AS phone, |
||||||
|
city.city AS city, |
||||||
|
country.country AS country, |
||||||
|
s.store_id AS SID |
||||||
|
FROM staff AS s JOIN address AS a ON s.address_id = a.address_id JOIN city ON a.city_id = city.city_id |
||||||
|
JOIN country ON city.country_id = country.country_id |
||||||
|
; |
||||||
|
-- |
||||||
|
-- View structure for view sales_by_store |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE VIEW sales_by_store |
||||||
|
AS |
||||||
|
SELECT |
||||||
|
s.store_id |
||||||
|
,c.city||','||cy.country AS store |
||||||
|
,m.first_name||' '||m.last_name AS manager |
||||||
|
,SUM(p.amount) AS total_sales |
||||||
|
FROM payment AS p |
||||||
|
INNER JOIN rental AS r ON p.rental_id = r.rental_id |
||||||
|
INNER JOIN inventory AS i ON r.inventory_id = i.inventory_id |
||||||
|
INNER JOIN store AS s ON i.store_id = s.store_id |
||||||
|
INNER JOIN address AS a ON s.address_id = a.address_id |
||||||
|
INNER JOIN city AS c ON a.city_id = c.city_id |
||||||
|
INNER JOIN country AS cy ON c.country_id = cy.country_id |
||||||
|
INNER JOIN staff AS m ON s.manager_staff_id = m.staff_id |
||||||
|
GROUP BY |
||||||
|
s.store_id |
||||||
|
, c.city||','||cy.country |
||||||
|
, m.first_name||' '||m.last_name |
||||||
|
; |
||||||
|
-- |
||||||
|
-- View structure for view sales_by_film_category |
||||||
|
-- |
||||||
|
-- Note that total sales will add up to >100% because |
||||||
|
-- some titles belong to more than 1 category |
||||||
|
-- |
||||||
|
|
||||||
|
CREATE VIEW sales_by_film_category |
||||||
|
AS |
||||||
|
SELECT |
||||||
|
c.name AS category |
||||||
|
, SUM(p.amount) AS total_sales |
||||||
|
FROM payment AS p |
||||||
|
INNER JOIN rental AS r ON p.rental_id = r.rental_id |
||||||
|
INNER JOIN inventory AS i ON r.inventory_id = i.inventory_id |
||||||
|
INNER JOIN film AS f ON i.film_id = f.film_id |
||||||
|
INNER JOIN film_category AS fc ON f.film_id = fc.film_id |
||||||
|
INNER JOIN category AS c ON fc.category_id = c.category_id |
||||||
|
GROUP BY c.name |
||||||
|
; |
||||||
|
|
||||||
|
-- |
||||||
|
-- View structure for view actor_info |
||||||
|
-- |
||||||
|
|
||||||
|
/* |
||||||
|
CREATE VIEW actor_info |
||||||
|
AS |
||||||
|
SELECT |
||||||
|
a.actor_id, |
||||||
|
a.first_name, |
||||||
|
a.last_name, |
||||||
|
GROUP_CONCAT(DISTINCT CONCAT(c.name, ': ', |
||||||
|
(SELECT GROUP_CONCAT(f.title ORDER BY f.title SEPARATOR ', ') |
||||||
|
FROM sakila.film f |
||||||
|
INNER JOIN sakila.film_category fc |
||||||
|
ON f.film_id = fc.film_id |
||||||
|
INNER JOIN sakila.film_actor fa |
||||||
|
ON f.film_id = fa.film_id |
||||||
|
WHERE fc.category_id = c.category_id |
||||||
|
AND fa.actor_id = a.actor_id |
||||||
|
) |
||||||
|
) |
||||||
|
ORDER BY c.name SEPARATOR '; ') |
||||||
|
AS film_info |
||||||
|
FROM sakila.actor a |
||||||
|
LEFT JOIN sakila.film_actor fa |
||||||
|
ON a.actor_id = fa.actor_id |
||||||
|
LEFT JOIN sakila.film_category fc |
||||||
|
ON fa.film_id = fc.film_id |
||||||
|
LEFT JOIN sakila.category c |
||||||
|
ON fc.category_id = c.category_id |
||||||
|
GROUP BY a.actor_id, a.first_name, a.last_name; |
||||||
|
*/ |
||||||
|
|
||||||
|
-- TO DO PROCEDURES |
||||||
|
-- TO DO TRIGGERS |
||||||
|
|
||||||
|
END TRANSACTION; |
Binary file not shown.
@ -0,0 +1,277 @@ |
|||||||
|
// Cypress test suite: project pre-configurations
|
||||||
|
//
|
||||||
|
|
||||||
|
import { loginPage, projectsPage } from "../../support/page_objects/navigation"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { |
||||||
|
staticProjects, |
||||||
|
roles, |
||||||
|
isTestSuiteActive, |
||||||
|
getCurrentMode, |
||||||
|
isXcdb, |
||||||
|
setProjectString, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
function prepareSqliteQuery(projId) { |
||||||
|
let sqliteQuery = [ |
||||||
|
`ALTER TABLE "actor" RENAME TO "${projId}actor"`, |
||||||
|
`ALTER TABLE "address" RENAME TO "${projId}address"`, |
||||||
|
`ALTER TABLE "category" RENAME TO "${projId}category"`, |
||||||
|
`ALTER TABLE "city" RENAME TO "${projId}city"`, |
||||||
|
`ALTER TABLE "country" RENAME TO "${projId}country"`, |
||||||
|
`ALTER TABLE "customer" RENAME TO "${projId}customer"`, |
||||||
|
`ALTER TABLE "film" RENAME TO "${projId}film"`, |
||||||
|
`ALTER TABLE "film_actor" RENAME TO "${projId}film_actor"`, |
||||||
|
`ALTER TABLE "film_category" RENAME TO "${projId}film_category"`, |
||||||
|
`ALTER TABLE "film_text" RENAME TO "${projId}film_text"`, |
||||||
|
`ALTER TABLE "inventory" RENAME TO "${projId}inventory"`, |
||||||
|
`ALTER TABLE "language" RENAME TO "${projId}language"`, |
||||||
|
`ALTER TABLE "payment" RENAME TO "${projId}payment"`, |
||||||
|
`ALTER TABLE "rental" RENAME TO "${projId}rental"`, |
||||||
|
`ALTER TABLE "staff" RENAME TO "${projId}staff"`, |
||||||
|
`ALTER TABLE "store" RENAME TO "${projId}store"`, |
||||||
|
`CREATE VIEW ${projId}customer_list
|
||||||
|
AS |
||||||
|
SELECT cu.customer_id AS ID, |
||||||
|
cu.first_name||' '||cu.last_name AS name, |
||||||
|
a.address AS address, |
||||||
|
a.postal_code AS zip_code, |
||||||
|
a.phone AS phone, |
||||||
|
"${projId}city".city AS city, |
||||||
|
"${projId}country".country AS country, |
||||||
|
case when cu.active=1 then 'active' else '' end AS notes, |
||||||
|
cu.store_id AS SID |
||||||
|
FROM "${projId}customer" AS cu JOIN "${projId}address" AS a ON cu.address_id = a.address_id JOIN "${projId}city" ON a.city_id = "${projId}city".city_id |
||||||
|
JOIN "${projId}country" ON "${projId}city".country_id = "${projId}country".country_id`,
|
||||||
|
`CREATE VIEW ${projId}film_list
|
||||||
|
AS |
||||||
|
SELECT "${projId}film".film_id AS FID, |
||||||
|
"${projId}film".title AS title, |
||||||
|
"${projId}film".description AS description, |
||||||
|
"${projId}category".name AS category, |
||||||
|
"${projId}film".rental_rate AS price, |
||||||
|
"${projId}film".length AS length, |
||||||
|
"${projId}film".rating AS rating, |
||||||
|
"${projId}actor".first_name||' '||"${projId}actor".last_name AS actors |
||||||
|
FROM "${projId}category" LEFT JOIN "${projId}film_category" ON "${projId}category".category_id = "${projId}film_category".category_id LEFT JOIN "${projId}film" ON "${projId}Film_category".film_id = "${projId}film".film_id |
||||||
|
JOIN "${projId}film_actor" ON "${projId}film".film_id = "${projId}film_actor".film_id |
||||||
|
JOIN "${projId}actor" ON "${projId}film_actor".actor_id = "${projId}actor".actor_id`,
|
||||||
|
`CREATE VIEW ${projId}sales_by_film_category
|
||||||
|
AS |
||||||
|
SELECT |
||||||
|
c.name AS category |
||||||
|
, SUM(p.amount) AS total_sales |
||||||
|
FROM "${projId}payment" AS p |
||||||
|
INNER JOIN "${projId}rental" AS r ON p.rental_id = r.rental_id |
||||||
|
INNER JOIN "${projId}inventory" AS i ON r.inventory_id = i.inventory_id |
||||||
|
INNER JOIN "${projId}film" AS f ON i.film_id = f.film_id |
||||||
|
INNER JOIN "${projId}film_category" AS fc ON f.film_id = fc.film_id |
||||||
|
INNER JOIN "${projId}category" AS c ON fc.category_id = c.category_id |
||||||
|
GROUP BY c.name`,
|
||||||
|
`CREATE VIEW ${projId}sales_by_store
|
||||||
|
AS |
||||||
|
SELECT |
||||||
|
s.store_id |
||||||
|
,c.city||','||cy.country AS store |
||||||
|
,m.first_name||' '||m.last_name AS manager |
||||||
|
,SUM(p.amount) AS total_sales |
||||||
|
FROM "${projId}payment" AS p |
||||||
|
INNER JOIN "${projId}rental" AS r ON p.rental_id = r.rental_id |
||||||
|
INNER JOIN "${projId}inventory" AS i ON r.inventory_id = i.inventory_id |
||||||
|
INNER JOIN "${projId}store" AS s ON i.store_id = s.store_id |
||||||
|
INNER JOIN "${projId}address" AS a ON s.address_id = a.address_id |
||||||
|
INNER JOIN "${projId}city" AS c ON a.city_id = c.city_id |
||||||
|
INNER JOIN "${projId}country" AS cy ON c.country_id = cy.country_id |
||||||
|
INNER JOIN "${projId}staff" AS m ON s.manager_staff_id = m.staff_id |
||||||
|
GROUP BY |
||||||
|
s.store_id |
||||||
|
, c.city||','||cy.country |
||||||
|
, m.first_name||' '||m.last_name`,
|
||||||
|
`CREATE VIEW ${projId}staff_list
|
||||||
|
AS |
||||||
|
SELECT s.staff_id AS ID, |
||||||
|
s.first_name||' '||s.last_name AS name, |
||||||
|
a.address AS address, |
||||||
|
a.postal_code AS zip_code, |
||||||
|
a.phone AS phone, |
||||||
|
"${projId}city".city AS city, |
||||||
|
"${projId}country".country AS country, |
||||||
|
s.store_id AS SID |
||||||
|
FROM "${projId}staff" AS s JOIN "${projId}address" AS a ON s.address_id = a.address_id JOIN "${projId}city" ON a.city_id = "${projId}city".city_id |
||||||
|
JOIN "${projId}country" ON "${projId}city".country_id = "${projId}country".country_id`,
|
||||||
|
// below two are dummy entries to ensure view record exists
|
||||||
|
`CREATE VIEW ${projId}actor_info
|
||||||
|
AS |
||||||
|
SELECT s.staff_id AS ID, |
||||||
|
s.first_name||' '||s.last_name AS name, |
||||||
|
a.address AS address, |
||||||
|
a.postal_code AS zip_code, |
||||||
|
a.phone AS phone, |
||||||
|
"${projId}city".city AS city, |
||||||
|
"${projId}country".country AS country, |
||||||
|
s.store_id AS SID |
||||||
|
FROM "${projId}staff" AS s JOIN "${projId}address" AS a ON s.address_id = a.address_id JOIN "${projId}city" ON a.city_id = "${projId}city".city_id |
||||||
|
JOIN "${projId}country" ON "${projId}city".country_id = "${projId}country".country_id`,
|
||||||
|
`CREATE VIEW ${projId}nice_but_slower_film_list
|
||||||
|
AS |
||||||
|
SELECT s.staff_id AS ID, |
||||||
|
s.first_name||' '||s.last_name AS name, |
||||||
|
a.address AS address, |
||||||
|
a.postal_code AS zip_code, |
||||||
|
a.phone AS phone, |
||||||
|
"${projId}city".city AS city, |
||||||
|
"${projId}country".country AS country, |
||||||
|
s.store_id AS SID |
||||||
|
FROM "${projId}staff" AS s JOIN "${projId}address" AS a ON s.address_id = a.address_id JOIN "${projId}city" ON a.city_id = "${projId}city".city_id |
||||||
|
JOIN "${projId}country" ON "${projId}city".country_id = "${projId}country".country_id`,
|
||||||
|
// `CREATE VIEW ${projId}actor_info
|
||||||
|
// AS
|
||||||
|
// SELECT
|
||||||
|
// a.actor_id AS actor_id,
|
||||||
|
// a.first_name AS first_name,
|
||||||
|
// a.last_name AS last_name,
|
||||||
|
// GROUP_CONCAT(DISTINCT CONCAT(c.name,
|
||||||
|
// ': ',
|
||||||
|
// (SELECT
|
||||||
|
// GROUP_CONCAT(f.title
|
||||||
|
// ORDER BY f.title ASC
|
||||||
|
// SEPARATOR ', ')
|
||||||
|
// FROM
|
||||||
|
// ((${projId}film f
|
||||||
|
// JOIN ${projId}film_category fc ON ((f.film_id = fc.film_id)))
|
||||||
|
// JOIN ${projId}film_actor fa ON ((f.film_id = fa.film_id)))
|
||||||
|
// WHERE
|
||||||
|
// ((fc.category_id = c.category_id)
|
||||||
|
// AND (fa.actor_id = a.actor_id))))
|
||||||
|
// ORDER BY c.name ASC
|
||||||
|
// SEPARATOR '; ') AS ${projId}film_info
|
||||||
|
// FROM
|
||||||
|
// (((actor a
|
||||||
|
// LEFT JOIN ${projId}film_actor fa ON ((a.actor_id = fa.actor_id)))
|
||||||
|
// LEFT JOIN ${projId}film_category fc ON ((fa.film_id = fc.film_id)))
|
||||||
|
// LEFT JOIN ${projId}category c ON ((fc.category_id = c.category_id)))
|
||||||
|
// GROUP BY a.actor_id , a.first_name , a.last_name`,
|
||||||
|
]; |
||||||
|
return sqliteQuery; |
||||||
|
} |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
describe(`Project pre-configurations`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
it("Admin SignUp", () => { |
||||||
|
cy.task("log", "This will be output to the terminal"); |
||||||
|
loginPage.signUp(roles.owner.credentials); |
||||||
|
}); |
||||||
|
|
||||||
|
const createProject = (proj) => { |
||||||
|
it(`Create ${proj.basic.name} project`, () => { |
||||||
|
|
||||||
|
// click home button
|
||||||
|
cy.get(".nc-noco-brand-icon").click(); |
||||||
|
cy.get(".ant-table-content").then((obj) => { |
||||||
|
|
||||||
|
// if project already created, open
|
||||||
|
// else, create a new one
|
||||||
|
if (true == obj[0].innerHTML.includes(proj.basic.name)) { |
||||||
|
projectsPage.openProject(proj.basic.name); |
||||||
|
let projId; |
||||||
|
if (dbType === "xcdb") { |
||||||
|
let query = `SELECT prefix from nc_projects_v2 where title = "sampleREST"; `; |
||||||
|
cy.task("sqliteExecReturnValue", query).then( |
||||||
|
(resolve) => { |
||||||
|
cy.log(resolve); |
||||||
|
projId = resolve.prefix; |
||||||
|
setProjectString(projId); |
||||||
|
cy.log(projId); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
} else { |
||||||
|
projectsPage.createProject(proj.basic, proj.config); |
||||||
|
if (dbType === "xcdb") { |
||||||
|
// store base URL- to re-visit and delete form view later
|
||||||
|
let projId; |
||||||
|
cy.url() |
||||||
|
.then((url) => { |
||||||
|
// project prefix code can include "_"
|
||||||
|
// projId = url.split("_")[1].split("?")[0];
|
||||||
|
let startIdx = url.indexOf("_"); |
||||||
|
let endIdx = url.indexOf("?"); |
||||||
|
projId = url.slice(startIdx + 1, endIdx); |
||||||
|
|
||||||
|
let query = `SELECT prefix from nc_projects_v2 where title = "sampleREST"; `; |
||||||
|
cy.task("sqliteExecReturnValue", query) |
||||||
|
.then((resolve) => { |
||||||
|
cy.log(resolve); |
||||||
|
projId = resolve.prefix; |
||||||
|
cy.log(projId); |
||||||
|
setProjectString(projId); |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let query = |
||||||
|
prepareSqliteQuery(projId); |
||||||
|
for ( |
||||||
|
let i = 0; |
||||||
|
i < query.length; |
||||||
|
i++ |
||||||
|
) { |
||||||
|
cy.task("sqliteExec", query[i]); |
||||||
|
cy.wait(1000); |
||||||
|
} |
||||||
|
}); |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
cy.log(projId); |
||||||
|
mainPage.openMetaTab(); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${projId}actor`, |
||||||
|
`New table, New relation added` |
||||||
|
); |
||||||
|
mainPage.closeMetaTab(); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// hack to disable dark mode
|
||||||
|
cy.fileHook(); |
||||||
|
|
||||||
|
|
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
if ("xcdb" === dbType) { |
||||||
|
createProject(staticProjects.sampleREST); |
||||||
|
} else if (dbType === "mysql") { |
||||||
|
createProject(staticProjects.externalREST); |
||||||
|
} else if (dbType === "postgres") { |
||||||
|
createProject(staticProjects.pgExternalREST); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,110 @@ |
|||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
import { mainPage, settingsPage } from "../../support/page_objects/mainPage"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${ |
||||||
|
dbType === "xcdb" ? "Meta - " : "" |
||||||
|
}${apiType.toUpperCase()} api - Table`, () => {
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
// cy.get(".mdi-close").click({ multiple: true });
|
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
// cy.get(".mdi-close").click({ multiple: true, force: true });
|
||||||
|
}); |
||||||
|
|
||||||
|
const name = "tablex"; |
||||||
|
|
||||||
|
// create a new random table
|
||||||
|
it("Create Table", () => { |
||||||
|
cy.createTable(name); |
||||||
|
}); |
||||||
|
|
||||||
|
// delete newly created table
|
||||||
|
it("Delete Table", () => { |
||||||
|
cy.deleteTable(name, dbType); |
||||||
|
}); |
||||||
|
|
||||||
|
const getAuditCell = (row, col) => { |
||||||
|
return cy.get("tbody > tr").eq(row).find("td.ant-table-cell").eq(col); |
||||||
|
}; |
||||||
|
|
||||||
|
it("Open Audit tab", () => { |
||||||
|
// mainPage.navigationDraw(mainPage.AUDIT).click();
|
||||||
|
settingsPage.openMenu(settingsPage.AUDIT); |
||||||
|
// wait for column headers to appear
|
||||||
|
//
|
||||||
|
cy.get("thead > tr > th.ant-table-cell").should("have.length", 5); |
||||||
|
|
||||||
|
// Audit table entries
|
||||||
|
// [Header] Operation Type, Operation Sub Type, Description, User, Created
|
||||||
|
// [0] TABLE, DELETED, delete table table-x, user@nocodb.com, ...
|
||||||
|
// [1] TABLE, Created, created table table-x, user@nocodb.com, ...
|
||||||
|
|
||||||
|
getAuditCell(0, 0).contains("TABLE").should("exist"); |
||||||
|
getAuditCell(0, 1).contains("DELETED").should("exist"); |
||||||
|
getAuditCell(0, 3).contains("user@nocodb.com").should("exist"); |
||||||
|
|
||||||
|
getAuditCell(1, 0).contains("TABLE").should("exist"); |
||||||
|
getAuditCell(1, 1).contains("CREATED").should("exist"); |
||||||
|
getAuditCell(1, 3).contains("user@nocodb.com").should("exist"); |
||||||
|
|
||||||
|
settingsPage.closeMenu() |
||||||
|
}); |
||||||
|
|
||||||
|
it("Table Rename operation", () => { |
||||||
|
cy.get(".nc-project-tree-tbl-City").should("exist").click(); |
||||||
|
|
||||||
|
cy.renameTable("City", "CityX"); |
||||||
|
|
||||||
|
// verify
|
||||||
|
// 1. Table name in project tree has changed
|
||||||
|
// cy.get(".nc-tbl-title").contains("CityX").should("exist");
|
||||||
|
cy.get(".nc-project-tree-tbl-CityX").should("exist"); |
||||||
|
|
||||||
|
// 2. Table tab name has changed
|
||||||
|
cy.get(`.ant-tabs-tab:contains('CityX'):visible`).should("exist"); |
||||||
|
|
||||||
|
// 3. contents of the table are valid
|
||||||
|
mainPage |
||||||
|
.getCell(`City`, 1) |
||||||
|
.contains("A Corua (La Corua)") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
cy.closeTableTab("CityX"); |
||||||
|
|
||||||
|
// revert re-name operation to not impact rest of test suite
|
||||||
|
cy.renameTable("CityX", "City"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,195 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { |
||||||
|
isTestSuiteActive, |
||||||
|
isXcdb, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
function addNewRow(index, cellValue) { |
||||||
|
cy.get(".nc-add-new-row-btn:visible").should("exist"); |
||||||
|
cy.get(".nc-add-new-row-btn").click(); |
||||||
|
// cy.get("#data-table-form-Title > input").first().type(cellValue);
|
||||||
|
cy.get(".nc-expand-col-Title").find(".nc-cell > input") |
||||||
|
.should("exist") |
||||||
|
.first() |
||||||
|
.clear() |
||||||
|
.type(cellValue); |
||||||
|
|
||||||
|
cy.getActiveDrawer() |
||||||
|
.find("button") |
||||||
|
.contains("Save row") |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
cy.toastWait("updated successfully"); |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
mainPage.getCell("Title", index).contains(cellValue).should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Table Column`, () => { |
||||||
|
const name = "tablex"; |
||||||
|
const colName = "column_name_a"; |
||||||
|
const updatedColName = "updated_column_name"; |
||||||
|
const randVal = "Test@1234.com"; |
||||||
|
const updatedRandVal = "Updated@1234.com"; |
||||||
|
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
cy.createTable(name); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
// delete table
|
||||||
|
after(() => { |
||||||
|
cy.deleteTable(name, dbType); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Create Table Column", () => { |
||||||
|
mainPage.addColumn(colName, name); |
||||||
|
}); |
||||||
|
|
||||||
|
// edit the newly created column
|
||||||
|
it("Edit table column - change datatype", () => { |
||||||
|
|
||||||
|
if (!isXcdb()) { |
||||||
|
cy.get(`th:contains(${colName}) .nc-icon.ant-dropdown-trigger`) |
||||||
|
.trigger("mouseover", { force: true }) |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
cy.get(".nc-column-edit").click(); |
||||||
|
cy.get(".nc-column-edit").should("not.be.visible"); |
||||||
|
|
||||||
|
// change column type and verify
|
||||||
|
cy.get(".nc-column-type-input").last().click(); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains("LongText").click(); |
||||||
|
cy.get(".ant-btn-primary:visible").contains("Save").click(); |
||||||
|
|
||||||
|
cy.toastWait("Column updated"); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// edit the newly created column
|
||||||
|
it("Edit table column - rename", () => { |
||||||
|
cy.get(`th:contains(${colName}) .nc-icon.ant-dropdown-trigger`) |
||||||
|
.trigger("mouseover", { force: true }) |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
cy.get(".nc-column-edit").click(); |
||||||
|
cy.get(".nc-column-edit").should("not.be.visible"); |
||||||
|
|
||||||
|
// rename column and verify
|
||||||
|
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 }) |
||||||
|
.should('exist') |
||||||
|
.clear() |
||||||
|
.type(updatedColName); |
||||||
|
cy.get(".ant-btn-primary:visible").contains("Save").click(); |
||||||
|
|
||||||
|
cy.toastWait("Column updated"); |
||||||
|
|
||||||
|
cy.get(`th:contains(${colName})`).should("not.exist"); |
||||||
|
cy.get(`th:contains(${updatedColName})`).should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
// delete the newly created column
|
||||||
|
it("Delete table column", () => { |
||||||
|
mainPage.deleteColumn(updatedColName); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Add new row", () => { |
||||||
|
addNewRow(1, randVal); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Update row", () => { |
||||||
|
mainPage |
||||||
|
.getRow(1) |
||||||
|
.find('.nc-row-no').should('exist').eq(0).trigger('mouseover', { force: true }) |
||||||
|
cy.get(".nc-row-expand") |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
cy.get(".nc-expand-col-Title").find(".nc-cell > input") |
||||||
|
.should("exist") |
||||||
|
.first() |
||||||
|
.clear() |
||||||
|
.type(updatedRandVal); |
||||||
|
|
||||||
|
cy.getActiveDrawer() |
||||||
|
.find("button") |
||||||
|
.contains("Save row") |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// partial toast message
|
||||||
|
cy.toastWait("updated successfully"); |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
|
||||||
|
mainPage.getCell("Title", 1).contains(randVal).should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Title", 1) |
||||||
|
.contains(updatedRandVal) |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Delete Row", () => { |
||||||
|
mainPage |
||||||
|
.getCell("Title", 1) |
||||||
|
.contains(updatedRandVal) |
||||||
|
.rightclick({ force: true }); |
||||||
|
|
||||||
|
// delete row
|
||||||
|
cy.getActiveMenu() |
||||||
|
.find('.ant-dropdown-menu-item:contains("Delete Row")') |
||||||
|
.first() |
||||||
|
.click({ force: true }); |
||||||
|
cy.get("td").contains(randVal).should("not.exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Select all row check-box validation", () => { |
||||||
|
// add multiple rows
|
||||||
|
addNewRow(1, "a1"); |
||||||
|
addNewRow(2, "a2"); |
||||||
|
addNewRow(3, "a3"); |
||||||
|
addNewRow(4, "a4"); |
||||||
|
addNewRow(5, "a5"); |
||||||
|
|
||||||
|
cy.get('.nc-no-label').should('exist').eq(0).trigger('mouseover', { force: true }) |
||||||
|
cy.get(".ant-checkbox").should('exist') |
||||||
|
.eq(0).click({ force: true }); |
||||||
|
|
||||||
|
// delete selected rows
|
||||||
|
mainPage.getCell("Title", 3).rightclick({ force: true }); |
||||||
|
cy.getActiveMenu() |
||||||
|
.contains("Delete Selected Rows") |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// verify if everything is wiped off
|
||||||
|
mainPage.getCell("Title", 1).contains("a1").should("not.exist"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,199 @@ |
|||||||
|
import { |
||||||
|
isTestSuiteActive, |
||||||
|
isXcdb, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} SQL Views`, () => { |
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
it(`XCDB: SQL View Column operations`, () => { |
||||||
|
// Open one of the views & verify validity of first two entries
|
||||||
|
if (isXcdb()) { |
||||||
|
cy.openViewsTab("CustomerList", 25); |
||||||
|
|
||||||
|
// Record-1 validation
|
||||||
|
mainPage.getCell(`ID`, 1).contains("1").should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`Name`, 1) |
||||||
|
.contains("MARY SMITH") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`Address`, 1) |
||||||
|
.contains("1913 Hanoi Way") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`ZipCode`, 1) |
||||||
|
.contains("35200") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// Record-2 validation
|
||||||
|
mainPage.getCell(`ID`, 2).contains("2").should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`Name`, 2) |
||||||
|
.contains("PATRICIA JOHNSON") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`Address`, 2) |
||||||
|
.contains("1121 Loja Avenue") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`ZipCode`, 2) |
||||||
|
.contains("17886") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// Column operations: Hide
|
||||||
|
mainPage.hideField(`ZipCode`); |
||||||
|
mainPage.unhideField(`ZipCode`); |
||||||
|
|
||||||
|
// Column operations: Sort
|
||||||
|
mainPage.sortField("Name", "Z → A"); |
||||||
|
mainPage |
||||||
|
.getCell(`Name`, 1) |
||||||
|
.contains("ZACHARY HITE") |
||||||
|
.should("exist"); |
||||||
|
mainPage.clearSort(); |
||||||
|
|
||||||
|
// Column operations: Filter
|
||||||
|
mainPage.filterField("Name", "is like", "MARY"); |
||||||
|
mainPage |
||||||
|
.getCell(`Name`, 1) |
||||||
|
.contains("MARY SMITH") |
||||||
|
.should("exist"); |
||||||
|
mainPage.filterReset(); |
||||||
|
|
||||||
|
cy.closeViewsTab("CustomerList"); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
it(`SQL View Column operations`, () => { |
||||||
|
if (!isXcdb()) { |
||||||
|
// Open one of the views & verify validity of first two entries
|
||||||
|
|
||||||
|
cy.openViewsTab("ActorInfo", 25); |
||||||
|
|
||||||
|
// Record-1 validation
|
||||||
|
mainPage.getCell(`ActorId`, 1).contains("1").should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`FirstName`, 1) |
||||||
|
.contains("PENELOPE") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`LastName`, 1) |
||||||
|
.contains("GUINESS") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`FilmInfo`, 1) |
||||||
|
.contains("Animation: ANACONDA CONFESSIONS") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// Record-2 validation
|
||||||
|
mainPage.getCell(`ActorId`, 2).contains("2").should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`FirstName`, 2) |
||||||
|
.contains("NICK") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`LastName`, 2) |
||||||
|
.contains("WAHLBERG") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(`FilmInfo`, 2) |
||||||
|
.contains("Action: BULL SHAWSHANK") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// Column operations: Hide
|
||||||
|
mainPage.hideField("FilmInfo"); |
||||||
|
mainPage.unhideField("FilmInfo"); |
||||||
|
|
||||||
|
// Column operations: Sort
|
||||||
|
mainPage.sortField("FirstName", "Z → A"); |
||||||
|
mainPage |
||||||
|
.getCell(`FirstName`, 1) |
||||||
|
.contains("ZERO") |
||||||
|
.should("exist"); |
||||||
|
mainPage.clearSort(); |
||||||
|
|
||||||
|
// Column operations: Filter
|
||||||
|
mainPage.filterField("FirstName", "is like", "PENELOPE"); |
||||||
|
mainPage |
||||||
|
.getCell(`FirstName`, 1) |
||||||
|
.contains("PENELOPE") |
||||||
|
.should("exist"); |
||||||
|
mainPage.filterReset(); |
||||||
|
|
||||||
|
cy.closeViewsTab("ActorInfo"); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
it(`SQL View List`, () => { |
||||||
|
// confirm if other views exist
|
||||||
|
//
|
||||||
|
cy.openViewsTab("CustomerList", 25); |
||||||
|
cy.closeViewsTab("CustomerList"); |
||||||
|
|
||||||
|
// cy.openViewsTab("FilmList", 25);
|
||||||
|
// cy.closeViewsTab("FilmList");
|
||||||
|
|
||||||
|
// cy.openViewsTab("SalesByFilmCategory", 16);
|
||||||
|
// cy.closeViewsTab("SalesByFilmCategory");
|
||||||
|
|
||||||
|
if (!isXcdb()) { |
||||||
|
// cy.openViewsTab("NicerButSlowerFilmList", 25);
|
||||||
|
// cy.closeViewsTab("NicerButSlowerFilmList");
|
||||||
|
|
||||||
|
// SalesByStore && StaffList contain no entries. Hence marking row count to 0
|
||||||
|
cy.openViewsTab("SalesByStore", 0); |
||||||
|
cy.closeViewsTab("SalesByStore"); |
||||||
|
|
||||||
|
cy.openViewsTab("StaffList", 0); |
||||||
|
cy.closeViewsTab("StaffList"); |
||||||
|
} else { |
||||||
|
cy.openViewsTab("SalesByStore", 2); |
||||||
|
cy.closeViewsTab("SalesByStore"); |
||||||
|
|
||||||
|
cy.openViewsTab("StaffList", 2); |
||||||
|
cy.closeViewsTab("StaffList"); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
// void
|
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,168 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { |
||||||
|
isTestSuiteActive, |
||||||
|
isXcdb, |
||||||
|
getProjectString, |
||||||
|
isPostgres, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} Table/view drag-drop reorder`, () => { |
||||||
|
function validateTreeField(index, tblName) { |
||||||
|
cy.get(`:nth-child(${index}) > .v-list-item__title > .caption`) |
||||||
|
.contains(tblName) |
||||||
|
.should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
}); |
||||||
|
|
||||||
|
/* |
||||||
|
Original order of list items |
||||||
|
Actor, Address, Category, City, Country, Customer, FIlm, FilmText, Language, Payment, Rental Staff |
||||||
|
ActorInfo, Customer List, Film List, NiceButSlowerFilm List, SalesByFilmCategory, SalesByStore, Staff List |
||||||
|
*/ |
||||||
|
|
||||||
|
it(`Table & SQL View list, Drag/drop`, () => { |
||||||
|
// expand tree-view menu
|
||||||
|
// cy.get(".nc-project-tree")
|
||||||
|
// .find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
|
||||||
|
// .should("exist")
|
||||||
|
// .first()
|
||||||
|
// .click({ force: true });
|
||||||
|
|
||||||
|
validateTreeField(1, "Actor"); |
||||||
|
|
||||||
|
// move Actor field down, above Staff (drag, drop)
|
||||||
|
cy.get(".nc-child-draggable-icon-Actor").drag( |
||||||
|
".nc-child-draggable-icon-Film" |
||||||
|
); |
||||||
|
|
||||||
|
validateTreeField(7, "Actor"); |
||||||
|
|
||||||
|
// // move ActorInfo (View) field up to first place (drag, drop)
|
||||||
|
// cy.get(".nc-child-draggable-icon-ActorInfo").drag(
|
||||||
|
// ".nc-child-draggable-icon-Address"
|
||||||
|
// );
|
||||||
|
|
||||||
|
// validateTreeField(1, "ActorInfo");
|
||||||
|
// validateTreeField(2, "Address");
|
||||||
|
// validateTreeField(8, "Actor");
|
||||||
|
|
||||||
|
// // restore ActorInfo field (drag, drop)
|
||||||
|
// cy.get(".nc-child-draggable-icon-ActorInfo").drag(
|
||||||
|
// ".nc-child-draggable-icon-Staff"
|
||||||
|
// );
|
||||||
|
|
||||||
|
// restore Actor field (drag, drop)
|
||||||
|
cy.get(".nc-child-draggable-icon-Actor").drag( |
||||||
|
".nc-child-draggable-icon-Address" |
||||||
|
); |
||||||
|
|
||||||
|
validateTreeField(1, "Actor"); |
||||||
|
validateTreeField(2, "Address"); |
||||||
|
|
||||||
|
// undo project-tree expand operation
|
||||||
|
cy.get(".nc-project-tree") |
||||||
|
.find(".v-list-item__title:contains(Tables)", { |
||||||
|
timeout: 10000, |
||||||
|
}) |
||||||
|
.should("exist") |
||||||
|
.first() |
||||||
|
.click({ force: true }); |
||||||
|
}); |
||||||
|
|
||||||
|
// create new view as specified by 'viewType'
|
||||||
|
// can be - grid/ gallery/ form
|
||||||
|
// wait for toast to appear
|
||||||
|
//
|
||||||
|
function createView(viewType) { |
||||||
|
// click on 'Grid/Gallery' button on Views bar
|
||||||
|
cy.get(`.nc-create-${viewType}-view`).click(); |
||||||
|
|
||||||
|
cy.snipActiveModal(`Modal_createView_${viewType}`); |
||||||
|
|
||||||
|
// Pop up window, click Submit (accepting default name for view)
|
||||||
|
cy.getActiveModal().find("button:contains(Submit)").click(); |
||||||
|
|
||||||
|
cy.toastWait("View created successfully"); |
||||||
|
} |
||||||
|
|
||||||
|
// verify view 'viewName' to be present at position 'index'
|
||||||
|
// index starts from 0
|
||||||
|
function validateViewField(index, viewName) { |
||||||
|
cy.get(".nc-view-item.nc-draggable-child") |
||||||
|
.eq(index) |
||||||
|
.contains(viewName) |
||||||
|
.should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
it(`View (Gallery/ Grid/ Form) re-order`, () => { |
||||||
|
cy.openTableTab("Actor", 25); |
||||||
|
|
||||||
|
// create 3 views, use default names
|
||||||
|
// Actor1, Actor2, Actor3
|
||||||
|
createView("grid"); |
||||||
|
createView("gallery"); |
||||||
|
createView("form"); |
||||||
|
|
||||||
|
// validate position order
|
||||||
|
validateViewField(0, "Actor"); |
||||||
|
validateViewField(1, "Actor1"); |
||||||
|
validateViewField(2, "Actor2"); |
||||||
|
validateViewField(3, "Actor3"); |
||||||
|
|
||||||
|
// move Actor3 field on top (drag, drop)
|
||||||
|
cy.get(".nc-child-draggable-icon-Actor3").drag( |
||||||
|
`.nc-child-draggable-icon-${ |
||||||
|
isXcdb() ? `${getProjectString()}` : `` |
||||||
|
}actor` |
||||||
|
); |
||||||
|
|
||||||
|
// validate new position order, Actor3 on top
|
||||||
|
validateViewField(0, "Actor3"); |
||||||
|
validateViewField(1, "Actor"); |
||||||
|
validateViewField(2, "Actor1"); |
||||||
|
validateViewField(3, "Actor2"); |
||||||
|
|
||||||
|
// delete all created views
|
||||||
|
// click on delete icon (becomes visible on hovering mouse)
|
||||||
|
cy.get(".nc-view-delete-icon").eq(0).click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
cy.get(".nc-view-delete-icon").eq(0).click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
cy.get(".nc-view-delete-icon").eq(0).click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
|
||||||
|
// wind up
|
||||||
|
cy.closeTableTab("Actor"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,172 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { |
||||||
|
isTestSuiteActive, |
||||||
|
isXcdb, |
||||||
|
getProjectString, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} Table/view drag-drop reorder`, () => { |
||||||
|
function validateTreeField(index, tblName) { |
||||||
|
cy.get(`.nc-project-tree-tbl`).eq(index-1).find('.nc-tbl-title').contains(tblName).should('exist'); |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
Original order of list items |
||||||
|
Actor, Address, Category, City, Country, Customer, FIlm, FilmText, Language, Payment, Rental Staff |
||||||
|
ActorInfo, Customer List, Film List, NiceButSlowerFilm List, SalesByFilmCategory, SalesByStore, Staff List |
||||||
|
*/ |
||||||
|
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Table & SQL View list, Drag/drop`, () => { |
||||||
|
// expand tree-view menu
|
||||||
|
// cy.get(".nc-project-tree")
|
||||||
|
// .find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
|
||||||
|
// .should("exist")
|
||||||
|
// .first()
|
||||||
|
// .click({ force: true });
|
||||||
|
|
||||||
|
validateTreeField(1, "Actor"); |
||||||
|
|
||||||
|
// move Actor field down, above Staff (drag, drop)
|
||||||
|
cy.get(".nc-child-draggable-icon-Actor").click({ force: true }); |
||||||
|
cy.get(".nc-child-draggable-icon-Actor").should("be.visible"); |
||||||
|
cy.get(".nc-child-draggable-icon-Actor").drag( |
||||||
|
".nc-child-draggable-icon-Staff", { force: true } |
||||||
|
); |
||||||
|
|
||||||
|
validateTreeField(12, "Actor"); |
||||||
|
|
||||||
|
// // move ActorInfo (View) field up to first place (drag, drop)
|
||||||
|
// cy.get(".nc-child-draggable-icon-ActorInfo").drag(
|
||||||
|
// ".nc-child-draggable-icon-Address"
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// validateTreeField(1, "ActorInfo");
|
||||||
|
// validateTreeField(2, "Address");
|
||||||
|
// validateTreeField(13, "Actor");
|
||||||
|
//
|
||||||
|
// // restore ActorInfo field (drag, drop)
|
||||||
|
// cy.get(".nc-child-draggable-icon-ActorInfo").drag(
|
||||||
|
// ".nc-child-draggable-icon-Actor"
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// // restore Actor field (drag, drop)
|
||||||
|
// cy.get(".nc-child-draggable-icon-Actor").drag(
|
||||||
|
// ".nc-child-draggable-icon-Address"
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// validateTreeField(1, "Actor");
|
||||||
|
// validateTreeField(2, "Address");
|
||||||
|
// validateTreeField(12, "Staff");
|
||||||
|
// validateTreeField(13, "ActorInfo");
|
||||||
|
// validateTreeField(14, "CustomerList");
|
||||||
|
//
|
||||||
|
// // undo project-tree expand operation
|
||||||
|
// cy.get(".nc-project-tree")
|
||||||
|
// .should("exist")
|
||||||
|
// .first()
|
||||||
|
// .click({ force: true });
|
||||||
|
}); |
||||||
|
|
||||||
|
// create new view as specified by 'viewType'
|
||||||
|
// can be - grid/ gallery/ form
|
||||||
|
// wait for toast to appear
|
||||||
|
//
|
||||||
|
function createView(viewType) { |
||||||
|
// click on 'Grid/Gallery' button on Views bar
|
||||||
|
cy.get(`.nc-create-${viewType}-view`).click(); |
||||||
|
|
||||||
|
cy.snipActiveModal(`Modal_createView_${viewType}`); |
||||||
|
|
||||||
|
// Pop up window, click Submit (accepting default name for view)
|
||||||
|
cy.getActiveModal().find("button:contains(Submit)").click(); |
||||||
|
|
||||||
|
cy.toastWait("View created successfully"); |
||||||
|
} |
||||||
|
|
||||||
|
// verify view 'viewName' to be present at position 'index'
|
||||||
|
// index starts from 0
|
||||||
|
function validateViewField(index, viewName) { |
||||||
|
cy.get(".nc-view-item.nc-draggable-child") |
||||||
|
.eq(index) |
||||||
|
.contains(viewName) |
||||||
|
.should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
// exclude@ncv2: to be investigated & fixed
|
||||||
|
it.skip(`View (Gallery/ Grid/ Form) re-order`, () => { |
||||||
|
cy.openTableTab("Actor", 25); |
||||||
|
|
||||||
|
// create 3 views, use default names
|
||||||
|
// Actor1, Actor2, Actor3
|
||||||
|
createView("grid"); |
||||||
|
createView("gallery"); |
||||||
|
createView("form"); |
||||||
|
|
||||||
|
// validate position order
|
||||||
|
validateViewField(0, "Actor"); |
||||||
|
validateViewField(1, "Actor1"); |
||||||
|
validateViewField(2, "Actor2"); |
||||||
|
validateViewField(3, "Actor3"); |
||||||
|
|
||||||
|
// move Actor3 field on top (drag, drop)
|
||||||
|
cy.get(".nc-child-draggable-icon-Actor3").drag( |
||||||
|
`.nc-child-draggable-icon-${ |
||||||
|
isXcdb() ? `${getProjectString()}` : `` |
||||||
|
}Actor` |
||||||
|
); |
||||||
|
|
||||||
|
// validate new position order, Actor3 on top
|
||||||
|
validateViewField(0, "Actor3"); |
||||||
|
validateViewField(1, "Actor"); |
||||||
|
validateViewField(2, "Actor1"); |
||||||
|
validateViewField(3, "Actor2"); |
||||||
|
|
||||||
|
// delete all created views
|
||||||
|
// click on delete icon (becomes visible on hovering mouse)
|
||||||
|
cy.get(".nc-view-delete-icon").eq(0).click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
cy.get(".nc-view-delete-icon").eq(0).click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
cy.get(".nc-view-delete-icon").eq(0).click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
|
||||||
|
// wind up
|
||||||
|
cy.closeTableTab("Actor"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,202 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { loginPage } from "../../support/page_objects/navigation"; |
||||||
|
import { |
||||||
|
getCurrentMode, |
||||||
|
getProjectString, |
||||||
|
isTestSuiteActive, |
||||||
|
isXcdb, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
let projPrefix = `sakila.`; |
||||||
|
let dbCmd = `queryDb`; |
||||||
|
let tblDisplayPrefix = ``; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Meta Sync`, () => { |
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
if (isXcdb()) { |
||||||
|
cy.log(getProjectString()); |
||||||
|
projPrefix = `${getProjectString()}`; |
||||||
|
dbCmd = `sqliteExec`; |
||||||
|
tblDisplayPrefix = `${getProjectString()}`; |
||||||
|
} |
||||||
|
mainPage.tabReset(); |
||||||
|
mainPage.openMetaTab(); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
mainPage.closeMetaTab(); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Create table`, () => { |
||||||
|
// Create Table
|
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`CREATE TABLE ${projPrefix}table1 (id INT NOT NULL, col1 INT NULL, PRIMARY KEY (id))` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`CREATE TABLE ${projPrefix}table2 (id INT NOT NULL, col1 INT NULL, PRIMARY KEY (id))` |
||||||
|
); |
||||||
|
mainPage.metaSyncValidate(`${tblDisplayPrefix}table1`, "New table"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Add relation`, () => { |
||||||
|
// working with relations in sqlite requires table to be deleted & recreated
|
||||||
|
//
|
||||||
|
if (!isXcdb()) { |
||||||
|
// Add relation (FK)
|
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`ALTER TABLE ${projPrefix}table1 ADD INDEX fk1_idx (col1 ASC) VISIBLE` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`ALTER TABLE ${projPrefix}table1 ADD CONSTRAINT fk1 FOREIGN KEY (col1) REFERENCES ${projPrefix}table2 (id) ON DELETE NO ACTION ON UPDATE NO ACTION` |
||||||
|
); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"New relation added" |
||||||
|
); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Remove relation`, () => { |
||||||
|
// working with relations in sqlite requires table to be deleted & recreated
|
||||||
|
//
|
||||||
|
if (!isXcdb()) { |
||||||
|
// Remove relation (FK)
|
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`ALTER TABLE ${projPrefix}table1 DROP FOREIGN KEY fk1` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`ALTER TABLE ${projPrefix}table1 DROP INDEX fk1_idx` |
||||||
|
); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"Relation removed" |
||||||
|
); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Add column`, () => { |
||||||
|
// Add Column
|
||||||
|
let queryString = `ALTER TABLE ${projPrefix}table1 ADD COLUMN newCol VARCHAR(45) NULL AFTER id`; |
||||||
|
if (isXcdb()) |
||||||
|
queryString = `ALTER TABLE ${projPrefix}table1 ADD COLUMN newCol TEXT NULL`; |
||||||
|
cy.task(dbCmd, queryString); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"New column(newCol)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Rename column`, () => { |
||||||
|
// Rename Column
|
||||||
|
let queryString = `ALTER TABLE ${projPrefix}table1 CHANGE COLUMN newCol newColName VARCHAR(45) NULL DEFAULT NULL`; |
||||||
|
if (isXcdb()) |
||||||
|
queryString = `ALTER TABLE ${projPrefix}table1 RENAME COLUMN newCol TO newColName`; |
||||||
|
cy.task(dbCmd, queryString); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"New column(newColName), Column removed(newCol)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Delete column`, () => { |
||||||
|
// Remove Column
|
||||||
|
// to be fixed for SQLITE
|
||||||
|
if (!isXcdb()) { |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`ALTER TABLE ${projPrefix}table1 DROP COLUMN newColName` |
||||||
|
); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"Column removed(newColName)" |
||||||
|
); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Delete table`, () => { |
||||||
|
// DROP TABLE
|
||||||
|
cy.task(dbCmd, `DROP TABLE ${projPrefix}table1`); |
||||||
|
cy.task(dbCmd, `DROP TABLE ${projPrefix}table2`); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"Table removed" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Hide, Filter, Sort`, () => { |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`CREATE TABLE ${projPrefix}table1 (id INT NOT NULL, col1 INT NULL, col2 INT NULL, col3 INT NULL, col4 INT NULL, PRIMARY KEY (id))` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO ${projPrefix}table1 (id, col1, col2, col3, col4) VALUES (1,1,1,1,1), (2,2,2,2,2), (3,3,3,3,3), (4,4,4,4,4), (5,5,5,5,5), (6,6,6,6,6), (7,7,7,7,7), (8,8,8,8,8), (9,9,9,9,9);` |
||||||
|
); |
||||||
|
mainPage.metaSyncValidate(`${tblDisplayPrefix}table1`, "New table"); |
||||||
|
mainPage.closeMetaTab(); |
||||||
|
|
||||||
|
cy.openTableTab("Table1", 9); |
||||||
|
mainPage.hideField("Col1"); |
||||||
|
mainPage.sortField("Col1", "9 → 1"); |
||||||
|
mainPage.filterField(`Col1`, ">=", "5"); |
||||||
|
cy.get(".nc-grid-row").should("have.length", 5); |
||||||
|
cy.closeTableTab("Table1"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Verify`, () => { |
||||||
|
mainPage.openMetaTab(); |
||||||
|
// Rename Column
|
||||||
|
let queryString = `ALTER TABLE ${projPrefix}table1 CHANGE COLUMN col1 newCol INT NULL DEFAULT NULL`; |
||||||
|
if (isXcdb()) |
||||||
|
queryString = `ALTER TABLE ${projPrefix}table1 RENAME COLUMN col1 TO newCol`; |
||||||
|
cy.task(dbCmd, queryString); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"New column(newCol), Column removed(col1)" |
||||||
|
); |
||||||
|
mainPage.closeMetaTab(); |
||||||
|
|
||||||
|
cy.openTableTab("Table1", 9); |
||||||
|
cy.deleteTable("Table1", dbType); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,205 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { loginPage } from "../../support/page_objects/navigation"; |
||||||
|
import { |
||||||
|
getCurrentMode, |
||||||
|
getProjectString, |
||||||
|
isTestSuiteActive, |
||||||
|
isXcdb, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
let projPrefix = `sakila.`; |
||||||
|
let dbCmd = `pgExec`; |
||||||
|
let tblDisplayPrefix = ``; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Meta Sync`, () => { |
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
mainPage.openMetaTab(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
mainPage.closeMetaTab(); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Create table`, () => { |
||||||
|
cy.log("this works"); |
||||||
|
// Create Table
|
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`CREATE TABLE table1( id INT NOT NULL, col1 INT NOT NULL, PRIMARY KEY(id))` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`CREATE TABLE table2( id INT NOT NULL, col1 INT NOT NULL, PRIMARY KEY(id))` |
||||||
|
); |
||||||
|
mainPage.metaSyncValidate(`${tblDisplayPrefix}table1`, "New table"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Add relation`, () => { |
||||||
|
// working with relations in sqlite requires table to be deleted & recreated
|
||||||
|
//
|
||||||
|
// Add relation (FK)
|
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`ALTER TABLE table1 ADD CONSTRAINT fk_idx FOREIGN KEY (id) REFERENCES table2 (id);` |
||||||
|
); |
||||||
|
// cy.task(
|
||||||
|
// dbCmd,
|
||||||
|
// `ALTER TABLE ${projPrefix}table1 ADD CONSTRAINT fk1 FOREIGN KEY (col1) REFERENCES ${projPrefix}table2 (id) ON DELETE NO ACTION ON UPDATE NO ACTION`
|
||||||
|
// );
|
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"New relation added" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Remove relation`, () => { |
||||||
|
// working with relations in sqlite requires table to be deleted & recreated
|
||||||
|
//
|
||||||
|
// Remove relation (FK)
|
||||||
|
cy.task(dbCmd, `ALTER TABLE table1 DROP CONSTRAINT fk_idx`); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"Relation removed" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Add column`, () => { |
||||||
|
// Add Column
|
||||||
|
let queryString = `ALTER TABLE table1 ADD COLUMN newCol INT`; |
||||||
|
cy.task(dbCmd, queryString); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"New column(newcol)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Rename column`, () => { |
||||||
|
// Rename Column
|
||||||
|
let queryString = `ALTER TABLE table1 RENAME COLUMN newCol TO newColName`; |
||||||
|
cy.task(dbCmd, queryString); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"New column(newcolname), Column removed(newcol)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Delete column`, () => { |
||||||
|
// Remove Column
|
||||||
|
cy.task(dbCmd, `ALTER TABLE table1 DROP COLUMN newColName`); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"Column removed(newcolname)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Delete table`, () => { |
||||||
|
// DROP TABLE
|
||||||
|
cy.task(dbCmd, `DROP TABLE IF EXISTS table1`); |
||||||
|
cy.task(dbCmd, `DROP TABLE IF EXISTS table2`); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"Table removed" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Hide, Filter, Sort`, () => { |
||||||
|
// kludge: bulk insert fail.
|
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`CREATE TABLE table1( id INT NOT NULL, col1 INT NOT NULL, col2 INT NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, PRIMARY KEY(id))` |
||||||
|
); |
||||||
|
cy.wait(3000); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO table1 (id, col1, col2, col3, col4) VALUES (1,1,1,1,1)` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO table1 (id, col1, col2, col3, col4) VALUES (2,2,2,2,2)` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO table1 (id, col1, col2, col3, col4) VALUES (3,3,3,3,3)` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO table1 (id, col1, col2, col3, col4) VALUES (4,4,4,4,4)` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO table1 (id, col1, col2, col3, col4) VALUES (5,5,5,5,5)` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO table1 (id, col1, col2, col3, col4) VALUES (6,6,6,6,6)` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO table1 (id, col1, col2, col3, col4) VALUES (7,7,7,7,7)` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO table1 (id, col1, col2, col3, col4) VALUES (8,8,8,8,8)` |
||||||
|
); |
||||||
|
cy.task( |
||||||
|
dbCmd, |
||||||
|
`INSERT INTO table1 (id, col1, col2, col3, col4) VALUES (9,9,9,9,9)` |
||||||
|
); |
||||||
|
mainPage.metaSyncValidate(`${tblDisplayPrefix}table1`, "New table"); |
||||||
|
mainPage.closeMetaTab(); |
||||||
|
|
||||||
|
cy.openTableTab("Table1", 9); |
||||||
|
mainPage.hideField("Col1"); |
||||||
|
mainPage.sortField("Col1", "9 → 1"); |
||||||
|
mainPage.filterField(`Col1`, ">=", "5"); |
||||||
|
cy.get(".nc-grid-row").should("have.length", 5); |
||||||
|
cy.closeTableTab("Table1"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Verify`, () => { |
||||||
|
mainPage.openMetaTab(); |
||||||
|
// Rename Column
|
||||||
|
let queryString = `ALTER TABLE table1 RENAME COLUMN col1 TO newcol`; |
||||||
|
cy.task(dbCmd, queryString); |
||||||
|
mainPage.metaSyncValidate( |
||||||
|
`${tblDisplayPrefix}table1`, |
||||||
|
"New column(newcol), Column removed(col1)" |
||||||
|
); |
||||||
|
mainPage.closeMetaTab(); |
||||||
|
|
||||||
|
cy.openTableTab("Table1", 9); |
||||||
|
// kludge- delete table triggered post sql backend operations doesnt carry any trigger toast
|
||||||
|
cy.deleteTable("Table1", "mysql"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,126 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Table: belongs to, link record`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("City"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("URL validation", () => { |
||||||
|
// column name validation
|
||||||
|
// cy.get(`.project-tab:contains(Country):visible`).should("exist");
|
||||||
|
// URL validation
|
||||||
|
cy.url().should("contain", `table/Country`); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Grid cell chip content validation", () => { |
||||||
|
// grid cell content validation
|
||||||
|
mainPage.getCell("City List", 1) |
||||||
|
.find('.nc-virtual-cell > .chips-wrapper > .chips > .group > .name') |
||||||
|
.contains("Kabul") |
||||||
|
.should('exist'); |
||||||
|
mainPage.getCell("City List", 2) |
||||||
|
.find('.nc-virtual-cell > .chips-wrapper > .chips > .group > .name') |
||||||
|
.contains("Batna") |
||||||
|
.should('exist'); |
||||||
|
mainPage.getCell("City List", 2) |
||||||
|
.find('.nc-virtual-cell > .chips-wrapper > .chips > .group > .name') |
||||||
|
.contains("Bchar") |
||||||
|
.should('exist'); |
||||||
|
mainPage.getCell("City List", 2) |
||||||
|
.find('.nc-virtual-cell > .chips-wrapper > .chips > .group > .name') |
||||||
|
.contains("Skikda") |
||||||
|
.should('exist'); |
||||||
|
}) |
||||||
|
|
||||||
|
it("Expand has-many column", () => { |
||||||
|
mainPage.getCell("City List", 1).should("exist").trigger("mouseover").click(); |
||||||
|
cy.get('.nc-action-icon').eq(0).should('exist').click({ force: true }); |
||||||
|
}); |
||||||
|
|
||||||
|
it.skip("Expand Link record, validate", () => { |
||||||
|
cy.getActiveModal() |
||||||
|
.find("button:contains(Link to 'City')") |
||||||
|
.click() |
||||||
|
.then(() => { |
||||||
|
cy.snipActiveModal("Modal_BT_LinkRecord"); |
||||||
|
|
||||||
|
// Link record form validation
|
||||||
|
cy.getActiveModal().contains("Link Record").should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find("button.mdi-reload") |
||||||
|
.should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find('button:contains("New Record")') |
||||||
|
.should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".child-card") |
||||||
|
.eq(0) |
||||||
|
.contains("A Corua (La Corua)") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
cy.getActiveModal() |
||||||
|
.find("button.mdi-close") |
||||||
|
.click() |
||||||
|
.then(() => { |
||||||
|
cy.getActiveModal() |
||||||
|
.find("button.mdi-close") |
||||||
|
.click(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Belongs to column, validate", () => { |
||||||
|
cy.closeTableTab("Country"); |
||||||
|
cy.openTableTab("City", 25); |
||||||
|
cy.url().should("contain", `table/City`); |
||||||
|
|
||||||
|
// grid cell content validation
|
||||||
|
mainPage.getCell("Country", 1) |
||||||
|
.find('.nc-virtual-cell > .chips-wrapper > .chips > .group > .name') |
||||||
|
.contains("Spain") |
||||||
|
.should('exist'); |
||||||
|
mainPage.getCell("Country", 2) |
||||||
|
.find('.nc-virtual-cell > .chips-wrapper > .chips > .group > .name') |
||||||
|
.contains("Saudi Arabia") |
||||||
|
.should('exist'); |
||||||
|
|
||||||
|
}) |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,135 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - M2M Column validation`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
cy.openTableTab("Actor", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("Actor"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Table column header, URL validation", () => { |
||||||
|
// column name validation
|
||||||
|
// cy.get(`.project-tab:contains(Actor):visible`).should("exist");
|
||||||
|
// URL validation
|
||||||
|
cy.url().should("contain", `table/Actor`); |
||||||
|
}); |
||||||
|
|
||||||
|
it("M2m chip content validation on grid", () => { |
||||||
|
// grid m2m content validation
|
||||||
|
mainPage.getCell("Film List", 1) |
||||||
|
.find('.nc-virtual-cell > .chips-wrapper > .chips > .group > .name') |
||||||
|
.contains("ACADEMY DINOSAUR") |
||||||
|
.should('exist'); |
||||||
|
mainPage.getCell("Film List", 1) |
||||||
|
.find('.nc-virtual-cell > .chips-wrapper > .chips > .group > .name') |
||||||
|
.contains("ANACONDA CONFESSIONS") |
||||||
|
.should('exist'); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Expand m2m column", () => { |
||||||
|
// expand first row
|
||||||
|
mainPage.getCell("Film List", 1).should("exist").trigger("mouseover").click(); |
||||||
|
cy.get('.nc-action-icon').eq(0).should('exist').click({ force: true }); |
||||||
|
|
||||||
|
// GUI-v2 Kludge:
|
||||||
|
// validations
|
||||||
|
// cy.getActiveModal().contains("Film").should("exist");
|
||||||
|
// cy.getActiveModal().find("button.mdi-reload").should("exist");
|
||||||
|
// cy.getActiveModal()
|
||||||
|
// .find("button:contains(Link to 'Film')")
|
||||||
|
// .should("exist");
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-card") |
||||||
|
.eq(0) |
||||||
|
.contains("ACADEMY DINOSAUR") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
// GUI-v2 Kludge:
|
||||||
|
it.skip('Expand "Link to" record, validate', () => { |
||||||
|
cy.getActiveModal() |
||||||
|
.find("button:contains(Link to 'Film')") |
||||||
|
.click() |
||||||
|
.then(() => { |
||||||
|
cy.snipActiveModal("Modal_M2M_LinkToRecord"); |
||||||
|
// Link record form validation
|
||||||
|
cy.getActiveModal().contains("Link Record").should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find("button.mdi-reload") |
||||||
|
.should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find('button:contains("New Record")') |
||||||
|
.should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".child-card") |
||||||
|
.eq(0) |
||||||
|
.contains("ACE GOLDFINGER") |
||||||
|
.should("exist"); |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Expand first linked card, validate", () => { |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-card") |
||||||
|
.eq(0) |
||||||
|
.contains("ACADEMY DINOSAUR", { timeout: 2000 }) |
||||||
|
.click() |
||||||
|
.then(() => { |
||||||
|
// wait to ensure pop up appears before we proceed further
|
||||||
|
cy.wait(1000) |
||||||
|
// Link card validation
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".text-lg") |
||||||
|
.contains("ACADEMY DINOSAUR") |
||||||
|
.should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find('button:contains("Save row")') |
||||||
|
.should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find('button:contains("Cancel")') |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
cy.getActiveModal() |
||||||
|
.find('button:contains("Cancel")') |
||||||
|
.click(); |
||||||
|
cy.getActiveModal().find("button.ant-modal-close").click(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,226 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Filter, Fields, Sort`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open country table
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("Country"); |
||||||
|
}); |
||||||
|
|
||||||
|
describe(`Pagination`, () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
// check pagination
|
||||||
|
it("Check country table - Pagination", () => { |
||||||
|
cy.get(".nc-pagination").should("exist"); |
||||||
|
|
||||||
|
// verify > pagination option
|
||||||
|
mainPage.getPagination(">").click(); |
||||||
|
mainPage |
||||||
|
.getPagination(2) |
||||||
|
.should("have.class", "ant-pagination-item-active"); |
||||||
|
|
||||||
|
// verify < pagination option
|
||||||
|
mainPage.getPagination("<").click(); |
||||||
|
mainPage |
||||||
|
.getPagination(1) |
||||||
|
.should("have.class", "ant-pagination-item-active"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe(`Row operations`, () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
// create new row using + button in header
|
||||||
|
//
|
||||||
|
it.skip("Add row using tool header button", () => { |
||||||
|
// add a row to end of Country table
|
||||||
|
cy.get(".nc-add-new-row-btn").click(); |
||||||
|
cy.get("#data-table-form-Country > input") |
||||||
|
.first() |
||||||
|
.type("Test Country"); |
||||||
|
cy.contains("Save row").filter("button").click(); |
||||||
|
|
||||||
|
cy.toastWait("updated successfully"); |
||||||
|
|
||||||
|
// verify
|
||||||
|
mainPage.getPagination(5).click(); |
||||||
|
// kludge: flicker on load
|
||||||
|
cy.wait(3000) |
||||||
|
mainPage |
||||||
|
.getCell("Country", 10) |
||||||
|
.contains("Test Country") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
// delete single row
|
||||||
|
//
|
||||||
|
it.skip("Delete Row", () => { |
||||||
|
// delete row added in previous step
|
||||||
|
mainPage.getCell("Country", 10).rightclick(); |
||||||
|
cy.getActiveMenu().contains("Delete Row").click(); |
||||||
|
|
||||||
|
// cy.toastWait('Deleted row successfully')
|
||||||
|
|
||||||
|
// verify
|
||||||
|
mainPage.getCell("Country", 10).should("not.exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
// create new row using right click menu option
|
||||||
|
//
|
||||||
|
it("Add row using rightclick menu option", () => { |
||||||
|
// Temporary
|
||||||
|
mainPage.getPagination(5).click(); |
||||||
|
|
||||||
|
mainPage.getCell("Country", 9).rightclick({ force: true }); |
||||||
|
cy.getActiveMenu() |
||||||
|
.contains("Insert new row") |
||||||
|
.click({ force: true }); |
||||||
|
mainPage |
||||||
|
.getCell("Country", 10) |
||||||
|
.dblclick() |
||||||
|
.find("input") |
||||||
|
.type("Test Country-1{enter}"); |
||||||
|
|
||||||
|
mainPage.getCell("Country", 10).rightclick({ force: true }); |
||||||
|
cy.getActiveMenu() |
||||||
|
.contains("Insert new row") |
||||||
|
.click({ force: true }); |
||||||
|
mainPage |
||||||
|
.getCell("Country", 11) |
||||||
|
.dblclick() |
||||||
|
.find("input") |
||||||
|
.type("Test Country-2{enter}"); |
||||||
|
|
||||||
|
// GUI-v2 Kludge:
|
||||||
|
// to move cursor away from input field; enter key is not recognized
|
||||||
|
mainPage.getCell("Country", 10).click() |
||||||
|
|
||||||
|
// verify
|
||||||
|
mainPage |
||||||
|
.getCell("Country", 10) |
||||||
|
.contains("Test Country-1") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Country", 11) |
||||||
|
.contains("Test Country-2") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
// delete selected rows (multiple)
|
||||||
|
//
|
||||||
|
it("Delete Selected", () => { |
||||||
|
cy.get(".ant-checkbox").should('exist') |
||||||
|
.eq(10).click({ force: true }); |
||||||
|
cy.get(".ant-checkbox").should('exist') |
||||||
|
.eq(11).click({ force: true }); |
||||||
|
|
||||||
|
mainPage.getCell("Country", 10).rightclick({ force: true }); |
||||||
|
cy.getActiveMenu() |
||||||
|
.contains("Delete Selected Rows") |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// verify
|
||||||
|
// mainPage.getCell("Country", 10).should("not.exist");
|
||||||
|
// mainPage.getCell("Country", 11).should("not.exist");
|
||||||
|
cy.get( |
||||||
|
`:nth-child(10) > [data-title="Country"]` |
||||||
|
).should("not.exist"); |
||||||
|
cy.get( |
||||||
|
`:nth-child(11) > [data-title="Country"]` |
||||||
|
).should("not.exist"); |
||||||
|
|
||||||
|
mainPage.getPagination(1).click(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
// GUI-v2 Kludge: Disable sort isn't disappearing after clear
|
||||||
|
// describe(`Sort operations`, () => {
|
||||||
|
// beforeEach(() => {
|
||||||
|
// cy.fileHook();
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// it("Enable sort", () => {
|
||||||
|
// mainPage.sortField("Country", "Z → A");
|
||||||
|
// cy.contains("Zambia").should("exist");
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// it("Disable sort", () => {
|
||||||
|
// mainPage.clearSort();
|
||||||
|
// cy.contains("Zambia").should("not.exist");
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
describe("Field Operation", () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
it("Hide field", () => { |
||||||
|
mainPage.hideField("LastUpdate"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Show field", () => { |
||||||
|
mainPage.unhideField("LastUpdate"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe("Filter operations", () => { |
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
it("Create Filter", () => { |
||||||
|
mainPage.filterField("Country", "is equal", "India"); |
||||||
|
// cy.get("td:contains(India)").should("exist");
|
||||||
|
mainPage.getCell("Country", 1) |
||||||
|
.contains("India") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Delete Filter", () => { |
||||||
|
// remove sort and check
|
||||||
|
mainPage.filterReset(); |
||||||
|
mainPage.getCell("Country", 1) |
||||||
|
.contains("India") |
||||||
|
.should("not.exist"); |
||||||
|
// cy.contains("td:contains(India)").should("not.exist");
|
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,246 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { |
||||||
|
isTestSuiteActive, |
||||||
|
isXcdb, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - FORMULA`, () => { |
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open a table to work on views
|
||||||
|
//
|
||||||
|
cy.openTableTab("City", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("City"); |
||||||
|
}); |
||||||
|
|
||||||
|
// Given rowname & expected result for first 10 entries, validate
|
||||||
|
// NOTE: Scroll issue with Cypress automation, to fix
|
||||||
|
// validating partial data, row number 5 to 9
|
||||||
|
//
|
||||||
|
const rowValidation = (rowName, result) => { |
||||||
|
// scroll back
|
||||||
|
// cy.get(
|
||||||
|
// `tbody > :nth-child(1) > [data-col="City"]`
|
||||||
|
// ).scrollIntoView();
|
||||||
|
|
||||||
|
// for (let i = 0; i < 10; i++)
|
||||||
|
for (let i = 3; i < 5; i++) |
||||||
|
mainPage.getCell(rowName, i+1).contains(result[i].toString()).should("exist"); |
||||||
|
// cy.get(`tbody > :nth-child(${i + 1}) > [data-col="${rowName}"]`)
|
||||||
|
// .contains(result[i].toString())
|
||||||
|
// .should("exist");
|
||||||
|
}; |
||||||
|
|
||||||
|
// Routine to create a new look up column
|
||||||
|
//
|
||||||
|
const addFormulaBasedColumn = (columnName, formula) => { |
||||||
|
cy.get(".nc-grid tr > th:last .nc-icon").click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
|
||||||
|
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 }) |
||||||
|
.should('exist') |
||||||
|
.clear() |
||||||
|
.type(columnName); |
||||||
|
cy.get(".nc-column-type-input").last().click().type("Formula"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains("Formula").click(); |
||||||
|
cy.get('textarea.nc-formula-input').click().type(formula, { parseSpecialCharSequences: false }); |
||||||
|
cy.get(".ant-btn-primary").contains("Save").should('exist').click(); |
||||||
|
|
||||||
|
// cy.toastWait(`Column created`);
|
||||||
|
cy.closeTableTab("City"); |
||||||
|
cy.openTableTab("City", 25); |
||||||
|
cy.get(`th[data-title="${columnName}"]`).should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
// routine to delete column
|
||||||
|
//
|
||||||
|
const deleteColumnByName = (columnName) => { |
||||||
|
mainPage.deleteColumn(columnName); |
||||||
|
}; |
||||||
|
|
||||||
|
// routine to edit column
|
||||||
|
//
|
||||||
|
const editColumnByName = (oldName, newName, newFormula) => { |
||||||
|
|
||||||
|
cy.get(`th:contains(${oldName}) .nc-icon.ant-dropdown-trigger`) |
||||||
|
.trigger("mouseover", { force: true }) |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
cy.get(".nc-column-edit").click(); |
||||||
|
cy.get(".nc-column-edit").should("not.be.visible"); |
||||||
|
|
||||||
|
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 }) |
||||||
|
.should('exist') |
||||||
|
.clear() |
||||||
|
.type(newName); |
||||||
|
|
||||||
|
cy.get('textarea.nc-formula-input').click().clear().type(newFormula); |
||||||
|
cy.get(".ant-btn-primary").contains("Save").should('exist').click(); |
||||||
|
cy.toastWait(`Column created`); |
||||||
|
cy.get(`th[data-title="${oldName}"]`).should("not.exist"); |
||||||
|
cy.get(`th[data-title="${newName}"]`).should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// Test case
|
||||||
|
|
||||||
|
// On City table (from Sakila DB), first 10 entries recorded here for verification
|
||||||
|
let cityId = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; |
||||||
|
let countryId = [87, 82, 101, 60, 97, 31, 107, 44, 44, 50]; |
||||||
|
let city = [ |
||||||
|
"A corua (La Corua)", |
||||||
|
"Abha", |
||||||
|
"Abu Dhabi", |
||||||
|
"Acua", |
||||||
|
"Adana", |
||||||
|
"Addis Abeba", |
||||||
|
"Aden", |
||||||
|
"Adoni", |
||||||
|
"Ahmadnagar", |
||||||
|
"Akishima", |
||||||
|
]; |
||||||
|
|
||||||
|
// Temporary locally computed expected results
|
||||||
|
let RESULT_STRING = []; |
||||||
|
let RESULT_MATH_0 = []; |
||||||
|
let RESULT_MATH_1 = []; |
||||||
|
let RESULT_MATH_2 = []; |
||||||
|
let RESULT_WEEKDAY_0 = []; |
||||||
|
let RESULT_WEEKDAY_1 = []; |
||||||
|
|
||||||
|
for (let i = 0; i < 10; i++) { |
||||||
|
// CONCAT, LOWER, UPPER, TRIM
|
||||||
|
RESULT_STRING[i] = `${city[i].toUpperCase()}${city[ |
||||||
|
i |
||||||
|
].toLowerCase()}trimmed`;
|
||||||
|
|
||||||
|
// ADD, AVG, LEN
|
||||||
|
RESULT_MATH_0[i] = |
||||||
|
cityId[i] + |
||||||
|
countryId[i] + |
||||||
|
(cityId[i] + countryId[i]) / 2 + |
||||||
|
city[i].length; |
||||||
|
|
||||||
|
// CEILING, FLOOR, ROUND, MOD, MIN, MAX
|
||||||
|
RESULT_MATH_1[i] = |
||||||
|
Math.ceil(1.4) + |
||||||
|
Math.floor(1.6) + |
||||||
|
Math.round(2.5) + |
||||||
|
(cityId[i] % 3) + |
||||||
|
Math.min(cityId[i], countryId[i]) + |
||||||
|
Math.max(cityId[i], countryId[i]); |
||||||
|
|
||||||
|
// LOG, EXP, POWER, SQRT
|
||||||
|
// only integer verification being computed, hence trunc
|
||||||
|
RESULT_MATH_2[i] = Math.trunc( |
||||||
|
Math.log(cityId[i]) + |
||||||
|
Math.exp(cityId[i]) + |
||||||
|
Math.pow(cityId[i], 3) + |
||||||
|
Math.sqrt(countryId[i]) |
||||||
|
); |
||||||
|
|
||||||
|
// WEEKDAY: starts from Monday
|
||||||
|
RESULT_WEEKDAY_0[i] = 1; |
||||||
|
// WEEKDAY: starts from Sunday
|
||||||
|
RESULT_WEEKDAY_1[i] = 2; |
||||||
|
} |
||||||
|
|
||||||
|
it("Formula: ADD, AVG, LEN", () => { |
||||||
|
addFormulaBasedColumn( |
||||||
|
"NC_MATH_0", |
||||||
|
"ADD({CityId}, {CountryId}) + AVG({CityId}, {CountryId}) + LEN({City})" |
||||||
|
); |
||||||
|
rowValidation("NC_MATH_0", RESULT_MATH_0); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Formula: WEEKDAY", () => { |
||||||
|
editColumnByName( |
||||||
|
"NC_MATH_0", |
||||||
|
"NC_WEEKDAY_0", |
||||||
|
`WEEKDAY("2022-07-19")` |
||||||
|
); |
||||||
|
rowValidation("NC_WEEKDAY_0", RESULT_WEEKDAY_0); |
||||||
|
|
||||||
|
editColumnByName( |
||||||
|
"NC_WEEKDAY_0", |
||||||
|
"NC_WEEKDAY_1", |
||||||
|
`WEEKDAY("2022-07-19", "sunday")` |
||||||
|
); |
||||||
|
rowValidation("NC_WEEKDAY_1", RESULT_WEEKDAY_1); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Formula: CONCAT, LOWER, UPPER, TRIM", () => { |
||||||
|
editColumnByName( |
||||||
|
"NC_WEEKDAY_1", |
||||||
|
"NC_STR_1", |
||||||
|
`CONCAT(UPPER({City}), LOWER({City}), TRIM(' trimmed '))` |
||||||
|
); |
||||||
|
rowValidation("NC_STR_1", RESULT_STRING); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Formula: CEILING, FLOOR, ROUND, MOD, MIN, MAX", () => { |
||||||
|
editColumnByName( |
||||||
|
"NC_STR_1", |
||||||
|
"NC_MATH_1", |
||||||
|
`CEILING(1.4) + FLOOR(1.6) + ROUND(2.5) + MOD({CityId}, 3) + MIN({CityId}, {CountryId}) + MAX({CityId}, {CountryId})` |
||||||
|
); |
||||||
|
rowValidation("NC_MATH_1", RESULT_MATH_1); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Formula: LOG, EXP, POWER, SQRT", () => { |
||||||
|
if (!isXcdb()) { |
||||||
|
// SQLITE doesnt support LOG, EXP, POWER SQRT construct
|
||||||
|
editColumnByName( |
||||||
|
"NC_MATH_1", |
||||||
|
"NC_MATH_2", |
||||||
|
`LOG({CityId}) + EXP({CityId}) + POWER({CityId}, 3) + SQRT({CountryId})` |
||||||
|
); |
||||||
|
rowValidation("NC_MATH_2", RESULT_MATH_2); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
it("Formula: NOW, EDIT & Delete column", () => { |
||||||
|
if (!isXcdb()) editColumnByName("NC_MATH_2", "NC_NOW", `NOW()`); |
||||||
|
else editColumnByName("NC_MATH_1", "NC_NOW", `NOW()`); |
||||||
|
deleteColumnByName("NC_NOW"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* @author Wing-Kam Wong <wingkwong.code@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,116 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - LookUp column`, () => { |
||||||
|
// to retrieve few v-input nodes from their label
|
||||||
|
//
|
||||||
|
const fetchParentFromLabel = (label) => { |
||||||
|
cy.get("label").contains(label).parents(".ant-row").click(); |
||||||
|
}; |
||||||
|
|
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open a table to work on views
|
||||||
|
//
|
||||||
|
cy.openTableTab("City", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("City"); |
||||||
|
}); |
||||||
|
|
||||||
|
// Routine to create a new look up column
|
||||||
|
//
|
||||||
|
const addLookUpColumn = (childTable, childCol) => { |
||||||
|
|
||||||
|
cy.get(".nc-grid tr > th:last .nc-icon").click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
|
||||||
|
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 }) |
||||||
|
.should('exist') |
||||||
|
.clear() |
||||||
|
.type(childCol); |
||||||
|
cy.get(".nc-column-type-input").last().click().type("Lookup"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains("Lookup").click(); |
||||||
|
|
||||||
|
// Configure Child table & column names
|
||||||
|
fetchParentFromLabel("Child table"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains(childTable).click(); |
||||||
|
// cy.getActiveMenu().contains(childTable).click();
|
||||||
|
|
||||||
|
fetchParentFromLabel("Child column"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains(childCol).click(); |
||||||
|
// cy.getActiveMenu().contains(childCol).click();
|
||||||
|
|
||||||
|
cy.get(".ant-btn-primary").contains("Save").should('exist').click(); |
||||||
|
cy.toastWait(`Column created`); |
||||||
|
|
||||||
|
cy.get(`th[data-title="${childCol}"]`).should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
// routine to delete column
|
||||||
|
//
|
||||||
|
const deleteColumnByName = (childCol) => { |
||||||
|
mainPage.deleteColumn(childCol); |
||||||
|
}; |
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// Test case
|
||||||
|
|
||||||
|
it("Add Lookup column (Address, PostalCode) & Delete", () => { |
||||||
|
addLookUpColumn("Address", "PostalCode"); |
||||||
|
|
||||||
|
// Verify first entry, will be displayed as alias here 'childColumn (from childTable)'
|
||||||
|
mainPage.getCell("PostalCode", 1) |
||||||
|
.contains("4166") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
deleteColumnByName("PostalCode"); |
||||||
|
}); |
||||||
|
|
||||||
|
it.skip("Add Lookup column (Country, CountryId) & Delete", () => { |
||||||
|
addLookUpColumn("Country", "CountryId"); |
||||||
|
|
||||||
|
// Verify first entry, will be displayed as alias here 'childColumn (from childTable)'
|
||||||
|
cy.get(`tbody > :nth-child(1) > [data-col="CountryId"]`) |
||||||
|
.contains("87") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
deleteColumnByName("CountryId"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,148 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - RollUp column`, () => { |
||||||
|
// to retrieve few v-input nodes from their label
|
||||||
|
//
|
||||||
|
const fetchParentFromLabel = (label) => { |
||||||
|
cy.get("label").contains(label).parents(".ant-row").click(); |
||||||
|
}; |
||||||
|
|
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open a table to work on views
|
||||||
|
//
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("Country"); |
||||||
|
}); |
||||||
|
|
||||||
|
// Routine to create a new look up column
|
||||||
|
//
|
||||||
|
const addLookUpColumn = ( |
||||||
|
columnName, |
||||||
|
childTable, |
||||||
|
childCol, |
||||||
|
aggregateFunc |
||||||
|
) => { |
||||||
|
|
||||||
|
cy.get(".nc-grid tr > th:last .nc-icon").click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
|
||||||
|
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 }) |
||||||
|
.should('exist') |
||||||
|
.clear() |
||||||
|
.type(childCol); |
||||||
|
cy.get(".nc-column-type-input").last().click().type("Rollup"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains("Rollup").click(); |
||||||
|
|
||||||
|
// Configure Child table & column names
|
||||||
|
fetchParentFromLabel("Child table"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains(childTable).click(); |
||||||
|
|
||||||
|
fetchParentFromLabel("Child column"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains(childCol).click(); |
||||||
|
|
||||||
|
fetchParentFromLabel("Aggregate function"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains(aggregateFunc).click(); |
||||||
|
|
||||||
|
cy.get(".ant-btn-primary").contains("Save").should('exist').click(); |
||||||
|
cy.toastWait(`Column created`); |
||||||
|
|
||||||
|
cy.get(`th[data-title="${childCol}"]`).should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
// routine to delete column
|
||||||
|
//
|
||||||
|
const deleteColumnByName = (columnName) => { |
||||||
|
mainPage.deleteColumn(columnName); |
||||||
|
}; |
||||||
|
|
||||||
|
// routine to edit column
|
||||||
|
//
|
||||||
|
const editColumnByName = (oldName, newName) => { |
||||||
|
// verify if column exists before delete
|
||||||
|
cy.get(`th:contains(${oldName})`).should("exist"); |
||||||
|
|
||||||
|
// delete opiton visible on mouse-over
|
||||||
|
cy.get(`th:contains(${oldName}) .mdi-menu-down`) |
||||||
|
.trigger("mouseover") |
||||||
|
.click(); |
||||||
|
|
||||||
|
// edit/ save on pop-up
|
||||||
|
cy.get(".nc-column-edit").click(); |
||||||
|
cy.get(".nc-column-name-input input").clear().type(newName); |
||||||
|
cy.get(".nc-col-create-or-edit-card").contains("Save").click(); |
||||||
|
|
||||||
|
cy.toastWait("Successfully updated alias"); |
||||||
|
|
||||||
|
// validate if deleted (column shouldnt exist)
|
||||||
|
cy.get(`th:contains(${oldName})`).should("not.exist"); |
||||||
|
cy.get(`th:contains(${newName})`).should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// Test case
|
||||||
|
|
||||||
|
it("Add Rollup column (City, City, count) & Delete", () => { |
||||||
|
addLookUpColumn("RollUpCol_2", "City", "City", "count"); |
||||||
|
|
||||||
|
// Verify first entry, will be displayed as alias here 'childColumn (from childTable)'
|
||||||
|
// intentionally verifying 4th item, as initial items are being masked out by list scroll down
|
||||||
|
mainPage.getCell("RollUpCol_2", 4) |
||||||
|
.contains("2") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// editColumnByName("RollUpCol_2", "RollUpCol_New");
|
||||||
|
deleteColumnByName("RollUpCol_2"); |
||||||
|
}); |
||||||
|
|
||||||
|
it.skip("Add Rollup column (City, CountryId, count) & Delete", () => { |
||||||
|
addLookUpColumn("RollUpCol_1", "City", "CountryId", "count"); |
||||||
|
|
||||||
|
// Verify first entry, will be displayed as alias here 'childColumn (from childTable)'
|
||||||
|
cy.get(`tbody > :nth-child(4) > [data-col="RollUpCol_1"]`) |
||||||
|
.contains("2") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
editColumnByName("RollUpCol_1", "RollUpCol_New"); |
||||||
|
deleteColumnByName("RollUpCol_New"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,264 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { |
||||||
|
isTestSuiteActive, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - DURATION`, () => { |
||||||
|
const tableName = "DurationTable"; |
||||||
|
|
||||||
|
// to retrieve few v-input nodes from their label
|
||||||
|
//
|
||||||
|
const fetchParentFromLabel = (label) => { |
||||||
|
cy.get("label").contains(label).parents(".ant-row").first().click(); |
||||||
|
}; |
||||||
|
|
||||||
|
// Run once before test- create table
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
cy.createTable(tableName); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.deleteTable(tableName); |
||||||
|
}); |
||||||
|
|
||||||
|
// Routine to create a new look up column
|
||||||
|
//
|
||||||
|
const addDurationColumn = (columnName, durationFormat) => { |
||||||
|
|
||||||
|
cy.get(".nc-grid tr > th:last .nc-icon").click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
|
||||||
|
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 }) |
||||||
|
.should('exist') |
||||||
|
.clear() |
||||||
|
.type(columnName); |
||||||
|
cy.get(".nc-column-type-input").last().click().type("Duration"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains("Duration").click(); |
||||||
|
|
||||||
|
// Configure Duration format
|
||||||
|
fetchParentFromLabel("Duration Format"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains(durationFormat).click(); |
||||||
|
// cy.getActiveMenu().contains(durationFormat).click();
|
||||||
|
|
||||||
|
cy.get(".ant-btn-primary").contains("Save").should('exist').click(); |
||||||
|
cy.toastWait(`Column created`); |
||||||
|
|
||||||
|
cy.get(`th[data-title="${columnName}"]`).should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
// routine to delete column
|
||||||
|
//
|
||||||
|
const deleteColumnByName = (columnName) => { |
||||||
|
mainPage.deleteColumn(columnName); |
||||||
|
}; |
||||||
|
|
||||||
|
// routine to edit column
|
||||||
|
//
|
||||||
|
const editColumnByName = (oldName, newName, newDurationFormat) => { |
||||||
|
|
||||||
|
cy.get(`th:contains(${oldName}) .nc-icon.ant-dropdown-trigger`) |
||||||
|
.trigger("mouseover", { force: true }) |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
cy.get(".nc-column-edit").click(); |
||||||
|
cy.get(".nc-column-edit").should("not.be.visible"); |
||||||
|
|
||||||
|
// rename column and verify
|
||||||
|
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 }) |
||||||
|
.should('exist') |
||||||
|
.clear() |
||||||
|
.type(newName); |
||||||
|
// Configure Duration format
|
||||||
|
fetchParentFromLabel("Duration Format"); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains(newDurationFormat).click(); |
||||||
|
|
||||||
|
cy.get(".ant-btn-primary:visible").contains("Save").click(); |
||||||
|
|
||||||
|
cy.toastWait("Column updated"); |
||||||
|
|
||||||
|
cy.get(`th:contains(${oldName})`).should("not.exist"); |
||||||
|
cy.get(`th:contains(${newName})`).should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
const addDurationData = (colName, index, cellValue, expectedValue, isNewRow = false) => { |
||||||
|
if (isNewRow) { |
||||||
|
cy.get(".nc-add-new-row-btn:visible").should("exist"); |
||||||
|
cy.wait(500) |
||||||
|
cy.get(".nc-add-new-row-btn").click(); |
||||||
|
} else { |
||||||
|
mainPage.getRow(index).find(".nc-row-expand-icon").click({ force: true }); |
||||||
|
} |
||||||
|
cy.get(".duration-cell-wrapper > input").first().should('exist').type(cellValue); |
||||||
|
cy.getActiveModal().find("button").contains("Save row").click({ force: true }); |
||||||
|
cy.toastWait("Row updated successfully"); |
||||||
|
mainPage.getCell(colName, index).find('input').then(($e) => { |
||||||
|
expect($e[0].value).to.equal(expectedValue) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// Test case
|
||||||
|
{ |
||||||
|
// Duration: h:mm
|
||||||
|
it("Duration: h:mm", () => { |
||||||
|
addDurationColumn("NC_DURATION_0", "h:mm (e.g. 1:23)"); |
||||||
|
addDurationData("NC_DURATION_0", 1, "1:30", "01:30", true); |
||||||
|
addDurationData("NC_DURATION_0", 2, "30", "00:30", true); |
||||||
|
addDurationData("NC_DURATION_0", 3, "60", "01:00", true); |
||||||
|
addDurationData("NC_DURATION_0", 4, "80", "01:20", true); |
||||||
|
addDurationData("NC_DURATION_0", 5, "12:34", "12:34", true); |
||||||
|
addDurationData("NC_DURATION_0", 6, "15:130", "17:10", true); |
||||||
|
addDurationData("NC_DURATION_0", 7, "123123", "2052:03", true); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Edit Column NC_DURATION_0", () => { |
||||||
|
editColumnByName( |
||||||
|
"NC_DURATION_0", |
||||||
|
"NC_DURATION_EDITED_0", |
||||||
|
"h:mm:ss (e.g. 3:45, 1:23:40)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Delete column", () => { |
||||||
|
deleteColumnByName("NC_DURATION_EDITED_0"); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
{ |
||||||
|
// Duration: h:mm:ss
|
||||||
|
it("Duration: h:mm:ss", () => { |
||||||
|
addDurationColumn("NC_DURATION_1", "h:mm:ss (e.g. 3:45, 1:23:40)"); |
||||||
|
addDurationData("NC_DURATION_1", 1, "11:22:33", "11:22:33"); |
||||||
|
addDurationData("NC_DURATION_1", 2, "1234", "00:20:34"); |
||||||
|
addDurationData("NC_DURATION_1", 3, "50", "00:00:50"); |
||||||
|
addDurationData("NC_DURATION_1", 4, "1:1111", "00:19:31"); |
||||||
|
addDurationData("NC_DURATION_1", 5, "1:11:1111", "01:29:31"); |
||||||
|
addDurationData("NC_DURATION_1", 6, "15:130", "00:17:10"); |
||||||
|
addDurationData("NC_DURATION_1", 7, "123123", "34:12:03"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Edit Column NC_DURATION_1", () => { |
||||||
|
editColumnByName( |
||||||
|
"NC_DURATION_1", |
||||||
|
"NC_DURATION_EDITED_1", |
||||||
|
"h:mm:ss.s (e.g. 3:34.6, 1:23:40.0)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Delete column", () => { |
||||||
|
deleteColumnByName("NC_DURATION_EDITED_1"); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
{ |
||||||
|
// h:mm:ss.s
|
||||||
|
it("Duration: h:mm:ss.s", () => { |
||||||
|
addDurationColumn("NC_DURATION_2", "h:mm:ss.s (e.g. 3:34.6, 1:23:40.0)"); |
||||||
|
addDurationData("NC_DURATION_2", 1, "1234", "00:20:34.0"); |
||||||
|
addDurationData("NC_DURATION_2", 2, "12:34", "00:12:34.0"); |
||||||
|
addDurationData("NC_DURATION_2", 3, "12:34:56", "12:34:56.0"); |
||||||
|
addDurationData("NC_DURATION_2", 4, "12:34:999", "12:50:39.0"); |
||||||
|
addDurationData("NC_DURATION_2", 5, "12:999:56", "28:39:56.0"); |
||||||
|
addDurationData("NC_DURATION_2", 6, "12:34:56.12", "12:34:56.1"); |
||||||
|
addDurationData("NC_DURATION_2", 7, "12:34:56.199", "12:34:56.2"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Edit Column NC_DURATION_2", () => { |
||||||
|
editColumnByName( |
||||||
|
"NC_DURATION_2", |
||||||
|
"NC_DURATION_EDITED_2", |
||||||
|
"h:mm:ss (e.g. 3:45, 1:23:40)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Delete column", () => { |
||||||
|
deleteColumnByName("NC_DURATION_EDITED_2"); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
{ |
||||||
|
// h:mm:ss.ss
|
||||||
|
it("Duration: h:mm:ss.ss", () => { |
||||||
|
addDurationColumn("NC_DURATION_3", "h:mm:ss.ss (e.g. 3.45.67, 1:23:40.00)"); |
||||||
|
addDurationData("NC_DURATION_3", 1, "1234", "00:20:34.00"); |
||||||
|
addDurationData("NC_DURATION_3", 2, "12:34", "00:12:34.00"); |
||||||
|
addDurationData("NC_DURATION_3", 3, "12:34:56", "12:34:56.00"); |
||||||
|
addDurationData("NC_DURATION_3", 4, "12:34:999", "12:50:39.00"); |
||||||
|
addDurationData("NC_DURATION_3", 5, "12:999:56", "28:39:56.00"); |
||||||
|
addDurationData("NC_DURATION_3", 6, "12:34:56.12", "12:34:56.12"); |
||||||
|
addDurationData("NC_DURATION_3", 7, "12:34:56.199", "12:34:56.20"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Edit Column NC_DURATION_3", () => { |
||||||
|
editColumnByName( |
||||||
|
"NC_DURATION_3", |
||||||
|
"NC_DURATION_EDITED_3", |
||||||
|
"h:mm:ss.ss (e.g. 3.45.67, 1:23:40.00)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Delete column", () => { |
||||||
|
deleteColumnByName("NC_DURATION_EDITED_3"); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
{ |
||||||
|
// h:mm:ss.sss
|
||||||
|
it("Duration: h:mm:ss.sss", () => { |
||||||
|
addDurationColumn("NC_DURATION_4", "h:mm:ss.sss (e.g. 3.45.678, 1:23:40.000)"); |
||||||
|
addDurationData("NC_DURATION_4", 1, "1234", "00:20:34.000"); |
||||||
|
addDurationData("NC_DURATION_4", 2, "12:34", "00:12:34.000"); |
||||||
|
addDurationData("NC_DURATION_4", 3, "12:34:56", "12:34:56.000"); |
||||||
|
addDurationData("NC_DURATION_4", 4, "12:34:999", "12:50:39.000"); |
||||||
|
addDurationData("NC_DURATION_4", 5, "12:999:56", "28:39:56.000"); |
||||||
|
addDurationData("NC_DURATION_4", 6, "12:34:56.12", "12:34:56.012"); |
||||||
|
addDurationData("NC_DURATION_4", 7, "12:34:56.199", "12:34:56.199"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Edit Column NC_DURATION_4", () => { |
||||||
|
editColumnByName( |
||||||
|
"NC_DURATION_4", |
||||||
|
"NC_DURATION_EDITED_4", |
||||||
|
"h:mm (e.g. 1:23)" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Duration: Delete column", () => { |
||||||
|
deleteColumnByName("NC_DURATION_EDITED_4"); |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Wing-Kam Wong <wingkwong.code@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,113 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
let viewTypeString = ["", "Form", "Gallery", "Grid"]; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Table views: Create/Edit/Delete`, () => { |
||||||
|
const name = "Test" + Date.now(); |
||||||
|
|
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open a table to work on views
|
||||||
|
//
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("Country"); |
||||||
|
}); |
||||||
|
|
||||||
|
// Common routine to create/edit/delete GRID & GALLERY view
|
||||||
|
// Input: viewType - 'grid'/'gallery'
|
||||||
|
//
|
||||||
|
const viewTest = (viewType) => { |
||||||
|
it(`Create ${viewType} view`, () => { |
||||||
|
// click on 'Grid/Gallery' button on Views bar
|
||||||
|
cy.get(`.nc-create-${viewType}-view`).click(); |
||||||
|
|
||||||
|
// Pop up window, click Submit (accepting default name for view)
|
||||||
|
// cy.getActiveModal().find("button:contains(Submit)").click();
|
||||||
|
cy.getActiveModal().find(".ant-btn-primary").click(); |
||||||
|
cy.toastWait("View created successfully"); |
||||||
|
|
||||||
|
// validate if view was created && contains default name 'Country1'
|
||||||
|
cy.get(`.nc-${viewType}-view-item`) |
||||||
|
.contains(`${viewTypeString[viewType]}-1`) |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it.skip(`Edit ${viewType} view name`, () => { |
||||||
|
// click on edit-icon (becomes visible on hovering mouse)
|
||||||
|
// cy.get(".nc-view-edit-icon").last().click({
|
||||||
|
// force: true,
|
||||||
|
// timeout: 1000,
|
||||||
|
// });
|
||||||
|
cy.get(`.nc-${viewType}-view-item`).last().dblclick(); |
||||||
|
|
||||||
|
// feed new name
|
||||||
|
cy.get(`.nc-${viewType}-view-item input`).type( |
||||||
|
`${viewType}View-1{enter}` |
||||||
|
); |
||||||
|
cy.toastWait("View renamed successfully"); |
||||||
|
|
||||||
|
// validate
|
||||||
|
cy.get(`.nc-${viewType}-view-item`) |
||||||
|
.contains(`${viewType}View-1`) |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Delete ${viewType} view`, () => { |
||||||
|
// number of view entries should be 2 before we delete
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 2); |
||||||
|
|
||||||
|
// click on delete icon (becomes visible on hovering mouse)
|
||||||
|
cy.get(`.nc-${viewType}-view-item`).last().trigger("mouseover").click(); |
||||||
|
cy.get(".nc-view-delete-icon").should('exist').click({ force: true }); |
||||||
|
cy.getActiveModal().find(".ant-btn-dangerous").click(); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
|
||||||
|
// confirm if the number of veiw entries is reduced by 1
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 1); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// below four scenario's will be invoked twice, once for rest & then for graphql
|
||||||
|
viewTest("3"); // grid view
|
||||||
|
viewTest("2"); // gallery view
|
||||||
|
viewTest("1"); // form view
|
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* @author Wing-Kam Wong <wingkwong.code@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,129 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
let storedURL = ""; |
||||||
|
let linkText = ""; |
||||||
|
|
||||||
|
const generateLinkWithPwd = () => { |
||||||
|
mainPage.shareView().click(); |
||||||
|
cy.getActiveModal().find(".ant-modal-title").contains("This view is shared via a private link").should("be.visible"); |
||||||
|
|
||||||
|
// enable checkbox & feed pwd, save
|
||||||
|
cy.getActiveModal().find('.ant-collapse').should('exist').click() |
||||||
|
cy.getActiveModal().find('.ant-checkbox-input').should('exist').first().then(($el) => { |
||||||
|
if (!$el.prop("checked")) { |
||||||
|
cy.wrap($el).click({ force: true }); |
||||||
|
cy.getActiveModal().find('input[type="password"]').type("1"); |
||||||
|
cy.getActiveModal().find('button:contains("Save password")').click(); |
||||||
|
cy.toastWait("Successfully updated"); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// copy link text, visit URL
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".nc-share-link-box") |
||||||
|
.then(($obj) => { |
||||||
|
linkText = $obj.text().trim(); |
||||||
|
cy.log(linkText); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Shared VIEWs (GRID)`, () => { |
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
cy.openTableTab("City", 25); |
||||||
|
|
||||||
|
// store base URL- to re-visit and delete form view later
|
||||||
|
cy.url().then((url) => { |
||||||
|
storedURL = url; |
||||||
|
}); |
||||||
|
|
||||||
|
generateLinkWithPwd(); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
cy.restoreLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
afterEach(() => { |
||||||
|
cy.saveLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
it.skip("Share view with incorrect password", () => { |
||||||
|
cy.visit(linkText, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
|
||||||
|
cy.getActiveModal().should("exist"); |
||||||
|
|
||||||
|
// feed password
|
||||||
|
cy.getActiveModal().find('input[type="password"]').type("a"); |
||||||
|
cy.getActiveModal().find('button:contains("Unlock")').click(); |
||||||
|
|
||||||
|
// if pwd is incorrect, active modal requesting to feed in password again will persist
|
||||||
|
cy.getActiveModal().find('button:contains("Unlock")').should('exist'); |
||||||
|
}); |
||||||
|
|
||||||
|
// fallover test- use previously opened view & continue verification instead of opening again
|
||||||
|
it.skip("Share view with correct password", () => { |
||||||
|
|
||||||
|
// feed password
|
||||||
|
cy.getActiveModal() |
||||||
|
.find('input[type="password"]') |
||||||
|
.clear() |
||||||
|
.type("1"); |
||||||
|
cy.getActiveModal().find('button:contains("Unlock")').click(); |
||||||
|
|
||||||
|
// if pwd is incorrect, active modal requesting to feed in password again will persist
|
||||||
|
cy.getActiveModal().find('button:contains("Unlock")').should('not.exist'); |
||||||
|
|
||||||
|
// Verify Download as CSV is here
|
||||||
|
mainPage.downloadCsv().should("exist"); |
||||||
|
mainPage.downloadExcel().should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Delete view", () => { |
||||||
|
cy.visit(storedURL, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
|
||||||
|
// wait for page load to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 25); |
||||||
|
mainPage.deleteCreatedViews(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("City"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,480 @@ |
|||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
import { mainPage, settingsPage } from "../../support/page_objects/mainPage"; |
||||||
|
|
||||||
|
let formViewURL; |
||||||
|
|
||||||
|
function verifyFormDrawerFieldLocation(fieldName, position) { |
||||||
|
cy.get(".nc-editable.item") |
||||||
|
.eq(position) |
||||||
|
.contains(fieldName) |
||||||
|
.should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
function verifyFormDrawerHideObjectCount(count) { |
||||||
|
cy.get(".nc-form") |
||||||
|
.find(".nc-field-remove-icon") |
||||||
|
.its("length") |
||||||
|
.should("eq", count); |
||||||
|
} |
||||||
|
|
||||||
|
function verifyFormMenuDrawerCardCount(cardCount) { |
||||||
|
cy.get('.nc-form-left-drawer').find('.ant-card').should('have.length', cardCount); |
||||||
|
} |
||||||
|
|
||||||
|
function validateFormHeader() { |
||||||
|
cy.get(".nc-form").should("exist"); |
||||||
|
|
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Form Title"]') |
||||||
|
.should("exist").then(($el) => { |
||||||
|
cy.log($el) |
||||||
|
expect($el.val()).to.equal("A B C D"); |
||||||
|
}) |
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Add form description"]') |
||||||
|
.should("exist").then(($el) => { |
||||||
|
cy.log($el) |
||||||
|
expect($el.val()).to.equal("Some description about form comes here"); |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - FORM view`, () => { |
||||||
|
const name = "Test" + Date.now(); |
||||||
|
|
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open a table to work on views
|
||||||
|
//
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
mainPage.toggleRightSidebar(); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
cy.restoreLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
afterEach(() => { |
||||||
|
cy.saveLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("Country"); |
||||||
|
}); |
||||||
|
|
||||||
|
// Common routine to create/edit/delete GRID & GALLERY view
|
||||||
|
// Input: viewType - 'grid'/'gallery'
|
||||||
|
//
|
||||||
|
const viewTest = (viewType) => { |
||||||
|
it(`Create ${viewType} view`, () => { |
||||||
|
// click on 'Grid/Gallery' button on Views bar
|
||||||
|
cy.get(`.nc-create-${viewType}-view`).click(); |
||||||
|
|
||||||
|
// Pop up window, click Submit (accepting default name for view)
|
||||||
|
cy.getActiveModal().find("button:contains(Submit)").click(); |
||||||
|
|
||||||
|
cy.toastWait("View created successfully"); |
||||||
|
|
||||||
|
// validate if view was creted && contains default name 'Form-1'
|
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Form-1") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType} view: Drag & drop for re-order items`, () => { |
||||||
|
// default order: Country, LastUpdate, Country => City
|
||||||
|
verifyFormDrawerFieldLocation("Country", 0); |
||||||
|
verifyFormDrawerFieldLocation("LastUpdate", 1); |
||||||
|
|
||||||
|
// move Country field down (drag, drop)
|
||||||
|
cy.get(".nc-form-drag-LastUpdate").drag( |
||||||
|
".nc-form-drag-Country" |
||||||
|
); |
||||||
|
|
||||||
|
// Verify if order is: LastUpdate, Country, Country => City
|
||||||
|
verifyFormDrawerFieldLocation("LastUpdate", 0); |
||||||
|
verifyFormDrawerFieldLocation("Country", 1); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType} view: Drag & drop for add/remove items`, () => { |
||||||
|
// default, only one item in menu-bar; ensure LastUpdate field was present in form view
|
||||||
|
verifyFormMenuDrawerCardCount(0) |
||||||
|
verifyFormDrawerFieldLocation("LastUpdate", 0); |
||||||
|
|
||||||
|
// drag 'LastUpdate' & drop into menu bar drag-drop box
|
||||||
|
cy.get(".nc-form-drag-LastUpdate").drag( |
||||||
|
".nc-drag-n-drop-to-hide" |
||||||
|
); |
||||||
|
|
||||||
|
// validate- fields count in menu bar to be increased by 1 &&
|
||||||
|
// first member in 'formView' is Country
|
||||||
|
verifyFormDrawerFieldLocation("Country", 0); |
||||||
|
verifyFormMenuDrawerCardCount(1); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType} view: Inverted order field member addition from menu`, () => { |
||||||
|
|
||||||
|
cy.get(".nc-form-remove-all").click(); |
||||||
|
verifyFormMenuDrawerCardCount(2) |
||||||
|
|
||||||
|
// click fields in inverted order: LastUpdate, Country => City
|
||||||
|
cy.get('.nc-form-left-drawer').find('.ant-card').eq(1).click(); |
||||||
|
|
||||||
|
verifyFormMenuDrawerCardCount(1); |
||||||
|
cy.get('.nc-form-left-drawer').find('.ant-card').eq(0).click(); |
||||||
|
|
||||||
|
// verify if order of appearance in form is right
|
||||||
|
// Country was never removed as its required field. Other two will appear in inverted order
|
||||||
|
verifyFormMenuDrawerCardCount(0); |
||||||
|
verifyFormDrawerFieldLocation("Country", 0); |
||||||
|
verifyFormDrawerFieldLocation("City List", 1); |
||||||
|
verifyFormDrawerFieldLocation("LastUpdate", 2); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: Form header & description validation`, () => { |
||||||
|
// Header & description should exist
|
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Form Title"]') |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Add form description"]') |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// Update header & add some description, verify
|
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Form Title"]') |
||||||
|
.clear() |
||||||
|
.type("A B C D"); |
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Add form description"]') |
||||||
|
.type("Some description about form comes here"); |
||||||
|
|
||||||
|
cy.get(".nc-form").click() |
||||||
|
|
||||||
|
// validate new contents
|
||||||
|
validateFormHeader(); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: Add all, Remove all validation`, () => { |
||||||
|
|
||||||
|
// ensure buttons exist on left hand menu
|
||||||
|
cy.get(".nc-form-left-drawer").find(".nc-form-add-all").should("not.exist"); |
||||||
|
cy.get(".nc-form-left-drawer").find(".nc-form-remove-all").should("be.visible"); |
||||||
|
|
||||||
|
// click: remove-all
|
||||||
|
cy.get(".nc-form-left-drawer").find(".nc-form-remove-all").click(); |
||||||
|
cy.wait(1000); |
||||||
|
// form should not contain any "field remove icons"
|
||||||
|
verifyFormDrawerHideObjectCount(0); |
||||||
|
// menu bar should contain 2 .pointer.item (LastUpdate, County->City)
|
||||||
|
verifyFormMenuDrawerCardCount(2); |
||||||
|
|
||||||
|
// click: Add all
|
||||||
|
cy.get(".nc-form-left-drawer").find(".nc-form-add-all").should('be.visible').click(); |
||||||
|
cy.get(".nc-form-left-drawer").find(".nc-form-remove-all").should("be.visible"); |
||||||
|
|
||||||
|
// form should contain "field remove icons"
|
||||||
|
verifyFormDrawerHideObjectCount(2); |
||||||
|
|
||||||
|
// menu bar should not contain .pointer.item (column name/ field name add options)
|
||||||
|
verifyFormMenuDrawerCardCount(0); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: Submit default, empty show this message textbox`, () => { |
||||||
|
// fill up mandatory fields
|
||||||
|
cy.get(".nc-form-input-Country").type("_abc"); |
||||||
|
cy.get(".nc-form-input-LastUpdate").click(); |
||||||
|
cy.getActiveModal().find("button").contains("19").click(); |
||||||
|
cy.getActiveModal().find("button").contains("OK").click(); |
||||||
|
|
||||||
|
// default message, no update
|
||||||
|
|
||||||
|
// submit button & validate
|
||||||
|
cy.get(".nc-form").find("button").contains("Submit").click(); |
||||||
|
|
||||||
|
cy.get(".ant-alert-message") |
||||||
|
.contains("Successfully submitted form data") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// end of test removes newly added rows from table. that step validates if row was successfully added.
|
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: Submit default, with valid Show message entry`, () => { |
||||||
|
// clicking again on view name shows blank still. work around- toggling between two views
|
||||||
|
// cy.get(`.nc-view-item.nc-grid-view-item`)
|
||||||
|
// .contains("Country")
|
||||||
|
// .click();
|
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Form-1") |
||||||
|
.click(); |
||||||
|
|
||||||
|
// fill up mandatory fields
|
||||||
|
cy.get(".nc-form-input-Country").type("_abc"); |
||||||
|
cy.get(".nc-form-input-LastUpdate").click(); |
||||||
|
cy.getActiveModal().find("button").contains("19").click(); |
||||||
|
cy.getActiveModal().find("button").contains("OK").click(); |
||||||
|
|
||||||
|
// add message
|
||||||
|
cy.get("textarea.nc-form-after-submit-msg") |
||||||
|
.type("Congratulations!"); |
||||||
|
|
||||||
|
// submit button & validate
|
||||||
|
cy.get(".nc-form").find("button").contains("Submit").click(); |
||||||
|
cy.get(".ant-alert-message").contains("Congratulations!").should("exist"); |
||||||
|
|
||||||
|
// end of test removes newly added rows from table. that step validates if row was successfully added.
|
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: Submit default, Enable checkbox "Submit another form`, () => { |
||||||
|
// clicking again on view name shows blank still. work around- toggling between two views
|
||||||
|
// cy.get(`.nc-view-item.nc-grid-view-item`)
|
||||||
|
// .contains("Country")
|
||||||
|
// .click();
|
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Form-1") |
||||||
|
.click(); |
||||||
|
|
||||||
|
// fill up mandatory fields
|
||||||
|
cy.get(".nc-form-input-Country").type("_abc"); |
||||||
|
cy.get(".nc-form-input-LastUpdate").click(); |
||||||
|
cy.getActiveModal().find("button").contains("19").click(); |
||||||
|
cy.getActiveModal().find("button").contains("OK").click(); |
||||||
|
|
||||||
|
// enable "Submit another form" check box
|
||||||
|
cy.get("button.nc-form-checkbox-submit-another-form").click(); |
||||||
|
|
||||||
|
// submit button & validate
|
||||||
|
cy.get(".nc-form").find("button").contains("Submit").click(); |
||||||
|
cy.get(".ant-alert-message").contains("Congratulations").should("exist"); |
||||||
|
cy.get("button") |
||||||
|
.contains("Submit Another Form") |
||||||
|
.should("exist") |
||||||
|
.click(); |
||||||
|
|
||||||
|
// New form appeared? Header & description should exist
|
||||||
|
validateFormHeader(); |
||||||
|
|
||||||
|
// end of test removes newly added rows from table. that step validates if row was successfully added.
|
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: Submit default, Enable checkbox "blank form after 5 seconds"`, () => { |
||||||
|
|
||||||
|
cy.get(".nc-form-input-Country").type("_abc"); |
||||||
|
cy.get(".nc-form-input-LastUpdate").click(); |
||||||
|
cy.getActiveModal().find("button").contains("19").click(); |
||||||
|
cy.getActiveModal().find("button").contains("OK").click(); |
||||||
|
|
||||||
|
// enable "New form after 5 seconds" button
|
||||||
|
cy.get("button.nc-form-checkbox-submit-another-form") |
||||||
|
.click(); |
||||||
|
cy.get("button.nc-form-checkbox-show-blank-form") |
||||||
|
.click(); |
||||||
|
|
||||||
|
// submit button & validate
|
||||||
|
cy.get(".nc-form").find("button").contains("Submit").click(); |
||||||
|
cy.get(".ant-alert-message") |
||||||
|
.contains("Congratulations") |
||||||
|
.should("exist") |
||||||
|
.then(() => { |
||||||
|
// validate if form has appeared again
|
||||||
|
validateFormHeader(); |
||||||
|
}); |
||||||
|
|
||||||
|
// end of test removes newly added rows from table. that step validates if row was successfully added.
|
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: Email me verification, without SMTP configuration`, () => { |
||||||
|
// open formview & enable "email me" option
|
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Form-1") |
||||||
|
.click(); |
||||||
|
|
||||||
|
// validate if form has appeared again
|
||||||
|
validateFormHeader(); |
||||||
|
|
||||||
|
cy.get("button.nc-form-checkbox-send-email") |
||||||
|
.click(); |
||||||
|
// validate if toaster pops up requesting to activate SMTP
|
||||||
|
cy.toastWait( |
||||||
|
"Please activate SMTP plugin in App store for enabling email notification" |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: Email me verification, with SMTP configuration`, () => { |
||||||
|
// activate SMTP, dummy profile
|
||||||
|
settingsPage.openMenu(settingsPage.APPSTORE) |
||||||
|
mainPage.configureSMTP( |
||||||
|
"admin@ex.com", |
||||||
|
"smtp.ex.com", |
||||||
|
"8080", |
||||||
|
"TLS" |
||||||
|
); |
||||||
|
|
||||||
|
// open form view & enable "email me" option
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
|
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Form-1") |
||||||
|
.click(); |
||||||
|
|
||||||
|
// validate if form has appeared again
|
||||||
|
validateFormHeader(); |
||||||
|
|
||||||
|
cy.get("button.nc-form-checkbox-send-email") |
||||||
|
.click(); |
||||||
|
|
||||||
|
settingsPage.openMenu(settingsPage.APPSTORE) |
||||||
|
mainPage.resetSMTP(); |
||||||
|
|
||||||
|
cy.wait(3000); |
||||||
|
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: Add/ remove field verification"`, () => { |
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Form-1") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.wait(3000); |
||||||
|
|
||||||
|
// validate if form has appeared again
|
||||||
|
validateFormHeader(); |
||||||
|
|
||||||
|
cy.get(".nc-form-input-LastUpdate").should("exist"); |
||||||
|
// remove "LastUpdate field"
|
||||||
|
cy.get(".nc-form").find(".nc-field-remove-icon").eq(2).click(); |
||||||
|
cy.get(".nc-form-input-LastUpdate").should("not.exist"); |
||||||
|
// cy.get(".col-md-4")
|
||||||
|
// .find(".pointer.item")
|
||||||
|
// .contains("LastUpdate")
|
||||||
|
// .should("exist");
|
||||||
|
|
||||||
|
// add it back
|
||||||
|
// cy.get(".col-md-4")
|
||||||
|
// .find(".pointer.item")
|
||||||
|
// .contains("LastUpdate")
|
||||||
|
// .click();
|
||||||
|
cy.get('.nc-form-left-drawer').find('.ant-card').contains('LastUpdate').should('exist').click(); |
||||||
|
cy.get(".nc-form-input-LastUpdate").should("exist"); |
||||||
|
|
||||||
|
cy.wait(3000); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: URL verification`, () => { |
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Form-1") |
||||||
|
.click(); |
||||||
|
|
||||||
|
// validate if form has appeared again
|
||||||
|
validateFormHeader(); |
||||||
|
|
||||||
|
// verify URL & copy it for subsequent test
|
||||||
|
cy.url().should("contain", `Country/Form-1`); |
||||||
|
cy.url().then((url) => { |
||||||
|
cy.log(url); |
||||||
|
formViewURL = url; |
||||||
|
}); |
||||||
|
|
||||||
|
cy.wait(3000); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Validate ${viewType}: URL validation after re-access`, () => { |
||||||
|
// visit URL
|
||||||
|
cy.log(formViewURL); |
||||||
|
cy.visit(formViewURL, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// New form appeared? Header & description should exist
|
||||||
|
validateFormHeader(); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Delete ${viewType} view`, () => { |
||||||
|
// number of view entries should be 2 before we delete
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 2); |
||||||
|
|
||||||
|
// click on delete icon (becomes visible on hovering mouse)
|
||||||
|
cy.get(".nc-view-delete-icon").click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
|
||||||
|
// confirm if the number of veiw entries is reduced by 1
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 1); |
||||||
|
|
||||||
|
// clean up newly added rows into Country table operations
|
||||||
|
// this auto verifies successfull addition of rows to table as well
|
||||||
|
mainPage.getPagination(5).click(); |
||||||
|
// kludge: flicker on load
|
||||||
|
// cy.wait(3000)
|
||||||
|
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 13); |
||||||
|
cy.get(".ant-checkbox").should('exist').eq(10).click({ force: true }); |
||||||
|
cy.get(".ant-checkbox").should('exist').eq(11).click({ force: true }); |
||||||
|
cy.get(".ant-checkbox").should('exist').eq(12).click({ force: true }); |
||||||
|
cy.get(".ant-checkbox").should('exist').eq(13).click({ force: true }); |
||||||
|
|
||||||
|
mainPage.getCell("Country", 10).rightclick({ force: true }); |
||||||
|
cy.getActiveMenu() |
||||||
|
.contains("Delete Selected Rows") |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// mainPage
|
||||||
|
// .getRow(10)
|
||||||
|
// .find(".mdi-checkbox-blank-outline")
|
||||||
|
// .click({ force: true });
|
||||||
|
// mainPage
|
||||||
|
// .getRow(11)
|
||||||
|
// .find(".mdi-checkbox-blank-outline")
|
||||||
|
// .click({ force: true });
|
||||||
|
// mainPage
|
||||||
|
// .getRow(12)
|
||||||
|
// .find(".mdi-checkbox-blank-outline")
|
||||||
|
// .click({ force: true });
|
||||||
|
// mainPage
|
||||||
|
// .getRow(13)
|
||||||
|
// .find(".mdi-checkbox-blank-outline")
|
||||||
|
// .click({ force: true });
|
||||||
|
//
|
||||||
|
// mainPage.getCell("Country", 10).rightclick();
|
||||||
|
// cy.getActiveMenu().contains("Delete Selected Row").click();
|
||||||
|
// cy.toastWait('Deleted selected rows successfully')
|
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// below scenario's will be invoked twice, once for rest & then for graphql
|
||||||
|
// viewTest("form");
|
||||||
|
viewTest("1"); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,124 @@ |
|||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Lock view`, () => { |
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open a table to work on views
|
||||||
|
//
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("Country"); |
||||||
|
}); |
||||||
|
|
||||||
|
const lockViewTest = (enabled) => { |
||||||
|
it(`Grid: lock view set to ${enabled}: validation`, () => { |
||||||
|
let vString = enabled ? "not." : ""; |
||||||
|
let menuOption = enabled ? 1 : 0; |
||||||
|
|
||||||
|
// on menu, collaboration view appears first (at index 0)
|
||||||
|
// followed by Locked view (at index 1)
|
||||||
|
cy.get(".nc-sidebar-lock-menu") |
||||||
|
.click(); |
||||||
|
cy.getActiveMenu() |
||||||
|
.find('.nc-menu-item:visible') |
||||||
|
.eq(menuOption) |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.toastWait('Successfully Switched to locked view') |
||||||
|
|
||||||
|
// expected toolbar for Lock view: Only lock-view menu, reload, toggle-nav-drawer to be enabled
|
||||||
|
//
|
||||||
|
cy.get(".nc-sidebar-lock-menu:enabled") |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-sidebar-reload-btn:enabled") |
||||||
|
.should("exist"); |
||||||
|
cy.get("nc-sidebar-add-row-btn:enabled") |
||||||
|
.should(`${vString}exist`); |
||||||
|
cy.get(".nc-fields-menu-btn:enabled") |
||||||
|
.should(`${vString}exist`); |
||||||
|
cy.get(".nc-sort-menu-btn:enabled") |
||||||
|
.should(`${vString}exist`); |
||||||
|
cy.get(".nc-filter-menu-btn:enabled") |
||||||
|
.should(`${vString}exist`); |
||||||
|
|
||||||
|
// dblClick on a cell & see if we can edit
|
||||||
|
mainPage.getCell("Country", 1).dblclick(); |
||||||
|
mainPage |
||||||
|
.getCell("Country", 1) |
||||||
|
.find("input") |
||||||
|
.should(`${vString}exist`); |
||||||
|
|
||||||
|
// check if expand row option is available?
|
||||||
|
// cy.get("td")
|
||||||
|
// .find(".nc-row-expand-icon")
|
||||||
|
// .should(`${vString}exist`);
|
||||||
|
mainPage |
||||||
|
.getRow(1) |
||||||
|
.find('.nc-row-no').should('exist').eq(0).trigger('mouseover', { force: true }) |
||||||
|
cy.get(".nc-row-expand") |
||||||
|
.should(`${vString}exist`); |
||||||
|
|
||||||
|
// check if add/ expand options available for 'has many' column type
|
||||||
|
// GUI-v2: TBD
|
||||||
|
mainPage |
||||||
|
.getCell("City List", 1) |
||||||
|
.click() |
||||||
|
.find("button.mdi-plus") |
||||||
|
.should(`${vString}exist`); |
||||||
|
mainPage |
||||||
|
.getCell("City List", 1) |
||||||
|
.click() |
||||||
|
.find("button.mdi-arrow-expand") |
||||||
|
.should(`${vString}exist`); |
||||||
|
|
||||||
|
// update row option (right click) - should not be available for Lock view
|
||||||
|
mainPage.getCell("City List", 1).rightclick(); |
||||||
|
cy.get(".ant-dropdown-content").should( |
||||||
|
`${vString}be.visible` |
||||||
|
); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// Locked view
|
||||||
|
lockViewTest(true); |
||||||
|
|
||||||
|
// collaboration view
|
||||||
|
lockViewTest(false); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,246 @@ |
|||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
|
||||||
|
let storedURL = ""; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - FORM view (Share)`, () => { |
||||||
|
const name = "Test" + Date.now(); |
||||||
|
|
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open a table to work on views
|
||||||
|
//
|
||||||
|
cy.openTableTab("City", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
cy.restoreLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
afterEach(() => { |
||||||
|
cy.saveLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("City"); |
||||||
|
}); |
||||||
|
|
||||||
|
// Common routine to create/edit/delete GRID & GALLERY view
|
||||||
|
// Input: viewType - 'grid'/'gallery'
|
||||||
|
//
|
||||||
|
const viewTest = (viewType) => { |
||||||
|
it(`Create ${viewType} view`, () => { |
||||||
|
|
||||||
|
// click on create grid view button
|
||||||
|
cy.get(`.nc-create-${viewType}-view`).click(); |
||||||
|
|
||||||
|
// Pop up window, click Submit (accepting default name for view)
|
||||||
|
cy.getActiveModal().find("button:contains(Submit)").click(); |
||||||
|
|
||||||
|
cy.toastWait("View created successfully"); |
||||||
|
|
||||||
|
// validate if view was creted && contains default name 'Country1'
|
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Form-1") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// Prepare form
|
||||||
|
// add header, description
|
||||||
|
// add post submission message
|
||||||
|
// swap position for City, LastUpdate fields
|
||||||
|
// remove City=>Address field
|
||||||
|
// enable "Submit another form" check box
|
||||||
|
cy.get("button.nc-form-checkbox-show-blank-form").click(); |
||||||
|
|
||||||
|
// Update header & add some description, verify
|
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Form Title"]') |
||||||
|
.clear() |
||||||
|
.type("A B C D"); |
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Add form description"]') |
||||||
|
.type("Some description about form comes here"); |
||||||
|
|
||||||
|
// add message
|
||||||
|
cy.get("textarea.nc-form-after-submit-msg") |
||||||
|
.type("Congratulations!"); |
||||||
|
|
||||||
|
// move Country field down (drag, drop)
|
||||||
|
cy.get(".nc-form-drag-LastUpdate").drag( |
||||||
|
".nc-form-drag-City"); |
||||||
|
|
||||||
|
cy.get('[title="Address List"]').drag(".nc-drag-n-drop-to-hide"); |
||||||
|
|
||||||
|
// cy.get(".nc-form > .mx-auto")
|
||||||
|
// .find('[type="checkbox"]')
|
||||||
|
// .eq(1)
|
||||||
|
// .should("be.checked");
|
||||||
|
|
||||||
|
// store base URL- to re-visit and delete form view later
|
||||||
|
cy.url().then((url) => { |
||||||
|
storedURL = url; |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share form view`, () => { |
||||||
|
// cy.get(".nc-form > .mx-auto")
|
||||||
|
// .find('[type="checkbox"]')
|
||||||
|
// .eq(1)
|
||||||
|
// .should("be.checked");
|
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Form-1") |
||||||
|
.click(); |
||||||
|
|
||||||
|
mainPage.shareView().click({ force: true }); |
||||||
|
|
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// copy link text, visit URL
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".share-link-box") |
||||||
|
.contains("/nc/form/", { timeout: 10000 }) |
||||||
|
.should("exist") |
||||||
|
.then(($obj) => { |
||||||
|
let linkText = $obj.text().trim(); |
||||||
|
cy.log(linkText); |
||||||
|
cy.visit(linkText, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// wait for share view page to load!
|
||||||
|
|
||||||
|
cy.get(".nc-form").should("exist"); |
||||||
|
|
||||||
|
// New form appeared? Header & description should exist
|
||||||
|
cy.get(".nc-form", { timeout: 10000 }) |
||||||
|
.find("h2") |
||||||
|
.contains("A B C D") |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-form", { timeout: 10000 }) |
||||||
|
.find(".body-1") |
||||||
|
.contains("Some description about form comes here") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// all fields, barring removed field should exist
|
||||||
|
cy.get('[title="City"]').should("exist"); |
||||||
|
cy.get('[title="LastUpdate"]').should("exist"); |
||||||
|
cy.get('[title="Country"]').should("exist"); |
||||||
|
cy.get('[title="Address List"]').should("not.exist"); |
||||||
|
|
||||||
|
// order of LastUpdate & City field is retained
|
||||||
|
cy.get(".nc-form-field") |
||||||
|
.eq(1) |
||||||
|
.contains("LastUpdate") |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-form-field") |
||||||
|
.eq(0) |
||||||
|
.contains("City") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// submit form, to read message
|
||||||
|
cy.get(".nc-form-input-City").type("_abc"); |
||||||
|
cy.get(".nc-form-input-LastUpdate").click(); |
||||||
|
cy.getActiveModal().find("button").contains("19").click(); |
||||||
|
cy.getActiveModal().find("button").contains("OK").click(); |
||||||
|
|
||||||
|
cy.get('.nc-form-field-Country') |
||||||
|
.trigger('mouseover') |
||||||
|
.click() |
||||||
|
.find('.nc-action-icon') |
||||||
|
.click(); |
||||||
|
// cy.get("button").contains("Link to 'Country'").click();
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-card") |
||||||
|
.contains("Afghanistan") |
||||||
|
.click(); |
||||||
|
|
||||||
|
// submit button & validate
|
||||||
|
cy.get(".nc-form") |
||||||
|
.find("button") |
||||||
|
.contains("Submit") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.get(".ant-alert-message") |
||||||
|
.contains("Congratulations") |
||||||
|
.should("exist") |
||||||
|
.then(() => { |
||||||
|
cy.get(".nc-form").should("exist"); |
||||||
|
|
||||||
|
// validate if form has appeared again
|
||||||
|
cy.get(".nc-share-form-title") |
||||||
|
.contains("A B C D") |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-share-form-desc") |
||||||
|
.contains("Some description about form comes here") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Delete ${viewType} view`, () => { |
||||||
|
// go back to base page
|
||||||
|
cy.visit(storedURL, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// number of view entries should be 2 before we delete
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 2); |
||||||
|
|
||||||
|
// click on delete icon (becomes visible on hovering mouse)
|
||||||
|
cy.get(".nc-view-delete-icon").click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
|
||||||
|
// confirm if the number of veiw entries is reduced by 1
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 1); |
||||||
|
|
||||||
|
// clean up newly added rows into Country table operations
|
||||||
|
// this auto verifies successfull addition of rows to table as well
|
||||||
|
mainPage.getPagination(25).click(); |
||||||
|
// kludge: flicker on load
|
||||||
|
cy.wait(3000) |
||||||
|
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 1); |
||||||
|
cy.get(".ant-checkbox").should('exist').eq(1).click({ force: true }); |
||||||
|
mainPage.getCell("Country", 1).rightclick({ force: true }); |
||||||
|
cy.getActiveMenu() |
||||||
|
.contains("Delete Selected Rows") |
||||||
|
.click({ force: true }); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// below scenario's will be invoked twice, once for rest & then for graphql
|
||||||
|
viewTest("form"); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,491 @@ |
|||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
|
||||||
|
let storedURL = ""; |
||||||
|
|
||||||
|
// 0: all enabled
|
||||||
|
// 1: field hide
|
||||||
|
// 2: field sort
|
||||||
|
// 3: field filter
|
||||||
|
// 4: default (address table): for view operation validation
|
||||||
|
// 5: default (country table): for update row/column validation
|
||||||
|
let viewURL = {}; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
const generateViewLink = (viewName) => { |
||||||
|
// click on share view
|
||||||
|
// cy.get(".v-navigation-drawer__content > .container")
|
||||||
|
// .find(".v-list > .v-list-item")
|
||||||
|
// .contains("Share View")
|
||||||
|
// .click();
|
||||||
|
mainPage.shareView().click({ force: true }); |
||||||
|
|
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// wait, as URL initially will be /undefined
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".share-link-box") |
||||||
|
.contains("/nc/view/", { timeout: 10000 }) |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// copy link text, visit URL
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".share-link-box") |
||||||
|
.contains("/nc/view/", { timeout: 10000 }) |
||||||
|
.then(($obj) => { |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
// viewURL.push($obj.text())
|
||||||
|
viewURL[viewName] = $obj.text().trim(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - GRID view (Share)`, () => { |
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open a table to work on views
|
||||||
|
//
|
||||||
|
cy.openTableTab("Address", 25); |
||||||
|
|
||||||
|
cy.saveLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
cy.restoreLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
afterEach(() => { |
||||||
|
cy.saveLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
// close table
|
||||||
|
// mainPage.deleteCreatedViews()
|
||||||
|
cy.closeTableTab("Address"); |
||||||
|
}); |
||||||
|
|
||||||
|
// Common routine to create/edit/delete GRID & GALLERY view
|
||||||
|
// Input: viewType - 'grid'/'gallery'
|
||||||
|
//
|
||||||
|
const viewTest = (viewType) => { |
||||||
|
it(`Create ${viewType.toUpperCase()} view`, () => { |
||||||
|
// create a normal public view
|
||||||
|
cy.get(`.nc-create-${viewType}-view`).click(); |
||||||
|
cy.getActiveModal().find("button:contains(Submit)").click(); |
||||||
|
cy.toastWait("View created successfully"); |
||||||
|
|
||||||
|
// store base URL- to re-visit and delete form view later
|
||||||
|
cy.url().then((url) => { |
||||||
|
storedURL = url; |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} hide, sort, filter & verify`, () => { |
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Grid-1") |
||||||
|
.click(); |
||||||
|
mainPage.hideField("Address2"); |
||||||
|
mainPage.sortField("District", "Z → A"); |
||||||
|
mainPage.filterField("Address", "is like", "Ab"); |
||||||
|
generateViewLink("combined"); |
||||||
|
cy.log(viewURL["combined"]); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : ensure we have only one link even if shared multiple times`, () => { |
||||||
|
// generate view link multiple times
|
||||||
|
generateViewLink("combined"); |
||||||
|
generateViewLink("combined"); |
||||||
|
|
||||||
|
// verify if only one link exists in table
|
||||||
|
// cy.get(".v-navigation-drawer__content > .container")
|
||||||
|
// .find(".v-list > .v-list-item")
|
||||||
|
// .contains("Share View")
|
||||||
|
// .parent()
|
||||||
|
// .find("button.mdi-dots-vertical")
|
||||||
|
// .click();
|
||||||
|
mainPage.shareViewList().click(); |
||||||
|
|
||||||
|
// cy.getActiveMenu().find(".v-list-item").contains("Views List").click();
|
||||||
|
|
||||||
|
cy.get('th:contains("View Link")').should("exist"); |
||||||
|
|
||||||
|
cy.get('th:contains("View Link")') |
||||||
|
.parent() |
||||||
|
.parent() |
||||||
|
.next() |
||||||
|
.find("tr") |
||||||
|
.its("length") |
||||||
|
.should("eq", 1) |
||||||
|
.then(() => { |
||||||
|
cy.get('button.ant-modal-close').click(); |
||||||
|
// cy.get(".v-overlay--active > .v-overlay__scrim").click({
|
||||||
|
// force: true,
|
||||||
|
// });
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Visit URL, Verify title`, () => { |
||||||
|
// visit public view
|
||||||
|
cy.visit(viewURL["combined"], { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 18); |
||||||
|
|
||||||
|
// verify title
|
||||||
|
// GUI-v2: fix me
|
||||||
|
cy.get("div.model-name").contains("Address1").should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : verify fields hidden/open`, () => { |
||||||
|
// verify column headers
|
||||||
|
cy.get('[data-title="Address"]').should("exist"); |
||||||
|
cy.get('[data-title="Address2"]').should("not.exist"); |
||||||
|
cy.get('[data-title="District"]').should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : verify fields sort/ filter`, () => { |
||||||
|
// country column content verification before sort
|
||||||
|
mainPage |
||||||
|
.getCell("District", 1) |
||||||
|
.contains("West Bengali") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell("District", 2) |
||||||
|
.contains("Tutuila") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell("District", 3) |
||||||
|
.contains("Tamil Nadu") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : verify download CSV`, () => { |
||||||
|
mainPage.hideField("LastUpdate"); |
||||||
|
const verifyCsv = (retrievedRecords) => { |
||||||
|
// expected output, statically configured
|
||||||
|
let storedRecords = [ |
||||||
|
`Address,District,PostalCode,Phone,Location,Customer List,Staff List,City,Staff List`, |
||||||
|
`1013 Tabuk Boulevard,West Bengali,96203,158399646978,[object Object],2,,Kanchrapara,`, |
||||||
|
`1892 Nabereznyje Telny Lane,Tutuila,28396,478229987054,[object Object],2,,Tafuna,`, |
||||||
|
`1993 Tabuk Lane,Tamil Nadu,64221,648482415405,[object Object],2,,Tambaram,`, |
||||||
|
`1661 Abha Drive,Tamil Nadu,14400,270456873752,[object Object],1,,Pudukkottai,`, |
||||||
|
]; |
||||||
|
|
||||||
|
for (let i = 0; i < storedRecords.length; i++) { |
||||||
|
let strCol = storedRecords[i].split(","); |
||||||
|
let retCol = retrievedRecords[i].split(","); |
||||||
|
for (let j = 0; j < 4; j++) { |
||||||
|
expect(strCol[j]).to.be.equal(retCol[j]); |
||||||
|
} |
||||||
|
// expect(retrievedRecords[i]).to.be.equal(storedRecords[i])
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// download & verify
|
||||||
|
mainPage.downloadAndVerifyCsv( |
||||||
|
`Address_exported_1.csv`, |
||||||
|
verifyCsv |
||||||
|
); |
||||||
|
mainPage.unhideField("LastUpdate"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Disable sort`, () => { |
||||||
|
// remove sort and validate
|
||||||
|
mainPage.clearSort(); |
||||||
|
mainPage |
||||||
|
.getCell("District", 1) |
||||||
|
.contains("West Bengali") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Enable sort`, () => { |
||||||
|
// Sort menu operations (Country Column, Z → A)
|
||||||
|
mainPage.sortField("District", "Z → A"); |
||||||
|
mainPage |
||||||
|
.getCell("District", 1) |
||||||
|
.contains("West Bengali") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Create Filter`, () => { |
||||||
|
// add filter & validate
|
||||||
|
mainPage.filterField("District", "is like", "Tamil"); |
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 2); |
||||||
|
mainPage |
||||||
|
.getCell("District", 1) |
||||||
|
.contains("Tamil") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : verify download CSV after local filter`, () => { |
||||||
|
mainPage.hideField("LastUpdate"); |
||||||
|
const verifyCsv = (retrievedRecords) => { |
||||||
|
// expected output, statically configured
|
||||||
|
let storedRecords = [ |
||||||
|
`Address,District,PostalCode,Phone,Location,Customer List,Staff List,City,Staff List`, |
||||||
|
`1993 Tabuk Lane,Tamil Nadu,64221,648482415405,[object Object],2,,Tambaram,`, |
||||||
|
`1661 Abha Drive,Tamil Nadu,14400,270456873752,[object Object],1,,Pudukkottai,`, |
||||||
|
]; |
||||||
|
|
||||||
|
// for (let i = 0; i < storedRecords.length; i++) {
|
||||||
|
// expect(retrievedRecords[i]).to.be.equal(storedRecords[i])
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ncv2@fixme
|
||||||
|
// for (let i = 0; i < storedRecords.length; i++) {
|
||||||
|
// let strCol = storedRecords[i].split(",");
|
||||||
|
// let retCol = retrievedRecords[i].split(",");
|
||||||
|
// for (let j = 0; j < 4; j++) {
|
||||||
|
// expect(strCol[j]).to.be.equal(retCol[j]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}; |
||||||
|
mainPage.downloadAndVerifyCsv( |
||||||
|
`Address_exported_1.csv`, |
||||||
|
verifyCsv |
||||||
|
); |
||||||
|
mainPage.unhideField("LastUpdate"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Delete Filter`, () => { |
||||||
|
// Remove sort and Validate
|
||||||
|
mainPage.filterReset(); |
||||||
|
mainPage |
||||||
|
.getCell("District", 1) |
||||||
|
.contains("West Bengali") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : Virtual column validation > has many`, () => { |
||||||
|
// verify column headers
|
||||||
|
cy.get('[data-title="Customer List"]').should("exist"); |
||||||
|
cy.get('[data-title="Staff List"]').should("exist"); |
||||||
|
cy.get('[data-title="City"]').should("exist"); |
||||||
|
cy.get('[data-title="Staff List"]').should("exist"); |
||||||
|
|
||||||
|
// has many field validation
|
||||||
|
mainPage |
||||||
|
.getCell("Customer List", 3) |
||||||
|
.click() |
||||||
|
.find(".nc-icon.nc-unlink-icon") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Customer List", 3) |
||||||
|
.click() |
||||||
|
.find(".nc-icon.nc-action-icon.nc-plus") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Customer List", 3) |
||||||
|
.click() |
||||||
|
.find(".nc-icon.nc-action-icon.nc-arrow-expand") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find(".nc-icon.nc-reload").should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find("button") |
||||||
|
.contains("Link to") |
||||||
|
.should("not.exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-card") |
||||||
|
.contains("2") |
||||||
|
.should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-card") |
||||||
|
.find("button") |
||||||
|
.should("not.exist"); |
||||||
|
cy.get('button.ant-modal-close').click(); |
||||||
|
// cy.get("body").type("{esc}");
|
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : Virtual column validation > belongs to`, () => { |
||||||
|
// belongs to field validation
|
||||||
|
mainPage |
||||||
|
.getCell("City", 1) |
||||||
|
.click() |
||||||
|
.find(".nc-icon.nc-unlink-icon") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("City", 1) |
||||||
|
.click() |
||||||
|
.find(".nc-icon.nc-action-icon.nc-arrow-expand") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("City", 1) |
||||||
|
.find(".chips") |
||||||
|
.contains("Kanchrapara") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : Virtual column validation > many to many`, () => { |
||||||
|
// many-to-many field validation
|
||||||
|
mainPage |
||||||
|
.getCell("Staff List", 1) |
||||||
|
.click() |
||||||
|
.find(".nc-icon.nc-unlink-icon") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Staff List", 1) |
||||||
|
.click() |
||||||
|
.find(".nc-icon.nc-action-icon.nc-plus") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Staff List", 1) |
||||||
|
.click() |
||||||
|
.find(".nc-icon.nc-action-icon.nc-arrow-expand") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find(".nc-icon.nc-reload").should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find("button") |
||||||
|
.contains("Link to") |
||||||
|
.should("not.exist"); |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Delete ${viewType.toUpperCase()} view`, () => { |
||||||
|
// go back to base page
|
||||||
|
cy.visit(storedURL, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
|
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// number of view entries should be 2 before we delete
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 2); |
||||||
|
|
||||||
|
cy.get(".nc-view-delete-icon").eq(0).click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
|
||||||
|
// confirm if the number of veiw entries is reduced by 1
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 1); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// below scenario's will be invoked twice, once for rest & then for graphql
|
||||||
|
viewTest("grid"); |
||||||
|
}); |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Grid view/ row-column update verification`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
// Address table has belongs to, has many & many-to-many
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
|
||||||
|
cy.saveLocalStorage(); |
||||||
|
// store base URL- to re-visit and delete form view later
|
||||||
|
cy.url().then((url) => { |
||||||
|
storedURL = url; |
||||||
|
generateViewLink("rowColUpdate"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
// close table
|
||||||
|
cy.restoreLocalStorage(); |
||||||
|
cy.visit(storedURL, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// delete row
|
||||||
|
mainPage.getPagination(5).click(); |
||||||
|
// kludge: flicker on load
|
||||||
|
cy.wait(3000) |
||||||
|
|
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 10); |
||||||
|
mainPage |
||||||
|
.getRow(10) |
||||||
|
.find(".mdi-checkbox-blank-outline") |
||||||
|
.click({ force: true }); |
||||||
|
mainPage.getCell("Country", 10).rightclick(); |
||||||
|
cy.getActiveMenu().contains("Delete selected row").click(); |
||||||
|
|
||||||
|
// delete column
|
||||||
|
cy.get(`th:contains('dummy') .nc-ui-dt-dropdown`) |
||||||
|
.trigger("mouseover") |
||||||
|
.click(); |
||||||
|
cy.get(".nc-column-delete").click(); |
||||||
|
cy.get("button:contains(Confirm)").click(); |
||||||
|
|
||||||
|
cy.toastWait("Update table successful"); |
||||||
|
|
||||||
|
mainPage.deleteCreatedViews(); |
||||||
|
|
||||||
|
// close table
|
||||||
|
cy.closeTableTab("Country"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Generate default Shared GRID view URL`, () => { |
||||||
|
// add row
|
||||||
|
cy.get(".nc-add-new-row-btn").click(); |
||||||
|
cy.get("#data-table-form-Country > input") |
||||||
|
.first() |
||||||
|
.click() |
||||||
|
.type("a"); |
||||||
|
cy.contains("Save row").filter("button").click({ force: true }); |
||||||
|
cy.toastWait("updated successfully"); |
||||||
|
|
||||||
|
// add column
|
||||||
|
mainPage.addColumn("dummy", "Country"); |
||||||
|
|
||||||
|
// visit public view
|
||||||
|
cy.log(viewURL["rowColUpdate"]); |
||||||
|
cy.restoreLocalStorage(); |
||||||
|
cy.visit(viewURL["rowColUpdate"], { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
//5
|
||||||
|
// wait for public view page to load!
|
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : new row visible`, () => { |
||||||
|
// verify row
|
||||||
|
cy.get(`.v-pagination > li:contains('5') button`).click(); |
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 10); |
||||||
|
mainPage.getCell("Country", 10).contains("a").should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it.skip(`Share GRID view : new column visible`, () => { |
||||||
|
// verify column headers
|
||||||
|
cy.get('[data-col="dummy"]').should("exist"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,487 @@ |
|||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
|
||||||
|
let storedURL = ""; |
||||||
|
|
||||||
|
// 0: all enabled
|
||||||
|
// 1: field hide
|
||||||
|
// 2: field sort
|
||||||
|
// 3: field filter
|
||||||
|
// 4: default (address table): for view operation validation
|
||||||
|
// 5: default (country table): for update row/column validation
|
||||||
|
let viewURL = {}; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
const generateViewLink = (viewName) => { |
||||||
|
// click on share view
|
||||||
|
// cy.get(".v-navigation-drawer__content > .container")
|
||||||
|
// .find(".v-list > .v-list-item")
|
||||||
|
// .contains("Share View")
|
||||||
|
// .click();
|
||||||
|
mainPage.shareView().click({ force: true }); |
||||||
|
|
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// wait, as URL initially will be /undefined
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".share-link-box") |
||||||
|
.contains("/nc/view/", { timeout: 10000 }) |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// copy link text, visit URL
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".share-link-box") |
||||||
|
.contains("/nc/view/", { timeout: 10000 }) |
||||||
|
.then(($obj) => { |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
// viewURL.push($obj.text())
|
||||||
|
viewURL[viewName] = $obj.text().trim(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - GRID view (Share)`, () => { |
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
// open a table to work on views
|
||||||
|
//
|
||||||
|
cy.openTableTab("Address", 25); |
||||||
|
|
||||||
|
cy.saveLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.restoreLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
afterEach(() => { |
||||||
|
cy.saveLocalStorage(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
// close table
|
||||||
|
// mainPage.deleteCreatedViews()
|
||||||
|
cy.closeTableTab("Address"); |
||||||
|
}); |
||||||
|
|
||||||
|
// Common routine to create/edit/delete GRID & GALLERY view
|
||||||
|
// Input: viewType - 'grid'/'gallery'
|
||||||
|
//
|
||||||
|
const viewTest = (viewType) => { |
||||||
|
it(`Create ${viewType.toUpperCase()} view`, () => { |
||||||
|
// create a normal public view
|
||||||
|
cy.get(`.nc-create-${viewType}-view`).click(); |
||||||
|
cy.getActiveModal().find("button:contains(Submit)").click(); |
||||||
|
cy.toastWait("View created successfully"); |
||||||
|
|
||||||
|
// store base URL- to re-visit and delete form view later
|
||||||
|
cy.url().then((url) => { |
||||||
|
storedURL = url; |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} hide, sort, filter & verify`, () => { |
||||||
|
cy.get(`.nc-view-item.nc-${viewType}-view-item`) |
||||||
|
.contains("Address1") |
||||||
|
.click(); |
||||||
|
mainPage.hideField("Address2"); |
||||||
|
mainPage.sortField("Address", "Z → A"); |
||||||
|
mainPage.filterField("Address", "is like", "Ab"); |
||||||
|
generateViewLink("combined"); |
||||||
|
cy.log(viewURL["combined"]); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : ensure we have only one link even if shared multiple times`, () => { |
||||||
|
// generate view link multiple times
|
||||||
|
generateViewLink("combined"); |
||||||
|
generateViewLink("combined"); |
||||||
|
|
||||||
|
// verify if only one link exists in table
|
||||||
|
// cy.get(".v-navigation-drawer__content > .container")
|
||||||
|
// .find(".v-list > .v-list-item")
|
||||||
|
// .contains("Share View")
|
||||||
|
// .parent()
|
||||||
|
// .find("button.mdi-dots-vertical")
|
||||||
|
// .click();
|
||||||
|
mainPage.shareViewList().click(); |
||||||
|
|
||||||
|
// cy.getActiveMenu().find(".v-list-item").contains("Views List").click();
|
||||||
|
|
||||||
|
cy.get('th:contains("View Link")').should("exist"); |
||||||
|
|
||||||
|
cy.get('th:contains("View Link")') |
||||||
|
.parent() |
||||||
|
.parent() |
||||||
|
.next() |
||||||
|
.find("tr") |
||||||
|
.its("length") |
||||||
|
.should("eq", 1) |
||||||
|
.then(() => { |
||||||
|
// cy.get(".v-overlay__content > .d-flex > .v-icon").click();
|
||||||
|
// close modal (fix me! add a close button to share view list modal)
|
||||||
|
cy.get(".v-overlay--active > .v-overlay__scrim").click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Visit URL, Verify title`, () => { |
||||||
|
// visit public view
|
||||||
|
cy.visit(viewURL["combined"], { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 18); |
||||||
|
|
||||||
|
// verify title
|
||||||
|
cy.get("div.model-name").contains("Address1").should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : verify fields hidden/open`, () => { |
||||||
|
// verify column headers
|
||||||
|
cy.get('[data-col="Address"]').should("exist"); |
||||||
|
cy.get('[data-col="Address2"]').should("not.exist"); |
||||||
|
cy.get('[data-col="District"]').should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : verify fields sort/ filter`, () => { |
||||||
|
// country column content verification before sort
|
||||||
|
mainPage |
||||||
|
.getCell("Address", 1) |
||||||
|
.contains("669 Firozabad Loop") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Address", 2) |
||||||
|
.contains("48 Maracabo Place") |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Address", 3) |
||||||
|
.contains("44 Najafabad Way") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : verify download CSV`, () => { |
||||||
|
mainPage.hideField("LastUpdate"); |
||||||
|
const verifyCsv = (retrievedRecords) => { |
||||||
|
// expected output, statically configured
|
||||||
|
let storedRecords = [ |
||||||
|
`Address,District,PostalCode,Phone`, |
||||||
|
`669 Firozabad Loop,,92265,,[object Object],2,,Kanchrapara,`, |
||||||
|
`48 Maracabo Place,,1570,,[object Object],2,,Tafuna,`, |
||||||
|
`44 Najafabad Way,,61391,,[object Object],2,,Tambaram,`, |
||||||
|
`381 Kabul Way,,87272,,[object Object],1,,Pudukkottai,`, |
||||||
|
]; |
||||||
|
|
||||||
|
for (let i = 0; i < storedRecords.length; i++) { |
||||||
|
let strCol = storedRecords[i].split(","); |
||||||
|
let retCol = retrievedRecords[i].split(","); |
||||||
|
expect(strCol[0]).to.be.equal(retCol[0]); |
||||||
|
expect(strCol[2]).to.be.equal(retCol[2]); |
||||||
|
// expect(retrievedRecords[i]).to.be.equal(storedRecords[i])
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// download & verify
|
||||||
|
mainPage.downloadAndVerifyCsv( |
||||||
|
`Address_exported_1.csv`, |
||||||
|
verifyCsv |
||||||
|
); |
||||||
|
mainPage.unhideField("LastUpdate"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Disable sort`, () => { |
||||||
|
// remove sort and validate
|
||||||
|
mainPage.clearSort(); |
||||||
|
mainPage |
||||||
|
.getCell("Address", 1) |
||||||
|
//ncv2@fixme
|
||||||
|
.contains("669 Firozabad Loop") |
||||||
|
//.contains("217 Botshabelo Place")
|
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Enable sort`, () => { |
||||||
|
// Sort menu operations (Country Column, Z->A)
|
||||||
|
mainPage.sortField("Address", "Z → A"); |
||||||
|
mainPage |
||||||
|
.getCell("Address", 1) |
||||||
|
.contains("669 Firozabad Loop") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Create Filter`, () => { |
||||||
|
// add filter & validate
|
||||||
|
mainPage.filterField("Address", "is like", "drive"); |
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 3); |
||||||
|
mainPage |
||||||
|
.getCell("Address", 1) |
||||||
|
.contains("1888 Kabul Drive") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : verify download CSV after local filter`, () => { |
||||||
|
mainPage.hideField("LastUpdate"); |
||||||
|
const verifyCsv = (retrievedRecords) => { |
||||||
|
// expected output, statically configured
|
||||||
|
let storedRecords = [ |
||||||
|
`Address,District,PostalCode,Phone,Location,Customer List,Staff List,City,Staff List`, |
||||||
|
`1888 Kabul Drive,,20936,,1,,Ife,,`, |
||||||
|
`1661 Abha Drive,,14400,,1,,Pudukkottai,,`, |
||||||
|
]; |
||||||
|
|
||||||
|
// for (let i = 0; i < storedRecords.length; i++) {
|
||||||
|
// expect(retrievedRecords[i]).to.be.equal(storedRecords[i])
|
||||||
|
// }
|
||||||
|
|
||||||
|
for (let i = 0; i < storedRecords.length; i++) { |
||||||
|
let strCol = storedRecords[i].split(","); |
||||||
|
let retCol = retrievedRecords[i].split(","); |
||||||
|
expect(strCol[0]).to.be.equal(retCol[0]); |
||||||
|
expect(strCol[2]).to.be.equal(retCol[2]); |
||||||
|
} |
||||||
|
}; |
||||||
|
mainPage.downloadAndVerifyCsv( |
||||||
|
`Address_exported_1.csv`, |
||||||
|
verifyCsv |
||||||
|
); |
||||||
|
mainPage.unhideField("LastUpdate"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share ${viewType.toUpperCase()} view : Delete Filter`, () => { |
||||||
|
// Remove sort and Validate
|
||||||
|
mainPage.filterReset(); |
||||||
|
mainPage |
||||||
|
.getCell("Address", 1) |
||||||
|
.contains("669 Firozabad Loop") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : Virtual column validation > has many`, () => { |
||||||
|
// verify column headers
|
||||||
|
cy.get('[data-col="Customer List"]').should("exist"); |
||||||
|
cy.get('[data-col="Staff List"]').should("exist"); |
||||||
|
cy.get('[data-col="City"]').should("exist"); |
||||||
|
cy.get('[data-col="Staff List"]').should("exist"); |
||||||
|
|
||||||
|
// has many field validation
|
||||||
|
mainPage |
||||||
|
.getCell("Customer List", 3) |
||||||
|
.click() |
||||||
|
.find("button.mdi-close-thick") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Customer List", 3) |
||||||
|
.click() |
||||||
|
.find("button.mdi-plus") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Customer List", 3) |
||||||
|
.click() |
||||||
|
.find("button.mdi-arrow-expand") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find("button.mdi-reload").should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find("button") |
||||||
|
.contains("Link to") |
||||||
|
.should("not.exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".child-card") |
||||||
|
.contains("2") |
||||||
|
.should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".child-card") |
||||||
|
.find("button") |
||||||
|
.should("not.exist"); |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : Virtual column validation > belongs to`, () => { |
||||||
|
// belongs to field validation
|
||||||
|
mainPage |
||||||
|
.getCell("City", 1) |
||||||
|
.click() |
||||||
|
.find("button.mdi-close-thick") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("City", 1) |
||||||
|
.click() |
||||||
|
.find("button.mdi-arrow-expand") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("City", 1) |
||||||
|
.find(".v-chip") |
||||||
|
.contains("al-Ayn") |
||||||
|
.should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : Virtual column validation > many to many`, () => { |
||||||
|
// many-to-many field validation
|
||||||
|
mainPage |
||||||
|
.getCell("Staff List", 1) |
||||||
|
.click() |
||||||
|
.find("button.mdi-close-thick") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Staff List", 1) |
||||||
|
.click() |
||||||
|
.find("button.mdi-plus") |
||||||
|
.should("not.exist"); |
||||||
|
mainPage |
||||||
|
.getCell("Staff List", 1) |
||||||
|
.click() |
||||||
|
.find("button.mdi-arrow-expand") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find("button.mdi-reload").should("exist"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find("button") |
||||||
|
.contains("Link to") |
||||||
|
.should("not.exist"); |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Delete ${viewType.toUpperCase()} view`, () => { |
||||||
|
// go back to base page
|
||||||
|
cy.visit(storedURL, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// number of view entries should be 2 before we delete
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 2); |
||||||
|
|
||||||
|
cy.get(".nc-view-delete-icon").eq(0).click({ force: true }); |
||||||
|
cy.toastWait("View deleted successfully"); |
||||||
|
|
||||||
|
// confirm if the number of veiw entries is reduced by 1
|
||||||
|
cy.get(".nc-view-item").its("length").should("eq", 1); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// below scenario's will be invoked twice, once for rest & then for graphql
|
||||||
|
viewTest("grid"); |
||||||
|
}); |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Grid view/ row-column update verification`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
// Address table has belongs to, has many & many-to-many
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
|
||||||
|
cy.saveLocalStorage(); |
||||||
|
// store base URL- to re-visit and delete form view later
|
||||||
|
cy.url().then((url) => { |
||||||
|
storedURL = url; |
||||||
|
generateViewLink("rowColUpdate"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
// close table
|
||||||
|
cy.restoreLocalStorage(); |
||||||
|
cy.visit(storedURL, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// delete row
|
||||||
|
mainPage.getPagination(5).click(); |
||||||
|
// kludge: flicker on load
|
||||||
|
cy.wait(3000) |
||||||
|
|
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 10); |
||||||
|
mainPage |
||||||
|
.getRow(10) |
||||||
|
.find(".mdi-checkbox-blank-outline") |
||||||
|
.click({ force: true }); |
||||||
|
mainPage.getCell("Country", 10).rightclick(); |
||||||
|
cy.getActiveMenu().contains("Delete Selected Row").click(); |
||||||
|
|
||||||
|
// delete column
|
||||||
|
cy.get(`th:contains('dummy') .mdi-menu-down`) |
||||||
|
.trigger("mouseover") |
||||||
|
.click(); |
||||||
|
cy.get(".nc-column-delete").click(); |
||||||
|
cy.get("button:contains(Confirm)").click(); |
||||||
|
|
||||||
|
cy.toastWait("Update table successful"); |
||||||
|
|
||||||
|
mainPage.deleteCreatedViews(); |
||||||
|
|
||||||
|
// close table
|
||||||
|
cy.closeTableTab("Country"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Generate default Shared GRID view URL`, () => { |
||||||
|
// add row
|
||||||
|
cy.get(".nc-add-new-row-btn").click(); |
||||||
|
cy.get("#data-table-form-Country > input") |
||||||
|
.first() |
||||||
|
.click() |
||||||
|
.type("a"); |
||||||
|
cy.contains("Save row").filter("button").click({ force: true }); |
||||||
|
cy.toastWait("updated successfully"); |
||||||
|
|
||||||
|
// add column
|
||||||
|
mainPage.addColumn("dummy", "Country"); |
||||||
|
|
||||||
|
// visit public view
|
||||||
|
cy.log(viewURL["rowColUpdate"]); |
||||||
|
cy.restoreLocalStorage(); |
||||||
|
cy.visit(viewURL["rowColUpdate"], { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
//5
|
||||||
|
// wait for public view page to load!
|
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Share GRID view : new row visible`, () => { |
||||||
|
// verify row
|
||||||
|
cy.get(`.v-pagination > li:contains('5') button`).click(); |
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 10); |
||||||
|
mainPage.getCell("Country", 10).contains("a").should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it.skip(`Share GRID view : new column visible`, () => { |
||||||
|
// verify column headers
|
||||||
|
cy.get('[data-col="dummy"]').should("exist"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,280 @@ |
|||||||
|
import { loginPage, projectsPage } from "../../support/page_objects/navigation"; |
||||||
|
import { mainPage, settingsPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { |
||||||
|
isPostgres, |
||||||
|
isXcdb, |
||||||
|
roles, |
||||||
|
staticProjects, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
import { |
||||||
|
_advSettings, |
||||||
|
_editSchema, |
||||||
|
_editData, |
||||||
|
_editComment, |
||||||
|
_viewMenu, |
||||||
|
_topRightMenu, |
||||||
|
disableTableAccess, |
||||||
|
_accessControl, |
||||||
|
} from "../spec/roleValidation.spec"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe("Static user creations (different roles)", () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
settingsPage.openMenu(settingsPage.TEAM_N_AUTH) |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
const addUser = (user) => { |
||||||
|
it(`RoleType: ${user.name}`, () => { |
||||||
|
// for first project, users need to be added explicitly using "New User" button
|
||||||
|
// for subsequent projects, they will be required to just add to this project
|
||||||
|
// using ROW count to identify if its former or latter scenario
|
||||||
|
// 5 users (owner, creator, editor, viewer, commenter) = 5
|
||||||
|
cy.get(`.nc-user-row`).then((obj) => { |
||||||
|
cy.log(obj.length); |
||||||
|
if (obj.length == 5) { |
||||||
|
mainPage.addExistingUserToProject( |
||||||
|
user.credentials.username, |
||||||
|
user.name |
||||||
|
); |
||||||
|
} else { |
||||||
|
mainPage.addNewUserToProject( |
||||||
|
user.credentials, |
||||||
|
user.name |
||||||
|
); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
addUser(roles.creator); |
||||||
|
addUser(roles.editor); |
||||||
|
addUser(roles.commenter); |
||||||
|
addUser(roles.viewer); |
||||||
|
|
||||||
|
// Access contrl list- configuration
|
||||||
|
//
|
||||||
|
it(`Access control list- configuration`, () => { |
||||||
|
mainPage.closeMetaTab(); |
||||||
|
|
||||||
|
// open Project metadata tab
|
||||||
|
//
|
||||||
|
settingsPage.openMenu(settingsPage.PROJ_METADATA); |
||||||
|
settingsPage.openTab(settingsPage.UI_ACCESS_CONTROL); |
||||||
|
|
||||||
|
// validate if it has 19 entries representing tables & views
|
||||||
|
if (isPostgres()) |
||||||
|
cy.get(".nc-acl-table-row").should("have.length", 24); |
||||||
|
else if (isXcdb()) |
||||||
|
cy.get(".nc-acl-table-row").should("have.length", 19); |
||||||
|
else cy.get(".nc-acl-table-row").should("have.length", 19); |
||||||
|
|
||||||
|
// disable table & view access
|
||||||
|
//
|
||||||
|
disableTableAccess("Language", "editor"); |
||||||
|
disableTableAccess("Language", "commenter"); |
||||||
|
disableTableAccess("Language", "viewer"); |
||||||
|
|
||||||
|
disableTableAccess("CustomerList", "editor"); |
||||||
|
disableTableAccess("CustomerList", "commenter"); |
||||||
|
disableTableAccess("CustomerList", "viewer"); |
||||||
|
|
||||||
|
cy.get("button.nc-acl-save").click({ force: true }); |
||||||
|
cy.toastWait("Updated UI ACL for tables successfully"); |
||||||
|
|
||||||
|
mainPage.closeMetaTab(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
const roleValidation = (roleType) => { |
||||||
|
describe(`User role validation`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
if (roleType != "owner") { |
||||||
|
it(`[${roles[roleType].name}] SignIn, Open project`, () => { |
||||||
|
cy.log(mainPage.roleURL[roleType]); |
||||||
|
cy.visit(mainPage.roleURL[roleType], { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// Redirected to new URL, feed details
|
||||||
|
//
|
||||||
|
cy.get('input[type="text"]') |
||||||
|
.should("exist") |
||||||
|
.type(roles[roleType].credentials.username); |
||||||
|
cy.get('input[type="password"]').type( |
||||||
|
roles[roleType].credentials.password |
||||||
|
); |
||||||
|
cy.get('button:contains("SIGN")').click(); |
||||||
|
|
||||||
|
// cy.url({ timeout: 6000 }).should("contain", "#/project");
|
||||||
|
cy.get('nc-project-page-title').contains("My Projects").should("be.visible"); |
||||||
|
|
||||||
|
if (dbType === "xcdb") { |
||||||
|
if ("rest" == apiType) |
||||||
|
projectsPage.openProject( |
||||||
|
staticProjects.sampleREST.basic.name |
||||||
|
); |
||||||
|
else |
||||||
|
projectsPage.openProject( |
||||||
|
staticProjects.sampleGQL.basic.name |
||||||
|
); |
||||||
|
} else if (dbType === "mysql") { |
||||||
|
if ("rest" == apiType) |
||||||
|
projectsPage.openProject( |
||||||
|
staticProjects.externalREST.basic.name |
||||||
|
); |
||||||
|
else |
||||||
|
projectsPage.openProject( |
||||||
|
staticProjects.externalGQL.basic.name |
||||||
|
); |
||||||
|
} else if (dbType === "postgres") { |
||||||
|
if ("rest" == apiType) |
||||||
|
projectsPage.openProject( |
||||||
|
staticProjects.pgExternalREST.basic.name |
||||||
|
); |
||||||
|
else |
||||||
|
projectsPage.openProject( |
||||||
|
staticProjects.pgExternalGQL.basic.name |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
if (roleType != "creator") { |
||||||
|
cy.closeTableTab("Actor"); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
// Test suite
|
||||||
|
|
||||||
|
it(`[${roles[roleType].name}] Left navigation menu, New User add`, () => { |
||||||
|
// project configuration settings
|
||||||
|
//
|
||||||
|
_advSettings(roleType, "userRole"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`[${roles[roleType].name}] Access control`, () => { |
||||||
|
// Access control validation
|
||||||
|
//
|
||||||
|
_accessControl(roleType, "userRole"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`[${roles[roleType].name}] Schema: create table, add/modify/delete column`, () => { |
||||||
|
// Schema related validations
|
||||||
|
// - Add/delete table
|
||||||
|
// - Add/Update/delete column
|
||||||
|
//
|
||||||
|
_editSchema(roleType, "userRole"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`[${roles[roleType].name}] Data: add/modify/delete row, update cell contents`, () => { |
||||||
|
// Table data related validations
|
||||||
|
// - Add/delete/modify row
|
||||||
|
//
|
||||||
|
_editData(roleType, "userRole"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`[${roles[roleType].name}] Comments: view/add`, () => { |
||||||
|
// read &/ update comment
|
||||||
|
// Viewer: only allowed to read
|
||||||
|
// Everyone else: read &/ update
|
||||||
|
//
|
||||||
|
_editComment(roleType, "userRole"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`[${roles[roleType].name}] Right navigation menu, share view`, () => { |
||||||
|
// right navigation menu bar
|
||||||
|
// Editor/Viewer/Commenter : can only view 'existing' views
|
||||||
|
// Rest: can create/edit
|
||||||
|
_viewMenu(roleType, "userRole"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`[${roles[roleType].name}] Top Right Menu bar`, () => { |
||||||
|
// Share button is conditional
|
||||||
|
// Rest are static/ mandatory
|
||||||
|
//
|
||||||
|
_topRightMenu(roleType, "userRole"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`[${roles[roleType].name}] Download files`, () => { |
||||||
|
// viewer & commenter doesn't contain hideField option in ncv2
|
||||||
|
// #ID, City, LastUpdate, City => Address, Country <= City, +
|
||||||
|
mainPage.hideField("LastUpdate"); |
||||||
|
|
||||||
|
const verifyCsv = (retrievedRecords) => { |
||||||
|
// expected output, statically configured
|
||||||
|
let storedRecords = [ |
||||||
|
`City,Address List,Country`, |
||||||
|
`A Corua (La Corua),939 Probolinggo Loop,Spain`, |
||||||
|
`Abha,733 Mandaluyong Place,Saudi Arabia`, |
||||||
|
`Abu Dhabi,535 Ahmadnagar Manor,United Arab Emirates`, |
||||||
|
`Acua,1789 Saint-Denis Parkway,Mexico`, |
||||||
|
]; |
||||||
|
|
||||||
|
// skip if xcdb
|
||||||
|
if (!isXcdb()) { |
||||||
|
for (let i = 0; i < storedRecords.length; i++) { |
||||||
|
// cy.log(retrievedRecords[i])
|
||||||
|
expect(retrievedRecords[i]).to.be.equal( |
||||||
|
storedRecords[i] |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// download & verify
|
||||||
|
mainPage.downloadAndVerifyCsv( |
||||||
|
`City_exported_1.csv`, |
||||||
|
verifyCsv |
||||||
|
); |
||||||
|
mainPage.unhideField("LastUpdate"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// skip owner validation as rest of the cases pretty much cover the same
|
||||||
|
// roleValidation('owner')
|
||||||
|
roleValidation("creator"); |
||||||
|
roleValidation("editor"); |
||||||
|
roleValidation("commenter"); |
||||||
|
roleValidation("viewer"); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,175 @@ |
|||||||
|
// pre-requisite:
|
||||||
|
// user@nocodb.com signed up as admin
|
||||||
|
// sakilaDb database created already
|
||||||
|
|
||||||
|
import { loginPage, projectsPage } from "../../support/page_objects/navigation"; |
||||||
|
import { mainPage, settingsPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { |
||||||
|
isPostgres, |
||||||
|
isTestSuiteActive, |
||||||
|
isXcdb, roles |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
import { |
||||||
|
_advSettings, |
||||||
|
_editSchema, |
||||||
|
_editData, |
||||||
|
_editComment, |
||||||
|
_viewMenu, |
||||||
|
_topRightMenu, |
||||||
|
enableTableAccess, |
||||||
|
_accessControl, |
||||||
|
} from "../spec/roleValidation.spec"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType, roleType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//// Test Suite
|
||||||
|
|
||||||
|
describe("Role preview validations", () => { |
||||||
|
// Sign in/ open project
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
loginPage.loginAndOpenProject(apiType, dbType); |
||||||
|
cy.openTableTab("City", 25); |
||||||
|
|
||||||
|
settingsPage.openProjectMenu(); |
||||||
|
cy.getActiveMenu().find(`[data-submenu-id="preview-as"]`).should('exist').click() |
||||||
|
cy.wait(1000) |
||||||
|
cy.get('.ant-dropdown-menu-submenu').eq(3).find(`[data-menu-id="editor"]`).should('exist').click() |
||||||
|
|
||||||
|
cy.wait(10000) |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
// cy.get(".nc-preview-reset").click({ force: true });
|
||||||
|
cy.get(".mdi-exit-to-app").click(); |
||||||
|
// cy.wait(20000)
|
||||||
|
|
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row", { timeout: 25000 }).should( |
||||||
|
"have.length", |
||||||
|
25 |
||||||
|
); |
||||||
|
|
||||||
|
// cy.get('.nc-preview-reset:visible').should('not-exist')
|
||||||
|
|
||||||
|
// mainPage.navigationDraw(mainPage.ROLE_VIEW).contains('Reset Preview').should('not.exist')
|
||||||
|
// cy.get('.nc-preview-reset').should('not-exist')
|
||||||
|
cy.closeTableTab("City"); |
||||||
|
|
||||||
|
// open Project metadata tab
|
||||||
|
//
|
||||||
|
mainPage.navigationDraw(mainPage.PROJ_METADATA).click(); |
||||||
|
// cy.get(".nc-exp-imp-metadata").dblclick({ force: true });
|
||||||
|
cy.get(".nc-ui-acl-tab").click({ force: true }); |
||||||
|
|
||||||
|
// validate if it has 19 entries representing tables & views
|
||||||
|
if (isPostgres()) |
||||||
|
cy.get(".nc-acl-table-row").should("have.length", 24); |
||||||
|
else if (isXcdb()) |
||||||
|
cy.get(".nc-acl-table-row").should("have.length", 19); |
||||||
|
else cy.get(".nc-acl-table-row").should("have.length", 19); |
||||||
|
|
||||||
|
// restore access
|
||||||
|
//
|
||||||
|
enableTableAccess("language", "editor"); |
||||||
|
enableTableAccess("language", "commenter"); |
||||||
|
enableTableAccess("language", "viewer"); |
||||||
|
|
||||||
|
enableTableAccess("customerlist", "editor"); |
||||||
|
enableTableAccess("customerlist", "commenter"); |
||||||
|
enableTableAccess("customerlist", "viewer"); |
||||||
|
}); |
||||||
|
|
||||||
|
const genTestSub = (roleType) => { |
||||||
|
it(`Role preview: ${roleType}: Enable preview`, () => { |
||||||
|
cy.get(".nc-floating-preview-btn", {timeout: 30000}).should("exist"); |
||||||
|
cy.get('.nc-floating-preview-btn') |
||||||
|
.find(`[type="radio"][value="${roleType}"]`) |
||||||
|
.should('exist') |
||||||
|
.click(); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Role preview: ${roleType}: Advance settings`, () => { |
||||||
|
// project configuration settings
|
||||||
|
//
|
||||||
|
_advSettings(roleType, "preview"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Role preview: ${roleType}: Access control`, () => { |
||||||
|
// Access control validation
|
||||||
|
//
|
||||||
|
_accessControl(roleType, "preview"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Role preview: ${roleType}: Edit data`, () => { |
||||||
|
// Table data related validations
|
||||||
|
// - Add/delete/modify row
|
||||||
|
//
|
||||||
|
_editData(roleType, "preview"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Role preview: ${roleType}: Edit comment`, () => { |
||||||
|
// read &/ update comment
|
||||||
|
// Viewer: not allowed to read
|
||||||
|
// Everyone else: read &/ update
|
||||||
|
//
|
||||||
|
_editComment(roleType, "preview"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Role preview: ${roleType}: Preview menu`, () => { |
||||||
|
// right navigation menu bar
|
||||||
|
// Editor/Viewer/Commenter : can only view 'existing' views
|
||||||
|
// Rest: can create/edit
|
||||||
|
_viewMenu(roleType, "preview"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Role preview: ${roleType}: Top Right Menu bar`, () => { |
||||||
|
// Share button is conditional
|
||||||
|
// Rest are static/ mandatory
|
||||||
|
//
|
||||||
|
_topRightMenu(roleType, "preview"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Role preview: ${roleType}: Edit Schema`, () => { |
||||||
|
// Schema related validations
|
||||||
|
// - Add/delete table
|
||||||
|
// - Add/Update/delete column
|
||||||
|
//
|
||||||
|
_editSchema(roleType, "preview"); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
genTestSub("editor"); |
||||||
|
genTestSub("commenter"); |
||||||
|
genTestSub("viewer"); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,89 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { loginPage } from "../../support/page_objects/navigation"; |
||||||
|
import { |
||||||
|
isPostgres, |
||||||
|
isTestSuiteActive, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} Upload/ Download CSV`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
mainPage.tabReset(); |
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.closeTableTab("Country"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Download verification- base view, default columns", () => { |
||||||
|
mainPage.hideField("LastUpdate"); |
||||||
|
const verifyCsv = (retrievedRecords) => { |
||||||
|
// expected output, statically configured
|
||||||
|
// let storedRecords = [
|
||||||
|
// `Country,CityList`,
|
||||||
|
// `Afghanistan,Kabul`,
|
||||||
|
// `Algeria,"Batna, Bchar, Skikda"`,
|
||||||
|
// `American Samoa,Tafuna`,
|
||||||
|
// `Angola,"Benguela, Namibe"`,
|
||||||
|
// ];
|
||||||
|
let storedRecords = [ |
||||||
|
['Country','City List'], |
||||||
|
['Afghanistan','Kabul'], |
||||||
|
['Algeria','Skikda', 'Bchar', 'Batna'], |
||||||
|
['American Samoa','Tafuna'], |
||||||
|
['Angola','Benguela', 'Namibe'], |
||||||
|
]; |
||||||
|
|
||||||
|
// if (isPostgres()) {
|
||||||
|
// // order of second entry is different
|
||||||
|
// storedRecords = [
|
||||||
|
// `Country,City List`,
|
||||||
|
// `Afghanistan,Kabul`,
|
||||||
|
// `Algeria,"Skikda, Bchar, Batna"`,
|
||||||
|
// `American Samoa,Tafuna`,
|
||||||
|
// `Angola,"Benguela, Namibe"`,
|
||||||
|
// ];
|
||||||
|
// }
|
||||||
|
|
||||||
|
for (let i = 0; i < storedRecords.length - 1; i++) { |
||||||
|
for(let j=0; j<storedRecords[i].length; j++) |
||||||
|
expect(retrievedRecords[i]).to.have.string(storedRecords[i][j]) |
||||||
|
|
||||||
|
// often, the order in which records "Skikda, Bchar, Batna" appear, used to toggle
|
||||||
|
// hence verifying record contents separately
|
||||||
|
// expect(retrievedRecords[i]).to.be.equal(storedRecords[i]);
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// download & verify
|
||||||
|
mainPage.downloadAndVerifyCsv(`Country_exported_1.csv`, verifyCsv); |
||||||
|
mainPage.unhideField("LastUpdate"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,276 @@ |
|||||||
|
import { loginPage } from "../../support/page_objects/navigation"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { roles } from "../../support/page_objects/projectConstants"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} : API List - Test preparation`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
loginPage.loginAndOpenProject(apiType, dbType); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Open project & record swagger URL, AuthToken", () => { |
||||||
|
let authToken = mainPage.getAuthToken(); |
||||||
|
cy.url().then((url) => { |
||||||
|
// retrieve project name from URL & use it to construct Swagger URL
|
||||||
|
// URL on homepage: http://localhost:3000/#/nc/externalrest_weUO?type=roles&dbalias=&name=Team%20%26%20Auth%20
|
||||||
|
// [REST] Swagger URL: http://localhost:8080/nc/externalrest_weUO/db/swagger
|
||||||
|
// [GQL] http://localhost:8080/nc/externalgql_dgwx/v1/graphql
|
||||||
|
const projectName = url.split("/")[5].split("?")[0]; |
||||||
|
let swaggerURL = ``; |
||||||
|
if ("rest" == apiType) { |
||||||
|
swaggerURL = `http://localhost:8080/nc/${projectName}/db/swagger`; |
||||||
|
} else { |
||||||
|
swaggerURL = `http://localhost:8080/nc/${projectName}/v1/graphql`; |
||||||
|
} |
||||||
|
|
||||||
|
// exchange information between two tests using a file
|
||||||
|
// https://stackoverflow.com/questions/52050657/what-is-the-best-practice-of-pass-states-between-tests-in-cypress
|
||||||
|
//
|
||||||
|
cy.writeFile("shared.json", { |
||||||
|
SWAGGER_URL: swaggerURL, |
||||||
|
AUTH_TOKEN: authToken, |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
if ("rest" == apiType) { |
||||||
|
describe(`Swagger page, base verification`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
// returns swagger button intended for
|
||||||
|
//
|
||||||
|
const getSwaggerButton = (tag, idx, desc) => { |
||||||
|
return cy |
||||||
|
.get(`#operations-tag-${tag}`) |
||||||
|
.next() |
||||||
|
.find(".opblock") |
||||||
|
.eq(idx) |
||||||
|
.find(`button:contains(${desc})`); |
||||||
|
}; |
||||||
|
|
||||||
|
let Token; |
||||||
|
|
||||||
|
// basic authentication tag verification
|
||||||
|
//
|
||||||
|
it("Swagger URL access & basic validation", () => { |
||||||
|
// retrieve information stored in previous IT block
|
||||||
|
//
|
||||||
|
cy.readFile("shared.json").then((jsonPayload) => { |
||||||
|
let URL = jsonPayload.SWAGGER_URL; |
||||||
|
Token = jsonPayload.AUTH_TOKEN; |
||||||
|
|
||||||
|
cy.visit(URL, { |
||||||
|
baseUrl: null, |
||||||
|
}).then(() => { |
||||||
|
// wait to allow time for SWAGGER Library loading to finish
|
||||||
|
cy.log(Token); |
||||||
|
|
||||||
|
// cy.snip("Swagger");
|
||||||
|
|
||||||
|
// validate; API order assumed
|
||||||
|
cy.get("#operations-tag-Authentication", { |
||||||
|
timeout: 20000, |
||||||
|
}) |
||||||
|
.should("exist") |
||||||
|
.next() |
||||||
|
.find(".opblock") |
||||||
|
.should("has.length", 9); |
||||||
|
getSwaggerButton( |
||||||
|
"Authentication", |
||||||
|
0, |
||||||
|
"User login" |
||||||
|
).should("exist"); |
||||||
|
getSwaggerButton( |
||||||
|
"Authentication", |
||||||
|
1, |
||||||
|
"User signup" |
||||||
|
).should("exist"); |
||||||
|
getSwaggerButton( |
||||||
|
"Authentication", |
||||||
|
2, |
||||||
|
"Password Forgot" |
||||||
|
).should("exist"); |
||||||
|
getSwaggerButton( |
||||||
|
"Authentication", |
||||||
|
3, |
||||||
|
"Email validate link" |
||||||
|
).should("exist"); |
||||||
|
getSwaggerButton( |
||||||
|
"Authentication", |
||||||
|
4, |
||||||
|
"Validate password reset token" |
||||||
|
).should("exist"); |
||||||
|
getSwaggerButton( |
||||||
|
"Authentication", |
||||||
|
5, |
||||||
|
"Password reset" |
||||||
|
).should("exist"); |
||||||
|
getSwaggerButton( |
||||||
|
"Authentication", |
||||||
|
6, |
||||||
|
"User details" |
||||||
|
).should("exist"); |
||||||
|
getSwaggerButton( |
||||||
|
"Authentication", |
||||||
|
7, |
||||||
|
"Update user details" |
||||||
|
).should("exist"); |
||||||
|
getSwaggerButton( |
||||||
|
"Authentication", |
||||||
|
8, |
||||||
|
"Update user details" |
||||||
|
).should("exist"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Authorize success: Valid token", () => { |
||||||
|
// authorize button, feed token, click authorize
|
||||||
|
cy.get('[class="btn authorize unlocked"]').click(); |
||||||
|
cy.get("input").type(Token); |
||||||
|
cy.get(".auth-btn-wrapper > .authorize").click(); |
||||||
|
|
||||||
|
// Response: "Authorized" should exist on DOM
|
||||||
|
cy.get(".auth-container") |
||||||
|
.contains("Authorized") |
||||||
|
.should("exist"); |
||||||
|
cy.get(".btn-done").click(); |
||||||
|
|
||||||
|
// Authorize button is LOCKED now
|
||||||
|
cy.get('[class="btn authorize locked"]').should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Execute Authentication (valid token case) > GET: User details API", () => { |
||||||
|
// Auth> User details API
|
||||||
|
getSwaggerButton("Authentication", 6, "User details").click(); |
||||||
|
|
||||||
|
// "Try it out" button, followed by "Execute"
|
||||||
|
cy.get(".try-out > .btn").click(); |
||||||
|
cy.get(".execute-wrapper > .btn").click(); |
||||||
|
|
||||||
|
// check response: validate email credentials
|
||||||
|
cy.get(".highlight-code > .microlight") |
||||||
|
.contains("email") |
||||||
|
.should("exist"); |
||||||
|
cy.get(".highlight-code > .microlight") |
||||||
|
.contains(roles.owner.credentials.username) |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// reset operations (clear, cancel, windback User details tab)
|
||||||
|
cy.get(".btn-clear").click(); |
||||||
|
cy.get(".try-out > .btn").click(); |
||||||
|
getSwaggerButton("Authentication", 6, "User details").click(); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Logout post authorization", () => { |
||||||
|
// authorize button, logout
|
||||||
|
cy.get('[class="btn authorize locked"]').click(); |
||||||
|
cy.get('.auth-btn-wrapper > button:contains("Logout")').click(); |
||||||
|
cy.get(".btn-done").click(); |
||||||
|
|
||||||
|
// Authorize button is UNLOCKED now
|
||||||
|
cy.get('[class="btn authorize unlocked"]').should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Execute Authentication (logout case) > GET: User details API", () => { |
||||||
|
// Auth> User details API
|
||||||
|
getSwaggerButton("Authentication", 6, "User details").click(); |
||||||
|
|
||||||
|
// "Try it out" button, followed by "Execute"
|
||||||
|
cy.get(".try-out > .btn").click(); |
||||||
|
cy.get(".execute-wrapper > .btn").click(); |
||||||
|
|
||||||
|
// check response: email credentials shouldnt exist. should display 'guest:true'
|
||||||
|
cy.get(".highlight-code > .microlight") |
||||||
|
.contains("guest") |
||||||
|
.should("exist"); |
||||||
|
cy.get(".highlight-code > .microlight") |
||||||
|
.contains("email") |
||||||
|
.should("not.exist"); |
||||||
|
cy.get(".highlight-code > .microlight") |
||||||
|
.contains(roles.owner.credentials.username) |
||||||
|
.should("not.exist"); |
||||||
|
|
||||||
|
// reset operations (clear, cancel, windback User details tab)
|
||||||
|
cy.get(".btn-clear").click(); |
||||||
|
cy.get(".try-out > .btn").click(); |
||||||
|
getSwaggerButton("Authentication", 6, "User details").click(); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Authorize failure: invalid token", () => { |
||||||
|
// authorize button, feed *invalid* token, click authorize
|
||||||
|
cy.get('[class="btn authorize unlocked"]').click(); |
||||||
|
cy.get("input").type("xyz"); |
||||||
|
cy.get(".auth-btn-wrapper > .authorize").click(); |
||||||
|
|
||||||
|
// Response: "Authorized" should *not* exist on DOM
|
||||||
|
// TBD: cy.get('.auth-container').contains('Authorized').should('not.exist')
|
||||||
|
cy.get(".btn-done").click(); |
||||||
|
|
||||||
|
// Authorize button should be UNLOCKED now
|
||||||
|
// TBD: cy.get('[class="btn authorize unlocked"]').should('exist')
|
||||||
|
}); |
||||||
|
|
||||||
|
it("Execute Authentication (invalid token case) > GET: User details API", () => { |
||||||
|
// Auth> User details API
|
||||||
|
getSwaggerButton("Authentication", 6, "User details").click(); |
||||||
|
|
||||||
|
// "Try it out" button, followed by "Execute"
|
||||||
|
cy.get(".try-out > .btn").click(); |
||||||
|
cy.get(".execute-wrapper > .btn").click(); |
||||||
|
|
||||||
|
// check response: email credentials shouldnt exist. should display 'guest:true'
|
||||||
|
cy.get(".highlight-code > .microlight") |
||||||
|
.contains("guest") |
||||||
|
.should("exist"); |
||||||
|
cy.get(".highlight-code > .microlight") |
||||||
|
.contains("email") |
||||||
|
.should("not.exist"); |
||||||
|
cy.get(".highlight-code > .microlight") |
||||||
|
.contains(roles.owner.credentials.username) |
||||||
|
.should("not.exist"); |
||||||
|
|
||||||
|
// reset operations (clear, cancel, windback User details tab)
|
||||||
|
cy.get(".btn-clear").click(); |
||||||
|
cy.get(".try-out > .btn").click(); |
||||||
|
getSwaggerButton("Authentication", 6, "User details").click(); |
||||||
|
}); |
||||||
|
|
||||||
|
// clean-up created file (shared.json)
|
||||||
|
// after(() => {
|
||||||
|
// cy.exec("del shared.json").then(()=> {
|
||||||
|
// cy.log("file cleaned up!")
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,100 @@ |
|||||||
|
const { mainPage } = require("../../support/page_objects/mainPage"); |
||||||
|
const { loginPage } = require("../../support/page_objects/navigation"); |
||||||
|
const { roles } = require("../../support/page_objects/projectConstants"); |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
describe(`Language support`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
cy.visit("/") |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}); |
||||||
|
|
||||||
|
const langVerification = (idx, lang) => { |
||||||
|
// pick json from the file specified
|
||||||
|
it(`Language verification: ${lang} > Projects page`, () => { |
||||||
|
let json = require(`../../../../packages/nc-gui-v2/lang/${lang}`); |
||||||
|
|
||||||
|
// toggle menu as per index
|
||||||
|
cy.get(".nc-menu-translate").should('exist').last().click(); |
||||||
|
cy.getActiveMenu().find(".ant-dropdown-menu-item").eq(idx).click(); |
||||||
|
|
||||||
|
// basic validations
|
||||||
|
// 1. Page title: "My Projects"
|
||||||
|
// 2. Button: "New Project"
|
||||||
|
// 3. Search box palceholder text: "Search Projects"
|
||||||
|
// cy.get("b").contains(json.title.myProject).should("exist");
|
||||||
|
cy.get(".nc-project-page-title") |
||||||
|
.contains(json.title.myProject) |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-new-project-menu") |
||||||
|
.contains(json.title.newProj) |
||||||
|
.should("exist"); |
||||||
|
cy.get(`[placeholder="${json.activity.searchProject}"]`).should( |
||||||
|
"exist" |
||||||
|
); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
let langMenu = [ |
||||||
|
"da.json", |
||||||
|
"de.json", |
||||||
|
"en.json", |
||||||
|
"es.json", |
||||||
|
"fa.json", |
||||||
|
"fi.json", |
||||||
|
"fr.json", |
||||||
|
"hr.json", |
||||||
|
"id.json", |
||||||
|
"it_IT.json", |
||||||
|
"iw.json", |
||||||
|
"ja.json", |
||||||
|
"ko.json", |
||||||
|
"lv.json", |
||||||
|
"nl.json", |
||||||
|
"no.json", |
||||||
|
"pt_BR.json", |
||||||
|
"ru.json", |
||||||
|
"sl.json", |
||||||
|
"sv.json", |
||||||
|
"th.json", |
||||||
|
"tr.json", |
||||||
|
"uk.json", |
||||||
|
"vi.json", |
||||||
|
"zh_CN.json", |
||||||
|
"zh_HK.json", |
||||||
|
"zh_TW.json", |
||||||
|
]; |
||||||
|
|
||||||
|
// Index is the order in which menu options appear
|
||||||
|
for (let i = 0; i < langMenu.length; i++) |
||||||
|
langVerification(i, langMenu[i]); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,49 @@ |
|||||||
|
import { loginPage } from "../../support/page_objects/navigation"; |
||||||
|
import { isXcdb, roles } from "../../support/page_objects/projectConstants"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
describe(`${apiType.toUpperCase()} Project operations`, () => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
loginPage.signIn(roles.owner.credentials); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Delete Project", () => { |
||||||
|
|
||||||
|
cy.get(`.nc-action-btn`) |
||||||
|
.should("exist") |
||||||
|
.last() |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-btn-dangerous") |
||||||
|
.should("exist") |
||||||
|
.click(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,184 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { loginPage } from "../../support/page_objects/navigation"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} Columns of type attachment`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
loginPage.loginAndOpenProject(apiType, dbType); |
||||||
|
|
||||||
|
// kludge: wait for page load to finish
|
||||||
|
cy.wait(3000); |
||||||
|
// close team & auth tab
|
||||||
|
cy.get('button.ant-tabs-tab-remove').should('exist').click(); |
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
mainPage.deleteColumn("testAttach"); |
||||||
|
|
||||||
|
// clean up newly added rows into Country table operations
|
||||||
|
// this auto verifies successfull addition of rows to table as well
|
||||||
|
mainPage.getPagination(5).click(); |
||||||
|
// kludge: flicker on load
|
||||||
|
cy.wait(3000) |
||||||
|
|
||||||
|
// wait for page rendering to complete
|
||||||
|
cy.get(".nc-grid-row").should("have.length", 10); |
||||||
|
// mainPage
|
||||||
|
// .getRow(10)
|
||||||
|
// .find(".mdi-checkbox-blank-outline")
|
||||||
|
// .click({ force: true });
|
||||||
|
|
||||||
|
mainPage.getCell("Country", 10).rightclick(); |
||||||
|
cy.getActiveMenu().contains("Delete Row").click(); |
||||||
|
|
||||||
|
cy.closeTableTab("Country"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Add column of type attachments`, () => { |
||||||
|
mainPage.addColumnWithType("testAttach", "Attachment", "Country"); |
||||||
|
|
||||||
|
for (let i = 4; i <= 6; i++) { |
||||||
|
let filepath = `sampleFiles/${i}.json`; |
||||||
|
cy.get('.nc-attachment-cell') |
||||||
|
.eq(i) |
||||||
|
.attachFile(filepath, { subjectType: 'drag-n-drop' }); |
||||||
|
cy.get('.nc-attachment-cell') |
||||||
|
.eq(i) |
||||||
|
.find(".nc-attachment") |
||||||
|
.should("exist"); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Form view with Attachment field- Submit & verify`, () => { |
||||||
|
|
||||||
|
// open right navbar
|
||||||
|
cy.get('.nc-toggle-right-navbar').should('exist').click(); |
||||||
|
|
||||||
|
// create form-view
|
||||||
|
cy.get(`.nc-create-1-view`).click(); |
||||||
|
cy.getActiveModal().find("button:contains(Submit)").click(); |
||||||
|
|
||||||
|
cy.toastWait("View created successfully"); |
||||||
|
|
||||||
|
mainPage.shareView().click(); |
||||||
|
|
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// copy link text, visit URL
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".share-link-box") |
||||||
|
.contains("/nc/form/", { timeout: 10000 }) |
||||||
|
.should('exist') |
||||||
|
.then(($obj) => { |
||||||
|
let linkText = $obj.text().trim(); |
||||||
|
cy.log(linkText); |
||||||
|
cy.visit(linkText, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
|
||||||
|
// wait for share view page to load!
|
||||||
|
cy.get(".nc-form").should("exist"); |
||||||
|
|
||||||
|
// fill form
|
||||||
|
// 0: Country
|
||||||
|
// 1: LastUpdate
|
||||||
|
cy.get(".nc-input").eq(0).type("_abc"); |
||||||
|
cy.get(".nc-input").eq(1).click(); |
||||||
|
cy.get('.ant-picker-dropdown').find(".ant-picker-now-btn").click(); |
||||||
|
cy.get('.ant-picker-dropdown').find("button.ant-btn-primary").click(); |
||||||
|
|
||||||
|
|
||||||
|
cy.get('.nc-attachment-cell') |
||||||
|
.attachFile(`sampleFiles/1.json`, { subjectType: 'drag-n-drop' }); |
||||||
|
// cy.get(".nc-field-editables")
|
||||||
|
// .last()
|
||||||
|
// .find('input[type="file"]')
|
||||||
|
// .attachFile(`sampleFiles/1.json`);
|
||||||
|
|
||||||
|
// submit button & validate
|
||||||
|
cy.get(".nc-form").find("button").contains("Submit").click(); |
||||||
|
|
||||||
|
cy.get(".ant-alert-message") |
||||||
|
.contains("Successfully submitted form data") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// // submit button & validate
|
||||||
|
// cy.get(".nc-form")
|
||||||
|
// .find("button")
|
||||||
|
// .contains("Submit")
|
||||||
|
// .click();
|
||||||
|
cy.toastWait("Saved successfully"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`Filter column which contain only attachments, download CSV`, () => { |
||||||
|
// come back to main window
|
||||||
|
loginPage.loginAndOpenProject(apiType, dbType); |
||||||
|
|
||||||
|
// kludge: wait for page load to finish
|
||||||
|
cy.wait(3000); |
||||||
|
// close team & auth tab
|
||||||
|
cy.get('button.ant-tabs-tab-remove').should('exist').click(); |
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
|
||||||
|
mainPage.filterField("testAttach", "is not null", null); |
||||||
|
mainPage.hideField("LastUpdate"); |
||||||
|
|
||||||
|
const verifyCsv = (retrievedRecords) => { |
||||||
|
let storedRecords = [ |
||||||
|
`Country,City List,testAttach`, |
||||||
|
`Afghanistan,Kabul,1.json(http://localhost:8080/download/p_h0wxjx5kgoq3w4/vw_skyvc7hsp9i34a/2HvU8R.json)`, |
||||||
|
]; |
||||||
|
|
||||||
|
expect(retrievedRecords[0]).to.be.equal(storedRecords[0]); |
||||||
|
for (let i = 1; i < storedRecords.length; i++) { |
||||||
|
const columns = retrievedRecords[i].split(","); |
||||||
|
expect(columns[2]).to.contain( |
||||||
|
".json(http://localhost:8080/download/" |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
cy.log(retrievedRecords[109]); |
||||||
|
cy.log(retrievedRecords[110]); |
||||||
|
cy.log(retrievedRecords[111]); |
||||||
|
}; |
||||||
|
|
||||||
|
mainPage.downloadAndVerifyCsv(`Country_exported_1.csv`, verifyCsv); |
||||||
|
mainPage.unhideField("LastUpdate"); |
||||||
|
mainPage.filterReset(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,189 @@ |
|||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { projectsPage } from "../../support/page_objects/navigation"; |
||||||
|
import { loginPage } from "../../support/page_objects/navigation"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
import { |
||||||
|
_advSettings, |
||||||
|
_editSchema, |
||||||
|
_editData, |
||||||
|
_editComment, |
||||||
|
_viewMenu, |
||||||
|
_topRightMenu, |
||||||
|
} from "../spec/roleValidation.spec"; |
||||||
|
|
||||||
|
// fix me
|
||||||
|
let linkText = ""; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
const permissionValidation = (roleType) => { |
||||||
|
it(`${roleType}: Visit base shared URL`, () => { |
||||||
|
cy.log(linkText); |
||||||
|
|
||||||
|
// visit URL & wait for page load to complete
|
||||||
|
cy.visit(linkText, { |
||||||
|
baseUrl: null, |
||||||
|
}); |
||||||
|
cy.wait(5000); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`${roleType}: Validate access permissions: advance menu`, () => { |
||||||
|
_advSettings(roleType, "baseShare"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`${roleType}: Validate access permissions: edit schema`, () => { |
||||||
|
_editSchema(roleType, "baseShare"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`${roleType}: Validate access permissions: edit data`, () => { |
||||||
|
_editData(roleType, "baseShare"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`${roleType}: Validate access permissions: edit comments`, () => { |
||||||
|
_editComment(roleType, "baseShare"); |
||||||
|
}); |
||||||
|
|
||||||
|
it(`${roleType}: Validate access permissions: view's menu`, () => { |
||||||
|
_viewMenu(roleType, "baseShare"); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} Base VIEW share`, () => { |
||||||
|
before(() => { |
||||||
|
// kludge: wait for page load to finish
|
||||||
|
cy.wait(3000); |
||||||
|
// close team & auth tab
|
||||||
|
cy.get('button.ant-tabs-tab-remove').should('exist').click(); |
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
cy.openTableTab("Country", 25); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
cy.fileHook(); |
||||||
|
}) |
||||||
|
|
||||||
|
it(`Generate base share URL`, () => { |
||||||
|
// click SHARE
|
||||||
|
cy.get(".nc-share-base:visible").should('exist').click(); |
||||||
|
|
||||||
|
// Click on readonly base text
|
||||||
|
cy.getActiveModal().find(".nc-disable-shared-base").click(); |
||||||
|
|
||||||
|
cy.getActiveMenu() |
||||||
|
.find(".ant-dropdown-menu-title-content") |
||||||
|
.contains("Anyone with the link") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find(".nc-shared-base-role").click(); |
||||||
|
|
||||||
|
cy.getActiveSelection() |
||||||
|
.find('.ant-select-item') |
||||||
|
.eq(1) |
||||||
|
.click(); |
||||||
|
|
||||||
|
// Copy URL
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".nc-url") |
||||||
|
.then(($obj) => { |
||||||
|
cy.log($obj[0]); |
||||||
|
linkText = $obj[0].innerText.trim(); |
||||||
|
|
||||||
|
const htmlFile = ` |
||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<body> |
||||||
|
|
||||||
|
<iframe |
||||||
|
class="nc-embed" |
||||||
|
src="${linkText}?embed" |
||||||
|
frameborder="0" |
||||||
|
width="100%" |
||||||
|
height="700" |
||||||
|
style="background: transparent; "></iframe> |
||||||
|
|
||||||
|
</body> |
||||||
|
</html> |
||||||
|
`;
|
||||||
|
cy.writeFile( |
||||||
|
"scripts/cypress/fixtures/sampleFiles/iFrame.html", |
||||||
|
htmlFile |
||||||
|
); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
permissionValidation("viewer"); |
||||||
|
|
||||||
|
it("Update to EDITOR base share link", () => { |
||||||
|
loginPage.loginAndOpenProject(apiType, dbType); |
||||||
|
|
||||||
|
// click SHARE
|
||||||
|
cy.get(".nc-share-base:visible").should('exist').click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find(".nc-shared-base-role").click(); |
||||||
|
|
||||||
|
cy.getActiveSelection() |
||||||
|
.find('.ant-select-item') |
||||||
|
.eq(0) |
||||||
|
.click(); |
||||||
|
}); |
||||||
|
|
||||||
|
permissionValidation("editor"); |
||||||
|
|
||||||
|
it("Generate & verify embed HTML IFrame", { baseUrl: null }, () => { |
||||||
|
// open iFrame html
|
||||||
|
cy.visit("scripts/cypress/fixtures/sampleFiles/iFrame.html"); |
||||||
|
|
||||||
|
// wait for iFrame to load
|
||||||
|
cy.frameLoaded(".nc-embed"); |
||||||
|
|
||||||
|
// cy.openTableTab("Country", 25);
|
||||||
|
cy.iframe().find(`.nc-project-tree-tbl-Actor`, { timeout: 10000 }).should("exist") |
||||||
|
.first() |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// validation for base menu opitons
|
||||||
|
cy.iframe().find(".nc-project-tree").should("exist"); |
||||||
|
cy.iframe().find(".nc-fields-menu-btn").should("exist"); |
||||||
|
cy.iframe().find(".nc-sort-menu-btn").should("exist"); |
||||||
|
cy.iframe().find(".nc-filter-menu-btn").should("exist"); |
||||||
|
cy.iframe().find(".nc-actions-menu-btn").should("exist"); |
||||||
|
|
||||||
|
// validate data (row-1)
|
||||||
|
cy.iframe().find(`.nc-grid-cell`).eq(1).contains("PENELOPE").should("exist"); |
||||||
|
cy.iframe().find(`.nc-grid-cell`).eq(2).contains("GUINESS").should("exist"); |
||||||
|
|
||||||
|
// mainPage
|
||||||
|
// .getIFrameCell("FirstName", 1)
|
||||||
|
// .contains("PENELOPE")
|
||||||
|
// .should("exist");
|
||||||
|
// mainPage
|
||||||
|
// .getIFrameCell("LastName", 1)
|
||||||
|
// .contains("GUINESS")
|
||||||
|
// .should("exist");
|
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,347 @@ |
|||||||
|
// Cypress test suite: Project creation using EXCEL
|
||||||
|
//
|
||||||
|
|
||||||
|
import { loginPage, projectsPage } from "../../support/page_objects/navigation"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { |
||||||
|
roles, |
||||||
|
isTestSuiteActive, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
// stores sheet names (table name)
|
||||||
|
let sheetList; |
||||||
|
|
||||||
|
// stores table data (read from excel)
|
||||||
|
let sheetData; |
||||||
|
//let UrlSheetData
|
||||||
|
|
||||||
|
let URL = "https://go.microsoft.com/fwlink/?LinkID=521962"; |
||||||
|
|
||||||
|
let filepath = `sampleFiles/simple.xlsx`; |
||||||
|
// let UrlFilePath = `sampleFiles/Financial Sample.xlsx`
|
||||||
|
|
||||||
|
let expectedData = { |
||||||
|
0: ["number", "Number", "Number"], |
||||||
|
1: ["float", "Decimal", "Float"], |
||||||
|
2: ["text", "SingleLineText", "Text"], |
||||||
|
}; |
||||||
|
|
||||||
|
// column names with spaces will be converted to include _
|
||||||
|
let UrlFileExpectedData = { |
||||||
|
0: ["Segment", "SingleSelect", ["Government"]], |
||||||
|
1: ["Country", "SingleSelect", ["Canada"]], |
||||||
|
2: ["Product", "SingleSelect", ["Carretera"]], |
||||||
|
3: ["Discount_Band", "SingleSelect", ["None"]], |
||||||
|
4: ["Units_Sold", "Decimal", [1618.5]], |
||||||
|
5: ["Manufacturing_Price", "Number", [3]], |
||||||
|
6: ["Sale_Price", "Number", [20]], |
||||||
|
7: ["Gross_Sales", "Decimal", [32370]], |
||||||
|
8: ["Discounts", "Decimal", [0]], |
||||||
|
9: ["Sales", "Decimal", [32370]], |
||||||
|
10: ["COGS", "Decimal", [16185]], |
||||||
|
11: ["Profit", "Decimal", [16185]], |
||||||
|
12: ["Date", "Date", ["2014-01-01"]], |
||||||
|
13: ["Month_Number", "Number", [1]], |
||||||
|
14: ["Month_Name", "SingleSelect", ["January"]], |
||||||
|
15: ["Year", "SingleSelect", [2014]], |
||||||
|
}; |
||||||
|
|
||||||
|
// let filepath = `sampleFiles/sample.xlsx`
|
||||||
|
// let expectedData = {
|
||||||
|
// 0: ['number', 'Number'],
|
||||||
|
// 1: ['float', 'Decimal'],
|
||||||
|
// 2: ['text', 'SingleLineText'],
|
||||||
|
// 3: ['boolean', 'Checkbox'],
|
||||||
|
// 4: ['currency', 'Currency'],
|
||||||
|
// 5: ['date', 'Date'],
|
||||||
|
// 6: ['field7', 'SingleLineText'],
|
||||||
|
// 7: ['multi line', 'LongText'],
|
||||||
|
// 8: ['multi select', 'MultiSelect'],
|
||||||
|
// 9: ['field10', 'SingleLineText'],
|
||||||
|
// 10: ['formula', 'Decimal'],
|
||||||
|
// 11: ['percentage', 'Decimal'],
|
||||||
|
// 12: ['dateTime', 'DateTime']
|
||||||
|
// }
|
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`Import from excel`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
cy.task("readSheetList", { |
||||||
|
file: `./scripts/cypress/fixtures/${filepath}`, |
||||||
|
}).then((rows) => { |
||||||
|
cy.log(rows); |
||||||
|
sheetList = rows; |
||||||
|
}); |
||||||
|
|
||||||
|
cy.task("readXlsx", { |
||||||
|
file: `./scripts/cypress/fixtures/${filepath}`, |
||||||
|
sheet: "Sheet2", |
||||||
|
}).then((rows) => { |
||||||
|
cy.log(rows); |
||||||
|
sheetData = rows; |
||||||
|
}); |
||||||
|
|
||||||
|
loginPage.signIn(roles.owner.credentials); |
||||||
|
projectsPage.createProject({ dbType: "none", apiType: "REST", name: "importSample" }, {}) |
||||||
|
}); |
||||||
|
|
||||||
|
it("File Upload: Upload excel as template", () => { |
||||||
|
|
||||||
|
cy.get('.nc-add-new-table').should('exist').trigger('mouseover') |
||||||
|
cy.get('.nc-import-menu').should('exist').click() |
||||||
|
cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Microsoft Excel').click() |
||||||
|
|
||||||
|
// trigger import
|
||||||
|
// cy.get(`[data-menu-id="addORImport"]`).click();
|
||||||
|
// cy.getActivePopUp().contains("Microsoft Excel").should('exist').click();
|
||||||
|
|
||||||
|
cy.get(".nc-input-import").should('exist').find('input').attachFile(filepath); |
||||||
|
cy.toastWait("Uploaded file simple.xlsx successfully"); |
||||||
|
cy.get(".nc-btn-import").should('exist').click(); |
||||||
|
|
||||||
|
// cy.toastWait("Uploaded file simple.xlsx successfully")
|
||||||
|
}); |
||||||
|
|
||||||
|
it("File Upload: Verify pre-load template page", () => { |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-collapse-item") |
||||||
|
.then((sheets) => { |
||||||
|
|
||||||
|
// hardcoded. fix me.
|
||||||
|
let sheetList = ["Sheet1", "Sheet3", "Sheet4"]; |
||||||
|
|
||||||
|
for (let i = 0; i < sheets.length; i++) { |
||||||
|
cy.wrap(sheets[i]) |
||||||
|
.find('.ant-collapse-header') |
||||||
|
.contains(sheetList[i]) |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// for each sheet, expand to verify table names & their data types
|
||||||
|
if(i!==0) |
||||||
|
cy.wrap(sheets[i]).find(".ant-collapse-arrow").click(); |
||||||
|
|
||||||
|
// sheet > tables > rows > cells > inputs
|
||||||
|
cy.wrap(sheets[i]).find(".ant-table-tbody").then((tables) => { |
||||||
|
cy.wrap(tables).find(".ant-table-row:visible") |
||||||
|
.should("have.length", 3) |
||||||
|
.then((rows) => { |
||||||
|
// cy.log(rows)
|
||||||
|
for (let j = 0; j < rows.length; j++) { |
||||||
|
cy.wrap(rows[j]).find(".ant-table-cell") |
||||||
|
.then((cells) => { |
||||||
|
cy.wrap(cells[0]).find("input") |
||||||
|
.then((input) => { |
||||||
|
expect(input.val()).to.equal(expectedData[j][0]) |
||||||
|
}) |
||||||
|
cy.wrap(cells[1]).find(".ant-select-selection-item") |
||||||
|
.contains(expectedData[j][1]) |
||||||
|
.should("exist") |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
// unwind
|
||||||
|
cy.wrap(sheets[i]).find(".ant-collapse-arrow").click(); |
||||||
|
} |
||||||
|
}); |
||||||
|
cy.getActiveModal().find(".ant-btn-primary").click(); |
||||||
|
}); |
||||||
|
|
||||||
|
it("File Upload: Verify loaded data", () => { |
||||||
|
|
||||||
|
cy.openTableTab("Sheet1", 2); |
||||||
|
for (const [key, value] of Object.entries(expectedData)) { |
||||||
|
mainPage |
||||||
|
.getCell(value[2], 1) |
||||||
|
.contains(sheetData[0][value[0]]) |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(value[2], 2) |
||||||
|
.contains(sheetData[1][value[0]]) |
||||||
|
.should("exist"); |
||||||
|
} |
||||||
|
cy.closeTableTab("Sheet1"); |
||||||
|
|
||||||
|
cy.openTableTab("Sheet3", 2); |
||||||
|
for (const [key, value] of Object.entries(expectedData)) { |
||||||
|
mainPage |
||||||
|
.getCell(value[2], 1) |
||||||
|
.contains(sheetData[0][value[0]]) |
||||||
|
.should("exist"); |
||||||
|
mainPage |
||||||
|
.getCell(value[2], 2) |
||||||
|
.contains(sheetData[1][value[0]]) |
||||||
|
.should("exist"); |
||||||
|
} |
||||||
|
cy.closeTableTab("Sheet3"); |
||||||
|
|
||||||
|
// // delete project once all operations are completed
|
||||||
|
// cy.get('.nc-noco-brand-icon').click();
|
||||||
|
//
|
||||||
|
// cy.get(`.nc-action-btn`)
|
||||||
|
// .should("exist")
|
||||||
|
// .last()
|
||||||
|
// .click();
|
||||||
|
//
|
||||||
|
// cy.getActiveModal()
|
||||||
|
// .find(".ant-btn-dangerous")
|
||||||
|
// .should("exist")
|
||||||
|
// .click();
|
||||||
|
}); |
||||||
|
|
||||||
|
it.skip("URL: Upload excel as template", () => { |
||||||
|
// trigger import
|
||||||
|
cy.get(`[data-menu-id="addORImport"]`).click(); |
||||||
|
cy.getActivePopUp().contains("Microsoft Excel").should('exist').click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find('.ant-tabs-tab').last().click() |
||||||
|
|
||||||
|
cy.get("input[type=\"text\"]") |
||||||
|
.last() |
||||||
|
.click() |
||||||
|
.type(URL); |
||||||
|
cy.get(".nc-btn-primary").should('exist').click(); |
||||||
|
}); |
||||||
|
|
||||||
|
it.skip("URL: Verify pre-load template page", () => { |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-collapse-item") |
||||||
|
.then((sheets) => { |
||||||
|
|
||||||
|
let sheetList = ["Sheet1"]; |
||||||
|
|
||||||
|
for (let i = 0; i < sheets.length; i++) { |
||||||
|
cy.wrap(sheets[i]) |
||||||
|
.find('.ant-collapse-header') |
||||||
|
.contains(sheetList[i]) |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
cy.wrap(sheets[i]).find(".ant-table-tbody").then((tables) => { |
||||||
|
cy.wrap(tables).find(".ant-table-row:visible") |
||||||
|
.then((rows) => { |
||||||
|
// cy.log(rows)
|
||||||
|
for (let j = 0; j < 10; j++) { |
||||||
|
cy.wrap(rows[j]).find(".ant-table-cell").then((cells) => { |
||||||
|
// cy.log(cells)
|
||||||
|
for (let k = 0; k < 2; k++) { |
||||||
|
cy.wrap(cells[k]).find("input").then((input) => { |
||||||
|
// cy.log(input)
|
||||||
|
expect(input.val()).to.equal(UrlFileExpectedData[j][k]) |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
// unwind
|
||||||
|
cy.wrap(sheets[i]).find(".ant-collapse-arrow").click(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
cy.getActiveModal().find(".ant-btn-primary").click(); |
||||||
|
}) |
||||||
|
|
||||||
|
it.skip("URL: Verify loaded data", () => { |
||||||
|
|
||||||
|
// wait for loading to be completed
|
||||||
|
projectsPage.waitHomePageLoad(); |
||||||
|
|
||||||
|
// open sheet & validate contents
|
||||||
|
// sheetData contains data read from excel in format
|
||||||
|
// 0: { float: 1.1, number: 1, text: "abc" }
|
||||||
|
// 1: { float: 1.2, number: 0, text: "def" }
|
||||||
|
|
||||||
|
cy.openTableTab("Sheet1", 25); |
||||||
|
let idx = 0; |
||||||
|
for (const [key, value] of Object.entries(UrlFileExpectedData)) { |
||||||
|
if (UrlFileExpectedData[idx][1] != "Date") |
||||||
|
mainPage |
||||||
|
.getCell(value[0], 1) |
||||||
|
.contains(UrlFileExpectedData[idx++][2][0]) |
||||||
|
.should("exist"); |
||||||
|
} |
||||||
|
cy.closeTableTab("Sheet1"); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
// delete project once all operations are completed
|
||||||
|
// mainPage.toolBarTopLeft(mainPage.HOME).click();
|
||||||
|
// projectsPage.deleteProject("importSample");
|
||||||
|
|
||||||
|
cy.get('.nc-noco-brand-icon').click(); |
||||||
|
|
||||||
|
cy.get(`.nc-action-btn`) |
||||||
|
.should("exist") |
||||||
|
.last() |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-btn-dangerous") |
||||||
|
.should("exist") |
||||||
|
.click(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// if (typeof require !== 'undefined') XLSX = require('xlsx');
|
||||||
|
|
||||||
|
// let workbook
|
||||||
|
|
||||||
|
// const getSheetList = (wb) => {
|
||||||
|
// return wb.SheetNames
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const getRow = (sheet, rowIdx) => {
|
||||||
|
// let sheetData = XLSX.utils.sheet_to_json(workbook.Sheets[sheet], {
|
||||||
|
// header: 1,
|
||||||
|
// blankrows: false
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return sheetData[rowIdx]
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // https://stackoverflow.com/questions/40630606/how-to-read-only-column-a-value-from-excel-using-nodejs
|
||||||
|
// const getColumn = (sheet, colIdx) => {
|
||||||
|
// let columnA = []
|
||||||
|
// const worksheet = workbook.Sheets[sheet];
|
||||||
|
// for (let z in worksheet) {
|
||||||
|
// if (z.toString()[0] === colIdx) {
|
||||||
|
// columnA.push(worksheet[z].v);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return columnA
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const getCell = (sheet, cellIdx) => {
|
||||||
|
// const worksheet = workbook.Sheets[sheet];
|
||||||
|
// var desired_cell = worksheet[cellIdx];
|
||||||
|
// desired_value = (desired_cell ? desired_cell.v : undefined);
|
||||||
|
// return desired_value
|
||||||
|
// }
|
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,68 @@ |
|||||||
|
// Cypress test suite: Project import from Airtable
|
||||||
|
//
|
||||||
|
|
||||||
|
import { isTestSuiteActive, roles } from "../../support/page_objects/projectConstants"; |
||||||
|
import { loginPage, projectsPage } from "../../support/page_objects/navigation"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
|
||||||
|
let apiKey = "" |
||||||
|
let sharedBase = "" |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
|
||||||
|
describe(`Import from airtable`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
apiKey = Cypress.env("airtable").apiKey; |
||||||
|
sharedBase = Cypress.env("airtable").sharedBase; |
||||||
|
|
||||||
|
loginPage.signIn(roles.owner.credentials); |
||||||
|
projectsPage.createProject({ dbType: "none", apiType: "REST", name: "importSample" }, {}) |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => {}); |
||||||
|
|
||||||
|
it("Import", () => { |
||||||
|
cy.log(apiKey, sharedBase); |
||||||
|
|
||||||
|
// trigger import
|
||||||
|
cy.get(`[data-menu-id="addORImport"]`).click(); |
||||||
|
cy.getActivePopUp().contains("Airtable").should('exist').click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find(".nc-input-api-key").should('exist').clear().type(apiKey) |
||||||
|
cy.getActiveModal().find(".nc-input-shared-base").should('exist').clear().type(sharedBase) |
||||||
|
cy.getActiveModal().find(".nc-btn-airtable-import").should('exist').click() |
||||||
|
|
||||||
|
// it will take a while for import to finish
|
||||||
|
// cy.getActiveModal().find(".nc-btn-go-dashboard", {timeout: 180000}).should('exist').click()
|
||||||
|
|
||||||
|
// wait for import to finish (kludge/hardcoded)
|
||||||
|
cy.get(':nth-child(51) > .flex', {timeout: 180000}).contains('Complete!').should('exist') |
||||||
|
cy.get('.ant-modal-close-x').should('exist').click() |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,434 @@ |
|||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { loginPage } from "../../support/page_objects/navigation"; |
||||||
|
|
||||||
|
// locally configured hook (server.js)
|
||||||
|
let hookPath = "http://localhost:9090/hook"; |
||||||
|
|
||||||
|
function createWebhook(hook, test) { |
||||||
|
cy.get('.nc-actions-menu-btn').should('exist').click(); |
||||||
|
cy.getActiveMenu().find('.ant-dropdown-menu-title-content').contains('Webhooks').click() |
||||||
|
|
||||||
|
// cy.get(".nc-btn-webhook").should("exist").click();
|
||||||
|
cy.get(".nc-btn-create-webhook").should("exist").click(); |
||||||
|
|
||||||
|
// hardcode "Content-type: application/json"
|
||||||
|
cy.get(".ant-tabs-tab-btn").contains("Headers").should("exist").click(); |
||||||
|
|
||||||
|
// kludge : as neither scrollIntoView nor scrollTo didn't yield any results
|
||||||
|
// cy.getActiveSelection().find('.ant-select-item').contains('Content-Type).scrollIntoView();
|
||||||
|
// cy.getActiveSelection().find('.rc-virtual-list').scrollTo('center');
|
||||||
|
// cy.getActiveSelection().select('Content-Type', { force: true });
|
||||||
|
|
||||||
|
cy.get(".nc-input-hook-header-key") |
||||||
|
.should("exist") |
||||||
|
.click() |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
.type('{downarrow}') |
||||||
|
|
||||||
|
cy.getActiveSelection().find('.ant-select-item-option-content').contains('Content-Type').should('exist').click(); |
||||||
|
|
||||||
|
cy.get("input.nc-input-hook-header-value") |
||||||
|
.should("exist") |
||||||
|
.clear({ force: true }) |
||||||
|
.type("application/json", { force: true }); |
||||||
|
|
||||||
|
cy.get('.nc-hook-header-tab-checkbox').find('input.ant-checkbox-input').should('exist').click(); |
||||||
|
|
||||||
|
// common routine for both create & modify to configure hook
|
||||||
|
configureWebhook(hook, test); |
||||||
|
} |
||||||
|
|
||||||
|
function deleteWebhook(index) { |
||||||
|
cy.get('.nc-actions-menu-btn').should('exist').click(); |
||||||
|
cy.getActiveMenu().find('.ant-dropdown-menu-title-content').contains('Webhooks').click() |
||||||
|
|
||||||
|
cy.get(".nc-hook-delete-icon").eq(index).click({ force: true }); |
||||||
|
cy.toastWait("Hook deleted successfully"); |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
} |
||||||
|
|
||||||
|
function openWebhook(index) { |
||||||
|
cy.get('.nc-actions-menu-btn').should('exist').click(); |
||||||
|
cy.getActiveMenu().find('.ant-dropdown-menu-title-content').contains('Webhooks').click() |
||||||
|
|
||||||
|
cy.get(".nc-hook").eq(index).click({ force: true }); |
||||||
|
} |
||||||
|
|
||||||
|
function configureWebhook(hook, test) { |
||||||
|
// configure what ever is present. ignore rest
|
||||||
|
// currently works for only URL type
|
||||||
|
|
||||||
|
if (hook?.title) { |
||||||
|
cy.get(".nc-text-field-hook-title") |
||||||
|
.should("exist") |
||||||
|
.clear() |
||||||
|
.type(hook.title); |
||||||
|
} |
||||||
|
|
||||||
|
if (hook?.event) { |
||||||
|
cy.get(".nc-text-field-hook-event").should("exist").click(); |
||||||
|
cy.getActiveSelection() |
||||||
|
.find(`.ant-select-item`) |
||||||
|
.contains(hook.event) |
||||||
|
.should("exist") |
||||||
|
.click(); |
||||||
|
} |
||||||
|
|
||||||
|
if (hook?.url?.path) { |
||||||
|
cy.get(".nc-text-field-hook-url-path") |
||||||
|
.should("exist") |
||||||
|
.clear() |
||||||
|
.type(hook.url.path); |
||||||
|
} |
||||||
|
|
||||||
|
if (hook?.deleteCondition === true) { |
||||||
|
cy.get(".nc-filter-item-remove-btn") |
||||||
|
.should("exist") |
||||||
|
.click({ force: true }); |
||||||
|
} |
||||||
|
|
||||||
|
if (hook?.condition) { |
||||||
|
cy.get(".nc-check-box-hook-condition").should("exist").click(); |
||||||
|
cy.get(".menu-filter-dropdown") |
||||||
|
.last() |
||||||
|
.find("button") |
||||||
|
.contains("Add Filter") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.get(".nc-filter-field-select") |
||||||
|
.should("exist") |
||||||
|
.last() |
||||||
|
.click() |
||||||
|
cy.get('.ant-select-dropdown:visible') |
||||||
|
.should('exist') |
||||||
|
.find(`.ant-select-item`) |
||||||
|
.contains(new RegExp("^" + hook.condition.column + "$", "g")) |
||||||
|
.should('exist') |
||||||
|
.click(); |
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
cy.get(".nc-filter-operation-select").should("exist").last().click(); |
||||||
|
cy.get('.ant-select-dropdown:visible') |
||||||
|
.should('exist') |
||||||
|
.find(`.ant-select-item`) |
||||||
|
.contains(hook.condition.operator) |
||||||
|
.should('exist') |
||||||
|
.click(); |
||||||
|
if (hook.condition.operator != "is null" && hook.condition.operator != "is not null") { |
||||||
|
cy.get(".nc-filter-value-select") |
||||||
|
.should("exist") |
||||||
|
.last() |
||||||
|
.type(hook.condition.value); |
||||||
|
cy.get(".nc-filter-operation-select").last().click(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (test) { |
||||||
|
cy.get(".nc-btn-webhook-test").should("exist").click(); |
||||||
|
cy.toastWait("Webhook tested successfully"); |
||||||
|
} |
||||||
|
|
||||||
|
cy.get(".nc-btn-webhook-save").should("exist").click(); |
||||||
|
cy.toastWait("Webhook details updated successfully"); |
||||||
|
cy.get(".nc-icon-hook-navigate-left").should("exist").click(); |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
} |
||||||
|
|
||||||
|
function clearServerData() { |
||||||
|
// clear stored data in server
|
||||||
|
cy.request("http://localhost:9090/hook/clear"); |
||||||
|
|
||||||
|
// ensure stored message count is 0
|
||||||
|
cy.request("http://localhost:9090/hook/count").then((msg) => { |
||||||
|
cy.log(msg.body); |
||||||
|
expect(msg.body).to.equal(0); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function addNewRow(index, cellValue) { |
||||||
|
cy.get(".nc-add-new-row-btn:visible").should("exist"); |
||||||
|
cy.get(".nc-add-new-row-btn").click(); |
||||||
|
cy.wait(1000); |
||||||
|
cy.get(".nc-expand-col-Title").find(".nc-cell > input").first().type(cellValue); |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-btn-primary") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.toastWait("updated successfully"); |
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-btn") |
||||||
|
.contains("Cancel") |
||||||
|
.click(); |
||||||
|
mainPage.getCell("Title", index).contains(cellValue).should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
function updateRow(index, cellValue) { |
||||||
|
cy.get(".nc-row-expand") |
||||||
|
.eq(index-1) |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
cy.get(".nc-expand-col-Title").find(".nc-cell > input") |
||||||
|
.should("exist") |
||||||
|
.first() |
||||||
|
.clear() |
||||||
|
.type(cellValue); |
||||||
|
|
||||||
|
cy.getActiveModal() |
||||||
|
.find("button") |
||||||
|
.contains("Save row") |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// partial toast message
|
||||||
|
cy.toastWait("updated successfully"); |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
} |
||||||
|
|
||||||
|
function verifyHookTrigger(count, lastValue) { |
||||||
|
cy.request("http://localhost:9090/hook/count").then((msg) => { |
||||||
|
cy.log(msg.body); |
||||||
|
expect(msg.body).to.equal(count); |
||||||
|
}); |
||||||
|
if (count) { |
||||||
|
cy.request("http://localhost:9090/hook/last").then((msg) => { |
||||||
|
cy.log(msg.body); |
||||||
|
expect(msg.body.Title).to.equal(lastValue); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function deleteRow(index) { |
||||||
|
mainPage |
||||||
|
.getCell("Title", 1) |
||||||
|
.rightclick(); |
||||||
|
|
||||||
|
// delete row
|
||||||
|
cy.getActiveMenu() |
||||||
|
.find('.ant-dropdown-menu-item:contains("Delete Row")') |
||||||
|
.first() |
||||||
|
.click({ force: true }); |
||||||
|
} |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
describe(`Webhook`, () => { |
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
loginPage.loginAndOpenProject(apiType, dbType); |
||||||
|
cy.createTable("Temp"); |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => { |
||||||
|
cy.deleteTable("Temp"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Create: 'After Insert' event", () => { |
||||||
|
createWebhook({ |
||||||
|
title: "hook-1", |
||||||
|
event: "After Insert", |
||||||
|
type: "URL", |
||||||
|
url: { |
||||||
|
method: "POST", |
||||||
|
path: hookPath, |
||||||
|
}, |
||||||
|
}); |
||||||
|
clearServerData(); |
||||||
|
addNewRow(1, "Poole"); |
||||||
|
verifyHookTrigger(1, "Poole"); |
||||||
|
updateRow(1, "Delaware"); |
||||||
|
verifyHookTrigger(1, "Poole"); |
||||||
|
deleteRow(1); |
||||||
|
verifyHookTrigger(1, "Poole"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Add 'After Update' event", () => { |
||||||
|
createWebhook({ |
||||||
|
title: "hook-2", |
||||||
|
event: "After Update", |
||||||
|
type: "URL", |
||||||
|
url: { |
||||||
|
method: "POST", |
||||||
|
path: hookPath, |
||||||
|
}, |
||||||
|
}); |
||||||
|
clearServerData(); |
||||||
|
addNewRow(1, "Poole"); |
||||||
|
verifyHookTrigger(1, "Poole"); |
||||||
|
updateRow(1, "Delaware"); |
||||||
|
verifyHookTrigger(2, "Delaware"); |
||||||
|
deleteRow(1); |
||||||
|
verifyHookTrigger(2, "Delaware"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Add 'After Delete' event", () => { |
||||||
|
createWebhook({ |
||||||
|
title: "hook-3", |
||||||
|
event: "After Delete", |
||||||
|
type: "URL", |
||||||
|
url: { |
||||||
|
method: "POST", |
||||||
|
path: hookPath, |
||||||
|
}, |
||||||
|
}); |
||||||
|
clearServerData(); |
||||||
|
addNewRow(1, "Poole"); |
||||||
|
verifyHookTrigger(1, "Poole"); |
||||||
|
updateRow(1, "Delaware"); |
||||||
|
verifyHookTrigger(2, "Delaware"); |
||||||
|
deleteRow(1); |
||||||
|
verifyHookTrigger(3, "Delaware"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Modify webhook", () => { |
||||||
|
openWebhook(0); |
||||||
|
configureWebhook({ event: "After Delete" }); |
||||||
|
openWebhook(1); |
||||||
|
configureWebhook({ event: "After Delete" }); |
||||||
|
|
||||||
|
clearServerData(); |
||||||
|
addNewRow(1, "Poole"); |
||||||
|
verifyHookTrigger(0, ""); |
||||||
|
updateRow(1, "Delaware"); |
||||||
|
verifyHookTrigger(0, ""); |
||||||
|
deleteRow(1); |
||||||
|
verifyHookTrigger(3, "Delaware"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Delete webhook", () => { |
||||||
|
deleteWebhook(2); |
||||||
|
deleteWebhook(1); |
||||||
|
deleteWebhook(0); |
||||||
|
|
||||||
|
clearServerData(); |
||||||
|
addNewRow(1, "Poole"); |
||||||
|
verifyHookTrigger(0, ""); |
||||||
|
updateRow(1, "Delaware"); |
||||||
|
verifyHookTrigger(0, ""); |
||||||
|
deleteRow(1); |
||||||
|
verifyHookTrigger(0, ""); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Create, with condition", () => { |
||||||
|
// create 3 webhooks with all three events, with condition this time
|
||||||
|
createWebhook({ |
||||||
|
title: "hook-with-condition-1", |
||||||
|
event: "After Insert", |
||||||
|
type: "URL", |
||||||
|
url: { |
||||||
|
method: "POST", |
||||||
|
path: hookPath, |
||||||
|
}, |
||||||
|
condition: { |
||||||
|
column: "Title", |
||||||
|
operator: "is like", |
||||||
|
value: "Poole", |
||||||
|
}, |
||||||
|
}); |
||||||
|
createWebhook({ |
||||||
|
title: "hook-with-condition-2", |
||||||
|
event: "After Update", |
||||||
|
type: "URL", |
||||||
|
url: { |
||||||
|
method: "POST", |
||||||
|
path: hookPath, |
||||||
|
}, |
||||||
|
condition: { |
||||||
|
column: "Title", |
||||||
|
operator: "is like", |
||||||
|
value: "Poole", |
||||||
|
}, |
||||||
|
}); |
||||||
|
createWebhook({ |
||||||
|
title: "hook-with-condition-3", |
||||||
|
event: "After Delete", |
||||||
|
type: "URL", |
||||||
|
url: { |
||||||
|
method: "POST", |
||||||
|
path: hookPath, |
||||||
|
}, |
||||||
|
condition: { |
||||||
|
column: "Title", |
||||||
|
operator: "is like", |
||||||
|
value: "Poole", |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
clearServerData(); |
||||||
|
addNewRow(1, "Poole"); |
||||||
|
addNewRow(2, "Delaware"); |
||||||
|
verifyHookTrigger(1, "Poole"); |
||||||
|
updateRow(1, "Delaware"); |
||||||
|
updateRow(2, "Poole"); |
||||||
|
verifyHookTrigger(2, "Poole"); |
||||||
|
deleteRow(2); |
||||||
|
deleteRow(1); |
||||||
|
verifyHookTrigger(3, "Poole"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Modify trigger condition", () => { |
||||||
|
openWebhook(0); |
||||||
|
configureWebhook({ deleteCondition: true }); |
||||||
|
openWebhook(1); |
||||||
|
configureWebhook({ deleteCondition: true }); |
||||||
|
openWebhook(2); |
||||||
|
configureWebhook({ deleteCondition: true }); |
||||||
|
|
||||||
|
clearServerData(); |
||||||
|
addNewRow(1, "Poole"); |
||||||
|
addNewRow(2, "Delaware"); |
||||||
|
verifyHookTrigger(2, "Delaware"); |
||||||
|
updateRow(1, "Delaware"); |
||||||
|
updateRow(2, "Poole"); |
||||||
|
verifyHookTrigger(4, "Poole"); |
||||||
|
deleteRow(2); |
||||||
|
deleteRow(1); |
||||||
|
verifyHookTrigger(6, "Delaware"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Delete trigger condition", () => { |
||||||
|
deleteWebhook(2); |
||||||
|
deleteWebhook(1); |
||||||
|
deleteWebhook(0); |
||||||
|
|
||||||
|
clearServerData(); |
||||||
|
addNewRow(1, "Poole"); |
||||||
|
verifyHookTrigger(0, ""); |
||||||
|
updateRow(1, "Delaware"); |
||||||
|
verifyHookTrigger(0, ""); |
||||||
|
deleteRow(1); |
||||||
|
verifyHookTrigger(0, ""); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,420 @@ |
|||||||
|
import { |
||||||
|
isTestSuiteActive, |
||||||
|
roles, |
||||||
|
} from "../../support/page_objects/projectConstants"; |
||||||
|
import { loginPage, projectsPage } from "../../support/page_objects/navigation"; |
||||||
|
import { mainPage } from "../../support/page_objects/mainPage"; |
||||||
|
|
||||||
|
// normal fields
|
||||||
|
let records = { |
||||||
|
Name: "Movie-1", |
||||||
|
Notes: "Good", |
||||||
|
Status: "Todo", |
||||||
|
Tags: "Jan", |
||||||
|
Phone: "123123123", |
||||||
|
Email: "a@b.com", |
||||||
|
URL: "www.a.com", |
||||||
|
Number: "1", |
||||||
|
Value: "$1.00", |
||||||
|
Percent: "0.01", |
||||||
|
}; |
||||||
|
|
||||||
|
// links/ computed fields
|
||||||
|
let records2 = { |
||||||
|
Duration: "00:01", |
||||||
|
Done: true, |
||||||
|
Date: "2022-05-31", |
||||||
|
Rating: "1", |
||||||
|
Actor: ["Actor1", "Actor2"], |
||||||
|
"Status (from Actor)": ["Todo", "In progress"], |
||||||
|
RollUp: "128", |
||||||
|
Computation: "4.04", |
||||||
|
Producer: ["P1", "P2"] |
||||||
|
}; |
||||||
|
|
||||||
|
let tn = [ "Film", "Actor", "Producer", ] |
||||||
|
|
||||||
|
let cn = [ "Name", "Notes", "Status", "Tags", "Done", "Date", "Phone", |
||||||
|
"Email", "URL", "Number", "Percent", "Duration", "Rating", |
||||||
|
"Actor", "Status (from Actor)", "RollUp", "Computation", "Producer" ] |
||||||
|
|
||||||
|
function openWebhook(index) { |
||||||
|
cy.get(".nc-btn-webhook").should("exist").click(); |
||||||
|
cy.get(".nc-hook").eq(index).click({ force: true }); |
||||||
|
} |
||||||
|
|
||||||
|
// to be invoked after open
|
||||||
|
function verifyWebhook(config) { |
||||||
|
cy.get(".nc-text-field-hook-title") |
||||||
|
.find('input').then(($element) => { |
||||||
|
expect($element[0].value).to.have.string(config.title) |
||||||
|
}) |
||||||
|
cy.get(".nc-text-field-hook-event") |
||||||
|
.find('.v-select__selection') |
||||||
|
.contains(config.event) |
||||||
|
.should('exist') |
||||||
|
cy.get(".nc-text-field-hook-notification-type") |
||||||
|
.find('.v-select__selection') |
||||||
|
.contains(config.notification) |
||||||
|
.should('exist') |
||||||
|
cy.get('.nc-select-hook-url-method') |
||||||
|
.find('.v-select__selection') |
||||||
|
.contains(config.type) |
||||||
|
.should('exist') |
||||||
|
cy.get(".nc-text-field-hook-url-path") |
||||||
|
.find('input').then(($element) => { |
||||||
|
expect($element[0].value).to.have.string(config.url) |
||||||
|
}) |
||||||
|
cy.get(".nc-icon-hook-navigate-left").click({force:true}) |
||||||
|
} |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType, testMode) => { |
||||||
|
if (!isTestSuiteActive(apiType, dbType)) return; |
||||||
|
describe(`Quick Tests`, () => { |
||||||
|
|
||||||
|
let cellIdx = 1; |
||||||
|
let columnCount = cn.length |
||||||
|
if(testMode === 'AT_IMPORT') { |
||||||
|
cellIdx = 3; |
||||||
|
columnCount -= 3; |
||||||
|
} |
||||||
|
|
||||||
|
before(() => { |
||||||
|
cy.fileHook(); |
||||||
|
if( testMode === 'CY_QUICK') { |
||||||
|
// cy.task("copyFile")
|
||||||
|
loginPage.signIn(roles.owner.credentials); |
||||||
|
projectsPage.openProject("sample"); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
after(() => {}); |
||||||
|
|
||||||
|
it("Verify Schema", () => { |
||||||
|
cy.openTableTab("Film", 3) |
||||||
|
|
||||||
|
// verify if all tables exist
|
||||||
|
for(let i=0; i<tn.length; i++) |
||||||
|
cy.get(".nc-project-tree").contains(tn[i]).should('exist') |
||||||
|
|
||||||
|
// for Film table, verify columns
|
||||||
|
for(let i=0; i<columnCount; i++) |
||||||
|
cy.get(".nc-grid-header-row").find(`[data-col="${cn[i]}"]`).should('exist') |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it("Verify Data types", () => { |
||||||
|
cy.openTableTab("Film", 3); |
||||||
|
|
||||||
|
// normal cells
|
||||||
|
for (let [key, value] of Object.entries(records)) { |
||||||
|
mainPage.getCell(key, cellIdx).contains(value).should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
// checkbox
|
||||||
|
mainPage |
||||||
|
.getCell("Done", cellIdx) |
||||||
|
.find(".mdi-check-circle-outline") |
||||||
|
.should(records2.Done ? "exist" : "not.exist"); |
||||||
|
|
||||||
|
// date
|
||||||
|
|
||||||
|
// duration
|
||||||
|
mainPage.getCell("Duration", cellIdx).find('input').then(($e) => { |
||||||
|
expect($e[0].value).to.equal(records2.Duration) |
||||||
|
}) |
||||||
|
|
||||||
|
// rating
|
||||||
|
mainPage |
||||||
|
.getCell("Rating", cellIdx) |
||||||
|
.find("button.mdi-star") |
||||||
|
.should("have.length", records2.Rating); |
||||||
|
|
||||||
|
// verifying only one instance as its different for PG & SQLite
|
||||||
|
// for PG: its Actor1, Actor1
|
||||||
|
// for SQLite: its Actor1, Actor2
|
||||||
|
// LinkToAnotherRecord
|
||||||
|
mainPage.getCell("Actor", cellIdx).scrollIntoView(); |
||||||
|
cy.get( |
||||||
|
`:nth-child(${cellIdx}) > [data-col="Actor"] > .nc-virtual-cell > .v-lazy > .d-100 > .chips > :nth-child(1) > .v-chip__content > .name` |
||||||
|
) |
||||||
|
.contains(records2.Actor[0]) |
||||||
|
.should("exist"); |
||||||
|
// cy.get(
|
||||||
|
// `:nth-child(${cellIdx}) > [data-col="Actor"] > .nc-virtual-cell > .v-lazy > .d-100 > .chips > :nth-child(2) > .v-chip__content > .name`
|
||||||
|
// )
|
||||||
|
// .contains(records2.Actor[1])
|
||||||
|
// .should("exist");
|
||||||
|
|
||||||
|
// lookup
|
||||||
|
mainPage.getCell("Status (from Actor)", cellIdx).scrollIntoView(); |
||||||
|
cy.get( |
||||||
|
`:nth-child(${cellIdx}) > [data-col="Status (from Actor)"] > .nc-virtual-cell > .v-lazy > .d-flex > :nth-child(1) > .v-chip__content > div > .set-item` |
||||||
|
) |
||||||
|
.contains(records2["Status (from Actor)"][0]) |
||||||
|
.should("exist"); |
||||||
|
// cy.get(
|
||||||
|
// `:nth-child(${cellIdx}) > [data-col="Status (from Actor)"] > .nc-virtual-cell > .v-lazy > .d-flex > :nth-child(2) > .v-chip__content > div > .set-item`
|
||||||
|
// )
|
||||||
|
// .contains(records2["Status (from Actor)"][1])
|
||||||
|
// .should("exist");
|
||||||
|
|
||||||
|
// rollup
|
||||||
|
if( testMode === 'CY_QUICK') { |
||||||
|
|
||||||
|
mainPage.getCell("RollUp", cellIdx).scrollIntoView(); |
||||||
|
cy.get(`:nth-child(${cellIdx}) > [data-col="RollUp"] > .nc-virtual-cell`) |
||||||
|
.contains(records2.RollUp) |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// formula
|
||||||
|
mainPage.getCell("Computation", cellIdx).scrollIntoView(); |
||||||
|
cy.get( |
||||||
|
`:nth-child(${cellIdx}) > [data-col="Computation"] > .nc-virtual-cell` |
||||||
|
) |
||||||
|
.contains(records2.Computation) |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// ltar hm relation
|
||||||
|
mainPage.getCell("Producer", cellIdx).scrollIntoView(); |
||||||
|
cy.get( |
||||||
|
`:nth-child(${cellIdx}) > [data-col="Producer"] > .nc-virtual-cell > .v-lazy > .d-100 > .chips > :nth-child(1) > .v-chip__content > .name` |
||||||
|
) |
||||||
|
.contains(records2.Producer[0]) |
||||||
|
.should("exist"); |
||||||
|
cy.get( |
||||||
|
`:nth-child(${cellIdx}) > [data-col="Producer"] > .nc-virtual-cell > .v-lazy > .d-100 > .chips > :nth-child(2) > .v-chip__content > .name` |
||||||
|
) |
||||||
|
.contains(records2.Producer[1]) |
||||||
|
.should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
cy.closeTableTab("Film"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Verify Views & Shared base", () => { |
||||||
|
cy.openTableTab("Film", 3); |
||||||
|
cy.get('.nc-form-view-item').eq(0) |
||||||
|
.click({ force: true }) |
||||||
|
|
||||||
|
// Header & description should exist
|
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Form Title"]') |
||||||
|
.contains("FormTitle") |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-form") |
||||||
|
.find('[placeholder="Add form description"]') |
||||||
|
.contains("FormDescription") |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
// modified column name & help text
|
||||||
|
cy.get(".nc-field-wrapper").eq(0) |
||||||
|
.find('.nc-field-labels') |
||||||
|
.contains("DisplayName") |
||||||
|
.should('exist') |
||||||
|
cy.get(".nc-field-wrapper").eq(0) |
||||||
|
.find('.nc-hint') |
||||||
|
.contains('HelpText') |
||||||
|
.should('exist') |
||||||
|
|
||||||
|
cy.get(".nc-field-wrapper").eq(1) |
||||||
|
.find('.nc-field-labels') |
||||||
|
.contains("Email") |
||||||
|
.should('exist') |
||||||
|
|
||||||
|
// add message
|
||||||
|
cy.get(".nc-form > .mx-auto") |
||||||
|
.find("textarea").then(($element) => { |
||||||
|
expect($element[0].value).to.have.string("Thank you for submitting the form!") |
||||||
|
}) |
||||||
|
|
||||||
|
// submit another form button
|
||||||
|
cy.get(".nc-form > .mx-auto") |
||||||
|
.find('[type="checkbox"]') |
||||||
|
.eq(0) |
||||||
|
.should('be.checked') |
||||||
|
// "New form after 5 seconds" button
|
||||||
|
cy.get(".nc-form > .mx-auto") |
||||||
|
.find('[type="checkbox"]') |
||||||
|
.eq(1) |
||||||
|
.should('be.checked') |
||||||
|
// email me
|
||||||
|
cy.get(".nc-form > .mx-auto") |
||||||
|
.find('[type="checkbox"]') |
||||||
|
.eq(2) |
||||||
|
.should('not.be.checked') |
||||||
|
|
||||||
|
cy.closeTableTab("Film"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Verify Webhooks", () => { |
||||||
|
if( testMode === 'CY_QUICK') { |
||||||
|
cy.openTableTab("Actor", 25); |
||||||
|
openWebhook(0) |
||||||
|
verifyWebhook({ |
||||||
|
title: "Webhook-1", |
||||||
|
event: "After Insert", |
||||||
|
notification: "URL", |
||||||
|
type: "POST", |
||||||
|
url: "http://localhost:9090/hook", |
||||||
|
condition: false |
||||||
|
}) |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
|
||||||
|
openWebhook(1) |
||||||
|
verifyWebhook({ |
||||||
|
title: "Webhook-2", |
||||||
|
event: "After Update", |
||||||
|
notification: "URL", |
||||||
|
type: "POST", |
||||||
|
url: "http://localhost:9090/hook", |
||||||
|
condition: false |
||||||
|
}) |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
|
||||||
|
openWebhook(2) |
||||||
|
verifyWebhook({ |
||||||
|
title: "Webhook-3", |
||||||
|
event: "After Delete", |
||||||
|
notification: "URL", |
||||||
|
type: "POST", |
||||||
|
url: "http://localhost:9090/hook", |
||||||
|
condition: false |
||||||
|
}) |
||||||
|
cy.get("body").type("{esc}"); |
||||||
|
|
||||||
|
cy.closeTableTab("Actor"); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
it("Pagination", () => { |
||||||
|
cy.openTableTab("Actor", 25); |
||||||
|
|
||||||
|
cy.get(".nc-pagination").should("exist"); |
||||||
|
|
||||||
|
// verify > pagination option
|
||||||
|
mainPage.getPagination(">").click(); |
||||||
|
mainPage |
||||||
|
.getPagination(2) |
||||||
|
.should("have.class", "v-pagination__item--active"); |
||||||
|
|
||||||
|
// verify < pagination option
|
||||||
|
mainPage.getPagination("<").click(); |
||||||
|
mainPage |
||||||
|
.getPagination(1) |
||||||
|
.should("have.class", "v-pagination__item--active"); |
||||||
|
|
||||||
|
cy.closeTableTab("Actor"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Verify Fields, Filter & Sort", () => { |
||||||
|
cy.openTableTab("Actor", 25); |
||||||
|
cy.get(".nc-grid-view-item").eq(1).click() |
||||||
|
|
||||||
|
cy.get(".nc-grid-header-cell").contains('Name').should("be.visible"); |
||||||
|
cy.get(".nc-grid-header-cell").contains('Notes').should("be.visible"); |
||||||
|
// fix me!
|
||||||
|
if(testMode !== 'AT_IMPORT') cy.get(".nc-grid-header-cell").contains('Attachments').should("not.be.visible"); |
||||||
|
cy.get(".nc-grid-header-cell").contains('Status').should("be.visible"); |
||||||
|
cy.get(".nc-grid-header-cell").contains('Film').should("be.visible"); |
||||||
|
|
||||||
|
cy.get(".nc-fields-menu-btn").click(); |
||||||
|
cy.getActiveMenu().find(`[type="checkbox"]`).eq(0).should('be.checked') |
||||||
|
cy.getActiveMenu().find(`[type="checkbox"]`).eq(1).should('be.checked') |
||||||
|
cy.getActiveMenu().find(`[type="checkbox"]`).eq(2).should('not.be.checked') |
||||||
|
cy.getActiveMenu().find(`[type="checkbox"]`).eq(3).should('be.checked') |
||||||
|
cy.getActiveMenu().find(`[type="checkbox"]`).eq(4).should('be.checked') |
||||||
|
cy.get(".nc-fields-menu-btn").click(); |
||||||
|
|
||||||
|
cy.get(".nc-sort-menu-btn").click(); |
||||||
|
cy.get(".nc-sort-field-select").eq(0) |
||||||
|
.contains('Name') |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-sort-dir-select").eq(0) |
||||||
|
.contains('A → Z') |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-sort-menu-btn").click(); |
||||||
|
|
||||||
|
cy.get(".nc-filter-menu-btn").click(); |
||||||
|
cy.get(".nc-filter-field-select").eq(0) |
||||||
|
.contains('Name') |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-filter-operation-select").eq(0) |
||||||
|
.contains('is like') |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
cy.get(".nc-filter-field-select").eq(1) |
||||||
|
.contains('Name') |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-filter-operation-select").eq(1) |
||||||
|
.contains('is like') |
||||||
|
.should("exist"); |
||||||
|
cy.get(".nc-filter-menu-btn").click(); |
||||||
|
|
||||||
|
cy.closeTableTab("Actor"); |
||||||
|
}); |
||||||
|
|
||||||
|
it("Views, bt relation", () => { |
||||||
|
if( testMode === 'CY_QUICK') { |
||||||
|
|
||||||
|
cy.openTableTab("Producer", 3) |
||||||
|
cy.get('.nc-grid-view-item').should('have.length', 4) |
||||||
|
cy.get('.nc-form-view-item').should('have.length', 4) |
||||||
|
cy.get('.nc-gallery-view-item').should('have.length', 3) |
||||||
|
|
||||||
|
// LinkToAnotherRecord hm relation
|
||||||
|
mainPage.getCell("FilmRead", 1).scrollIntoView(); |
||||||
|
cy.get( |
||||||
|
':nth-child(1) > [data-col="FilmRead"] > .nc-virtual-cell > .v-lazy > .d-100 > .chips > :nth-child(1) > .v-chip__content > .name' |
||||||
|
) |
||||||
|
.contains('Movie-1') |
||||||
|
.should("exist"); |
||||||
|
|
||||||
|
cy.closeTableTab("Producer") |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
it("Delete Project", () => { |
||||||
|
if( testMode === 'AT_IMPORT') { |
||||||
|
mainPage.toolBarTopLeft(mainPage.HOME).click({force:true}) |
||||||
|
cy.get(`.mdi-delete-outline`, { |
||||||
|
timeout: 10000, |
||||||
|
}) |
||||||
|
.should("exist") |
||||||
|
.last() |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.getActiveModal() |
||||||
|
.find("button") |
||||||
|
.contains("Submit") |
||||||
|
.should("exist") |
||||||
|
.click(); |
||||||
|
cy.toastWait("deleted successfully"); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// genTest("rest", "xcdb");
|
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,279 @@ |
|||||||
|
import { mainPage, settingsPage } from "../../support/page_objects/mainPage"; |
||||||
|
import { roles } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
// Left hand navigation bar, validation for
|
||||||
|
// 1. Audit menu
|
||||||
|
// 2. Advance settings menu
|
||||||
|
// 3. Preview mode menu
|
||||||
|
//
|
||||||
|
export function _advSettings(roleType, mode) { |
||||||
|
cy.log(roleType, mode); |
||||||
|
|
||||||
|
if(mode === 'baseShare') { |
||||||
|
cy.get('.nc-project-menu').should('not.exist') |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
let validationString = |
||||||
|
true == roles[roleType].validations.advSettings ? "exist" : "not.exist"; |
||||||
|
|
||||||
|
// cy.get(".nc-team-settings").should(validationString);
|
||||||
|
cy.get('.nc-project-menu').should('exist').click() |
||||||
|
cy.getActiveMenu().find(`[data-menu-id="preview-as"]`).should(validationString) |
||||||
|
cy.getActiveMenu().find(`[data-menu-id="teamAndSettings"]:visible`).should(validationString) |
||||||
|
|
||||||
|
if (true === roles[roleType].validations.advSettings) { |
||||||
|
cy.getActiveMenu().find(`[data-menu-id="teamAndSettings"]:visible`).should(validationString).click() |
||||||
|
|
||||||
|
cy.get(`[data-menu-id="teamAndAuth"]`).should('exist') |
||||||
|
cy.get(`[data-menu-id="appStore"]`).should('exist') |
||||||
|
cy.get(`[data-menu-id="metaData"]`).should('exist') |
||||||
|
cy.get(`[data-menu-id="audit"]`).should('exist') |
||||||
|
|
||||||
|
settingsPage.closeMenu() |
||||||
|
} else { |
||||||
|
cy.get('.nc-project-menu').should('exist').click() |
||||||
|
} |
||||||
|
|
||||||
|
// float menu in preview mode
|
||||||
|
if ("preview" === mode) { |
||||||
|
cy.get(".nc-floating-preview-btn").should("exist"); |
||||||
|
cy.get('.nc-floating-preview-btn') |
||||||
|
.find(`[type="radio"][value="${roles[roleType].name}"]`) |
||||||
|
.should("be.checked"); |
||||||
|
} |
||||||
|
|
||||||
|
// cy.get("body").click("bottomRight");
|
||||||
|
} |
||||||
|
|
||||||
|
export function _editSchema(roleType, mode) { |
||||||
|
let columnName = "City"; |
||||||
|
let validationString = |
||||||
|
true == roles[roleType].validations.editSchema ? "exist" : "not.exist"; |
||||||
|
|
||||||
|
cy.openTableTab(columnName, 25); |
||||||
|
|
||||||
|
// create table
|
||||||
|
cy.get(`.nc-add-import-btn`).should(validationString); |
||||||
|
|
||||||
|
// delete table option
|
||||||
|
cy.get(`.nc-project-tree-tbl-City`).should("exist").rightclick(); |
||||||
|
cy.get(".ant-dropdown-content:visible").should(validationString); |
||||||
|
|
||||||
|
if(validationString === "exist"){ |
||||||
|
cy.getActiveMenu().find('[role="menuitem"]').contains("Delete").should("exist"); |
||||||
|
cy.getActiveMenu().find('[role="menuitem"]').contains("Rename").should("exist"); |
||||||
|
|
||||||
|
mainPage.getCell(columnName, 1).click(); |
||||||
|
} |
||||||
|
|
||||||
|
// add new column option
|
||||||
|
//
|
||||||
|
cy.get(".nc-column-add").should(validationString); |
||||||
|
|
||||||
|
// update column (edit/ delete menu)
|
||||||
|
cy.get('.nc-ui-dt-dropdown').should(validationString) |
||||||
|
} |
||||||
|
|
||||||
|
export function _editData(roleType, mode) { |
||||||
|
let columnName = "City"; |
||||||
|
let validationString = |
||||||
|
true === roles[roleType].validations.editData ? "exist" : "not.exist"; |
||||||
|
|
||||||
|
cy.openTableTab(columnName, 25); |
||||||
|
|
||||||
|
// add row
|
||||||
|
cy.get('.nc-add-new-row-btn:visible').should(validationString); |
||||||
|
|
||||||
|
mainPage.getCell(columnName, 25).scrollIntoView(); |
||||||
|
// cy.get('.nc-grid-add-new-cell').scrollIntoView();
|
||||||
|
|
||||||
|
cy.get('.nc-grid-add-new-cell:visible').should(validationString); |
||||||
|
|
||||||
|
// update row option (right click)
|
||||||
|
//
|
||||||
|
mainPage.getCell("City", 5).rightclick(); |
||||||
|
|
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
cy.get(".ant-dropdown-content:visible").should(validationString); |
||||||
|
|
||||||
|
if (validationString === "exist") { |
||||||
|
// right click options will exist (only for 'exist' case)
|
||||||
|
//
|
||||||
|
cy.getActiveMenu().contains("Insert New Row").should(validationString); |
||||||
|
cy.getActiveMenu().contains("Clear cell").should(validationString); |
||||||
|
cy.getActiveMenu().contains("Delete Row").should(validationString); |
||||||
|
cy.getActiveMenu().contains("Delete Selected Rows").should(validationString); |
||||||
|
|
||||||
|
// cy.get("body").type("{esc}");
|
||||||
|
mainPage.getCell("City", 13).click(); |
||||||
|
|
||||||
|
// update cell contents option using row expander should be enabled
|
||||||
|
//
|
||||||
|
mainPage |
||||||
|
.getRow(1) |
||||||
|
.find('.nc-row-no').should('exist') |
||||||
|
.eq(0) |
||||||
|
.trigger('mouseover', { force: true }) |
||||||
|
cy.get(".nc-row-expand") |
||||||
|
.should("exist") |
||||||
|
.eq(10) |
||||||
|
.click({ force: true }); |
||||||
|
cy.getActiveModal().find("button").contains("Save row").should("exist"); |
||||||
|
cy.getActiveModal().find("button").contains("Cancel").should("exist").click(); |
||||||
|
} else { |
||||||
|
// update cell contents option using row expander should be disabled
|
||||||
|
//
|
||||||
|
cy.get(".nc-row-expand") |
||||||
|
.should("exist") |
||||||
|
.eq(10) |
||||||
|
.click({ force: true }); |
||||||
|
cy.getActiveModal().find("button:disabled").contains("Save row").should("exist"); |
||||||
|
cy.getActiveModal().find("button").contains("Cancel").should("exist").click(); |
||||||
|
} |
||||||
|
|
||||||
|
// double click cell entries to edit
|
||||||
|
//
|
||||||
|
mainPage.getCell("City", 5) |
||||||
|
.dblclick() |
||||||
|
.find("input") |
||||||
|
.should(validationString); |
||||||
|
} |
||||||
|
|
||||||
|
// read &/ update comment
|
||||||
|
// Viewer: only allowed to read
|
||||||
|
// Everyone else: read &/ update
|
||||||
|
//
|
||||||
|
export function _editComment(roleType, mode) { |
||||||
|
let columnName = "City"; |
||||||
|
let validationString = |
||||||
|
true === roles[roleType].validations.editComment |
||||||
|
? "Comment added successfully" |
||||||
|
: "Not allowed"; |
||||||
|
|
||||||
|
cy.openTableTab(columnName, 25); |
||||||
|
|
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
// click on comment icon & type comment
|
||||||
|
//
|
||||||
|
cy.get(".nc-row-expand") |
||||||
|
.should("exist") |
||||||
|
.eq(10) |
||||||
|
.click({force:true}); |
||||||
|
|
||||||
|
// Expected response:
|
||||||
|
// Viewer: Not able to see comment option
|
||||||
|
// Everyone else: Comment added/read successfully
|
||||||
|
//
|
||||||
|
|
||||||
|
cy.wait(3000); |
||||||
|
|
||||||
|
if ("viewer" === roleType) { |
||||||
|
cy.getActiveModal() |
||||||
|
.should('exist') |
||||||
|
.find(".nc-toggle-comments") |
||||||
|
.should("not.exist"); |
||||||
|
} else { |
||||||
|
cy.getActiveModal() |
||||||
|
.should('exist') |
||||||
|
.find(".nc-toggle-comments") |
||||||
|
.should("exist") |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find(".nc-comment-box").should('exist').type("Comment-1{enter}"); |
||||||
|
cy.toastWait('Comment added successfully') |
||||||
|
cy.getActiveModal().find(".nc-toggle-comments").click(); |
||||||
|
} |
||||||
|
|
||||||
|
cy.getActiveModal() |
||||||
|
.find("button") |
||||||
|
.contains("Cancel") |
||||||
|
.should("exist") |
||||||
|
.click(); |
||||||
|
} |
||||||
|
|
||||||
|
// right navigation menu bar
|
||||||
|
// Editor/Viewer/Commenter : can only view 'existing' views
|
||||||
|
// Rest: can create/edit
|
||||||
|
export function _viewMenu(roleType, mode) { |
||||||
|
let columnName = "City"; |
||||||
|
|
||||||
|
// Download CSV, Excel
|
||||||
|
let actionsMenuItemsCnt = 2; |
||||||
|
|
||||||
|
cy.openTableTab(columnName, 25); |
||||||
|
|
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
// temporary!
|
||||||
|
cy.get('.nc-toggle-right-navbar').click(); |
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
let validationString = |
||||||
|
true === roles[roleType].validations.shareView ? "exist" : "not.exist"; |
||||||
|
|
||||||
|
if (roleType === "owner" || roleType === "creator") { |
||||||
|
// Download CSV / Download XLSX / Upload CSV / Shared View List / Webhook
|
||||||
|
actionsMenuItemsCnt = 5; |
||||||
|
} else if (roleType == "editor") { |
||||||
|
// Download CSV / Upload CSV / Download XLSX
|
||||||
|
actionsMenuItemsCnt = 2; |
||||||
|
} |
||||||
|
|
||||||
|
// view list field (default GRID view)
|
||||||
|
cy.get(`.nc-view-item`).should("exist"); |
||||||
|
|
||||||
|
// view create option, exists only for owner/ creator
|
||||||
|
cy.get(`.nc-create-1-view`).should(validationString); |
||||||
|
cy.get(`.nc-create-2-view`).should(validationString); |
||||||
|
cy.get(`.nc-create-3-view`).should(validationString); |
||||||
|
|
||||||
|
// share view & automations, exists only for owner/creator
|
||||||
|
// cy.get(".nc-btn-share-view").should(validationString);
|
||||||
|
// cy.get(`.nc-webhook-btn`).should(validationString);
|
||||||
|
|
||||||
|
// share view permissions are role specific
|
||||||
|
|
||||||
|
// actions menu (more), only download csv should be visible for non-previlaged users
|
||||||
|
cy.get(".nc-actions-menu-btn").click(); |
||||||
|
cy.getActiveMenu() |
||||||
|
.find('.nc-project-menu-item') |
||||||
|
.should("have.length", actionsMenuItemsCnt); |
||||||
|
} |
||||||
|
|
||||||
|
export function _topRightMenu(roleType, mode) { |
||||||
|
// kludge; download csv menu persists until clicked
|
||||||
|
let columnName = "City"; |
||||||
|
cy.closeTableTab(columnName); |
||||||
|
cy.openTableTab(columnName, 25); |
||||||
|
|
||||||
|
let validationString = |
||||||
|
true == roles[roleType].validations.shareView ? "exist" : "not.exist"; |
||||||
|
|
||||||
|
cy.get(`.nc-share-base`).should(validationString); |
||||||
|
cy.get(".nc-menu-translate").should("exist"); |
||||||
|
cy.get(".nc-menu-accounts").should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
// Access control list
|
||||||
|
//
|
||||||
|
export function disableTableAccess(tbl, role) { |
||||||
|
const cls = `.nc-acl-${tbl}-${role}-chkbox`; |
||||||
|
cy.get(cls).find("input").should("be.checked").click({ force: true }); |
||||||
|
cy.get(cls).find("input").should("not.be.checked"); |
||||||
|
} |
||||||
|
|
||||||
|
export function enableTableAccess(tbl, role) { |
||||||
|
const cls = `.nc-acl-${tbl}-${role}-chkbox`; |
||||||
|
cy.get(cls).find("input").should("not.be.checked").click({ force: true }); |
||||||
|
cy.get(cls).find("input").should("be.checked"); |
||||||
|
} |
||||||
|
|
||||||
|
export function _accessControl(roleType, previewMode) { |
||||||
|
let validationString = roleType === "creator" ? "exist" : "not.exist"; |
||||||
|
|
||||||
|
cy.get(`.nc-project-tree-tbl-Language`).should(validationString) |
||||||
|
cy.get(`.nc-project-tree-tbl-CustomerList`).should(validationString) |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
import { loginPage } from "../../support/page_objects/navigation"; |
||||||
|
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"; |
||||||
|
|
||||||
|
export const genTest = (apiType, dbType) => { |
||||||
|
// if (!isTestSuiteActive(apiType, dbType)) return;
|
||||||
|
|
||||||
|
describe(`${apiType.toUpperCase()} api - Login & Open project`, () => { |
||||||
|
// Run once before test- create project (rest/graphql)
|
||||||
|
//
|
||||||
|
before(() => { |
||||||
|
// loginPage.loginAndOpenProject(apiType, dbType);
|
||||||
|
// open a table to work on views
|
||||||
|
// cy.openTableTab('City');
|
||||||
|
}); |
||||||
|
|
||||||
|
it(``, () => { |
||||||
|
cy.log("Test-1"); |
||||||
|
|
||||||
|
let projId = ""; |
||||||
|
let query = `SELECT prefix from nc_projects_v2 where title = "sampleREST"; `; |
||||||
|
cy.task("sqliteExecReturnValue", query) |
||||||
|
.then((resolve) => { |
||||||
|
cy.log(resolve); |
||||||
|
projId = resolve.prefix.split("_")[1]; |
||||||
|
cy.log(projId); |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let query = `ALTER TABLE "actor" RENAME TO "${projId}actor"`; |
||||||
|
cy.task("sqliteExec", query); |
||||||
|
cy.wait(1000); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// genTest("rest", "mysql");
|
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Pranav C Balan <pranavxc@gmail.com> |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,67 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t6b = require("../common/6b_downloadCsv"); |
||||||
|
let t6c = require("../common/6c_swagger_api"); |
||||||
|
let t6d = require("../common/6d_language_validation"); |
||||||
|
let t6e = require("../common/6e_project_operations"); |
||||||
|
let t6f = require("../common/6f_attachments"); |
||||||
|
let t6g = require("../common/6g_base_share"); |
||||||
|
let t7a = require("../common/7a_create_project_from_excel"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
const t8a = require("../common/8a_webhook"); |
||||||
|
|
||||||
|
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
|
||||||
|
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
|
||||||
|
const executionMode = 1; |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
if (0 == executionMode) { |
||||||
|
t0.genTest(apiType, dbType); |
||||||
|
} else { |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
} |
||||||
|
|
||||||
|
t6b.genTest(apiType, dbType); |
||||||
|
// language validation kept common under REST MISC Suite
|
||||||
|
// t6d.genTest(apiType, dbType);
|
||||||
|
// ncv2@fixme t6c.genTest(apiType, dbType);
|
||||||
|
t6f.genTest(apiType, dbType); |
||||||
|
t6g.genTest(apiType, dbType); |
||||||
|
|
||||||
|
// webhook tests
|
||||||
|
t8a.genTest(apiType, dbType) |
||||||
|
|
||||||
|
// **deletes created project, hence place it @ end
|
||||||
|
t6e.genTest(apiType, dbType); |
||||||
|
|
||||||
|
// intended to keep this after earlier project deletion
|
||||||
|
// creates project using excel & deletes it
|
||||||
|
// ncv2@fixme t7a.genTest(apiType, dbType);
|
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "postgres"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,47 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t5a = require("../common/5a_user_role"); |
||||||
|
let t5b = require("../common/5b_preview_role"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
|
||||||
|
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
|
||||||
|
const executionMode = 1; |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
if (0 == executionMode) { |
||||||
|
t0.genTest(apiType, dbType); |
||||||
|
} else { |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
} |
||||||
|
|
||||||
|
t5a.genTest(apiType, dbType); |
||||||
|
t5b.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "postgres"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,68 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t1a = require("../common/1a_table_operations"); |
||||||
|
let t1b = require("../common/1b_table_column_operations"); |
||||||
|
let t1c = require("../common/1c_sql_view"); |
||||||
|
let t1d = require("../common/1d_pg_table_view_drag_drop_reorder"); |
||||||
|
let t1e = require("../common/1e_pg_meta_sync"); |
||||||
|
let t2a = require("../common/2a_table_with_belongs_to_colulmn"); |
||||||
|
let t2b = require("../common/2b_table_with_m2m_column"); |
||||||
|
let t3a = require("../common/3a_filter_sort_fields_operations"); |
||||||
|
let t3b = require("../common/3b_formula_column"); |
||||||
|
let t3c = require("../common/3c_lookup_column"); |
||||||
|
let t3d = require("../common/3d_rollup_column"); |
||||||
|
let t3e = require("../common/3e_duration_column"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
|
||||||
|
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
|
||||||
|
const executionMode = 1; |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
if (0 == executionMode) { |
||||||
|
t0.genTest(apiType, dbType); |
||||||
|
} else { |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
} |
||||||
|
|
||||||
|
t1a.genTest(apiType, dbType); |
||||||
|
t1b.genTest(apiType, dbType); |
||||||
|
t1c.genTest(apiType, dbType); |
||||||
|
// ncv2@fixme t1d.genTest(apiType, dbType);
|
||||||
|
t1e.genTest(apiType, dbType); |
||||||
|
t2a.genTest(apiType, dbType); |
||||||
|
t2b.genTest(apiType, dbType); |
||||||
|
t3a.genTest(apiType, dbType); |
||||||
|
// t3b.genTest(apiType, dbType);
|
||||||
|
t3c.genTest(apiType, dbType); |
||||||
|
t3d.genTest(apiType, dbType); |
||||||
|
t3e.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "postgres"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* @author Wing-Kam Wong <wingkwong.code@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,55 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t4a = require("../common/4a_table_view_grid_gallery_form"); |
||||||
|
let t4b = require("../common/4b_table_view_share"); |
||||||
|
let t4c = require("../common/4c_form_view_detailed"); |
||||||
|
let t4d = require("../common/4d_table_view_grid_locked"); |
||||||
|
let t4e = require("../common/4e_form_view_share"); |
||||||
|
let t4f = require("../common/4f_pg_grid_view_share"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
|
||||||
|
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
|
||||||
|
const executionMode = 1; |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
if (0 == executionMode) { |
||||||
|
t0.genTest(apiType, dbType); |
||||||
|
} else { |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
} |
||||||
|
|
||||||
|
t4a.genTest(apiType, dbType); |
||||||
|
t4b.genTest(apiType, dbType); |
||||||
|
t4c.genTest(apiType, dbType); |
||||||
|
t4d.genTest(apiType, dbType); |
||||||
|
t4e.genTest(apiType, dbType); |
||||||
|
t4f.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "postgres"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,39 @@ |
|||||||
|
let t7b = require("../common/7b_import_from_airtable"); |
||||||
|
let t9a = require("../common/9a_QuickTest"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
// CY Migration verification / Quick test
|
||||||
|
t9a.genTest(apiType, dbType, "CY_QUICK"); |
||||||
|
|
||||||
|
// AT Import verification
|
||||||
|
t7b.genTest(apiType, dbType) |
||||||
|
t9a.genTest(apiType, dbType, "AT_IMPORT"); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "xcdb"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,58 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t6b = require("../common/6b_downloadCsv"); |
||||||
|
let t6c = require("../common/6c_swagger_api"); |
||||||
|
let t6d = require("../common/6d_language_validation"); |
||||||
|
let t6e = require("../common/6e_project_operations"); |
||||||
|
let t6f = require("../common/6f_attachments"); |
||||||
|
let t6g = require("../common/6g_base_share"); |
||||||
|
let t7a = require("../common/7a_create_project_from_excel"); |
||||||
|
let t8a = require("../common/8a_webhook") |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
|
||||||
|
t6b.genTest(apiType, dbType); |
||||||
|
t6d.genTest(apiType, dbType); |
||||||
|
// exclude@ncv2 t6c.genTest(apiType, dbType);
|
||||||
|
t6f.genTest(apiType, dbType); |
||||||
|
t6g.genTest(apiType, dbType); |
||||||
|
|
||||||
|
// webhook tests
|
||||||
|
t8a.genTest(apiType, dbType) |
||||||
|
|
||||||
|
// **deletes created project, hence place it @ end
|
||||||
|
t6e.genTest(apiType, dbType); |
||||||
|
|
||||||
|
// intended to keep this after earlier project deletion
|
||||||
|
// creates project using excel & deletes it
|
||||||
|
t7a.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "mysql"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,39 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t5a = require("../common/5a_user_role"); |
||||||
|
let t5b = require("../common/5b_preview_role"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
|
||||||
|
t5a.genTest(apiType, dbType); |
||||||
|
t5b.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "mysql"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,60 @@ |
|||||||
|
|
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t1a = require("../common/1a_table_operations"); |
||||||
|
let t1b = require("../common/1b_table_column_operations"); |
||||||
|
let t1c = require("../common/1c_sql_view"); |
||||||
|
let t1d = require("../common/1d_table_view_drag_drop_reorder"); |
||||||
|
let t1e = require("../common/1e_meta_sync"); |
||||||
|
let t2a = require("../common/2a_table_with_belongs_to_colulmn"); |
||||||
|
let t2b = require("../common/2b_table_with_m2m_column"); |
||||||
|
let t3a = require("../common/3a_filter_sort_fields_operations"); |
||||||
|
let t3b = require("../common/3b_formula_column"); |
||||||
|
let t3c = require("../common/3c_lookup_column"); |
||||||
|
let t3d = require("../common/3d_rollup_column"); |
||||||
|
let t3e = require("../common/3e_duration_column"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
|
||||||
|
t1a.genTest(apiType, dbType); |
||||||
|
t1b.genTest(apiType, dbType); |
||||||
|
t1c.genTest(apiType, dbType); |
||||||
|
// NcGUI v2 t1d.genTest(apiType, dbType);
|
||||||
|
t1e.genTest(apiType, dbType); |
||||||
|
t2a.genTest(apiType, dbType); |
||||||
|
t2b.genTest(apiType, dbType); |
||||||
|
t3a.genTest(apiType, dbType); |
||||||
|
t3b.genTest(apiType, dbType); |
||||||
|
t3c.genTest(apiType, dbType); |
||||||
|
t3d.genTest(apiType, dbType); |
||||||
|
t3e.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "mysql"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* @author Wing-Kam Wong <wingkwong.code@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,47 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t4a = require("../common/4a_table_view_grid_gallery_form"); |
||||||
|
let t4b = require("../common/4b_table_view_share"); |
||||||
|
let t4c = require("../common/4c_form_view_detailed"); |
||||||
|
let t4d = require("../common/4d_table_view_grid_locked"); |
||||||
|
let t4e = require("../common/4e_form_view_share"); |
||||||
|
let t4f = require("../common/4f_grid_view_share"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
|
||||||
|
t4a.genTest(apiType, dbType); |
||||||
|
t4b.genTest(apiType, dbType); |
||||||
|
t4c.genTest(apiType, dbType); |
||||||
|
t4d.genTest(apiType, dbType); |
||||||
|
t4e.genTest(apiType, dbType); |
||||||
|
t4f.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "mysql"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,70 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t6b = require("../common/6b_downloadCsv"); |
||||||
|
let t6c = require("../common/6c_swagger_api"); |
||||||
|
let t6d = require("../common/6d_language_validation"); |
||||||
|
let t6e = require("../common/6e_project_operations"); |
||||||
|
let t6f = require("../common/6f_attachments"); |
||||||
|
let t6g = require("../common/6g_base_share"); |
||||||
|
let t7a = require("../common/7a_create_project_from_excel"); |
||||||
|
let t8a = require("../common/8a_webhook") |
||||||
|
|
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
|
||||||
|
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
|
||||||
|
const executionMode = 1; |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
if (0 == executionMode) { |
||||||
|
t0.genTest(apiType, dbType); |
||||||
|
} else { |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
} |
||||||
|
|
||||||
|
t6b.genTest(apiType, dbType); |
||||||
|
// language validation kept common under REST MISC Suite
|
||||||
|
// t6d.genTest(apiType, dbType);
|
||||||
|
// ncv2@fixme: swagger disable
|
||||||
|
// t6c.genTest(apiType, dbType);
|
||||||
|
t6f.genTest(apiType, dbType); |
||||||
|
t6g.genTest(apiType, dbType); |
||||||
|
|
||||||
|
// webhook tests
|
||||||
|
t8a.genTest(apiType, dbType) |
||||||
|
|
||||||
|
// **deletes created project, hence place it @ end
|
||||||
|
t6e.genTest(apiType, dbType); |
||||||
|
|
||||||
|
// intended to keep this after earlier project deletion
|
||||||
|
// creates project using excel & deletes it
|
||||||
|
// ncv2@fixme: disable excel import
|
||||||
|
// t7a.genTest(apiType, dbType);
|
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "xcdb"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,47 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t5a = require("../common/5a_user_role"); |
||||||
|
let t5b = require("../common/5b_preview_role"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
|
||||||
|
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
|
||||||
|
const executionMode = 1; |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
if (0 == executionMode) { |
||||||
|
t0.genTest(apiType, dbType); |
||||||
|
} else { |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
} |
||||||
|
|
||||||
|
t5a.genTest(apiType, dbType); |
||||||
|
t5b.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "xcdb"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,59 @@ |
|||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t1a = require("../common/1a_table_operations"); |
||||||
|
let t1b = require("../common/1b_table_column_operations"); |
||||||
|
let t1c = require("../common/1c_sql_view"); |
||||||
|
let t1d = require("../common/1d_table_view_drag_drop_reorder"); |
||||||
|
let t1e = require("../common/1e_meta_sync"); |
||||||
|
let t2a = require("../common/2a_table_with_belongs_to_colulmn"); |
||||||
|
let t2b = require("../common/2b_table_with_m2m_column"); |
||||||
|
let t3a = require("../common/3a_filter_sort_fields_operations"); |
||||||
|
let t3b = require("../common/3b_formula_column"); |
||||||
|
let t3c = require("../common/3c_lookup_column"); |
||||||
|
let t3d = require("../common/3d_rollup_column"); |
||||||
|
let t3e = require("../common/3e_duration_column"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
|
||||||
|
t1a.genTest(apiType, dbType); |
||||||
|
t1b.genTest(apiType, dbType); |
||||||
|
t1c.genTest(apiType, dbType); |
||||||
|
// ncv2@fixme t1d.genTest(apiType, dbType);
|
||||||
|
t1e.genTest(apiType, dbType); |
||||||
|
t2a.genTest(apiType, dbType); |
||||||
|
t2b.genTest(apiType, dbType); |
||||||
|
t3a.genTest(apiType, dbType); |
||||||
|
t3b.genTest(apiType, dbType); |
||||||
|
t3c.genTest(apiType, dbType); |
||||||
|
t3d.genTest(apiType, dbType); |
||||||
|
t3e.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "xcdb"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* @author Wing-Kam Wong <wingkwong.code@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,55 @@ |
|||||||
|
let t0 = require("./explicitLogin"); |
||||||
|
let t01 = require("../common/00_pre_configurations"); |
||||||
|
let t4a = require("../common/4a_table_view_grid_gallery_form"); |
||||||
|
let t4b = require("../common/4b_table_view_share"); |
||||||
|
let t4c = require("../common/4c_form_view_detailed"); |
||||||
|
let t4d = require("../common/4d_table_view_grid_locked"); |
||||||
|
let t4e = require("../common/4e_form_view_share"); |
||||||
|
let t4f = require("../common/4f_grid_view_share"); |
||||||
|
const { |
||||||
|
setCurrentMode, |
||||||
|
} = require("../../support/page_objects/projectConstants"); |
||||||
|
|
||||||
|
// use 0 as mode to execute individual files (debug mode, skip pre-configs)
|
||||||
|
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
|
||||||
|
const executionMode = 1; |
||||||
|
|
||||||
|
const nocoTestSuite = (apiType, dbType) => { |
||||||
|
setCurrentMode(apiType, dbType); |
||||||
|
if (0 == executionMode) { |
||||||
|
t0.genTest(apiType, dbType); |
||||||
|
} else { |
||||||
|
t01.genTest(apiType, dbType); |
||||||
|
} |
||||||
|
|
||||||
|
t4a.genTest(apiType, dbType); |
||||||
|
t4b.genTest(apiType, dbType); |
||||||
|
t4c.genTest(apiType, dbType); |
||||||
|
t4d.genTest(apiType, dbType); |
||||||
|
t4e.genTest(apiType, dbType); |
||||||
|
t4f.genTest(apiType, dbType); |
||||||
|
}; |
||||||
|
|
||||||
|
nocoTestSuite("rest", "xcdb"); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,225 @@ |
|||||||
|
/// <reference types="cypress" />
|
||||||
|
// ***********************************************************
|
||||||
|
// This example plugins/index.js can be used to load plugins
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off loading
|
||||||
|
// the plugins file with the 'pluginsFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/plugins-guide
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// This function is called when a project is opened or re-opened (e.g. due to
|
||||||
|
// the project's config changing)
|
||||||
|
const { rmdir, copyFile } = require("fs"); |
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/61934443/read-excel-files-in-cypress
|
||||||
|
const readXlsx = require("./read-xlsx"); |
||||||
|
const makeServer = require('./server') |
||||||
|
/** |
||||||
|
* @type {Cypress.PluginConfig} |
||||||
|
*/ |
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
module.exports = (on, config) => { |
||||||
|
// `on` is used to hook into various events Cypress emits
|
||||||
|
// `config` is the resolved Cypress config
|
||||||
|
|
||||||
|
// register utility tasks to read and parse Excel files
|
||||||
|
on("task", { |
||||||
|
copyFile() { |
||||||
|
console.log("copyFile", __dirname) |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
copyFile("./scripts/cypress/fixtures/quickTest/noco_0_91_7.db", "./packages/nocodb/noco.db", (err) => { |
||||||
|
if(err) { |
||||||
|
console.log(err) |
||||||
|
return reject(err) |
||||||
|
} |
||||||
|
resolve(null); |
||||||
|
}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
deleteFolder(folderName) { |
||||||
|
console.log("deleting folder %s", folderName); |
||||||
|
|
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
rmdir( |
||||||
|
folderName, |
||||||
|
{ maxRetries: 10, recursive: true }, |
||||||
|
(err) => { |
||||||
|
if (err) { |
||||||
|
console.error(err); |
||||||
|
|
||||||
|
return reject(err); |
||||||
|
} |
||||||
|
|
||||||
|
resolve(null); |
||||||
|
} |
||||||
|
); |
||||||
|
}); |
||||||
|
}, |
||||||
|
readXlsx: readXlsx.read, |
||||||
|
readSheetList: readXlsx.sheetList, |
||||||
|
log(message) { |
||||||
|
console.log(`##Cypress>> ${message}`); |
||||||
|
return null; |
||||||
|
}, |
||||||
|
queryDb: (query) => { |
||||||
|
return queryTestDb(query, config); |
||||||
|
}, |
||||||
|
sqliteExec: (query) => { |
||||||
|
_sqliteExec(query); |
||||||
|
return null; |
||||||
|
}, |
||||||
|
sqliteExecReturnValue: (query) => { |
||||||
|
return _sqliteExecReturnValue(query); |
||||||
|
}, |
||||||
|
pgExec: (query) => { |
||||||
|
_pgExec(query); |
||||||
|
return null; |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
let server, port, close |
||||||
|
|
||||||
|
on('before:spec', async (spec) => { |
||||||
|
// we can customize the server based on the spec about to run
|
||||||
|
const info = await makeServer() |
||||||
|
// save the server instance information
|
||||||
|
server = info.server |
||||||
|
port = info.port |
||||||
|
close = info.close |
||||||
|
console.log('started the server on port %d', port) |
||||||
|
}) |
||||||
|
|
||||||
|
on('after:spec', async (spec) => { |
||||||
|
if (!server) { |
||||||
|
console.log('no server to close') |
||||||
|
return |
||||||
|
} |
||||||
|
await close() |
||||||
|
console.log('closed the server running on port %d', port) |
||||||
|
}) |
||||||
|
}; |
||||||
|
|
||||||
|
// mysql connection
|
||||||
|
// https://gist.github.com/fityanos/0a345e9e9de498b6c629f78e6b2835f5
|
||||||
|
|
||||||
|
const mysql = require("mysql2"); |
||||||
|
function queryTestDb(query, config) { |
||||||
|
// creates a new mysql connection using credentials from cypress.json env's
|
||||||
|
const connection = mysql.createConnection(config.env.db); |
||||||
|
// start connection to db
|
||||||
|
connection.connect(); |
||||||
|
// exec query + disconnect to db as a Promise
|
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
connection.query(query, (error, results) => { |
||||||
|
if (error) reject(error); |
||||||
|
else { |
||||||
|
connection.end(); |
||||||
|
// console.log(results)
|
||||||
|
return resolve(results); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
// sqlite connection
|
||||||
|
const sqlite3 = require("sqlite3").verbose(); |
||||||
|
function _sqliteExecReturnValue(query) { |
||||||
|
// open the database
|
||||||
|
console.log("Current directory: " + process.cwd()); |
||||||
|
let db = new sqlite3.Database( |
||||||
|
"./scripts/cypress/fixtures/sqlite-sakila/sakila.db", |
||||||
|
sqlite3.OPEN_READWRITE, |
||||||
|
(err) => { |
||||||
|
if (err) { |
||||||
|
console.error(err.message); |
||||||
|
} else { |
||||||
|
console.log("Connected to the noco xcdb database."); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// exec query + disconnect to db as a Promise
|
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
db.get(query, [], (err, row) => { |
||||||
|
db.close(); |
||||||
|
if (err) { |
||||||
|
reject(err); |
||||||
|
} else { |
||||||
|
return resolve(row); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function _sqliteExec(query) { |
||||||
|
// open the database
|
||||||
|
console.log("Current directory: " + process.cwd()); |
||||||
|
let db = new sqlite3.Database( |
||||||
|
"./scripts/cypress/fixtures/sqlite-sakila/sakila.db", |
||||||
|
sqlite3.OPEN_READWRITE, |
||||||
|
(err) => { |
||||||
|
if (err) { |
||||||
|
console.error(err.message); |
||||||
|
} else { |
||||||
|
console.log("Connected to the noco xcdb database."); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
db.serialize(() => { |
||||||
|
db.run(query); |
||||||
|
}); |
||||||
|
|
||||||
|
db.close((err) => { |
||||||
|
if (err) { |
||||||
|
console.error(err.message); |
||||||
|
} else { |
||||||
|
console.log("Close the database connection."); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
// pg connection
|
||||||
|
const { Pool, Client } = require("pg"); |
||||||
|
const pg_credentials = { |
||||||
|
user: "postgres", |
||||||
|
host: "localhost", |
||||||
|
database: "postgres", |
||||||
|
password: "password", |
||||||
|
port: 5432, |
||||||
|
}; |
||||||
|
function _pgExec(query) { |
||||||
|
// open pg client connection
|
||||||
|
const client = new Client(pg_credentials); |
||||||
|
client.connect(); |
||||||
|
|
||||||
|
// query & terminate
|
||||||
|
client.query(query, (err, res) => { |
||||||
|
console.log(err, res); |
||||||
|
client.end(); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,33 @@ |
|||||||
|
// https://stackoverflow.com/questions/61934443/read-excel-files-in-cypress
|
||||||
|
|
||||||
|
const fs = require("fs"); |
||||||
|
const XLSX = require("xlsx"); |
||||||
|
|
||||||
|
const read = ({ file, sheet }) => { |
||||||
|
const buf = fs.readFileSync(file); |
||||||
|
const workbook = XLSX.read(buf, { type: "buffer" }); |
||||||
|
const rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]); |
||||||
|
return rows; |
||||||
|
}; |
||||||
|
|
||||||
|
// const read = ({file, sheet}) => {
|
||||||
|
// const buf = fs.readFileSync(file);
|
||||||
|
// const workbook = XLSX.read(buf, { type: 'buffer' });
|
||||||
|
// const rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheet], {
|
||||||
|
// header: 1,
|
||||||
|
// blankrows: false
|
||||||
|
// });
|
||||||
|
// return rows
|
||||||
|
// }
|
||||||
|
|
||||||
|
const sheetList = ({ file }) => { |
||||||
|
const buf = fs.readFileSync(file); |
||||||
|
const workbook = XLSX.read(buf, { type: "buffer" }); |
||||||
|
const rows = workbook.SheetNames; |
||||||
|
return rows; |
||||||
|
}; |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
read, |
||||||
|
sheetList, |
||||||
|
}; |
@ -0,0 +1,84 @@ |
|||||||
|
|
||||||
|
// https://glebbahmutov.com/blog/restart-server/
|
||||||
|
|
||||||
|
const express = require('express') |
||||||
|
const bodyParser = require("body-parser") |
||||||
|
|
||||||
|
let request = [] |
||||||
|
|
||||||
|
function makeServer() { |
||||||
|
const app = express() |
||||||
|
app.use(bodyParser.json()) |
||||||
|
|
||||||
|
app.get("/hook/all", (req, res) => { |
||||||
|
// console.log(request)
|
||||||
|
res.json(request) |
||||||
|
}) |
||||||
|
app.get("/hook/last", (req, res) => { |
||||||
|
if(request.length) { |
||||||
|
// console.log(request[request.length - 1])
|
||||||
|
res.json(request[request.length - 1]) |
||||||
|
} |
||||||
|
}) |
||||||
|
app.get("/hook/count", (req, res) => { |
||||||
|
// console.log(request.length)
|
||||||
|
res.json(request.length) |
||||||
|
}) |
||||||
|
app.get("/hook/clear", (req, res) => { |
||||||
|
request = [] |
||||||
|
res.status(200).end() |
||||||
|
}) |
||||||
|
|
||||||
|
app.post("/hook", (req, res) => { |
||||||
|
request.push(req.body) |
||||||
|
// console.log("/hook :: ", req.body) // Call your action on the request here
|
||||||
|
res.status(200).end() // Responding is important
|
||||||
|
}) |
||||||
|
|
||||||
|
app.post("/stop", (req, res) => { |
||||||
|
process.exit(); |
||||||
|
}) |
||||||
|
|
||||||
|
const port = 9090 |
||||||
|
|
||||||
|
return new Promise((resolve) => { |
||||||
|
const server = app.listen(port, function () { |
||||||
|
const port = server.address().port |
||||||
|
console.log('Example app listening at port %d', port) |
||||||
|
|
||||||
|
// close the server
|
||||||
|
const close = () => { |
||||||
|
return new Promise((resolve) => { |
||||||
|
console.log('closing server') |
||||||
|
server.close(resolve) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
resolve({ server, port, close }) |
||||||
|
}) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = makeServer |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,555 @@ |
|||||||
|
// ***********************************************
|
||||||
|
// This example commands.js shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
// @author Roman Rezinkin roman.rezinkin@hotmail.com
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||||
|
|
||||||
|
import "cypress-file-upload"; |
||||||
|
import { isXcdb, isPostgres } from "./page_objects/projectConstants"; |
||||||
|
|
||||||
|
require("@4tw/cypress-drag-drop"); |
||||||
|
|
||||||
|
// for waiting until page load
|
||||||
|
Cypress.Commands.add("waitForSpinners", () => { |
||||||
|
cy.visit("http://localhost:3000/signup", { |
||||||
|
retryOnNetworkFailure: true, |
||||||
|
timeout: 1200000, |
||||||
|
headers: { |
||||||
|
"Accept-Encoding": "gzip, deflate", |
||||||
|
}, |
||||||
|
}); |
||||||
|
cy.get(".nc-form-signup").should("exist") |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("signinOrSignup", (_args) => { |
||||||
|
const args = Object.assign( |
||||||
|
{ username: "user@nocodb.com", password: "Password123." }, |
||||||
|
_args |
||||||
|
); |
||||||
|
|
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
// signin/signup
|
||||||
|
cy.get("body").then(($body) => { |
||||||
|
// cy.wait(1000)
|
||||||
|
cy.url().then((url) => { |
||||||
|
if (!url.includes("/projects")) { |
||||||
|
// handle initial load
|
||||||
|
if ($body.find(".welcome-page").length > 0) { |
||||||
|
cy.wait(8000); |
||||||
|
cy.get("body").trigger("mousemove"); |
||||||
|
cy.snip("LetsBegin"); |
||||||
|
cy.contains("Let's Begin").click(); |
||||||
|
cy.get('input[type="text"]', { timeout: 12000 }).type( |
||||||
|
args.username |
||||||
|
); |
||||||
|
cy.get('input[type="password"]').type(args.password); |
||||||
|
cy.snip("SignUp"); |
||||||
|
cy.get('button:contains("SIGN UP")').click(); |
||||||
|
|
||||||
|
// handle signin
|
||||||
|
} else { |
||||||
|
cy.get('input[type="text"]', { timeout: 12000 }).type( |
||||||
|
args.username |
||||||
|
); |
||||||
|
cy.get('input[type="password"]').type(args.password); |
||||||
|
cy.snip("SignIn"); |
||||||
|
cy.get('button:contains("SIGN IN")').click(); |
||||||
|
} |
||||||
|
} else if (url.includes("/signin")) { |
||||||
|
cy.get('input[type="text"]', { timeout: 12000 }).type( |
||||||
|
args.username |
||||||
|
); |
||||||
|
cy.get('input[type="password"]').type(args.password); |
||||||
|
cy.snip("SignIn"); |
||||||
|
cy.get('button:contains("SIGN IN")').click(); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
// indicates page-load complete
|
||||||
|
cy.get(".nc-noco-brand-icon", { timeout: 12000 }).should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
// for opening/creating a rest project
|
||||||
|
Cypress.Commands.add("openOrCreateRestProject", (_args) => { |
||||||
|
const args = Object.assign({ new: false }, _args); |
||||||
|
|
||||||
|
// signin/signup
|
||||||
|
cy.signinOrSignup(); |
||||||
|
cy.get(".nc-new-project-menu").should("exist"); |
||||||
|
cy.snip("ProjectPage"); |
||||||
|
cy.get("body").then(($body) => { |
||||||
|
const filter = args.meta |
||||||
|
? ".nc-meta-project-row" |
||||||
|
: ":not(.nc-meta-project-row)"; |
||||||
|
// if project exist open
|
||||||
|
if ( |
||||||
|
$body.find(".nc-rest-project-row").filter(filter).length && |
||||||
|
!args.new |
||||||
|
) { |
||||||
|
cy.get(".nc-rest-project-row").filter(filter).first().click(); |
||||||
|
} else { |
||||||
|
cy.contains("New Project") |
||||||
|
.trigger("onmouseover") |
||||||
|
.trigger("mouseenter"); |
||||||
|
if (args.meta) { |
||||||
|
cy.get(".nc-create-xc-db-project").click(); |
||||||
|
cy.url({ timeout: 6000 }).should("contain", "#/project/xcdb"); |
||||||
|
cy.get(".nc-metadb-project-name").type( |
||||||
|
"test_proj" + Date.now() |
||||||
|
); |
||||||
|
cy.contains("button", "Create", { timeout: 3000 }).click(); |
||||||
|
} else { |
||||||
|
cy.get(".nc-create-external-db-project").click(); |
||||||
|
cy.url({ timeout: 6000 }).should("contain", "#/project"); |
||||||
|
cy.get(".database-field input").click().clear().type("sakila"); |
||||||
|
cy.contains("Test Database Connection").click(); |
||||||
|
cy.contains("Ok & Save Project", { timeout: 3000 }).click(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
cy.url({ timeout: 20000 }).should("contain", "#/nc/"); |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("refreshTableTab", () => { |
||||||
|
cy.task("log", `[refreshTableTab]`); |
||||||
|
|
||||||
|
cy.get(".nc-project-tree") |
||||||
|
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 }) |
||||||
|
.should("exist") |
||||||
|
.first() |
||||||
|
.rightclick({ force: true }); |
||||||
|
|
||||||
|
cy.getActiveMenu() |
||||||
|
.find('[role="menuitem"]') |
||||||
|
.contains("Tables Refresh") |
||||||
|
.should("exist") |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
cy.toastWait("Tables refreshed"); |
||||||
|
}); |
||||||
|
|
||||||
|
// tn: table name
|
||||||
|
// rc: row count. validate row count if rc!=0
|
||||||
|
Cypress.Commands.add("openTableTab", (tn, rc) => { |
||||||
|
cy.task("log", `[openTableTab] ${tn} ${rc}`); |
||||||
|
cy.get(`.nc-project-tree-tbl-${tn}`, { timeout: 10000 }).should("exist") |
||||||
|
.first() |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// kludge to make new tab active
|
||||||
|
cy.get('.ant-tabs-tab-btn') |
||||||
|
.contains(tn) |
||||||
|
.should('exist') |
||||||
|
.click({ force: true }); |
||||||
|
cy.get('.xc-row-table.nc-grid').should('exist'); |
||||||
|
|
||||||
|
// wait for page rendering to complete
|
||||||
|
if (rc != 0) { |
||||||
|
cy.get(".nc-grid-row").should("have.length", rc); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("closeTableTab", (tn) => { |
||||||
|
cy.task("log", `[closeTableTab] ${tn}`); |
||||||
|
cy.get('.ant-tabs-tab-btn') |
||||||
|
.contains(tn) |
||||||
|
.should('exist') |
||||||
|
.parent() |
||||||
|
.parent() |
||||||
|
.find('button') |
||||||
|
.click(); |
||||||
|
|
||||||
|
// subsequent tab open commands will fail if tab is not closed completely
|
||||||
|
cy.wait(1000); |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("openOrCreateGqlProject", (_args) => { |
||||||
|
const args = Object.assign({ new: false, meta: false }, _args); |
||||||
|
|
||||||
|
cy.signinOrSignup(); |
||||||
|
|
||||||
|
cy.get(".nc-new-project-menu").should("exist"); |
||||||
|
cy.get("body").then(($body) => { |
||||||
|
const filter = args.meta |
||||||
|
? ".nc-meta-project-row" |
||||||
|
: ":not(.nc-meta-project-row)"; |
||||||
|
// if project exist open
|
||||||
|
if ( |
||||||
|
$body.find(".nc-graphql-project-row").filter(filter).length && |
||||||
|
!args.new |
||||||
|
) { |
||||||
|
cy.get(".nc-graphql-project-row").filter(filter).first().click(); |
||||||
|
} else { |
||||||
|
cy.contains("New Project") |
||||||
|
.trigger("onmouseover") |
||||||
|
.trigger("mouseenter"); |
||||||
|
if (args.meta) { |
||||||
|
cy.get(".nc-create-xc-db-project").click(); |
||||||
|
cy.url({ timeout: 6000 }).should("contain", "#/project/xcdb"); |
||||||
|
cy.contains("GRAPHQL APIs").closest("label").click(); |
||||||
|
cy.get(".nc-metadb-project-name").type( |
||||||
|
"test_proj" + Date.now() |
||||||
|
); |
||||||
|
cy.contains("button", "Create", { timeout: 3000 }).click(); |
||||||
|
} else { |
||||||
|
cy.get(".nc-create-external-db-project").click(); |
||||||
|
cy.url({ timeout: 6000 }).should("contain", "#/project"); |
||||||
|
cy.contains("GRAPHQL APIs").closest("label").click(); |
||||||
|
cy.get(".database-field input").click().clear().type("sakila"); |
||||||
|
cy.contains("Test Database Connection").click(); |
||||||
|
cy.contains("Ok & Save Project").should('exist').click(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
cy.url({ timeout: 20000 }).should("contain", "#/nc/"); |
||||||
|
}); |
||||||
|
|
||||||
|
let LOCAL_STORAGE_MEMORY = {}; |
||||||
|
|
||||||
|
Cypress.Commands.add("saveLocalStorage", () => { |
||||||
|
Object.keys(localStorage).forEach((key) => { |
||||||
|
LOCAL_STORAGE_MEMORY[key] = localStorage[key]; |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("restoreLocalStorage", () => { |
||||||
|
Object.keys(LOCAL_STORAGE_MEMORY).forEach((key) => { |
||||||
|
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("deleteLocalStorage", () => { |
||||||
|
Object.keys(LOCAL_STORAGE_MEMORY).forEach((key) => { |
||||||
|
localStorage.removeItem(key); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("getActiveModal", () => { |
||||||
|
return cy.get(".ant-modal-content:visible").last() |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("getActiveMenu", () => { |
||||||
|
return cy.get(".ant-dropdown-content:visible").last(); |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("getActivePopUp", () => { |
||||||
|
return cy.get(".ant-menu-submenu-popup:visible").last(); |
||||||
|
}) |
||||||
|
|
||||||
|
Cypress.Commands.add("getActiveSelection", () => { |
||||||
|
return cy.get(".ant-select-dropdown:visible").last(); |
||||||
|
}) |
||||||
|
|
||||||
|
Cypress.Commands.add("getActiveDrawer", () => { |
||||||
|
return cy.get(".ant-drawer-content:visible").last(); |
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add("createTable", (name) => { |
||||||
|
// cy.get(".nc-btn-tbl-add").click();
|
||||||
|
|
||||||
|
// cy.get(`[data-menu-id="addORImport"]`).click();
|
||||||
|
// cy.getActivePopUp().contains("Add new table").should('exist').click();
|
||||||
|
|
||||||
|
cy.get('.nc-add-new-table').should('exist').click(); |
||||||
|
|
||||||
|
cy.getActiveModal().find(`input[type="text"]:visible`) |
||||||
|
.click() |
||||||
|
.clear() |
||||||
|
.type(name) |
||||||
|
cy.getActiveModal().find("button").contains("Submit").click(); |
||||||
|
cy.get('.xc-row-table.nc-grid').should('exist'); |
||||||
|
cy.get('.ant-tabs-tab-active > .ant-tabs-tab-btn').contains(name).should("exist"); |
||||||
|
cy.url().should("contain", `table/${name}`); |
||||||
|
cy.get(`.nc-project-tree-tbl-${name}`).should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("deleteTable", (name, dbType) => { |
||||||
|
cy.get(`.nc-project-tree-tbl-${name}`).should("exist").rightclick(); |
||||||
|
cy.getActiveMenu().find('[role="menuitem"]').contains("Delete").click(); |
||||||
|
cy.getActiveModal().find("button").contains("Yes").click(); |
||||||
|
|
||||||
|
// only for postgre project
|
||||||
|
if (dbType === "postgres") cy.toastWait(`Delete trigger successful`); |
||||||
|
cy.toastWait(`Deleted table ${name} successfully`); |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("renameTable", (oldName, newName) => { |
||||||
|
|
||||||
|
// right click on project table name
|
||||||
|
cy.get(`.nc-project-tree-tbl-${oldName}`) |
||||||
|
.should('exist') |
||||||
|
.first() |
||||||
|
.rightclick(); |
||||||
|
|
||||||
|
// choose rename option from menu
|
||||||
|
cy.getActiveMenu() |
||||||
|
.find('[role="menuitem"]') |
||||||
|
.contains("Rename") |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// feed new name
|
||||||
|
cy.getActiveModal().find("input").clear().type(newName); |
||||||
|
|
||||||
|
// submit
|
||||||
|
cy.getActiveModal().find("button").contains("Submit").click(); |
||||||
|
|
||||||
|
cy.toastWait("Table renamed successfully"); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("createColumn", (table, columnName) => { |
||||||
|
cy.get(".nc-project-tree") |
||||||
|
.find(".v-list-item__title:contains(Tables)") |
||||||
|
.should('exist') |
||||||
|
.first() |
||||||
|
.click(); |
||||||
|
cy.get(".nc-project-tree") |
||||||
|
.contains(table) |
||||||
|
.should('exist') |
||||||
|
.first() |
||||||
|
.click({ force: true }); |
||||||
|
cy.get(`.project-tab:contains(${table}):visible`).should("exist"); |
||||||
|
cy.get(".v-window-item--active .nc-grid tr > th:last button").click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
cy.get(".nc-column-name-input input").clear().type(columnName); |
||||||
|
cy.getActiveMenu("Menu_CreateColumn"); |
||||||
|
cy.get(".nc-col-create-or-edit-card").contains("Save").click(); |
||||||
|
cy.get("th:contains(new_column)").should("exist"); |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("toastWait", (msg) => { |
||||||
|
cy.get('.ant-message-notice-content:visible', { timout: 12000 }).contains(msg).should('exist') |
||||||
|
cy.get('.ant-message-notice-content:visible', { timout: 12000 }).should('not.exist') |
||||||
|
|
||||||
|
// cy.get(".toasted:visible", { timout: 12000 }).contains(msg).should("exist");
|
||||||
|
// cy.get(".toasted:visible", { timout: 12000 })
|
||||||
|
// .contains(msg)
|
||||||
|
// .should("not.exist");
|
||||||
|
// cy.wait(3000);
|
||||||
|
}); |
||||||
|
|
||||||
|
// vn: view name
|
||||||
|
// rc: expected row count. validate row count if rc!=0
|
||||||
|
Cypress.Commands.add("openViewsTab", (vn, rc) => { |
||||||
|
cy.task("log", `[openViewsTab] ${vn} ${rc}`); |
||||||
|
|
||||||
|
cy.get(`.nc-project-tree-tbl-${vn}`, { timeout: 10000 }).should("exist") |
||||||
|
.first() |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// kludge to make new tab active
|
||||||
|
cy.get('.ant-tabs-tab-btn') |
||||||
|
.contains(vn) |
||||||
|
.should('exist') |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
// wait for page rendering to complete
|
||||||
|
if (rc != 0) { |
||||||
|
cy.get('.xc-row-table.nc-grid').should('exist'); |
||||||
|
cy.get(".nc-grid-row").should("have.length", rc); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
Cypress.Commands.add("closeViewsTab", (vn) => { |
||||||
|
cy.task("log", `[closeViewsTab] ${vn}`); |
||||||
|
cy.get('.ant-tabs-tab-btn') |
||||||
|
.contains(vn) |
||||||
|
.should('exist') |
||||||
|
.parent() |
||||||
|
.parent() |
||||||
|
.find('button') |
||||||
|
.click(); |
||||||
|
}); |
||||||
|
|
||||||
|
// Support for screen-shots
|
||||||
|
//
|
||||||
|
|
||||||
|
let screenShotDb = []; |
||||||
|
|
||||||
|
// snip entire screen
|
||||||
|
Cypress.Commands.add("snip", (filename) => { |
||||||
|
if ( |
||||||
|
true === Cypress.env("screenshot") && |
||||||
|
false === screenShotDb.includes(filename) |
||||||
|
) { |
||||||
|
let storeName = `${screenShotDb.length}_${filename}`; |
||||||
|
screenShotDb.push(filename); |
||||||
|
cy.wait(1000); |
||||||
|
cy.screenshot(storeName, { overwrite: true }); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// snip current modal
|
||||||
|
Cypress.Commands.add("snipActiveModal", (filename) => { |
||||||
|
if ( |
||||||
|
true === Cypress.env("screenshot") && |
||||||
|
false === screenShotDb.includes(filename) |
||||||
|
) { |
||||||
|
let storeName = `${screenShotDb.length}_${filename}`; |
||||||
|
screenShotDb.push(filename); |
||||||
|
cy.wait(1000); |
||||||
|
// cy.getActiveModal().screenshot(filename, {
|
||||||
|
// padding: 0,
|
||||||
|
// overwrite: true,
|
||||||
|
// });
|
||||||
|
cy.screenshot(storeName, { overwrite: true }); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// snip current menu
|
||||||
|
Cypress.Commands.add("snipActiveMenu", (filename) => { |
||||||
|
if ( |
||||||
|
true === Cypress.env("screenshot") && |
||||||
|
false === screenShotDb.includes(filename) |
||||||
|
) { |
||||||
|
let storeName = `${screenShotDb.length}_${filename}`; |
||||||
|
screenShotDb.push(filename); |
||||||
|
cy.wait(1000); |
||||||
|
// cy.getActiveMenu().screenshot(filename, {
|
||||||
|
// padding: 0,
|
||||||
|
// overwrite: true,
|
||||||
|
// });
|
||||||
|
cy.screenshot(storeName, { overwrite: true }); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// pre-test file hook
|
||||||
|
Cypress.Commands.add("fileHook", () => { |
||||||
|
window.localStorage.setItem('vueuse-color-scheme', 'light') |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Drag n Drop
|
||||||
|
// refer: https://stackoverflow.com/a/55409853
|
||||||
|
/* |
||||||
|
|
||||||
|
const getCoords = ($el) => { |
||||||
|
const domRect = $el[0].getBoundingClientRect() |
||||||
|
const coords = { x: domRect.left + (domRect.width / 2 || 0), y: domRect.top + (domRect.height / 2 || 0) } |
||||||
|
|
||||||
|
return coords |
||||||
|
} |
||||||
|
|
||||||
|
const dragTo = (subject, to, opts) => { |
||||||
|
|
||||||
|
opts = Cypress._.defaults(opts, { |
||||||
|
// delay inbetween steps
|
||||||
|
delay: 0, |
||||||
|
// interpolation between coords
|
||||||
|
steps: 0, |
||||||
|
// >=10 steps
|
||||||
|
smooth: false, |
||||||
|
}) |
||||||
|
|
||||||
|
if (opts.smooth) { |
||||||
|
opts.steps = Math.max(opts.steps, 10) |
||||||
|
} |
||||||
|
|
||||||
|
const win = subject[0].ownerDocument.defaultView |
||||||
|
|
||||||
|
const elFromCoords = (coords) => win.document.elementFromPoint(coords.x, coords.y) |
||||||
|
const winMouseEvent = win.MouseEvent |
||||||
|
|
||||||
|
const send = (type, coords, el) => { |
||||||
|
|
||||||
|
el = el || elFromCoords(coords) |
||||||
|
|
||||||
|
el.dispatchEvent( |
||||||
|
new winMouseEvent(type, Object.assign({}, { clientX: coords.x, clientY: coords.y }, { bubbles: true, cancelable: true })) |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
const toSel = to |
||||||
|
|
||||||
|
function drag (from, to, steps = 1) { |
||||||
|
|
||||||
|
const fromEl = elFromCoords(from) |
||||||
|
|
||||||
|
const _log = Cypress.log({ |
||||||
|
$el: fromEl, |
||||||
|
name: 'drag to', |
||||||
|
message: toSel, |
||||||
|
}) |
||||||
|
|
||||||
|
_log.snapshot('before', { next: 'after', at: 0 }) |
||||||
|
|
||||||
|
_log.set({ coords: to }) |
||||||
|
|
||||||
|
send('mouseover', from, fromEl) |
||||||
|
send('mousedown', from, fromEl) |
||||||
|
|
||||||
|
cy.then(() => { |
||||||
|
return Cypress.Promise.try(() => { |
||||||
|
|
||||||
|
if (steps > 0) { |
||||||
|
|
||||||
|
const dx = (to.x - from.x) / steps |
||||||
|
const dy = (to.y - from.y) / steps |
||||||
|
|
||||||
|
return Cypress.Promise.map(Array(steps).fill(), (v, i) => { |
||||||
|
i = steps - 1 - i |
||||||
|
|
||||||
|
let _to = { |
||||||
|
x: from.x + dx * (i), |
||||||
|
y: from.y + dy * (i), |
||||||
|
} |
||||||
|
|
||||||
|
send('mousemove', _to, fromEl) |
||||||
|
|
||||||
|
return Cypress.Promise.delay(opts.delay) |
||||||
|
|
||||||
|
}, { concurrency: 1 }) |
||||||
|
} |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
|
||||||
|
send('mousemove', to, fromEl) |
||||||
|
send('mouseover', to) |
||||||
|
send('mousemove', to) |
||||||
|
send('mouseup', to) |
||||||
|
_log.snapshot('after', { at: 1 }).end() |
||||||
|
|
||||||
|
}) |
||||||
|
|
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
const $el = subject |
||||||
|
const fromCoords = getCoords($el) |
||||||
|
const toCoords = getCoords(cy.$$(to)) |
||||||
|
|
||||||
|
drag(fromCoords, toCoords, opts.steps) |
||||||
|
} |
||||||
|
|
||||||
|
Cypress.Commands.addAll( |
||||||
|
{ prevSubject: 'element' }, |
||||||
|
{ |
||||||
|
dragTo, |
||||||
|
} |
||||||
|
) |
||||||
|
*/ |
@ -0,0 +1,32 @@ |
|||||||
|
// ***********************************************************
|
||||||
|
// This example support/index.js is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import "./commands"; |
||||||
|
|
||||||
|
// https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress/
|
||||||
|
import "cypress-iframe"; |
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
||||||
|
|
||||||
|
Cypress.on("uncaught:exception", (err, runnable) => { |
||||||
|
// returning false here prevents Cypress from
|
||||||
|
// failing the test
|
||||||
|
console.log("uncaught:exception"); |
||||||
|
console.log(err); |
||||||
|
console.log(runnable); |
||||||
|
return false; |
||||||
|
}); |
@ -0,0 +1,490 @@ |
|||||||
|
import { projectsPage } from "./navigation"; |
||||||
|
|
||||||
|
const path = require("path"); |
||||||
|
|
||||||
|
/** |
||||||
|
* Delete the downloads folder to make sure the test has "clean" |
||||||
|
* slate before starting. |
||||||
|
*/ |
||||||
|
export const deleteDownloadsFolder = () => { |
||||||
|
const downloadsFolder = Cypress.config("downloadsFolder"); |
||||||
|
cy.task("deleteFolder", downloadsFolder); |
||||||
|
}; |
||||||
|
|
||||||
|
export class _settingsPage { |
||||||
|
constructor() { |
||||||
|
// menu
|
||||||
|
this.TEAM_N_AUTH = "teamAndAuth"; |
||||||
|
this.APPSTORE = "appStore"; |
||||||
|
this.PROJ_METADATA = "metaData"; |
||||||
|
this.AUDIT = "audit"; |
||||||
|
|
||||||
|
// submenu
|
||||||
|
this.USER_MANAGEMENT = "usersManagement"; |
||||||
|
this.API_TOKEN_MANAGEMENT = "apiTokenManagement"; |
||||||
|
this.APPS = "new"; |
||||||
|
this.METADATA = "metaData"; |
||||||
|
this.UI_ACCESS_CONTROL = "acl"; |
||||||
|
this.AUDIT_LOG = "audit"; |
||||||
|
} |
||||||
|
|
||||||
|
openMenu(menuId) { |
||||||
|
// open settings tab
|
||||||
|
// cy.get('.nc-team-settings').should('exist').click()
|
||||||
|
// cy.get(`[data-menu-id=${menuId}]`).should('exist').click()
|
||||||
|
cy.get('.nc-project-menu').should('exist').click() |
||||||
|
cy.getActiveMenu().find(`[data-menu-id="teamAndSettings"]`).should('exist').click() |
||||||
|
cy.get(`[data-menu-id=${menuId}]`).should('exist').click() |
||||||
|
} |
||||||
|
|
||||||
|
openTab(tabId) { |
||||||
|
cy.get(`[data-menu-id=${tabId}]`).should('exist').last().click() |
||||||
|
} |
||||||
|
|
||||||
|
closeMenu() { |
||||||
|
cy.getActiveModal().find('.nc-modal-close').click({ force: true }); |
||||||
|
} |
||||||
|
|
||||||
|
openProjectMenu() { |
||||||
|
cy.get('.nc-project-menu').should('exist').click() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// main page
|
||||||
|
export class _mainPage { |
||||||
|
constructor() { |
||||||
|
|
||||||
|
// Top Left items
|
||||||
|
this.HOME = 0; |
||||||
|
|
||||||
|
this.AUDIT = 0; |
||||||
|
this.APPSTORE = 2; |
||||||
|
this.TEAM_N_AUTH = 3; |
||||||
|
this.PROJ_METADATA = 4; |
||||||
|
this.ROLE_VIEW = 5; |
||||||
|
this.ROLE_VIEW_EDITOR = 6; |
||||||
|
this.ROLE_VIEW_COMMENTER = 7; |
||||||
|
this.ROLE_VIEW_VIEWER = 8; |
||||||
|
this.ROLE_VIEW_RESET = 9; |
||||||
|
|
||||||
|
this.roleURL = {}; |
||||||
|
} |
||||||
|
|
||||||
|
toolBarTopLeft(toolBarItem) { |
||||||
|
return cy |
||||||
|
.get("header.v-toolbar", { timeout: 20000 }) |
||||||
|
.eq(0) |
||||||
|
.find("a") |
||||||
|
.eq(toolBarItem); |
||||||
|
} |
||||||
|
|
||||||
|
toolBarTopRight(toolBarItem) { |
||||||
|
return cy |
||||||
|
.get("header.v-toolbar", { timeout: 20000 }) |
||||||
|
.eq(0) |
||||||
|
.find("button") |
||||||
|
.eq(toolBarItem); |
||||||
|
} |
||||||
|
|
||||||
|
navigationDraw(item) { |
||||||
|
// open settings tab
|
||||||
|
cy.get('.nc-project-menu').should('exist').click() |
||||||
|
cy.getActiveMenu().find(`[data-menu-id="teamAndSettings"]`).should('exist').click() |
||||||
|
|
||||||
|
switch (item) { |
||||||
|
case this.AUDIT: |
||||||
|
return cy.get(".nc-settings-audit:visible").should("exist"); |
||||||
|
case this.APPSTORE: |
||||||
|
return cy.get(".nc-settings-appstore:visible").should("exist"); |
||||||
|
case this.TEAM_N_AUTH: |
||||||
|
return cy.get(".nc-settings-teamauth:visible").should("exist"); |
||||||
|
case this.PROJ_METADATA: |
||||||
|
return cy.get(".nc-settings-projmeta:visible").should("exist"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// add new user to specified role
|
||||||
|
//
|
||||||
|
addNewUserToProject = (userCred, roleType) => { |
||||||
|
let linkText; |
||||||
|
let roleIndex = ["creator", "editor", "commenter", "viewer"].indexOf(roleType) |
||||||
|
|
||||||
|
// click on New User button, feed details
|
||||||
|
cy.get('button.nc-invite-team').click(); |
||||||
|
|
||||||
|
cy.get('input[placeholder="E-mail"]') |
||||||
|
.type(userCred.username) |
||||||
|
|
||||||
|
cy.get('.ant-select.nc-user-roles').click(); |
||||||
|
|
||||||
|
// opt-in requested role & submit
|
||||||
|
// cy.getActiveSelection().contains(roleType).click({force: true});
|
||||||
|
cy.getActiveSelection().find('.nc-role-option').eq(roleIndex).should('exist').click() |
||||||
|
cy.getActiveModal().find("button.ant-btn-primary").click(); |
||||||
|
|
||||||
|
cy.toastWait("Successfully updated the user details"); |
||||||
|
|
||||||
|
// get URL, invoke
|
||||||
|
cy.getActiveModal() |
||||||
|
.find(".ant-alert-message") |
||||||
|
.then(($obj) => { |
||||||
|
linkText = $obj.text().trim(); |
||||||
|
cy.log(linkText); |
||||||
|
this.roleURL[roleType] = linkText; |
||||||
|
|
||||||
|
cy.get("body").click("right"); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
addExistingUserToProject = (emailId, role) => { |
||||||
|
cy.get('.v-list-item:contains("Team & Auth")').click(); |
||||||
|
cy.get(`tr:contains(${emailId})`) |
||||||
|
.find(".mdi-plus", { timeout: 2000 }) |
||||||
|
.click(); |
||||||
|
cy.get(`tr:contains(${emailId})`) |
||||||
|
.find(".mdi-pencil-outline", { timeout: 2000 }) |
||||||
|
.click(); |
||||||
|
|
||||||
|
cy.get("label:contains(Select User Role)").click(); |
||||||
|
|
||||||
|
// opt-in requested role & submit
|
||||||
|
//
|
||||||
|
cy.getActiveMenu().contains(role).click(); |
||||||
|
cy.get(".nc-invite-or-save-btn").click(); |
||||||
|
cy.toastWait("Successfully updated the user details"); |
||||||
|
|
||||||
|
this.roleURL[role] = |
||||||
|
"http://localhost:3000/#/user/authentication/signin"; |
||||||
|
}; |
||||||
|
|
||||||
|
getCell = (columnHeader, cellNumber) => { |
||||||
|
return cy.get( |
||||||
|
`:nth-child(${cellNumber}) > [data-title="${columnHeader}"]` |
||||||
|
).last(); |
||||||
|
}; |
||||||
|
|
||||||
|
getPagination = (pageNumber) => { |
||||||
|
if (pageNumber == "<") |
||||||
|
return cy.get(".nc-pagination > .ant-pagination-prev"); |
||||||
|
if (pageNumber == ">") |
||||||
|
return cy.get(".nc-pagination > .ant-pagination-next"); |
||||||
|
|
||||||
|
return cy.get( |
||||||
|
`.nc-pagination > .ant-pagination-item.ant-pagination-item-${pageNumber}` |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
getRow = (rowIndex) => { |
||||||
|
return cy.get(".xc-row-table").find("tr").eq(rowIndex); |
||||||
|
}; |
||||||
|
|
||||||
|
addColumn = (colName, tableName) => { |
||||||
|
cy.get(".nc-column-add").click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
|
||||||
|
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 }) |
||||||
|
.should('exist') |
||||||
|
.clear() |
||||||
|
.type(colName); |
||||||
|
cy.get(".ant-btn-primary").contains("Save").should('exist').click(); |
||||||
|
cy.toastWait(`Column created`); |
||||||
|
cy.get(`th[data-title="${colName}"]`).should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
addColumnWithType = (colName, colType, tableName) => { |
||||||
|
cy.get(".nc-column-add").click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
|
||||||
|
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 }) |
||||||
|
.should('exist') |
||||||
|
.clear() |
||||||
|
.type(colName); |
||||||
|
|
||||||
|
// change column type and verify
|
||||||
|
cy.get(".nc-column-type-input").last().click(); |
||||||
|
cy.getActiveSelection().find('.ant-select-item-option').contains(colType).click(); |
||||||
|
cy.get(".ant-btn-primary:visible").contains("Save").click(); |
||||||
|
|
||||||
|
cy.toastWait(`Column created`); |
||||||
|
cy.get(`th[data-title="${colName}"]`).should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
deleteColumn = (colName) => { |
||||||
|
cy.get(`th:contains(${colName})`).should("exist"); |
||||||
|
|
||||||
|
cy.get(`th:contains(${colName}) .nc-icon.ant-dropdown-trigger`) |
||||||
|
.trigger("mouseover", { force: true }) |
||||||
|
.click({ force: true }); |
||||||
|
|
||||||
|
cy.get(".nc-column-delete").click(); |
||||||
|
cy.get(".nc-column-delete").should("not.be.visible"); |
||||||
|
cy.get(".ant-btn-dangerous:visible").contains("Delete").click(); |
||||||
|
|
||||||
|
cy.get(`th:contains(${colName})`).should("not.exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
getAuthToken = () => { |
||||||
|
let obj = JSON.parse(localStorage["vuex"]); |
||||||
|
return obj["users"]["token"]; |
||||||
|
}; |
||||||
|
|
||||||
|
configureSMTP = (from, host, port, secure) => { |
||||||
|
cy.getActiveModal().find('.nc-app-store-card-SMTP').click().then((obj) => { |
||||||
|
cy.wrap(obj).find('.nc-app-store-card-install').click({ force: true }); |
||||||
|
}) |
||||||
|
|
||||||
|
cy.getActiveModal().find('#form_item_from').should('exist').clear().type(from) |
||||||
|
cy.getActiveModal().find('#form_item_host').should('exist').clear().type(host) |
||||||
|
cy.getActiveModal().find('#form_item_port').should('exist').clear().type(port) |
||||||
|
cy.getActiveModal().find('#form_item_secure').should('exist').clear().type(secure) |
||||||
|
cy.getActiveModal().find("button").contains("Save").click(); |
||||||
|
|
||||||
|
cy.toastWait('Successfully installed and email notification will use SMTP configuration'); |
||||||
|
}; |
||||||
|
|
||||||
|
resetSMTP = () => { |
||||||
|
cy.getActiveModal().find('.nc-app-store-card-SMTP').click().then((obj) => { |
||||||
|
cy.wrap(obj).find('.nc-app-store-card-reset').click({ force: true }); |
||||||
|
}) |
||||||
|
cy.getActiveModal().find("button").contains("Confirm").click(); |
||||||
|
|
||||||
|
cy.toastWait("Plugin uninstalled successfully"); |
||||||
|
}; |
||||||
|
|
||||||
|
shareView = () => { |
||||||
|
return cy.get(".nc-btn-share-view").should("exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
shareViewList = () => { |
||||||
|
cy.get(".nc-actions-menu-btn").click(); |
||||||
|
return cy.getActiveMenu().find('.nc-menu-item').contains('Shared View List'); |
||||||
|
}; |
||||||
|
|
||||||
|
downloadCsv = () => { |
||||||
|
cy.get(".nc-actions-menu-btn").click(); |
||||||
|
return cy.getActiveMenu().find('.nc-menu-item').contains('Download as CSV'); |
||||||
|
}; |
||||||
|
|
||||||
|
downloadExcel = () => { |
||||||
|
cy.get(".nc-actions-menu-btn").click(); |
||||||
|
return cy.getActiveMenu().find('.nc-menu-item').contains('Download as XLSX'); |
||||||
|
}; |
||||||
|
|
||||||
|
uploadCsv = () => { |
||||||
|
cy.get(".nc-actions-menu-btn").click(); |
||||||
|
return cy.getActiveMenu().find('.nc-menu-item').contains('Upload CSV'); |
||||||
|
}; |
||||||
|
|
||||||
|
automations = () => { |
||||||
|
cy.get(".nc-actions-menu-btn").click(); |
||||||
|
return cy.getActiveMenu().find('.nc-menu-item').contains('Webhooks'); |
||||||
|
}; |
||||||
|
|
||||||
|
hideField = (field) => { |
||||||
|
cy.get(`th[data-title="${field}"]`).should("be.visible"); |
||||||
|
cy.get(".nc-fields-menu-btn").click(); |
||||||
|
cy.getActiveMenu().find(`.nc-fields-list label:contains(${field}):visible`).click(); |
||||||
|
cy.get(".nc-fields-menu-btn").click(); |
||||||
|
cy.get(`th[data-title="${field}"]`).should("not.exist"); |
||||||
|
}; |
||||||
|
|
||||||
|
unhideField = (field) => { |
||||||
|
cy.get(`th[data-title="${field}"]`).should("not.exist"); |
||||||
|
cy.get(".nc-fields-menu-btn").click(); |
||||||
|
cy.getActiveMenu().find(`.nc-fields-list label:contains(${field}):visible`).click(); |
||||||
|
cy.get(".nc-fields-menu-btn").click(); |
||||||
|
cy.get(`th[data-title="${field}"]`).should("be.visible"); |
||||||
|
}; |
||||||
|
|
||||||
|
sortField = (field, criteria) => { |
||||||
|
cy.get(".nc-sort-menu-btn").click(); |
||||||
|
cy.getActiveMenu().contains("Add Sort Option").click(); |
||||||
|
// cy.get(".nc-sort-field-select div").first().click().type(field);
|
||||||
|
cy.get(".nc-sort-field-select div").first().click(); |
||||||
|
cy.get('.ant-select-dropdown:visible').find(`.ant-select-item`).contains(new RegExp("^" + field + "$", "g")).should('exist').click(); |
||||||
|
cy.get(".nc-sort-dir-select div").first().click(); |
||||||
|
cy.get('.ant-select-dropdown:visible').find(`.ant-select-item`).contains(criteria).should('exist').click(); |
||||||
|
cy.get(".nc-sort-menu-btn").click(); |
||||||
|
}; |
||||||
|
|
||||||
|
clearSort = () => { |
||||||
|
cy.get(".nc-sort-menu-btn").click(); |
||||||
|
cy.wait(1000) |
||||||
|
cy.get(".nc-sort-item-remove-btn").click(); |
||||||
|
cy.wait(1000) |
||||||
|
cy.get(".nc-sort-item-remove-btn:visible").should("not.exist"); |
||||||
|
cy.get(".nc-sort-menu-btn").click(); |
||||||
|
}; |
||||||
|
|
||||||
|
filterField = (field, operation, value) => { |
||||||
|
cy.get(".nc-filter-menu-btn").click(); |
||||||
|
cy.contains("Add Filter").click(); |
||||||
|
// cy.get(".nc-filter-field-select").should("exist").last().click().type(field);
|
||||||
|
cy.get(".nc-filter-field-select").should("exist").last().click(); |
||||||
|
cy.get('.ant-select-dropdown:visible').should('exist').find(`.ant-select-item`).contains(new RegExp("^" + field + "$", "g")).should('exist').click(); |
||||||
|
cy.wait(1000); |
||||||
|
cy.get(".nc-filter-operation-select").should("exist").last().click(); |
||||||
|
cy.get('.ant-select-dropdown:visible').should('exist').find(`.ant-select-item`).contains(operation).should('exist').click(); |
||||||
|
if (operation != "is null" && operation != "is not null") { |
||||||
|
cy.get(".nc-filter-value-select") |
||||||
|
.should("exist") |
||||||
|
.last() |
||||||
|
.type(value); |
||||||
|
cy.get(".nc-filter-operation-select").last().click(); |
||||||
|
} |
||||||
|
cy.get(".nc-filter-menu-btn").click(); |
||||||
|
}; |
||||||
|
|
||||||
|
filterReset = () => { |
||||||
|
cy.get(".nc-filter-menu-btn").click(); |
||||||
|
cy.get(".nc-filter-item-remove-btn").click(); |
||||||
|
cy.get(".nc-filter-item-remove-btn").should("not.exist"); |
||||||
|
cy.get(".nc-filter-menu-btn").click(); |
||||||
|
}; |
||||||
|
|
||||||
|
// delete created views
|
||||||
|
//
|
||||||
|
deleteCreatedViews = () => { |
||||||
|
this.shareViewList().click(); |
||||||
|
|
||||||
|
cy.get('th:contains("View Link")') |
||||||
|
.should("be.visible") |
||||||
|
.parent() |
||||||
|
.parent() |
||||||
|
.next() |
||||||
|
.find("tr") |
||||||
|
.each(($tableRow) => { |
||||||
|
cy.log($tableRow[0].childElementCount); |
||||||
|
|
||||||
|
// one of the row would contain seggregation header ('other views)
|
||||||
|
if (5 == $tableRow[0].childElementCount) { |
||||||
|
cy.wrap($tableRow).find(".nc-icon").last().click(); |
||||||
|
cy.wait(1000); |
||||||
|
} |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
cy.toastWait("Deleted shared view successfully"); |
||||||
|
cy.getActiveModal().find("button.ant-modal-close").should('exist').click(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// download CSV & verify
|
||||||
|
// download folder is configurable in cypress.
|
||||||
|
// trigger download
|
||||||
|
// wait for a while & check in configured download folder for the intended file
|
||||||
|
// if it exists, verify it against 'expectedRecords' passed in as parameter
|
||||||
|
//
|
||||||
|
downloadAndVerifyCsv = (filename, verifyCsv) => { |
||||||
|
cy.get(".nc-actions-menu-btn").click(); |
||||||
|
cy.getActiveMenu().find('.nc-project-menu-item').contains('Download').click(); |
||||||
|
cy.wait(1000); |
||||||
|
cy.get('.nc-project-menu-item').contains('Download as CSV').should('exist').click(); |
||||||
|
|
||||||
|
cy.toastWait("Successfully exported all table data").then(() => { |
||||||
|
// download folder path, read from config file
|
||||||
|
const downloadsFolder = Cypress.config("downloadsFolder"); |
||||||
|
let filePath = path.join(downloadsFolder, filename); |
||||||
|
|
||||||
|
// append download folder path with filename to generate full file path, retrieve file
|
||||||
|
cy.readFile(filePath).then((fileData) => { |
||||||
|
// from CSV, split into records (rows)
|
||||||
|
const rows = fileData.replace(/\r\n/g, "\n").split("\n"); |
||||||
|
verifyCsv(rows); |
||||||
|
deleteDownloadsFolder(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
getIFrameCell = (columnHeader, cellNumber) => { |
||||||
|
return cy |
||||||
|
.iframe() |
||||||
|
.find( |
||||||
|
`tbody > :nth-child(${cellNumber}) > [data-col="${columnHeader}"]` |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
// https://docs.cypress.io/guides/core-concepts/variables-and-aliases#Sharing-Context
|
||||||
|
getDatatype = (tableName, columnName) => { |
||||||
|
cy.window().then((win) => { |
||||||
|
const col = win.$nuxt.$store.state.meta.metas[tableName].columns; |
||||||
|
let dataType = ""; |
||||||
|
col.forEach((element) => { |
||||||
|
if (element.cn == columnName) dataType = element.uidt; |
||||||
|
}); |
||||||
|
cy.wrap(dataType).as("ncDatatype"); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
openMetaTab() { |
||||||
|
// open Project metadata tab
|
||||||
|
//
|
||||||
|
settingsPage.openMenu(settingsPage.PROJ_METADATA) |
||||||
|
settingsPage.openTab(settingsPage.METADATA) |
||||||
|
} |
||||||
|
|
||||||
|
closeMetaTab() { |
||||||
|
// close Project metadata tab
|
||||||
|
settingsPage.closeMenu() |
||||||
|
} |
||||||
|
|
||||||
|
metaSyncValidate(tbl, msg) { |
||||||
|
cy.get(".nc-btn-metasync-reload") |
||||||
|
.should("exist") |
||||||
|
.click({ force: true }); |
||||||
|
cy.get(`.nc-metasync-row-${tbl}`).contains(msg).should("exist"); |
||||||
|
cy.get(".nc-btn-metasync-sync-now") |
||||||
|
.should("exist") |
||||||
|
.click({ force: true }) |
||||||
|
.then(() => { |
||||||
|
cy.toastWait(`Table metadata recreated successfully`); |
||||||
|
}); |
||||||
|
cy.get(".nc-metasync-row").then((row) => { |
||||||
|
for (let i = 0; i < row.length; i++) { |
||||||
|
cy.wrap(row).contains("No change identified").should("exist"); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
tabReset() { |
||||||
|
// temporary disable (kludge)
|
||||||
|
// mainPage.toolBarTopLeft(mainPage.HOME).click({ force: true });
|
||||||
|
// cy.get(".project-row").should("exist").click({ force: true });
|
||||||
|
// projectsPage.waitHomePageLoad();
|
||||||
|
// option-2
|
||||||
|
// cy.openTableTab("Country", 0);
|
||||||
|
// cy.get(".mdi-close").click({ multiple: true });
|
||||||
|
// cy.get("button.ant-tabs-tab-remove").click({ multiple: true });
|
||||||
|
// cy.get('.ant-tabs-tab-remove').should('not.exist')
|
||||||
|
} |
||||||
|
|
||||||
|
toggleRightSidebar() { |
||||||
|
cy.get(".nc-right-sidebar-toggle").should("exist").click(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export const mainPage = new _mainPage(); |
||||||
|
export const settingsPage = new _settingsPage(); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,289 @@ |
|||||||
|
import { roles, staticProjects, defaultDbParams } from "./projectConstants"; |
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// Sign in/ Sign up page
|
||||||
|
|
||||||
|
// list of hard-wired URL that can be used by nocodb
|
||||||
|
// suffix to baseUrl needs to be defined here
|
||||||
|
//
|
||||||
|
const urlPool = { |
||||||
|
ncUrlBase: "/", |
||||||
|
ncUrlSignUp: "/signup", |
||||||
|
ncUrlSignIn: "/signin", |
||||||
|
}; |
||||||
|
|
||||||
|
export class _loginPage { |
||||||
|
// prefix: baseUrl
|
||||||
|
go(urlKey) { |
||||||
|
cy.visit(urlKey); |
||||||
|
} |
||||||
|
|
||||||
|
// visit SignIn URL, enter credentials passed as parameters
|
||||||
|
//
|
||||||
|
signIn(userCredentials) { |
||||||
|
this.go(urlPool.ncUrlSignIn); |
||||||
|
|
||||||
|
cy.get('input[type="text"]', { timeout: 20000 }).type( |
||||||
|
userCredentials.username |
||||||
|
); |
||||||
|
cy.get('input[type="password"]').type(userCredentials.password); |
||||||
|
cy.get('button:contains("SIGN IN")').click(); |
||||||
|
|
||||||
|
this.waitProjectPageLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
// visit SignUp URL, enter credentials passed as parameters
|
||||||
|
//
|
||||||
|
signUp(userCredentials) { |
||||||
|
this.go(urlPool.ncUrlSignUp); |
||||||
|
|
||||||
|
cy.get('input[type="text"]', { timeout: 20000 }).type( |
||||||
|
userCredentials.username |
||||||
|
); |
||||||
|
cy.get('input[type="password"]').type(userCredentials.password); |
||||||
|
cy.get('button:contains("SIGN UP")').click(); |
||||||
|
|
||||||
|
this.waitProjectPageLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
// logout signed up user
|
||||||
|
//
|
||||||
|
signOut() { |
||||||
|
cy.get(".nc-user-menu").click(); |
||||||
|
cy.get(".nc-user-menu-signout").click(); |
||||||
|
|
||||||
|
this.waitLoginPageLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
// delay/ wait utility routines
|
||||||
|
//
|
||||||
|
waitProjectPageLoad() { |
||||||
|
cy.get(".nc-new-project-menu").should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
waitLoginPageLoad() { |
||||||
|
cy.get(".nc-form-signin").should("exist"); |
||||||
|
} |
||||||
|
|
||||||
|
// standard pre-project activity
|
||||||
|
//
|
||||||
|
loginAndOpenProject(apiType, dbType) { |
||||||
|
loginPage.signIn(roles.owner.credentials); |
||||||
|
|
||||||
|
if (dbType === "mysql") { |
||||||
|
projectsPage.openProject(staticProjects.externalREST.basic.name); |
||||||
|
} else if (dbType === "xcdb") { |
||||||
|
projectsPage.openProject(staticProjects.sampleREST.basic.name); |
||||||
|
} else if (dbType === "postgres") { |
||||||
|
projectsPage.openProject(staticProjects.pgExternalREST.basic.name); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// Projects page
|
||||||
|
|
||||||
|
export class _projectsPage { |
||||||
|
// Project creation options
|
||||||
|
//
|
||||||
|
|
||||||
|
// {dbType, apiType, name}
|
||||||
|
// for external database, {databaseType, hostAddress, portNumber, username, password, databaseName}
|
||||||
|
|
||||||
|
// Open existing project
|
||||||
|
//
|
||||||
|
openProject(projectName) { |
||||||
|
cy.get(".ant-table-row").contains(`${projectName}`).should("exist").click(); |
||||||
|
|
||||||
|
// takes a while to load project
|
||||||
|
this.waitHomePageLoad(); |
||||||
|
} |
||||||
|
|
||||||
|
// Create new project
|
||||||
|
// Input:
|
||||||
|
// projectData {dbType, apiType, name}
|
||||||
|
// dbCredentials {databaseType, hostAddress, portNumber, username, password, databaseName}
|
||||||
|
// Returns: projectName
|
||||||
|
//
|
||||||
|
// To configure
|
||||||
|
// SSL & advanced parameters
|
||||||
|
// Database type selection
|
||||||
|
//
|
||||||
|
createProject(projectData, cred) { |
||||||
|
cy.get("body", { timeout: 2000 }); |
||||||
|
|
||||||
|
let projectName = projectData.name; |
||||||
|
if (projectData.name == "") projectName = "test_proj" + Date.now(); |
||||||
|
|
||||||
|
// click on "New Project"
|
||||||
|
cy.get(".nc-new-project-menu").should("exist").click(); |
||||||
|
|
||||||
|
if ("none" == projectData.dbType) { |
||||||
|
// Subsequent form, select (+ Create) option
|
||||||
|
cy.get(".nc-create-xc-db-project", { timeout: 20000 }).last().click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
|
||||||
|
// wait for page load by verifying required elements
|
||||||
|
cy.get(".nc-metadb-project-name").should("exist"); |
||||||
|
cy.contains("button", "Create").should("exist"); |
||||||
|
|
||||||
|
// feed project name
|
||||||
|
cy.get(".nc-metadb-project-name", { timeout: 20000 }).clear().type( |
||||||
|
projectName |
||||||
|
); |
||||||
|
|
||||||
|
// Submit
|
||||||
|
cy.contains("button", "Create", { timeout: 20000 }).click(); |
||||||
|
|
||||||
|
// takes a while to load project
|
||||||
|
this.waitHomePageLoad(); |
||||||
|
|
||||||
|
return projectName; |
||||||
|
} |
||||||
|
|
||||||
|
// dbType == 'external'
|
||||||
|
else { |
||||||
|
// Subsequent form, select (+ Create by connection to external database) option
|
||||||
|
cy.get(".nc-create-external-db-project", { timeout: 20000 }).last().click({ |
||||||
|
force: true, |
||||||
|
}); |
||||||
|
|
||||||
|
// wait for page load by verifying required elements
|
||||||
|
cy.get('.nc-extdb-host-database').should('exist'); |
||||||
|
cy.get('.nc-extdb-proj-name').should('exist'); |
||||||
|
cy.get('.nc-extdb-btn-test-connection').should('exist'); |
||||||
|
|
||||||
|
// CY goes too fast at times, so wait for the page to load
|
||||||
|
cy.wait(1000); |
||||||
|
|
||||||
|
cy.get('.nc-extdb-proj-name').clear().type(projectName); |
||||||
|
|
||||||
|
if (cred.databaseType === 1) { |
||||||
|
cy.get('.nc-extdb-db-type').select('PostgreSQL'); |
||||||
|
} |
||||||
|
|
||||||
|
if (cred.databaseName !== "") { |
||||||
|
cy.get('.nc-extdb-host-database').clear().type(cred.databaseName); |
||||||
|
} |
||||||
|
|
||||||
|
// Test database connection
|
||||||
|
cy.contains("Test Database Connection", { timeout: 20000 }).click(); |
||||||
|
|
||||||
|
// Create project
|
||||||
|
cy.contains("Ok & Save Project", { timeout: 20000 }).click(); |
||||||
|
|
||||||
|
// takes a while to load project
|
||||||
|
this.waitHomePageLoad(); |
||||||
|
|
||||||
|
return projectName; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// // create REST default project (sakila DB)
|
||||||
|
// //
|
||||||
|
// createDefaulRestProject() {
|
||||||
|
// return this.createProject(
|
||||||
|
// { dbType: 1, apiType: 0, name: "" },
|
||||||
|
// defaultDbParams
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // search project with given key
|
||||||
|
// // return project-name array
|
||||||
|
// //
|
||||||
|
// searchProject(projectNameKey) {
|
||||||
|
// cy.get('input[placeholder="Search Project"]').type(projectNameKey);
|
||||||
|
//
|
||||||
|
// const projectName = [];
|
||||||
|
//
|
||||||
|
// cy.get("table tr")
|
||||||
|
// .each((tableRow) => {
|
||||||
|
// cy.wrap(tableRow)
|
||||||
|
// .find("td")
|
||||||
|
// .eq(0)
|
||||||
|
// .find(".title")
|
||||||
|
// .then((input) => {
|
||||||
|
// projectName.push(input.text());
|
||||||
|
// });
|
||||||
|
// })
|
||||||
|
// .then(() => {
|
||||||
|
// // TBD: validate project name to contain search key
|
||||||
|
// console.log(projectName);
|
||||||
|
// return projectName;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// remove specified project entry
|
||||||
|
//
|
||||||
|
deleteProject(projectName) { |
||||||
|
cy.log("Delete project: " + projectName); |
||||||
|
cy.get(".nc-noco-brand-icon").should('exist').click(); |
||||||
|
cy.get(".ant-table-row").contains(`${projectName}`).should("exist") |
||||||
|
.then(($obj) => { |
||||||
|
cy.log($obj) |
||||||
|
cy.wrap($obj).parent().parent().find('.ant-table-cell').last().click() |
||||||
|
}) |
||||||
|
|
||||||
|
// pop-up, submit
|
||||||
|
cy.getActiveModal().find('button:contains("Yes")').click({}); |
||||||
|
} |
||||||
|
|
||||||
|
// remove all projects created
|
||||||
|
//
|
||||||
|
// 1. read all project names to be deleted, store in array
|
||||||
|
// 2. invoke delete project for each entry in array
|
||||||
|
//
|
||||||
|
// deleteAllProject() {
|
||||||
|
|
||||||
|
// const projectName = []
|
||||||
|
|
||||||
|
// cy.get('table tr').each((tableRow) => {
|
||||||
|
|
||||||
|
// cy.wrap(tableRow).find('td').eq(0).find('.title').then((input) => {
|
||||||
|
// projectName.push(input.text())
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// .then(() => {
|
||||||
|
// console.log(projectName)
|
||||||
|
// projectName.forEach(element => {
|
||||||
|
|
||||||
|
// // bring back the DOM to normalcy
|
||||||
|
// cy.get('div').parentsUntil('body')
|
||||||
|
// this.deleteProject(element)
|
||||||
|
|
||||||
|
// // wait needed for pop up to disapper
|
||||||
|
// this.waitDeletePageLoad()
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
waitHomePageLoad() { |
||||||
|
// cy.url({ timeout: 50000 }).should("contain", "&dbalias=");
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export const loginPage = new _loginPage(); |
||||||
|
export const projectsPage = new _projectsPage(); |
||||||
|
|
||||||
|
/** |
||||||
|
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||||
|
* |
||||||
|
* @author Raju Udava <sivadstala@gmail.com> |
||||||
|
* |
||||||
|
* @license GNU AGPL version 3 or any later version |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
@ -0,0 +1,158 @@ |
|||||||
|
export const defaultDbParams = { |
||||||
|
databaseType: 0, // MySQL
|
||||||
|
hostAddress: "localhost", |
||||||
|
portNumber: "3306", |
||||||
|
username: "root", |
||||||
|
password: "password", |
||||||
|
databaseName: "sakila", |
||||||
|
}; |
||||||
|
|
||||||
|
export const defaultPgDbParams = { |
||||||
|
databaseType: 1, // Postgres
|
||||||
|
hostAddress: "localhost", |
||||||
|
portNumber: "5432", |
||||||
|
username: "postgres", |
||||||
|
password: "password", |
||||||
|
databaseName: "postgres", |
||||||
|
}; |
||||||
|
|
||||||
|
// database
|
||||||
|
// validation details
|
||||||
|
// advSettings: left navigation bar (audit, metadata, auth, transient view modes)
|
||||||
|
// editSchema: create table, add/update/delete column
|
||||||
|
// editData: add/ update/ delete row, cell contents
|
||||||
|
// editComment: add comment
|
||||||
|
// shareView: right navigation bar (share options)
|
||||||
|
export const roles = { |
||||||
|
owner: { |
||||||
|
name: "owner", |
||||||
|
credentials: { username: "user@nocodb.com", password: "Password123." }, |
||||||
|
validations: { |
||||||
|
advSettings: true, |
||||||
|
editSchema: true, |
||||||
|
editData: true, |
||||||
|
editComment: true, |
||||||
|
shareView: true, |
||||||
|
}, |
||||||
|
}, |
||||||
|
creator: { |
||||||
|
name: "creator", |
||||||
|
credentials: { |
||||||
|
username: "creator@nocodb.com", |
||||||
|
password: "Password123.", |
||||||
|
}, |
||||||
|
validations: { |
||||||
|
advSettings: true, |
||||||
|
editSchema: true, |
||||||
|
editData: true, |
||||||
|
editComment: true, |
||||||
|
shareView: true, |
||||||
|
}, |
||||||
|
}, |
||||||
|
editor: { |
||||||
|
name: "editor", |
||||||
|
credentials: { |
||||||
|
username: "editor@nocodb.com", |
||||||
|
password: "Password123.", |
||||||
|
}, |
||||||
|
validations: { |
||||||
|
advSettings: false, |
||||||
|
editSchema: false, |
||||||
|
editData: true, |
||||||
|
editComment: true, |
||||||
|
shareView: false, |
||||||
|
}, |
||||||
|
}, |
||||||
|
commenter: { |
||||||
|
name: "commenter", |
||||||
|
credentials: { |
||||||
|
username: "commenter@nocodb.com", |
||||||
|
password: "Password123.", |
||||||
|
}, |
||||||
|
validations: { |
||||||
|
advSettings: false, |
||||||
|
editSchema: false, |
||||||
|
editData: false, |
||||||
|
editComment: true, |
||||||
|
shareView: false, |
||||||
|
}, |
||||||
|
}, |
||||||
|
viewer: { |
||||||
|
name: "viewer", |
||||||
|
credentials: { |
||||||
|
username: "viewer@nocodb.com", |
||||||
|
password: "Password123.", |
||||||
|
}, |
||||||
|
validations: { |
||||||
|
advSettings: false, |
||||||
|
editSchema: false, |
||||||
|
editData: false, |
||||||
|
editComment: false, |
||||||
|
shareView: false, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
// default projects
|
||||||
|
//
|
||||||
|
export const staticProjects = { |
||||||
|
sampleREST: { |
||||||
|
basic: { dbType: "none", apiType: "REST", name: "sampleREST" }, |
||||||
|
config: {}, |
||||||
|
}, |
||||||
|
sampleGQL: { |
||||||
|
basic: { dbType: "none", apiType: "GQL", name: "sampleGQL" }, |
||||||
|
config: {}, |
||||||
|
}, |
||||||
|
externalREST: { |
||||||
|
basic: { dbType: "external", apiType: "REST", name: "externalREST" }, |
||||||
|
config: defaultDbParams, |
||||||
|
}, |
||||||
|
externalGQL: { |
||||||
|
basic: { dbType: "external", apiType: "GQL", name: "externalGQL" }, |
||||||
|
config: defaultDbParams, |
||||||
|
}, |
||||||
|
pgExternalREST: { |
||||||
|
basic: { dbType: "external", apiType: "REST", name: "pgExternalREST" }, |
||||||
|
config: defaultPgDbParams, |
||||||
|
}, |
||||||
|
pgExternalGQL: { |
||||||
|
basic: { dbType: "external", apiType: "GQL", name: "pgExternalGQL" }, |
||||||
|
config: defaultPgDbParams, |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
// return TRUE if test suite specified is activated from env-variables
|
||||||
|
//
|
||||||
|
export const isTestSuiteActive = (apiType, dbType) => { |
||||||
|
const env = Cypress.env("testMode"); |
||||||
|
return env.some( |
||||||
|
(element) => element.apiType === apiType && element.dbType === dbType |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
let currentTestMode = { apiType: null, dbType: null }; |
||||||
|
let xcdbProjectString = ``; |
||||||
|
export function setCurrentMode(apiType, dbType) { |
||||||
|
currentTestMode = { apiType: apiType, dbType: dbType }; |
||||||
|
} |
||||||
|
|
||||||
|
export function getCurrentMode() { |
||||||
|
return currentTestMode; |
||||||
|
} |
||||||
|
|
||||||
|
export function isXcdb() { |
||||||
|
return currentTestMode.dbType === "xcdb"; |
||||||
|
} |
||||||
|
|
||||||
|
export function isPostgres() { |
||||||
|
return currentTestMode.dbType === "postgres"; |
||||||
|
} |
||||||
|
|
||||||
|
export function setProjectString(projStr) { |
||||||
|
xcdbProjectString = projStr; |
||||||
|
} |
||||||
|
|
||||||
|
export function getProjectString() { |
||||||
|
return xcdbProjectString; |
||||||
|
} |
Loading…
Reference in new issue