fix: release script, excel upload duplicate primary keys, cypress fix
This commit is contained in:
parent
d88ab8bf58
commit
2f79487aea
@ -16,10 +16,9 @@ jobs:
|
||||
node-version: 18
|
||||
|
||||
- name: Write .npmrc file
|
||||
run: echo "$NPMRC" > client/.npmrc
|
||||
shell: bash
|
||||
env:
|
||||
NPMRC: ${{ secrets.NPMRC}}
|
||||
run: |
|
||||
touch client/.npmrc
|
||||
echo '${{ secrets.NPMRC}}' > client/.npmrc
|
||||
|
||||
- run: apt-get update
|
||||
- run: wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
|
||||
@ -28,17 +27,13 @@ jobs:
|
||||
- run: apt-get update -y
|
||||
- run: apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
|
||||
- run: apt -y install jq
|
||||
# - run: 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
|
||||
# - run: eval $(ssh-agent -s)
|
||||
# - run: echo "$ssh_key" | tr -d '\r' | ssh-add -
|
||||
|
||||
- name: Write cypress credentials
|
||||
run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json
|
||||
shell: bash
|
||||
env:
|
||||
CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }}
|
||||
|
||||
# - run: mkdir -p ~/.ssh
|
||||
# - run: chmod 700 ~/.ssh
|
||||
- run: npm ci
|
||||
# Install pm2 and prepare SASJS server
|
||||
- run: npm i -g pm2
|
||||
@ -49,12 +44,7 @@ jobs:
|
||||
- run: echo NODE_PATH=node >> .env
|
||||
- run: echo CORS=enable >> .env
|
||||
- run: echo WHITELIST=http://localhost:4200 >> .env
|
||||
# - run: echo "SERVER_URL=$server_url" >> .env
|
||||
# - run: echo "SERVER_TYPE=$server_type" >> .env
|
||||
# - run: echo "CLIENT=$client_sasjs" >> .env
|
||||
# - run: echo "ACCESS_TOKEN=$access_token_sasjs" >> .env
|
||||
# - run: echo "REFRESH_TOKEN=$refresh_token_sasjs" >> .env
|
||||
# - run: cat .env
|
||||
- run: cat .env
|
||||
- run: pm2 start api-linux --wait-ready
|
||||
|
||||
- name: Deploy mocked services
|
||||
@ -65,28 +55,27 @@ jobs:
|
||||
sasjs cbd -t server-ci
|
||||
# sasjs request services/admin/makedata -t server-ci -d ./deploy/makeData4GL.json -c ./deploy/requestConfig.json -o ./output.json
|
||||
|
||||
- name: Prepare frontend
|
||||
- name: Install ZIP
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install zip
|
||||
|
||||
- name: Prepare and run frontend and cypress
|
||||
run: |
|
||||
cd ./client
|
||||
# mv ./cypress.env.example.json ./cypress.env.json
|
||||
# replace-in-files --regex='"username".*' --replacement='"username":"'$cypress_username_sasjs'",' ./cypress.env.json
|
||||
# replace-in-files --regex='"password".*' --replacement='"password":"'$cypress_pwd_sasjs'" ' ./cypress.env.json
|
||||
mv ./cypress.env.example.json ./cypress.env.json
|
||||
replace-in-files --regex='"username".*' --replacement='"username":"'${{ secrets.CYPRESS_USERNAME_SASJS }}'",' ./cypress.env.json
|
||||
replace-in-files --regex='"password".*' --replacement='"password":"'${{ secrets.CYPRESS_PWD_SASJS }}'" ' ./cypress.env.json
|
||||
cat ./cypress.env.json
|
||||
npm run postinstall
|
||||
# Prepare index.html to SASJS local
|
||||
replace-in-files --regex='serverUrl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./src/index.html
|
||||
replace-in-files --regex='appLoc=".*?"' --replacement='appLoc="/Public/app/devtest"' ./src/index.html
|
||||
replace-in-files --regex='serverType=".*?"' --replacement='serverType="SASJS"' ./src/index.html
|
||||
# Prepare and deploy SASJS version
|
||||
# replace-in-files --regex='serverurl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./dist/index.html
|
||||
# replace-in-files --regex='apploc=".*?"' --replacement='appLoc="/30.SASApps/app/devtest"' ./dist/index.html
|
||||
# replace-in-files --regex='servertype=".*?"' --replacement='serverType="SASJS"' ./dist/index.html
|
||||
# scp -o stricthostkeychecking=no -r ./dist/* dcgitlab@sas.4gl.io:/var/www/html/dcviya/development/newadapter
|
||||
replace-in-files --regex='"hosturl".*' --replacement='hosturl:"http://localhost:4200",' ./cypress.config.ts
|
||||
# replace-in-files --regex='"appLocation".*' --replacement='appLocation:"/dcviya/development/newadapter",' ./cypress.config.ts
|
||||
cat ./cypress.config.ts
|
||||
# Start frontend and run cypress
|
||||
npm start & npx wait-on http://localhost:4200 && ./run-cypress-tests.sh
|
||||
npm start & npx wait-on http://localhost:4200 && npx cypress run --browser chrome --spec "cypress/e2e/liveness.cy.ts,cypress/e2e/editor.cy.ts,cypress/e2e/excel.cy.ts,cypress/e2e/filtering.cy.ts,cypress/e2e/licensing.cy.ts"
|
||||
|
||||
Build-and-test-development-latest-adapter:
|
||||
runs-on: ubuntu-latest
|
||||
@ -110,17 +99,13 @@ jobs:
|
||||
- run: apt-get update -y
|
||||
- run: apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
|
||||
- run: apt -y install jq
|
||||
# - run: 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
|
||||
# - run: eval $(ssh-agent -s)
|
||||
# - run: echo "$ssh_key" | tr -d '\r' | ssh-add -
|
||||
|
||||
- name: Write cypress credentials
|
||||
run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json
|
||||
shell: bash
|
||||
env:
|
||||
CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }}
|
||||
|
||||
# - run: mkdir -p ~/.ssh
|
||||
# - run: chmod 700 ~/.ssh
|
||||
- run: npm ci
|
||||
# Install pm2 and prepare SASJS server
|
||||
- run: npm i -g pm2
|
||||
@ -131,12 +116,7 @@ jobs:
|
||||
- run: echo NODE_PATH=node >> .env
|
||||
- run: echo CORS=enable >> .env
|
||||
- run: echo WHITELIST=http://localhost:4200 >> .env
|
||||
# - run: echo "SERVER_URL=$server_url" >> .env
|
||||
# - run: echo "SERVER_TYPE=$server_type" >> .env
|
||||
# - run: echo "CLIENT=$client_sasjs" >> .env
|
||||
# - run: echo "ACCESS_TOKEN=$access_token_sasjs" >> .env
|
||||
# - run: echo "REFRESH_TOKEN=$refresh_token_sasjs" >> .env
|
||||
# - run: cat .env
|
||||
- run: cat .env
|
||||
- run: pm2 start api-linux --wait-ready
|
||||
|
||||
- name: Deploy mocked services
|
||||
@ -147,12 +127,17 @@ jobs:
|
||||
sasjs cbd -t server-ci
|
||||
# sasjs request services/admin/makedata -t server-ci -d ./deploy/makeData4GL.json -c ./deploy/requestConfig.json -o ./output.json
|
||||
|
||||
- name: Prepare frontend
|
||||
- name: Install ZIP
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install zip
|
||||
|
||||
- name: Prepare and run frontend and cypress
|
||||
run: |
|
||||
cd ./client
|
||||
# mv ./cypress.env.example.json ./cypress.env.json
|
||||
# replace-in-files --regex='"username".*' --replacement='"username":"'$cypress_username_sasjs'",' ./cypress.env.json
|
||||
# replace-in-files --regex='"password".*' --replacement='"password":"'$cypress_pwd_sasjs'" ' ./cypress.env.json
|
||||
mv ./cypress.env.example.json ./cypress.env.json
|
||||
replace-in-files --regex='"username".*' --replacement='"username":"'${{ secrets.CYPRESS_USERNAME_SASJS }}'",' ./cypress.env.json
|
||||
replace-in-files --regex='"password".*' --replacement='"password":"'${{ secrets.CYPRESS_PWD_SASJS }}'" ' ./cypress.env.json
|
||||
cat ./cypress.env.json
|
||||
npm run postinstall
|
||||
npm install @sasjs/adapter@latest
|
||||
@ -160,13 +145,7 @@ jobs:
|
||||
replace-in-files --regex='serverUrl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./src/index.html
|
||||
replace-in-files --regex='appLoc=".*?"' --replacement='appLoc="/Public/app/devtest"' ./src/index.html
|
||||
replace-in-files --regex='serverType=".*?"' --replacement='serverType="SASJS"' ./src/index.html
|
||||
# Prepare and deploy SASJS version
|
||||
# replace-in-files --regex='serverurl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./dist/index.html
|
||||
# replace-in-files --regex='apploc=".*?"' --replacement='appLoc="/30.SASApps/app/devtest"' ./dist/index.html
|
||||
# replace-in-files --regex='servertype=".*?"' --replacement='serverType="SASJS"' ./dist/index.html
|
||||
# scp -o stricthostkeychecking=no -r ./dist/* dcgitlab@sas.4gl.io:/var/www/html/dcviya/development/newadapter
|
||||
replace-in-files --regex='"hosturl".*' --replacement='hosturl:"http://localhost:4200",' ./cypress.config.ts
|
||||
# replace-in-files --regex='"appLocation".*' --replacement='appLocation:"/dcviya/development/newadapter",' ./cypress.config.ts
|
||||
cat ./cypress.config.ts
|
||||
# Start frontend and run cypress
|
||||
npm start & npx wait-on http://localhost:4200 && ./run-cypress-tests.sh
|
||||
npm start & npx wait-on http://localhost:4200 && npx cypress run --browser chrome --spec "cypress/e2e/liveness.cy.ts,cypress/e2e/editor.cy.ts,cypress/e2e/excel.cy.ts,cypress/e2e/filtering.cy.ts,cypress/e2e/licensing.cy.ts"
|
@ -22,29 +22,89 @@ jobs:
|
||||
env:
|
||||
NPMRC: ${{ secrets.NPMRC}}
|
||||
|
||||
- name: Install ZIP
|
||||
- name: Install ZIP and SASjs CLI
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install zip
|
||||
npm i -g @sasjs/cli
|
||||
# test
|
||||
|
||||
- name: release-build
|
||||
- name: Install JQ for parsing JSON
|
||||
run: |
|
||||
cd client
|
||||
npm ci
|
||||
npm run build
|
||||
zip -r dist.zip ./dist
|
||||
apt-get update
|
||||
apt-get install jq
|
||||
|
||||
- name: Install Semantic Release and plugins
|
||||
- name: Install Semantic Release and plugins and create Release
|
||||
run: |
|
||||
npm i
|
||||
npm i -g semantic-release
|
||||
|
||||
- name: Release
|
||||
run: |
|
||||
GITEA_TOKEN=${{ secrets.RELEASE_TOKEN }} GITEA_URL=https://git.datacontroller.io semantic-release
|
||||
|
||||
- name: Build SAS9 EBI Release
|
||||
description: compile SAS 9 services, remove tests & create deployment program
|
||||
run: |
|
||||
cd sas
|
||||
npm ci
|
||||
sasjs c -t sas9
|
||||
rm -rf sasjsbuild/tests
|
||||
sasjs b -t sas9
|
||||
cp sasjsbuild/mysas9deploy.sas ./demostream_sas9.sas
|
||||
#
|
||||
# remove streamed component and rebuild SAS 9 services
|
||||
#
|
||||
rm -rf sasjsbuild/services/web9
|
||||
rm sasjsbuild/services/clickme.sas
|
||||
sasjs b -t sas9
|
||||
cp sasjsbuild/mysas9deploy.sas ./sas9.sas
|
||||
|
||||
- name: Build SASjs Server Release
|
||||
description: compile Base (SASjs) services, remove tests & create deployment JSON
|
||||
run: |
|
||||
cd sas
|
||||
cp sasjs/utils/favicon.ico ../client/dist/favicon.ico
|
||||
sasjs c -t server
|
||||
rm -rf sasjsbuild/tests
|
||||
sasjs b -t server
|
||||
cp sasjsbuild/server.json.zip ./sasjs_server.json.zip
|
||||
|
||||
- name: Build Viya Release
|
||||
description: compile Viya Streaming Deploy (without tests)
|
||||
run: |
|
||||
cd sas
|
||||
sasjs c -t viya
|
||||
rm -rf sasjsbuild/tests
|
||||
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/clickme.html
|
||||
sasjs b -t viya
|
||||
cp sasjsbuild/viya.sas ./demostream_viya.sas
|
||||
# compile Viya Full deploy (without web)
|
||||
rm -rf sasjsbuild/services/web
|
||||
rm sasjsbuild/services/clickme.html
|
||||
sasjs b -t viya
|
||||
cp sasjsbuild/viya.sas ./viya.sas
|
||||
|
||||
- name: Frontend Build
|
||||
run: |
|
||||
cd client
|
||||
npm ci
|
||||
# Disabled to speed up dev process
|
||||
# npm run build
|
||||
# zip -r dist.zip ./dist
|
||||
touch dist.zip
|
||||
|
||||
- name: Zip Frontend (including viya.json for full viya deploy)
|
||||
run: |
|
||||
cd sas
|
||||
cp sasjsbuild/viya.json ../client/dist
|
||||
cd ..
|
||||
zip -r frontend.zip ./client/dist
|
||||
|
||||
- name: Release Typedoc
|
||||
run: |
|
||||
cd client
|
||||
npm run typedoc
|
||||
# deploy docs
|
||||
# deploy docs
|
||||
|
||||
- name: Upload artifacts to release
|
||||
run: |
|
||||
RELEASE_ID=`curl -k 'https://git.datacontroller.io/api/v1/repos/mihajlo/dc_throwaway/releases/latest?access_token=${{ secrets.RELEASE_TOKEN }}' | jq -r '.id'`
|
||||
curl -k https://git.datacontroller.io/api/v1/repos/mihajlo/dc_throwaway/releases/$RELEASE_ID/assets?access_token=${{ secrets.RELEASE_TOKEN }} -F attachment=@frontend.zip
|
||||
|
48
.releaserc
48
.releaserc
@ -1,22 +1,44 @@
|
||||
{
|
||||
"branches": ["main"],
|
||||
"branches": [
|
||||
"main"
|
||||
],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/changelog",
|
||||
[
|
||||
"@semantic-release/git",
|
||||
{
|
||||
"assets": [
|
||||
"CHANGELOG.md"
|
||||
]
|
||||
}
|
||||
"@semantic-release/git",
|
||||
{
|
||||
"assets": [
|
||||
"CHANGELOG.md"
|
||||
]
|
||||
}
|
||||
],
|
||||
["@saithodev/semantic-release-gitea", {
|
||||
"giteaUrl": "https://git.datacontroller.io",
|
||||
"assets": [
|
||||
{"path": "client/dist.zip"}
|
||||
]
|
||||
}]
|
||||
[
|
||||
"@saithodev/semantic-release-gitea",
|
||||
{
|
||||
"giteaUrl": "https://git.datacontroller.io",
|
||||
"assets": [
|
||||
{
|
||||
"path": "sas/demostream_sas9.sas"
|
||||
},
|
||||
{
|
||||
"path": "sas/demostream_viya.sas"
|
||||
},
|
||||
{
|
||||
"path": "sas/frontend.zip"
|
||||
},
|
||||
{
|
||||
"path": "sas/sasjs_server.json.zip"
|
||||
},
|
||||
{
|
||||
"path": "sas/sas9.sas"
|
||||
},
|
||||
{
|
||||
"path": "sas/viya.sas"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
@ -1,7 +1,3 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
||||
|
||||
## [6.0.0](https://gitlab.com/macropeople/datacontroller/compare/v5.3.0...v6.0.0) (2023-06-27)
|
||||
|
||||
|
||||
|
@ -1,17 +1,20 @@
|
||||
import { defineConfig } from 'cypress'
|
||||
import { defineConfig } from "cypress";
|
||||
|
||||
export default defineConfig({
|
||||
reporter: 'mochawesome',
|
||||
reporter: "mochawesome",
|
||||
|
||||
reporterOptions: {
|
||||
reportDir: 'cypress/results',
|
||||
reportDir: "cypress/results",
|
||||
overwrite: false,
|
||||
html: true,
|
||||
json: false,
|
||||
},
|
||||
|
||||
chromeWebSecurity: false,
|
||||
defaultCommandTimeout: 30000,
|
||||
|
||||
env: {
|
||||
hosturl:"http://localhost:4200",
|
||||
hosturl: "http://localhost:4200",
|
||||
appLocation: "",
|
||||
site_id_SAS9: "70221618",
|
||||
site_id_SASVIYA: "70253615",
|
||||
@ -23,6 +26,12 @@ export default defineConfig({
|
||||
debug: false,
|
||||
screenshotOnRunFailure: false,
|
||||
longerCommandTimeout: 50000,
|
||||
testLicenceUserLimits: false
|
||||
}
|
||||
})
|
||||
testLicenceUserLimits: false,
|
||||
},
|
||||
|
||||
e2e: {
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
},
|
||||
},
|
||||
});
|
||||
|
250
client/cypress/e2e/download.cy.ts
Normal file
250
client/cypress/e2e/download.cy.ts
Normal file
@ -0,0 +1,250 @@
|
||||
const username = Cypress.env('username')
|
||||
const password = Cypress.env('password')
|
||||
const hostUrl = Cypress.env('hosturl')
|
||||
const appLocation = Cypress.env('appLocation')
|
||||
const longerCommandTimeout = Cypress.env('longerCommandTimeout')
|
||||
const serverType = Cypress.env('serverType')
|
||||
const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`)
|
||||
const downloadsFolder = Cypress.config('downloadsFolder')
|
||||
|
||||
import { deleteDownloadsFolder } from '../util/deleteDownloadFolder'
|
||||
|
||||
context('download files test: ', function () {
|
||||
this.beforeAll(() => {
|
||||
cy.visit(`${hostUrl}/SASLogon/logout`)
|
||||
cy.loginAndUpdateValidKey()
|
||||
})
|
||||
|
||||
this.beforeEach(() => {
|
||||
cy.visit(hostUrl + appLocation)
|
||||
cy.get('input.username').type(username)
|
||||
cy.get('input.password').type(password)
|
||||
cy.get('.login-group button').click()
|
||||
|
||||
visitPage('home')
|
||||
})
|
||||
|
||||
this.afterEach(() => {
|
||||
deleteDownloadsFolder()
|
||||
})
|
||||
|
||||
it('1 | downloads audit file', (done) => {
|
||||
visitPage('approve/toapprove')
|
||||
|
||||
cy.get('.app-loading', { timeout: longerCommandTimeout })
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
cy.get('.btn.btn-success')
|
||||
.should('be.visible')
|
||||
.then((buttons) => {
|
||||
buttons[0].click()
|
||||
const id = buttons[0].id
|
||||
|
||||
checkForFileDownloaded(id, 'zip', () => done())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('2 | downloads viewer csv', (done) => {
|
||||
visitPage('view/data')
|
||||
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openDownloadModal(() => {
|
||||
cy.get('select')
|
||||
.select('CSV')
|
||||
.then(() => {
|
||||
cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
|
||||
button.trigger('click')
|
||||
|
||||
const id = button[0].id
|
||||
|
||||
checkForFileDownloaded(id, 'csv', () => done())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('3 | downloads viewer excel', (done) => {
|
||||
visitPage('view/data')
|
||||
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openDownloadModal(() => {
|
||||
cy.get('select')
|
||||
.select('Excel')
|
||||
.then(() => {
|
||||
cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
|
||||
button.trigger('click')
|
||||
|
||||
const id = button[0].id
|
||||
|
||||
checkForFileDownloaded(id, 'xlsx', () => done())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('4 | downloads viewer SAS Datalines', (done) => {
|
||||
visitPage('view/data')
|
||||
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openDownloadModal(() => {
|
||||
cy.get('select')
|
||||
.select('SAS Datalines')
|
||||
.then(() => {
|
||||
cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
|
||||
button.trigger('click')
|
||||
|
||||
const id = button[0].id
|
||||
|
||||
checkForFileDownloaded(id, 'sas', () => done())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('5 | downloads viewer SAS DDL', (done) => {
|
||||
visitPage('view/data')
|
||||
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openDownloadModal(() => {
|
||||
cy.get('select')
|
||||
.select('SAS DDL')
|
||||
.then(() => {
|
||||
cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
|
||||
button.trigger('click')
|
||||
|
||||
const id = button[0].id
|
||||
|
||||
checkForFileDownloaded(id, 'ddl', () => done(), '_')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('6 | downloads viewer TSQL DDL', (done) => {
|
||||
visitPage('view/data')
|
||||
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openDownloadModal(() => {
|
||||
cy.get('select')
|
||||
.select('TSQL DDL')
|
||||
.then(() => {
|
||||
cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
|
||||
button.trigger('click')
|
||||
|
||||
const id = button[0].id
|
||||
|
||||
checkForFileDownloaded(id, 'ddl', () => done(), '_')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('7 | downloads viewer PGSQL DDL', (done) => {
|
||||
visitPage('view/data')
|
||||
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openDownloadModal(() => {
|
||||
cy.get('select')
|
||||
.select('PGSQL DDL')
|
||||
.then(() => {
|
||||
cy.get('.btn.btn-sm.btn-success-outline').then((button) => {
|
||||
button.trigger('click')
|
||||
|
||||
const id = button[0].id
|
||||
|
||||
checkForFileDownloaded(id, 'ddl', () => done(), '_')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
this.afterEach(() => {
|
||||
cy.visit(`${hostUrl}/SASLogon/logout`)
|
||||
})
|
||||
})
|
||||
|
||||
const visitPage = (url: string) => {
|
||||
cy.visit(`${hostUrl}${appLocation}/#/${url}`)
|
||||
}
|
||||
|
||||
const checkForFileDownloaded = (
|
||||
id: string,
|
||||
extension: string,
|
||||
callback?: any,
|
||||
libDivider: string = '.'
|
||||
) => {
|
||||
cy.on('url:changed', (newUrl) => {
|
||||
console.log('newUrl', newUrl)
|
||||
})
|
||||
|
||||
id = id.replace('.', libDivider)
|
||||
|
||||
const filename = downloadsFolder + '/' + id + '.' + extension
|
||||
// browser might take a while to download the file,
|
||||
// so use "cy.readFile" to retry until the file exists
|
||||
// and has length - and we assume that it has finished downloading then
|
||||
cy.readFile(filename, { timeout: longerCommandTimeout })
|
||||
.should('have.length.gt', 10)
|
||||
.then((file) => {
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const openDownloadModal = (callback?: any) => {
|
||||
cy.get('.btn.btn-sm.btn-outline.filterSide.dropdown-toggle')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('clr-dropdown-menu button').then((buttons) => {
|
||||
for (let button of buttons) {
|
||||
if (button.innerText.toLowerCase().includes('download')) {
|
||||
button.click()
|
||||
|
||||
if (callback) callback()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const openTableFromTree = (libNameIncludes: string, tablename: string) => {
|
||||
cy.get('.app-loading', { timeout: longerCommandTimeout })
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
cy.get('.nav-tree clr-tree > clr-tree-node', {
|
||||
timeout: longerCommandTimeout
|
||||
}).then((treeNodes: any) => {
|
||||
let viyaLib
|
||||
|
||||
for (let node of treeNodes) {
|
||||
if (node.innerText.toLowerCase().includes(libNameIncludes)) {
|
||||
viyaLib = node
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
console.log('viyaLib', viyaLib)
|
||||
|
||||
cy.get(viyaLib).within(() => {
|
||||
cy.get(
|
||||
'.clr-tree-node-content-container .clr-treenode-content p'
|
||||
).click()
|
||||
|
||||
cy.get('.clr-treenode-link').then((innerNodes: any) => {
|
||||
for (let innerNode of innerNodes) {
|
||||
if (innerNode.innerText.toLowerCase().includes(tablename)) {
|
||||
innerNode.click()
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
257
client/cypress/e2e/editor.cy.ts
Normal file
257
client/cypress/e2e/editor.cy.ts
Normal file
@ -0,0 +1,257 @@
|
||||
const username = Cypress.env('username')
|
||||
const password = Cypress.env('password')
|
||||
const hostUrl = Cypress.env('hosturl')
|
||||
const appLocation = Cypress.env('appLocation')
|
||||
const longerCommandTimeout = Cypress.env('longerCommandTimeout')
|
||||
const serverType = Cypress.env('serverType')
|
||||
const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`)
|
||||
const fixturePath = 'excels_general/'
|
||||
|
||||
context('editor tests: ', function () {
|
||||
this.beforeAll(() => {
|
||||
cy.visit(`${hostUrl}/SASLogon/logout`)
|
||||
cy.loginAndUpdateValidKey()
|
||||
})
|
||||
|
||||
this.beforeEach(() => {
|
||||
cy.visit(hostUrl + appLocation)
|
||||
// cy.get('input.username').type(username)
|
||||
// cy.get('input.password').type(password)
|
||||
// cy.get('.login-group button').click()
|
||||
|
||||
visitPage('home')
|
||||
})
|
||||
|
||||
it('1 | Submits duplicate primary keys', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary')
|
||||
|
||||
attachExcelFile('MPE_DATADICTIONARY_duplicate_keys.xlsx', () => {
|
||||
clickOnUploadPreview(() => {
|
||||
confirmEditPreviewFile(() => {
|
||||
submitTable(() => {
|
||||
cy.get('.modal-body').then((modalBody: any) => {
|
||||
if (modalBody[0].innerText.includes(`Duplicates found:`)) {
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('2 | Submits null cells which must not be null', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
clickOnEdit(() => {
|
||||
cy.get('.btn.btn-sm.btn-icon.btn-outline-danger', {
|
||||
timeout: longerCommandTimeout
|
||||
}).then(() => {
|
||||
cy.get('.ht_master tbody tr').then((rows: any) => {
|
||||
cy.get(rows[1].childNodes[2])
|
||||
.dblclick({ force: true })
|
||||
.then(() => {
|
||||
cy.focused()
|
||||
.clear()
|
||||
.type('{enter}')
|
||||
.then(() => {
|
||||
submitTable(() => {
|
||||
cy.get('.modal-body').then((modalBody: any) => {
|
||||
if (
|
||||
modalBody[0].innerHTML
|
||||
.toLowerCase()
|
||||
.includes(`invalid values are present`)
|
||||
) {
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('3 | Gets basic dynamic cell validation', () => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
clickOnEdit(() => {
|
||||
cy.get('.btn.btn-sm.btn-icon.btn-outline-danger', {
|
||||
timeout: longerCommandTimeout
|
||||
}).then(() => {
|
||||
cy.get('.ht_master tbody tr').then((rows: any) => {
|
||||
cy.get(rows[1].childNodes[5])
|
||||
.click({ force: true })
|
||||
.then(($td) => {
|
||||
cy.get('.htAutocompleteArrow', { withinSubject: $td }).should(
|
||||
'exist'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('4 | Gets advanced dynamic cell validation', () => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_tables')
|
||||
|
||||
clickOnEdit(() => {
|
||||
cy.get('.btn.btn-sm.btn-icon.btn-outline-danger', {
|
||||
timeout: longerCommandTimeout
|
||||
}).then(() => {
|
||||
cy.get('.ht_master tbody tr').then((rows: any) => {
|
||||
cy.get(rows[1].childNodes[3])
|
||||
.click({ force: true })
|
||||
.then(($td) => {
|
||||
cy.get('.htAutocompleteArrow', { withinSubject: $td }).should(
|
||||
'exist'
|
||||
)
|
||||
cy.get('.htAutocompleteArrow', {
|
||||
withinSubject: rows[1].childNodes[7]
|
||||
}).should('exist')
|
||||
cy.get('.htAutocompleteArrow', {
|
||||
withinSubject: rows[1].childNodes[8]
|
||||
}).should('exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
this.afterEach(() => {
|
||||
// cy.visit(`${hostUrl}/SASLogon/logout`)
|
||||
})
|
||||
})
|
||||
|
||||
const clickOnEdit = (callback?: any) => {
|
||||
cy.get('.btnCtrl button.btn-primary', { timeout: longerCommandTimeout })
|
||||
.click()
|
||||
.then(() => {
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const openTableFromTree = (libNameIncludes: string, tablename: string) => {
|
||||
cy.get('.app-loading', { timeout: longerCommandTimeout })
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
cy.get('.nav-tree clr-tree > clr-tree-node', {
|
||||
timeout: longerCommandTimeout
|
||||
}).then((treeNodes: any) => {
|
||||
let viyaLib
|
||||
|
||||
for (let node of treeNodes) {
|
||||
if (node.innerText.toLowerCase().includes(libNameIncludes)) {
|
||||
viyaLib = node
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cy.get(viyaLib).within(() => {
|
||||
cy.get('.clr-tree-node-content-container > button').click()
|
||||
|
||||
cy.get('.clr-treenode-link').then((innerNodes: any) => {
|
||||
for (let innerNode of innerNodes) {
|
||||
if (innerNode.innerText.toLowerCase().includes(tablename)) {
|
||||
innerNode.click()
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const attachExcelFile = (excelFilename: string, callback?: any) => {
|
||||
cy.get('.buttonBar button:last-child')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('input[type="file"]#file-upload')
|
||||
.attachFile(`/${fixturePath}/${excelFilename}`)
|
||||
.then(() => {
|
||||
cy.get('.modal-footer .btn.btn-primary').then((modalBtn) => {
|
||||
modalBtn.click()
|
||||
if (callback) callback()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const clickOnUploadPreview = (callback?: any) => {
|
||||
cy.get('.buttonBar button.btn-primary.btn-upload-preview')
|
||||
.click()
|
||||
.then(() => {
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const confirmEditPreviewFile = (callback?: any) => {
|
||||
cy.get('.modal-footer button.btn-success-outline')
|
||||
.click()
|
||||
.then(() => {
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const submitTable = (callback?: any) => {
|
||||
cy.get('.btnCtrl button.btn-primary')
|
||||
.click()
|
||||
.then(() => {
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const submitTableMessage = (callback?: any) => {
|
||||
cy.get('.modal-footer .btn.btn-sm.btn-success-outline')
|
||||
.click()
|
||||
.then(() => {
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const submitExcel = (callback?: any) => {
|
||||
cy.get('.buttonBar button.preview-submit')
|
||||
.click()
|
||||
.then(() => {
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const rejectExcel = (callback?: any) => {
|
||||
cy.get('button', { timeout: longerCommandTimeout })
|
||||
.should('contain', 'Go to approvals screen')
|
||||
.then((allButtons: any) => {
|
||||
for (let approvalButton of allButtons) {
|
||||
if (
|
||||
approvalButton.innerText
|
||||
.toLowerCase()
|
||||
.includes('go to approvals screen')
|
||||
) {
|
||||
approvalButton.click()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cy.get('button.btn-danger')
|
||||
.should('exist')
|
||||
.should('not.be.disabled')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('.modal-footer button.btn-success-outline')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('app-history')
|
||||
.should('exist')
|
||||
.then(() => {
|
||||
if (callback) callback()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const visitPage = (url: string) => {
|
||||
cy.visit(`${hostUrl}${appLocation}/#/${url}`)
|
||||
}
|
537
client/cypress/e2e/excel.cy.ts
Normal file
537
client/cypress/e2e/excel.cy.ts
Normal file
@ -0,0 +1,537 @@
|
||||
import { Callbacks } from 'cypress/types/jquery/index'
|
||||
|
||||
const username = Cypress.env('username')
|
||||
const password = Cypress.env('password')
|
||||
const hostUrl = Cypress.env('hosturl')
|
||||
const appLocation = Cypress.env('appLocation')
|
||||
const longerCommandTimeout = Cypress.env('longerCommandTimeout')
|
||||
const serverType = Cypress.env('serverType')
|
||||
const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`)
|
||||
const fixturePath = 'excels/'
|
||||
|
||||
context('excel tests: ', function () {
|
||||
this.beforeAll(() => {
|
||||
cy.visit(`${hostUrl}/SASLogon/logout`)
|
||||
cy.loginAndUpdateValidKey(true)
|
||||
})
|
||||
|
||||
this.beforeEach(() => {
|
||||
cy.visit(hostUrl + appLocation)
|
||||
// cy.get('input.username').type(username)
|
||||
// cy.get('input.password').type(password)
|
||||
// cy.get('.login-group button').click()
|
||||
|
||||
visitPage('home')
|
||||
|
||||
colorLog(
|
||||
`TEST START ---> ${
|
||||
Cypress.mocha.getRunner().suite.ctx.currentTest.title
|
||||
}`,
|
||||
'#3498DB'
|
||||
)
|
||||
})
|
||||
|
||||
it('1 | Uploads regular Excel file', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('regular_excel.xlsx', () => {
|
||||
submitExcel()
|
||||
rejectExcel(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('2 | Uploads Excel with data on the 7th tab', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('7th_tab_excel.xlsx', () => {
|
||||
submitExcel()
|
||||
rejectExcel(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('3 | Uploads Excel with missing columns (should fail)', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('missing_columns_excel.xlsx', () => {
|
||||
cy.get('.abortMsg', { timeout: longerCommandTimeout })
|
||||
.should('exist')
|
||||
.then((elements: any) => {
|
||||
if (elements[0]) {
|
||||
if (elements[0].innerText.toLowerCase().includes('missing')) done()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('4 | Uploads Excel with formulas', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary')
|
||||
|
||||
attachExcelFile('formulas_excel.xlsx', () => {
|
||||
checkResultOfFormulaUpload(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('5 | Uploads Excel with no data rows', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('nodata_rows_excel.xlsx', () => {
|
||||
cy.get('.abortMsg', { timeout: longerCommandTimeout })
|
||||
.should('exist')
|
||||
.then((elements: any) => {
|
||||
if (elements[0]) {
|
||||
if (
|
||||
elements[0].innerText
|
||||
.toLowerCase()
|
||||
.includes('no relevant data found')
|
||||
)
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('6 | Uploads Excel with a table that is surrounded by other data', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('surrounded_data_excel.xlsx', () => {
|
||||
submitExcel()
|
||||
rejectExcel(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('7 | Uploads Excel with a extra columns in the middle', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('extra_column_excel.xlsx', () => {
|
||||
submitExcel()
|
||||
rejectExcel(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('8 | Uploads Excel with a duplicate column', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('duplicate_column_excel.xlsx', () => {
|
||||
cy.get('.abortMsg', { timeout: longerCommandTimeout })
|
||||
.should('exist')
|
||||
.then((elements: any) => {
|
||||
if (elements[0]) {
|
||||
if (elements[0].innerText.toLowerCase().includes('missing')) done()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('9 | Uploads Excel with a duplicate row', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('duplicate_row_excel.xlsx', () => {
|
||||
submitExcel(() => {
|
||||
cy.get('.duplicate-keys-modal', { timeout: longerCommandTimeout })
|
||||
.should('exist')
|
||||
.then((elements: any) => {
|
||||
if (elements[0]) {
|
||||
if (elements[0].innerText.toLowerCase().includes('duplicates'))
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('10 | Uploads Excel with a mixed content', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('mixed_content_excel.xlsx', () => {
|
||||
submitExcel(() => {
|
||||
cy.get('.modal-body').then((modalBody: any) => {
|
||||
if (
|
||||
modalBody[0].innerHTML
|
||||
.toLowerCase()
|
||||
.includes(`invalid values are present`)
|
||||
) {
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('11 | Uploads Excel with a blank columns', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('blank_columns_excel.xlsx', () => {
|
||||
cy.get('.abortMsg', { timeout: longerCommandTimeout })
|
||||
.should('exist')
|
||||
.then((elements: any) => {
|
||||
if (elements[0]) {
|
||||
if (elements[0].innerText.toLowerCase().includes('missing')) done()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('12 | Uploads Excel xls extension', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('regular_excel_xls.xls', () => {
|
||||
submitExcel()
|
||||
rejectExcel(done)
|
||||
})
|
||||
})
|
||||
|
||||
// For some strange reason this file breaks cypress. When uploaded manually in DC it is working.
|
||||
// it('13 | Uploads Excel xlsm extension', (done) => {
|
||||
// openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
// attachExcelFile('regular_excel_macro.xlsm', () => {
|
||||
// submitExcel()
|
||||
// rejectExcel(done)
|
||||
// })
|
||||
// })
|
||||
|
||||
it('14 | Uploads Excel with composite primary key', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary')
|
||||
|
||||
attachExcelFile('MPE_DATADICTIONARY_composite_keys.xlsx', () => {
|
||||
submitExcel()
|
||||
rejectExcel(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('15 | Uploads Excel with missing row (empty table)', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary')
|
||||
|
||||
attachExcelFile('MPE_DATADICTIONARY_missing_row.xlsx', () => {
|
||||
cy.get('.abortMsg', { timeout: longerCommandTimeout })
|
||||
.should('exist')
|
||||
.then((elements: any) => {
|
||||
if (elements[0]) {
|
||||
if (
|
||||
elements[0].innerText
|
||||
.toLowerCase()
|
||||
.includes('no relevant data found')
|
||||
)
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('16 | Uploads Excel with merged cells', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_datadictionary')
|
||||
|
||||
attachExcelFile('MPE_DATADICTIONARY_merged_cells.xlsx', () => {
|
||||
submitExcel()
|
||||
rejectExcel(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('17 | Check uploaded values from excel with xls extension', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('regular_excel_xls.xls', () => {
|
||||
checkResultOfXLSUpload(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('18 | Uploads Excel with missing row (empty table)', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('blank_column_with_header.xlsx', () => {
|
||||
cy.get('.btn-upload-preview', { timeout: 60000 })
|
||||
.should('be.visible')
|
||||
.then(() => {
|
||||
cy.get('#hotInstance', { timeout: 30000 })
|
||||
.find('div.ht_master.handsontable')
|
||||
.find('div.wtHolder')
|
||||
.find('div.wtHider')
|
||||
.find('div.wtSpreader')
|
||||
.find('table.htCore')
|
||||
.find('tbody')
|
||||
.then((data) => {
|
||||
let allEmpty = true
|
||||
|
||||
for (let col = 0; col < data[0].children.length; col++) {
|
||||
const cell: any = data[0].children[col].children[5]
|
||||
|
||||
if (cell.innerText !== '') {
|
||||
allEmpty = false
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (allEmpty) done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('19 | Uploads Excel with data on random sheet surrounded with all empty cells', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('surrounded_data_all_cells_empty_excel.xlsx', () => {
|
||||
checkResultOfXLSUpload(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('20 | Uploads Excel with data surrounded with empty cells ', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('surrounded_data_empty_cells_excel.xlsx', () => {
|
||||
checkResultOfXLSUpload(done)
|
||||
})
|
||||
})
|
||||
|
||||
it('21 | Uploads regular Excel file with first row marked for Delete (yes)', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
attachExcelFile('regular_excel_with_delete.xlsx', () => {
|
||||
cy.get('.btn-upload-preview', { timeout: 60000 })
|
||||
.should('be.visible')
|
||||
.then(() => {
|
||||
cy.get('#hotInstance', { timeout: 30000 })
|
||||
.find('div.ht_master.handsontable')
|
||||
.find('div.wtHolder')
|
||||
.find('div.wtHider')
|
||||
.find('div.wtSpreader')
|
||||
.find('table.htCore')
|
||||
.find('tbody')
|
||||
.then((data: JQuery<HTMLTableSectionElement>) => {
|
||||
const firstRowFirstCol: Partial<HTMLElement> =
|
||||
data[0].children[0].children[1]
|
||||
|
||||
if (
|
||||
firstRowFirstCol.innerText &&
|
||||
!firstRowFirstCol.innerText.toLowerCase().includes('yes')
|
||||
) {
|
||||
done('Delete? column from file not applied')
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
submitExcel()
|
||||
rejectExcel(done)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// Large files break Cypress
|
||||
|
||||
// it ('? | Uploads Excel with size of 5MB', (done) => {
|
||||
// attachExcelFile('5mb_excel.xlsx', () => {
|
||||
// submitExcel();
|
||||
// rejectExcel(done);
|
||||
// });
|
||||
// })
|
||||
|
||||
// it ('? | Uploads Excel with size of 15MB', (done) => {
|
||||
// attachExcelFile('15mb_excel.xlsx', () => {
|
||||
// submitExcel();
|
||||
// rejectExcel(done);
|
||||
// });
|
||||
// })
|
||||
|
||||
//Large files tests end
|
||||
|
||||
this.afterEach(() => {
|
||||
colorLog(`TEST END -------------`, '#3498DB')
|
||||
// cy.visit(`${hostUrl}/SASLogon/logout`)
|
||||
})
|
||||
})
|
||||
|
||||
const openTableFromTree = (libNameIncludes: string, tablename: string) => {
|
||||
cy.get('.app-loading', { timeout: longerCommandTimeout })
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
cy.get('.nav-tree clr-tree > clr-tree-node', {
|
||||
timeout: longerCommandTimeout
|
||||
}).then((treeNodes: any) => {
|
||||
let viyaLib
|
||||
|
||||
for (let node of treeNodes) {
|
||||
if (node.innerText.toLowerCase().includes(libNameIncludes)) {
|
||||
viyaLib = node
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cy.get(viyaLib).within(() => {
|
||||
cy.get('.clr-tree-node-content-container > button').click()
|
||||
|
||||
cy.get('.clr-treenode-link').then((innerNodes: any) => {
|
||||
for (let innerNode of innerNodes) {
|
||||
if (innerNode.innerText.toLowerCase().includes(tablename)) {
|
||||
innerNode.click()
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const attachExcelFile = (excelFilename: string, callback?: any) => {
|
||||
cy.get('.buttonBar button:last-child')
|
||||
.should('exist')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('input[type="file"]#file-upload')
|
||||
.attachFile(`/${fixturePath}/${excelFilename}`)
|
||||
.then(() => {
|
||||
cy.get('.clr-abort-modal .modal-title').then((modalTitle) => {
|
||||
if (!modalTitle[0].innerHTML.includes('Abort Message')) {
|
||||
cy.get('.modal-footer .btn.btn-primary').then((modalBtn) => {
|
||||
modalBtn.click()
|
||||
if (callback) callback()
|
||||
})
|
||||
} else {
|
||||
if (callback) callback()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const submitExcel = (callback?: any) => {
|
||||
cy.get('.buttonBar button.preview-submit', { timeout: longerCommandTimeout })
|
||||
.click()
|
||||
.then(() => {
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const rejectExcel = (callback?: any) => {
|
||||
cy.get('button', { timeout: longerCommandTimeout })
|
||||
.should('contain', 'Go to approvals screen')
|
||||
.then((allButtons: any) => {
|
||||
for (let approvalButton of allButtons) {
|
||||
if (
|
||||
approvalButton.innerText
|
||||
.toLowerCase()
|
||||
.includes('go to approvals screen')
|
||||
) {
|
||||
approvalButton.click()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cy.get('button.btn-danger')
|
||||
.should('exist')
|
||||
.should('not.be.disabled')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('.modal-footer button.btn-success-outline')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('app-history')
|
||||
.should('exist')
|
||||
.then(() => {
|
||||
if (callback) callback()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const acceptExcel = (callback?: any) => {
|
||||
cy.get('button', { timeout: longerCommandTimeout })
|
||||
.should('contain', 'Go to approvals screen')
|
||||
.then((allButtons: any) => {
|
||||
for (let approvalButton of allButtons) {
|
||||
if (
|
||||
approvalButton.innerText
|
||||
.toLowerCase()
|
||||
.includes('go to approvals screen')
|
||||
) {
|
||||
approvalButton.click()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cy.get('#acceptBtn')
|
||||
.should('exist')
|
||||
.should('not.be.disabled')
|
||||
.click()
|
||||
.then(() => {
|
||||
if (callback) {
|
||||
callback()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const checkResultOfFormulaUpload = (callback?: any) => {
|
||||
cy.get('#hotInstance', { timeout: longerCommandTimeout })
|
||||
.find('div.ht_master.handsontable')
|
||||
.find('div.wtHolder')
|
||||
.find('div.wtHider')
|
||||
.find('div.wtSpreader')
|
||||
.find('table.htCore')
|
||||
.find('tbody')
|
||||
.then((data) => {
|
||||
const cell: any = data[0].children[0].children[5]
|
||||
expect(cell.innerText).to.equal('=1+1')
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const checkResultOfXLSUpload = (callback?: any) => {
|
||||
cy.viewport(1280, 720)
|
||||
cy.get('#hotInstance', { timeout: 30000 })
|
||||
.find('div.ht_master.handsontable')
|
||||
.find('div.wtHolder')
|
||||
.find('div.wtHider')
|
||||
.find('div.wtSpreader')
|
||||
.find('table.htCore')
|
||||
.find('tbody')
|
||||
.then((data) => {
|
||||
let cell: any = data[0].children[0].children[2]
|
||||
|
||||
expect(cell.innerText).to.equal('0')
|
||||
cell = data[0].children[0].children[3]
|
||||
expect(cell.innerText).to.equal('this is dummy data changed in excel')
|
||||
cell = data[0].children[0].children[4]
|
||||
expect(cell.innerText).to.equal('▼\nOption 1')
|
||||
cell = data[0].children[0].children[5]
|
||||
expect(cell.innerText).to.equal('42')
|
||||
cell = data[0].children[0].children[6]
|
||||
expect(cell.innerText).to.equal('▼\n1960-02-12')
|
||||
// When CI detached browser screen is smaller, below cells are not visible so test fails
|
||||
// Commenting it out now until we figure out workaround
|
||||
// cell = data[0].children[0].children[7]
|
||||
// expect(cell.innerText).to.equal('▼\n1960-01-01 00:00:42')
|
||||
// cell = data[0].children[0].children[8]
|
||||
// expect(cell.innerText).to.equal('00:00:42')
|
||||
|
||||
if (callback) callback()
|
||||
})
|
||||
|
||||
cy.get('#hotInstance', { timeout: 30000 })
|
||||
.find('div.ht_master.handsontable')
|
||||
.find('div.wtHolder')
|
||||
.scrollTo('right')
|
||||
.find('div.wtHider')
|
||||
.find('div.wtSpreader')
|
||||
.find('table.htCore')
|
||||
.find('tbody')
|
||||
.then((data) => {
|
||||
let cell: any = data[0].children[0].children[1]
|
||||
|
||||
cell = data[0].children[0].children[9]
|
||||
|
||||
expect(cell.innerText).to.equal('44')
|
||||
|
||||
if (callback) callback()
|
||||
})
|
||||
}
|
||||
|
||||
const visitPage = (url: string) => {
|
||||
cy.visit(`${hostUrl}${appLocation}/#/${url}`)
|
||||
}
|
||||
|
||||
const colorLog = (msg: string, color: string) => {
|
||||
console.log('%c' + msg, 'color:' + color + ';font-weight:bold;')
|
||||
}
|
383
client/cypress/e2e/filtering.cy.ts
Normal file
383
client/cypress/e2e/filtering.cy.ts
Normal file
@ -0,0 +1,383 @@
|
||||
const username = Cypress.env('username')
|
||||
const password = Cypress.env('password')
|
||||
const hostUrl = Cypress.env('hosturl')
|
||||
const appLocation = Cypress.env('appLocation')
|
||||
const longerCommandTimeout = Cypress.env('longerCommandTimeout')
|
||||
const serverType = Cypress.env('serverType')
|
||||
const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`)
|
||||
const fixturePath = 'excels_general/'
|
||||
|
||||
context('filtering tests: ', function () {
|
||||
this.beforeAll(() => {
|
||||
cy.visit(`${hostUrl}/SASLogon/logout`, { timeout: longerCommandTimeout })
|
||||
cy.loginAndUpdateValidKey()
|
||||
})
|
||||
|
||||
this.beforeEach(() => {
|
||||
cy.visit(hostUrl + appLocation, { timeout: longerCommandTimeout })
|
||||
// cy.get('input.username').type(username)
|
||||
// cy.get('input.password').type(password)
|
||||
// cy.get('.login-group button').click()
|
||||
|
||||
visitPage('home')
|
||||
})
|
||||
|
||||
it('1 | filter char field', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openFilterPopup(() => {
|
||||
setFilterWithValue('SOME_CHAR', 'this is dummy data', 'value', () => {
|
||||
checkInfoBarIncludes(
|
||||
`AND,AND,0,SOME_CHAR,=,"'this is dummy data'"`,
|
||||
(includes: boolean) => {
|
||||
if (includes) done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('2 | filter number field', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openFilterPopup(() => {
|
||||
setFilterWithValue('SOME_NUM', '42', 'value', () => {
|
||||
checkInfoBarIncludes(`AND,AND,0,SOME_NUM,=,42`, (includes: boolean) => {
|
||||
if (includes) done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('3 | filter time field', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openFilterPopup(() => {
|
||||
setFilterWithValue('SOME_TIME', '00:00:42', 'time', () => {
|
||||
checkInfoBarIncludes(
|
||||
`AND,AND,0,SOME_TIME,=,42`,
|
||||
(includes: boolean) => {
|
||||
if (includes) done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('3.1 | Non picker - filter time field', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openFilterPopup(() => {
|
||||
setFilterWithValue('SOME_TIME', '42', 'value', () => {
|
||||
checkInfoBarIncludes(
|
||||
`AND,AND,0,SOME_TIME,=,42`,
|
||||
(includes: boolean) => {
|
||||
if (includes) done()
|
||||
}
|
||||
)
|
||||
})
|
||||
}, false)
|
||||
})
|
||||
|
||||
it('4 | filter date field', (done) => {
|
||||
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
|
||||
|
||||
openFilterPopup(() => {
|
||||
setFilterWithValue('SOME_DATE', '12/02/1960', 'date', () => {
|
||||
checkInfoBarIncludes(
|
||||
`AND,AND,0,SOME_DATE,=,42`,
|
||||
(includes: boolean) => {
|
||||
if (includes) done()
|
||||
}
|
||||
)
|
||||
})
|
||||