import { arrayBufferToBase64 } from './../util/helper-functions' import * as moment from 'moment' 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 fixturePath = 'excels_general/' const serverType = Cypress.env('serverType') const site_id = Cypress.env(`site_id_${serverType}`) const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`) const testLicenceUserLimits = Cypress.env('testLicenceUserLimits') /** IMPORTANT NOTICE * Before running tests, make sure that table `MPE_USERS` is present */ interface EditConfigTableCells { varName: string varValue: string } context('licensing 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 | key valid, not expired', (done) => { let keyData = { valid_until: moment().add(1, 'year').format('YYYY-MM-DD'), users_allowed: 4, hot_license_key: '', demo: false, site_id: site_id } let keys: { licenseKey: any; activationKey: any } generateKeys(keyData, (keysGen: any) => { keys = keysGen cy.wait(2000) isLicensingPage((result: boolean) => { if (result) { inputLicenseKeyPage(keys.licenseKey, keys.activationKey) cy.wait(2000) } acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(10000) } visitPage('home') cy.get('.nav-tree clr-tree > clr-tree-node', { timeout: longerCommandTimeout }).then((treeNodes: any) => { done() }) }) }) }) }) it('2 | Key will expire in less then 14 days, not free tier', (done) => { // make 2 separate for this one let keyData = { valid_until: moment().add(10, 'day').format('YYYY-MM-DD'), users_allowed: 4, hot_license_key: '', demo: false, site_id: site_id } let keys: { licenseKey: any; activationKey: any } generateKeys(keyData, (keysGen: any) => { keys = keysGen console.log('keys', keys) cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } updateLicenseKeyQuick(keysGen, () => { cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } verifyLicensingWarning('This license key will expire in ', () => { done() }) }) }) }) }) }) it('3 | key expired, free tier works', (done) => { let keyData = { valid_until: moment().subtract(1, 'day').format('YYYY-MM-DD'), users_allowed: 4, hot_license_key: '', demo: false, site_id: site_id } let keys: { licenseKey: any; activationKey: any } generateKeys(keyData, (keysGen: any) => { keys = keysGen cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } cy.wait(2000) updateLicenseKeyQuick(keysGen, () => { cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } verifyLicensingPage( 'Licence key is expired - please contact', (success: boolean) => { if (success) { verifyLicensingWarning( '(FREE Tier) - Problem with licence', () => { done() } ) } } ) }) }) }) }) }) it('4 | key invalid, free tier works', (done) => { let keyData = { valid_until: moment().subtract(1, 'day').format('YYYY-MM-DD'), users_allowed: 4, hot_license_key: '', demo: false, site_id: site_id } let keys: { licenseKey: any; activationKey: any } generateKeys(keyData, (keysGen: any) => { keys = keysGen keys.activationKey = 'invalid' + keys.activationKey cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } cy.wait(2000) updateLicenseKeyQuick(keysGen, () => { cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } verifyLicensingPage( 'Licence key is invalid - please contact', (success: boolean) => { if (success) { verifyLicensingWarning( '(FREE Tier) - Problem with licence', () => { done() } ) } } ) }) }) }) }) }) it('5 | key for wrong organisation, free tier works', (done) => { let keyData = { valid_until: moment().add(1, 'year').format('YYYY-MM-DD'), users_allowed: 4, hot_license_key: '', demo: false, site_id: 100 } let keys: { licenseKey: any; activationKey: any } generateKeys(keyData, (keysGen: any) => { keys = keysGen keys.activationKey = keys.activationKey cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } cy.wait(2000) updateLicenseKeyQuick(keysGen, () => { cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } verifyLicensingPage( 'SYSSITE (below) is not found', (success: boolean) => { if (success) { verifyLicensingWarning( '(FREE Tier) - Problem with licence', () => { done() } ) } } ) }) }) }) }) }) if (testLicenceUserLimits) { it('4 | User try to register when limit is reached', (done) => { let keyData = { valid_until: moment().add(1, 'month').format('YYYY-MM-DD'), users_allowed: 10, hot_license_key: '', demo: false, site_id: site_id } let keyData2 = { valid_until: moment().add(1, 'month').format('YYYY-MM-DD'), users_allowed: 1, hot_license_key: '', demo: false, site_id: site_id } generateKeys(keyData, (keysGen: any) => { generateKeys(keyData2, (keysGen2: any) => { cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } updateLicenseKeyQuick(keysGen, () => { cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } updateLicenseKeyQuick(keysGen2, () => { cy.wait(2000) const random = Cypress._.random(0, 1000) const newUser = { username: `randomusername${random}notregistered`, last_seen_at: moment().add(1, 'month').format('YYYY-MM-DD'), registered_at: moment().add(1, 'month').format('YYYY-MM-DD') } updateUsersTable( { deleteAll: true, newUsers: [newUser] }, () => { logout(() => { cy.visit(hostUrl + appLocation) // cy.get('input.username').type(username) // cy.get('input.password').type(password) // cy.get('.login-group button').click() visitPage('home') cy.wait(2000) verifyLicensingPage( 'The registered number of users reached the limit specified for your licence.', (success: boolean) => { if (success) done() } ) }) } ) }) }) }) }) }) }) }) it('5 | Show warning banner when limit is exceeded', (done) => { let keyData = { valid_until: moment().add(1, 'month').format('YYYY-MM-DD'), users_allowed: 10, hot_license_key: '', demo: false, site_id: site_id } let keyData2 = { valid_until: moment().add(1, 'month').format('YYYY-MM-DD'), users_allowed: 1, hot_license_key: '', demo: false, site_id: site_id } generateKeys(keyData, (keysGen: any) => { generateKeys(keyData2, (keysGen2: any) => { cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } updateLicenseKeyQuick(keysGen, () => { cy.wait(2000) acceptTermsIfPresented((result: boolean) => { if (result) { cy.wait(20000) } const random = Cypress._.random(0, 1000) const newUser = { username: `randomusername${random}`, last_seen_at: moment().add(1, 'month').format('YYYY-MM-DD'), registered_at: moment().add(1, 'month').format('YYYY-MM-DD') } updateUsersTable( { deleteAll: true, keep: username, newUsers: [newUser] }, () => { updateLicenseKeyQuick(keysGen2, () => { cy.wait(2000) verifyLicensingWarning( 'The registered number of users exceeds the limit specified for your license.', () => { done() } ) }) } ) }) }) }) }) }) }) } this.afterEach(() => { // cy.visit(`${hostUrl}/SASLogon/logout`) }) }) const logout = (callback?: any) => { cy.get('.header-actions .dropdown-toggle') .click() .then(() => { cy.get('.header-actions .dropdown-menu > .separator') .next() .click() .then(() => { if (callback) callback() }) }) } const acceptTermsIfPresented = (callback?: any) => { cy.url().then((url: string) => { if (url.includes('licensing/register')) { cy.get('.card-block') .scrollTo('bottom') .then(() => { cy.get('#checkbox1') .click() .then(() => { if (callback) callback(true) }) }) } else { if (callback) callback(false) } }) } const isLicensingPage = (callback: any) => { return cy.url().then((url: string) => { callback( url.includes('#/licensing/') && !url.includes('licensing/register') ) }) } const verifyLicensingPage = (text: string, callback: any) => { // visitPage('home') cy.wait(1000) isLicensingPage((result: boolean) => { if (result) { cy.get('p.key-error') .should('contain', text) .then((treeNodes: any) => { callback(true) }) } }) } const verifyLicensingWarning = (text: string, callback: any) => { visitPage('home') cy.wait(1000) cy.get("div[role='alert'] .alert-text") .invoke('text') .should('contain', text) .then(() => { callback() }) } const inputLicenseKeyPage = (licenseKey: string, activationKey: string) => { cy.get('button').contains('Paste licence').click() cy.get('.license-key-form textarea', { timeout: longerCommandTimeout }) .invoke('val', licenseKey) .trigger('input') .should('not.be.undefined') cy.get('.activation-key-form textarea', { timeout: longerCommandTimeout }) .invoke('val', activationKey) .trigger('input') .should('not.be.undefined') cy.get('button.apply-keys').click() } const updateUsersTable = (options: any, callback?: any) => { visitPage('home') openTableFromTree(libraryToOpenIncludes, 'mpe_users') clickOnEdit(() => { cy.get('.ht_master tbody tr').then((rows: any) => { if (options.deleteAll) { for (let row of rows) { const user_id = row.childNodes[2] if (!options.keep || user_id.innerText !== options.keep) { cy.get(row.childNodes[1]) .dblclick() .then(() => { cy.focused().type('{selectall}').type('Yes').type('{enter}') }) } } } if (options.newUsers && options.newUsers.length) { for (let newUser of options.newUsers) { clickOnAddRow(() => { cy.get('#hotInstance tbody tr:last-child').then((rows: any) => { cy.get(rows[0].childNodes[2]) .dblclick() .then(() => { cy.focused() .type('{selectall}') .type(newUser.username) .type('{enter}') }) // cy.get(rows[0].childNodes[3]) // .dblclick() // .then(() => { // cy.focused() // .type('{selectall}') // .type(newUser.last_seen_at) // .type('{enter}') // }) // cy.get(rows[0].childNodes[4]) // .dblclick() // .then(() => { // cy.focused() // .type('{selectall}') // .type(newUser.registered_at) // .type('{enter}') // }) submitTable(() => { cy.wait(2000) approveTable(callback) }) }) }) } } }) }) } const changeLicenseKeyTable = (keys: any, callback?: any) => { visitPage('home') openTableFromTree(libraryToOpenIncludes, 'mpe_config') clickOnEdit(() => { editTableField( [ { varName: 'DC_ACTIVATION_KEY', varValue: keys.activationKey }, { varName: 'DC_LICENCE_KEY', varValue: keys.licenseKey } ], () => { submitTable(() => { cy.wait(2000) approveTable(() => { cy.reload() if (callback) callback() }) }) } ) }) } const updateLicenseKeyQuick = (keys: any, callback: any) => { isLicensingPage((result: boolean) => { if (!result) { visitPage('licensing/update') cy.wait(2000) } inputLicenseKeyPage(keys.licenseKey, keys.activationKey) callback() }) } const generateKeys = async (licenseData: any, resultCallback?: any) => { let keyPair = await window.crypto.subtle.generateKey( { name: 'RSA-OAEP', modulusLength: 2024, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256' }, true, ['encrypt', 'decrypt'] ) const encoded = new TextEncoder().encode(JSON.stringify(licenseData)) const cipher = await window.crypto.subtle .encrypt( { name: 'RSA-OAEP' }, keyPair.publicKey, encoded ) .then( (value) => { return value }, (err) => { console.log('Encrpyt error', err) } ) if (!cipher) { alert('Encryptin keys failed') throw new Error('Encryptin keys failed') } const privateKeyBytes = await window.crypto.subtle.exportKey( 'pkcs8', keyPair.privateKey ) const activationKey = await arrayBufferToBase64(privateKeyBytes) const licenseKey = await arrayBufferToBase64(cipher) if (resultCallback) resultCallback({ activationKey, licenseKey }) } const editTableField = (edits: EditConfigTableCells[], callback?: any) => { cy.get('td').then((tdNodes: any) => { for (let edit of edits) { let correctRow = false for (let node of tdNodes) { if (correctRow) { cy.get(node) .dblclick() .then(() => { // textarea update on long keys cy.focused().invoke('val', edit.varValue).type('{enter}') }) correctRow = false break } if (node.innerText.includes(edit.varName)) { correctRow = true } } } if (callback) callback() }) } const openTableFromTree = ( libNameIncludes: string, tablename: string, callback?: any ) => { 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() if (callback) callback() break } } }) }) }) }) } const clickOnAddRow = (callback?: any) => { cy.get('.btnCtrl button.btn-success') .click() .then(() => { if (callback) callback() }) } const clickOnEdit = (callback?: any) => { cy.get('.btnCtrl button.btn-primary', { timeout: longerCommandTimeout }) .click() .then(() => { if (callback) callback() }) } const submitTable = (callback?: any) => { cy.get('.btnCtrl button.btn-primary', { timout: longerCommandTimeout }) .click() .then(() => { cy.get(".modal.ng-star-inserted button[type='submit']") .click() .then(() => { if (callback) callback() }) }) } const approveTable = (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#acceptBtn', { timeout: longerCommandTimeout }) .should('exist') .should('not.be.disabled') .click() .then(() => { cy.get('app-history', { timeout: longerCommandTimeout }) .should('exist') .then(() => { if (callback) callback() }) }) }) } const visitPage = (url: string) => { cy.visit(`${hostUrl}${appLocation}/#/${url}`) }