feat: initial commit

This commit is contained in:
Thom Lamb
2026-06-23 11:18:54 -05:00
parent fc3ce9a074
commit 1bb980f070
790 changed files with 149255 additions and 218 deletions
+10
View File
@@ -0,0 +1,10 @@
{
"baseUrl": "https://analytics.dev.stratanetwork.net/workbooks/",
"userName": "dssadmin",
"basicUserName": "capbasic",
"userPassword": "Password1",
"dbguid": "102e1bc4-f789-4ee8-8810-828af508a8ab",
"orgPin": "0777",
"dbName": "QA Master",
"clientId": "StrataUI"
}
+45
View File
@@ -0,0 +1,45 @@
{
"baseUrl": "https://analytics.dev.stratanetwork.net/workbooks/",
"requestTimeout": 8000,
"defaultCommandTimeout": 10000,
"trashAssetsBeforeRuns": true,
"downloadsFolder": "cypress/fixtures",
"viewportWidth": 1440,
"viewportHeight": 900,
"scrollBehavior": false,
"chromeWebSecurity": false,
"ignoreTestFiles": [
"**/__snapshots__/*",
"**/__image_snapshots__/*"
],
"cypress-plugin-snapshots": {
"autoCleanUp": false,
"autopassNewSnapshots": true,
"diffLines": 3,
"excludeFields": [],
"ignoreExtraArrayItems": false,
"ignoreExtraFields": false,
"normalizeJson": true,
"prettier": true,
"imageConfig": {
"createDiffImage": true,
"resizeDevicePixelRatio": true,
"threshold": 0.05,
"thresholdType": "percent"
},
"screenshotConfig": {
"blackout": [],
"capture": "fullPage",
"clip": null,
"disableTimersAndAnimations": true,
"log": false,
"scale": false,
"timeout": 30000
},
"serverEnabled": true,
"serverHost": "localhost",
"serverPort": 2121,
"updateSnapshots": false,
"backgroundBlend": "difference"
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"baseUrl": "https://analytics.dev.stratanetwork.net/analytics/",
"env": {
"basePageUrl": "https://analytics.dev.stratanetwork.net/analytics/",
"apiUrl": "https://analytics-api.dev.stratanetwork.net/api/",
"username": "username",
"password": "password",
"dbguid": "102e1bc4-f789-4ee8-8810-828af508a8ab",
"orgPin": "0777",
"dbName": "QA Master",
"clientId": "StrataUI"
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"baseUrl": "http://localhost:3000/analytics/",
"env": {
"basePageUrl": "http://localhost:3000/analytics/",
"apiUrl": "https://localhost:8443/api/",
"username": "username",
"password": "password",
"dbguid": "102e1bc4-f789-4ee8-8810-828af508a8ab",
"orgPin": "0777",
"dbName": "QA Master",
"clientId": "StrataUI"
}
}
@@ -0,0 +1,42 @@
import * as dayjs from 'dayjs';
import advancedAnalyticsDatamartPage from '../pageObjects/advancedAnalyticsDataSourcePageObject';
const dataSourcePage = new advancedAnalyticsDatamartPage();
const dataSourceName1 = `Cypress_Test_Datamart1_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const dataSourceName2 = `Cypress_Test_Datamart2_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const datamartDescription = 'Test datamart made in Cypress - datamart security test';
const dssPatientEncounter = '55370';
before(() => {
cy.vaultLoginByUserTitle('IDTestUser');
cy.createDataSource(dataSourceName1, datamartDescription);
cy.createDataSource(dataSourceName2, datamartDescription);
cy.addTableToDataSource(dssPatientEncounter, dataSourceName1);
cy.addTableToDataSource(dssPatientEncounter, dataSourceName2);
});
beforeEach(() => {
cy.wait(1);
});
after(() => {
cy.deleteDataSource(dataSourceName1);
cy.deleteDataSource(dataSourceName2);
cy.visit('/');
});
describe('Advanced Analytics data mart tests', () => {
it('Data mart can be secured from users', () => {
cy.goToDataSource(dataSourceName2);
dataSourcePage.addUsersToDataSource(dataSourceName2, [{ userName: 'Capital Administrator' }]);
cy.logout();
cy.vaultLoginByUserTitle('Capital Administrator');
cy.findByText('Add Workbook').click();
cy.get('#defaultDataSourceId').click();
cy.get('div').contains(dataSourceName1).should('not.exist');
cy.get('div').contains(dataSourceName2).should('exist');
cy.logout();
cy.vaultLoginByUserTitle('IDTestUser');
});
});
@@ -0,0 +1,87 @@
import * as dayjs from 'dayjs';
import advancedAnalyticsDatamartPage from '../pageObjects/advancedAnalyticsDataSourcePageObject';
const dataSourcePage = new advancedAnalyticsDatamartPage();
const dataSourceName = `Cypress_Test_Data_Source_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const dataSourceNameEdit = `Cypress_Test_Data_Source_Edit_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const dataSourceDescription = 'Test data source made in Cypress - smoke tests';
const dataSourceDescriptionEdit = 'Edited test data source made in Cypress - smoke tests';
const standardDataSourceName = `Cypress_Test_Standard_Data_Source_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const standardDataSourceNameEdit = `Cypress_Test_Standard_Data_Source_Edit_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const standardDataSourceDescription = 'Test standard data source made in Cypress - smoke tests';
const standardDataSourceDescriptionEdit = 'Edited test standard data source made in Cypress - smoke tests';
before(() => {
cy.vaultLoginByUserTitle('IDTestUser');
});
afterEach(() => {
cy.visit('/');
});
after(() => {
cy.deleteDataSource(dataSourceName);
cy.deleteDataSource(dataSourceNameEdit);
});
describe('Advanced Analytics smoke tests', () => {
it('Create Data Source', () => {
dataSourcePage.addDataSource(dataSourceName, dataSourceDescription);
dataSourcePage.goToDataSources();
cy.findByText(dataSourceName).should('exist');
});
it('Edit Data Source', () => {
dataSourcePage.editDataSource(dataSourceName, dataSourceNameEdit, dataSourceDescriptionEdit);
cy.findByText('Save').click();
cy.findByText('Saved', { timeout: 5000 }).should('exist');
dataSourcePage.goToDataSources();
cy.findByText(dataSourceNameEdit).should('exist');
cy.findByText(dataSourceName).should('not.exist');
});
it('Delete Data Source', () => {
dataSourcePage.goToDataSources();
dataSourcePage.deleteDataSourceFromPage(dataSourceNameEdit);
dataSourcePage.goToDataSources();
cy.get('main').find('span').contains(dataSourceNameEdit).should('not.exist');
});
// Skipping until issue with IDTestUser not being a strata employee
it.skip('Create Standard Data Source', () => {
dataSourcePage.addStandardDataSource(standardDataSourceName, standardDataSourceDescription);
cy.findByText('Back to Standard Data Sources', { timeout: 5000 }).click();
cy.findByText(standardDataSourceName).should('exist');
});
// Skipping until issue with IDTestUser not being a strata employee
it.skip('Edit Standard Data Source', () => {
dataSourcePage.goToStandardDataSources();
//Verify unsaved changes are not kept
cy.goToStandardDataSource(standardDataSourceName);
dataSourcePage.openDataSourceEditWindow();
cy.get('#name').clear().type(standardDataSourceNameEdit);
cy.findByText('Apply').click();
cy.findByText('Back to Standard Data Sources').click();
cy.findByText('Discard your unsaved changes?').should('exist');
cy.findByText('Discard Changes').click();
cy.findByText('Standard Data Sources').should('exist');
cy.findByText(standardDataSourceName).should('exist');
cy.findByText(standardDataSourceNameEdit).should('not.exist');
//Verify changes are saved
dataSourcePage.editStandardDataSource(standardDataSourceName, standardDataSourceNameEdit, standardDataSourceDescriptionEdit);
cy.findByText('Save').click();
cy.findByText('Saved', { timeout: 5000 }).should('exist');
dataSourcePage.goToStandardDataSources();
cy.findByText(standardDataSourceNameEdit).should('exist');
cy.findByText(standardDataSourceName).should('not.exist');
});
// Skipping until issue with IDTestUser not being a strata employee
it.skip('Delete Standard Data Source', () => {
dataSourcePage.goToStandardDataSources();
dataSourcePage.deleteDataSourceFromPage(standardDataSourceNameEdit);
dataSourcePage.goToStandardDataSources();
cy.get('main').find('span').contains(standardDataSourceNameEdit).should('not.exist');
});
});
@@ -0,0 +1,111 @@
import * as dayjs from 'dayjs';
import advancedAnalyticsExtractPage from '../pageObjects/advancedAnalyticsExtractPageObject';
const extractPage = new advancedAnalyticsExtractPage();
const extractAdminName = `Cypress_Test_Extract_Admin_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const extractNonAdminName = `Cypress_Test_Extract_Non_Aadmin_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const extractAdminEditName = `Cypress_Test_Extract_Admin_Edit_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const extractNonAdminEditName = `Cypress_Test_Extract_Non_Admin_Edit_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const extractShareName = `Cypress_Test_Extract_Share_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const extractShareNoAccessName = `Cypress_Test_Extract_Share_No_Access_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const extractScheduleName = `Cypress_Test_Extract_Shedulee_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const extractDescription = 'Test extract made in Cypress - CRUD';
const extractEditDescription = 'Test extract made in Cypress - CRUD - edit';
const extractShareDescription = 'Test extract made in Cypress - Share';
const extractScheduleDescription = 'Test extract made in Cypress - Schedule';
before(() => {
cy.vaultLoginByUserTitle('obAdmin');
});
beforeEach(() => {
cy.visit('/extracts');
});
after(() => {
cy.switchUser('IDTestUser');
cy.visit('/extracts');
cy.deleteExtract(extractAdminName);
cy.deleteExtract(extractNonAdminName);
cy.deleteExtract(extractAdminEditName);
cy.deleteExtract(extractNonAdminEditName);
cy.deleteExtract(extractShareName);
cy.deleteExtract(extractShareNoAccessName);
cy.deleteExtract(extractScheduleName);
});
describe('Advanced Analytics extract CRUD tests', () => {
it('Non-admin users can create extracts', () => {
extractPage.addNewExtract(extractNonAdminName, 'Encounter Summary', extractDescription);
cy.visit('/extracts');
cy.findByText(extractNonAdminName).should('exist');
});
it('Non-admin users can edit extracts', () => {
extractPage.editExtract(extractNonAdminName, extractNonAdminEditName, extractEditDescription);
cy.findByText(extractNonAdminEditName).should('exist');
cy.findByText(extractNonAdminName).should('not.exist');
});
it('Non-admin users can delete extracts', () => {
extractPage.deleteExtract(extractNonAdminEditName);
cy.findByText('Extracts').should('be.visible');
cy.findByText(extractNonAdminEditName).should('not.exist');
});
it('Admin users can create extracts', () => {
cy.switchUser('IDTestUser');
cy.visit('/extracts');
extractPage.addNewCustomExtract(extractAdminName, extractDescription);
cy.findByText(extractAdminName).should('exist');
});
it('Admin users can edit extracts', () => {
extractPage.editExtract(extractAdminName, extractAdminEditName, extractEditDescription);
cy.findByText(extractAdminEditName).should('exist');
cy.findByText(extractAdminName).should('not.exist');
});
it('Admin users can delete extracts', () => {
extractPage.deleteExtract(extractAdminEditName);
cy.findByText('Extracts').should('be.visible');
cy.findByText(extractAdminEditName).should('not.exist');
});
});
describe('Advanced Analytics extract tests', () => {
it('Users can share extracts', () => {
extractPage.addNewCustomExtract(extractShareName, extractShareDescription);
cy.visit('/extracts');
cy.findByText(extractShareName).should('exist');
extractPage.shareExtract(extractShareName, 'Capital - System Administrator');
cy.visit('/extracts');
extractPage.addNewCustomExtract(extractShareNoAccessName, extractShareDescription);
cy.logout();
cy.vaultLoginByUserTitle('Capital Administrator');
cy.visit('/extracts');
cy.findByText(extractShareName).should('exist');
cy.findByText(extractShareNoAccessName).should('not.exist');
});
// Waiting on Jon's fix
it.skip('Scheduling an extract will create an entry in the UI', () => {
cy.switchUser('IDTestUser');
cy.visit('/extracts');
cy.addExtract(extractScheduleName, extractScheduleDescription, 'Encounter Summary');
extractPage.scheduleExtract(extractScheduleName, '2:35 A', 'Daily');
cy.findByText('Daily at 2:35 AM').should('exist');
});
// Waiting on Jon's fix
it.skip('User can enable and disable a schedule', () => {
cy.goToExtract(extractScheduleName);
extractPage.selectMenuOption('Schedule');
cy.get('.ant-switch').click();
cy.get('.ant-switch').invoke('attr', 'aria-checked').should('eq', 'true');
cy.findByText('Daily at 2:35 AM').should('exist');
cy.get('.ant-switch').click();
cy.get('.ant-switch').invoke('attr', 'aria-checked').should('eq', 'false');
cy.findByText('Daily at 2:35 AM').should('exist');
});
});
@@ -0,0 +1,433 @@
import * as dayjs from 'dayjs';
import advancedAnalyticsPage from '../pageObjects/advancedAnalyticsPageObject';
const advPage = new advancedAnalyticsPage();
const workbookName = `Cypress_Test_Workbook_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookDescription = 'Test workbook made in Cypress';
const dataSourceName = `Cypress_Test_Data_Source_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const dataSourceName2 = `Cypress_Test_Data_Source2_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const dataSourceNameNoAccess = `Cypress_Test_Data_Source_NoAccess_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const datamartDescription = 'Test datamart made in Cypress';
const dssPatientEncounter = '55370';
const generalLedgerAndStaffing = '55426';
before(() => {
cy.vaultLoginByUserTitle('IDTestUser');
cy.createDataSource(dataSourceName, datamartDescription);
cy.addTableToDataSource(dssPatientEncounter, dataSourceName);
cy.addUserToDataSource(dataSourceName, 'obadmin', 'viewer');
cy.createDataSource(dataSourceName2, datamartDescription);
cy.addTableToDataSource(generalLedgerAndStaffing, dataSourceName2);
cy.addUserToDataSource(dataSourceName2, 'obadmin', 'viewer');
cy.createDataSource(dataSourceNameNoAccess, datamartDescription);
cy.addTableToDataSource(dssPatientEncounter, dataSourceNameNoAccess);
cy.logout();
cy.vaultLogin(true);
cy.addWorkbook(workbookName, workbookDescription, 'Encounter Summary');
cy.goToWorkbook(workbookName);
cy.wait(2000);
advPage.addDashboard();
cy.findByText('Save').click();
cy.wait(500);
});
beforeEach(() => {
cy.goToWorkbook(workbookName);
});
after(() => {
cy.logout();
cy.vaultLoginByUserTitle('IDTestUser');
cy.deleteDataSource(dataSourceName);
cy.deleteDataSource(dataSourceName2);
cy.deleteDataSource(dataSourceNameNoAccess);
cy.logout();
cy.vaultLogin(true);
cy.deleteWorkbook(workbookName);
cy.visit('/');
});
describe('Advanced Analytics widget filter tests', () => {
it('Calendar Date Time options are correctly disabled', () => {
advPage.addVisualizationWidget();
advPage.addwidgetFilter('Admit Date', 'Calendar Date Time');
advPage.openEditFilter('Admit Date - Calendar Date Time');
cy.wait(2000);
cy.get('.ant-popover-content').find('.ant-select-selector').click();
cy.get('.rc-virtual-list-holder-inner').findByText('Fiscal Year').click();
cy.findByText('Time Frame')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.findByText('Time Frame')
.parent()
.next()
.findByText('Calendar')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contains('disabled');
});
cy.findByText('List')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.get('.ant-popover-content').find('.ant-select-selector').click();
cy.get('.rc-virtual-list-holder-inner').findByText('Fiscal Quarter').click();
cy.findByText('Time Frame')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.findByText('Time Frame')
.parent()
.next()
.findByText('Calendar')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contains('disabled');
});
cy.findByText('List')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.get('.ant-popover-content').find('.ant-select-selector').click();
cy.get('.rc-virtual-list-holder-inner').findByText('Calendar Year').click();
cy.findByText('Time Frame')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.findByText('Time Frame')
.parent()
.next()
.findByText('Calendar')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.findByText('List')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.get('.ant-popover-content').find('.ant-select-selector').click();
cy.get('.rc-virtual-list-holder-inner').findByText('Month').click();
cy.findByText('Time Frame')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.findByText('Time Frame')
.parent()
.next()
.findByText('Calendar')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.findByText('List')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.get('.ant-popover-content').find('.ant-select-selector').click();
cy.get('.rc-virtual-list-holder-inner').findByText('Day').click();
cy.findByText('Time Frame')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.findByText('Time Frame')
.parent()
.next()
.findByText('Calendar')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).not.to.contains('disabled');
});
cy.findByText('List')
.prev()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contains('disabled');
});
cy.get('.ant-popover-content').findByText('Cancel').click();
cy.wait(500);
});
it('And/Or selection works correctly', () => {
advPage.addVisualizationWidget();
advPage.addwidgetFilter('Age', 'Age');
advPage.openEditFilter('Age - Age');
cy.findByText('Conditions').click();
cy.findByText('Add Condition').click();
cy.findByText('And').click();
cy.findByText('Add Condition').parent().parent().parent().siblings().last().contains('And').should('exist');
cy.findByText('Add Condition').parent().parent().parent().siblings().last().contains('Or').should('not.exist');
cy.findByText('Or').click();
cy.findByText('Add Condition').parent().parent().parent().siblings().last().contains('Or').should('exist');
cy.findByText('Add Condition').parent().parent().parent().siblings().last().contains('And').should('not.exist');
});
it('Not In shows up correctly', () => {
advPage.addVisualizationWidget();
advPage.addwidgetFilter('Age', 'Rollup');
advPage.openEditFilter('Age - Rollup');
cy.get('.tempo-action-bar__filters').find('input[type="checkbox"]').click();
cy.findByText('0-17').click();
cy.findByText('Apply').click();
cy.get('.filters-bar__item').should('contain', 'Not In: 0-17');
});
it('Filter can be renamed', () => {
advPage.addVisualizationWidget();
advPage.addwidgetFilter('Age', 'Rollup');
advPage.editFilterName('Age - Rollup', 'Updated Filter Name');
cy.findByText('Updated Filter Name:').should('exist');
});
it('Custom date filters', () => {
const filterAttribute = 'Calendar Date Time';
advPage.addVisualizationWidget();
advPage.addwidgetFilter('Admit Date', filterAttribute);
advPage.openEditFilter(`Admit Date - ${filterAttribute}`);
cy.get('.ant-popover-content').find('.ant-select-selector').click();
cy.get('.rc-virtual-list-holder-inner').findByText('Fiscal Year').click();
cy.findByText('Custom').click();
cy.findByText('Custom').parentsUntil('.tempo-spacing.tempo-spacing--col').last().next().find('input').click();
cy.findByText('This + Previous Fiscal Years').click();
cy.findByText('This + Previous').parent().next().clear().type('3');
cy.findByText('Apply').click();
cy.get('.filters-bar__item').contains(`${filterAttribute}: Custom`).should('exist');
advPage.openEditFilter(`Admit Date - ${filterAttribute}`);
cy.findByText('This + Previous').parent().next().should('have.value', '3');
});
it('Fiscal Year/Quarter filters are filtered to -10 and +8 years in a visualization widget', () => {
const tooEarlyYear = parseInt(dayjs().format('YYYY')) - 11;
const earliestYear = parseInt(dayjs().format('YYYY')) - 10;
const latestYear = parseInt(dayjs().format('YYYY')) + 8;
const toolateYear = parseInt(dayjs().format('YYYY')) + 9;
advPage.addVisualizationWidget();
advPage.addwidgetFilter('Admit Date', 'Calendar Date Time');
advPage.openEditFilter('Admit Date - Calendar Date Time');
cy.get('.ant-popover-content').find('.ant-select.ant-select-single.ant-select-show-arrow').click();
cy.findByText('Fiscal Year').click();
cy.findByText('List').click();
cy.findByText('This Fiscal Year').should('not.exist');
cy.get('.ant-spin.ant-spin-spinning', { timeout: 10000 }).should('exist');
cy.get('.ant-spin.ant-spin-spinning', { timeout: 10000 }).should('not.exist');
cy.get('.ant-popover-content').find('.p-datatable-scrollable-body-table').should('exist');
cy.get('.tempo-datacell').contains(`FY${earliestYear}`).should('exist');
cy.get('.tempo-datacell').contains(`FY${tooEarlyYear}`).should('not.exist');
//This is commented out until data past 2026 is available
//cy.get('.tempo-datacell').contains(`FY${latestYear}`).should('exist');
cy.get('.tempo-datacell').contains(`FY${toolateYear}`).should('not.exist');
cy.get('.ant-popover-content').find('.ant-select.ant-select-single.ant-select-show-arrow').click();
cy.findByText('Fiscal Quarter').click();
cy.get('.tempo-datacell').contains(`FY${earliestYear} Q1`).should('exist');
cy.get('.tempo-datacell').contains(`FY${tooEarlyYear} Q4`).should('not.exist');
//This is commented out until data past 2026 is available
//cy.get('.tempo-datacell').contains(`FY${latestYear} Q4`).should('exist');
cy.get('.tempo-datacell').contains(`FY${toolateYear} Q1`).should('not.exist');
});
it('Fiscal Year/Quarter filters are filtered to -10 and +8 years in a data sheet', () => {
const tooEarlyYear = parseInt(dayjs().format('YYYY')) - 11;
const earliestYear = parseInt(dayjs().format('YYYY')) - 10;
const latestYear = parseInt(dayjs().format('YYYY')) + 8;
const toolateYear = parseInt(dayjs().format('YYYY')) + 9;
advPage.addDataAnlysisSheet();
advPage.addwidgetFilter('Admit Date', 'Calendar Date Time');
advPage.openEditFilter('Admit Date - Calendar Date Time');
cy.get('.ant-popover-content').find('.ant-select.ant-select-single.ant-select-show-arrow').click();
cy.findByText('Fiscal Year').click();
cy.findByText('List').click();
cy.findByText('This Fiscal Year').should('not.exist');
cy.get('.ant-spin.ant-spin-spinning', { timeout: 10000 }).should('exist');
cy.get('.ant-spin.ant-spin-spinning', { timeout: 10000 }).should('not.exist');
cy.get('.ant-popover-content').find('.p-datatable-scrollable-body-table').should('exist');
cy.get('.tempo-datacell').contains(`FY${earliestYear}`).should('exist');
cy.get('.tempo-datacell').contains(`FY${tooEarlyYear}`).should('not.exist');
//This is commented out until data past 2026 is available
//cy.get('.tempo-datacell').contains(`FY${latestYear}`).should('exist');
cy.get('.tempo-datacell').contains(`FY${toolateYear}`).should('not.exist');
cy.get('.ant-popover-content').find('.ant-select.ant-select-single.ant-select-show-arrow').click();
cy.findByText('Fiscal Quarter').click();
cy.get('.tempo-datacell').contains(`FY${earliestYear} Q1`).should('exist');
cy.get('.tempo-datacell').contains(`FY${tooEarlyYear} Q4`).should('not.exist');
//This is commented out until data past 2026 is available
//cy.get('.tempo-datacell').contains(`FY${latestYear} Q4`).should('exist');
cy.get('.tempo-datacell').contains(`FY${toolateYear} Q1`).should('not.exist');
});
// JAZZ-58142
it.skip('Create filter by custom list option', () => {
advPage.addDataAnlysisSheet();
advPage.addwidgetFilter('Admit Date', 'Calendar Month');
advPage.openEditFilter('Admit Date - Calendar Month');
cy.findByText('Custom List').click();
cy.findByText('Upload List', { timeout: 5000 }).should('exist');
cy.get('#list').type('5, 6, 7, 9, 10');
cy.findByText('Apply').click();
cy.findByText('Configure').should('not.exist');
cy.wait(5000);
advPage.dragAndDropArea('Admit Date', 'Calendar Month', 'Rows');
advPage.dragAndDropArea('Measures', 'Account Balance', 'Columns');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view', { timeout: 5000 }).find('.p-treetable-row.p-treetable-row--child').contains('5').should('exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view', { timeout: 5000 }).find('.p-treetable-row.p-treetable-row--child').contains('6').should('exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view', { timeout: 5000 }).find('.p-treetable-row.p-treetable-row--child').contains('7').should('exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view', { timeout: 5000 }).find('.p-treetable-row.p-treetable-row--child').contains('9').should('exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view', { timeout: 5000 }).find('.p-treetable-row.p-treetable-row--child').contains('10').should('exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view', { timeout: 5000 }).find('.p-treetable-row.p-treetable-row--child').contains('4').should('not.exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view', { timeout: 5000 }).find('.p-treetable-row.p-treetable-row--child').contains('8').should('not.exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view', { timeout: 5000 }).find('.p-treetable-row.p-treetable-row--child').contains('11').should('not.exist');
});
// JAZZ-58142
it.skip('New list filter option overwrites the old selection', () => {
advPage.addDataAnlysisSheet();
advPage.addwidgetFilter('Admit Date', 'Calendar Month');
advPage.openEditFilter('Admit Date - Calendar Month');
cy.findByText('Custom List').click();
cy.findByText('Upload List', { timeout: 5000 }).should('exist');
cy.get('#list').type('5, 6, 7, 9, 10');
cy.findByText('Apply').click();
cy.findByText('Configure').should('not.exist');
cy.wait(5000);
advPage.setFilterValue('Admit Date - Calendar Month', '8');
cy.wait(5000);
advPage.dragAndDropArea('Admit Date', 'Calendar Month', 'Rows');
advPage.dragAndDropArea('Measures', 'Account Balance', 'Columns');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-row.p-treetable-row--child').contains('8').should('exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-row.p-treetable-row--child').contains('5').should('not.exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-row.p-treetable-row--child').contains('6').should('not.exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-row.p-treetable-row--child').contains('7').should('not.exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-row.p-treetable-row--child').contains('9').should('not.exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-row.p-treetable-row--child').contains('10').should('not.exist');
advPage.openEditFilter('Admit Date - Calendar Month');
cy.findByText('Custom List').click();
cy.findByText('Upload List', { timeout: 5000 }).should('exist');
cy.get('#list').type('11\n12');
cy.findByText('Apply').click();
cy.findByText('Configure').should('not.exist');
cy.wait(5000);
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-row.p-treetable-row--child').contains('11').should('exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-row.p-treetable-row--child').contains('12').should('exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-row.p-treetable-row--child').contains('8').should('not.exist');
});
});
describe('Advanced Analytics dashboard filter tests', () => {
it('Dashboard filter can have datamart changed', () => {
cy.findByText('Add Filter').click();
cy.findByText('Admit Date').should('exist');
cy.findByText('Charge Code').should('not.exist');
advPage.setCurrentDashboardFilterDataSource(dataSourceName2);
cy.findByText('Charge Code').should('exist');
cy.findByText('Admit Date').should('not.exist');
});
it('User cannot select a datamart they do not have access to', () => {
cy.findByText('Add Filter').click();
cy.findByTitle('Dimensions').parent().find('.ant-tree-switcher.ant-tree-switcher_open', { timeout: 10000 }).should('exist');
cy.findByText('Data Source').parent().next().click();
cy.findByText(dataSourceName).should('exist');
cy.findByText(dataSourceNameNoAccess).should('not.exist');
});
it('User cannot add multiple filters of the same attribute', () => {
advPage.addDashboardFilter('Admit Date', 'Calendar Month');
advPage.addDashboardFilter('Admit Date', 'Calendar Month');
cy.wait(1000);
cy.get('.ant-popover-content').findByText('Add').should('exist');
cy.get('.filters-bar__item').should('have.length', 1);
});
it('User can edit filters in present mode', () => {
advPage.addDashboardFilter('Admit Date', 'Calendar Month');
advPage.setDashboardFilter('Admit Date - Calendar Month', '1');
cy.findByText('Save').click();
cy.findByText('Saved').should('exist');
cy.findByText('Present').click();
cy.findByText('Exit').should('exist');
advPage.setDashboardFilter('Admit Date - Calendar Month', '2');
cy.findByText('Exit').click();
cy.findByText('Save').should('exist');
});
it('Fiscal Year/Quarter filters are filtered to -10 and +8 years in dashboard filter', () => {
const tooEarlyYear = parseInt(dayjs().format('YYYY')) - 11;
const earliestYear = parseInt(dayjs().format('YYYY')) - 10;
const latestYear = parseInt(dayjs().format('YYYY')) + 8;
const toolateYear = parseInt(dayjs().format('YYYY')) + 9;
advPage.addDashboardFilter('Admit Date', 'Calendar Date Time');
cy.findByText('Admit Date - Calendar Date Time:').click();
cy.get('.ant-popover-content').find('.ant-select.ant-select-single.ant-select-show-arrow').click();
cy.findByText('Fiscal Year').click();
cy.findByText('List').click();
cy.findByText('This Fiscal Year').should('not.exist');
cy.get('.ant-spin.ant-spin-spinning', { timeout: 10000 }).should('exist');
cy.get('.ant-spin.ant-spin-spinning', { timeout: 10000 }).should('not.exist');
cy.get('.ant-popover-content').find('.p-datatable-scrollable-body-table').should('exist');
cy.get('.tempo-datacell').contains(`FY${earliestYear}`).should('exist');
cy.get('.tempo-datacell').contains(`FY${tooEarlyYear}`).should('not.exist');
//This is commented out until data past 2026 is available
//cy.get('.tempo-datacell').contains(`FY${latestYear}`).should('exist');
cy.get('.tempo-datacell').contains(`FY${toolateYear}`).should('not.exist');
cy.get('.ant-popover-content').find('.ant-select.ant-select-single.ant-select-show-arrow').click();
cy.findByText('Fiscal Quarter').click();
cy.get('.tempo-datacell').contains(`FY${earliestYear} Q1`).should('exist');
cy.get('.tempo-datacell').contains(`FY${tooEarlyYear} Q4`).should('not.exist');
//This is commented out until data past 2026 is available
//cy.get('.tempo-datacell').contains(`FY${latestYear} Q4`).should('exist');
cy.get('.tempo-datacell').contains(`FY${toolateYear} Q1`).should('not.exist');
});
});
@@ -0,0 +1,42 @@
import * as dayjs from 'dayjs';
import advancedAnalyticsPage from '../pageObjects/advancedAnalyticsPageObject';
const advPage = new advancedAnalyticsPage();
const workbookName = `Cypress_Test_Workbook_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookDescription = 'Test workbook made in Cypress - search tests';
before(() => {
cy.vaultLogin(true);
cy.wait(1000);
cy.addWorkbook(workbookName, workbookDescription, 'Encounter Summary');
cy.visit('/');
cy.goToWorkbook(workbookName);
advPage.addDashboard();
cy.findByText('Add Widget').click();
cy.findByText('Add Visual').click();
cy.wait(2000);
});
after(() => {
cy.deleteWorkbook(workbookName);
cy.visit('/');
});
describe('Advanced Analytics search tests', () => {
it('Clearing search will return to default state', () => {
advPage.expandNode('Account Class', 'open');
cy.get('div').contains('Account Class Code').should('exist');
cy.get('div').contains('Account Class Description').should('exist');
advPage.searchForAttribute('Admit Date');
advPage.expandNode('Admit Date', 'open');
cy.wait(500);
cy.get('span[title="Admit Date"]').should('exist');
cy.get('div').contains('Calendar Date Time').should('exist');
cy.get('div').contains('Calendar Month').should('exist');
advPage.clearSearch();
cy.get('span[title="Admit Date"]').should('exist');
cy.get('div').contains('Calendar Date Time').should('not.exist');
cy.get('div').contains('Calendar Month').should('not.exist');
cy.get('div').contains('Account Class Code').should('not.exist');
cy.get('div').contains('Account Class Description').should('not.exist');
});
});
@@ -0,0 +1,68 @@
import * as dayjs from 'dayjs';
import advancedAnalyticsPage from '../pageObjects/advancedAnalyticsPageObject';
const advPage = new advancedAnalyticsPage();
const workbookName = `Cypress_Test_Workbook_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const deleteWorkbookName = `dummy_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookDescription = 'Test workbook made in Cypress - smoke tests';
before(() => {
cy.vaultLogin(true);
});
afterEach(() => {
cy.visit('/');
});
after(() => {
cy.logout();
cy.vaultLogin(true);
cy.deleteWorkbook(workbookName);
cy.deleteWorkbook(deleteWorkbookName);
});
describe('Advanced Analytics smoke tests', () => {
it('Create workbook', () => {
advPage.createWorkbook(workbookName, 'Encounter Summary', workbookDescription);
advPage.addDashboard();
advPage.addDashboardWidget(
'Bar',
'Clustered',
[{ dimensionGroup: 'Account Class', dimensionName: 'Account Class Code' }],
[{ measureGroup: 'Measures', mesureName: 'Account Balance' }],
[{ dimensionsOrMeasures: 'Dimensions', filterAttributeGroup: 'Age', filterAttributeName: 'Rollup', filterAttributeValue: '0-17' }]
);
advPage.addDataAnalysis([{ dimensionGroup: 'Account Class', dimensionName: 'Account Class Code' }], [{ measureGroup: 'Measures', mesureName: 'Account Balance' }]);
cy.findByText('Save').click();
cy.findByText('Saved').should('exist');
});
it('Update workbook', () => {
advPage.selectWorkbookFromTable(workbookName);
advPage.openEditWidget('Untitled Visualization');
advPage.deleteAttributeFromWidget('Account Class - Account Class Code', 'Categories');
cy.wait(2000);
advPage.addAttributeToWidget('Account Class', 'Account Class Description', 'Dimensions', 'Categories');
//Commented out because of JAZZ-58105
//advPage.setFilterValue('Rollup', '18-64');
advPage.saveWidget();
cy.findByText('Save').click();
cy.findByText('Saved').should('exist');
});
it('Delete all dashboards', () => {
cy.goToWorkbook(workbookName);
advPage.deleteDashboard('Dashboard');
advPage.deleteDashboard('Data Sheet');
cy.findByText('New workbook content available from Add button.').should('exist');
});
it('Delete workbook', () => {
cy.goToWorkbook(workbookName);
advPage.deleteWorkbookFromWorkbook(workbookName);
cy.addWorkbook(deleteWorkbookName, workbookDescription, 'Encounter Summary');
cy.visit('/');
advPage.deleteWorkbookFromTable(deleteWorkbookName);
});
});
@@ -0,0 +1,463 @@
import * as dayjs from 'dayjs';
import advancedAnalyticsPage from '../pageObjects/advancedAnalyticsPageObject';
const advPage = new advancedAnalyticsPage();
const workbookName = `Cypress_Test_Workbook_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookName2 = `Cypress_Test_Workbook2_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookName3 = `Cypress_Test_Workbook3_Crossout_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const dataSourceName = `Cypress_Test_Data_Source_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const dataSourceName2 = `Cypress_Test_Data_Source_For_Crossout_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookDescription = 'Test workbook made in Cypress - widget tests';
const workbookDescription2 = 'Test workbook made in Cypress - widget tests - crossout';
const dataSourceDescription = 'Test data source made in Cypress - widget tests';
const dataSourceDescription2 = 'Test data source made in Cypress - widget tests - crossout';
const dssPatientEncounter = '55370';
const generalLedgerAndStaffing = '55426';
const formula = 'sum([Actual Dollars])*0+0.1234567';
before(() => {
cy.vaultLoginByUserTitle('IDTestUser');
cy.createDataSource(dataSourceName, dataSourceDescription);
cy.createDataSource(dataSourceName2, dataSourceDescription2);
cy.addTableToDataSource(generalLedgerAndStaffing, dataSourceName);
cy.addTableToDataSource(generalLedgerAndStaffing, dataSourceName2);
cy.addTableToDataSource(dssPatientEncounter, dataSourceName2);
cy.addUserToDataSource(dataSourceName, 'obadmin', 'viewer');
cy.addUserToDataSource(dataSourceName2, 'obadmin', 'viewer');
cy.logout();
cy.vaultLogin(true);
cy.addWorkbook(workbookName, workbookDescription, 'Encounter Summary');
cy.addWorkbook(workbookName2, workbookDescription, dataSourceName);
cy.addWorkbook(workbookName3, workbookDescription2, dataSourceName2);
cy.visit('/');
cy.goToWorkbook(workbookName);
advPage.addDashboard();
cy.findByText('Add Widget').click();
cy.findByText('Add Text').click();
cy.findByText('Ok').click();
cy.findByText('Save').click();
cy.findByText('Saved').should('exist');
});
beforeEach(() => {
cy.goToWorkbook(workbookName);
cy.wait(1000);
});
after(() => {
cy.logout();
cy.vaultLoginByUserTitle('IDTestUser');
cy.deleteDataSource(dataSourceName);
cy.deleteDataSource(dataSourceName2);
cy.logout();
cy.vaultLogin(true);
cy.deleteWorkbook(workbookName);
cy.deleteWorkbook(workbookName2);
cy.deleteWorkbook(workbookName3);
cy.logout();
cy.vaultLoginByUserTitle('IDTestUser');
cy.deleteDataSource(dataSourceName);
});
describe('Advanced Analytics text widget tests', () => {
it('Text widget - formatting options', () => {
advPage.editTextWidget();
//Bold
cy.get('.ql-bold').click();
cy.get('.ant-modal-content').find('.ql-editor').type('Bold Text\n');
cy.get('.ql-bold').click();
//Italics
cy.get('.ql-italic').click();
cy.get('.ant-modal-content').find('.ql-editor').type('Italic Text\n');
cy.get('.ql-italic').click();
//Underline
cy.get('.ql-underline').click();
cy.get('.ant-modal-content').find('.ql-editor').type('Underline Text\n');
cy.get('.ql-underline').click();
//Strikeout
cy.get('.ql-strike').click();
cy.get('.ant-modal-content').find('.ql-editor').type('Strikeout Text\n');
cy.get('.ql-strike').click();
cy.get('strong').should(($p) => {
expect($p).to.contain('Bold Text');
});
cy.get('em').should(($p) => {
expect($p).to.contain('Italic Text');
});
cy.get('u').should(($p) => {
expect($p).to.contain('Underline Text');
});
cy.get('s').should(($p) => {
expect($p).to.contain('Strikeout Text');
});
});
it('Text widget - Hyperlink testing', () => {
advPage.editTextWidget();
const text = 'Hyperlink Text';
cy.get('.ant-modal-content').find('.ql-editor').type(`${text}\n`);
cy.get('.ant-modal-content').find('.ql-editor').type('{selectall}');
cy.get('.ql-link').click();
cy.get('div[class$="ql-editing"]').find('input').type('https://www.google.com');
cy.get('.ql-action').click();
cy.wait(1000);
cy.findByText('Ok').click();
cy.wait(1000);
cy.get('a')
.contains(text)
.invoke('attr', 'href')
.then((classVal) => {
expect(classVal).to.be.equal('https://www.google.com');
});
cy.get('a').contains(text).click();
cy.wait(5000);
cy.location('href').should((loc) => {
expect(loc).contains('https://www.google.com');
});
});
});
describe('Advanced Analytics visualization widget tests', () => {
it('Visualization Widget - Each type has the correct options', () => {
cy.findByText('Add Widget').click();
cy.findByText('Add Visual').click();
cy.findByText('Visualization Type').parent().next().click();
cy.get('.ant-select-item-option-content').contains('Bar').click();
cy.findByText('Visualization Type').parent().next().next().click();
cy.get('div[aria-label="Clustered"]').should('exist');
cy.get('div[aria-label="Stacked"]').should('exist');
cy.findByText('Visualization Type').parent().next().click();
cy.get('.ant-select-item-option-content').contains('Column').click();
cy.findByText('Visualization Type').parent().next().next().click();
cy.get('div[aria-label="Clustered"]').should('exist');
cy.get('div[aria-label="Stacked"]').should('exist');
cy.findByText('Visualization Type').parent().next().click();
cy.get('.ant-select-item-option-content').contains('Line').click();
cy.findByText('Visualization Type').parent().next().next().should('not.exist');
cy.findByText('Visualization Type').parent().next().click();
cy.get('.ant-select-item-option-content').contains('Pie').click();
cy.findByText('Visualization Type').parent().next().next().click();
cy.get('div[aria-label="Donut"]').should('exist');
cy.get('div[aria-label="Pie"]').should('exist');
cy.findByText('Visualization Type').parent().next().click();
cy.get('.ant-select-item-option-content').contains('Calendar').click();
cy.findByText('Visualization Type').parent().next().next().should('not.exist');
cy.findByText('Visualization Type').parent().next().click();
cy.get('.ant-select-item-option-content').contains('Metric').click();
cy.findByText('Visualization Type').parent().next().next().should('not.exist');
});
it('Visualization Widget - create pie chart', () => {
advPage.addDashboardWidget('Pie', 'Pie', [{ dimensionGroup: 'Age', dimensionName: 'Rollup' }], [{ measureGroup: 'Measures', mesureName: 'Net Revenue' }]);
});
it('Switching around the legend', () => {
advPage.addDashboardWidgetWithPivots(
'Bar',
[{ dimensionGroup: 'Age', dimensionName: 'Rollup' }],
[{ measureGroup: 'Measures', mesureName: 'Net Revenue' }],
[{ pivoteGroup: 'Admit Date', pivotName: 'Fiscal Year' }]
);
advPage.openEditWidget('Untitled Visualization');
cy.findByText('Design').click();
cy.findByText('Positioning').scrollIntoView();
cy.wait(2000);
cy.findByText('Top').click({ force: true });
cy.wait(2000);
cy.findByText('Right').click({ force: true });
cy.wait(2000);
cy.findByText('Bottom').click({ force: true });
cy.wait(2000);
cy.findByText('Left').click({ force: true });
cy.wait(2000);
});
it('Switching data marts in a widget', () => {
cy.goToWorkbook(workbookName);
advPage.addVisualizationWidget();
advPage.dragAndDropArea('Account Class', 'Account Class Code', 'Categories');
advPage.dragAndDropArea('Measures', 'Account Balance', 'Values');
advPage.clearSearch();
//Account Class is in the original data mart and Charge Code is in the one that will be changed to
cy.findByText('Account Class').should('exist');
cy.findByText('Charge Code').should('not.exist');
advPage.switchDataSource(dataSourceName);
cy.contains('Encounter Summary').should('not.exist');
cy.contains(dataSourceName).should('exist');
cy.get('.data-designer__fields').find('div').contains('Account Class Code').should('not.exist');
cy.get('.data-designer__fields').find('div').contains('Account Balance').should('not.exist');
//Charge Code is in the new data mart and Account Class was in the original data mart
cy.findByText('Account Class').should('not.exist');
cy.findByText('Charge Code').should('exist');
});
// Cross out was taken out
it.skip('Cross out for dimensions and measures in data vizualization widget', () => {
cy.logout();
cy.vaultLoginByUserTitle('IDTestUser');
cy.addTableToDataSource(dssPatientEncounter, dataSourceName);
cy.logout();
cy.vaultLogin(true);
cy.goToWorkbook(workbookName2);
advPage.addDashboard();
advPage.addVisualizationWidget();
//Categories
advPage.dragAndDropArea('Account Class', 'Account Class Code', 'Categories');
advPage.searchForAttribute('Actual Dollars');
cy.get('div')
.contains('Actual Dollars')
.parentsUntil('.ant-tree-treenode.ant-tree-treenode-disabled')
.last()
.parent()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contain('ant-tree-treenode-disabled');
});
advPage.clearSearch();
//Values
advPage.deleteAttributeFromWidget('Account Class - Account Class Code', 'Categories');
advPage.dragAndDropArea('Measures', 'Actual Dollars', 'Values');
advPage.searchForAttribute('Account Class Code');
cy.get('div')
.contains('Account Class Code')
.parentsUntil('.ant-tree-treenode.ant-tree-treenode-disabled')
.last()
.parent()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contain('ant-tree-treenode-disabled');
});
advPage.clearSearch();
//Break By
advPage.deleteAttributeFromWidget('Actual Dollars', 'Values');
advPage.dragAndDropArea('Account Class', 'Account Class Code', 'Break By');
advPage.searchForAttribute('Actual Dollars');
cy.get('div')
.contains('Actual Dollars')
.parentsUntil('.ant-tree-treenode.ant-tree-treenode-disabled')
.last()
.parent()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contain('ant-tree-treenode-disabled');
});
advPage.clearSearch();
//Filters
advPage.deleteAttributeFromWidget('Account Class - Account Class Code', 'Break By');
advPage.addwidgetFilter('Measures', 'Actual Dollars');
advPage.searchForAttribute('Account Class Code');
cy.get('div')
.contains('Account Class Code')
.parentsUntil('.ant-tree-treenode.ant-tree-treenode-disabled')
.last()
.parent()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contain('ant-tree-treenode-disabled');
});
advPage.clearSearch();
});
});
describe('Advanced Analytics data analysis tests', () => {
// Cross out was taken out
it.skip('Cross out for dimensions and measures in data analysis', () => {
cy.goToWorkbook(workbookName3);
advPage.addDataAnlysisSheet();
//Rows
advPage.dragAndDropArea('Account Class', 'Account Class Code', 'Rows');
advPage.searchForAttribute('Actual Dollars');
cy.get('div')
.contains('Actual Dollars')
.parentsUntil('.ant-tree-treenode.ant-tree-treenode-disabled')
.last()
.parent()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contain('ant-tree-treenode-disabled');
});
advPage.clearSearch();
//Values
advPage.deleteAttributeFromWidget('Account Class - Account Class Code', 'Rows');
advPage.dragAndDropArea('Measures', 'Actual Dollars', 'Columns');
advPage.searchForAttribute('Account Class Code');
cy.get('div')
.contains('Account Class Code')
.parentsUntil('.ant-tree-treenode.ant-tree-treenode-disabled')
.last()
.parent()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contain('ant-tree-treenode-disabled');
});
advPage.clearSearch();
//Filters
advPage.deleteAttributeFromWidget('Actual Dollars', 'Columns');
advPage.addwidgetFilter('Account Class', 'Account Class Code');
advPage.searchForAttribute('Actual Dollars');
cy.get('div')
.contains('Actual Dollars')
.parentsUntil('.ant-tree-treenode.ant-tree-treenode-disabled')
.last()
.parent()
.invoke('attr', 'class')
.then((classVal) => {
expect(classVal).to.contain('ant-tree-treenode-disabled');
});
advPage.clearSearch();
});
it('Duplicate values', () => {
cy.goToWorkbook(workbookName3);
advPage.addDataAnlysisSheet();
advPage.dragAndDropArea('Measures', 'Account Balance', 'Columns');
advPage.duplicateValue('Account Balance', 'Account Balance_1');
cy.findAllByText('Account Balance_1').should('exist');
});
it('Test decimal places in data sheets', () => {
cy.goToWorkbook(workbookName3);
advPage.addDataAnlysisSheet();
advPage.dragAndDropArea('Account Class', 'Account Class Code', 'Rows');
advPage.addDataSheetCustomCalculatedValue('test', null, formula);
advPage.addDataSheetCustomCalculatedValue('test 2', 'Number (2 Decimals)', formula);
advPage.addDataSheetCustomCalculatedValue('test 3', 'Number (4 Decimals)', formula);
cy.findByText('0.12', { timeout: 10000 }).should('exist');
cy.findByText('0.1235', { timeout: 10000 }).should('exist');
});
it('Measures can be added to multiple groups when they exist', () => {
advPage.addDataAnlysisSheet();
advPage.addNewDataSheetGroup();
advPage.addNewDataSheetGroup();
advPage.dragAndDropArea('Measures', 'Account Balance', 'Columns');
advPage.dragAndDropArea('Measures', 'Birth Weight', 'Columns', 1);
cy.get('.fields').eq(1).findByText('Account Balance').should('exist');
cy.get('.fields').eq(2).findByText('Birth Weight').should('exist');
advPage.deleteNumberedDataSheetGroup(2);
cy.get('.fields').eq(1).findByText('Account Balance').should('exist');
cy.get('.fields').eq(2).findByText('Birth Weight').should('not.exist');
});
it('Test disabling auto refresh', () => {
cy.goToWorkbook(workbookName);
advPage.addDataAnlysisSheet();
//cy.findByText('Turn on Auto Refresh to see current data').should('not.exist');
cy.findByText('Auto Refresh').click();
//cy.findByText('Turn on Auto Refresh to see current data').should('exist');
advPage.dragAndDropArea('Account Class', 'Account Class Code', 'Rows');
advPage.dragAndDropArea('Measures', 'Account Balance', 'Columns');
cy.get('.p-treetable-scrollable-wrapper').children().eq(0).findByText('Auto Refresh Disabled').should('exist');
cy.get('.p-treetable-scrollable-wrapper').children().eq(1).findByText('Auto Refresh Disabled').should('exist');
cy.get('.p-treetable-scrollable-wrapper').children().eq(0).find('.p-treetable-scrollable-header').findByText('Account Class Code').should('not.exist');
cy.get('.p-treetable-scrollable-wrapper').children().eq(1).find('.p-treetable-scrollable-header').findByText('Account Balance').should('exist');
cy.findByText('Auto Refresh').click();
cy.get('ant-spin.ant-spin-spinning', { timeout: 10000 }).should('not.exist');
cy.get('.p-treetable-scrollable-view.p-treetable-frozen-view').find('.p-treetable-tbody').findByText('0');
cy.get('.p-treetable-scrollable-view.p-treetable-unfrozen-view').find('.p-treetable-tbody').findByText('28,375,615');
});
it('Calculated values cannot be saved without all fields filled in', () => {
cy.goToWorkbook(workbookName3);
advPage.addDataAnlysisSheet();
cy.findByText('Columns').parentsUntil('.fields-column-header').last().next().click();
cy.findByText('Add Calculation').click();
cy.get('#name').should('be.visible');
cy.get('.calculated-value-editor').find('textarea').type(formula, { force: true }).wait(1000);
cy.findByText('Apply').click({ force: true });
cy.findByTitle('Name').parent().next().findByText('Required').should('exist');
cy.findByTitle('Calculation').parent().next().findByText('Required').should('not.exist');
cy.findByText('Cancel').click();
cy.findByText('Cancel').should('not.exist');
});
it('Creating a filter in a calculation with multiple tables', () => {
cy.goToWorkbook(workbookName2);
advPage.addDataAnlysisSheet();
advPage.dragAndDropArea('Account', 'Account Code', 'Rows');
advPage.addDataSheetCustomCalculatedValue('test', null, formula);
advPage.editValue('test', null, null, 'sum([Net Revenue]) - sum([Fixed Direct Cost]) + sum([Account Balance])');
advPage.openCalculatedValue('test');
advPage.addCalculationFilter('Account Class', 'Account Class Code');
cy.findByText('Apply').click({ force: true });
cy.get('.ant-modal-title').contains('test').should('not.exist');
});
it('Target moving an attribute into a column and row', () => {
cy.goToWorkbook(workbookName);
advPage.addDataAnlysisSheet();
cy.findByText('Auto Refresh').click();
advPage.dragAndDropArea('Account Class', 'Account Class Code', 'Rows');
advPage.dragAndDropArea('Measures', 'Account Balance', 'Columns');
advPage.dragAndDropAreaToPosition('Account Class', 'Account Class', 'Rows', 0);
advPage.dragAndDropAreaToPosition('Account Class', 'Account Class Description', 'Rows', 1);
advPage.dragAndDropAreaToPosition('Measures', 'Date Of Birth', 'Columns', 0);
cy.wait(3000);
//Tests the Expand To dropdown
cy.findByText('Expand To').parent().parent().click();
cy.get('.rc-virtual-list-holder-inner').children().first().invoke('attr', 'title').should('eq', 'Account Class - Account Class');
cy.get('.rc-virtual-list-holder-inner').children().eq(1).invoke('attr', 'title').should('eq', 'Account Class - Account Class Description');
cy.get('.rc-virtual-list-holder-inner').children().last().invoke('attr', 'title').should('eq', 'Account Class - Account Class Code');
//Checks the rows
cy.findAllByText('Rows').eq(0).parentsUntil('.fields').last().next().find('.sortable-list').children().first().findByText('Account Class - Account Class');
cy.findAllByText('Rows').eq(0).parentsUntil('.fields').last().next().find('.sortable-list').children().eq(1).findByText('Account Class - Account Class Description');
cy.findAllByText('Rows').eq(0).parentsUntil('.fields').last().next().find('.sortable-list').children().last().findByText('Account Class - Account Class Code');
//Checks the columns
cy.findAllByText('Columns').eq(0).parentsUntil('.fields').last().next().find('.sortable-list').children().first().findByText('Date Of Birth');
cy.findAllByText('Columns').eq(0).parentsUntil('.fields').last().next().find('.sortable-list').children().last().findByText('Account Balance');
});
it('Column groups can be duplicated', () => {
cy.goToWorkbook(workbookName);
advPage.addDataAnlysisSheet();
advPage.dragAndDropArea('Measures', 'Account Balance', 'Columns');
advPage.addDataSheetCustomCalculatedValueToNumberedGroup(1, 'test', null, 'sum([Net Revenue]) - sum([Fixed Direct Cost]) + sum([Account Balance])');
advPage.DuplicateGroup(1);
cy.findAllByText('Columns').should('have.length', 2);
});
});
@@ -0,0 +1,82 @@
import * as dayjs from 'dayjs';
import advancedAnalyticsPage from '../pageObjects/advancedAnalyticsPageObject';
const advPage = new advancedAnalyticsPage();
const workbookNameOb = `Cypress_Test_OB_Workbook_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookNameObShareViewer = `Cypress_Test_OB_Share_Viewer_Workbook_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookNameObShareEditor = `Cypress_Test_OB_Share_Editor_Workbook_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookNameCap = `Cypress_Test_Cap_Workbook_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookDescription = 'Test workbook made in Cypress - workbook security tests';
before(() => {
cy.vaultLogin(true);
cy.addWorkbook(workbookNameOb, workbookDescription, 'Encounter Summary');
cy.addWorkbook(workbookNameObShareViewer, workbookDescription, 'Encounter Summary');
cy.addUserToWorkbook(workbookNameObShareViewer, 'capadmin', 'viewer');
cy.addWorkbook(workbookNameObShareEditor, workbookDescription, 'Encounter Summary');
cy.addUserToWorkbook(workbookNameObShareEditor, 'capadmin', 'editor');
});
after(() => {
cy.logout();
cy.vaultLogin(true);
cy.deleteWorkbook(workbookNameOb);
cy.deleteWorkbook(workbookNameObShareViewer);
cy.deleteWorkbook(workbookNameObShareEditor);
cy.logout();
cy.vaultLoginByUserTitle('Capital Administrator');
cy.deleteWorkbook(workbookNameCap);
});
describe('Advanced Analytics workbook security tests', () => {
it('Users see the correct workbooks', () => {
cy.logout();
cy.vaultLoginByUserTitle('Capital Administrator');
cy.addWorkbook(workbookNameCap, workbookDescription, 'Encounter Summary');
cy.visit('/');
cy.findByText('Created by Me').click();
cy.get('main').find('span').contains(workbookNameCap).should('exist');
cy.get('main').find('span').contains(workbookNameOb).should('not.exist');
cy.get('main').find('span').contains(workbookNameObShareViewer).should('not.exist');
cy.get('main').find('span').contains(workbookNameObShareEditor).should('not.exist');
cy.findByText('Shared with Me').click();
cy.get('main').find('span').contains(workbookNameCap).should('not.exist');
cy.get('main').find('span').contains(workbookNameOb).should('not.exist');
cy.get('main').find('span').contains(workbookNameObShareViewer).should('exist');
cy.get('main').find('span').contains(workbookNameObShareEditor).should('exist');
cy.goToWorkbook(workbookNameObShareEditor);
cy.findByText('Add').should('exist');
advPage.openWorkbookKabob(workbookNameObShareEditor);
cy.findByText('Edit').should('exist');
cy.findByText('Open in a New Tab').should('exist');
cy.findByText('Share').should('exist');
cy.findByText('Delete').should('exist');
cy.goToWorkbook(workbookNameObShareViewer);
cy.findByText('Add').should('not.exist');
advPage.openWorkbookKabobOneButton(workbookNameObShareViewer);
cy.findByText('Edit').should('not.be.visible');
cy.findByText('Open in a New Tab').should('exist');
cy.findByText('Share').should('not.be.visible');
cy.findByText('Delete').should('not.be.visible');
cy.logout();
cy.vaultLogin(true);
cy.findByText('Created by Me').click();
cy.get('main').find('span').contains(workbookNameCap).should('not.exist');
cy.get('main').find('span').contains(workbookNameOb).should('exist');
cy.get('main').find('span').contains(workbookNameObShareViewer).should('exist');
cy.get('main').find('span').contains(workbookNameObShareEditor).should('exist');
cy.findByText('Shared with Me').click();
cy.get('main').find('span').contains(workbookNameCap).should('not.exist');
cy.get('main').find('span').contains(workbookNameOb).should('not.exist');
cy.get('main').find('span').contains(workbookNameObShareViewer).should('not.exist');
cy.get('main').find('span').contains(workbookNameObShareEditor).should('not.exist');
});
});
@@ -0,0 +1,31 @@
import * as dayjs from 'dayjs';
import advancedAnalyticsPage from '../pageObjects/advancedAnalyticsPageObject';
const advPage = new advancedAnalyticsPage();
const workbookName = `Cypress_Test_Workbook_migrate_adhoc_${dayjs().format('YYYY-MM-DD_HHmmss')}`;
const workbookDescription = 'Test workbook made in Cypress - migrate from ad-hoc';
before(() => {
cy.vaultLoginByUserTitle('IDTestUser');
cy.addWorkbook(workbookName, workbookDescription, 'Encounter Summary');
});
beforeEach(() => {
cy.goToWorkbook(workbookName);
});
afterEach(() => {
cy.visit('/');
});
after(() => {
cy.deleteWorkbook(workbookName);
});
describe('Advanced Analytics smoke tests', () => {
it('Add from ad-hoc with multiple columns', () => {
advPage.addFromAdHoc('BK Test Migrate');
cy.get('.fields').eq(0).findByText('Admit Date - Fiscal Year').should('exist');
cy.get('.fields').eq(1).findByText('Cases').should('exist');
});
});
@@ -0,0 +1,89 @@
export default class advancedAnalyticsPage {
addDataSource = (dataSourceName: string, dataSourceDescription?: string | undefined): void => {
this.goToDataSources();
cy.findByText('Add Data Source').click();
this.fillOutDataSourceDetailsForm(dataSourceName, dataSourceDescription);
};
addStandardDataSource = (dataSourceName: string, dataSourceDescription?: string | undefined): void => {
this.goToStandardDataSources();
cy.findByText('Add Standard Data Source').click();
this.fillOutDataSourceDetailsForm(dataSourceName, dataSourceDescription);
};
editDataSource = (oldDataSourceName: string, dataSourceName: string, dataSourceDescription?: string | undefined): void => {
cy.goToDataSource(oldDataSourceName);
cy.get('h1').contains(oldDataSourceName, { timeout: 5000 }).should('exist');
this.editCurrentDataSource(dataSourceName, dataSourceDescription);
};
editStandardDataSource = (oldDataSourceName: string, dataSourceName: string, dataSourceDescription?: string | undefined): void => {
cy.goToStandardDataSource(oldDataSourceName);
cy.get('h1').contains(oldDataSourceName, { timeout: 5000 }).should('exist');
this.editCurrentDataSource(dataSourceName, dataSourceDescription);
};
deleteDataSourceFromPage = (dataSourceName: string): void => {
cy.findByText(dataSourceName).parentsUntil('tr').last().siblings().last().find('span[aria-label="delete"]').click({ force: true });
cy.get('span').contains(`Permanently delete ${dataSourceName}?`).parentsUntil('.ant-modal-confirm-body-wrapper').last().next().findByText('Delete Data Source').click();
};
deleteStandardDataSourceFromPage = (dataSourceName: string): void => {
cy.findByText(dataSourceName).parentsUntil('tr').last().siblings().last().find('span[aria-label="delete"]').click({ force: true });
cy.get('span').contains(`Permanently delete ${dataSourceName}?`).parentsUntil('.ant-modal-confirm-body-wrapper').last().next().findByText('Delete Data Source').click();
};
goToDataSources = (): void => {
cy.visit('/datasources');
};
goToStandardDataSources = (): void => {
cy.visit('/standard-datasources');
};
fillOutDataSourceDetailsForm = (dataSourceName: string, dataSourceDescription?: string | undefined): void => {
cy.get('#name').clear();
cy.get('#name').type(dataSourceName);
if (dataSourceDescription !== undefined) {
cy.get('#description').clear().type(dataSourceDescription);
}
cy.findByText('Apply').click();
cy.get('#name', { timeout: 5000 }).should('not.exist');
};
openDataSourceEditWindow = (): void => {
cy.get('.tempo-header--extra-wrapper').find('button').first().click();
cy.findByText('Edit').click();
};
editCurrentDataSource = (dataSourceName: string, dataSourceDescription?: string | undefined): void => {
this.openDataSourceEditWindow();
this.fillOutDataSourceDetailsForm(dataSourceName, dataSourceDescription);
};
addDataTable = (dataTableName: string): void => {
cy.findByText('Add Data Table').click();
cy.wait(500);
cy.get('.ant-modal-body').find('input').type(dataTableName);
cy.wait(500);
cy.findByText(dataTableName).click();
cy.findByText('Apply').click();
};
addUsersToDataSource = (dataSourceName: string, userNames: { userName: string }[]): void => {
cy.goToDataSource(dataSourceName);
cy.findByText(dataSourceName).should('exist');
cy.findByText(dataSourceName).parentsUntil('.tempo-header').next().find('button').first().click();
cy.findByText('Security').click();
cy.findByText('Add Users').click();
cy.wait(2000);
userNames.forEach((username) => {
cy.get('.ant-drawer-body').find('input[type="text"]').type(username.userName);
cy.get('span').contains(username.userName).click();
cy.get('.ant-drawer-body').find('input[type="text"]').clear();
});
cy.findByText('Add').click();
cy.findByText('Save').click();
cy.wait(2000);
};
}
@@ -0,0 +1,100 @@
export default class advancedAnalyticsPage {
addNewExtract = (extractName: string, extractDataSource: string, extractDescription?: string | undefined): void => {
cy.findByText('Add Extract').click();
cy.get('.ant-dropdown-menu-title-content').contains('Extract').click();
cy.get('#name').type(extractName);
if (extractDescription !== undefined) {
cy.get('#description').type(extractDescription);
}
cy.get('#dataSourceId').click();
cy.findByText(extractDataSource).click();
cy.findByText('Save').click();
cy.findByText(extractName).should('exist');
};
addNewCustomExtract = (extractName: string, extractDescription?: string | undefined): void => {
cy.findByText('Add Extract').click();
cy.findByText('Custom Sql Extract').click();
cy.get('#name').type(extractName);
if (extractDescription !== undefined) {
cy.get('#description').type(extractDescription);
}
cy.findByText('Save').click();
cy.findByText(extractName).should('exist');
};
editExtract = (extractName: string, newExtractName: string, newExtractDescription?: string | undefined): void => {
this.goToExtract(extractName);
cy.findByText('Back to Extracts').should('exist');
cy.findByText(extractName).should('exist');
this.selectMenuOption('Edit');
cy.findByText('Edit Extract').should('exist');
cy.get('#name').clear().type(newExtractName);
if (newExtractDescription !== undefined) {
cy.get('#description').clear().type(newExtractDescription);
}
cy.findByText('Apply').click();
};
deleteExtract = (extractName: string): void => {
cy.get('.tempo-link__text').then((items) => {
const list = Array.from(items, (item) => item.innerText);
list.forEach((element) => {
if (element === extractName) {
cy.findByText(extractName).parentsUntil('.p-datatable-tbody').last().find('.anticon.anticon-delete').scrollIntoView();
cy.findByText(extractName).parentsUntil('.p-datatable-tbody').last().find('.anticon.anticon-delete').click();
cy.findByText('Delete Extract').click();
cy.findByText(`Permanently delete ${extractName}?`).should('not.exist');
}
});
});
};
goToExtract = (extractName: string): void => {
cy.findByText(extractName).click();
cy.get('h1').contains(extractName).should('exist');
};
shareExtract = (extractName: string, userGroupName: string): void => {
this.goToExtract(extractName);
this.selectMenuOption('Share');
cy.findByText(`Share ${extractName}`).should('exist');
cy.findByText('Add Groups').click();
cy.findByText('User Groups').should('exist');
cy.get('input[type="text"]').type(userGroupName);
cy.wait(500);
cy.get('span').contains(userGroupName).click();
cy.get('.ant-drawer-title').contains('Add Groups').parentsUntil('.ant-drawer-wrapper-body').last().siblings().last().findByText('Add').click();
cy.findByText(`Share ${extractName}`).should('exist');
cy.findByText('Save').click();
cy.findByText(`Share ${extractName}`).should('not.exist');
};
scheduleExtract = (extractName: string, startTime: string, frequency: string): void => {
cy.goToExtract(extractName);
this.selectMenuOption('Schedule');
cy.findByText('Schedule Extract', { timeout: 5000 }).should('exist');
cy.wait(3000);
cy.findByText('Add Schedule').click();
cy.get('#startTime', { timeout: 2000 }).should('exist');
cy.get('#startTime').click();
cy.get('#startTime').clear().type(startTime).type('{enter}');
cy.findByText('Repeats').parent().next().click();
cy.get('span').contains(frequency).click();
cy.findByText('Save').click();
cy.get('#startTime', { timeout: 2000 }).should('not.exist');
};
selectMenuOption = (menuOption: string): void => {
cy.findByText('Export').parentsUntil('.tempo-spacing.tempo-spacing--row').last().next().click();
cy.findByText(menuOption).click();
};
}
@@ -0,0 +1,511 @@
export default class advancedAnalyticsPage {
createWorkbook = (workbookName: string, dataSourceName: string, workbookDescription?: string | undefined): void => {
cy.visit('/');
cy.findByText('Add Workbook').click({ force: true });
cy.get('#name').type(workbookName);
cy.get('#description').type(workbookDescription);
cy.get('#defaultDataSourceId').click();
cy.findByText(dataSourceName).click();
cy.findByText('Save').click();
cy.wait(2000);
};
addDashboard = (): void => {
cy.findByText('Add').click();
cy.findByText('Dashboard').click();
};
addDashboardWidget = (
widgetType: string,
widgetSubtype: string,
rowValues: { dimensionGroup: string; dimensionName: string }[],
valuesValues: { measureGroup: string; mesureName: string }[],
filters?: { dimensionsOrMeasures: string; filterAttributeGroup: string; filterAttributeName: string; filterAttributeValue: string }[] | undefined
): void => {
this.addVisualizationWidget();
this.setWidgetType(widgetType, widgetSubtype);
rowValues.forEach((rowValue) => {
this.dragAndDropArea(rowValue.dimensionGroup, rowValue.dimensionName, 'Categories');
});
valuesValues.forEach((valuesValue) => {
this.dragAndDropArea(valuesValue.measureGroup, valuesValue.mesureName, 'Values');
});
//Commented out because of JAZZ-58105
//if (filters !== undefined) {
// filters.forEach((filter) => {
// this.addwidgetFilter(filter.filterAttributeGroup, filter.filterAttributeName, filter.filterAttributeValue);
// });
//}
cy.get('.ant-modal-content').findByText('Save').click();
};
saveWidget = () => {
cy.get('.ant-modal-content').findByText('Save').click();
};
setWidgetType = (widgetType: string, widgetSubType: string) => {
cy.findByText('Visualization Type').parent().next().click();
cy.get('.ant-select-item-option-content').contains(widgetType).click();
cy.findByText('Visualization Type').parent().next().next().click();
cy.findAllByRole('listbox').last().next().findByText(widgetSubType).click();
};
addVisualizationWidget = (): void => {
cy.findByText('Add Widget').click();
cy.findByText('Add Visual').click();
cy.findByTitle('Dimensions').parent().find('.ant-tree-switcher.ant-tree-switcher_open', { timeout: 10000 }).should('exist');
};
addDataAnlysisSheet = (): void => {
cy.findByText('Add').click();
cy.findByText('Data Sheet').click();
cy.findByTitle('Dimensions').parent().find('.ant-tree-switcher.ant-tree-switcher_open', { timeout: 10000 }).should('exist');
};
addAttributesToWidget = (attributes: { attributeGroup: string; attributeName: string; sectionName: string; attributeDestination: string }[]): void => {
attributes.forEach((attribute) => {
this.addAttributeToWidget(attribute.attributeGroup, attribute.attributeName, attribute.sectionName, attribute.attributeDestination);
});
};
addAttributeToWidget = (attributeGroup: string, attributeName: string, attributeSection: string, attributeDestination: string): void => {
this.dragAndDropArea(attributeGroup, attributeName, attributeDestination);
};
addDashboardWidgetWithPivots = (
widgetType: string,
rowValues: { dimensionGroup: string; dimensionName: string }[],
valuesValues: { measureGroup: string; mesureName: string }[],
pivotValues: { pivoteGroup: string; pivotName: string }[],
filters?: { filterAttributeGroup: string; filterAttributeName: string; filterAttributeValue: string }[] | undefined
): void => {
this.addVisualizationWidget();
rowValues.forEach((rowValue) => {
this.dragAndDropArea(rowValue.dimensionGroup, rowValue.dimensionName, 'Categories');
});
valuesValues.forEach((valuesValue) => {
this.dragAndDropArea(valuesValue.measureGroup, valuesValue.mesureName, 'Values');
});
pivotValues.forEach((pivotValue) => {
this.dragAndDropArea(pivotValue.pivoteGroup, pivotValue.pivotName, 'Break By');
});
if (filters !== undefined) {
filters.forEach((filter) => {
this.addwidgetFilter(filter.filterAttributeGroup, filter.filterAttributeName, filter.filterAttributeValue);
});
}
cy.findByText('Save').click();
};
expandNode = (nodeName: string, openOrClose: string): void => {
cy.findByTitle(nodeName)
.invoke('attr', 'class')
.then((classVal) => {
if (classVal.includes('ant-tree-node-content-wrapper-close') && openOrClose === 'open') {
cy.findByTitle(nodeName).siblings().last().click();
}
if (classVal.includes('ant-tree-node-content-wrapper-open') && openOrClose === 'close') {
cy.findByTitle(nodeName).siblings().last().click();
}
});
cy.wait(500);
};
addDataAnalysis = (
rowValues: { dimensionGroup: string; dimensionName: string }[],
valuesValues: { measureGroup: string; mesureName: string }[],
filters?: { dimensionsOrMeasures: string; filterAttributeGroup: string; filterAttributeName: string; filterAttributeValue: string }[] | undefined
): void => {
this.addDataAnlysisSheet();
rowValues.forEach((rowValue) => {
this.dragAndDropArea(rowValue.dimensionGroup, rowValue.dimensionName, 'Rows');
});
valuesValues.forEach((valuesValue) => {
this.dragAndDropArea(valuesValue.measureGroup, valuesValue.mesureName, 'Columns');
});
if (filters === undefined) return;
filters.forEach((filter) => {
this.addwidgetFilter(filter.filterAttributeGroup, filter.filterAttributeName);
});
};
dragAndDropArea = (dimensionGroup: string, dimensionName: string, areaToDrop: string, whichSection = 0): void => {
const dataTransfer = new DataTransfer();
this.searchForAttribute(dimensionName);
this.expandNode(dimensionGroup, 'open');
cy.get(`span[title="${dimensionGroup}"]`).parent().next().findByText(dimensionName).trigger('dragstart', {
dataTransfer
});
cy.findAllByText(areaToDrop).then((elm) => {
const elementLength = elm.length;
if (elementLength === 1) {
whichSection = 0;
cy.log(`There were not multiple ${areaToDrop} sections, defaulting to 0`);
cy.findAllByText(areaToDrop).eq(0).parentsUntil('.fields').last().next().trigger('drop', {
dataTransfer
});
} else {
cy.findAllByText(areaToDrop).eq(whichSection).parentsUntil('.fields').last().next().trigger('drop', {
dataTransfer
});
}
});
this.clearSearch();
};
dragAndDropAreaToPosition = (dimensionGroup: string, dimensionName: string, areaToDrop: string, positionNumber: number, whichSection = 0): void => {
const dataTransfer = new DataTransfer();
this.searchForAttribute(dimensionName);
this.expandNode(dimensionGroup, 'open');
cy.get(`span[title="${dimensionGroup}"]`).parent().next().findByText(dimensionName).trigger('dragstart', {
dataTransfer
});
cy.findAllByText(areaToDrop).then((elm) => {
const numberOfSections = elm.length;
cy.log(`Number of elements is ${numberOfSections}`);
if (numberOfSections === 1) {
whichSection = 0;
cy.log(`There were not multiple ${areaToDrop} sections, defaulting to 0`);
cy.findAllByText(areaToDrop).eq(0).parentsUntil('.fields').last().next().find(`#div-dropzone-${positionNumber}`).trigger('drop', {
dataTransfer
});
} else {
cy.findAllByText(areaToDrop).eq(whichSection).parentsUntil('.fields').last().next().find(`#div-dropzone-${positionNumber}`).trigger('drop', {
dataTransfer
});
}
});
};
addwidgetFilter = (dimensionGroup: string, dimensionName: string, filterValue?: string | null): void => {
const dataTransfer = new DataTransfer();
this.searchForAttribute(dimensionName);
this.expandNode(dimensionGroup, 'open');
cy.get(`span[title="${dimensionGroup}"]`).parent().next().findByText(dimensionName).trigger('dragstart', {
dataTransfer
});
cy.get('.filters-bar').findByText('Filters').parent().parent().parent().next().trigger('drop', {
dataTransfer
});
if (filterValue != null) {
cy.findByText(filterValue).click();
}
cy.findByText('Apply').click();
};
addCalculationFilter = (filterAttributeGroup: string, filterAttribute: string): void => {
cy.findByText('Add Filter').click();
cy.get('.ant-modal-content').find('input').type(filterAttribute);
cy.findByTitle(filterAttributeGroup).parent().next().findByTitle(filterAttribute).click();
cy.get('.ant-modal-content').findByText('Apply').click();
cy.findByText('Filter').should('not.exist');
};
searchForAttribute = (attributeName: string): void => {
cy.get('input[name="Search"]').clear().type(attributeName).wait(500);
};
setFilterValue = (filterAttribute: string, filterValue: string): void => {
cy.wait(1);
this.openEditFilter(filterAttribute);
cy.findByText('List').click();
cy.get('.tempo-action-bar__filters').find('input[inputmode="text"]').clear().type(filterValue).wait(1000);
cy.findByText(filterValue).click();
cy.findByText('Apply').click();
};
openEditFilter = (filter: string): void => {
cy.get('.filters-bar').findByText(`${filter}:`).click();
};
openEditWidget = (widgetName: string): void => {
cy.findByText(widgetName)
.parent()
.parent()
.parent()
.parent()
.then((widget) => {
cy.wrap(widget).trigger('mouseover');
cy.wrap(widget).find('span[aria-label="edit"]').click();
});
};
selectWorkbookFromTable = (workbookName: string): void => {
cy.get('main').findByText(workbookName).click();
};
selectWorkbookFromPane = (workbookName: string): void => {
cy.get('.ant-menu-item-group').findByText(workbookName).parent().click();
};
deleteAttributesFromWidget = (attributes: { attributeName: string; sectionName: string }[]): void => {
attributes.forEach((attribute) => {
this.deleteAttributeFromWidget(attribute.attributeName, attribute.sectionName);
});
};
deleteAttributeFromWidget = (attributeName: string, sectionName: string): void => {
if (sectionName === 'Values' || sectionName === 'Columns') {
this.deleteAttributeFromValues(attributeName, sectionName);
} else {
cy.get('.designer').findByText(sectionName).parentsUntil('.fields').last().next().findByText(attributeName).next().find('span[aria-label="delete"]').click();
}
};
deleteAttributeFromValues = (attributeName: string, sectionName: string): void => {
cy.get('.designer').findByText(sectionName).parentsUntil('.fields').last().next().findByText(attributeName).next().click();
cy.findByText('Delete').click();
};
deleteWorkbookFromWorkbook = (workbookName: string): void => {
cy.goToWorkbook(workbookName);
this.openWorkbookKabob(workbookName);
cy.findByText('Delete').click().wait(1000);
cy.get('.ant-modal-confirm-btns').findByText('Delete Workbook').click();
cy.findByText('Delete Workbook').should('not.exist');
};
deleteWorkbookFromTable = (workbookName: string): void => {
cy.visit('/');
cy.get('.p-datatable-tbody').findByText(workbookName).parent().parent().parent().find('span[class$="anticon-delete"]').click();
cy.get('.ant-modal-confirm-btns').findByText('Delete Workbook').click();
cy.findByText('Delete Workbook').should('not.exist');
};
deleteDashboard = (dashboardName: string): void => {
cy.get('.worksheet-tab__title').contains(dashboardName).next().click();
cy.findByText('Delete').click();
cy.findByText(`Delete ${dashboardName}`).should('exist');
cy.findByText('Cancel').parent().next().click();
cy.findByText(`Delete ${dashboardName}`).should('not.exist');
};
clearSearch = (): void => {
cy.get('input[name="Search"]').next().click();
};
editTextWidget = (): void => {
cy.get('.text-widget--richtext').trigger('mouseover');
cy.get('.ql-snow').parent().prev().find('span[class$="anticon-edit"]').click();
};
addDataSource = (dataSourceName: string, dataSourceDescription?: string | undefined): void => {
this.goToDataSources();
cy.findByText('Add Data Source').click();
cy.get('#name').type(dataSourceName);
cy.get('#description').type(dataSourceDescription);
cy.findByText('Apply').click();
};
goToDataSources = (): void => {
cy.visit('/datasources');
};
shareWorkbook = (workbookName: string, userName: string): void => {
cy.goToWorkbook(workbookName);
this.openWorkbookKabob(workbookName);
cy.findByText('Share').click();
cy.findByText('Add User').click();
cy.findByText('Users').parentsUntil('.ant-drawer-body').last().find('.ant-tabs-content-holder').find('input[type="text"]').type(userName);
cy.get('span').contains(userName).click();
cy.get('.ant-drawer-title').contains('Add User').parent().siblings().last().findByText('Add').click();
cy.wait(2000);
cy.findByText('Save').click();
cy.wait(2000);
};
openWorkbookKabobOneButton = (workbookName: string): void => {
cy.get('.ant-layout-content').findByText(workbookName).parentsUntil('.tempo-header').last().next().find('button').click();
};
openWorkbookKabob = (workbookName: string): void => {
cy.get('.ant-layout-content').findByText(workbookName).parentsUntil('.tempo-header').last().next().findByText('Present').parentsUntil('.tempo-spacing.tempo-spacing--row').last().next().click();
};
setRoleOfWorkbookSharedUser = (workbookName: string, userName: string, viewerOrEditor: string): void => {
cy.goToWorkbook(workbookName);
this.openWorkbookKabob(workbookName);
cy.findByText('Share').click();
cy.get('div').contains(userName).parent().next().click();
cy.get('.ant-select-item-option-content').contains(viewerOrEditor).click();
cy.findByText('Save').click();
cy.wait(2000);
};
switchDataSource = (newDataSourceName: string): void => {
cy.get('.designer__datasource-tree-selector').prev().find('button').click();
cy.findByTitle('Data Source').parent().next().find('.ant-form-item-control-input').click();
cy.findByText(newDataSourceName).click();
cy.wait(2000);
cy.findByText('Change Data Source').parentsUntil('.ant-modal-content').last().parent().findByText('Save').click();
//cy.get('.ant-modal-content').findByText('Save').click({ force: true });
};
addDashboardFilter = (filterGroup: string, filterMember: string, dataSourceName?: string | undefined): void => {
cy.findByText('Add Filter').click();
cy.findByTitle('Dimensions').parent().find('.ant-tree-switcher.ant-tree-switcher_open', { timeout: 10000 }).should('exist');
this.searchForAttribute(filterMember);
cy.findByTitle(filterGroup).parent().next().findByTitle(filterMember).click();
if (dataSourceName !== undefined) {
this.setCurrentDashboardFilterDataSource(dataSourceName);
}
cy.get('.ant-popover-content').findByText('Add').click();
};
setDashboardFilterDataSource = (filterName: string, newDataSourceName: string): void => {
cy.findByText(`${filterName}:`).click();
this.setCurrentDashboardFilterDataSource(newDataSourceName);
};
setCurrentDashboardFilterDataSource = (newDataSourceName: string): void => {
cy.findByText('Data Source').parent().next().click();
cy.findByText(newDataSourceName).scrollIntoView().click();
};
editFilterName = (filterName: string, newFilterName: string): void => {
cy.findByText(`${filterName}:`).click();
cy.findByText('Configure').click();
cy.get('#name').clear().type(newFilterName);
cy.findByText('Apply').click();
};
setDashboardFilter = (filterName: string, filterValue: string): void => {
this.openDashboardFilter(filterName);
cy.get('.tempo-action-bar__filters').find('input[inputmode="text"]').clear().type(filterValue).wait(1000);
cy.findByText(filterValue).click();
cy.findByText('Apply').click();
};
openDashboardFilter = (filterName: string): void => {
cy.get('.filters-bar__item').findByText(`${filterName}:`).click();
cy.findByText('Conditions').should('exist');
};
duplicateValue = (valueToDuplicate: string, duplicatedValueName: string): void => {
cy.get('.sortable-list-item__content').contains(valueToDuplicate).next().click();
cy.findByText('Duplicate').should('exist').click();
cy.get('#name', { timeout: 5000 }).should('exist');
cy.get('#name').clear().type(duplicatedValueName).wait(1000);
cy.findByText('Apply').click();
cy.get('#name', { timeout: 5000 }).should('not.exist');
};
editValue = (valueToUpdate: string, updateName?: string, updateFormula?: string, updateCalculation?: string): void => {
this.openCalculatedValue(valueToUpdate);
this.editCurrentCalculatedValue(updateName, updateFormula, updateCalculation);
cy.findByText('Apply').click({ force: true });
cy.findByText('Apply').should('not.exist');
};
openCalculatedValue = (valueToUpdate: string): void => {
cy.get('.sortable-list-item__content').contains(valueToUpdate).next().click();
cy.findByText('Edit').click();
cy.get('h3', { timeout: 5000 }).contains(valueToUpdate).should('exist');
};
editCurrentCalculatedValue = (calcValName?: string, calcValFormula?: string, calcValCalculation?: string): void => {
if (calcValName !== null) {
cy.get('#name').clear().type(calcValName).wait(1000);
}
if (calcValFormula !== null) {
cy.findByText('Format').parent().next().click();
cy.findByText(calcValFormula).click();
}
if (calcValCalculation !== null) {
cy.get('.calculated-value-editor').find('textarea').clear({ force: true }).type(calcValCalculation, { force: true }).wait(1000);
}
};
addCustomCalculatedValue = (calcValName: string, updateFormula?: string, updateCalculation?: string): void => {
cy.findByText('Values').parentsUntil('.fields-header').last().next().click();
cy.get('#name').should('be.visible');
this.editCurrentCalculatedValue(calcValName, updateFormula, updateCalculation);
cy.findByText('Apply').click();
cy.findByText('Apply').should('not.exist');
};
addDataSheetCustomCalculatedValue = (calcValName: string, updateFormula?: string, updateCalculation?: string): void => {
cy.findByText('Columns').parentsUntil('.fields-column-header').last().next().click();
cy.findByText('Add Calculation').click();
cy.get('#name').should('be.visible');
this.editCurrentCalculatedValue(calcValName, updateFormula, updateCalculation);
cy.findByText('Apply').click({ force: true });
cy.findByText('Apply').should('not.exist');
};
addDataSheetCustomCalculatedValueToNumberedGroup = (whichGroup: number, calcValName: string, calculationFormula?: string, calculationCalculation?: string): void => {
cy.findAllByText('Columns')
.eq(whichGroup - 1)
.parentsUntil('.fields-column-header')
.last()
.next()
.click();
cy.findByText('Add Calculation').click();
cy.get('#name').should('be.visible');
this.editCurrentCalculatedValue(calcValName, calculationFormula, calculationCalculation);
cy.findByText('Apply').click();
cy.findByText('Apply').should('not.exist');
};
addNewDataSheetGroup = (): void => {
cy.findAllByText('Columns').first().parentsUntil('.fields-column-header').last().next().click();
cy.findByText('Add Group').click();
};
DuplicateGroup = (whichGroup: number): void => {
cy.findAllByText('Columns')
.eq(whichGroup - 1)
.parentsUntil('.fields-column-header')
.last()
.next()
.click();
cy.findByText('Duplicate Group').click();
};
deleteNumberedDataSheetGroup = (whichGroup: number): void => {
cy.findAllByText('Columns')
.eq(whichGroup - 1)
.parentsUntil('.fields-column-header')
.last()
.next()
.click();
cy.findAllByText('Delete Group').last().click();
};
addFromAdHoc = (adHocReport: string): void => {
cy.findByText('Add').click();
cy.findByText('From Adhoc', { timeout: 5000 }).should('exist');
cy.findByText('From Adhoc').click();
cy.findByText('Create from Ad-hoc', { timeout: 10000 }).should('exist');
cy.get('.ant-input').type(adHocReport);
cy.findByText(adHocReport).click();
cy.findByText('Create').click();
cy.get('.worksheet-tab__title').contains(adHocReport, { timeout: 10000 }).should('exist');
};
}
+43
View File
@@ -0,0 +1,43 @@
import fs = require('fs');
import path = require('path');
import { spawnSync } from 'child_process';
import fsExtra = require('fs-extra');
/// <reference types="cypress" />
/// <reference types="cypress-plugin-snapshots" />
/// <reference types="cypress-iframe" />
// ***********************************************************
// 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)
/**
* @type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-var-requires
function getConfigurationByFile(file: any) {
const pathToConfigFile = path.resolve('..', 'cypress/cypress', `cypress.${file}.json`);
return fsExtra.readJson(pathToConfigFile);
}
const sleep = (ms: number) => {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
};
module.exports = (on: any, config: any) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
//initPlugin(on, config);
const configResolved = config.env.fileconfig != null ? getConfigurationByFile(config.env.fileconfig) : null;
return configResolved;
};
+6
View File
@@ -0,0 +1,6 @@
export interface IUserData {
Title: string;
UserName: string;
Password: string;
Description: string;
}
+401
View File
@@ -0,0 +1,401 @@
import '@testing-library/cypress/add-commands';
import { IUserData } from './IUserData';
// ***********************************************
// 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
// ***********************************************
//
//
// -- 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 '@testing-library/cypress/add-commands';
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface Chainable {
logout(): Chainable<Element>;
vaultLogin(admin?: boolean): Chainable<void>;
vaultLoginByUserTitle(userTitle: string): Chainable<void>;
switchUser(userTitle: string): Chainable<void>;
deleteWorkbook(workbookName: string): Chainable<void>;
addWorkbook(workbookName: string, workbookDescription: string, datamartName: string): Chainable<void>;
goToWorkbook(workbookName: string): Chainable<void>;
goToDataSource(dataMartName: string): Chainable<void>;
goToStandardDataSource(dataMartName: string): Chainable<void>;
verifyDataSourceExists(dataMartName: string): Chainable<void>;
verifyDataSourceDoesNotExist(dataMartName: string): Chainable<void>;
createDataSource(dataMartName: string, datamartDescription: string): Chainable<void>;
deleteDataSource(dataMartName: string): Chainable<void>;
addUserToDataSource(datamartName: string, userName: string, viewerOrEditor: string): Chainable<void>;
addTableToDataSource(dataTableId: string, dataMartName: string): Chainable<void>;
addUserToWorkbook(workbookName: string, userName: string, viewerOrEditor: string): Chainable<void>;
addExtract(extractName: string, extractDescription: string, datamartName: string): Chainable<void>;
goToExtract(extractName: string): Chainable<void>;
deleteExtract(extractName: string): Chainable<void>;
}
}
}
Cypress.Commands.add('logout', () => {
cy.window().then((win) => {
win.sessionStorage.clear();
});
cy.visit('/');
});
// USE THIS FOR ALL TEST LOGINS TO PULL FROM VAULT
Cypress.Commands.add('vaultLogin', (admin = true) => {
document.cookie = 'StrataIdentityServerLogin=true';
const userTitle = admin ? 'obAdmin' : 'capBasic';
cy.request({
method: 'GET',
url: `https://vault.sdt.local/api/searchpasswords/122?title=${userTitle}`,
headers: {
apiKey: 'a69d2e478c3f5b395b687ecdf34a3239'
}
})
.then((response) => response.body[0])
.then((user: IUserData) => {
// Test against your own test user
//cy.login(Cypress.env('username'), Cypress.env('password'), Cypress.env('dbguid'), Cypress.env('clientId'), '/');
cy.login(user.UserName, user.Password, Cypress.env('dbguid'), Cypress.env('clientId'), '/');
});
});
Cypress.Commands.add('vaultLoginByUserTitle', (userTitle: string) => {
document.cookie = 'StrataIdentityServerLogin=true';
cy.request({
method: 'GET',
url: `https://vault.sdt.local/api/searchpasswords/122?title=${userTitle}`,
headers: {
apiKey: 'a69d2e478c3f5b395b687ecdf34a3239'
}
})
.then((response) => response.body[0])
.then((user: IUserData) => {
// Test against your own test user
//cy.login(Cypress.env('username'), Cypress.env('password'), Cypress.env('dbguid'), Cypress.env('clientId'), '/');
cy.login(user.UserName, user.Password, Cypress.env('dbguid'), Cypress.env('clientId'), '/');
});
});
Cypress.Commands.add('switchUser', (userTitle: string) => {
cy.logout();
cy.vaultLoginByUserTitle(userTitle);
});
Cypress.Commands.add('deleteWorkbook', (workbookName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/workbooks`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const workbooks = response.body as { workbookId: string; name: string }[];
const matchingWorkbooks = workbooks.find((r) => r.name === workbookName);
if (matchingWorkbooks === undefined) return;
const workbookId = matchingWorkbooks.workbookId;
cy.request({
method: 'DELETE',
url: `${Cypress.env('apiUrl')}v1/workbooks/${workbookId}`,
headers: { Authorization: `Bearer ${token}` }
});
});
});
Cypress.Commands.add('addWorkbook', (workbookName: string, workbookDescription: string, dataSourceName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/data-sources`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const dataSources = response.body as { dataSourceId: string; name: string }[];
const dataSourceId = dataSources.find((r) => r.name === dataSourceName).dataSourceId;
cy.request({
method: 'POST',
url: `${Cypress.env('apiUrl')}v1/workbooks/`,
headers: { Authorization: `Bearer ${token}` },
body: {
name: workbookName,
description: workbookDescription,
defaultDataSourceId: dataSourceId
}
});
});
});
Cypress.Commands.add('goToWorkbook', (workbookName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/workbooks`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const workbooks = response.body as { workbookId: string; name: string }[];
const matchingWorkbooks = workbooks.find((r) => r.name === workbookName);
if (matchingWorkbooks === undefined) return;
const workbookId = matchingWorkbooks.workbookId;
cy.visit(`/workbooks/${workbookId}`);
});
cy.get('h1').findByText(workbookName, { timeout: 25000 }).should('exist');
});
Cypress.Commands.add('goToDataSource', (dataSourceName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/data-sources`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const dataSources = response.body as { dataSourceId: string; name: string }[];
const dataSourceId = dataSources.find((r) => r.name === dataSourceName).dataSourceId;
cy.visit(`/datasources/${dataSourceId}`);
});
});
Cypress.Commands.add('goToStandardDataSource', (dataSourceName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/standard-data-sources`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const dataSources = response.body as { standardDataSourceId: string; name: string }[];
const dataSourceId = dataSources.find((r) => r.name === dataSourceName).standardDataSourceId;
cy.visit(`/standard-datasources/${dataSourceId}`);
});
});
Cypress.Commands.add('verifyDataSourceExists', (dataSourceName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/data-sources`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const dataSources = response.body as { dataSourceId: string; name: string }[];
const dataSource = dataSources.find((r) => r.name === dataSourceName);
expect(dataSource.name).to.eq(dataSourceName);
});
});
Cypress.Commands.add('verifyDataSourceDoesNotExist', (dataSourceName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/data-sources`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const dataSources = response.body as { dataSourceId: string; name: string }[];
const dataSource = dataSources.find((r) => r.name === dataSourceName);
expect(dataSource).to.be(null);
});
});
Cypress.Commands.add('createDataSource', (dataSourceName: string, dataSourceDescription: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'POST',
url: `${Cypress.env('apiUrl')}v1/data-sources`,
headers: { Authorization: `Bearer ${token}` },
body: {
name: dataSourceName,
description: dataSourceDescription
}
});
});
Cypress.Commands.add('deleteDataSource', (dataSourceName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/data-sources`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const dataSources = response.body as { dataSourceId: string; name: string }[];
const matchingDataSources = dataSources.find((r) => r.name === dataSourceName);
if (matchingDataSources === undefined) return;
const dataSourceId = matchingDataSources.dataSourceId;
cy.request({
method: 'DELETE',
url: `${Cypress.env('apiUrl')}v1/data-sources/${dataSourceId}`,
headers: { Authorization: `Bearer ${token}` }
});
});
});
Cypress.Commands.add('addUserToDataSource', (dataSourceName: string, userName: string, viewerOrEditor: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/users`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const users = response.body as { userGuid: string; username: string }[];
const matchingUsers = users.find((r) => r.username === userName);
if (matchingUsers === undefined) return;
const userGuid = matchingUsers.userGuid;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/data-sources`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const dataSources = response.body as { dataSourceId: string; name: string }[];
const matchingDataSources = dataSources.find((r) => r.name === dataSourceName);
if (matchingDataSources === undefined) return;
const dataSourceId = matchingDataSources.dataSourceId;
cy.request({
method: 'POST',
url: `${Cypress.env('apiUrl')}v1/data-sources/${dataSourceId}/role-assignments/batch`,
headers: { Authorization: `Bearer ${token}` },
body: {
updates: [
{
identityGuid: userGuid,
identityName: userName,
identityType: 'user',
role: viewerOrEditor
}
]
}
});
});
});
});
Cypress.Commands.add('addTableToDataSource', (dataTableId: string, dataSourceName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/data-sources`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const dataSources = response.body as { dataSourceId: string; name: string }[];
const dataSourceId = dataSources.find((r) => r.name === dataSourceName).dataSourceId;
cy.request({
method: 'POST',
url: `${Cypress.env('apiUrl')}v1/data-sources/${dataSourceId}/tables/${dataTableId}`,
headers: { Authorization: `Bearer ${token}` }
});
});
});
Cypress.Commands.add('addUserToWorkbook', (workbookName: string, userName: string, viewerOrEditor: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/users`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const users = response.body as { userGuid: string; username: string }[];
const matchingUsers = users.find((r) => r.username === userName);
if (matchingUsers === undefined) return;
const userGuid = matchingUsers.userGuid;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/workbooks`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const workbooks = response.body as { workbookId: string; name: string }[];
const matchingWorkbooks = workbooks.find((r) => r.name === workbookName);
if (matchingWorkbooks === undefined) return;
const workbookId = matchingWorkbooks.workbookId;
cy.request({
method: 'POST',
url: `${Cypress.env('apiUrl')}v1/workbooks/${workbookId}/role-assignments/batch`,
headers: { Authorization: `Bearer ${token}` },
body: {
updates: [
{
identityGuid: userGuid,
identityName: userName,
identityType: 'user',
role: viewerOrEditor
}
]
}
});
});
});
});
Cypress.Commands.add('addExtract', (extractName: string, extractDescription: string, dataMartName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/data-sources`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const datamarts = response.body as { dataSourceId: string; name: string }[];
const dataSourceId = datamarts.find((r) => r.name === dataMartName).dataSourceId;
cy.request({
method: 'POST',
url: `${Cypress.env('apiUrl')}v1/extracts/`,
headers: { Authorization: `Bearer ${token}` },
body: {
name: extractName,
description: extractDescription,
defaultdataSourceId: dataSourceId
}
});
});
});
Cypress.Commands.add('goToExtract', (extractName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/extracts`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const extracts = response.body as { extractId: string; name: string }[];
const matchingExtracts = extracts.find((r) => r.name === extractName);
if (matchingExtracts === undefined) return;
const extractId = matchingExtracts.extractId;
cy.visit(`/extracts/${extractId}`);
});
cy.get('h1').findByText(extractName, { timeout: 25000 }).should('exist');
});
Cypress.Commands.add('deleteExtract', (extractName: string) => {
const token = JSON.parse(window.sessionStorage.getItem('oidc.user:https://identity.dev.stratanetwork.net/:StrataUI')).access_token;
cy.request({
method: 'GET',
url: `${Cypress.env('apiUrl')}v1/extracts`,
headers: { Authorization: `Bearer ${token}` }
}).then((response) => {
const extracts = response.body as { extractId: string; name: string }[];
const matchingExtracts = extracts.find((r) => r.name === extractName);
if (matchingExtracts === undefined) return;
const extractId = matchingExtracts.extractId;
cy.request({
method: 'DELETE',
url: `${Cypress.env('apiUrl')}v1/extracts/${extractId}`,
headers: { Authorization: `Bearer ${token}` }
});
});
});
+29
View File
@@ -0,0 +1,29 @@
// ***********************************************************
// 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';
import 'cypress-file-upload';
import { expandTreeCommand, selectTreeCommand, checkTreeCommand } from '@strata/cypress/lib/tree';
import { loginCommand } from '@strata/cypress/lib/login';
loginCommand();
expandTreeCommand();
selectTreeCommand();
checkTreeCommand();
// Alternatively you can use CommonJS syntax:
// require('./commands')
Cypress.on('uncaught:exception', (err) => !err.message.includes('ResizeObserver loop limit exceeded'));
+22
View File
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"noEmit": true,
"target": "es5",
"lib": [
"es5",
"dom"
],
"types": [
"cypress",
"@testing-library/cypress",
"node"
]
},
"include": [
"../node_modules",
"**/*.ts",
"support/commands.js",
"cypress/plugins/index.ts",
"cypress/support/index.js"
]
}
+9229
View File
File diff suppressed because it is too large Load Diff
+45
View File
@@ -0,0 +1,45 @@
{
"name": "advanced-analytics-e2e",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "cypress open",
"test-local": "cypress open --env fileconfig=local",
"test-dev": "cypress open --env fileconfig=development"
},
"eslintConfig": {
"extends": "@strata"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@percy/cli": "^1.17.0",
"@percy/cypress": "^3.1.2",
"@testing-library/cypress": "^8.0.2",
"@types/node": "^16.11.6",
"cypress": "^9.5.3",
"cypress-file-upload": "^5.0.8",
"cypress-iframe": "^1.0.1",
"js-base64": "^2.5.2",
"node-xlsx": "^0.17.2",
"typescript": "^4.6.3"
},
"dependencies": {
"@strata/cypress": "^1.7.0",
"@strata/eslint-config": "^3.6.0",
"@typescript-eslint/eslint-plugin": "^4.28.0",
"dayjs": "^1.11.7",
"eslint": "^7.29.0",
"eslint-plugin-flowtype": "^5.7.2",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"prettier": "^2.3.1"
},
"volta": {
"node": "14.19.1"
}
}