cypress_run () {
local specs="$1"
local timeout="$2"
- local override_config="ignoreTestFiles=*.po.ts,retries=0,testFiles=${specs},chromeWebSecurity=false"
+ local override_config="excludeSpecPattern=*.po.ts,retries=0,specPattern=${specs},chromeWebSecurity=false"
if [[ -n "$timeout" ]]; then
override_config="${override_config},defaultCommandTimeout=${timeout}"
fi
kcli ssh -u root ceph-node-00 'cephadm shell "ceph config set mgr mgr/prometheus/exclude_perf_counters false"'
-cypress_run ["orchestrator/workflow/*.feature, orchestrator/workflow/*-spec.ts"]
-cypress_run "orchestrator/grafana/*.feature"
+cypress_run ["cypress/e2e/orchestrator/workflow/*.feature, cypress/e2e/orchestrator/workflow/*-spec.ts"]
+cypress_run "cypress/e2e/orchestrator/grafana/*.feature"
--- /dev/null
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ video: true,
+ videoUploadOnPasses: false,
+ defaultCommandTimeout: 120000,
+ responseTimeout: 45000,
+ viewportHeight: 1080,
+ viewportWidth: 1920,
+ projectId: 'k7ab29',
+ reporter: 'cypress-multi-reporters',
+ reporterOptions: {
+ reporterEnabled: 'spec, mocha-junit-reporter',
+ mochaJunitReporterReporterOptions: {
+ mochaFile: 'cypress/reports/results-[hash].xml',
+ },
+ },
+ retries: 1,
+ env: {
+ LOGIN_USER: 'admin',
+ LOGIN_PWD: 'admin',
+ CEPH2_URL: 'https://localhost:4202/',
+ },
+ chromeWebSecurity: false,
+ eyesIsDisabled: false,
+ eyesFailCypressOnDiff: true,
+ eyesDisableBrowserFetching: false,
+ eyesLegacyHooks: true,
+ eyesTestConcurrency: 5,
+ eyesPort: 35321,
+ e2e: {
+ // We've imported your old cypress plugins here.
+ // You may want to clean this up later by importing these.
+ setupNodeEvents(on, config) {
+ return require('./cypress/plugins/index.js')(on, config)
+ },
+ baseUrl: 'https://localhost:4200/',
+ excludeSpecPattern: ['*.po.ts', '**/orchestrator/**'],
+ experimentalSessionAndOrigin: true,
+ specPattern: 'cypress/e2e/**/*-spec.{js,jsx,ts,tsx}',
+ },
+})
+++ /dev/null
-{
- "baseUrl": "https://localhost:4200/",
- "ignoreTestFiles": [
- "*.po.ts",
- "**/orchestrator/**"
- ],
- "supportFile": "cypress/support/index.ts",
- "video": true,
- "videoUploadOnPasses": false,
- "defaultCommandTimeout": 120000,
- "responseTimeout": 45000,
- "viewportHeight": 1080,
- "viewportWidth": 1920,
- "projectId": "k7ab29",
- "reporter": "cypress-multi-reporters",
- "reporterOptions": {
- "reporterEnabled": "spec, mocha-junit-reporter",
- "mochaJunitReporterReporterOptions": {
- "mochaFile": "cypress/reports/results-[hash].xml"
- }
- },
- "retries": 1,
- "env": {
- "LOGIN_USER": "admin",
- "LOGIN_PWD": "admin",
- "CEPH2_URL": "http://localhost:4202/"
- },
- "experimentalSessionAndOrigin": true,
- "chromeWebSecurity": false
-}
--- /dev/null
+import { DashboardPageHelper } from '../ui/dashboard.po';
+
+describe('Dashboard Main Page', { retries: 0 }, () => {
+ const dashboard = new DashboardPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ dashboard.navigateTo();
+ });
+
+ describe('Dashboard accessibility', () => {
+ it('should have no accessibility violations', () => {
+ cy.injectAxe();
+ cy.checkAccessibility(
+ {
+ exclude: [['.cd-navbar-main']]
+ },
+ {
+ rules: {
+ 'page-has-heading-one': { enabled: false }
+ }
+ }
+ );
+ });
+ });
+});
--- /dev/null
+import { NavigationPageHelper } from '../ui/navigation.po';
+
+describe('Navigation accessibility', { retries: 0 }, () => {
+ const shared = new NavigationPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ shared.navigateTo();
+ });
+
+ it('top-nav should have no accessibility violations', () => {
+ cy.injectAxe();
+ cy.checkAccessibility('.cd-navbar-top');
+ });
+
+ it('sidebar should have no accessibility violations', () => {
+ cy.injectAxe();
+ cy.checkAccessibility('nav[id=sidebar]');
+ });
+});
--- /dev/null
+import { PoolPageHelper } from '../pools/pools.po';
+import { ImagesPageHelper } from './images.po';
+
+describe('Images page', () => {
+ const pools = new PoolPageHelper();
+ const images = new ImagesPageHelper();
+
+ const poolName = 'e2e_images_pool';
+
+ before(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ // Need pool for image testing
+ pools.navigateTo('create');
+ pools.create(poolName, 8, 'rbd');
+ pools.existTableCell(poolName);
+ });
+
+ after(() => {
+ // Deletes images test pool
+ pools.navigateTo();
+ pools.delete(poolName);
+ pools.navigateTo();
+ pools.existTableCell(poolName, false);
+ });
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ images.navigateTo();
+ });
+
+ it('should open and show breadcrumb', () => {
+ images.expectBreadcrumbText('Images');
+ });
+
+ it('should show four tabs', () => {
+ images.getTabsCount().should('eq', 4);
+ });
+
+ it('should show text for all tabs', () => {
+ images.getTabText(0).should('eq', 'Images');
+ images.getTabText(1).should('eq', 'Namespaces');
+ images.getTabText(2).should('eq', 'Trash');
+ images.getTabText(3).should('eq', 'Overall Performance');
+ });
+
+ describe('create, edit & delete image test', () => {
+ const imageName = 'e2e_images#image';
+ const newImageName = 'e2e_images#image_new';
+
+ it('should create image', () => {
+ images.createImage(imageName, poolName, '1');
+ images.getFirstTableCell(imageName).should('exist');
+ });
+
+ it('should edit image', () => {
+ images.editImage(imageName, poolName, newImageName, '2');
+ images.getFirstTableCell(newImageName).should('exist');
+ });
+
+ it('should delete image', () => {
+ images.delete(newImageName);
+ });
+ });
+
+ describe('move to trash, restore and purge image tests', () => {
+ const imageName = 'e2e_trash#image';
+ const newImageName = 'e2e_newtrash#image';
+
+ before(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ // Need image for trash testing
+ images.createImage(imageName, poolName, '1');
+ images.getFirstTableCell(imageName).should('exist');
+ });
+
+ it('should move the image to the trash', () => {
+ images.moveToTrash(imageName);
+ images.getFirstTableCell(imageName).should('exist');
+ });
+
+ it('should restore image to images table', () => {
+ images.restoreImage(imageName, newImageName);
+ images.getFirstTableCell(newImageName).should('exist');
+ });
+
+ it('should purge trash in images trash tab', () => {
+ images.getFirstTableCell(newImageName).should('exist');
+ images.moveToTrash(newImageName);
+ images.purgeTrash(newImageName, poolName);
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class ImagesPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/block/rbd', id: 'cd-rbd-list' },
+ create: { url: '#/block/rbd/create', id: 'cd-rbd-form' }
+ };
+
+ // Creates a block image and fills in the name, pool, and size fields.
+ // Then checks if the image is present in the Images table.
+ createImage(name: string, pool: string, size: string) {
+ this.navigateTo('create');
+
+ cy.get('#name').type(name); // Enter in image name
+
+ // Select image pool
+ cy.contains('Loading...').should('not.exist');
+ this.selectOption('pool', pool);
+ cy.get('#pool').should('have.class', 'ng-valid'); // check if selected
+
+ // Enter in the size of the image
+ cy.get('#size').type(size);
+
+ // Click the create button and wait for image to be made
+ cy.get('[data-cy=submitBtn]').click();
+ this.getFirstTableCell(name).should('exist');
+ }
+
+ editImage(name: string, pool: string, newName: string, newSize: string) {
+ this.navigateEdit(name);
+
+ // Wait until data is loaded
+ cy.get('#pool').should('contain.value', pool);
+
+ cy.get('#name').clear().type(newName);
+ cy.get('#size').clear().type(newSize); // click the size box and send new size
+
+ cy.get('[data-cy=submitBtn]').click();
+
+ this.getExpandCollapseElement(newName).click();
+ cy.get('.table.table-striped.table-bordered').contains('td', newSize);
+ }
+
+ // Selects RBD image and moves it to the trash,
+ // checks that it is present in the trash table
+ moveToTrash(name: string) {
+ // wait for image to be created
+ cy.get('.datatable-body').first().should('not.contain.text', '(Creating...)');
+
+ this.getFirstTableCell(name).click();
+
+ // click on the drop down and selects the move to trash option
+ cy.get('.table-actions button.dropdown-toggle').first().click();
+ cy.get('button.move-to-trash').click();
+
+ cy.get('[data-cy=submitBtn]').should('be.visible').click();
+
+ // Clicks trash tab
+ cy.contains('.nav-link', 'Trash').click();
+ this.getFirstTableCell(name).should('exist');
+ }
+
+ // Checks trash tab table for image and then restores it to the RBD Images table
+ // (could change name if new name is given)
+ restoreImage(name: string, newName?: string) {
+ // clicks on trash tab
+ cy.contains('.nav-link', 'Trash').click();
+
+ // wait for table to load
+ this.getFirstTableCell(name).click();
+ cy.contains('button', 'Restore').click();
+
+ // wait for pop-up to be visible (checks for title of pop-up)
+ cy.get('cd-modal #name').should('be.visible');
+
+ // If a new name for the image is passed, it changes the name of the image
+ if (newName !== undefined) {
+ // click name box and send new name
+ cy.get('cd-modal #name').clear().type(newName);
+ }
+
+ cy.get('[data-cy=submitBtn]').click();
+
+ // clicks images tab
+ cy.contains('.nav-link', 'Images').click();
+
+ this.getFirstTableCell(newName).should('exist');
+ }
+
+ // Enters trash tab and purges trash, thus emptying the trash table.
+ // Checks if Image is still in the table.
+ purgeTrash(name: string, pool?: string) {
+ // clicks trash tab
+ cy.contains('.nav-link', 'Trash').click();
+ cy.contains('button', 'Purge Trash').click();
+
+ // Check for visibility of modal container
+ cy.get('.modal-header').should('be.visible');
+
+ // If purgeing a specific pool, selects that pool if given
+ if (pool !== undefined) {
+ this.selectOption('poolName', pool);
+ cy.get('#poolName').should('have.class', 'ng-valid'); // check if pool is selected
+ }
+ cy.get('[data-cy=submitBtn]').click();
+ // Wait for image to delete and check it is not present
+
+ this.getFirstTableCell(name).should('not.exist');
+ }
+}
--- /dev/null
+import { IscsiPageHelper } from './iscsi.po';
+
+describe('Iscsi Page', () => {
+ const iscsi = new IscsiPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ iscsi.navigateTo();
+ });
+
+ it('should open and show breadcrumb', () => {
+ iscsi.expectBreadcrumbText('Overview');
+ });
+
+ it('should check that tables are displayed and legends are correct', () => {
+ // Check tables are displayed
+ iscsi.getDataTables().its(0).should('be.visible');
+ iscsi.getDataTables().its(1).should('be.visible');
+
+ // Check that legends are correct
+ iscsi.getLegends().its(0).should('contain.text', 'Gateways');
+ iscsi.getLegends().its(1).should('contain.text', 'Images');
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class IscsiPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/block/iscsi/overview', id: 'cd-iscsi' }
+ };
+}
--- /dev/null
+import { PoolPageHelper } from '../pools/pools.po';
+import { MirroringPageHelper } from './mirroring.po';
+
+describe('Mirroring page', () => {
+ const pools = new PoolPageHelper();
+ const mirroring = new MirroringPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ mirroring.navigateTo();
+ });
+
+ it('should open and show breadcrumb', () => {
+ mirroring.expectBreadcrumbText('Mirroring');
+ });
+
+ it('should show three tabs', () => {
+ mirroring.getTabsCount().should('eq', 3);
+ });
+
+ it('should show text for all tabs', () => {
+ mirroring.getTabText(0).should('eq', 'Issues (0)');
+ mirroring.getTabText(1).should('eq', 'Syncing (0)');
+ mirroring.getTabText(2).should('eq', 'Ready (0)');
+ });
+
+ describe('rbd mirroring bootstrap', () => {
+ const poolName = 'rbd-mirror';
+
+ beforeEach(() => {
+ // login to the second ceph cluster
+ cy.ceph2Login();
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo('create');
+ pools.create(poolName, 8, 'rbd');
+ pools.navigateTo();
+ pools.existTableCell(poolName, true);
+ mirroring.navigateTo();
+ });
+
+ it('should generate and import the bootstrap token between clusters', () => {
+ const url: string = Cypress.env('CEPH2_URL');
+ mirroring.navigateTo();
+ mirroring.generateToken(poolName);
+ cy.get('@token').then((bootstrapToken) => {
+ // pass the token to the origin as an arg
+ const args = { name: poolName, bootstrapToken: String(bootstrapToken) };
+ // can't use any imports or functions inside the origin
+ // so writing the code to copy the token inside the origin manually
+ // rather than using a function call
+ // @ts-ignore
+ cy.origin(url, { args }, ({ name, bootstrapToken }) => {
+ // Create an rbd pool in the second cluster
+
+ // Login to the second cluster
+ // Somehow its not working with the cypress login function
+ cy.visit('#/pool/create').wait(100);
+
+ cy.get('[name=username]').type('admin');
+ cy.get('#password').type('admin');
+ cy.get('[type=submit]').click();
+ cy.get('input[name=name]').clear().type(name);
+ cy.get(`select[name=poolType]`).select('replicated');
+ cy.get(`select[name=poolType] option:checked`).contains('replicated');
+ cy.get('.float-start.me-2.select-menu-edit').click();
+ cy.get('.popover-body').should('be.visible');
+ // Choose rbd as the application label
+ cy.get('.select-menu-item-content').contains('rbd').click();
+ cy.get('cd-submit-button').click();
+ cy.get('cd-pool-list').should('exist');
+
+ cy.visit('#/block/mirroring').wait(1000);
+ cy.get('.table-actions button.dropdown-toggle').first().click();
+ cy.get('[aria-label="Import Bootstrap Token"]').click();
+ cy.get('cd-bootstrap-import-modal').within(() => {
+ cy.get(`label[for=${name}]`).click();
+ cy.get('textarea[id=token]').wait(100).type(bootstrapToken);
+ cy.get('button[type=submit]').click();
+ });
+ });
+ });
+
+ // login again since origin removes all the cookies
+ // sessions, localStorage items etc..
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ mirroring.navigateTo();
+ mirroring.checkPoolHealthStatus(poolName, 'OK');
+ });
+ });
+
+ describe('checks that edit mode functionality shows in the pools table', () => {
+ const poolName = 'mirroring_test';
+
+ beforeEach(() => {
+ pools.navigateTo('create'); // Need pool for mirroring testing
+ pools.create(poolName, 8, 'rbd');
+ pools.navigateTo();
+ pools.existTableCell(poolName, true);
+ });
+
+ it('tests editing mode for pools', () => {
+ mirroring.navigateTo();
+
+ mirroring.editMirror(poolName, 'Pool');
+ mirroring.getFirstTableCell('pool').should('be.visible');
+ mirroring.editMirror(poolName, 'Image');
+ mirroring.getFirstTableCell('image').should('be.visible');
+ mirroring.editMirror(poolName, 'Disabled');
+ mirroring.getFirstTableCell('disabled').should('be.visible');
+ });
+
+ afterEach(() => {
+ pools.navigateTo();
+ pools.delete(poolName);
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/block/mirroring', id: 'cd-mirroring' }
+};
+
+export class MirroringPageHelper extends PageHelper {
+ pages = pages;
+
+ poolsColumnIndex = {
+ name: 1,
+ health: 6
+ };
+
+ /**
+ * Goes to the mirroring page and edits a pool in the Pool table. Clicks on the
+ * pool and chooses an option (either pool, image, or disabled)
+ */
+ @PageHelper.restrictTo(pages.index.url)
+ editMirror(name: string, option: string) {
+ // Clicks the pool in the table
+ this.getFirstTableCell(name).click();
+
+ // Clicks the Edit Mode button
+ cy.contains('button', 'Edit Mode').click();
+
+ // Clicks the drop down in the edit pop-up, then clicks the Update button
+ cy.get('.modal-content').should('be.visible');
+ this.selectOption('mirrorMode', option);
+
+ // Clicks update button and checks if the mode has been changed
+ cy.contains('button', 'Update').click();
+ cy.contains('.modal-dialog', 'Edit pool mirror mode').should('not.exist');
+ const val = option.toLowerCase(); // used since entries in table are lower case
+ this.getFirstTableCell(val).should('be.visible');
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ generateToken(poolName: string) {
+ cy.get('[aria-label="Create Bootstrap Token"]').first().click();
+ cy.get('cd-bootstrap-create-modal').within(() => {
+ cy.get(`label[for=${poolName}]`).click();
+ cy.get('button[type=submit]').click();
+ cy.get('textarea[id=token]').wait(200).invoke('val').as('token');
+ cy.get('[aria-label="Back"]').click();
+ });
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ checkPoolHealthStatus(poolName: string, status: string) {
+ cy.get('cd-mirroring-pools').within(() => {
+ this.getTableCell(this.poolsColumnIndex.name, poolName)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.poolsColumnIndex.health}) .badge`)
+ .should(($ele) => {
+ const newLabels = $ele.toArray().map((v) => v.innerText);
+ expect(newLabels).to.include(status);
+ });
+ });
+ }
+}
--- /dev/null
+import { ConfigurationPageHelper } from './configuration.po';
+
+describe('Configuration page', () => {
+ const configuration = new ConfigurationPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ configuration.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ configuration.expectBreadcrumbText('Configuration');
+ });
+ });
+
+ describe('fields check', () => {
+ beforeEach(() => {
+ configuration.getExpandCollapseElement().click();
+ });
+
+ it('should check that details table opens (w/o tab header)', () => {
+ configuration.getStatusTables().should('be.visible');
+ configuration.getTabs().should('not.exist');
+ });
+ });
+
+ describe('edit configuration test', () => {
+ const configName = 'client_cache_size';
+
+ beforeEach(() => {
+ configuration.clearTableSearchInput();
+ configuration.getTableCount('found').as('configFound');
+ });
+
+ after(() => {
+ configuration.configClear(configName);
+ });
+
+ it('should click and edit a configuration and results should appear in the table', () => {
+ configuration.edit(
+ configName,
+ ['global', '1'],
+ ['mon', '2'],
+ ['mgr', '3'],
+ ['osd', '4'],
+ ['mds', '5'],
+ ['client', '6']
+ );
+ });
+
+ it('should verify modified filter is applied properly', () => {
+ configuration.filterTable('Modified', 'no');
+ configuration.getTableCount('found').as('unmodifiedConfigs');
+
+ // Modified filter value to yes
+ configuration.filterTable('Modified', 'yes');
+ configuration.getTableCount('found').as('modifiedConfigs');
+
+ cy.get('@configFound').then((configFound) => {
+ cy.get('@unmodifiedConfigs').then((unmodifiedConfigs) => {
+ const modifiedConfigs = Number(configFound) - Number(unmodifiedConfigs);
+ configuration.getTableCount('found').should('eq', modifiedConfigs);
+ });
+ });
+
+ // Modified filter value to no
+ configuration.filterTable('Modified', 'no');
+ cy.get('@configFound').then((configFound) => {
+ cy.get('@modifiedConfigs').then((modifiedConfigs) => {
+ const unmodifiedConfigs = Number(configFound) - Number(modifiedConfigs);
+ configuration.getTableCount('found').should('eq', unmodifiedConfigs);
+ });
+ });
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class ConfigurationPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/configuration', id: 'cd-configuration' }
+ };
+
+ /**
+ * Clears out all the values in a config to reset before and after testing
+ * Does not work for configs with checkbox only, possible future PR
+ */
+ configClear(name: string) {
+ const valList = ['global', 'mon', 'mgr', 'osd', 'mds', 'client']; // Editable values
+
+ this.navigateEdit(name);
+ // Waits for the data to load
+ cy.contains('.card-header', `Edit ${name}`);
+
+ for (const i of valList) {
+ cy.get(`#${i}`).clear();
+ }
+ // Clicks save button and checks that values are not present for the selected config
+ cy.get('[data-cy=submitBtn]').click();
+
+ // Enter config setting name into filter box
+ this.searchTable(name);
+
+ // Expand row
+ this.getExpandCollapseElement(name).click();
+
+ // Checks for visibility of details tab
+ this.getStatusTables().should('be.visible');
+
+ for (const i of valList) {
+ // Waits until values are not present in the details table
+ this.getStatusTables().should('not.contain.text', i + ':');
+ }
+ }
+
+ /**
+ * Clicks the designated config, then inputs the values passed into the edit function.
+ * Then checks if the edit is reflected in the config table.
+ * Takes in name of config and a list of tuples of values the user wants edited,
+ * each tuple having the desired value along with the number tehey want for that value.
+ * Ex: [global, '2'] is the global value with an input of 2
+ */
+ edit(name: string, ...values: [string, string][]) {
+ this.navigateEdit(name);
+
+ // Waits for data to load
+ cy.contains('.card-header', `Edit ${name}`);
+
+ values.forEach((valtuple) => {
+ // Finds desired value based off given list
+ cy.get(`#${valtuple[0]}`).type(valtuple[1]); // of values and inserts the given number for the value
+ });
+
+ // Clicks save button then waits until the desired config is visible, clicks it,
+ // then checks that each desired value appears with the desired number
+ cy.get('[data-cy=submitBtn]').click();
+
+ // Enter config setting name into filter box
+ this.searchTable(name);
+
+ // Checks for visibility of config in table
+ this.getExpandCollapseElement(name).should('be.visible').click();
+
+ // Clicks config
+ values.forEach((value) => {
+ // iterates through list of values and
+ // checks if the value appears in details with the correct number attatched
+ cy.contains('.table.table-striped.table-bordered', `${value[0]}\: ${value[1]}`);
+ });
+ }
+}
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+import { NotificationSidebarPageHelper } from '../ui/notification.po';
+import { HostsPageHelper } from './hosts.po';
+import { ServicesPageHelper } from './services.po';
+
+const pages = {
+ index: { url: '#/expand-cluster', id: 'cd-create-cluster' }
+};
+export class CreateClusterWizardHelper extends PageHelper {
+ pages = pages;
+
+ createCluster() {
+ cy.get('cd-create-cluster').should('contain.text', 'Please expand your cluster first');
+ cy.get('[name=expand-cluster]').click();
+ cy.get('cd-wizard').should('exist');
+ }
+
+ doSkip() {
+ cy.get('[name=skip-cluster-creation]').click();
+ cy.contains('cd-modal button', 'Continue').click();
+
+ cy.get('cd-dashboard').should('exist');
+ const notification = new NotificationSidebarPageHelper();
+ notification.open();
+ notification.getNotifications().should('contain', 'Cluster expansion skipped by user');
+ }
+}
+
+export class CreateClusterHostPageHelper extends HostsPageHelper {
+ pages = {
+ index: { url: '#/expand-cluster', id: 'cd-wizard' },
+ add: { url: '', id: 'cd-host-form' }
+ };
+
+ columnIndex = {
+ hostname: 1,
+ labels: 2,
+ status: 3,
+ services: 0
+ };
+}
+
+export class CreateClusterServicePageHelper extends ServicesPageHelper {
+ pages = {
+ index: { url: '#/expand-cluster', id: 'cd-wizard' },
+ create: { url: '', id: 'cd-service-form' }
+ };
+
+ columnIndex = {
+ service_name: 1,
+ placement: 2,
+ running: 0,
+ size: 0,
+ last_refresh: 0
+ };
+}
--- /dev/null
+import { CrushMapPageHelper } from './crush-map.po';
+
+describe('CRUSH map page', () => {
+ const crushmap = new CrushMapPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ crushmap.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ crushmap.expectBreadcrumbText('CRUSH map');
+ });
+ });
+
+ describe('fields check', () => {
+ it('should check that title & table appears', () => {
+ // Check that title (CRUSH map viewer) appears
+ crushmap.getPageTitle().should('equal', 'CRUSH map viewer');
+
+ // Check that title appears once OSD is clicked
+ crushmap.getCrushNode(0).click();
+
+ crushmap
+ .getLegends()
+ .invoke('text')
+ .then((legend) => {
+ crushmap.getCrushNode(0).should('have.text', legend);
+ });
+
+ // Check that table appears once OSD is clicked
+ crushmap.getDataTables().should('be.visible');
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class CrushMapPageHelper extends PageHelper {
+ pages = { index: { url: '#/crush-map', id: 'cd-crushmap' } };
+
+ getPageTitle() {
+ return cy.get('cd-crushmap .card-header').text();
+ }
+
+ getCrushNode(idx: number) {
+ return cy.get('.node-name.type-osd').eq(idx);
+ }
+}
--- /dev/null
+import { HostsPageHelper } from './hosts.po';
+
+describe('Hosts page', () => {
+ const hosts = new HostsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ hosts.navigateTo();
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ it('should open and show breadcrumb', () => {
+ hosts.expectBreadcrumbText('Hosts');
+ });
+
+ it('should show two tabs', () => {
+ hosts.getTabsCount().should('eq', 2);
+ });
+
+ it('should show hosts list tab at first', () => {
+ hosts.getTabText(0).should('eq', 'Hosts List');
+ });
+
+ it('should show overall performance as a second tab', () => {
+ hosts.getTabText(1).should('eq', 'Overall Performance');
+ });
+ });
+
+ describe('services link test', () => {
+ it('should check at least one host is present', () => {
+ hosts.check_for_host();
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/hosts', id: 'cd-hosts' },
+ add: { url: '#/hosts/(modal:add)', id: 'cd-host-form' }
+};
+
+export class HostsPageHelper extends PageHelper {
+ pages = pages;
+
+ columnIndex = {
+ hostname: 2,
+ services: 3,
+ labels: 4,
+ status: 5
+ };
+
+ check_for_host() {
+ this.getTableCount('total').should('not.be.eq', 0);
+ }
+
+ add(hostname: string, exist?: boolean, maintenance?: boolean, labels: string[] = []) {
+ cy.get(`${this.pages.add.id}`).within(() => {
+ cy.get('#hostname').type(hostname);
+ if (maintenance) {
+ cy.get('label[for=maintenance]').click();
+ }
+ if (exist) {
+ cy.get('#hostname').should('have.class', 'ng-invalid');
+ }
+ });
+
+ if (labels.length) {
+ this.selectPredefinedLabels(labels);
+ }
+
+ cy.get('cd-submit-button').click();
+ // back to host list
+ cy.get(`${this.pages.index.id}`);
+ }
+
+ selectPredefinedLabels(labels: string[]) {
+ cy.get('a[data-testid=select-menu-edit]').click();
+ for (const label of labels) {
+ cy.get('.popover-body div.select-menu-item-content').contains(label).click();
+ }
+ }
+
+ checkExist(hostname: string, exist: boolean) {
+ this.getTableCell(this.columnIndex.hostname, hostname).should(($elements) => {
+ const hosts = $elements.map((_, el) => el.textContent).get();
+ if (exist) {
+ expect(hosts).to.include(hostname);
+ } else {
+ expect(hosts).to.not.include(hostname);
+ }
+ });
+ }
+
+ remove(hostname: string) {
+ super.delete(hostname, this.columnIndex.hostname, 'hosts');
+ }
+
+ // Add or remove labels on a host, then verify labels in the table
+ editLabels(hostname: string, labels: string[], add: boolean) {
+ this.getTableCell(this.columnIndex.hostname, hostname).click();
+ this.clickActionButton('edit');
+
+ // add or remove label badges
+ if (add) {
+ cy.get('cd-modal').find('.select-menu-edit').click();
+ for (const label of labels) {
+ cy.contains('cd-modal .badge', new RegExp(`^${label}$`)).should('not.exist');
+ cy.get('.popover-body input').type(`${label}{enter}`);
+ }
+ } else {
+ for (const label of labels) {
+ cy.contains('cd-modal .badge', new RegExp(`^${label}$`))
+ .find('.badge-remove')
+ .click();
+ }
+ }
+ cy.get('cd-modal cd-submit-button').click();
+ this.checkLabelExists(hostname, labels, add);
+ }
+
+ checkLabelExists(hostname: string, labels: string[], add: boolean) {
+ // Verify labels are added or removed from Labels column
+ // First find row with hostname, then find labels in the row
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .click()
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.labels}) .badge`)
+ .should(($ele) => {
+ const newLabels = $ele.toArray().map((v) => v.innerText);
+ for (const label of labels) {
+ if (add) {
+ expect(newLabels).to.include(label);
+ } else {
+ expect(newLabels).to.not.include(label);
+ }
+ }
+ });
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ maintenance(hostname: string, exit = false, force = false) {
+ this.clearTableSearchInput();
+ if (force) {
+ this.getTableCell(this.columnIndex.hostname, hostname).click();
+ this.clickActionButton('enter-maintenance');
+
+ cy.get('cd-modal').within(() => {
+ cy.contains('button', 'Continue').click();
+ });
+
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.status}) .badge`)
+ .should(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ expect(status).to.include('maintenance');
+ });
+ }
+ if (exit) {
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .click()
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.status})`)
+ .then(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ if (status[0].includes('maintenance')) {
+ this.clickActionButton('exit-maintenance');
+ }
+ });
+
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.status})`)
+ .should(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ expect(status).to.not.include('maintenance');
+ });
+ } else {
+ this.getTableCell(this.columnIndex.hostname, hostname).click();
+ this.clickActionButton('enter-maintenance');
+
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.status}) .badge`)
+ .should(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ expect(status).to.include('maintenance');
+ });
+ }
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ drain(hostname: string) {
+ this.getTableCell(this.columnIndex.hostname, hostname).click();
+ this.clickActionButton('start-drain');
+ this.checkLabelExists(hostname, ['_no_schedule'], true);
+
+ this.clickTab('cd-host-details', hostname, 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ cy.wait(20000);
+ this.expectTableCount('total', 0);
+ });
+ }
+
+ checkServiceInstancesExist(hostname: string, instances: string[]) {
+ this.getTableCell(this.columnIndex.hostname, hostname)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.services}) .badge`)
+ .should(($ele) => {
+ const serviceInstances = $ele.toArray().map((v) => v.innerText);
+ for (const instance of instances) {
+ expect(serviceInstances).to.include(instance);
+ }
+ });
+ }
+}
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/inventory', id: 'cd-inventory' }
+};
+
+export class InventoryPageHelper extends PageHelper {
+ pages = pages;
+
+ identify() {
+ // Nothing we can do, just verify the form is there
+ this.getFirstTableCell().click();
+ cy.contains('cd-table-actions button', 'Identify').click();
+ cy.get('cd-modal').within(() => {
+ cy.get('#duration').select('15 minutes');
+ cy.get('#duration').select('10 minutes');
+ cy.get('cd-back-button').click();
+ });
+ cy.get('cd-modal').should('not.exist');
+ cy.get(`${this.pages.index.id}`);
+ }
+}
--- /dev/null
+import { PoolPageHelper } from '../pools/pools.po';
+import { LogsPageHelper } from './logs.po';
+
+describe('Logs page', () => {
+ const logs = new LogsPageHelper();
+ const pools = new PoolPageHelper();
+
+ const poolname = 'e2e_logs_test_pool';
+ const today = new Date();
+ let hour = today.getHours();
+ if (hour > 12) {
+ hour = hour - 12;
+ }
+ const minute = today.getMinutes();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ beforeEach(() => {
+ logs.navigateTo();
+ });
+
+ it('should open and show breadcrumb', () => {
+ logs.expectBreadcrumbText('Logs');
+ });
+
+ it('should show three tabs', () => {
+ logs.getTabsCount().should('eq', 3);
+ });
+
+ it('should show cluster logs tab at first', () => {
+ logs.getTabText(0).should('eq', 'Cluster Logs');
+ });
+
+ it('should show audit logs as a second tab', () => {
+ logs.getTabText(1).should('eq', 'Audit Logs');
+ });
+
+ it('should show daemon logs as a third tab', () => {
+ logs.getTabText(2).should('eq', 'Daemon Logs');
+ });
+ });
+
+ describe('audit logs respond to pool creation and deletion test', () => {
+ it('should create pool and check audit logs reacted', () => {
+ pools.navigateTo('create');
+ pools.create(poolname, 8);
+ pools.navigateTo();
+ pools.existTableCell(poolname, true);
+ logs.checkAuditForPoolFunction(poolname, 'create', hour, minute);
+ });
+
+ it('should delete pool and check audit logs reacted', () => {
+ pools.navigateTo();
+ pools.delete(poolname);
+ logs.checkAuditForPoolFunction(poolname, 'delete', hour, minute);
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class LogsPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/logs', id: 'cd-logs' }
+ };
+
+ checkAuditForPoolFunction(poolname: string, poolfunction: string, hour: number, minute: number) {
+ this.navigateTo();
+
+ // sometimes the modal from deleting pool is still present at this point.
+ // This wait makes sure it isn't
+ cy.contains('.modal-dialog', 'Delete Pool').should('not.exist');
+
+ // go to audit logs tab
+ cy.contains('.nav-link', 'Audit Logs').click();
+
+ // Enter an earliest time so that no old messages with the same pool name show up
+ cy.get('.ngb-tp-input').its(0).clear();
+
+ if (hour < 10) {
+ cy.get('.ngb-tp-input').its(0).type('0');
+ }
+ cy.get('.ngb-tp-input').its(0).type(`${hour}`);
+
+ cy.get('.ngb-tp-input').its(1).clear();
+ if (minute < 10) {
+ cy.get('.ngb-tp-input').its(1).type('0');
+ }
+ cy.get('.ngb-tp-input').its(1).type(`${minute}`);
+
+ // Enter the pool name into the filter box
+ cy.get('input.form-control.ng-valid').first().clear().type(poolname);
+
+ cy.get('.tab-pane.active')
+ .get('.card-body')
+ .get('.message')
+ .should('contain.text', poolname)
+ .and('contain.text', `pool ${poolfunction}`);
+ }
+
+ checkAuditForConfigChange(configname: string, setting: string, hour: number, minute: number) {
+ this.navigateTo();
+
+ // go to audit logs tab
+ cy.contains('.nav-link', 'Audit Logs').click();
+
+ // Enter an earliest time so that no old messages with the same config name show up
+ cy.get('.ngb-tp-input').its(0).clear();
+ if (hour < 10) {
+ cy.get('.ngb-tp-input').its(0).type('0');
+ }
+ cy.get('.ngb-tp-input').its(0).type(`${hour}`);
+
+ cy.get('.ngb-tp-input').its(1).clear();
+ if (minute < 10) {
+ cy.get('.ngb-tp-input').its(1).type('0');
+ }
+ cy.get('.ngb-tp-input').its(1).type(`${minute}`);
+
+ // Enter the config name into the filter box
+ cy.get('input.form-control.ng-valid').first().clear().type(configname);
+
+ cy.get('.tab-pane.active')
+ .get('.card-body')
+ .get('.message')
+ .should('contain.text', configname)
+ .and('contain.text', setting);
+ }
+}
--- /dev/null
+import { Input, ManagerModulesPageHelper } from './mgr-modules.po';
+
+describe('Manager modules page', () => {
+ const mgrmodules = new ManagerModulesPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ mgrmodules.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ mgrmodules.expectBreadcrumbText('Manager Modules');
+ });
+ });
+
+ describe('verifies editing functionality for manager modules', () => {
+ it('should test editing on balancer module', () => {
+ const balancerArr: Input[] = [
+ {
+ id: 'crush_compat_max_iterations',
+ newValue: '123',
+ oldValue: '25'
+ }
+ ];
+ mgrmodules.editMgrModule('balancer', balancerArr);
+ });
+
+ it('should test editing on dashboard module', () => {
+ const dashboardArr: Input[] = [
+ {
+ id: 'GRAFANA_API_PASSWORD',
+ newValue: 'rafa',
+ oldValue: ''
+ }
+ ];
+ mgrmodules.editMgrModule('dashboard', dashboardArr);
+ });
+
+ it('should test editing on devicehealth module', () => {
+ const devHealthArray: Input[] = [
+ {
+ id: 'mark_out_threshold',
+ newValue: '1987',
+ oldValue: '2419200'
+ },
+ {
+ id: 'pool_name',
+ newValue: 'sox',
+ oldValue: '.mgr'
+ },
+ {
+ id: 'retention_period',
+ newValue: '1999',
+ oldValue: '15552000'
+ },
+ {
+ id: 'scrape_frequency',
+ newValue: '2020',
+ oldValue: '86400'
+ },
+ {
+ id: 'sleep_interval',
+ newValue: '456',
+ oldValue: '600'
+ },
+ {
+ id: 'warn_threshold',
+ newValue: '567',
+ oldValue: '7257600'
+ }
+ ];
+
+ mgrmodules.editMgrModule('devicehealth', devHealthArray);
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class Input {
+ id: string;
+ oldValue: string;
+ newValue: string;
+}
+
+export class ManagerModulesPageHelper extends PageHelper {
+ pages = { index: { url: '#/mgr-modules', id: 'cd-mgr-module-list' } };
+
+ /**
+ * Selects the Manager Module and then fills in the desired fields.
+ */
+ editMgrModule(name: string, inputs: Input[]) {
+ this.navigateEdit(name);
+
+ for (const input of inputs) {
+ // Clears fields and adds edits
+ cy.get(`#${input.id}`).clear().type(input.newValue);
+ }
+
+ cy.contains('button', 'Update').click();
+ // Checks if edits appear
+ this.getExpandCollapseElement(name).should('be.visible').click();
+
+ for (const input of inputs) {
+ cy.get('.datatable-body').last().contains(input.newValue);
+ }
+
+ // Clear mgr module of all edits made to it
+ this.navigateEdit(name);
+
+ // Clears the editable fields
+ for (const input of inputs) {
+ if (input.oldValue) {
+ const id = `#${input.id}`;
+ cy.get(id).clear();
+ if (input.oldValue) {
+ cy.get(id).type(input.oldValue);
+ }
+ }
+ }
+
+ // Checks that clearing represents in details tab of module
+ cy.contains('button', 'Update').click();
+ this.getExpandCollapseElement(name).should('be.visible').click();
+ for (const input of inputs) {
+ if (input.oldValue) {
+ cy.get('.datatable-body')
+ .eq(1)
+ .should('contain', input.id)
+ .and('not.contain', input.newValue);
+ }
+ }
+ }
+}
--- /dev/null
+import { MonitorsPageHelper } from './monitors.po';
+
+describe('Monitors page', () => {
+ const monitors = new MonitorsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ monitors.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ monitors.expectBreadcrumbText('Monitors');
+ });
+ });
+
+ describe('fields check', () => {
+ it('should check status table is present', () => {
+ // check for table header 'Status'
+ monitors.getLegends().its(0).should('have.text', 'Status');
+
+ // check for fields in table
+ monitors
+ .getStatusTables()
+ .should('contain.text', 'Cluster ID')
+ .and('contain.text', 'monmap modified')
+ .and('contain.text', 'monmap epoch')
+ .and('contain.text', 'quorum con')
+ .and('contain.text', 'quorum mon')
+ .and('contain.text', 'required con')
+ .and('contain.text', 'required mon');
+ });
+
+ it('should check In Quorum and Not In Quorum tables are present', () => {
+ // check for there to be two tables
+ monitors.getDataTables().should('have.length', 2);
+
+ // check for table header 'In Quorum'
+ monitors.getLegends().its(1).should('have.text', 'In Quorum');
+
+ // check for table header 'Not In Quorum'
+ monitors.getLegends().its(2).should('have.text', 'Not In Quorum');
+
+ // verify correct columns on In Quorum table
+ monitors.getDataTableHeaders(0).contains('Name');
+
+ monitors.getDataTableHeaders(0).contains('Rank');
+
+ monitors.getDataTableHeaders(0).contains('Public Address');
+
+ monitors.getDataTableHeaders(0).contains('Open Sessions');
+
+ // verify correct columns on Not In Quorum table
+ monitors.getDataTableHeaders(1).contains('Name');
+
+ monitors.getDataTableHeaders(1).contains('Rank');
+
+ monitors.getDataTableHeaders(1).contains('Public Address');
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class MonitorsPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/monitor', id: 'cd-monitor' }
+ };
+}
--- /dev/null
+import { OSDsPageHelper } from './osds.po';
+
+describe('OSDs page', () => {
+ const osds = new OSDsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ osds.navigateTo();
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ it('should open and show breadcrumb', () => {
+ osds.expectBreadcrumbText('OSDs');
+ });
+
+ it('should show two tabs', () => {
+ osds.getTabsCount().should('eq', 2);
+ osds.getTabText(0).should('eq', 'OSDs List');
+ osds.getTabText(1).should('eq', 'Overall Performance');
+ });
+ });
+
+ describe('check existence of fields on OSD page', () => {
+ it('should check that number of rows and count in footer match', () => {
+ osds.getTableCount('total').then((text) => {
+ osds.getTableRows().its('length').should('equal', text);
+ });
+ });
+
+ it('should verify that buttons exist', () => {
+ cy.contains('button', 'Create');
+ cy.contains('button', 'Cluster-wide configuration');
+ });
+
+ describe('by selecting one row in OSDs List', () => {
+ beforeEach(() => {
+ osds.getExpandCollapseElement().click();
+ });
+
+ it('should show the correct text for the tab labels', () => {
+ cy.get('#tabset-osd-details > a').then(($tabs) => {
+ const tabHeadings = $tabs.map((_i, e) => e.textContent).get();
+
+ expect(tabHeadings).to.eql([
+ 'Devices',
+ 'Attributes (OSD map)',
+ 'Metadata',
+ 'Device health',
+ 'Performance counter',
+ 'Performance Details'
+ ]);
+ });
+ });
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/osd', id: 'cd-osd-list' },
+ create: { url: '#/osd/create', id: 'cd-osd-form' }
+};
+
+export class OSDsPageHelper extends PageHelper {
+ pages = pages;
+
+ columnIndex = {
+ id: 3,
+ status: 5
+ };
+
+ create(deviceType: 'hdd' | 'ssd', hostname?: string, expandCluster = false) {
+ cy.get('[aria-label="toggle advanced mode"]').click();
+ // Click Primary devices Add button
+ cy.get('cd-osd-devices-selection-groups[name="Primary"]').as('primaryGroups');
+ cy.get('@primaryGroups').find('button').click();
+
+ // Select all devices with `deviceType`
+ cy.get('cd-osd-devices-selection-modal').within(() => {
+ cy.get('.modal-footer .tc_submitButton').as('addButton').should('be.disabled');
+ this.filterTable('Type', deviceType);
+ if (hostname) {
+ this.filterTable('Hostname', hostname);
+ }
+
+ if (expandCluster) {
+ this.getTableCount('total').should('be.gte', 1);
+ }
+ cy.get('@addButton').click();
+ });
+
+ if (!expandCluster) {
+ cy.get('@primaryGroups').within(() => {
+ this.getTableCount('total').as('newOSDCount');
+ });
+
+ cy.get(`${pages.create.id} .card-footer .tc_submitButton`).click();
+ cy.get(`cd-osd-creation-preview-modal .modal-footer .tc_submitButton`).click();
+ }
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ checkStatus(id: number, status: string[]) {
+ this.searchTable(`id:${id}`);
+ this.expectTableCount('found', 1);
+ cy.get(`datatable-body-cell:nth-child(${this.columnIndex.status}) .badge`).should(($ele) => {
+ const allStatus = $ele.toArray().map((v) => v.innerText);
+ for (const s of status) {
+ expect(allStatus).to.include(s);
+ }
+ });
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ ensureNoOsd(id: number) {
+ this.searchTable(`id:${id}`);
+ this.expectTableCount('found', 0);
+ this.clearTableSearchInput();
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ deleteByIDs(osdIds: number[], replace?: boolean) {
+ this.getTableRows().each(($el) => {
+ const rowOSD = Number(
+ $el.find('datatable-body-cell .datatable-body-cell-label').get(this.columnIndex.id - 1)
+ .textContent
+ );
+ if (osdIds.includes(rowOSD)) {
+ cy.wrap($el).click();
+ }
+ });
+ this.clickActionButton('delete');
+ if (replace) {
+ cy.get('cd-modal label[for="preserve"]').click();
+ }
+ cy.get('cd-modal label[for="confirmation"]').click();
+ cy.contains('cd-modal button', 'Delete').click();
+ cy.get('cd-modal').should('not.exist');
+ }
+}
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/services', id: 'cd-services' },
+ create: { url: '#/services/(modal:create)', id: 'cd-service-form' }
+};
+
+export class ServicesPageHelper extends PageHelper {
+ pages = pages;
+
+ columnIndex = {
+ service_name: 2,
+ placement: 3,
+ running: 4,
+ size: 5,
+ last_refresh: 6
+ };
+
+ serviceDetailColumnIndex = {
+ daemonName: 2,
+ status: 4
+ };
+
+ check_for_service() {
+ this.getTableCount('total').should('not.be.eq', 0);
+ }
+
+ private selectServiceType(serviceType: string) {
+ return this.selectOption('service_type', serviceType);
+ }
+
+ clickServiceTab(serviceName: string, tabName: string) {
+ this.getExpandCollapseElement(serviceName).click();
+ cy.get('cd-service-details').within(() => {
+ this.getTab(tabName).click();
+ });
+ }
+
+ addService(
+ serviceType: string,
+ exist?: boolean,
+ count = 1,
+ snmpVersion?: string,
+ snmpPrivProtocol?: boolean,
+ unmanaged = false
+ ) {
+ cy.get(`${this.pages.create.id}`).within(() => {
+ this.selectServiceType(serviceType);
+ switch (serviceType) {
+ case 'rgw':
+ cy.get('#service_id').type('foo');
+ unmanaged ? cy.get('label[for=unmanaged]').click() : cy.get('#count').type(String(count));
+ break;
+
+ case 'ingress':
+ if (unmanaged) {
+ cy.get('label[for=unmanaged]').click();
+ }
+ this.selectOption('backend_service', 'rgw.foo');
+ cy.get('#service_id').should('have.value', 'rgw.foo');
+ cy.get('#virtual_ip').type('192.168.100.1/24');
+ cy.get('#frontend_port').type('8081');
+ cy.get('#monitor_port').type('8082');
+ break;
+
+ case 'nfs':
+ cy.get('#service_id').type('testnfs');
+ unmanaged ? cy.get('label[for=unmanaged]').click() : cy.get('#count').type(String(count));
+ break;
+
+ case 'snmp-gateway':
+ this.selectOption('snmp_version', snmpVersion);
+ cy.get('#snmp_destination').type('192.168.0.1:8443');
+ if (snmpVersion === 'V2c') {
+ cy.get('#snmp_community').type('public');
+ } else {
+ cy.get('#engine_id').type('800C53F00000');
+ this.selectOption('auth_protocol', 'SHA');
+ if (snmpPrivProtocol) {
+ this.selectOption('privacy_protocol', 'DES');
+ cy.get('#snmp_v3_priv_password').type('testencrypt');
+ }
+
+ // Credentials
+ cy.get('#snmp_v3_auth_username').type('test');
+ cy.get('#snmp_v3_auth_password').type('testpass');
+ }
+ break;
+
+ default:
+ cy.get('#service_id').type('test');
+ unmanaged ? cy.get('label[for=unmanaged]').click() : cy.get('#count').type(String(count));
+ break;
+ }
+ if (serviceType === 'snmp-gateway') {
+ cy.get('cd-submit-button').dblclick();
+ } else {
+ cy.get('cd-submit-button').click();
+ }
+ });
+ if (exist) {
+ cy.get('#service_id').should('have.class', 'ng-invalid');
+ } else {
+ // back to service list
+ cy.get(`${this.pages.index.id}`);
+ }
+ }
+
+ editService(name: string, daemonCount: string) {
+ this.navigateEdit(name, true, false);
+ cy.get(`${this.pages.create.id}`).within(() => {
+ cy.get('#service_type').should('be.disabled');
+ cy.get('#service_id').should('be.disabled');
+ cy.get('#count').clear().type(daemonCount);
+ cy.get('cd-submit-button').click();
+ });
+ }
+
+ checkServiceStatus(daemon: string, expectedStatus = 'running') {
+ let daemonNameIndex = this.serviceDetailColumnIndex.daemonName;
+ let statusIndex = this.serviceDetailColumnIndex.status;
+
+ // since hostname row is hidden from the hosts details table,
+ // we'll need to manually override the indexes when this check is being
+ // done for the daemons in host details page. So we'll get the url and
+ // verify if the current page is not the services index page
+ cy.url().then((url) => {
+ if (!url.includes(pages.index.url)) {
+ daemonNameIndex = 1;
+ statusIndex = 3;
+ }
+
+ cy.get('cd-service-daemon-list').within(() => {
+ this.getTableCell(daemonNameIndex, daemon, true)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${statusIndex}) .badge`)
+ .should(($ele) => {
+ const status = $ele.toArray().map((v) => v.innerText);
+ expect(status).to.include(expectedStatus);
+ });
+ });
+ });
+ }
+
+ expectPlacementCount(serviceName: string, expectedCount: string) {
+ this.getTableCell(this.columnIndex.service_name, serviceName)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.placement})`)
+ .should(($ele) => {
+ const running = $ele.text().split(';');
+ expect(running).to.include(`count:${expectedCount}`);
+ });
+ }
+
+ checkExist(serviceName: string, exist: boolean) {
+ this.getTableCell(this.columnIndex.service_name, serviceName).should(($elements) => {
+ const services = $elements.map((_, el) => el.textContent).get();
+ if (exist) {
+ expect(services).to.include(serviceName);
+ } else {
+ expect(services).to.not.include(serviceName);
+ }
+ });
+ }
+
+ isUnmanaged(serviceName: string, unmanaged: boolean) {
+ this.getTableCell(this.columnIndex.service_name, serviceName)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.placement})`)
+ .should(($ele) => {
+ const placement = $ele.text().split(';');
+ unmanaged
+ ? expect(placement).to.include('unmanaged')
+ : expect(placement).to.not.include('unmanaged');
+ });
+ }
+
+ deleteService(serviceName: string) {
+ const getRow = this.getTableCell.bind(this, this.columnIndex.service_name);
+ getRow(serviceName).click();
+
+ // Clicks on table Delete button
+ this.clickActionButton('delete');
+
+ // Confirms deletion
+ cy.get('cd-modal .custom-control-label').click();
+ cy.contains('cd-modal button', 'Delete').click();
+
+ // Wait for modal to close
+ cy.get('cd-modal').should('not.exist');
+ this.checkExist(serviceName, false);
+ }
+
+ daemonAction(daemon: string, action: string) {
+ cy.get('cd-service-daemon-list').within(() => {
+ this.getTableRow(daemon).click();
+ this.clickActionButton(action);
+ });
+ }
+}
--- /dev/null
+import { UsersPageHelper } from './users.po';
+
+describe('Cluster Ceph Users', () => {
+ const users = new UsersPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ users.navigateTo();
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ it('should open and show breadcrumb', () => {
+ users.expectBreadcrumbText('Ceph Users');
+ });
+ });
+
+ describe('Cluster users table', () => {
+ it('should verify the table is not empty', () => {
+ users.checkForUsers();
+ });
+
+ it('should verify the keys are hidden', () => {
+ users.verifyKeysAreHidden();
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/ceph-users', id: 'cd-crud-table' }
+};
+
+export class UsersPageHelper extends PageHelper {
+ pages = pages;
+
+ columnIndex = {
+ entity: 2,
+ capabilities: 3,
+ key: 4
+ };
+
+ checkForUsers() {
+ this.getTableCount('total').should('not.be.eq', 0);
+ }
+
+ verifyKeysAreHidden() {
+ this.getTableCell(this.columnIndex.entity, 'osd.0')
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.columnIndex.key}) span`)
+ .should(($ele) => {
+ const serviceInstances = $ele.toArray().map((v) => v.innerText);
+ expect(serviceInstances).not.contains(/^[a-z0-9]+$/i);
+ });
+ }
+}
--- /dev/null
+import { And, Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
+
+import { UrlsCollection } from './urls.po';
+
+const urlsCollection = new UrlsCollection();
+
+Given('I am logged in', () => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+});
+
+Given('I am on the {string} page', (page: string) => {
+ cy.visit(urlsCollection.pages[page].url);
+ cy.get(urlsCollection.pages[page].id).should('exist');
+});
+
+Then('I should be on the {string} page', (page: string) => {
+ cy.get(urlsCollection.pages[page].id).should('exist');
+});
+
+And('I should see a button to {string}', (button: string) => {
+ cy.get(`[aria-label="${button}"]`).should('be.visible');
+});
+
+When('I click on {string} button', (button: string) => {
+ cy.get(`[aria-label="${button}"]`).first().click();
+});
+
+// When you are clicking on an action in the table actions dropdown button
+When('I click on {string} button from the table actions', (button: string) => {
+ cy.get('.table-actions button.dropdown-toggle').first().click();
+ cy.get(`[aria-label="${button}"]`).first().click();
+});
+
+And('select options {string}', (labels: string) => {
+ if (labels) {
+ cy.get('a[data-testid=select-menu-edit]').click();
+ for (const label of labels.split(', ')) {
+ cy.get('.popover-body div.select-menu-item-content').contains(label).click();
+ }
+ }
+});
+
+And('{string} option {string}', (action: string, labels: string) => {
+ if (labels) {
+ if (action === 'add') {
+ cy.get('cd-modal').find('.select-menu-edit').click();
+ for (const label of labels.split(', ')) {
+ cy.get('.popover-body input').type(`${label}{enter}`);
+ }
+ } else {
+ for (const label of labels.split(', ')) {
+ cy.contains('cd-modal .badge', new RegExp(`^${label}$`))
+ .find('.badge-remove')
+ .click();
+ }
+ }
+ }
+});
+
+/**
+ * Fills in the given field using the value provided
+ * @param field ID of the field that needs to be filled out.
+ * @param value Value that should be filled in the field.
+ */
+And('enter {string} {string}', (field: string, value: string) => {
+ cy.get('cd-modal').within(() => {
+ cy.get(`input[id=${field}]`).type(value);
+ });
+});
+
+And('I click on submit button', () => {
+ cy.get('[data-cy=submitBtn]').click();
+});
+
+/**
+ * Selects any row on the datatable if it matches the given name
+ */
+When('I select a row {string}', (row: string) => {
+ cy.get('cd-table .search input').first().clear().type(row);
+ cy.contains(`datatable-body-row datatable-body-cell .datatable-body-cell-label`, row).click();
+});
+
+Then('I should see the modal', () => {
+ cy.get('cd-modal').should('exist');
+});
+
+Then('I should not see the modal', () => {
+ cy.get('cd-modal').should('not.exist');
+});
+
+/**
+ * Some modals have an additional confirmation to be provided
+ * by ticking the 'Are you sure?' box.
+ */
+Then('I check the tick box in modal', () => {
+ cy.get('cd-modal .custom-control-label').click();
+});
+
+And('I confirm to {string}', (action: string) => {
+ cy.contains('cd-modal button', action).click();
+ cy.get('cd-modal').should('not.exist');
+});
+
+Then('I should see an error in {string} field', (field: string) => {
+ cy.get('cd-modal').within(() => {
+ cy.get(`input[id=${field}]`).should('have.class', 'ng-invalid');
+ });
+});
+
+Then('I should see a row with {string}', (row: string) => {
+ cy.get('cd-table .search input').first().clear().type(row);
+ cy.contains(`datatable-body-row datatable-body-cell .datatable-body-cell-label`, row).should(
+ 'exist'
+ );
+});
+
+Then('I should not see a row with {string}', (row: string) => {
+ cy.get('cd-table .search input').first().clear().type(row);
+ cy.contains(`datatable-body-row datatable-body-cell .datatable-body-cell-label`, row).should(
+ 'not.exist'
+ );
+});
+
+Then('I should see rows with following entries', (entries) => {
+ entries.hashes().forEach((entry: any) => {
+ cy.get('cd-table .search input').first().clear().type(entry.hostname);
+ cy.contains(
+ `datatable-body-row datatable-body-cell .datatable-body-cell-label`,
+ entry.hostname
+ ).should('exist');
+ });
+});
+
+And('I should see row {string} have {string}', (row: string, options: string) => {
+ if (options) {
+ cy.get('cd-table .search input').first().clear().type(row);
+ for (const option of options.split(',')) {
+ cy.contains(
+ `datatable-body-row datatable-body-cell .datatable-body-cell-label .badge`,
+ option
+ ).should('exist');
+ }
+ }
+});
+
+And('I should see row {string} does not have {string}', (row: string, options: string) => {
+ if (options) {
+ cy.get('cd-table .search input').first().clear().type(row);
+ for (const option of options.split(',')) {
+ cy.contains(
+ `datatable-body-row datatable-body-cell .datatable-body-cell-label .badge`,
+ option
+ ).should('not.exist');
+ }
+ }
+});
+
+And('I go to the {string} tab', (names: string) => {
+ for (const name of names.split(', ')) {
+ cy.contains('.nav.nav-tabs a', name).click();
+ }
+});
+
+And('select {string} {string}', (selectionName: string, option: string) => {
+ cy.get(`select[name=${selectionName}]`).select(option);
+ cy.get(`select[name=${selectionName}] option:checked`).contains(option);
+});
+
+When('I expand the row {string}', (row: string) => {
+ cy.contains('.datatable-body-row', row).first().find('.tc_expand-collapse').click();
+});
+
+And('I should see row {string} have {string} on this tab', (row: string, options: string) => {
+ if (options) {
+ cy.get('cd-table').should('exist');
+ cy.get('datatable-scroller, .empty-row');
+ cy.get('.datatable-row-detail').within(() => {
+ cy.get('cd-table .search input').first().clear().type(row);
+ for (const option of options.split(',')) {
+ cy.contains(
+ `datatable-body-row datatable-body-cell .datatable-body-cell-label span`,
+ option
+ ).should('exist');
+ }
+ });
+ }
+});
--- /dev/null
+import { Given, Then } from 'cypress-cucumber-preprocessor/steps';
+
+Given('I am on the {string} section', (page: string) => {
+ cy.get('cd-wizard').within(() => {
+ cy.get('.nav-link').should('contain.text', page).first().click();
+ cy.get('.nav-link.active').should('contain.text', page);
+ });
+});
+
+Then('I should see a message {string}', () => {
+ cy.get('cd-create-cluster').should('contain.text', 'Please expand your cluster first');
+});
--- /dev/null
+import { Then, When } from 'cypress-cucumber-preprocessor/steps';
+import 'cypress-iframe';
+
+function getIframe() {
+ cy.frameLoaded('#iframe');
+ return cy.iframe();
+}
+
+Then('I should see the grafana panel {string}', (panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ cy.get(`[aria-label="${panel} panel"]`).should('be.visible');
+ });
+ }
+ });
+});
+
+When('I view the grafana panel {string}', (panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ cy.get(`[aria-label="${panel} panel"]`).within(() => {
+ cy.get('h2').click();
+ });
+ cy.get('[aria-label="Panel header item View"]').click();
+ });
+ }
+ });
+});
+
+Then('I should not see {string} in the panel {string}', (value: string, panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ cy.get(`[aria-label="${panel} panel"]`)
+ .should('be.visible')
+ .within(() => {
+ cy.get('span').first().should('not.have.text', value);
+ });
+ });
+ }
+ });
+});
+
+Then(
+ 'I should see the legends {string} in the graph {string}',
+ (legends: string, panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ cy.get(`[aria-label="${panel} panel"]`)
+ .should('be.visible')
+ .within(() => {
+ for (const legend of legends.split(', ')) {
+ cy.get('a').contains(legend);
+ }
+ });
+ });
+ }
+ });
+ }
+);
+
+Then('I should not see No Data in the graph {string}', (panels: string) => {
+ getIframe().within(() => {
+ for (const panel of panels.split(', ')) {
+ cy.get('.grafana-app')
+ .wait(100)
+ .within(() => {
+ cy.get(`[aria-label="${panel} panel"]`)
+ .should('be.visible')
+ .within(() => {
+ cy.get('div.datapoints-warning').should('not.exist');
+ });
+ });
+ }
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class UrlsCollection extends PageHelper {
+ pages = {
+ // Cluster expansion
+ welcome: { url: '#/expand-cluster', id: 'cd-create-cluster' },
+
+ // Landing page
+ dashboard: { url: '#/dashboard', id: 'cd-dashboard' },
+
+ // Hosts
+ hosts: { url: '#/hosts', id: 'cd-hosts' },
+ 'add hosts': { url: '#/hosts/(modal:add)', id: 'cd-host-form' },
+
+ // Services
+ services: { url: '#/services', id: 'cd-services' },
+ 'create services': { url: '#/services/(modal:create)', id: 'cd-service-form' },
+
+ // Physical Disks
+ 'physical disks': { url: '#/inventory', id: 'cd-inventory' },
+
+ // Monitors
+ monitors: { url: '#/monitor', id: 'cd-monitor' },
+
+ // OSDs
+ osds: { url: '#/osd', id: 'cd-osd-list' },
+ 'create osds': { url: '#/osd/create', id: 'cd-osd-form' },
+
+ // Configuration
+ configuration: { url: '#/configuration', id: 'cd-configuration' },
+
+ // Crush Map
+ 'crush map': { url: '#/crush-map', id: 'cd-crushmap' },
+
+ // Mgr modules
+ 'mgr-modules': { url: '#/mgr-modules', id: 'cd-mgr-module-list' },
+
+ // Logs
+ logs: { url: '#/logs', id: 'cd-logs' },
+
+ // RGW Daemons
+ 'rgw daemons': { url: '#/rgw/daemon', id: 'cd-rgw-daemon-list' }
+ };
+}
--- /dev/null
+import { FilesystemsPageHelper } from './filesystems.po';
+
+describe('File Systems page', () => {
+ const filesystems = new FilesystemsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ filesystems.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ filesystems.expectBreadcrumbText('File Systems');
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class FilesystemsPageHelper extends PageHelper {
+ pages = { index: { url: '#/cephfs', id: 'cd-cephfs-list' } };
+}
--- /dev/null
+import { HostsPageHelper } from '../cluster/hosts.po';
+
+describe('Hosts page', () => {
+ const hosts = new HostsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ hosts.navigateTo();
+ });
+
+ describe('when Orchestrator is available', () => {
+ beforeEach(function () {
+ cy.fixture('orchestrator/inventory.json').as('hosts');
+ cy.fixture('orchestrator/services.json').as('services');
+ });
+
+ it('should not add an exsiting host', function () {
+ const hostname = Cypress._.sample(this.hosts).name;
+ hosts.navigateTo('add');
+ hosts.add(hostname, true);
+ });
+
+ it('should drain and remove a host and then add it back', function () {
+ const hostname = Cypress._.last(this.hosts)['name'];
+
+ // should drain the host first before deleting
+ hosts.drain(hostname);
+ hosts.remove(hostname);
+
+ // add it back
+ hosts.navigateTo('add');
+ hosts.add(hostname);
+ hosts.checkExist(hostname, true);
+ });
+
+ it('should display inventory', function () {
+ for (const host of this.hosts) {
+ hosts.clickTab('cd-host-details', host.name, 'Physical Disks');
+ cy.get('cd-host-details').within(() => {
+ hosts.expectTableCount('total', host.devices.length);
+ });
+ }
+ });
+
+ it('should display daemons', function () {
+ for (const host of this.hosts) {
+ hosts.clickTab('cd-host-details', host.name, 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ hosts.getTableCount('total').should('be.gte', 0);
+ });
+ }
+ });
+
+ it('should edit host labels', function () {
+ const hostname = Cypress._.sample(this.hosts).name;
+ const labels = ['foo', 'bar'];
+ hosts.editLabels(hostname, labels, true);
+ hosts.editLabels(hostname, labels, false);
+ });
+
+ it('should enter host into maintenance', function () {
+ const hostname = Cypress._.sample(this.hosts).name;
+ const serviceList = new Array();
+ this.services.forEach((service: any) => {
+ if (hostname === service.hostname) {
+ serviceList.push(service.daemon_type);
+ }
+ });
+ let enterMaintenance = true;
+ serviceList.forEach((service: string) => {
+ if (service === 'mgr' || service === 'alertmanager') {
+ enterMaintenance = false;
+ }
+ });
+ if (enterMaintenance) {
+ hosts.maintenance(hostname);
+ }
+ });
+
+ it('should exit host from maintenance', function () {
+ const hostname = Cypress._.sample(this.hosts).name;
+ hosts.maintenance(hostname, true);
+ });
+ });
+});
--- /dev/null
+import { InventoryPageHelper } from '../cluster/inventory.po';
+
+describe('Physical Disks page', () => {
+ const inventory = new InventoryPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ inventory.navigateTo();
+ });
+
+ it('should have correct devices', () => {
+ cy.fixture('orchestrator/inventory.json').then((hosts) => {
+ const totalDiskCount = Cypress._.sumBy(hosts, 'devices.length');
+ inventory.expectTableCount('total', totalDiskCount);
+ for (const host of hosts) {
+ inventory.filterTable('Hostname', host['name']);
+ inventory.getTableCount('found').should('be.eq', host.devices.length);
+ }
+ });
+ });
+
+ it('should identify device', () => {
+ inventory.identify();
+ });
+});
--- /dev/null
+import { OSDsPageHelper } from '../cluster/osds.po';
+import { DashboardPageHelper } from '../ui/dashboard.po';
+
+describe('OSDs page', () => {
+ const osds = new OSDsPageHelper();
+ const dashboard = new DashboardPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ osds.navigateTo();
+ });
+
+ describe('when Orchestrator is available', () => {
+ it('should create and delete OSDs', () => {
+ osds.getTableCount('total').as('initOSDCount');
+ osds.navigateTo('create');
+ osds.create('hdd');
+
+ cy.get('@newOSDCount').then((newCount) => {
+ cy.get('@initOSDCount').then((oldCount) => {
+ const expectedCount = Number(oldCount) + Number(newCount);
+
+ // check total rows
+ osds.expectTableCount('total', expectedCount);
+
+ // landing page is easier to check OSD status
+ dashboard.navigateTo();
+ dashboard.infoCardBody('OSDs').should('contain.text', `${expectedCount} total`);
+ dashboard.infoCardBody('OSDs').should('contain.text', `${expectedCount} up`);
+ dashboard.infoCardBody('OSDs').should('contain.text', `${expectedCount} in`);
+
+ cy.wait(30000);
+ expect(Number(newCount)).to.be.gte(2);
+ // Delete the first OSD we created
+ osds.navigateTo();
+ const deleteOsdId = Number(oldCount);
+ osds.deleteByIDs([deleteOsdId], false);
+ osds.ensureNoOsd(deleteOsdId);
+
+ cy.wait(30000);
+ // Replace the second OSD we created
+ const replaceID = Number(oldCount) + 1;
+ osds.deleteByIDs([replaceID], true);
+ osds.checkStatus(replaceID, ['destroyed']);
+ });
+ });
+ });
+ });
+});
--- /dev/null
+import { ServicesPageHelper } from '../cluster/services.po';
+
+describe('Services page', () => {
+ const services = new ServicesPageHelper();
+ const serviceName = 'rgw.foo';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ services.navigateTo();
+ });
+
+ describe('when Orchestrator is available', () => {
+ it('should create an rgw service', () => {
+ services.navigateTo('create');
+ services.addService('rgw');
+
+ services.checkExist(serviceName, true);
+ });
+
+ it('should edit a service', () => {
+ const count = '2';
+ services.editService(serviceName, count);
+ services.expectPlacementCount(serviceName, count);
+ });
+
+ it('should create and delete an ingress service', () => {
+ services.navigateTo('create');
+ services.addService('ingress');
+
+ services.checkExist('ingress.rgw.foo', true);
+
+ services.deleteService('ingress.rgw.foo');
+ });
+ });
+});
--- /dev/null
+Feature: Grafana panels
+
+ Go to some of the grafana performance section and check if
+ panels are populated without any issues
+
+ Background: Log in
+ Given I am logged in
+
+ Scenario Outline: Hosts Overall Performance
+ Given I am on the "hosts" page
+ When I go to the "Overall Performance" tab
+ Then I should see the grafana panel "<panel>"
+ When I view the grafana panel "<panel>"
+ Then I should not see "No Data" in the panel "<panel>"
+
+ Examples:
+ | panel |
+ | OSD Hosts |
+ | AVG CPU Busy |
+ | AVG RAM Utilization |
+ | Physical IOPS |
+ | AVG Disk Utilization |
+ | Network Load |
+ | CPU Busy - Top 10 Hosts |
+ | Network Load - Top 10 Hosts |
+
+ Scenario Outline: RGW Daemon Overall Performance
+ Given I am on the "rgw daemons" page
+ When I go to the "Overall Performance" tab
+ Then I should see the grafana panel "<panel>"
+ When I view the grafana panel "<panel>"
+ Then I should not see No Data in the graph "<panel>"
+ And I should see the legends "<legends>" in the graph "<panel>"
+
+ Examples:
+ | panel | legends |
+ | Total Requests/sec by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
+ | GET Latencies by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
+ | Bandwidth by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
+ | PUT Latencies by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
+ | Average GET/PUT Latencies | GET AVG, PUT AVG |
+ | Bandwidth Consumed by Type | GETs, PUTs |
+
+ Scenario Outline: RGW per Daemon Performance
+ Given I am on the "rgw daemons" page
+ When I expand the row "<name>"
+ And I go to the "Performance Details" tab
+ Then I should see the grafana panel "<panel>"
+ When I view the grafana panel "<panel>"
+ Then I should not see No Data in the graph "<panel>"
+ And I should see the legends "<name>" in the graph "<panel>"
+
+ Examples:
+ | name | panel |
+ | foo.ceph-node-00 | Bandwidth by HTTP Operation |
+ | foo.ceph-node-00 | HTTP Request Breakdown |
+ | foo.ceph-node-00 | Workload Breakdown |
+ | foo.ceph-node-01 | Bandwidth by HTTP Operation |
+ | foo.ceph-node-01 | HTTP Request Breakdown |
+ | foo.ceph-node-01 | Workload Breakdown |
+ | foo.ceph-node-02 | Bandwidth by HTTP Operation |
+ | foo.ceph-node-02 | HTTP Request Breakdown |
+ | foo.ceph-node-02 | Workload Breakdown |
--- /dev/null
+Feature: Cluster expansion welcome screen
+
+ Go to the welcome screen and decide whether
+ to proceed to wizard or skips to landing page
+
+ Background: Login
+ Given I am logged in
+
+ Scenario: Cluster expansion welcome screen
+ Given I am on the "welcome" page
+ And I should see a button to "Expand Cluster"
+ And I should see a button to "Skip"
+ And I should see a message "Please expand your cluster first"
+
+ Scenario: Go to the Cluster expansion wizard
+ Given I am on the "welcome" page
+ And I should see a button to "Expand Cluster"
+ When I click on "Expand Cluster" button
+ Then I am on the "Add Hosts" section
+
+ Scenario: Skips the process and go to the landing page
+ Given I am on the "welcome" page
+ And I should see a button to "Skip"
+ When I click on "Skip" button
+ And I confirm to "Continue"
+ Then I should be on the "dashboard" page
--- /dev/null
+Feature: Cluster expansion host addition
+
+ Add some hosts and perform some host related actions like editing the labels
+ and removing the hosts from the cluster and verify all of the actions are performed
+ as expected
+
+ Background: Cluster expansion wizard
+ Given I am logged in
+ And I am on the "welcome" page
+ And I click on "Expand Cluster" button
+
+ Scenario Outline: Add hosts
+ Given I am on the "Add Hosts" section
+ When I click on "Add" button
+ And enter "hostname" "<hostname>"
+ And select options "<labels>"
+ And I click on "Add Host" button
+ Then I should not see the modal
+ And I should see a row with "<hostname>"
+ And I should see row "<hostname>" have "<labels>"
+
+ Examples:
+ | hostname | labels |
+ | ceph-node-01 | mon, mgr |
+ | ceph-node-02 ||
+
+ Scenario Outline: Remove hosts
+ Given I am on the "Add Hosts" section
+ And I should see a row with "<hostname>"
+ When I select a row "<hostname>"
+ And I click on "Remove" button from the table actions
+ Then I should see the modal
+ And I check the tick box in modal
+ And I click on "Remove Host" button
+ Then I should not see the modal
+ And I should not see a row with "<hostname>"
+
+ Examples:
+ | hostname |
+ | ceph-node-01 |
+ | ceph-node-02 |
+
+ Scenario: Add hosts using pattern 'ceph-node-[01-02]'
+ Given I am on the "Add Hosts" section
+ When I click on "Add" button
+ And enter "hostname" "ceph-node-[01-02]"
+ And I click on "Add Host" button
+ Then I should not see the modal
+ And I should see rows with following entries
+ | hostname |
+ | ceph-node-01 |
+ | ceph-node-02 |
+
+ Scenario: Add exisiting host and verify it failed
+ Given I am on the "Add Hosts" section
+ And I should see a row with "ceph-node-00"
+ When I click on "Add" button
+ And enter "hostname" "ceph-node-00"
+ Then I should see an error in "hostname" field
+
+ Scenario Outline: Add and remove labels on host
+ Given I am on the "Add Hosts" section
+ When I select a row "<hostname>"
+ And I click on "Edit" button from the table actions
+ And "add" option "<labels>"
+ And I click on "Edit Host" button
+ Then I should see row "<hostname>" have "<labels>"
+ When I select a row "<hostname>"
+ And I click on "Edit" button from the table actions
+ And "remove" option "<labels>"
+ And I click on "Edit Host" button
+ Then I should see row "<hostname>" does not have "<labels>"
+
+ Examples:
+ | hostname | labels |
+ | ceph-node-01 | foo |
--- /dev/null
+/* tslint:disable*/
+import {
+ CreateClusterServicePageHelper,
+ CreateClusterWizardHelper
+} from '../../cluster/create-cluster.po';
+/* tslint:enable*/
+
+describe('Create cluster create services page', () => {
+ const createCluster = new CreateClusterWizardHelper();
+ const createClusterServicePage = new CreateClusterServicePageHelper();
+
+ const createService = (serviceType: string, serviceName: string, count = 1) => {
+ cy.get('[aria-label=Create]').first().click();
+ createClusterServicePage.addService(serviceType, false, count);
+ createClusterServicePage.checkExist(serviceName, true);
+ };
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ createCluster.navigateTo();
+ createCluster.createCluster();
+ cy.get('.nav-link').contains('Create Services').click();
+ });
+
+ it('should check if title contains Create Services', () => {
+ cy.get('.title').should('contain.text', 'Create Services');
+ });
+
+ describe('when Orchestrator is available', () => {
+ const serviceName = 'mds.test';
+
+ it('should create an mds service', () => {
+ createService('mds', serviceName);
+ });
+
+ it('should edit a service', () => {
+ const daemonCount = '2';
+ createClusterServicePage.editService(serviceName, daemonCount);
+ createClusterServicePage.expectPlacementCount(serviceName, daemonCount);
+ });
+
+ it('should delete mds service', () => {
+ createClusterServicePage.deleteService('mds.test');
+ });
+ });
+});
--- /dev/null
+/* tslint:disable*/
+import { CreateClusterWizardHelper } from '../../cluster/create-cluster.po';
+import { OSDsPageHelper } from '../../cluster/osds.po';
+/* tslint:enable*/
+
+const osds = new OSDsPageHelper();
+
+describe('Create cluster create osds page', () => {
+ const createCluster = new CreateClusterWizardHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ createCluster.navigateTo();
+ createCluster.createCluster();
+ cy.get('.nav-link').contains('Create OSDs').click();
+ });
+
+ it('should check if title contains Create OSDs', () => {
+ cy.get('.title').should('contain.text', 'Create OSDs');
+ });
+
+ describe('when Orchestrator is available', () => {
+ it('should create OSDs', () => {
+ const hostnames = ['ceph-node-00', 'ceph-node-01'];
+ for (const hostname of hostnames) {
+ osds.create('hdd', hostname, true);
+
+ // Go to the Review section and Expand the cluster
+ // because the drive group spec is only stored
+ // in frontend and will be lost when refreshed
+ cy.get('.nav-link').contains('Review').click();
+ cy.get('button[aria-label="Next"]').click();
+ cy.get('cd-dashboard').should('exist');
+ createCluster.navigateTo();
+ createCluster.createCluster();
+ cy.get('.nav-link').contains('Create OSDs').click();
+ }
+ });
+ });
+});
--- /dev/null
+/* tslint:disable*/
+import {
+ CreateClusterHostPageHelper,
+ CreateClusterWizardHelper
+} from '../../cluster/create-cluster.po';
+/* tslint:enable*/
+
+describe('Create Cluster Review page', () => {
+ const createCluster = new CreateClusterWizardHelper();
+ const createClusterHostPage = new CreateClusterHostPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ createCluster.navigateTo();
+ createCluster.createCluster();
+
+ cy.get('.nav-link').contains('Review').click();
+ });
+
+ describe('navigation link test', () => {
+ it('should check if active nav-link is of Review section', () => {
+ cy.get('.nav-link.active').should('contain.text', 'Review');
+ });
+ });
+
+ describe('fields check', () => {
+ it('should check cluster resources table is present', () => {
+ // check for table header 'Cluster Resources'
+ createCluster.getLegends().its(0).should('have.text', 'Cluster Resources');
+
+ // check for fields in table
+ createCluster.getStatusTables().should('contain.text', 'Hosts');
+ createCluster.getStatusTables().should('contain.text', 'Storage Capacity');
+ createCluster.getStatusTables().should('contain.text', 'CPUs');
+ createCluster.getStatusTables().should('contain.text', 'Memory');
+ });
+
+ it('should check Host Details table is present', () => {
+ // check for there to be two tables
+ createCluster.getDataTables().should('have.length', 1);
+
+ // verify correct columns on Host Details table
+ createCluster.getDataTableHeaders(0).contains('Hostname');
+
+ createCluster.getDataTableHeaders(0).contains('Labels');
+
+ createCluster.getDataTableHeaders(0).contains('CPUs');
+
+ createCluster.getDataTableHeaders(0).contains('Cores');
+
+ createCluster.getDataTableHeaders(0).contains('Total Memory');
+
+ createCluster.getDataTableHeaders(0).contains('Raw Capacity');
+
+ createCluster.getDataTableHeaders(0).contains('HDDs');
+
+ createCluster.getDataTableHeaders(0).contains('Flash');
+
+ createCluster.getDataTableHeaders(0).contains('NICs');
+ });
+
+ it('should check default host name is present', () => {
+ createClusterHostPage.check_for_host();
+ });
+ });
+});
--- /dev/null
+/* tslint:disable*/
+import { CreateClusterWizardHelper } from '../../cluster/create-cluster.po';
+import { HostsPageHelper } from '../../cluster/hosts.po';
+import { ServicesPageHelper } from '../../cluster/services.po';
+/* tslint:enable*/
+
+describe('when cluster creation is completed', () => {
+ const createCluster = new CreateClusterWizardHelper();
+ const services = new ServicesPageHelper();
+ const hosts = new HostsPageHelper();
+
+ const hostnames = ['ceph-node-00', 'ceph-node-01', 'ceph-node-02', 'ceph-node-03'];
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ });
+
+ it('should redirect to dashboard landing page after cluster creation', () => {
+ createCluster.navigateTo();
+ createCluster.createCluster();
+
+ // Explicitly skip OSD Creation Step so that it prevents from
+ // deploying OSDs to the hosts automatically.
+ cy.get('.nav-link').contains('Create OSDs').click();
+ cy.get('button[aria-label="Skip this step"]').click();
+
+ cy.get('.nav-link').contains('Review').click();
+ cy.get('button[aria-label="Next"]').click();
+ cy.get('cd-dashboard').should('exist');
+ });
+
+ describe('Hosts page', () => {
+ beforeEach(() => {
+ hosts.navigateTo();
+ });
+
+ it('should add one more host', () => {
+ hosts.navigateTo('add');
+ hosts.add(hostnames[3]);
+ hosts.checkExist(hostnames[3], true);
+ });
+
+ it('should check if monitoring stacks are running on the root host', { retries: 2 }, () => {
+ const monitoringStack = ['alertmanager', 'grafana', 'node-exporter', 'prometheus'];
+ hosts.clickTab('cd-host-details', 'ceph-node-00', 'Daemons');
+ for (const daemon of monitoringStack) {
+ cy.get('cd-host-details').within(() => {
+ services.checkServiceStatus(daemon);
+ });
+ }
+ });
+
+ it('should have removed "_no_schedule" label', () => {
+ for (const hostname of hostnames) {
+ hosts.checkLabelExists(hostname, ['_no_schedule'], false);
+ }
+ });
+
+ it('should display inventory', () => {
+ hosts.clickTab('cd-host-details', hostnames[1], 'Physical Disks');
+ cy.get('cd-host-details').within(() => {
+ hosts.getTableCount('total').should('be.gte', 0);
+ });
+ });
+
+ it('should display daemons', () => {
+ hosts.clickTab('cd-host-details', hostnames[1], 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ hosts.getTableCount('total').should('be.gte', 0);
+ });
+ });
+
+ it('should check if mon daemon is running on all hosts', () => {
+ for (const hostname of hostnames) {
+ hosts.clickTab('cd-host-details', hostname, 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ services.checkServiceStatus('mon');
+ });
+ }
+ });
+ });
+});
--- /dev/null
+/* tslint:disable*/
+import { OSDsPageHelper } from '../../cluster/osds.po';
+/* tslint:enable*/
+
+describe('OSDs page', () => {
+ const osds = new OSDsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ osds.navigateTo();
+ });
+
+ it('should check if atleast 3 osds are created', { retries: 3 }, () => {
+ // we have created a total of more than 3 osds throughout
+ // the whole tests so ensuring that atleast
+ // 3 osds are listed in the table. Since the OSD
+ // creation can take more time going with
+ // retry of 3
+ for (let id = 0; id < 3; id++) {
+ osds.checkStatus(id, ['in', 'up']);
+ }
+ });
+});
--- /dev/null
+/* tslint:disable*/
+import { HostsPageHelper } from '../../cluster/hosts.po';
+import { ServicesPageHelper } from '../../cluster/services.po';
+/* tslint:enable*/
+
+describe('Host Page', () => {
+ const hosts = new HostsPageHelper();
+ const services = new ServicesPageHelper();
+
+ const hostnames = ['ceph-node-00', 'ceph-node-01', 'ceph-node-02', 'ceph-node-03'];
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ hosts.navigateTo();
+ });
+
+ // rgw is needed for testing the force maintenance
+ it('should create rgw services', () => {
+ services.navigateTo('create');
+ services.addService('rgw', false, 4);
+ services.checkExist('rgw.foo', true);
+ });
+
+ it('should check if rgw daemon is running on all hosts', () => {
+ for (const hostname of hostnames) {
+ hosts.clickTab('cd-host-details', hostname, 'Daemons');
+ cy.get('cd-host-details').within(() => {
+ services.checkServiceStatus('rgw');
+ });
+ }
+ });
+
+ it('should force maintenance and exit', () => {
+ hosts.maintenance(hostnames[3], true, true);
+ });
+
+ it('should drain, remove and add the host back', () => {
+ hosts.drain(hostnames[3]);
+ hosts.remove(hostnames[3]);
+ hosts.navigateTo('add');
+ hosts.add(hostnames[3]);
+ hosts.checkExist(hostnames[3], true);
+ });
+
+ it('should show the exact count of daemons', () => {
+ hosts.checkServiceInstancesExist(hostnames[0], ['mgr: 1', 'prometheus: 1']);
+ });
+});
--- /dev/null
+/* tslint:disable*/
+import { ServicesPageHelper } from '../../cluster/services.po';
+/* tslint:enable*/
+
+describe('Services page', () => {
+ const services = new ServicesPageHelper();
+ const mdsDaemonName = 'mds.test';
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ services.navigateTo();
+ });
+
+ it('should check if rgw service is created', () => {
+ services.checkExist('rgw.foo', true);
+ });
+
+ it('should create an mds service', () => {
+ services.navigateTo('create');
+ services.addService('mds', false);
+ services.checkExist(mdsDaemonName, true);
+
+ services.clickServiceTab(mdsDaemonName, 'Daemons');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus(mdsDaemonName);
+ });
+ });
+
+ it('should stop a daemon', () => {
+ services.clickServiceTab(mdsDaemonName, 'Daemons');
+ services.checkServiceStatus(mdsDaemonName);
+
+ services.daemonAction('mds', 'stop');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus(mdsDaemonName, 'stopped');
+ });
+ });
+
+ it('should restart a daemon', () => {
+ services.checkExist(mdsDaemonName, true);
+ services.clickServiceTab(mdsDaemonName, 'Daemons');
+ services.daemonAction('mds', 'restart');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus(mdsDaemonName, 'running');
+ });
+ });
+
+ it('should redeploy a daemon', () => {
+ services.checkExist(mdsDaemonName, true);
+ services.clickServiceTab(mdsDaemonName, 'Daemons');
+
+ services.daemonAction('mds', 'stop');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus(mdsDaemonName, 'stopped');
+ });
+ services.daemonAction('mds', 'redeploy');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus(mdsDaemonName, 'running');
+ });
+ });
+
+ it('should start a daemon', () => {
+ services.checkExist(mdsDaemonName, true);
+ services.clickServiceTab(mdsDaemonName, 'Daemons');
+
+ services.daemonAction('mds', 'stop');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus(mdsDaemonName, 'stopped');
+ });
+ services.daemonAction('mds', 'start');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus(mdsDaemonName, 'running');
+ });
+ });
+
+ it('should delete an mds service', () => {
+ services.deleteService(mdsDaemonName);
+ });
+
+ it('should create and delete snmp-gateway service with version V2c', () => {
+ services.navigateTo('create');
+ services.addService('snmp-gateway', false, 1, 'V2c');
+ services.checkExist('snmp-gateway', true);
+
+ services.clickServiceTab('snmp-gateway', 'Daemons');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus('snmp-gateway');
+ });
+
+ services.deleteService('snmp-gateway');
+ });
+
+ it('should create and delete snmp-gateway service with version V3', () => {
+ services.navigateTo('create');
+ services.addService('snmp-gateway', false, 1, 'V3', true);
+ services.checkExist('snmp-gateway', true);
+
+ services.clickServiceTab('snmp-gateway', 'Daemons');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus('snmp-gateway');
+ });
+
+ services.deleteService('snmp-gateway');
+ });
+
+ it('should create and delete snmp-gateway service with version V3 and w/o privacy protocol', () => {
+ services.navigateTo('create');
+ services.addService('snmp-gateway', false, 1, 'V3', false);
+ services.checkExist('snmp-gateway', true);
+
+ services.clickServiceTab('snmp-gateway', 'Daemons');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus('snmp-gateway');
+ });
+
+ services.deleteService('snmp-gateway');
+ });
+
+ it('should create ingress as unmanaged', () => {
+ services.navigateTo('create');
+ services.addService('ingress', false, undefined, undefined, undefined, true);
+ services.checkExist('ingress.rgw.foo', true);
+ services.isUnmanaged('ingress.rgw.foo', true);
+ services.deleteService('ingress.rgw.foo');
+ });
+
+ it('should check if exporter daemons are running', () => {
+ services.clickServiceTab('ceph-exporter', 'Daemons');
+ cy.get('cd-service-details').within(() => {
+ services.checkServiceStatus('ceph-exporter', 'running');
+ });
+ });
+});
--- /dev/null
+/* tslint:disable*/
+import { ServicesPageHelper } from '../../cluster/services.po';
+import { NFSPageHelper } from '../../orchestrator/workflow/nfs/nfs-export.po';
+import { BucketsPageHelper } from '../../rgw/buckets.po';
+/* tslint:enable*/
+
+describe('nfsExport page', () => {
+ const nfsExport = new NFSPageHelper();
+ const services = new ServicesPageHelper();
+ const buckets = new BucketsPageHelper();
+ const bucketName = 'e2e.nfs.bucket';
+ // @TODO: uncomment this when a CephFS volume can be created through Dashboard.
+ // const fsPseudo = '/fsPseudo';
+ const rgwPseudo = '/rgwPseudo';
+ const editPseudo = '/editPseudo';
+ const backends = ['CephFS', 'Object Gateway'];
+ const squash = 'no_root_squash';
+ const client: object = { addresses: '192.168.0.10' };
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ nfsExport.navigateTo();
+ });
+
+ describe('breadcrumb test', () => {
+ it('should open and show breadcrumb', () => {
+ nfsExport.expectBreadcrumbText('NFS');
+ });
+ });
+
+ describe('Create, edit and delete', () => {
+ it('should create an NFS cluster', () => {
+ services.navigateTo('create');
+
+ services.addService('nfs');
+
+ services.checkExist('nfs.testnfs', true);
+ services.clickServiceTab('nfs.testnfs', 'Daemons');
+ services.checkServiceStatus('nfs');
+ });
+
+ it('should create a nfs-export with RGW backend', () => {
+ buckets.navigateTo('create');
+ buckets.create(bucketName, 'dashboard', 'default-placement');
+
+ nfsExport.navigateTo();
+ nfsExport.existTableCell(rgwPseudo, false);
+ nfsExport.navigateTo('create');
+ nfsExport.create(backends[1], squash, client, rgwPseudo, bucketName);
+ nfsExport.existTableCell(rgwPseudo);
+ });
+
+ // @TODO: uncomment this when a CephFS volume can be created through Dashboard.
+ // it('should create a nfs-export with CephFS backend', () => {
+ // nfsExport.navigateTo();
+ // nfsExport.existTableCell(fsPseudo, false);
+ // nfsExport.navigateTo('create');
+ // nfsExport.create(backends[0], squash, client, fsPseudo);
+ // nfsExport.existTableCell(fsPseudo);
+ // });
+
+ it('should show Clients', () => {
+ nfsExport.clickTab('cd-nfs-details', rgwPseudo, 'Clients (1)');
+ cy.get('cd-nfs-details').within(() => {
+ nfsExport.getTableCount('total').should('be.gte', 0);
+ });
+ });
+
+ it('should edit an export', () => {
+ nfsExport.editExport(rgwPseudo, editPseudo);
+
+ nfsExport.existTableCell(editPseudo);
+ });
+
+ it('should delete exports and bucket', () => {
+ nfsExport.delete(editPseudo);
+
+ buckets.navigateTo();
+ buckets.delete(bucketName);
+ });
+ });
+});
--- /dev/null
+/* tslint:disable*/
+import { PageHelper } from '../../../page-helper.po';
+/* tslint:enable*/
+
+const pages = {
+ index: { url: '#/nfs', id: 'cd-nfs-list' },
+ create: { url: '#/nfs/create', id: 'cd-nfs-form' }
+};
+
+export class NFSPageHelper extends PageHelper {
+ pages = pages;
+
+ @PageHelper.restrictTo(pages.create.url)
+ create(backend: string, squash: string, client: object, pseudo: string, rgwPath?: string) {
+ this.selectOption('cluster_id', 'testnfs');
+ // select a storage backend
+ this.selectOption('name', backend);
+ if (backend === 'CephFS') {
+ this.selectOption('fs_name', 'myfs');
+
+ cy.get('#security_label').click({ force: true });
+ } else {
+ cy.get('input[data-testid=rgw_path]').type(rgwPath);
+ }
+
+ cy.get('input[name=pseudo]').type(pseudo);
+ this.selectOption('squash', squash);
+
+ // Add clients
+ cy.get('button[name=add_client]').click({ force: true });
+ cy.get('input[name=addresses]').type(client['addresses']);
+
+ // Check if we can remove clients and add it again
+ cy.get('span[name=remove_client]').click({ force: true });
+ cy.get('button[name=add_client]').click({ force: true });
+ cy.get('input[name=addresses]').type(client['addresses']);
+
+ cy.get('cd-submit-button').click();
+ }
+
+ editExport(pseudo: string, editPseudo: string) {
+ this.navigateEdit(pseudo);
+
+ cy.get('input[name=pseudo]').clear().type(editPseudo);
+
+ cy.get('cd-submit-button').click();
+
+ // Click the export and check its details table for updated content
+ this.getExpandCollapseElement(editPseudo).click();
+ cy.get('.active.tab-pane').should('contain.text', editPseudo);
+ }
+}
--- /dev/null
+interface Page {
+ url: string;
+ id: string;
+}
+
+export abstract class PageHelper {
+ pages: Record<string, Page>;
+
+ /**
+ * Decorator to be used on Helper methods to restrict access to one particular URL. This shall
+ * help developers to prevent and highlight mistakes. It also reduces boilerplate code and by
+ * thus, increases readability.
+ */
+ static restrictTo(page: string): Function {
+ return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
+ const fn: Function = descriptor.value;
+ descriptor.value = function (...args: any) {
+ cy.location('hash').should((url) => {
+ expect(url).to.eq(
+ page,
+ `Method ${target.constructor.name}::${propertyKey} is supposed to be ` +
+ `run on path "${page}", but was run on URL "${url}"`
+ );
+ });
+ fn.apply(this, args);
+ };
+ };
+ }
+
+ /**
+ * Navigates to the given page or to index.
+ * Waits until the page component is loaded
+ */
+ navigateTo(name: string = null) {
+ name = name || 'index';
+ const page = this.pages[name];
+
+ cy.visit(page.url);
+ cy.get(page.id);
+ }
+
+ /**
+ * Navigates back and waits for the hash to change
+ */
+ navigateBack() {
+ cy.location('hash').then((hash) => {
+ cy.go('back');
+ cy.location('hash').should('not.be', hash);
+ });
+ }
+
+ /**
+ * Navigates to the edit page
+ */
+ navigateEdit(name: string, select = true, breadcrumb = true) {
+ if (select) {
+ this.navigateTo();
+ this.getFirstTableCell(name).click();
+ }
+ cy.contains('Creating...').should('not.exist');
+ cy.contains('button', 'Edit').click();
+ if (breadcrumb) {
+ this.expectBreadcrumbText('Edit');
+ }
+ }
+
+ /**
+ * Checks the active breadcrumb value.
+ */
+ expectBreadcrumbText(text: string) {
+ cy.get('.breadcrumb-item.active').should('have.text', text);
+ }
+
+ getTabs() {
+ return cy.get('.nav.nav-tabs a');
+ }
+
+ getTab(tabName: string) {
+ return cy.contains('.nav.nav-tabs a', tabName);
+ }
+
+ getTabText(index: number) {
+ return this.getTabs().its(index).text();
+ }
+
+ getTabsCount(): any {
+ return this.getTabs().its('length');
+ }
+
+ /**
+ * Helper method to navigate/click a tab inside the expanded table row.
+ * @param selector The selector of the expanded table row.
+ * @param name The name of the row which should expand.
+ * @param tabName Name of the tab to be navigated/clicked.
+ */
+ clickTab(selector: string, name: string, tabName: string) {
+ this.getExpandCollapseElement(name).click();
+ cy.get(selector).within(() => {
+ this.getTab(tabName).click();
+ });
+ }
+
+ /**
+ * Helper method to select an option inside a select element.
+ * This method will also expect that the option was set.
+ * @param option The option text (not value) to be selected.
+ */
+ selectOption(selectionName: string, option: string) {
+ cy.get(`select[name=${selectionName}]`).select(option);
+ return this.expectSelectOption(selectionName, option);
+ }
+
+ /**
+ * Helper method to expect a set option inside a select element.
+ * @param option The selected option text (not value) that is to
+ * be expected.
+ */
+ expectSelectOption(selectionName: string, option: string) {
+ return cy.get(`select[name=${selectionName}] option:checked`).contains(option);
+ }
+
+ getLegends() {
+ return cy.get('legend');
+ }
+
+ getToast() {
+ return cy.get('.ngx-toastr');
+ }
+
+ /**
+ * Waits for the table to load its data
+ * Should be used in all methods that access the datatable
+ */
+ private waitDataTableToLoad() {
+ cy.get('cd-table').should('exist');
+ cy.get('datatable-scroller, .empty-row');
+ }
+
+ getDataTables() {
+ this.waitDataTableToLoad();
+
+ return cy.get('cd-table .dataTables_wrapper');
+ }
+
+ private getTableCountSpan(spanType: 'selected' | 'found' | 'total') {
+ return cy.contains('.datatable-footer-inner .page-count span', spanType);
+ }
+
+ // Get 'selected', 'found', or 'total' row count of a table.
+ getTableCount(spanType: 'selected' | 'found' | 'total') {
+ this.waitDataTableToLoad();
+ return this.getTableCountSpan(spanType).then(($elem) => {
+ const text = $elem
+ .filter((_i, e) => e.innerText.includes(spanType))
+ .first()
+ .text();
+
+ return Number(text.match(/(\d+)\s+\w*/)[1]);
+ });
+ }
+
+ // Wait until selected', 'found', or 'total' row count of a table equal to a number.
+ expectTableCount(spanType: 'selected' | 'found' | 'total', count: number) {
+ this.waitDataTableToLoad();
+ this.getTableCountSpan(spanType).should(($elem) => {
+ const text = $elem.first().text();
+ expect(Number(text.match(/(\d+)\s+\w*/)[1])).to.equal(count);
+ });
+ }
+
+ getTableRow(content: string) {
+ this.waitDataTableToLoad();
+
+ this.searchTable(content);
+ return cy.contains('.datatable-body-row', content);
+ }
+
+ getTableRows() {
+ this.waitDataTableToLoad();
+
+ return cy.get('datatable-row-wrapper');
+ }
+
+ /**
+ * Returns the first table cell.
+ * Optionally, you can specify the content of the cell.
+ */
+ getFirstTableCell(content?: string) {
+ this.waitDataTableToLoad();
+
+ if (content) {
+ this.searchTable(content);
+ return cy.contains('.datatable-body-cell-label', content);
+ } else {
+ return cy.get('.datatable-body-cell-label').first();
+ }
+ }
+
+ getTableCell(columnIndex: number, exactContent: string, partialMatch = false) {
+ this.waitDataTableToLoad();
+ this.clearTableSearchInput();
+ this.searchTable(exactContent);
+ if (partialMatch) {
+ return cy.contains(
+ `datatable-body-row datatable-body-cell:nth-child(${columnIndex})`,
+ exactContent
+ );
+ }
+ return cy.contains(
+ `datatable-body-row datatable-body-cell:nth-child(${columnIndex})`,
+ new RegExp(`^${exactContent}$`)
+ );
+ }
+
+ existTableCell(name: string, oughtToBePresent = true) {
+ const waitRule = oughtToBePresent ? 'be.visible' : 'not.exist';
+ this.getFirstTableCell(name).should(waitRule);
+ }
+
+ getExpandCollapseElement(content?: string) {
+ this.waitDataTableToLoad();
+
+ if (content) {
+ return cy.contains('.datatable-body-row', content).find('.tc_expand-collapse');
+ } else {
+ return cy.get('.tc_expand-collapse').first();
+ }
+ }
+
+ /**
+ * Gets column headers of table
+ */
+ getDataTableHeaders(index = 0) {
+ this.waitDataTableToLoad();
+
+ return cy.get('.datatable-header').its(index).find('.datatable-header-cell');
+ }
+
+ /**
+ * Grabs striped tables
+ */
+ getStatusTables() {
+ return cy.get('.table.table-striped');
+ }
+
+ filterTable(name: string, option: string) {
+ this.waitDataTableToLoad();
+
+ cy.get('.tc_filter_name > button').click();
+ cy.contains(`.tc_filter_name .dropdown-item`, name).click();
+
+ cy.get('.tc_filter_option > button').click();
+ cy.contains(`.tc_filter_option .dropdown-item`, option).click();
+ }
+
+ setPageSize(size: string) {
+ cy.get('cd-table .dataTables_paginate input').first().clear({ force: true }).type(size);
+ }
+
+ searchTable(text: string) {
+ this.waitDataTableToLoad();
+
+ this.setPageSize('10');
+ cy.get('[aria-label=search]').first().clear({ force: true }).type(text);
+ }
+
+ clearTableSearchInput() {
+ this.waitDataTableToLoad();
+
+ return cy.get('cd-table .search button').first().click();
+ }
+
+ // Click the action button
+ clickActionButton(action: string) {
+ cy.get('.table-actions button.dropdown-toggle').first().click(); // open submenu
+ cy.get(`button.${action}`).click(); // click on "action" menu item
+ }
+
+ /**
+ * This is a generic method to delete table rows.
+ * It will select the first row that contains the provided name and delete it.
+ * After that it will wait until the row is no longer displayed.
+ * @param name The string to search in table cells.
+ * @param columnIndex If provided, search string in columnIndex column.
+ */
+ delete(name: string, columnIndex?: number, section?: string) {
+ // Selects row
+ const getRow = columnIndex
+ ? this.getTableCell.bind(this, columnIndex)
+ : this.getFirstTableCell.bind(this);
+ getRow(name).click();
+ let action: string;
+ section === 'hosts' ? (action = 'remove') : (action = 'delete');
+
+ // Clicks on table Delete/Remove button
+ this.clickActionButton(action);
+
+ // Convert action to SentenceCase and Confirms deletion
+ const actionUpperCase = action.charAt(0).toUpperCase() + action.slice(1);
+ cy.get('cd-modal .custom-control-label').click();
+ cy.contains('cd-modal button', actionUpperCase).click();
+
+ // Wait for modal to close
+ cy.get('cd-modal').should('not.exist');
+
+ // Waits for item to be removed from table
+ getRow(name).should('not.exist');
+ }
+}
--- /dev/null
+import { PoolPageHelper } from './pools.po';
+
+describe('Pools page', () => {
+ const pools = new PoolPageHelper();
+ const poolName = 'pool_e2e_pool-test';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo();
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ it('should open and show breadcrumb', () => {
+ pools.expectBreadcrumbText('Pools');
+ });
+
+ it('should show two tabs', () => {
+ pools.getTabsCount().should('equal', 2);
+ });
+
+ it('should show pools list tab at first', () => {
+ pools.getTabText(0).should('eq', 'Pools List');
+ });
+
+ it('should show overall performance as a second tab', () => {
+ pools.getTabText(1).should('eq', 'Overall Performance');
+ });
+ });
+
+ describe('Create, update and destroy', () => {
+ it('should create a pool', () => {
+ pools.existTableCell(poolName, false);
+ pools.navigateTo('create');
+ pools.create(poolName, 8, 'rbd');
+ pools.existTableCell(poolName);
+ });
+
+ it('should edit a pools placement group', () => {
+ pools.existTableCell(poolName);
+ pools.edit_pool_pg(poolName, 32);
+ });
+
+ it('should show updated configuration field values', () => {
+ pools.existTableCell(poolName);
+ const bpsLimit = '4 B/s';
+ pools.edit_pool_configuration(poolName, bpsLimit);
+ });
+
+ it('should delete a pool', () => {
+ pools.delete(poolName);
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/pool', id: 'cd-pool-list' },
+ create: { url: '#/pool/create', id: 'cd-pool-form' }
+};
+
+export class PoolPageHelper extends PageHelper {
+ pages = pages;
+
+ private isPowerOf2(n: number) {
+ // tslint:disable-next-line: no-bitwise
+ return expect((n & (n - 1)) === 0, `Placement groups ${n} are not a power of 2`).to.be.true;
+ }
+
+ @PageHelper.restrictTo(pages.create.url)
+ create(name: string, placement_groups: number, ...apps: string[]) {
+ cy.get('input[name=name]').clear().type(name);
+
+ this.isPowerOf2(placement_groups);
+
+ this.selectOption('poolType', 'replicated');
+
+ this.expectSelectOption('pgAutoscaleMode', 'on');
+ this.selectOption('pgAutoscaleMode', 'off'); // To show pgNum field
+ cy.get('input[name=pgNum]').clear().type(`${placement_groups}`);
+ this.setApplications(apps);
+ cy.get('cd-submit-button').click();
+ }
+
+ edit_pool_pg(name: string, new_pg: number, wait = true) {
+ this.isPowerOf2(new_pg);
+ this.navigateEdit(name);
+
+ cy.get('input[name=pgNum]').clear().type(`${new_pg}`);
+ cy.get('cd-submit-button').click();
+ const str = `${new_pg} active+clean`;
+ this.getTableRow(name);
+ if (wait) {
+ this.getTableRow(name).contains(str);
+ }
+ }
+
+ edit_pool_configuration(name: string, bpsLimit: string) {
+ this.navigateEdit(name);
+
+ cy.get('.collapsible').click();
+ cy.get('cd-rbd-configuration-form')
+ .get('input[name=rbd_qos_bps_limit]')
+ .clear()
+ .type(`${bpsLimit}`);
+ cy.get('cd-submit-button').click();
+
+ this.navigateEdit(name);
+
+ cy.get('.collapsible').click();
+ cy.get('cd-rbd-configuration-form')
+ .get('input[name=rbd_qos_bps_limit]')
+ .should('have.value', bpsLimit);
+ }
+
+ private setApplications(apps: string[]) {
+ if (!apps || apps.length === 0) {
+ return;
+ }
+ cy.get('.float-start.me-2.select-menu-edit').click();
+ cy.get('.popover-body').should('be.visible');
+ apps.forEach((app) => cy.get('.select-menu-item-content').contains(app).click());
+ }
+}
--- /dev/null
+import { BucketsPageHelper } from './buckets.po';
+
+describe('RGW buckets page', () => {
+ const buckets = new BucketsPageHelper();
+ const bucket_name = 'e2ebucket';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ buckets.navigateTo();
+ });
+
+ describe('breadcrumb tests', () => {
+ it('should open and show breadcrumb', () => {
+ buckets.expectBreadcrumbText('Buckets');
+ });
+ });
+
+ describe('create, edit & delete bucket tests', () => {
+ it('should create bucket', () => {
+ buckets.navigateTo('create');
+ buckets.create(bucket_name, BucketsPageHelper.USERS[0], 'default-placement');
+ buckets.getFirstTableCell(bucket_name).should('exist');
+ });
+
+ it('should edit bucket', () => {
+ buckets.edit(bucket_name, BucketsPageHelper.USERS[1]);
+ buckets.getDataTables().should('contain.text', BucketsPageHelper.USERS[1]);
+ });
+
+ it('should delete bucket', () => {
+ buckets.delete(bucket_name);
+ });
+
+ it('should check default encryption is SSE-S3', () => {
+ buckets.navigateTo('create');
+ buckets.checkForDefaultEncryption();
+ });
+
+ it('should create bucket with object locking enabled', () => {
+ buckets.navigateTo('create');
+ buckets.create(bucket_name, BucketsPageHelper.USERS[0], 'default-placement', true);
+ buckets.getFirstTableCell(bucket_name).should('exist');
+ });
+
+ it('should not allow to edit versioning if object locking is enabled', () => {
+ buckets.edit(bucket_name, BucketsPageHelper.USERS[1], true);
+ buckets.getDataTables().should('contain.text', BucketsPageHelper.USERS[1]);
+
+ buckets.delete(bucket_name);
+ });
+ });
+
+ describe('Invalid Input in Create and Edit tests', () => {
+ it('should test invalid inputs in create fields', () => {
+ buckets.testInvalidCreate();
+ });
+
+ it('should test invalid input in edit owner field', () => {
+ buckets.navigateTo('create');
+ buckets.create(bucket_name, BucketsPageHelper.USERS[0], 'default-placement');
+ buckets.testInvalidEdit(bucket_name);
+ buckets.navigateTo();
+ buckets.delete(bucket_name);
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/rgw/bucket', id: 'cd-rgw-bucket-list' },
+ create: { url: '#/rgw/bucket/create', id: 'cd-rgw-bucket-form' }
+};
+
+export class BucketsPageHelper extends PageHelper {
+ static readonly USERS = ['dashboard', 'testid'];
+
+ pages = pages;
+
+ versioningStateEnabled = 'Enabled';
+ versioningStateSuspended = 'Suspended';
+
+ private selectOwner(owner: string) {
+ return this.selectOption('owner', owner);
+ }
+
+ private selectPlacementTarget(placementTarget: string) {
+ return this.selectOption('placement-target', placementTarget);
+ }
+
+ private selectLockMode(lockMode: string) {
+ return this.selectOption('lock_mode', lockMode);
+ }
+
+ @PageHelper.restrictTo(pages.create.url)
+ create(name: string, owner: string, placementTarget: string, isLocking = false) {
+ // Enter in bucket name
+ cy.get('#bid').type(name);
+
+ // Select bucket owner
+ this.selectOwner(owner);
+ cy.get('#owner').should('have.class', 'ng-valid');
+
+ // Select bucket placement target:
+ this.selectPlacementTarget(placementTarget);
+ cy.get('#placement-target').should('have.class', 'ng-valid');
+
+ if (isLocking) {
+ cy.get('#lock_enabled').click({ force: true });
+ // Select lock mode:
+ this.selectLockMode('Compliance');
+ cy.get('#lock_mode').should('have.class', 'ng-valid');
+ cy.get('#lock_retention_period_days').type('3');
+ }
+
+ // Click the create button and wait for bucket to be made
+ cy.contains('button', 'Create Bucket').click();
+
+ this.getFirstTableCell(name).should('exist');
+ }
+
+ @PageHelper.restrictTo(pages.create.url)
+ checkForDefaultEncryption() {
+ cy.get("cd-helper[aria-label='toggle encryption helper']").click();
+ cy.get("a[aria-label='click here']").click();
+ cy.get('cd-modal').within(() => {
+ cy.get('input[id=s3Enabled]').should('be.checked');
+ });
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ edit(name: string, new_owner: string, isLocking = false) {
+ this.navigateEdit(name);
+
+ cy.get('input[name=placement-target]').should('have.value', 'default-placement');
+ this.selectOwner(new_owner);
+
+ // If object locking is enabled versioning shouldn't be visible
+ if (isLocking) {
+ cy.get('input[id=versioning]').should('be.disabled');
+ cy.contains('button', 'Edit Bucket').click();
+
+ // wait to be back on buckets page with table visible and click
+ this.getExpandCollapseElement(name).click();
+
+ // check its details table for edited owner field
+ cy.get('.table.table-striped.table-bordered')
+ .first()
+ .should('contains.text', new_owner)
+ .as('bucketDataTable');
+
+ // Check versioning enabled:
+ cy.get('@bucketDataTable').find('tr').its(2).find('td').last().should('have.text', new_owner);
+ cy.get('@bucketDataTable').find('tr').its(11).find('td').last().as('versioningValueCell');
+
+ return cy.get('@versioningValueCell').should('have.text', this.versioningStateEnabled);
+ }
+ // Enable versioning
+ cy.get('input[id=versioning]').should('not.be.checked');
+ cy.get('label[for=versioning]').click();
+ cy.get('input[id=versioning]').should('be.checked');
+
+ cy.contains('button', 'Edit Bucket').click();
+
+ // wait to be back on buckets page with table visible and click
+ this.getExpandCollapseElement(name).click();
+
+ // check its details table for edited owner field
+ cy.get('.table.table-striped.table-bordered')
+ .first()
+ .should('contains.text', new_owner)
+ .as('bucketDataTable');
+
+ // Check versioning enabled:
+ cy.get('@bucketDataTable').find('tr').its(2).find('td').last().should('have.text', new_owner);
+ cy.get('@bucketDataTable').find('tr').its(11).find('td').last().as('versioningValueCell');
+
+ cy.get('@versioningValueCell').should('have.text', this.versioningStateEnabled);
+
+ // Disable versioning:
+ this.navigateEdit(name);
+
+ cy.get('label[for=versioning]').click();
+ cy.get('input[id=versioning]').should('not.be.checked');
+ cy.contains('button', 'Edit Bucket').click();
+
+ // Check versioning suspended:
+ this.getExpandCollapseElement(name).click();
+
+ return cy.get('@versioningValueCell').should('have.text', this.versioningStateSuspended);
+ }
+
+ testInvalidCreate() {
+ this.navigateTo('create');
+ cy.get('#bid').as('nameInputField'); // Grabs name box field
+
+ // Gives an invalid name (too short), then waits for dashboard to determine validity
+ cy.get('@nameInputField').type('rq');
+
+ cy.contains('button', 'Create Bucket').click(); // To trigger a validation
+
+ // Waiting for website to decide if name is valid or not
+ // Check that name input field was marked invalid in the css
+ cy.get('@nameInputField')
+ .should('not.have.class', 'ng-pending')
+ .and('have.class', 'ng-invalid');
+
+ // Check that error message was printed under name input field
+ cy.get('#bid + .invalid-feedback').should(
+ 'have.text',
+ 'Bucket names must be 3 to 63 characters long.'
+ );
+
+ // Test invalid owner input
+ // select some valid option. The owner drop down error message will not appear unless a valid user was selected at
+ // one point before the invalid placeholder user is selected.
+ this.selectOwner(BucketsPageHelper.USERS[1]);
+
+ // select the first option, which is invalid because it is a placeholder
+ this.selectOwner('-- Select a user --');
+
+ cy.get('@nameInputField').click();
+
+ // Check that owner drop down field was marked invalid in the css
+ cy.get('#owner').should('have.class', 'ng-invalid');
+
+ // Check that error message was printed under owner drop down field
+ cy.get('#owner + .invalid-feedback').should('have.text', 'This field is required.');
+
+ // Check invalid placement target input
+ this.selectOwner(BucketsPageHelper.USERS[1]);
+ // The drop down error message will not appear unless a valid option is previsously selected.
+ this.selectPlacementTarget('default-placement');
+ this.selectPlacementTarget('-- Select a placement target --');
+ cy.get('@nameInputField').click(); // Trigger validation
+ cy.get('#placement-target').should('have.class', 'ng-invalid');
+ cy.get('#placement-target + .invalid-feedback').should('have.text', 'This field is required.');
+
+ // Clicks the Create Bucket button but the page doesn't move.
+ // Done by testing for the breadcrumb
+ cy.contains('button', 'Create Bucket').click(); // Clicks Create Bucket button
+ this.expectBreadcrumbText('Create');
+ // content in fields seems to subsist through tests if not cleared, so it is cleared
+ cy.get('@nameInputField').clear();
+ return cy.contains('button', 'Cancel').click();
+ }
+
+ testInvalidEdit(name: string) {
+ this.navigateEdit(name);
+
+ cy.get('input[id=versioning]').should('exist').and('not.be.checked');
+
+ // Chooses 'Select a user' rather than a valid owner on Edit Bucket page
+ // and checks if it's an invalid input
+
+ // select the first option, which is invalid because it is a placeholder
+ this.selectOwner('-- Select a user --');
+
+ cy.contains('button', 'Edit Bucket').click();
+
+ // Check that owner drop down field was marked invalid in the css
+ cy.get('#owner').should('have.class', 'ng-invalid');
+
+ // Check that error message was printed under owner drop down field
+ cy.get('#owner + .invalid-feedback').should('have.text', 'This field is required.');
+
+ this.expectBreadcrumbText('Edit');
+ }
+}
--- /dev/null
+import { DaemonsPageHelper } from './daemons.po';
+
+describe('RGW daemons page', () => {
+ const daemons = new DaemonsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ daemons.navigateTo();
+ });
+
+ describe('breadcrumb and tab tests', () => {
+ it('should open and show breadcrumb', () => {
+ daemons.expectBreadcrumbText('Gateways');
+ });
+
+ it('should show two tabs', () => {
+ daemons.getTabsCount().should('eq', 2);
+ });
+
+ it('should show daemons list tab at first', () => {
+ daemons.getTabText(0).should('eq', 'Gateways List');
+ });
+
+ it('should show overall performance as a second tab', () => {
+ daemons.getTabText(1).should('eq', 'Overall Performance');
+ });
+ });
+
+ describe('details and performance counters table tests', () => {
+ it('should check that details/performance tables are visible when daemon is selected', () => {
+ daemons.checkTables();
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class DaemonsPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/rgw/daemon', id: 'cd-rgw-daemon-list' }
+ };
+
+ getTableCell() {
+ return cy
+ .get('.tab-content')
+ .its(1)
+ .find('cd-table')
+ .should('have.length', 1) // Only 1 table should be renderer
+ .find('datatable-body-cell');
+ }
+
+ checkTables() {
+ // click on a daemon so details table appears
+ cy.get('.datatable-body-cell-label').first().click();
+
+ // check details table is visible
+ // check at least one field is present
+ this.getTableCell().should('be.visible').should('contain.text', 'ceph_version');
+
+ // click on performance counters tab and check table is loaded
+ cy.contains('.nav-link', 'Performance Counters').click();
+
+ // check at least one field is present
+ this.getTableCell().should('be.visible').should('contain.text', 'objecter.op_r');
+
+ // click on performance details tab
+ cy.contains('.nav-link', 'Performance Details').click();
+ }
+}
--- /dev/null
+import { UsersPageHelper } from './users.po';
+
+describe('RGW users page', () => {
+ const users = new UsersPageHelper();
+ const tenant = 'e2e_000tenant';
+ const user_id = 'e2e_000user_create_edit_delete';
+ const user_name = tenant + '$' + user_id;
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ users.navigateTo();
+ });
+
+ describe('breadcrumb tests', () => {
+ it('should open and show breadcrumb', () => {
+ users.expectBreadcrumbText('Users');
+ });
+ });
+
+ describe('create, edit & delete user tests', () => {
+ it('should create user', () => {
+ users.navigateTo('create');
+ users.create(tenant, user_id, 'Some Name', 'original@website.com', '1200');
+ users.getFirstTableCell(user_id).should('exist');
+ });
+
+ it('should edit users full name, email and max buckets', () => {
+ users.edit(user_name, 'Another Identity', 'changed@othersite.com', '1969');
+ });
+
+ it('should delete user', () => {
+ users.delete(user_name);
+ });
+ });
+
+ describe('Invalid input tests', () => {
+ it('should put invalid input into user creation form and check fields are marked invalid', () => {
+ users.invalidCreate();
+ });
+
+ it('should put invalid input into user edit form and check fields are marked invalid', () => {
+ users.invalidEdit();
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+const pages = {
+ index: { url: '#/rgw/user', id: 'cd-rgw-user-list' },
+ create: { url: '#/rgw/user/create', id: 'cd-rgw-user-form' }
+};
+
+export class UsersPageHelper extends PageHelper {
+ pages = pages;
+
+ @PageHelper.restrictTo(pages.create.url)
+ create(tenant: string, user_id: string, fullname: string, email: string, maxbuckets: string) {
+ // Enter in user_id
+ cy.get('#user_id').type(user_id);
+ // Show Tenanat
+ cy.get('#show_tenant').click({ force: true });
+ // Enter in tenant
+ cy.get('#tenant').type(tenant);
+ // Enter in full name
+ cy.get('#display_name').click().type(fullname);
+
+ // Enter in email
+ cy.get('#email').click().type(email);
+
+ // Enter max buckets
+ this.selectOption('max_buckets_mode', 'Custom');
+ cy.get('#max_buckets').should('exist').should('have.value', '1000');
+ cy.get('#max_buckets').click().clear().type(maxbuckets);
+
+ // Click the create button and wait for user to be made
+ cy.contains('button', 'Create User').click();
+ this.getFirstTableCell(tenant + '$' + user_id).should('exist');
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ edit(name: string, new_fullname: string, new_email: string, new_maxbuckets: string) {
+ this.navigateEdit(name);
+
+ // Change the full name field
+ cy.get('#display_name').click().clear().type(new_fullname);
+
+ // Change the email field
+ cy.get('#email').click().clear().type(new_email);
+
+ // Change the max buckets field
+ this.selectOption('max_buckets_mode', 'Custom');
+ cy.get('#max_buckets').click().clear().type(new_maxbuckets);
+
+ cy.contains('button', 'Edit User').click();
+
+ // Click the user and check its details table for updated content
+ this.getExpandCollapseElement(name).click();
+ cy.get('.datatable-row-detail')
+ .should('contain.text', new_fullname)
+ .and('contain.text', new_email)
+ .and('contain.text', new_maxbuckets);
+ }
+
+ invalidCreate() {
+ const tenant = '000invalid_tenant';
+ const uname = '000invalid_create_user';
+ // creating this user in order to check that you can't give two users the same name
+ this.navigateTo('create');
+ this.create(tenant, uname, 'xxx', 'xxx@xxx', '1');
+
+ this.navigateTo('create');
+
+ // Username
+ cy.get('#user_id')
+ // No username had been entered. Field should be invalid
+ .should('have.class', 'ng-invalid')
+ // Try to give user already taken name. Should make field invalid.
+ .type(uname);
+ cy.get('#show_tenant').click({ force: true });
+ cy.get('#tenant').type(tenant).should('have.class', 'ng-invalid');
+ cy.contains('#tenant + .invalid-feedback', 'The chosen user ID exists in this tenant.');
+
+ // check that username field is marked invalid if username has been cleared off
+ cy.get('#user_id').clear().blur().should('have.class', 'ng-invalid');
+ cy.contains('#user_id + .invalid-feedback', 'This field is required.');
+
+ // Full name
+ cy.get('#display_name')
+ // No display name has been given so field should be invalid
+ .should('have.class', 'ng-invalid')
+ // display name field should also be marked invalid if given input then emptied
+ .type('a')
+ .clear()
+ .blur()
+ .should('have.class', 'ng-invalid');
+ cy.contains('#display_name + .invalid-feedback', 'This field is required.');
+
+ // put invalid email to make field invalid
+ cy.get('#email').type('a').blur().should('have.class', 'ng-invalid');
+ cy.contains('#email + .invalid-feedback', 'This is not a valid email address.');
+
+ // put negative max buckets to make field invalid
+ this.expectSelectOption('max_buckets_mode', 'Custom');
+ cy.get('#max_buckets').clear().type('-5').blur().should('have.class', 'ng-invalid');
+ cy.contains('#max_buckets + .invalid-feedback', 'The entered value must be >= 1.');
+
+ this.navigateTo();
+ this.delete(tenant + '$' + uname);
+ }
+
+ invalidEdit() {
+ const tenant = '000invalid_tenant';
+ const uname = '000invalid_edit_user';
+ // creating this user to edit for the test
+ this.navigateTo('create');
+ this.create(tenant, uname, 'xxx', 'xxx@xxx', '50');
+ const name = tenant + '$' + uname;
+ this.navigateEdit(name);
+
+ // put invalid email to make field invalid
+ cy.get('#email')
+ .clear()
+ .type('a')
+ .blur()
+ .should('not.have.class', 'ng-pending')
+ .should('have.class', 'ng-invalid');
+ cy.contains('#email + .invalid-feedback', 'This is not a valid email address.');
+
+ // empty the display name field making it invalid
+ cy.get('#display_name').clear().blur().should('have.class', 'ng-invalid');
+ cy.contains('#display_name + .invalid-feedback', 'This field is required.');
+
+ // put negative max buckets to make field invalid
+ this.selectOption('max_buckets_mode', 'Disabled');
+ cy.get('#max_buckets').should('not.exist');
+ this.selectOption('max_buckets_mode', 'Custom');
+ cy.get('#max_buckets').should('exist').should('have.value', '50');
+ cy.get('#max_buckets').clear().type('-5').blur().should('have.class', 'ng-invalid');
+ cy.contains('#max_buckets + .invalid-feedback', 'The entered value must be >= 1.');
+
+ this.navigateTo();
+ this.delete(tenant + '$' + uname);
+ }
+}
--- /dev/null
+import { ApiDocsPageHelper } from '../ui/api-docs.po';
+
+describe('Api Docs Page', () => {
+ const apiDocs = new ApiDocsPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ apiDocs.navigateTo();
+ });
+
+ it('should show the API Docs description', () => {
+ cy.get('.renderedMarkdown').first().contains('This is the official Ceph REST API');
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class ApiDocsPageHelper extends PageHelper {
+ pages = { index: { url: '#/api-docs', id: 'cd-api-docs' } };
+}
--- /dev/null
+import { ManagerModulesPageHelper } from '../cluster/mgr-modules.po';
+import { DashboardV3PageHelper } from './dashboard-v3.po';
+
+describe('Dashboard-v3 Main Page', () => {
+ const dashboard = new DashboardV3PageHelper();
+ const mgrmodules = new ManagerModulesPageHelper();
+
+ before(() => {
+ cy.login();
+ mgrmodules.navigateTo();
+ mgrmodules.navigateEdit('dashboard');
+ cy.get('#FEATURE_TOGGLE_DASHBOARD').check();
+ cy.contains('button', 'Update').click();
+ });
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ dashboard.navigateTo();
+ });
+
+ describe('Check that all hyperlinks on inventory card lead to the correct page and fields exist', () => {
+ it('should ensure that all linked pages in the inventory card lead to correct page', () => {
+ const expectationMap = {
+ Host: 'Hosts',
+ Monitor: 'Monitors',
+ OSDs: 'OSDs',
+ Pool: 'Pools',
+ 'Object Gateway': 'Gateways'
+ };
+
+ for (const [linkText, breadcrumbText] of Object.entries(expectationMap)) {
+ cy.location('hash').should('eq', '#/dashboard');
+ dashboard.clickInventoryCardLink(linkText);
+ dashboard.expectBreadcrumbText(breadcrumbText);
+ dashboard.navigateBack();
+ }
+ });
+
+ it('should verify that cards exist on dashboard in proper order', () => {
+ // Ensures that cards are all displayed on the dashboard tab while being in the proper
+ // order, checks for card title and position via indexing into a list of all cards.
+ const order = ['Details', 'Status', 'Capacity', 'Inventory', 'Cluster utilization'];
+
+ for (let i = 0; i < order.length; i++) {
+ dashboard.card(i).should('contain.text', order[i]);
+ }
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class DashboardV3PageHelper extends PageHelper {
+ pages = { index: { url: '#/dashboard', id: 'cd-dashboard-v3' } };
+
+ cardTitle(index: number) {
+ return cy.get('.card-title').its(index).text();
+ }
+
+ clickInventoryCardLink(link: string) {
+ console.log(link);
+ cy.get(`cd-card[cardTitle="Inventory"]`).contains('a', link).click();
+ }
+
+ card(indexOrTitle: number) {
+ cy.get('cd-card').as('cards');
+
+ return cy.get('@cards').its(indexOrTitle);
+ }
+}
--- /dev/null
+import { IscsiPageHelper } from '../block/iscsi.po';
+import { HostsPageHelper } from '../cluster/hosts.po';
+import { ManagerModulesPageHelper } from '../cluster/mgr-modules.po';
+import { MonitorsPageHelper } from '../cluster/monitors.po';
+import { OSDsPageHelper } from '../cluster/osds.po';
+import { PageHelper } from '../page-helper.po';
+import { PoolPageHelper } from '../pools/pools.po';
+import { DaemonsPageHelper } from '../rgw/daemons.po';
+import { DashboardPageHelper } from './dashboard.po';
+
+describe('Dashboard Main Page', () => {
+ const dashboard = new DashboardPageHelper();
+ const daemons = new DaemonsPageHelper();
+ const hosts = new HostsPageHelper();
+ const osds = new OSDsPageHelper();
+ const pools = new PoolPageHelper();
+ const monitors = new MonitorsPageHelper();
+ const iscsi = new IscsiPageHelper();
+ const mgrmodules = new ManagerModulesPageHelper();
+
+ before(() => {
+ cy.login();
+ mgrmodules.navigateTo();
+ mgrmodules.navigateEdit('dashboard');
+ cy.get('#FEATURE_TOGGLE_DASHBOARD').uncheck();
+ cy.contains('button', 'Update').click();
+ });
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ dashboard.navigateTo();
+ });
+
+ describe('Check that all hyperlinks on info cards lead to the correct page and fields exist', () => {
+ it('should ensure that all linked info cards lead to correct page', () => {
+ const expectationMap = {
+ Monitors: 'Monitors',
+ OSDs: 'OSDs',
+ Hosts: 'Hosts',
+ 'Object Gateways': 'Gateways',
+ 'iSCSI Gateways': 'Overview',
+ Pools: 'Pools'
+ };
+
+ for (const [linkText, breadcrumbText] of Object.entries(expectationMap)) {
+ cy.location('hash').should('eq', '#/dashboard');
+ dashboard.clickInfoCardLink(linkText);
+ dashboard.expectBreadcrumbText(breadcrumbText);
+ dashboard.navigateBack();
+ }
+ });
+
+ it('should verify that info cards exist on dashboard in proper order', () => {
+ // Ensures that info cards are all displayed on the dashboard tab while being in the proper
+ // order, checks for card title and position via indexing into a list of all info cards.
+ const order = [
+ 'Cluster Status',
+ 'Hosts',
+ 'Monitors',
+ 'OSDs',
+ 'Managers',
+ 'Object Gateways',
+ 'Metadata Servers',
+ 'iSCSI Gateways',
+ 'Raw Capacity',
+ 'Objects',
+ 'PG Status',
+ 'Pools',
+ 'PGs per OSD',
+ 'Client Read/Write',
+ 'Client Throughput',
+ 'Recovery Throughput',
+ 'Scrubbing'
+ ];
+
+ for (let i = 0; i < order.length; i++) {
+ dashboard.infoCard(i).should('contain.text', order[i]);
+ }
+ });
+
+ it('should verify that info card group titles are present and in the right order', () => {
+ cy.location('hash').should('eq', '#/dashboard');
+ dashboard.infoGroupTitle(0).should('eq', 'Status');
+ dashboard.infoGroupTitle(1).should('eq', 'Capacity');
+ dashboard.infoGroupTitle(2).should('eq', 'Performance');
+ });
+ });
+
+ it('Should check that dashboard cards have correct information', () => {
+ interface TestSpec {
+ cardName: string;
+ regexMatcher?: RegExp;
+ pageObject: PageHelper;
+ }
+ const testSpecs: TestSpec[] = [
+ { cardName: 'Object Gateways', regexMatcher: /(\d+)\s+total/, pageObject: daemons },
+ { cardName: 'Monitors', regexMatcher: /(\d+)\s+\(quorum/, pageObject: monitors },
+ { cardName: 'Hosts', regexMatcher: /(\d+)\s+total/, pageObject: hosts },
+ { cardName: 'OSDs', regexMatcher: /(\d+)\s+total/, pageObject: osds },
+ { cardName: 'Pools', pageObject: pools },
+ { cardName: 'iSCSI Gateways', regexMatcher: /(\d+)\s+total/, pageObject: iscsi }
+ ];
+ for (let i = 0; i < testSpecs.length; i++) {
+ const spec = testSpecs[i];
+ dashboard.navigateTo();
+
+ dashboard.infoCardBodyText(spec.cardName).then((infoCardBodyText: string) => {
+ let dashCount = 0;
+
+ if (spec.regexMatcher) {
+ const match = infoCardBodyText.match(new RegExp(spec.regexMatcher));
+ expect(match).to.length.gt(
+ 1,
+ `Regex ${spec.regexMatcher} did not find a match for card with name ` +
+ `${spec.cardName}`
+ );
+ dashCount = Number(match[1]);
+ } else {
+ dashCount = Number(infoCardBodyText);
+ }
+
+ spec.pageObject.navigateTo();
+ spec.pageObject.getTableCount('total').then((tableCount) => {
+ expect(tableCount).to.eq(
+ dashCount,
+ `Text of card "${spec.cardName}" and regex "${spec.regexMatcher}" resulted in ${dashCount} ` +
+ `but did not match table count ${tableCount}`
+ );
+ });
+ });
+ }
+ });
+
+ after(() => {
+ cy.login();
+ mgrmodules.navigateTo();
+ mgrmodules.navigateEdit('dashboard');
+ cy.get('#FEATURE_TOGGLE_DASHBOARD').click();
+ cy.contains('button', 'Update').click();
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class DashboardPageHelper extends PageHelper {
+ pages = { index: { url: '#/dashboard', id: 'cd-dashboard' } };
+
+ infoGroupTitle(index: number) {
+ return cy.get('.info-group-title').its(index).text();
+ }
+
+ clickInfoCardLink(cardName: string) {
+ cy.get(`cd-info-card[cardtitle="${cardName}"]`).contains('a', cardName).click();
+ }
+
+ infoCard(indexOrTitle: number | string) {
+ cy.get('cd-info-card').as('infoCards');
+
+ if (typeof indexOrTitle === 'number') {
+ return cy.get('@infoCards').its(indexOrTitle);
+ } else {
+ return cy.contains('cd-info-card a', indexOrTitle).parent().parent().parent().parent();
+ }
+ }
+
+ infoCardBodyText(infoCard: string) {
+ return this.infoCard(infoCard).find('.card-text').text();
+ }
+
+ infoCardBody(infoCard: string) {
+ return this.infoCard(infoCard).find('.card-text');
+ }
+}
--- /dev/null
+import { LanguagePageHelper } from './language.po';
+
+describe('Shared pages', () => {
+ const language = new LanguagePageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ language.navigateTo();
+ });
+
+ it('should check default language', () => {
+ language.getLanguageBtn().should('contain.text', 'English');
+ });
+
+ it('should check all available languages', () => {
+ language.getLanguageBtn().click();
+ language.getAllLanguages().should('have.length', 1).should('contain.text', 'English');
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class LanguagePageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/dashboard', id: 'cd-dashboard' }
+ };
+
+ getLanguageBtn() {
+ return cy.get('cd-language-selector a').first();
+ }
+
+ getAllLanguages() {
+ return cy.get('cd-language-selector button');
+ }
+}
--- /dev/null
+import { LoginPageHelper } from './login.po';
+
+describe('Login page', () => {
+ const login = new LoginPageHelper();
+
+ it('should login and navigate to dashboard page', () => {
+ login.navigateTo();
+ login.doLogin();
+ });
+
+ it('should logout when clicking the button', () => {
+ login.navigateTo();
+ login.doLogin();
+
+ login.doLogout();
+ });
+
+ it('should have no accessibility violations', () => {
+ login.navigateTo();
+ cy.injectAxe();
+ cy.checkA11y();
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class LoginPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/login', id: 'cd-login' },
+ dashboard: { url: '#/dashboard', id: 'cd-dashboard' }
+ };
+
+ doLogin() {
+ cy.get('[name=username]').type('admin');
+ cy.get('#password').type('admin');
+ cy.get('[type=submit]').click();
+ cy.get('cd-dashboard').should('exist');
+ }
+
+ doLogout() {
+ cy.get('cd-identity a').click();
+ cy.contains('cd-identity span', 'Sign out').click();
+ cy.get('cd-login').should('exist');
+ cy.location('hash').should('eq', '#/login');
+ }
+}
--- /dev/null
+import { NavigationPageHelper } from './navigation.po';
+
+describe('Shared pages', () => {
+ const shared = new NavigationPageHelper();
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ shared.navigateTo();
+ });
+
+ it('should display the vertical menu by default', () => {
+ shared.getVerticalMenu().should('not.have.class', 'active');
+ });
+
+ it('should hide the vertical menu', () => {
+ shared.getMenuToggler().click();
+ shared.getVerticalMenu().should('have.class', 'active');
+ });
+
+ it('should navigate to the correct page', () => {
+ shared.checkNavigations(shared.navigations);
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class NavigationPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/dashboard', id: 'cd-dashboard' }
+ };
+
+ navigations = [
+ { menu: 'NFS', component: 'cd-error' },
+ {
+ menu: 'Object Gateway',
+ submenus: [
+ { menu: 'Gateways', component: 'cd-rgw-daemon-list' },
+ { menu: 'Users', component: 'cd-rgw-user-list' },
+ { menu: 'Buckets', component: 'cd-rgw-bucket-list' }
+ ]
+ },
+ { menu: 'Dashboard', component: 'cd-dashboard' },
+ {
+ menu: 'Cluster',
+ submenus: [
+ { menu: 'Hosts', component: 'cd-hosts' },
+ { menu: 'Physical Disks', component: 'cd-error' },
+ { menu: 'Monitors', component: 'cd-monitor' },
+ { menu: 'Services', component: 'cd-error' },
+ { menu: 'OSDs', component: 'cd-osd-list' },
+ { menu: 'Configuration', component: 'cd-configuration' },
+ { menu: 'CRUSH map', component: 'cd-crushmap' },
+ { menu: 'Manager Modules', component: 'cd-mgr-module-list' },
+ { menu: 'Ceph Users', component: 'cd-crud-table' },
+ { menu: 'Logs', component: 'cd-logs' },
+ { menu: 'Alerts', component: 'cd-prometheus-tabs' }
+ ]
+ },
+ { menu: 'Pools', component: 'cd-pool-list' },
+ {
+ menu: 'Block',
+ submenus: [
+ { menu: 'Images', component: 'cd-error' },
+ { menu: 'Mirroring', component: 'cd-mirroring' },
+ { menu: 'iSCSI', component: 'cd-iscsi' }
+ ]
+ },
+ { menu: 'File Systems', component: 'cd-cephfs-list' }
+ ];
+
+ getVerticalMenu() {
+ return cy.get('nav[id=sidebar]');
+ }
+
+ getMenuToggler() {
+ return cy.get('[aria-label="toggle sidebar visibility"]');
+ }
+
+ checkNavigations(navs: any) {
+ // The nfs-ganesha, RGW, and block/rbd status requests are mocked to ensure that this method runs in time
+ cy.intercept('/ui-api/nfs-ganesha/status', { fixture: 'nfs-ganesha-status.json' });
+ cy.intercept('/ui-api/rgw/status', { fixture: 'rgw-status.json' });
+ cy.intercept('/ui-api/block/rbd/status', { fixture: 'block-rbd-status.json' });
+
+ navs.forEach((nav: any) => {
+ cy.contains('.simplebar-content li.nav-item a', nav.menu).click();
+ if (nav.submenus) {
+ this.checkNavSubMenu(nav.menu, nav.submenus);
+ } else {
+ cy.get(nav.component).should('exist');
+ }
+ });
+ }
+
+ checkNavSubMenu(menu: any, submenu: any) {
+ submenu.forEach((nav: any) => {
+ cy.contains('.simplebar-content li.nav-item', menu).within(() => {
+ cy.contains(`ul.list-unstyled li a`, nav.menu).click();
+ });
+ });
+ }
+}
--- /dev/null
+import { PoolPageHelper } from '../pools/pools.po';
+import { NotificationSidebarPageHelper } from './notification.po';
+
+describe('Notification page', () => {
+ const notification = new NotificationSidebarPageHelper();
+ const pools = new PoolPageHelper();
+ const poolName = 'e2e_notification_pool';
+
+ before(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo('create');
+ pools.create(poolName, 8);
+ pools.edit_pool_pg(poolName, 4, false);
+ });
+
+ after(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo();
+ pools.delete(poolName);
+ });
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo();
+ });
+
+ it('should open notification sidebar', () => {
+ notification.getSidebar().should('not.be.visible');
+ notification.open();
+ notification.getSidebar().should('be.visible');
+ });
+
+ it('should display a running task', () => {
+ notification.getToast().should('not.exist');
+
+ // Check that running task is shown.
+ notification.open();
+ notification.getTasks().contains(poolName).should('exist');
+
+ // Delete pool after task is complete (otherwise we get an error).
+ notification.getTasks().contains(poolName, { timeout: 300000 }).should('not.exist');
+ });
+
+ it('should have notifications', () => {
+ notification.open();
+ notification.getNotifications().should('have.length.gt', 0);
+ });
+
+ it('should clear notifications', () => {
+ notification.getToast().should('not.exist');
+ notification.open();
+ notification.getNotifications().should('have.length.gt', 0);
+ notification.getClearNotficationsBtn().should('be.visible');
+ notification.clearNotifications();
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class NotificationSidebarPageHelper extends PageHelper {
+ getNotificatinoIcon() {
+ return cy.get('cd-notifications a');
+ }
+
+ getSidebar() {
+ return cy.get('cd-notifications-sidebar');
+ }
+
+ getTasks() {
+ return this.getSidebar().find('.card.tc_task');
+ }
+
+ getNotifications() {
+ return this.getSidebar().find('.card.tc_notification');
+ }
+
+ getClearNotficationsBtn() {
+ return this.getSidebar().find('button.btn-block');
+ }
+
+ getCloseBtn() {
+ return this.getSidebar().find('button.close');
+ }
+
+ open() {
+ this.getNotificatinoIcon().click();
+ this.getSidebar().should('be.visible');
+ }
+
+ clearNotifications() {
+ // It can happen that although notifications are cleared, by the time we check the notifications
+ // amount, another notification can appear, so we check it more than once (if needed).
+ this.getClearNotficationsBtn().click();
+ this.getNotifications()
+ .should('have.length.gte', 0)
+ .then(($elems) => {
+ if ($elems.length > 0) {
+ this.clearNotifications();
+ }
+ });
+ }
+}
--- /dev/null
+import { RoleMgmtPageHelper } from './role-mgmt.po';
+
+describe('Role Management page', () => {
+ const roleMgmt = new RoleMgmtPageHelper();
+ const role_name = 'e2e_role_mgmt_role';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ roleMgmt.navigateTo();
+ });
+
+ describe('breadcrumb tests', () => {
+ it('should check breadcrumb on roles tab on user management page', () => {
+ roleMgmt.expectBreadcrumbText('Roles');
+ });
+
+ it('should check breadcrumb on role creation page', () => {
+ roleMgmt.navigateTo('create');
+ roleMgmt.expectBreadcrumbText('Create');
+ });
+ });
+
+ describe('role create, edit & delete test', () => {
+ it('should create a role', () => {
+ roleMgmt.create(role_name, 'An interesting description');
+ });
+
+ it('should edit a role', () => {
+ roleMgmt.edit(role_name, 'A far more interesting description');
+ });
+
+ it('should delete a role', () => {
+ roleMgmt.delete(role_name);
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class RoleMgmtPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/user-management/roles', id: 'cd-role-list' },
+ create: { url: '#/user-management/roles/create', id: 'cd-role-form' }
+ };
+
+ create(name: string, description: string) {
+ this.navigateTo('create');
+ // Waits for data to load
+ cy.contains('grafana');
+
+ // fill in fields
+ cy.get('#name').type(name);
+ cy.get('#description').type(description);
+
+ // Click the create button and wait for role to be made
+ cy.get('[data-cy=submitBtn]').click();
+ cy.get('.breadcrumb-item.active').should('not.have.text', 'Create');
+
+ this.getFirstTableCell(name).should('exist');
+ }
+
+ edit(name: string, description: string) {
+ this.navigateEdit(name);
+ // Waits for data to load
+ cy.contains('grafana');
+
+ // fill in fields with new values
+ cy.get('#description').clear().type(description);
+
+ // Click the edit button and check new values are present in table
+ cy.get('[data-cy=submitBtn]').click();
+ cy.get('.breadcrumb-item.active').should('not.have.text', 'Edit');
+
+ this.getFirstTableCell(name).should('exist');
+ this.getFirstTableCell(description).should('exist');
+ }
+}
--- /dev/null
+import { UserMgmtPageHelper } from './user-mgmt.po';
+
+describe('User Management page', () => {
+ const userMgmt = new UserMgmtPageHelper();
+ const user_name = 'e2e_user_mgmt_user';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ userMgmt.navigateTo();
+ });
+
+ describe('breadcrumb tests', () => {
+ it('should check breadcrumb on users tab of user management page', () => {
+ userMgmt.expectBreadcrumbText('Users');
+ });
+
+ it('should check breadcrumb on user creation page', () => {
+ userMgmt.navigateTo('create');
+ userMgmt.expectBreadcrumbText('Create');
+ });
+ });
+
+ describe('user create, edit & delete test', () => {
+ it('should create a user', () => {
+ userMgmt.create(user_name, 'cool_password', 'Jeff', 'realemail@realwebsite.com');
+ });
+
+ it('should edit a user', () => {
+ userMgmt.edit(user_name, 'cool_password_number_2', 'Geoff', 'w@m');
+ });
+
+ it('should delete a user', () => {
+ userMgmt.delete(user_name);
+ });
+ });
+});
--- /dev/null
+import { PageHelper } from '../page-helper.po';
+
+export class UserMgmtPageHelper extends PageHelper {
+ pages = {
+ index: { url: '#/user-management/users', id: 'cd-user-list' },
+ create: { url: '#/user-management/users/create', id: 'cd-user-form' }
+ };
+
+ create(username: string, password: string, name: string, email: string) {
+ this.navigateTo('create');
+
+ // fill in fields
+ cy.get('#username').type(username);
+ cy.get('#password').type(password);
+ cy.get('#confirmpassword').type(password);
+ cy.get('#name').type(name);
+ cy.get('#email').type(email);
+
+ // Click the create button and wait for user to be made
+ cy.get('[data-cy=submitBtn]').click();
+ this.getFirstTableCell(username).should('exist');
+ }
+
+ edit(username: string, password: string, name: string, email: string) {
+ this.navigateEdit(username);
+
+ // fill in fields with new values
+ cy.get('#password').clear().type(password);
+ cy.get('#confirmpassword').clear().type(password);
+ cy.get('#name').clear().type(name);
+ cy.get('#email').clear().type(email);
+
+ // Click the edit button and check new values are present in table
+ const editButton = cy.get('[data-cy=submitBtn]');
+ editButton.click();
+ this.getFirstTableCell(email).should('exist');
+ this.getFirstTableCell(name).should('exist');
+ }
+}
--- /dev/null
+import { LoginPageHelper } from '../ui/login.po';
+
+describe('Dashboard Landing Page', () => {
+ const login = new LoginPageHelper();
+
+ beforeEach(() => {
+ cy.eyesOpen({
+ testName: 'Dashboard Component'
+ });
+ });
+
+ afterEach(() => {
+ cy.eyesClose();
+ });
+
+ it('should take screenshot of dashboard landing page', () => {
+ login.navigateTo();
+ login.doLogin();
+ cy.get('[aria-label="Status card"]').should('be.visible');
+ cy.get('[aria-label="Inventory card"]').should('be.visible');
+ cy.get('[aria-label="Cluster utilization card"]').should('be.visible');
+ cy.eyesCheckWindow({ tag: 'Dashboard landing page' });
+ });
+});
--- /dev/null
+describe('Login Page', () => {
+ beforeEach(() => {
+ cy.visit('#/login');
+ cy.eyesOpen({
+ appName: 'Ceph',
+ testName: 'Login Component Check'
+ });
+ });
+
+ afterEach(() => {
+ cy.eyesClose();
+ });
+
+ it('types login credentials and takes screenshot', () => {
+ cy.get('[name=username]').type('admin');
+ cy.get('#password').type('admin');
+ cy.eyesCheckWindow({ tag: 'Login Screen with credentials typed' });
+ });
+});
+++ /dev/null
-import { DashboardPageHelper } from '../ui/dashboard.po';
-
-describe('Dashboard Main Page', { retries: 0 }, () => {
- const dashboard = new DashboardPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- dashboard.navigateTo();
- });
-
- describe('Dashboard accessibility', () => {
- it('should have no accessibility violations', () => {
- cy.injectAxe();
- cy.checkAccessibility(
- {
- exclude: [['.cd-navbar-main']]
- },
- {
- rules: {
- 'page-has-heading-one': { enabled: false }
- }
- }
- );
- });
- });
-});
+++ /dev/null
-import { NavigationPageHelper } from '../ui/navigation.po';
-
-describe('Navigation accessibility', { retries: 0 }, () => {
- const shared = new NavigationPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- shared.navigateTo();
- });
-
- it('top-nav should have no accessibility violations', () => {
- cy.injectAxe();
- cy.checkAccessibility('.cd-navbar-top');
- });
-
- it('sidebar should have no accessibility violations', () => {
- cy.injectAxe();
- cy.checkAccessibility('nav[id=sidebar]');
- });
-});
+++ /dev/null
-import { PoolPageHelper } from '../pools/pools.po';
-import { ImagesPageHelper } from './images.po';
-
-describe('Images page', () => {
- const pools = new PoolPageHelper();
- const images = new ImagesPageHelper();
-
- const poolName = 'e2e_images_pool';
-
- before(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- // Need pool for image testing
- pools.navigateTo('create');
- pools.create(poolName, 8, 'rbd');
- pools.existTableCell(poolName);
- });
-
- after(() => {
- // Deletes images test pool
- pools.navigateTo();
- pools.delete(poolName);
- pools.navigateTo();
- pools.existTableCell(poolName, false);
- });
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- images.navigateTo();
- });
-
- it('should open and show breadcrumb', () => {
- images.expectBreadcrumbText('Images');
- });
-
- it('should show four tabs', () => {
- images.getTabsCount().should('eq', 4);
- });
-
- it('should show text for all tabs', () => {
- images.getTabText(0).should('eq', 'Images');
- images.getTabText(1).should('eq', 'Namespaces');
- images.getTabText(2).should('eq', 'Trash');
- images.getTabText(3).should('eq', 'Overall Performance');
- });
-
- describe('create, edit & delete image test', () => {
- const imageName = 'e2e_images#image';
- const newImageName = 'e2e_images#image_new';
-
- it('should create image', () => {
- images.createImage(imageName, poolName, '1');
- images.getFirstTableCell(imageName).should('exist');
- });
-
- it('should edit image', () => {
- images.editImage(imageName, poolName, newImageName, '2');
- images.getFirstTableCell(newImageName).should('exist');
- });
-
- it('should delete image', () => {
- images.delete(newImageName);
- });
- });
-
- describe('move to trash, restore and purge image tests', () => {
- const imageName = 'e2e_trash#image';
- const newImageName = 'e2e_newtrash#image';
-
- before(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- // Need image for trash testing
- images.createImage(imageName, poolName, '1');
- images.getFirstTableCell(imageName).should('exist');
- });
-
- it('should move the image to the trash', () => {
- images.moveToTrash(imageName);
- images.getFirstTableCell(imageName).should('exist');
- });
-
- it('should restore image to images table', () => {
- images.restoreImage(imageName, newImageName);
- images.getFirstTableCell(newImageName).should('exist');
- });
-
- it('should purge trash in images trash tab', () => {
- images.getFirstTableCell(newImageName).should('exist');
- images.moveToTrash(newImageName);
- images.purgeTrash(newImageName, poolName);
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class ImagesPageHelper extends PageHelper {
- pages = {
- index: { url: '#/block/rbd', id: 'cd-rbd-list' },
- create: { url: '#/block/rbd/create', id: 'cd-rbd-form' }
- };
-
- // Creates a block image and fills in the name, pool, and size fields.
- // Then checks if the image is present in the Images table.
- createImage(name: string, pool: string, size: string) {
- this.navigateTo('create');
-
- cy.get('#name').type(name); // Enter in image name
-
- // Select image pool
- cy.contains('Loading...').should('not.exist');
- this.selectOption('pool', pool);
- cy.get('#pool').should('have.class', 'ng-valid'); // check if selected
-
- // Enter in the size of the image
- cy.get('#size').type(size);
-
- // Click the create button and wait for image to be made
- cy.get('[data-cy=submitBtn]').click();
- this.getFirstTableCell(name).should('exist');
- }
-
- editImage(name: string, pool: string, newName: string, newSize: string) {
- this.navigateEdit(name);
-
- // Wait until data is loaded
- cy.get('#pool').should('contain.value', pool);
-
- cy.get('#name').clear().type(newName);
- cy.get('#size').clear().type(newSize); // click the size box and send new size
-
- cy.get('[data-cy=submitBtn]').click();
-
- this.getExpandCollapseElement(newName).click();
- cy.get('.table.table-striped.table-bordered').contains('td', newSize);
- }
-
- // Selects RBD image and moves it to the trash,
- // checks that it is present in the trash table
- moveToTrash(name: string) {
- // wait for image to be created
- cy.get('.datatable-body').first().should('not.contain.text', '(Creating...)');
-
- this.getFirstTableCell(name).click();
-
- // click on the drop down and selects the move to trash option
- cy.get('.table-actions button.dropdown-toggle').first().click();
- cy.get('button.move-to-trash').click();
-
- cy.get('[data-cy=submitBtn]').should('be.visible').click();
-
- // Clicks trash tab
- cy.contains('.nav-link', 'Trash').click();
- this.getFirstTableCell(name).should('exist');
- }
-
- // Checks trash tab table for image and then restores it to the RBD Images table
- // (could change name if new name is given)
- restoreImage(name: string, newName?: string) {
- // clicks on trash tab
- cy.contains('.nav-link', 'Trash').click();
-
- // wait for table to load
- this.getFirstTableCell(name).click();
- cy.contains('button', 'Restore').click();
-
- // wait for pop-up to be visible (checks for title of pop-up)
- cy.get('cd-modal #name').should('be.visible');
-
- // If a new name for the image is passed, it changes the name of the image
- if (newName !== undefined) {
- // click name box and send new name
- cy.get('cd-modal #name').clear().type(newName);
- }
-
- cy.get('[data-cy=submitBtn]').click();
-
- // clicks images tab
- cy.contains('.nav-link', 'Images').click();
-
- this.getFirstTableCell(newName).should('exist');
- }
-
- // Enters trash tab and purges trash, thus emptying the trash table.
- // Checks if Image is still in the table.
- purgeTrash(name: string, pool?: string) {
- // clicks trash tab
- cy.contains('.nav-link', 'Trash').click();
- cy.contains('button', 'Purge Trash').click();
-
- // Check for visibility of modal container
- cy.get('.modal-header').should('be.visible');
-
- // If purgeing a specific pool, selects that pool if given
- if (pool !== undefined) {
- this.selectOption('poolName', pool);
- cy.get('#poolName').should('have.class', 'ng-valid'); // check if pool is selected
- }
- cy.get('[data-cy=submitBtn]').click();
- // Wait for image to delete and check it is not present
-
- this.getFirstTableCell(name).should('not.exist');
- }
-}
+++ /dev/null
-import { IscsiPageHelper } from './iscsi.po';
-
-describe('Iscsi Page', () => {
- const iscsi = new IscsiPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- iscsi.navigateTo();
- });
-
- it('should open and show breadcrumb', () => {
- iscsi.expectBreadcrumbText('Overview');
- });
-
- it('should check that tables are displayed and legends are correct', () => {
- // Check tables are displayed
- iscsi.getDataTables().its(0).should('be.visible');
- iscsi.getDataTables().its(1).should('be.visible');
-
- // Check that legends are correct
- iscsi.getLegends().its(0).should('contain.text', 'Gateways');
- iscsi.getLegends().its(1).should('contain.text', 'Images');
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class IscsiPageHelper extends PageHelper {
- pages = {
- index: { url: '#/block/iscsi/overview', id: 'cd-iscsi' }
- };
-}
+++ /dev/null
-import { PoolPageHelper } from '../pools/pools.po';
-import { MirroringPageHelper } from './mirroring.po';
-
-describe('Mirroring page', () => {
- const pools = new PoolPageHelper();
- const mirroring = new MirroringPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- mirroring.navigateTo();
- });
-
- it('should open and show breadcrumb', () => {
- mirroring.expectBreadcrumbText('Mirroring');
- });
-
- it('should show three tabs', () => {
- mirroring.getTabsCount().should('eq', 3);
- });
-
- it('should show text for all tabs', () => {
- mirroring.getTabText(0).should('eq', 'Issues (0)');
- mirroring.getTabText(1).should('eq', 'Syncing (0)');
- mirroring.getTabText(2).should('eq', 'Ready (0)');
- });
-
- describe('rbd mirroring bootstrap', () => {
- const poolName = 'rbd-mirror';
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- pools.navigateTo('create');
- pools.create(poolName, 8, 'rbd');
- pools.navigateTo();
- pools.existTableCell(poolName, true);
- mirroring.navigateTo();
- });
-
- it('should generate and import the bootstrap token between clusters', () => {
- const url: string = Cypress.env('CEPH2_URL');
- mirroring.navigateTo();
- mirroring.generateToken(poolName);
- cy.get('@token').then((bootstrapToken) => {
- // pass the token to the origin as an arg
- const args = { name: poolName, token: String(bootstrapToken) };
-
- // login to the second ceph cluster
- cy.ceph2Login();
-
- // can't use any imports or functions inside the origin
- // so writing the code to copy the token inside the origin manually
- // rather than using a function call
- // @ts-ignore
- cy.origin(url, { args }, ({ name, token }: any) => {
- // Create an rbd pool in the second cluster
- cy.visit('#/pool/create').wait(100);
- cy.get('input[name=name]').clear().type(name);
- cy.get(`select[name=poolType]`).select('replicated');
- cy.get(`select[name=poolType] option:checked`).contains('replicated');
- cy.get('.float-start.me-2.select-menu-edit').click();
- cy.get('.popover-body').should('be.visible');
- // Choose rbd as the application label
- cy.get('.select-menu-item-content').contains('rbd').click();
- cy.get('cd-submit-button').click();
- cy.get('cd-pool-list').should('exist');
-
- cy.visit('#/block/mirroring').wait(1000);
- cy.get('.table-actions button.dropdown-toggle').first().click();
- cy.get('[aria-label="Import Bootstrap Token"]').click();
- cy.get('cd-bootstrap-import-modal').within(() => {
- cy.get(`label[for=${name}]`).click();
- cy.get('textarea[id=token]').wait(100).type(token);
- cy.get('button[type=submit]').click();
- });
- });
- });
-
- // login again since origin removes all the cookies
- // sessions, localStorage items etc..
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- mirroring.navigateTo();
- mirroring.checkPoolHealthStatus(poolName, 'OK');
- });
- });
-
- describe('checks that edit mode functionality shows in the pools table', () => {
- const poolName = 'mirroring_test';
-
- beforeEach(() => {
- pools.navigateTo('create'); // Need pool for mirroring testing
- pools.create(poolName, 8, 'rbd');
- pools.navigateTo();
- pools.existTableCell(poolName, true);
- });
-
- it('tests editing mode for pools', () => {
- mirroring.navigateTo();
-
- mirroring.editMirror(poolName, 'Pool');
- mirroring.getFirstTableCell('pool').should('be.visible');
- mirroring.editMirror(poolName, 'Image');
- mirroring.getFirstTableCell('image').should('be.visible');
- mirroring.editMirror(poolName, 'Disabled');
- mirroring.getFirstTableCell('disabled').should('be.visible');
- });
-
- afterEach(() => {
- pools.navigateTo();
- pools.delete(poolName);
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-const pages = {
- index: { url: '#/block/mirroring', id: 'cd-mirroring' }
-};
-
-export class MirroringPageHelper extends PageHelper {
- pages = pages;
-
- poolsColumnIndex = {
- name: 1,
- health: 6
- };
-
- /**
- * Goes to the mirroring page and edits a pool in the Pool table. Clicks on the
- * pool and chooses an option (either pool, image, or disabled)
- */
- @PageHelper.restrictTo(pages.index.url)
- editMirror(name: string, option: string) {
- // Clicks the pool in the table
- this.getFirstTableCell(name).click();
-
- // Clicks the Edit Mode button
- cy.contains('button', 'Edit Mode').click();
-
- // Clicks the drop down in the edit pop-up, then clicks the Update button
- cy.get('.modal-content').should('be.visible');
- this.selectOption('mirrorMode', option);
-
- // Clicks update button and checks if the mode has been changed
- cy.contains('button', 'Update').click();
- cy.contains('.modal-dialog', 'Edit pool mirror mode').should('not.exist');
- const val = option.toLowerCase(); // used since entries in table are lower case
- this.getFirstTableCell(val).should('be.visible');
- }
-
- @PageHelper.restrictTo(pages.index.url)
- generateToken(poolName: string) {
- cy.get('[aria-label="Create Bootstrap Token"]').first().click();
- cy.get('cd-bootstrap-create-modal').within(() => {
- cy.get(`label[for=${poolName}]`).click();
- cy.get('button[type=submit]').click();
- cy.get('textarea[id=token]').wait(200).invoke('val').as('token');
- cy.get('[aria-label="Back"]').click();
- });
- }
-
- @PageHelper.restrictTo(pages.index.url)
- checkPoolHealthStatus(poolName: string, status: string) {
- cy.get('cd-mirroring-pools').within(() => {
- this.getTableCell(this.poolsColumnIndex.name, poolName)
- .parent()
- .find(`datatable-body-cell:nth-child(${this.poolsColumnIndex.health}) .badge`)
- .should(($ele) => {
- const newLabels = $ele.toArray().map((v) => v.innerText);
- expect(newLabels).to.include(status);
- });
- });
- }
-}
+++ /dev/null
-import { ConfigurationPageHelper } from './configuration.po';
-
-describe('Configuration page', () => {
- const configuration = new ConfigurationPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- configuration.navigateTo();
- });
-
- describe('breadcrumb test', () => {
- it('should open and show breadcrumb', () => {
- configuration.expectBreadcrumbText('Configuration');
- });
- });
-
- describe('fields check', () => {
- beforeEach(() => {
- configuration.getExpandCollapseElement().click();
- });
-
- it('should check that details table opens (w/o tab header)', () => {
- configuration.getStatusTables().should('be.visible');
- configuration.getTabs().should('not.exist');
- });
- });
-
- describe('edit configuration test', () => {
- const configName = 'client_cache_size';
-
- beforeEach(() => {
- configuration.clearTableSearchInput();
- configuration.getTableCount('found').as('configFound');
- });
-
- after(() => {
- configuration.configClear(configName);
- });
-
- it('should click and edit a configuration and results should appear in the table', () => {
- configuration.edit(
- configName,
- ['global', '1'],
- ['mon', '2'],
- ['mgr', '3'],
- ['osd', '4'],
- ['mds', '5'],
- ['client', '6']
- );
- });
-
- it('should verify modified filter is applied properly', () => {
- configuration.filterTable('Modified', 'no');
- configuration.getTableCount('found').as('unmodifiedConfigs');
-
- // Modified filter value to yes
- configuration.filterTable('Modified', 'yes');
- configuration.getTableCount('found').as('modifiedConfigs');
-
- cy.get('@configFound').then((configFound) => {
- cy.get('@unmodifiedConfigs').then((unmodifiedConfigs) => {
- const modifiedConfigs = Number(configFound) - Number(unmodifiedConfigs);
- configuration.getTableCount('found').should('eq', modifiedConfigs);
- });
- });
-
- // Modified filter value to no
- configuration.filterTable('Modified', 'no');
- cy.get('@configFound').then((configFound) => {
- cy.get('@modifiedConfigs').then((modifiedConfigs) => {
- const unmodifiedConfigs = Number(configFound) - Number(modifiedConfigs);
- configuration.getTableCount('found').should('eq', unmodifiedConfigs);
- });
- });
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class ConfigurationPageHelper extends PageHelper {
- pages = {
- index: { url: '#/configuration', id: 'cd-configuration' }
- };
-
- /**
- * Clears out all the values in a config to reset before and after testing
- * Does not work for configs with checkbox only, possible future PR
- */
- configClear(name: string) {
- const valList = ['global', 'mon', 'mgr', 'osd', 'mds', 'client']; // Editable values
-
- this.navigateEdit(name);
- // Waits for the data to load
- cy.contains('.card-header', `Edit ${name}`);
-
- for (const i of valList) {
- cy.get(`#${i}`).clear();
- }
- // Clicks save button and checks that values are not present for the selected config
- cy.get('[data-cy=submitBtn]').click();
-
- // Enter config setting name into filter box
- this.searchTable(name);
-
- // Expand row
- this.getExpandCollapseElement(name).click();
-
- // Checks for visibility of details tab
- this.getStatusTables().should('be.visible');
-
- for (const i of valList) {
- // Waits until values are not present in the details table
- this.getStatusTables().should('not.contain.text', i + ':');
- }
- }
-
- /**
- * Clicks the designated config, then inputs the values passed into the edit function.
- * Then checks if the edit is reflected in the config table.
- * Takes in name of config and a list of tuples of values the user wants edited,
- * each tuple having the desired value along with the number tehey want for that value.
- * Ex: [global, '2'] is the global value with an input of 2
- */
- edit(name: string, ...values: [string, string][]) {
- this.navigateEdit(name);
-
- // Waits for data to load
- cy.contains('.card-header', `Edit ${name}`);
-
- values.forEach((valtuple) => {
- // Finds desired value based off given list
- cy.get(`#${valtuple[0]}`).type(valtuple[1]); // of values and inserts the given number for the value
- });
-
- // Clicks save button then waits until the desired config is visible, clicks it,
- // then checks that each desired value appears with the desired number
- cy.get('[data-cy=submitBtn]').click();
-
- // Enter config setting name into filter box
- this.searchTable(name);
-
- // Checks for visibility of config in table
- this.getExpandCollapseElement(name).should('be.visible').click();
-
- // Clicks config
- values.forEach((value) => {
- // iterates through list of values and
- // checks if the value appears in details with the correct number attatched
- cy.contains('.table.table-striped.table-bordered', `${value[0]}\: ${value[1]}`);
- });
- }
-}
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-import { NotificationSidebarPageHelper } from '../ui/notification.po';
-import { HostsPageHelper } from './hosts.po';
-import { ServicesPageHelper } from './services.po';
-
-const pages = {
- index: { url: '#/expand-cluster', id: 'cd-create-cluster' }
-};
-export class CreateClusterWizardHelper extends PageHelper {
- pages = pages;
-
- createCluster() {
- cy.get('cd-create-cluster').should('contain.text', 'Please expand your cluster first');
- cy.get('[name=expand-cluster]').click();
- cy.get('cd-wizard').should('exist');
- }
-
- doSkip() {
- cy.get('[name=skip-cluster-creation]').click();
- cy.contains('cd-modal button', 'Continue').click();
-
- cy.get('cd-dashboard').should('exist');
- const notification = new NotificationSidebarPageHelper();
- notification.open();
- notification.getNotifications().should('contain', 'Cluster expansion skipped by user');
- }
-}
-
-export class CreateClusterHostPageHelper extends HostsPageHelper {
- pages = {
- index: { url: '#/expand-cluster', id: 'cd-wizard' },
- add: { url: '', id: 'cd-host-form' }
- };
-
- columnIndex = {
- hostname: 1,
- labels: 2,
- status: 3,
- services: 0
- };
-}
-
-export class CreateClusterServicePageHelper extends ServicesPageHelper {
- pages = {
- index: { url: '#/expand-cluster', id: 'cd-wizard' },
- create: { url: '', id: 'cd-service-form' }
- };
-
- columnIndex = {
- service_name: 1,
- placement: 2,
- running: 0,
- size: 0,
- last_refresh: 0
- };
-}
+++ /dev/null
-import { CrushMapPageHelper } from './crush-map.po';
-
-describe('CRUSH map page', () => {
- const crushmap = new CrushMapPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- crushmap.navigateTo();
- });
-
- describe('breadcrumb test', () => {
- it('should open and show breadcrumb', () => {
- crushmap.expectBreadcrumbText('CRUSH map');
- });
- });
-
- describe('fields check', () => {
- it('should check that title & table appears', () => {
- // Check that title (CRUSH map viewer) appears
- crushmap.getPageTitle().should('equal', 'CRUSH map viewer');
-
- // Check that title appears once OSD is clicked
- crushmap.getCrushNode(0).click();
-
- crushmap
- .getLegends()
- .invoke('text')
- .then((legend) => {
- crushmap.getCrushNode(0).should('have.text', legend);
- });
-
- // Check that table appears once OSD is clicked
- crushmap.getDataTables().should('be.visible');
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class CrushMapPageHelper extends PageHelper {
- pages = { index: { url: '#/crush-map', id: 'cd-crushmap' } };
-
- getPageTitle() {
- return cy.get('cd-crushmap .card-header').text();
- }
-
- getCrushNode(idx: number) {
- return cy.get('.node-name.type-osd').eq(idx);
- }
-}
+++ /dev/null
-import { HostsPageHelper } from './hosts.po';
-
-describe('Hosts page', () => {
- const hosts = new HostsPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- hosts.navigateTo();
- });
-
- describe('breadcrumb and tab tests', () => {
- it('should open and show breadcrumb', () => {
- hosts.expectBreadcrumbText('Hosts');
- });
-
- it('should show two tabs', () => {
- hosts.getTabsCount().should('eq', 2);
- });
-
- it('should show hosts list tab at first', () => {
- hosts.getTabText(0).should('eq', 'Hosts List');
- });
-
- it('should show overall performance as a second tab', () => {
- hosts.getTabText(1).should('eq', 'Overall Performance');
- });
- });
-
- describe('services link test', () => {
- it('should check at least one host is present', () => {
- hosts.check_for_host();
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-const pages = {
- index: { url: '#/hosts', id: 'cd-hosts' },
- add: { url: '#/hosts/(modal:add)', id: 'cd-host-form' }
-};
-
-export class HostsPageHelper extends PageHelper {
- pages = pages;
-
- columnIndex = {
- hostname: 2,
- services: 3,
- labels: 4,
- status: 5
- };
-
- check_for_host() {
- this.getTableCount('total').should('not.be.eq', 0);
- }
-
- add(hostname: string, exist?: boolean, maintenance?: boolean, labels: string[] = []) {
- cy.get(`${this.pages.add.id}`).within(() => {
- cy.get('#hostname').type(hostname);
- if (maintenance) {
- cy.get('label[for=maintenance]').click();
- }
- if (exist) {
- cy.get('#hostname').should('have.class', 'ng-invalid');
- }
- });
-
- if (labels.length) {
- this.selectPredefinedLabels(labels);
- }
-
- cy.get('cd-submit-button').click();
- // back to host list
- cy.get(`${this.pages.index.id}`);
- }
-
- selectPredefinedLabels(labels: string[]) {
- cy.get('a[data-testid=select-menu-edit]').click();
- for (const label of labels) {
- cy.get('.popover-body div.select-menu-item-content').contains(label).click();
- }
- }
-
- checkExist(hostname: string, exist: boolean) {
- this.getTableCell(this.columnIndex.hostname, hostname).should(($elements) => {
- const hosts = $elements.map((_, el) => el.textContent).get();
- if (exist) {
- expect(hosts).to.include(hostname);
- } else {
- expect(hosts).to.not.include(hostname);
- }
- });
- }
-
- remove(hostname: string) {
- super.delete(hostname, this.columnIndex.hostname, 'hosts');
- }
-
- // Add or remove labels on a host, then verify labels in the table
- editLabels(hostname: string, labels: string[], add: boolean) {
- this.getTableCell(this.columnIndex.hostname, hostname).click();
- this.clickActionButton('edit');
-
- // add or remove label badges
- if (add) {
- cy.get('cd-modal').find('.select-menu-edit').click();
- for (const label of labels) {
- cy.contains('cd-modal .badge', new RegExp(`^${label}$`)).should('not.exist');
- cy.get('.popover-body input').type(`${label}{enter}`);
- }
- } else {
- for (const label of labels) {
- cy.contains('cd-modal .badge', new RegExp(`^${label}$`))
- .find('.badge-remove')
- .click();
- }
- }
- cy.get('cd-modal cd-submit-button').click();
- this.checkLabelExists(hostname, labels, add);
- }
-
- checkLabelExists(hostname: string, labels: string[], add: boolean) {
- // Verify labels are added or removed from Labels column
- // First find row with hostname, then find labels in the row
- this.getTableCell(this.columnIndex.hostname, hostname)
- .click()
- .parent()
- .find(`datatable-body-cell:nth-child(${this.columnIndex.labels}) .badge`)
- .should(($ele) => {
- const newLabels = $ele.toArray().map((v) => v.innerText);
- for (const label of labels) {
- if (add) {
- expect(newLabels).to.include(label);
- } else {
- expect(newLabels).to.not.include(label);
- }
- }
- });
- }
-
- @PageHelper.restrictTo(pages.index.url)
- maintenance(hostname: string, exit = false, force = false) {
- this.clearTableSearchInput();
- if (force) {
- this.getTableCell(this.columnIndex.hostname, hostname).click();
- this.clickActionButton('enter-maintenance');
-
- cy.get('cd-modal').within(() => {
- cy.contains('button', 'Continue').click();
- });
-
- this.getTableCell(this.columnIndex.hostname, hostname)
- .parent()
- .find(`datatable-body-cell:nth-child(${this.columnIndex.status}) .badge`)
- .should(($ele) => {
- const status = $ele.toArray().map((v) => v.innerText);
- expect(status).to.include('maintenance');
- });
- }
- if (exit) {
- this.getTableCell(this.columnIndex.hostname, hostname)
- .click()
- .parent()
- .find(`datatable-body-cell:nth-child(${this.columnIndex.status})`)
- .then(($ele) => {
- const status = $ele.toArray().map((v) => v.innerText);
- if (status[0].includes('maintenance')) {
- this.clickActionButton('exit-maintenance');
- }
- });
-
- this.getTableCell(this.columnIndex.hostname, hostname)
- .parent()
- .find(`datatable-body-cell:nth-child(${this.columnIndex.status})`)
- .should(($ele) => {
- const status = $ele.toArray().map((v) => v.innerText);
- expect(status).to.not.include('maintenance');
- });
- } else {
- this.getTableCell(this.columnIndex.hostname, hostname).click();
- this.clickActionButton('enter-maintenance');
-
- this.getTableCell(this.columnIndex.hostname, hostname)
- .parent()
- .find(`datatable-body-cell:nth-child(${this.columnIndex.status}) .badge`)
- .should(($ele) => {
- const status = $ele.toArray().map((v) => v.innerText);
- expect(status).to.include('maintenance');
- });
- }
- }
-
- @PageHelper.restrictTo(pages.index.url)
- drain(hostname: string) {
- this.getTableCell(this.columnIndex.hostname, hostname).click();
- this.clickActionButton('start-drain');
- this.checkLabelExists(hostname, ['_no_schedule'], true);
-
- this.clickTab('cd-host-details', hostname, 'Daemons');
- cy.get('cd-host-details').within(() => {
- cy.wait(20000);
- this.expectTableCount('total', 0);
- });
- }
-
- checkServiceInstancesExist(hostname: string, instances: string[]) {
- this.getTableCell(this.columnIndex.hostname, hostname)
- .parent()
- .find(`datatable-body-cell:nth-child(${this.columnIndex.services}) .badge`)
- .should(($ele) => {
- const serviceInstances = $ele.toArray().map((v) => v.innerText);
- for (const instance of instances) {
- expect(serviceInstances).to.include(instance);
- }
- });
- }
-}
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-const pages = {
- index: { url: '#/inventory', id: 'cd-inventory' }
-};
-
-export class InventoryPageHelper extends PageHelper {
- pages = pages;
-
- identify() {
- // Nothing we can do, just verify the form is there
- this.getFirstTableCell().click();
- cy.contains('cd-table-actions button', 'Identify').click();
- cy.get('cd-modal').within(() => {
- cy.get('#duration').select('15 minutes');
- cy.get('#duration').select('10 minutes');
- cy.get('cd-back-button').click();
- });
- cy.get('cd-modal').should('not.exist');
- cy.get(`${this.pages.index.id}`);
- }
-}
+++ /dev/null
-import { PoolPageHelper } from '../pools/pools.po';
-import { LogsPageHelper } from './logs.po';
-
-describe('Logs page', () => {
- const logs = new LogsPageHelper();
- const pools = new PoolPageHelper();
-
- const poolname = 'e2e_logs_test_pool';
- const today = new Date();
- let hour = today.getHours();
- if (hour > 12) {
- hour = hour - 12;
- }
- const minute = today.getMinutes();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- });
-
- describe('breadcrumb and tab tests', () => {
- beforeEach(() => {
- logs.navigateTo();
- });
-
- it('should open and show breadcrumb', () => {
- logs.expectBreadcrumbText('Logs');
- });
-
- it('should show three tabs', () => {
- logs.getTabsCount().should('eq', 3);
- });
-
- it('should show cluster logs tab at first', () => {
- logs.getTabText(0).should('eq', 'Cluster Logs');
- });
-
- it('should show audit logs as a second tab', () => {
- logs.getTabText(1).should('eq', 'Audit Logs');
- });
-
- it('should show daemon logs as a third tab', () => {
- logs.getTabText(2).should('eq', 'Daemon Logs');
- });
- });
-
- describe('audit logs respond to pool creation and deletion test', () => {
- it('should create pool and check audit logs reacted', () => {
- pools.navigateTo('create');
- pools.create(poolname, 8);
- pools.navigateTo();
- pools.existTableCell(poolname, true);
- logs.checkAuditForPoolFunction(poolname, 'create', hour, minute);
- });
-
- it('should delete pool and check audit logs reacted', () => {
- pools.navigateTo();
- pools.delete(poolname);
- logs.checkAuditForPoolFunction(poolname, 'delete', hour, minute);
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class LogsPageHelper extends PageHelper {
- pages = {
- index: { url: '#/logs', id: 'cd-logs' }
- };
-
- checkAuditForPoolFunction(poolname: string, poolfunction: string, hour: number, minute: number) {
- this.navigateTo();
-
- // sometimes the modal from deleting pool is still present at this point.
- // This wait makes sure it isn't
- cy.contains('.modal-dialog', 'Delete Pool').should('not.exist');
-
- // go to audit logs tab
- cy.contains('.nav-link', 'Audit Logs').click();
-
- // Enter an earliest time so that no old messages with the same pool name show up
- cy.get('.ngb-tp-input').its(0).clear();
-
- if (hour < 10) {
- cy.get('.ngb-tp-input').its(0).type('0');
- }
- cy.get('.ngb-tp-input').its(0).type(`${hour}`);
-
- cy.get('.ngb-tp-input').its(1).clear();
- if (minute < 10) {
- cy.get('.ngb-tp-input').its(1).type('0');
- }
- cy.get('.ngb-tp-input').its(1).type(`${minute}`);
-
- // Enter the pool name into the filter box
- cy.get('input.form-control.ng-valid').first().clear().type(poolname);
-
- cy.get('.tab-pane.active')
- .get('.card-body')
- .get('.message')
- .should('contain.text', poolname)
- .and('contain.text', `pool ${poolfunction}`);
- }
-
- checkAuditForConfigChange(configname: string, setting: string, hour: number, minute: number) {
- this.navigateTo();
-
- // go to audit logs tab
- cy.contains('.nav-link', 'Audit Logs').click();
-
- // Enter an earliest time so that no old messages with the same config name show up
- cy.get('.ngb-tp-input').its(0).clear();
- if (hour < 10) {
- cy.get('.ngb-tp-input').its(0).type('0');
- }
- cy.get('.ngb-tp-input').its(0).type(`${hour}`);
-
- cy.get('.ngb-tp-input').its(1).clear();
- if (minute < 10) {
- cy.get('.ngb-tp-input').its(1).type('0');
- }
- cy.get('.ngb-tp-input').its(1).type(`${minute}`);
-
- // Enter the config name into the filter box
- cy.get('input.form-control.ng-valid').first().clear().type(configname);
-
- cy.get('.tab-pane.active')
- .get('.card-body')
- .get('.message')
- .should('contain.text', configname)
- .and('contain.text', setting);
- }
-}
+++ /dev/null
-import { Input, ManagerModulesPageHelper } from './mgr-modules.po';
-
-describe('Manager modules page', () => {
- const mgrmodules = new ManagerModulesPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- mgrmodules.navigateTo();
- });
-
- describe('breadcrumb test', () => {
- it('should open and show breadcrumb', () => {
- mgrmodules.expectBreadcrumbText('Manager Modules');
- });
- });
-
- describe('verifies editing functionality for manager modules', () => {
- it('should test editing on balancer module', () => {
- const balancerArr: Input[] = [
- {
- id: 'crush_compat_max_iterations',
- newValue: '123',
- oldValue: '25'
- }
- ];
- mgrmodules.editMgrModule('balancer', balancerArr);
- });
-
- it('should test editing on dashboard module', () => {
- const dashboardArr: Input[] = [
- {
- id: 'GRAFANA_API_PASSWORD',
- newValue: 'rafa',
- oldValue: ''
- }
- ];
- mgrmodules.editMgrModule('dashboard', dashboardArr);
- });
-
- it('should test editing on devicehealth module', () => {
- const devHealthArray: Input[] = [
- {
- id: 'mark_out_threshold',
- newValue: '1987',
- oldValue: '2419200'
- },
- {
- id: 'pool_name',
- newValue: 'sox',
- oldValue: '.mgr'
- },
- {
- id: 'retention_period',
- newValue: '1999',
- oldValue: '15552000'
- },
- {
- id: 'scrape_frequency',
- newValue: '2020',
- oldValue: '86400'
- },
- {
- id: 'sleep_interval',
- newValue: '456',
- oldValue: '600'
- },
- {
- id: 'warn_threshold',
- newValue: '567',
- oldValue: '7257600'
- }
- ];
-
- mgrmodules.editMgrModule('devicehealth', devHealthArray);
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class Input {
- id: string;
- oldValue: string;
- newValue: string;
-}
-
-export class ManagerModulesPageHelper extends PageHelper {
- pages = { index: { url: '#/mgr-modules', id: 'cd-mgr-module-list' } };
-
- /**
- * Selects the Manager Module and then fills in the desired fields.
- */
- editMgrModule(name: string, inputs: Input[]) {
- this.navigateEdit(name);
-
- for (const input of inputs) {
- // Clears fields and adds edits
- cy.get(`#${input.id}`).clear().type(input.newValue);
- }
-
- cy.contains('button', 'Update').click();
- // Checks if edits appear
- this.getExpandCollapseElement(name).should('be.visible').click();
-
- for (const input of inputs) {
- cy.get('.datatable-body').last().contains(input.newValue);
- }
-
- // Clear mgr module of all edits made to it
- this.navigateEdit(name);
-
- // Clears the editable fields
- for (const input of inputs) {
- if (input.oldValue) {
- const id = `#${input.id}`;
- cy.get(id).clear();
- if (input.oldValue) {
- cy.get(id).type(input.oldValue);
- }
- }
- }
-
- // Checks that clearing represents in details tab of module
- cy.contains('button', 'Update').click();
- this.getExpandCollapseElement(name).should('be.visible').click();
- for (const input of inputs) {
- if (input.oldValue) {
- cy.get('.datatable-body')
- .eq(1)
- .should('contain', input.id)
- .and('not.contain', input.newValue);
- }
- }
- }
-}
+++ /dev/null
-import { MonitorsPageHelper } from './monitors.po';
-
-describe('Monitors page', () => {
- const monitors = new MonitorsPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- monitors.navigateTo();
- });
-
- describe('breadcrumb test', () => {
- it('should open and show breadcrumb', () => {
- monitors.expectBreadcrumbText('Monitors');
- });
- });
-
- describe('fields check', () => {
- it('should check status table is present', () => {
- // check for table header 'Status'
- monitors.getLegends().its(0).should('have.text', 'Status');
-
- // check for fields in table
- monitors
- .getStatusTables()
- .should('contain.text', 'Cluster ID')
- .and('contain.text', 'monmap modified')
- .and('contain.text', 'monmap epoch')
- .and('contain.text', 'quorum con')
- .and('contain.text', 'quorum mon')
- .and('contain.text', 'required con')
- .and('contain.text', 'required mon');
- });
-
- it('should check In Quorum and Not In Quorum tables are present', () => {
- // check for there to be two tables
- monitors.getDataTables().should('have.length', 2);
-
- // check for table header 'In Quorum'
- monitors.getLegends().its(1).should('have.text', 'In Quorum');
-
- // check for table header 'Not In Quorum'
- monitors.getLegends().its(2).should('have.text', 'Not In Quorum');
-
- // verify correct columns on In Quorum table
- monitors.getDataTableHeaders(0).contains('Name');
-
- monitors.getDataTableHeaders(0).contains('Rank');
-
- monitors.getDataTableHeaders(0).contains('Public Address');
-
- monitors.getDataTableHeaders(0).contains('Open Sessions');
-
- // verify correct columns on Not In Quorum table
- monitors.getDataTableHeaders(1).contains('Name');
-
- monitors.getDataTableHeaders(1).contains('Rank');
-
- monitors.getDataTableHeaders(1).contains('Public Address');
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class MonitorsPageHelper extends PageHelper {
- pages = {
- index: { url: '#/monitor', id: 'cd-monitor' }
- };
-}
+++ /dev/null
-import { OSDsPageHelper } from './osds.po';
-
-describe('OSDs page', () => {
- const osds = new OSDsPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- osds.navigateTo();
- });
-
- describe('breadcrumb and tab tests', () => {
- it('should open and show breadcrumb', () => {
- osds.expectBreadcrumbText('OSDs');
- });
-
- it('should show two tabs', () => {
- osds.getTabsCount().should('eq', 2);
- osds.getTabText(0).should('eq', 'OSDs List');
- osds.getTabText(1).should('eq', 'Overall Performance');
- });
- });
-
- describe('check existence of fields on OSD page', () => {
- it('should check that number of rows and count in footer match', () => {
- osds.getTableCount('total').then((text) => {
- osds.getTableRows().its('length').should('equal', text);
- });
- });
-
- it('should verify that buttons exist', () => {
- cy.contains('button', 'Create');
- cy.contains('button', 'Cluster-wide configuration');
- });
-
- describe('by selecting one row in OSDs List', () => {
- beforeEach(() => {
- osds.getExpandCollapseElement().click();
- });
-
- it('should show the correct text for the tab labels', () => {
- cy.get('#tabset-osd-details > a').then(($tabs) => {
- const tabHeadings = $tabs.map((_i, e) => e.textContent).get();
-
- expect(tabHeadings).to.eql([
- 'Devices',
- 'Attributes (OSD map)',
- 'Metadata',
- 'Device health',
- 'Performance counter',
- 'Performance Details'
- ]);
- });
- });
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-const pages = {
- index: { url: '#/osd', id: 'cd-osd-list' },
- create: { url: '#/osd/create', id: 'cd-osd-form' }
-};
-
-export class OSDsPageHelper extends PageHelper {
- pages = pages;
-
- columnIndex = {
- id: 3,
- status: 5
- };
-
- create(deviceType: 'hdd' | 'ssd', hostname?: string, expandCluster = false) {
- cy.get('[aria-label="toggle advanced mode"]').click();
- // Click Primary devices Add button
- cy.get('cd-osd-devices-selection-groups[name="Primary"]').as('primaryGroups');
- cy.get('@primaryGroups').find('button').click();
-
- // Select all devices with `deviceType`
- cy.get('cd-osd-devices-selection-modal').within(() => {
- cy.get('.modal-footer .tc_submitButton').as('addButton').should('be.disabled');
- this.filterTable('Type', deviceType);
- if (hostname) {
- this.filterTable('Hostname', hostname);
- }
-
- if (expandCluster) {
- this.getTableCount('total').should('be.gte', 1);
- }
- cy.get('@addButton').click();
- });
-
- if (!expandCluster) {
- cy.get('@primaryGroups').within(() => {
- this.getTableCount('total').as('newOSDCount');
- });
-
- cy.get(`${pages.create.id} .card-footer .tc_submitButton`).click();
- cy.get(`cd-osd-creation-preview-modal .modal-footer .tc_submitButton`).click();
- }
- }
-
- @PageHelper.restrictTo(pages.index.url)
- checkStatus(id: number, status: string[]) {
- this.searchTable(`id:${id}`);
- this.expectTableCount('found', 1);
- cy.get(`datatable-body-cell:nth-child(${this.columnIndex.status}) .badge`).should(($ele) => {
- const allStatus = $ele.toArray().map((v) => v.innerText);
- for (const s of status) {
- expect(allStatus).to.include(s);
- }
- });
- }
-
- @PageHelper.restrictTo(pages.index.url)
- ensureNoOsd(id: number) {
- this.searchTable(`id:${id}`);
- this.expectTableCount('found', 0);
- this.clearTableSearchInput();
- }
-
- @PageHelper.restrictTo(pages.index.url)
- deleteByIDs(osdIds: number[], replace?: boolean) {
- this.getTableRows().each(($el) => {
- const rowOSD = Number(
- $el.find('datatable-body-cell .datatable-body-cell-label').get(this.columnIndex.id - 1)
- .textContent
- );
- if (osdIds.includes(rowOSD)) {
- cy.wrap($el).click();
- }
- });
- this.clickActionButton('delete');
- if (replace) {
- cy.get('cd-modal label[for="preserve"]').click();
- }
- cy.get('cd-modal label[for="confirmation"]').click();
- cy.contains('cd-modal button', 'Delete').click();
- cy.get('cd-modal').should('not.exist');
- }
-}
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-const pages = {
- index: { url: '#/services', id: 'cd-services' },
- create: { url: '#/services/(modal:create)', id: 'cd-service-form' }
-};
-
-export class ServicesPageHelper extends PageHelper {
- pages = pages;
-
- columnIndex = {
- service_name: 2,
- placement: 3,
- running: 4,
- size: 5,
- last_refresh: 6
- };
-
- serviceDetailColumnIndex = {
- daemonName: 2,
- status: 4
- };
-
- check_for_service() {
- this.getTableCount('total').should('not.be.eq', 0);
- }
-
- private selectServiceType(serviceType: string) {
- return this.selectOption('service_type', serviceType);
- }
-
- clickServiceTab(serviceName: string, tabName: string) {
- this.getExpandCollapseElement(serviceName).click();
- cy.get('cd-service-details').within(() => {
- this.getTab(tabName).click();
- });
- }
-
- addService(
- serviceType: string,
- exist?: boolean,
- count = 1,
- snmpVersion?: string,
- snmpPrivProtocol?: boolean,
- unmanaged = false
- ) {
- cy.get(`${this.pages.create.id}`).within(() => {
- this.selectServiceType(serviceType);
- switch (serviceType) {
- case 'rgw':
- cy.get('#service_id').type('foo');
- unmanaged ? cy.get('label[for=unmanaged]').click() : cy.get('#count').type(String(count));
- break;
-
- case 'ingress':
- if (unmanaged) {
- cy.get('label[for=unmanaged]').click();
- }
- this.selectOption('backend_service', 'rgw.foo');
- cy.get('#service_id').should('have.value', 'rgw.foo');
- cy.get('#virtual_ip').type('192.168.100.1/24');
- cy.get('#frontend_port').type('8081');
- cy.get('#monitor_port').type('8082');
- break;
-
- case 'nfs':
- cy.get('#service_id').type('testnfs');
- unmanaged ? cy.get('label[for=unmanaged]').click() : cy.get('#count').type(String(count));
- break;
-
- case 'snmp-gateway':
- this.selectOption('snmp_version', snmpVersion);
- cy.get('#snmp_destination').type('192.168.0.1:8443');
- if (snmpVersion === 'V2c') {
- cy.get('#snmp_community').type('public');
- } else {
- cy.get('#engine_id').type('800C53F00000');
- this.selectOption('auth_protocol', 'SHA');
- if (snmpPrivProtocol) {
- this.selectOption('privacy_protocol', 'DES');
- cy.get('#snmp_v3_priv_password').type('testencrypt');
- }
-
- // Credentials
- cy.get('#snmp_v3_auth_username').type('test');
- cy.get('#snmp_v3_auth_password').type('testpass');
- }
- break;
-
- default:
- cy.get('#service_id').type('test');
- unmanaged ? cy.get('label[for=unmanaged]').click() : cy.get('#count').type(String(count));
- break;
- }
- if (serviceType === 'snmp-gateway') {
- cy.get('cd-submit-button').dblclick();
- } else {
- cy.get('cd-submit-button').click();
- }
- });
- if (exist) {
- cy.get('#service_id').should('have.class', 'ng-invalid');
- } else {
- // back to service list
- cy.get(`${this.pages.index.id}`);
- }
- }
-
- editService(name: string, daemonCount: string) {
- this.navigateEdit(name, true, false);
- cy.get(`${this.pages.create.id}`).within(() => {
- cy.get('#service_type').should('be.disabled');
- cy.get('#service_id').should('be.disabled');
- cy.get('#count').clear().type(daemonCount);
- cy.get('cd-submit-button').click();
- });
- }
-
- checkServiceStatus(daemon: string, expectedStatus = 'running') {
- let daemonNameIndex = this.serviceDetailColumnIndex.daemonName;
- let statusIndex = this.serviceDetailColumnIndex.status;
-
- // since hostname row is hidden from the hosts details table,
- // we'll need to manually override the indexes when this check is being
- // done for the daemons in host details page. So we'll get the url and
- // verify if the current page is not the services index page
- cy.url().then((url) => {
- if (!url.includes(pages.index.url)) {
- daemonNameIndex = 1;
- statusIndex = 3;
- }
-
- cy.get('cd-service-daemon-list').within(() => {
- this.getTableCell(daemonNameIndex, daemon, true)
- .parent()
- .find(`datatable-body-cell:nth-child(${statusIndex}) .badge`)
- .should(($ele) => {
- const status = $ele.toArray().map((v) => v.innerText);
- expect(status).to.include(expectedStatus);
- });
- });
- });
- }
-
- expectPlacementCount(serviceName: string, expectedCount: string) {
- this.getTableCell(this.columnIndex.service_name, serviceName)
- .parent()
- .find(`datatable-body-cell:nth-child(${this.columnIndex.placement})`)
- .should(($ele) => {
- const running = $ele.text().split(';');
- expect(running).to.include(`count:${expectedCount}`);
- });
- }
-
- checkExist(serviceName: string, exist: boolean) {
- this.getTableCell(this.columnIndex.service_name, serviceName).should(($elements) => {
- const services = $elements.map((_, el) => el.textContent).get();
- if (exist) {
- expect(services).to.include(serviceName);
- } else {
- expect(services).to.not.include(serviceName);
- }
- });
- }
-
- isUnmanaged(serviceName: string, unmanaged: boolean) {
- this.getTableCell(this.columnIndex.service_name, serviceName)
- .parent()
- .find(`datatable-body-cell:nth-child(${this.columnIndex.placement})`)
- .should(($ele) => {
- const placement = $ele.text().split(';');
- unmanaged
- ? expect(placement).to.include('unmanaged')
- : expect(placement).to.not.include('unmanaged');
- });
- }
-
- deleteService(serviceName: string) {
- const getRow = this.getTableCell.bind(this, this.columnIndex.service_name);
- getRow(serviceName).click();
-
- // Clicks on table Delete button
- this.clickActionButton('delete');
-
- // Confirms deletion
- cy.get('cd-modal .custom-control-label').click();
- cy.contains('cd-modal button', 'Delete').click();
-
- // Wait for modal to close
- cy.get('cd-modal').should('not.exist');
- this.checkExist(serviceName, false);
- }
-
- daemonAction(daemon: string, action: string) {
- cy.get('cd-service-daemon-list').within(() => {
- this.getTableRow(daemon).click();
- this.clickActionButton(action);
- });
- }
-}
+++ /dev/null
-import { UsersPageHelper } from './users.po';
-
-describe('Cluster Ceph Users', () => {
- const users = new UsersPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- users.navigateTo();
- });
-
- describe('breadcrumb and tab tests', () => {
- it('should open and show breadcrumb', () => {
- users.expectBreadcrumbText('Ceph Users');
- });
- });
-
- describe('Cluster users table', () => {
- it('should verify the table is not empty', () => {
- users.checkForUsers();
- });
-
- it('should verify the keys are hidden', () => {
- users.verifyKeysAreHidden();
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-const pages = {
- index: { url: '#/ceph-users', id: 'cd-crud-table' }
-};
-
-export class UsersPageHelper extends PageHelper {
- pages = pages;
-
- columnIndex = {
- entity: 1,
- capabilities: 2,
- key: 3
- };
-
- checkForUsers() {
- this.getTableCount('total').should('not.be.eq', 0);
- }
-
- verifyKeysAreHidden() {
- this.getTableCell(this.columnIndex.entity, 'osd.0')
- .parent()
- .find(`datatable-body-cell:nth-child(${this.columnIndex.key}) span`)
- .should(($ele) => {
- const serviceInstances = $ele.toArray().map((v) => v.innerText);
- expect(serviceInstances).not.contains(/^[a-z0-9]+$/i);
- });
- }
-}
+++ /dev/null
-import { And, Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
-
-import { UrlsCollection } from './urls.po';
-
-const urlsCollection = new UrlsCollection();
-
-Given('I am logged in', () => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
-});
-
-Given('I am on the {string} page', (page: string) => {
- cy.visit(urlsCollection.pages[page].url);
- cy.get(urlsCollection.pages[page].id).should('exist');
-});
-
-Then('I should be on the {string} page', (page: string) => {
- cy.get(urlsCollection.pages[page].id).should('exist');
-});
-
-And('I should see a button to {string}', (button: string) => {
- cy.get(`[aria-label="${button}"]`).should('be.visible');
-});
-
-When('I click on {string} button', (button: string) => {
- cy.get(`[aria-label="${button}"]`).first().click();
-});
-
-// When you are clicking on an action in the table actions dropdown button
-When('I click on {string} button from the table actions', (button: string) => {
- cy.get('.table-actions button.dropdown-toggle').first().click();
- cy.get(`[aria-label="${button}"]`).first().click();
-});
-
-And('select options {string}', (labels: string) => {
- if (labels) {
- cy.get('a[data-testid=select-menu-edit]').click();
- for (const label of labels.split(', ')) {
- cy.get('.popover-body div.select-menu-item-content').contains(label).click();
- }
- }
-});
-
-And('{string} option {string}', (action: string, labels: string) => {
- if (labels) {
- if (action === 'add') {
- cy.get('cd-modal').find('.select-menu-edit').click();
- for (const label of labels.split(', ')) {
- cy.get('.popover-body input').type(`${label}{enter}`);
- }
- } else {
- for (const label of labels.split(', ')) {
- cy.contains('cd-modal .badge', new RegExp(`^${label}$`))
- .find('.badge-remove')
- .click();
- }
- }
- }
-});
-
-/**
- * Fills in the given field using the value provided
- * @param field ID of the field that needs to be filled out.
- * @param value Value that should be filled in the field.
- */
-And('enter {string} {string}', (field: string, value: string) => {
- cy.get('cd-modal').within(() => {
- cy.get(`input[id=${field}]`).type(value);
- });
-});
-
-And('I click on submit button', () => {
- cy.get('[data-cy=submitBtn]').click();
-});
-
-/**
- * Selects any row on the datatable if it matches the given name
- */
-When('I select a row {string}', (row: string) => {
- cy.get('cd-table .search input').first().clear().type(row);
- cy.contains(`datatable-body-row datatable-body-cell .datatable-body-cell-label`, row).click();
-});
-
-Then('I should see the modal', () => {
- cy.get('cd-modal').should('exist');
-});
-
-Then('I should not see the modal', () => {
- cy.get('cd-modal').should('not.exist');
-});
-
-/**
- * Some modals have an additional confirmation to be provided
- * by ticking the 'Are you sure?' box.
- */
-Then('I check the tick box in modal', () => {
- cy.get('cd-modal .custom-control-label').click();
-});
-
-And('I confirm to {string}', (action: string) => {
- cy.contains('cd-modal button', action).click();
- cy.get('cd-modal').should('not.exist');
-});
-
-Then('I should see an error in {string} field', (field: string) => {
- cy.get('cd-modal').within(() => {
- cy.get(`input[id=${field}]`).should('have.class', 'ng-invalid');
- });
-});
-
-Then('I should see a row with {string}', (row: string) => {
- cy.get('cd-table .search input').first().clear().type(row);
- cy.contains(`datatable-body-row datatable-body-cell .datatable-body-cell-label`, row).should(
- 'exist'
- );
-});
-
-Then('I should not see a row with {string}', (row: string) => {
- cy.get('cd-table .search input').first().clear().type(row);
- cy.contains(`datatable-body-row datatable-body-cell .datatable-body-cell-label`, row).should(
- 'not.exist'
- );
-});
-
-Then('I should see rows with following entries', (entries) => {
- entries.hashes().forEach((entry: any) => {
- cy.get('cd-table .search input').first().clear().type(entry.hostname);
- cy.contains(
- `datatable-body-row datatable-body-cell .datatable-body-cell-label`,
- entry.hostname
- ).should('exist');
- });
-});
-
-And('I should see row {string} have {string}', (row: string, options: string) => {
- if (options) {
- cy.get('cd-table .search input').first().clear().type(row);
- for (const option of options.split(',')) {
- cy.contains(
- `datatable-body-row datatable-body-cell .datatable-body-cell-label .badge`,
- option
- ).should('exist');
- }
- }
-});
-
-And('I should see row {string} does not have {string}', (row: string, options: string) => {
- if (options) {
- cy.get('cd-table .search input').first().clear().type(row);
- for (const option of options.split(',')) {
- cy.contains(
- `datatable-body-row datatable-body-cell .datatable-body-cell-label .badge`,
- option
- ).should('not.exist');
- }
- }
-});
-
-And('I go to the {string} tab', (names: string) => {
- for (const name of names.split(', ')) {
- cy.contains('.nav.nav-tabs a', name).click();
- }
-});
-
-And('select {string} {string}', (selectionName: string, option: string) => {
- cy.get(`select[name=${selectionName}]`).select(option);
- cy.get(`select[name=${selectionName}] option:checked`).contains(option);
-});
-
-When('I expand the row {string}', (row: string) => {
- cy.contains('.datatable-body-row', row).first().find('.tc_expand-collapse').click();
-});
-
-And('I should see row {string} have {string} on this tab', (row: string, options: string) => {
- if (options) {
- cy.get('cd-table').should('exist');
- cy.get('datatable-scroller, .empty-row');
- cy.get('.datatable-row-detail').within(() => {
- cy.get('cd-table .search input').first().clear().type(row);
- for (const option of options.split(',')) {
- cy.contains(
- `datatable-body-row datatable-body-cell .datatable-body-cell-label span`,
- option
- ).should('exist');
- }
- });
- }
-});
+++ /dev/null
-import { Given, Then } from 'cypress-cucumber-preprocessor/steps';
-
-Given('I am on the {string} section', (page: string) => {
- cy.get('cd-wizard').within(() => {
- cy.get('.nav-link').should('contain.text', page).first().click();
- cy.get('.nav-link.active').should('contain.text', page);
- });
-});
-
-Then('I should see a message {string}', () => {
- cy.get('cd-create-cluster').should('contain.text', 'Please expand your cluster first');
-});
+++ /dev/null
-import { e2e } from '@grafana/e2e';
-import { Then, When } from 'cypress-cucumber-preprocessor/steps';
-import 'cypress-iframe';
-
-function getIframe() {
- cy.frameLoaded('#iframe');
- return cy.iframe();
-}
-
-Then('I should see the grafana panel {string}', (panels: string) => {
- getIframe().within(() => {
- for (const panel of panels.split(', ')) {
- cy.get('.grafana-app')
- .wait(100)
- .within(() => {
- e2e.components.Panels.Panel.title(panel).should('be.visible');
- });
- }
- });
-});
-
-When('I view the grafana panel {string}', (panels: string) => {
- getIframe().within(() => {
- for (const panel of panels.split(', ')) {
- cy.get('.grafana-app')
- .wait(100)
- .within(() => {
- e2e.components.Panels.Panel.title(panel).should('be.visible').click();
- e2e.components.Panels.Panel.headerItems('View').should('be.visible').click();
- });
- }
- });
-});
-
-Then('I should not see {string} in the panel {string}', (value: string, panels: string) => {
- getIframe().within(() => {
- for (const panel of panels.split(', ')) {
- cy.get('.grafana-app')
- .wait(100)
- .within(() => {
- cy.get(`[aria-label="${panel} panel"]`)
- .should('be.visible')
- .within(() => {
- cy.get('span').first().should('not.have.text', value);
- });
- });
- }
- });
-});
-
-Then(
- 'I should see the legends {string} in the graph {string}',
- (legends: string, panels: string) => {
- getIframe().within(() => {
- for (const panel of panels.split(', ')) {
- cy.get('.grafana-app')
- .wait(100)
- .within(() => {
- cy.get(`[aria-label="${panel} panel"]`)
- .should('be.visible')
- .within(() => {
- for (const legend of legends.split(', ')) {
- cy.get('a').contains(legend);
- }
- });
- });
- }
- });
- }
-);
-
-Then('I should not see No Data in the graph {string}', (panels: string) => {
- getIframe().within(() => {
- for (const panel of panels.split(', ')) {
- cy.get('.grafana-app')
- .wait(100)
- .within(() => {
- cy.get(`[aria-label="${panel} panel"]`)
- .should('be.visible')
- .within(() => {
- cy.get('div.datapoints-warning').should('not.exist');
- });
- });
- }
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class UrlsCollection extends PageHelper {
- pages = {
- // Cluster expansion
- welcome: { url: '#/expand-cluster', id: 'cd-create-cluster' },
-
- // Landing page
- dashboard: { url: '#/dashboard', id: 'cd-dashboard' },
-
- // Hosts
- hosts: { url: '#/hosts', id: 'cd-hosts' },
- 'add hosts': { url: '#/hosts/(modal:add)', id: 'cd-host-form' },
-
- // Services
- services: { url: '#/services', id: 'cd-services' },
- 'create services': { url: '#/services/(modal:create)', id: 'cd-service-form' },
-
- // Physical Disks
- 'physical disks': { url: '#/inventory', id: 'cd-inventory' },
-
- // Monitors
- monitors: { url: '#/monitor', id: 'cd-monitor' },
-
- // OSDs
- osds: { url: '#/osd', id: 'cd-osd-list' },
- 'create osds': { url: '#/osd/create', id: 'cd-osd-form' },
-
- // Configuration
- configuration: { url: '#/configuration', id: 'cd-configuration' },
-
- // Crush Map
- 'crush map': { url: '#/crush-map', id: 'cd-crushmap' },
-
- // Mgr modules
- 'mgr-modules': { url: '#/mgr-modules', id: 'cd-mgr-module-list' },
-
- // Logs
- logs: { url: '#/logs', id: 'cd-logs' },
-
- // RGW Daemons
- 'rgw daemons': { url: '#/rgw/daemon', id: 'cd-rgw-daemon-list' }
- };
-}
+++ /dev/null
-import { FilesystemsPageHelper } from './filesystems.po';
-
-describe('File Systems page', () => {
- const filesystems = new FilesystemsPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- filesystems.navigateTo();
- });
-
- describe('breadcrumb test', () => {
- it('should open and show breadcrumb', () => {
- filesystems.expectBreadcrumbText('File Systems');
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class FilesystemsPageHelper extends PageHelper {
- pages = { index: { url: '#/cephfs', id: 'cd-cephfs-list' } };
-}
+++ /dev/null
-import { HostsPageHelper } from '../cluster/hosts.po';
-
-describe('Hosts page', () => {
- const hosts = new HostsPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- hosts.navigateTo();
- });
-
- describe('when Orchestrator is available', () => {
- beforeEach(function () {
- cy.fixture('orchestrator/inventory.json').as('hosts');
- cy.fixture('orchestrator/services.json').as('services');
- });
-
- it('should not add an exsiting host', function () {
- const hostname = Cypress._.sample(this.hosts).name;
- hosts.navigateTo('add');
- hosts.add(hostname, true);
- });
-
- it('should drain and remove a host and then add it back', function () {
- const hostname = Cypress._.last(this.hosts)['name'];
-
- // should drain the host first before deleting
- hosts.drain(hostname);
- hosts.remove(hostname);
-
- // add it back
- hosts.navigateTo('add');
- hosts.add(hostname);
- hosts.checkExist(hostname, true);
- });
-
- it('should display inventory', function () {
- for (const host of this.hosts) {
- hosts.clickTab('cd-host-details', host.name, 'Physical Disks');
- cy.get('cd-host-details').within(() => {
- hosts.expectTableCount('total', host.devices.length);
- });
- }
- });
-
- it('should display daemons', function () {
- for (const host of this.hosts) {
- hosts.clickTab('cd-host-details', host.name, 'Daemons');
- cy.get('cd-host-details').within(() => {
- hosts.getTableCount('total').should('be.gte', 0);
- });
- }
- });
-
- it('should edit host labels', function () {
- const hostname = Cypress._.sample(this.hosts).name;
- const labels = ['foo', 'bar'];
- hosts.editLabels(hostname, labels, true);
- hosts.editLabels(hostname, labels, false);
- });
-
- it('should enter host into maintenance', function () {
- const hostname = Cypress._.sample(this.hosts).name;
- const serviceList = new Array();
- this.services.forEach((service: any) => {
- if (hostname === service.hostname) {
- serviceList.push(service.daemon_type);
- }
- });
- let enterMaintenance = true;
- serviceList.forEach((service: string) => {
- if (service === 'mgr' || service === 'alertmanager') {
- enterMaintenance = false;
- }
- });
- if (enterMaintenance) {
- hosts.maintenance(hostname);
- }
- });
-
- it('should exit host from maintenance', function () {
- const hostname = Cypress._.sample(this.hosts).name;
- hosts.maintenance(hostname, true);
- });
- });
-});
+++ /dev/null
-import { InventoryPageHelper } from '../cluster/inventory.po';
-
-describe('Physical Disks page', () => {
- const inventory = new InventoryPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- inventory.navigateTo();
- });
-
- it('should have correct devices', () => {
- cy.fixture('orchestrator/inventory.json').then((hosts) => {
- const totalDiskCount = Cypress._.sumBy(hosts, 'devices.length');
- inventory.expectTableCount('total', totalDiskCount);
- for (const host of hosts) {
- inventory.filterTable('Hostname', host['name']);
- inventory.getTableCount('found').should('be.eq', host.devices.length);
- }
- });
- });
-
- it('should identify device', () => {
- inventory.identify();
- });
-});
+++ /dev/null
-import { OSDsPageHelper } from '../cluster/osds.po';
-import { DashboardPageHelper } from '../ui/dashboard.po';
-
-describe('OSDs page', () => {
- const osds = new OSDsPageHelper();
- const dashboard = new DashboardPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- osds.navigateTo();
- });
-
- describe('when Orchestrator is available', () => {
- it('should create and delete OSDs', () => {
- osds.getTableCount('total').as('initOSDCount');
- osds.navigateTo('create');
- osds.create('hdd');
-
- cy.get('@newOSDCount').then((newCount) => {
- cy.get('@initOSDCount').then((oldCount) => {
- const expectedCount = Number(oldCount) + Number(newCount);
-
- // check total rows
- osds.expectTableCount('total', expectedCount);
-
- // landing page is easier to check OSD status
- dashboard.navigateTo();
- dashboard.infoCardBody('OSDs').should('contain.text', `${expectedCount} total`);
- dashboard.infoCardBody('OSDs').should('contain.text', `${expectedCount} up`);
- dashboard.infoCardBody('OSDs').should('contain.text', `${expectedCount} in`);
-
- cy.wait(30000);
- expect(Number(newCount)).to.be.gte(2);
- // Delete the first OSD we created
- osds.navigateTo();
- const deleteOsdId = Number(oldCount);
- osds.deleteByIDs([deleteOsdId], false);
- osds.ensureNoOsd(deleteOsdId);
-
- cy.wait(30000);
- // Replace the second OSD we created
- const replaceID = Number(oldCount) + 1;
- osds.deleteByIDs([replaceID], true);
- osds.checkStatus(replaceID, ['destroyed']);
- });
- });
- });
- });
-});
+++ /dev/null
-import { ServicesPageHelper } from '../cluster/services.po';
-
-describe('Services page', () => {
- const services = new ServicesPageHelper();
- const serviceName = 'rgw.foo';
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- services.navigateTo();
- });
-
- describe('when Orchestrator is available', () => {
- it('should create an rgw service', () => {
- services.navigateTo('create');
- services.addService('rgw');
-
- services.checkExist(serviceName, true);
- });
-
- it('should edit a service', () => {
- const count = '2';
- services.editService(serviceName, count);
- services.expectPlacementCount(serviceName, count);
- });
-
- it('should create and delete an ingress service', () => {
- services.navigateTo('create');
- services.addService('ingress');
-
- services.checkExist('ingress.rgw.foo', true);
-
- services.deleteService('ingress.rgw.foo');
- });
- });
-});
+++ /dev/null
-Feature: Grafana panels
-
- Go to some of the grafana performance section and check if
- panels are populated without any issues
-
- Background: Log in
- Given I am logged in
-
- Scenario Outline: Hosts Overall Performance
- Given I am on the "hosts" page
- When I go to the "Overall Performance" tab
- Then I should see the grafana panel "<panel>"
- When I view the grafana panel "<panel>"
- Then I should not see "No Data" in the panel "<panel>"
-
- Examples:
- | panel |
- | OSD Hosts |
- | AVG CPU Busy |
- | AVG RAM Utilization |
- | Physical IOPS |
- | AVG Disk Utilization |
- | Network Load |
- | CPU Busy - Top 10 Hosts |
- | Network Load - Top 10 Hosts |
-
- Scenario Outline: RGW Daemon Overall Performance
- Given I am on the "rgw daemons" page
- When I go to the "Overall Performance" tab
- Then I should see the grafana panel "<panel>"
- When I view the grafana panel "<panel>"
- Then I should not see No Data in the graph "<panel>"
- And I should see the legends "<legends>" in the graph "<panel>"
-
- Examples:
- | panel | legends |
- | Total Requests/sec by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
- | GET Latencies by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
- | Bandwidth by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
- | PUT Latencies by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 |
- | Average GET/PUT Latencies | GET AVG, PUT AVG |
- | Bandwidth Consumed by Type | GETs, PUTs |
-
- Scenario Outline: RGW per Daemon Performance
- Given I am on the "rgw daemons" page
- When I expand the row "<name>"
- And I go to the "Performance Details" tab
- Then I should see the grafana panel "<panel>"
- When I view the grafana panel "<panel>"
- Then I should not see No Data in the graph "<panel>"
- And I should see the legends "<name>" in the graph "<panel>"
-
- Examples:
- | name | panel |
- | foo.ceph-node-00 | Bandwidth by HTTP Operation |
- | foo.ceph-node-00 | HTTP Request Breakdown |
- | foo.ceph-node-00 | Workload Breakdown |
- | foo.ceph-node-01 | Bandwidth by HTTP Operation |
- | foo.ceph-node-01 | HTTP Request Breakdown |
- | foo.ceph-node-01 | Workload Breakdown |
- | foo.ceph-node-02 | Bandwidth by HTTP Operation |
- | foo.ceph-node-02 | HTTP Request Breakdown |
- | foo.ceph-node-02 | Workload Breakdown |
+++ /dev/null
-Feature: Cluster expansion welcome screen
-
- Go to the welcome screen and decide whether
- to proceed to wizard or skips to landing page
-
- Background: Login
- Given I am logged in
-
- Scenario: Cluster expansion welcome screen
- Given I am on the "welcome" page
- And I should see a button to "Expand Cluster"
- And I should see a button to "Skip"
- And I should see a message "Please expand your cluster first"
-
- Scenario: Go to the Cluster expansion wizard
- Given I am on the "welcome" page
- And I should see a button to "Expand Cluster"
- When I click on "Expand Cluster" button
- Then I am on the "Add Hosts" section
-
- Scenario: Skips the process and go to the landing page
- Given I am on the "welcome" page
- And I should see a button to "Skip"
- When I click on "Skip" button
- And I confirm to "Continue"
- Then I should be on the "dashboard" page
+++ /dev/null
-Feature: Cluster expansion host addition
-
- Add some hosts and perform some host related actions like editing the labels
- and removing the hosts from the cluster and verify all of the actions are performed
- as expected
-
- Background: Cluster expansion wizard
- Given I am logged in
- And I am on the "welcome" page
- And I click on "Expand Cluster" button
-
- Scenario Outline: Add hosts
- Given I am on the "Add Hosts" section
- When I click on "Add" button
- And enter "hostname" "<hostname>"
- And select options "<labels>"
- And I click on "Add Host" button
- Then I should not see the modal
- And I should see a row with "<hostname>"
- And I should see row "<hostname>" have "<labels>"
-
- Examples:
- | hostname | labels |
- | ceph-node-01 | mon, mgr |
- | ceph-node-02 ||
-
- Scenario Outline: Remove hosts
- Given I am on the "Add Hosts" section
- And I should see a row with "<hostname>"
- When I select a row "<hostname>"
- And I click on "Remove" button from the table actions
- Then I should see the modal
- And I check the tick box in modal
- And I click on "Remove Host" button
- Then I should not see the modal
- And I should not see a row with "<hostname>"
-
- Examples:
- | hostname |
- | ceph-node-01 |
- | ceph-node-02 |
-
- Scenario: Add hosts using pattern 'ceph-node-[01-02]'
- Given I am on the "Add Hosts" section
- When I click on "Add" button
- And enter "hostname" "ceph-node-[01-02]"
- And I click on "Add Host" button
- Then I should not see the modal
- And I should see rows with following entries
- | hostname |
- | ceph-node-01 |
- | ceph-node-02 |
-
- Scenario: Add exisiting host and verify it failed
- Given I am on the "Add Hosts" section
- And I should see a row with "ceph-node-00"
- When I click on "Add" button
- And enter "hostname" "ceph-node-00"
- Then I should see an error in "hostname" field
-
- Scenario Outline: Add and remove labels on host
- Given I am on the "Add Hosts" section
- When I select a row "<hostname>"
- And I click on "Edit" button from the table actions
- And "add" option "<labels>"
- And I click on "Edit Host" button
- Then I should see row "<hostname>" have "<labels>"
- When I select a row "<hostname>"
- And I click on "Edit" button from the table actions
- And "remove" option "<labels>"
- And I click on "Edit Host" button
- Then I should see row "<hostname>" does not have "<labels>"
-
- Examples:
- | hostname | labels |
- | ceph-node-01 | foo |
+++ /dev/null
-/* tslint:disable*/
-import {
- CreateClusterServicePageHelper,
- CreateClusterWizardHelper
-} from '../../cluster/create-cluster.po';
-/* tslint:enable*/
-
-describe('Create cluster create services page', () => {
- const createCluster = new CreateClusterWizardHelper();
- const createClusterServicePage = new CreateClusterServicePageHelper();
-
- const createService = (serviceType: string, serviceName: string, count = 1) => {
- cy.get('[aria-label=Create]').first().click();
- createClusterServicePage.addService(serviceType, false, count);
- createClusterServicePage.checkExist(serviceName, true);
- };
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- createCluster.navigateTo();
- createCluster.createCluster();
- cy.get('.nav-link').contains('Create Services').click();
- });
-
- it('should check if title contains Create Services', () => {
- cy.get('.title').should('contain.text', 'Create Services');
- });
-
- describe('when Orchestrator is available', () => {
- const serviceName = 'mds.test';
-
- it('should create an mds service', () => {
- createService('mds', serviceName);
- });
-
- it('should edit a service', () => {
- const daemonCount = '2';
- createClusterServicePage.editService(serviceName, daemonCount);
- createClusterServicePage.expectPlacementCount(serviceName, daemonCount);
- });
-
- it('should delete mds service', () => {
- createClusterServicePage.deleteService('mds.test');
- });
- });
-});
+++ /dev/null
-/* tslint:disable*/
-import { CreateClusterWizardHelper } from '../../cluster/create-cluster.po';
-import { OSDsPageHelper } from '../../cluster/osds.po';
-/* tslint:enable*/
-
-const osds = new OSDsPageHelper();
-
-describe('Create cluster create osds page', () => {
- const createCluster = new CreateClusterWizardHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- createCluster.navigateTo();
- createCluster.createCluster();
- cy.get('.nav-link').contains('Create OSDs').click();
- });
-
- it('should check if title contains Create OSDs', () => {
- cy.get('.title').should('contain.text', 'Create OSDs');
- });
-
- describe('when Orchestrator is available', () => {
- it('should create OSDs', () => {
- const hostnames = ['ceph-node-00', 'ceph-node-01'];
- for (const hostname of hostnames) {
- osds.create('hdd', hostname, true);
-
- // Go to the Review section and Expand the cluster
- // because the drive group spec is only stored
- // in frontend and will be lost when refreshed
- cy.get('.nav-link').contains('Review').click();
- cy.get('button[aria-label="Next"]').click();
- cy.get('cd-dashboard').should('exist');
- createCluster.navigateTo();
- createCluster.createCluster();
- cy.get('.nav-link').contains('Create OSDs').click();
- }
- });
- });
-});
+++ /dev/null
-/* tslint:disable*/
-import {
- CreateClusterHostPageHelper,
- CreateClusterWizardHelper
-} from '../../cluster/create-cluster.po';
-/* tslint:enable*/
-
-describe('Create Cluster Review page', () => {
- const createCluster = new CreateClusterWizardHelper();
- const createClusterHostPage = new CreateClusterHostPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- createCluster.navigateTo();
- createCluster.createCluster();
-
- cy.get('.nav-link').contains('Review').click();
- });
-
- describe('navigation link test', () => {
- it('should check if active nav-link is of Review section', () => {
- cy.get('.nav-link.active').should('contain.text', 'Review');
- });
- });
-
- describe('fields check', () => {
- it('should check cluster resources table is present', () => {
- // check for table header 'Cluster Resources'
- createCluster.getLegends().its(0).should('have.text', 'Cluster Resources');
-
- // check for fields in table
- createCluster.getStatusTables().should('contain.text', 'Hosts');
- createCluster.getStatusTables().should('contain.text', 'Storage Capacity');
- createCluster.getStatusTables().should('contain.text', 'CPUs');
- createCluster.getStatusTables().should('contain.text', 'Memory');
- });
-
- it('should check Host Details table is present', () => {
- // check for there to be two tables
- createCluster.getDataTables().should('have.length', 1);
-
- // verify correct columns on Host Details table
- createCluster.getDataTableHeaders(0).contains('Hostname');
-
- createCluster.getDataTableHeaders(0).contains('Labels');
-
- createCluster.getDataTableHeaders(0).contains('CPUs');
-
- createCluster.getDataTableHeaders(0).contains('Cores');
-
- createCluster.getDataTableHeaders(0).contains('Total Memory');
-
- createCluster.getDataTableHeaders(0).contains('Raw Capacity');
-
- createCluster.getDataTableHeaders(0).contains('HDDs');
-
- createCluster.getDataTableHeaders(0).contains('Flash');
-
- createCluster.getDataTableHeaders(0).contains('NICs');
- });
-
- it('should check default host name is present', () => {
- createClusterHostPage.check_for_host();
- });
- });
-});
+++ /dev/null
-/* tslint:disable*/
-import { CreateClusterWizardHelper } from '../../cluster/create-cluster.po';
-import { HostsPageHelper } from '../../cluster/hosts.po';
-import { ServicesPageHelper } from '../../cluster/services.po';
-/* tslint:enable*/
-
-describe('when cluster creation is completed', () => {
- const createCluster = new CreateClusterWizardHelper();
- const services = new ServicesPageHelper();
- const hosts = new HostsPageHelper();
-
- const hostnames = ['ceph-node-00', 'ceph-node-01', 'ceph-node-02', 'ceph-node-03'];
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- });
-
- it('should redirect to dashboard landing page after cluster creation', () => {
- createCluster.navigateTo();
- createCluster.createCluster();
-
- // Explicitly skip OSD Creation Step so that it prevents from
- // deploying OSDs to the hosts automatically.
- cy.get('.nav-link').contains('Create OSDs').click();
- cy.get('button[aria-label="Skip this step"]').click();
-
- cy.get('.nav-link').contains('Review').click();
- cy.get('button[aria-label="Next"]').click();
- cy.get('cd-dashboard').should('exist');
- });
-
- describe('Hosts page', () => {
- beforeEach(() => {
- hosts.navigateTo();
- });
-
- it('should add one more host', () => {
- hosts.navigateTo('add');
- hosts.add(hostnames[3]);
- hosts.checkExist(hostnames[3], true);
- });
-
- it('should check if monitoring stacks are running on the root host', { retries: 2 }, () => {
- const monitoringStack = ['alertmanager', 'grafana', 'node-exporter', 'prometheus'];
- hosts.clickTab('cd-host-details', 'ceph-node-00', 'Daemons');
- for (const daemon of monitoringStack) {
- cy.get('cd-host-details').within(() => {
- services.checkServiceStatus(daemon);
- });
- }
- });
-
- it('should have removed "_no_schedule" label', () => {
- for (const hostname of hostnames) {
- hosts.checkLabelExists(hostname, ['_no_schedule'], false);
- }
- });
-
- it('should display inventory', () => {
- hosts.clickTab('cd-host-details', hostnames[1], 'Physical Disks');
- cy.get('cd-host-details').within(() => {
- hosts.getTableCount('total').should('be.gte', 0);
- });
- });
-
- it('should display daemons', () => {
- hosts.clickTab('cd-host-details', hostnames[1], 'Daemons');
- cy.get('cd-host-details').within(() => {
- hosts.getTableCount('total').should('be.gte', 0);
- });
- });
-
- it('should check if mon daemon is running on all hosts', () => {
- for (const hostname of hostnames) {
- hosts.clickTab('cd-host-details', hostname, 'Daemons');
- cy.get('cd-host-details').within(() => {
- services.checkServiceStatus('mon');
- });
- }
- });
- });
-});
+++ /dev/null
-/* tslint:disable*/
-import { OSDsPageHelper } from '../../cluster/osds.po';
-/* tslint:enable*/
-
-describe('OSDs page', () => {
- const osds = new OSDsPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- osds.navigateTo();
- });
-
- it('should check if atleast 3 osds are created', { retries: 3 }, () => {
- // we have created a total of more than 3 osds throughout
- // the whole tests so ensuring that atleast
- // 3 osds are listed in the table. Since the OSD
- // creation can take more time going with
- // retry of 3
- for (let id = 0; id < 3; id++) {
- osds.checkStatus(id, ['in', 'up']);
- }
- });
-});
+++ /dev/null
-/* tslint:disable*/
-import { HostsPageHelper } from '../../cluster/hosts.po';
-import { ServicesPageHelper } from '../../cluster/services.po';
-/* tslint:enable*/
-
-describe('Host Page', () => {
- const hosts = new HostsPageHelper();
- const services = new ServicesPageHelper();
-
- const hostnames = ['ceph-node-00', 'ceph-node-01', 'ceph-node-02', 'ceph-node-03'];
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- hosts.navigateTo();
- });
-
- // rgw is needed for testing the force maintenance
- it('should create rgw services', () => {
- services.navigateTo('create');
- services.addService('rgw', false, 4);
- services.checkExist('rgw.foo', true);
- });
-
- it('should check if rgw daemon is running on all hosts', () => {
- for (const hostname of hostnames) {
- hosts.clickTab('cd-host-details', hostname, 'Daemons');
- cy.get('cd-host-details').within(() => {
- services.checkServiceStatus('rgw');
- });
- }
- });
-
- it('should force maintenance and exit', () => {
- hosts.maintenance(hostnames[3], true, true);
- });
-
- it('should drain, remove and add the host back', () => {
- hosts.drain(hostnames[3]);
- hosts.remove(hostnames[3]);
- hosts.navigateTo('add');
- hosts.add(hostnames[3]);
- hosts.checkExist(hostnames[3], true);
- });
-
- it('should show the exact count of daemons', () => {
- hosts.checkServiceInstancesExist(hostnames[0], ['mgr: 1', 'prometheus: 1']);
- });
-});
+++ /dev/null
-/* tslint:disable*/
-import { ServicesPageHelper } from '../../cluster/services.po';
-/* tslint:enable*/
-
-describe('Services page', () => {
- const services = new ServicesPageHelper();
- const mdsDaemonName = 'mds.test';
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- services.navigateTo();
- });
-
- it('should check if rgw service is created', () => {
- services.checkExist('rgw.foo', true);
- });
-
- it('should create an mds service', () => {
- services.navigateTo('create');
- services.addService('mds', false);
- services.checkExist(mdsDaemonName, true);
-
- services.clickServiceTab(mdsDaemonName, 'Daemons');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus(mdsDaemonName);
- });
- });
-
- it('should stop a daemon', () => {
- services.clickServiceTab(mdsDaemonName, 'Daemons');
- services.checkServiceStatus(mdsDaemonName);
-
- services.daemonAction('mds', 'stop');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus(mdsDaemonName, 'stopped');
- });
- });
-
- it('should restart a daemon', () => {
- services.checkExist(mdsDaemonName, true);
- services.clickServiceTab(mdsDaemonName, 'Daemons');
- services.daemonAction('mds', 'restart');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus(mdsDaemonName, 'running');
- });
- });
-
- it('should redeploy a daemon', () => {
- services.checkExist(mdsDaemonName, true);
- services.clickServiceTab(mdsDaemonName, 'Daemons');
-
- services.daemonAction('mds', 'stop');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus(mdsDaemonName, 'stopped');
- });
- services.daemonAction('mds', 'redeploy');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus(mdsDaemonName, 'running');
- });
- });
-
- it('should start a daemon', () => {
- services.checkExist(mdsDaemonName, true);
- services.clickServiceTab(mdsDaemonName, 'Daemons');
-
- services.daemonAction('mds', 'stop');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus(mdsDaemonName, 'stopped');
- });
- services.daemonAction('mds', 'start');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus(mdsDaemonName, 'running');
- });
- });
-
- it('should delete an mds service', () => {
- services.deleteService(mdsDaemonName);
- });
-
- it('should create and delete snmp-gateway service with version V2c', () => {
- services.navigateTo('create');
- services.addService('snmp-gateway', false, 1, 'V2c');
- services.checkExist('snmp-gateway', true);
-
- services.clickServiceTab('snmp-gateway', 'Daemons');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus('snmp-gateway');
- });
-
- services.deleteService('snmp-gateway');
- });
-
- it('should create and delete snmp-gateway service with version V3', () => {
- services.navigateTo('create');
- services.addService('snmp-gateway', false, 1, 'V3', true);
- services.checkExist('snmp-gateway', true);
-
- services.clickServiceTab('snmp-gateway', 'Daemons');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus('snmp-gateway');
- });
-
- services.deleteService('snmp-gateway');
- });
-
- it('should create and delete snmp-gateway service with version V3 and w/o privacy protocol', () => {
- services.navigateTo('create');
- services.addService('snmp-gateway', false, 1, 'V3', false);
- services.checkExist('snmp-gateway', true);
-
- services.clickServiceTab('snmp-gateway', 'Daemons');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus('snmp-gateway');
- });
-
- services.deleteService('snmp-gateway');
- });
-
- it('should create ingress as unmanaged', () => {
- services.navigateTo('create');
- services.addService('ingress', false, undefined, undefined, undefined, true);
- services.checkExist('ingress.rgw.foo', true);
- services.isUnmanaged('ingress.rgw.foo', true);
- services.deleteService('ingress.rgw.foo');
- });
-
- it('should check if exporter daemons are running', () => {
- services.clickServiceTab('ceph-exporter', 'Daemons');
- cy.get('cd-service-details').within(() => {
- services.checkServiceStatus('ceph-exporter', 'running');
- });
- });
-});
+++ /dev/null
-/* tslint:disable*/
-import { ServicesPageHelper } from '../../cluster/services.po';
-import { NFSPageHelper } from '../../orchestrator/workflow/nfs/nfs-export.po';
-import { BucketsPageHelper } from '../../rgw/buckets.po';
-/* tslint:enable*/
-
-describe('nfsExport page', () => {
- const nfsExport = new NFSPageHelper();
- const services = new ServicesPageHelper();
- const buckets = new BucketsPageHelper();
- const bucketName = 'e2e.nfs.bucket';
- // @TODO: uncomment this when a CephFS volume can be created through Dashboard.
- // const fsPseudo = '/fsPseudo';
- const rgwPseudo = '/rgwPseudo';
- const editPseudo = '/editPseudo';
- const backends = ['CephFS', 'Object Gateway'];
- const squash = 'no_root_squash';
- const client: object = { addresses: '192.168.0.10' };
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- nfsExport.navigateTo();
- });
-
- describe('breadcrumb test', () => {
- it('should open and show breadcrumb', () => {
- nfsExport.expectBreadcrumbText('NFS');
- });
- });
-
- describe('Create, edit and delete', () => {
- it('should create an NFS cluster', () => {
- services.navigateTo('create');
-
- services.addService('nfs');
-
- services.checkExist('nfs.testnfs', true);
- services.clickServiceTab('nfs.testnfs', 'Daemons');
- services.checkServiceStatus('nfs');
- });
-
- it('should create a nfs-export with RGW backend', () => {
- buckets.navigateTo('create');
- buckets.create(bucketName, 'dashboard', 'default-placement');
-
- nfsExport.navigateTo();
- nfsExport.existTableCell(rgwPseudo, false);
- nfsExport.navigateTo('create');
- nfsExport.create(backends[1], squash, client, rgwPseudo, bucketName);
- nfsExport.existTableCell(rgwPseudo);
- });
-
- // @TODO: uncomment this when a CephFS volume can be created through Dashboard.
- // it('should create a nfs-export with CephFS backend', () => {
- // nfsExport.navigateTo();
- // nfsExport.existTableCell(fsPseudo, false);
- // nfsExport.navigateTo('create');
- // nfsExport.create(backends[0], squash, client, fsPseudo);
- // nfsExport.existTableCell(fsPseudo);
- // });
-
- it('should show Clients', () => {
- nfsExport.clickTab('cd-nfs-details', rgwPseudo, 'Clients (1)');
- cy.get('cd-nfs-details').within(() => {
- nfsExport.getTableCount('total').should('be.gte', 0);
- });
- });
-
- it('should edit an export', () => {
- nfsExport.editExport(rgwPseudo, editPseudo);
-
- nfsExport.existTableCell(editPseudo);
- });
-
- it('should delete exports and bucket', () => {
- nfsExport.delete(editPseudo);
-
- buckets.navigateTo();
- buckets.delete(bucketName);
- });
- });
-});
+++ /dev/null
-/* tslint:disable*/
-import { PageHelper } from '../../../page-helper.po';
-/* tslint:enable*/
-
-const pages = {
- index: { url: '#/nfs', id: 'cd-nfs-list' },
- create: { url: '#/nfs/create', id: 'cd-nfs-form' }
-};
-
-export class NFSPageHelper extends PageHelper {
- pages = pages;
-
- @PageHelper.restrictTo(pages.create.url)
- create(backend: string, squash: string, client: object, pseudo: string, rgwPath?: string) {
- this.selectOption('cluster_id', 'testnfs');
- // select a storage backend
- this.selectOption('name', backend);
- if (backend === 'CephFS') {
- this.selectOption('fs_name', 'myfs');
-
- cy.get('#security_label').click({ force: true });
- } else {
- cy.get('input[data-testid=rgw_path]').type(rgwPath);
- }
-
- cy.get('input[name=pseudo]').type(pseudo);
- this.selectOption('squash', squash);
-
- // Add clients
- cy.get('button[name=add_client]').click({ force: true });
- cy.get('input[name=addresses]').type(client['addresses']);
-
- // Check if we can remove clients and add it again
- cy.get('span[name=remove_client]').click({ force: true });
- cy.get('button[name=add_client]').click({ force: true });
- cy.get('input[name=addresses]').type(client['addresses']);
-
- cy.get('cd-submit-button').click();
- }
-
- editExport(pseudo: string, editPseudo: string) {
- this.navigateEdit(pseudo);
-
- cy.get('input[name=pseudo]').clear().type(editPseudo);
-
- cy.get('cd-submit-button').click();
-
- // Click the export and check its details table for updated content
- this.getExpandCollapseElement(editPseudo).click();
- cy.get('.active.tab-pane').should('contain.text', editPseudo);
- }
-}
+++ /dev/null
-interface Page {
- url: string;
- id: string;
-}
-
-export abstract class PageHelper {
- pages: Record<string, Page>;
-
- /**
- * Decorator to be used on Helper methods to restrict access to one particular URL. This shall
- * help developers to prevent and highlight mistakes. It also reduces boilerplate code and by
- * thus, increases readability.
- */
- static restrictTo(page: string): Function {
- return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
- const fn: Function = descriptor.value;
- descriptor.value = function (...args: any) {
- cy.location('hash').should((url) => {
- expect(url).to.eq(
- page,
- `Method ${target.constructor.name}::${propertyKey} is supposed to be ` +
- `run on path "${page}", but was run on URL "${url}"`
- );
- });
- fn.apply(this, args);
- };
- };
- }
-
- /**
- * Navigates to the given page or to index.
- * Waits until the page component is loaded
- */
- navigateTo(name: string = null) {
- name = name || 'index';
- const page = this.pages[name];
-
- cy.visit(page.url);
- cy.get(page.id);
- }
-
- /**
- * Navigates back and waits for the hash to change
- */
- navigateBack() {
- cy.location('hash').then((hash) => {
- cy.go('back');
- cy.location('hash').should('not.be', hash);
- });
- }
-
- /**
- * Navigates to the edit page
- */
- navigateEdit(name: string, select = true, breadcrumb = true) {
- if (select) {
- this.navigateTo();
- this.getFirstTableCell(name).click();
- }
- cy.contains('Creating...').should('not.exist');
- cy.contains('button', 'Edit').click();
- if (breadcrumb) {
- this.expectBreadcrumbText('Edit');
- }
- }
-
- /**
- * Checks the active breadcrumb value.
- */
- expectBreadcrumbText(text: string) {
- cy.get('.breadcrumb-item.active').should('have.text', text);
- }
-
- getTabs() {
- return cy.get('.nav.nav-tabs a');
- }
-
- getTab(tabName: string) {
- return cy.contains('.nav.nav-tabs a', tabName);
- }
-
- getTabText(index: number) {
- return this.getTabs().its(index).text();
- }
-
- getTabsCount(): any {
- return this.getTabs().its('length');
- }
-
- /**
- * Helper method to navigate/click a tab inside the expanded table row.
- * @param selector The selector of the expanded table row.
- * @param name The name of the row which should expand.
- * @param tabName Name of the tab to be navigated/clicked.
- */
- clickTab(selector: string, name: string, tabName: string) {
- this.getExpandCollapseElement(name).click();
- cy.get(selector).within(() => {
- this.getTab(tabName).click();
- });
- }
-
- /**
- * Helper method to select an option inside a select element.
- * This method will also expect that the option was set.
- * @param option The option text (not value) to be selected.
- */
- selectOption(selectionName: string, option: string) {
- cy.get(`select[name=${selectionName}]`).select(option);
- return this.expectSelectOption(selectionName, option);
- }
-
- /**
- * Helper method to expect a set option inside a select element.
- * @param option The selected option text (not value) that is to
- * be expected.
- */
- expectSelectOption(selectionName: string, option: string) {
- return cy.get(`select[name=${selectionName}] option:checked`).contains(option);
- }
-
- getLegends() {
- return cy.get('legend');
- }
-
- getToast() {
- return cy.get('.ngx-toastr');
- }
-
- /**
- * Waits for the table to load its data
- * Should be used in all methods that access the datatable
- */
- private waitDataTableToLoad() {
- cy.get('cd-table').should('exist');
- cy.get('datatable-scroller, .empty-row');
- }
-
- getDataTables() {
- this.waitDataTableToLoad();
-
- return cy.get('cd-table .dataTables_wrapper');
- }
-
- private getTableCountSpan(spanType: 'selected' | 'found' | 'total') {
- return cy.contains('.datatable-footer-inner .page-count span', spanType);
- }
-
- // Get 'selected', 'found', or 'total' row count of a table.
- getTableCount(spanType: 'selected' | 'found' | 'total') {
- this.waitDataTableToLoad();
- return this.getTableCountSpan(spanType).then(($elem) => {
- const text = $elem
- .filter((_i, e) => e.innerText.includes(spanType))
- .first()
- .text();
-
- return Number(text.match(/(\d+)\s+\w*/)[1]);
- });
- }
-
- // Wait until selected', 'found', or 'total' row count of a table equal to a number.
- expectTableCount(spanType: 'selected' | 'found' | 'total', count: number) {
- this.waitDataTableToLoad();
- this.getTableCountSpan(spanType).should(($elem) => {
- const text = $elem.first().text();
- expect(Number(text.match(/(\d+)\s+\w*/)[1])).to.equal(count);
- });
- }
-
- getTableRow(content: string) {
- this.waitDataTableToLoad();
-
- this.searchTable(content);
- return cy.contains('.datatable-body-row', content);
- }
-
- getTableRows() {
- this.waitDataTableToLoad();
-
- return cy.get('datatable-row-wrapper');
- }
-
- /**
- * Returns the first table cell.
- * Optionally, you can specify the content of the cell.
- */
- getFirstTableCell(content?: string) {
- this.waitDataTableToLoad();
-
- if (content) {
- this.searchTable(content);
- return cy.contains('.datatable-body-cell-label', content);
- } else {
- return cy.get('.datatable-body-cell-label').first();
- }
- }
-
- getTableCell(columnIndex: number, exactContent: string, partialMatch = false) {
- this.waitDataTableToLoad();
- this.clearTableSearchInput();
- this.searchTable(exactContent);
- if (partialMatch) {
- return cy.contains(
- `datatable-body-row datatable-body-cell:nth-child(${columnIndex})`,
- exactContent
- );
- }
- return cy.contains(
- `datatable-body-row datatable-body-cell:nth-child(${columnIndex})`,
- new RegExp(`^${exactContent}$`)
- );
- }
-
- existTableCell(name: string, oughtToBePresent = true) {
- const waitRule = oughtToBePresent ? 'be.visible' : 'not.exist';
- this.getFirstTableCell(name).should(waitRule);
- }
-
- getExpandCollapseElement(content?: string) {
- this.waitDataTableToLoad();
-
- if (content) {
- return cy.contains('.datatable-body-row', content).find('.tc_expand-collapse');
- } else {
- return cy.get('.tc_expand-collapse').first();
- }
- }
-
- /**
- * Gets column headers of table
- */
- getDataTableHeaders(index = 0) {
- this.waitDataTableToLoad();
-
- return cy.get('.datatable-header').its(index).find('.datatable-header-cell');
- }
-
- /**
- * Grabs striped tables
- */
- getStatusTables() {
- return cy.get('.table.table-striped');
- }
-
- filterTable(name: string, option: string) {
- this.waitDataTableToLoad();
-
- cy.get('.tc_filter_name > button').click();
- cy.contains(`.tc_filter_name .dropdown-item`, name).click();
-
- cy.get('.tc_filter_option > button').click();
- cy.contains(`.tc_filter_option .dropdown-item`, option).click();
- }
-
- setPageSize(size: string) {
- cy.get('cd-table .dataTables_paginate input').first().clear({ force: true }).type(size);
- }
-
- searchTable(text: string) {
- this.waitDataTableToLoad();
-
- this.setPageSize('10');
- cy.get('[aria-label=search]').first().clear({ force: true }).type(text);
- }
-
- clearTableSearchInput() {
- this.waitDataTableToLoad();
-
- return cy.get('cd-table .search button').first().click();
- }
-
- // Click the action button
- clickActionButton(action: string) {
- cy.get('.table-actions button.dropdown-toggle').first().click(); // open submenu
- cy.get(`button.${action}`).click(); // click on "action" menu item
- }
-
- /**
- * This is a generic method to delete table rows.
- * It will select the first row that contains the provided name and delete it.
- * After that it will wait until the row is no longer displayed.
- * @param name The string to search in table cells.
- * @param columnIndex If provided, search string in columnIndex column.
- */
- delete(name: string, columnIndex?: number, section?: string) {
- // Selects row
- const getRow = columnIndex
- ? this.getTableCell.bind(this, columnIndex)
- : this.getFirstTableCell.bind(this);
- getRow(name).click();
- let action: string;
- section === 'hosts' ? (action = 'remove') : (action = 'delete');
-
- // Clicks on table Delete/Remove button
- this.clickActionButton(action);
-
- // Convert action to SentenceCase and Confirms deletion
- const actionUpperCase = action.charAt(0).toUpperCase() + action.slice(1);
- cy.get('cd-modal .custom-control-label').click();
- cy.contains('cd-modal button', actionUpperCase).click();
-
- // Wait for modal to close
- cy.get('cd-modal').should('not.exist');
-
- // Waits for item to be removed from table
- getRow(name).should('not.exist');
- }
-}
+++ /dev/null
-import { PoolPageHelper } from './pools.po';
-
-describe('Pools page', () => {
- const pools = new PoolPageHelper();
- const poolName = 'pool_e2e_pool-test';
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- pools.navigateTo();
- });
-
- describe('breadcrumb and tab tests', () => {
- it('should open and show breadcrumb', () => {
- pools.expectBreadcrumbText('Pools');
- });
-
- it('should show two tabs', () => {
- pools.getTabsCount().should('equal', 2);
- });
-
- it('should show pools list tab at first', () => {
- pools.getTabText(0).should('eq', 'Pools List');
- });
-
- it('should show overall performance as a second tab', () => {
- pools.getTabText(1).should('eq', 'Overall Performance');
- });
- });
-
- describe('Create, update and destroy', () => {
- it('should create a pool', () => {
- pools.existTableCell(poolName, false);
- pools.navigateTo('create');
- pools.create(poolName, 8, 'rbd');
- pools.existTableCell(poolName);
- });
-
- it('should edit a pools placement group', () => {
- pools.existTableCell(poolName);
- pools.edit_pool_pg(poolName, 32);
- });
-
- it('should show updated configuration field values', () => {
- pools.existTableCell(poolName);
- const bpsLimit = '4 B/s';
- pools.edit_pool_configuration(poolName, bpsLimit);
- });
-
- it('should delete a pool', () => {
- pools.delete(poolName);
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-const pages = {
- index: { url: '#/pool', id: 'cd-pool-list' },
- create: { url: '#/pool/create', id: 'cd-pool-form' }
-};
-
-export class PoolPageHelper extends PageHelper {
- pages = pages;
-
- private isPowerOf2(n: number) {
- // tslint:disable-next-line: no-bitwise
- return expect((n & (n - 1)) === 0, `Placement groups ${n} are not a power of 2`).to.be.true;
- }
-
- @PageHelper.restrictTo(pages.create.url)
- create(name: string, placement_groups: number, ...apps: string[]) {
- cy.get('input[name=name]').clear().type(name);
-
- this.isPowerOf2(placement_groups);
-
- this.selectOption('poolType', 'replicated');
-
- this.expectSelectOption('pgAutoscaleMode', 'on');
- this.selectOption('pgAutoscaleMode', 'off'); // To show pgNum field
- cy.get('input[name=pgNum]').clear().type(`${placement_groups}`);
- this.setApplications(apps);
- cy.get('cd-submit-button').click();
- }
-
- edit_pool_pg(name: string, new_pg: number, wait = true) {
- this.isPowerOf2(new_pg);
- this.navigateEdit(name);
-
- cy.get('input[name=pgNum]').clear().type(`${new_pg}`);
- cy.get('cd-submit-button').click();
- const str = `${new_pg} active+clean`;
- this.getTableRow(name);
- if (wait) {
- this.getTableRow(name).contains(str);
- }
- }
-
- edit_pool_configuration(name: string, bpsLimit: string) {
- this.navigateEdit(name);
-
- cy.get('.collapsible').click();
- cy.get('cd-rbd-configuration-form')
- .get('input[name=rbd_qos_bps_limit]')
- .clear()
- .type(`${bpsLimit}`);
- cy.get('cd-submit-button').click();
-
- this.navigateEdit(name);
-
- cy.get('.collapsible').click();
- cy.get('cd-rbd-configuration-form')
- .get('input[name=rbd_qos_bps_limit]')
- .should('have.value', bpsLimit);
- }
-
- private setApplications(apps: string[]) {
- if (!apps || apps.length === 0) {
- return;
- }
- cy.get('.float-start.me-2.select-menu-edit').click();
- cy.get('.popover-body').should('be.visible');
- apps.forEach((app) => cy.get('.select-menu-item-content').contains(app).click());
- }
-}
+++ /dev/null
-import { BucketsPageHelper } from './buckets.po';
-
-describe('RGW buckets page', () => {
- const buckets = new BucketsPageHelper();
- const bucket_name = 'e2ebucket';
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- buckets.navigateTo();
- });
-
- describe('breadcrumb tests', () => {
- it('should open and show breadcrumb', () => {
- buckets.expectBreadcrumbText('Buckets');
- });
- });
-
- describe('create, edit & delete bucket tests', () => {
- it('should create bucket', () => {
- buckets.navigateTo('create');
- buckets.create(bucket_name, BucketsPageHelper.USERS[0], 'default-placement');
- buckets.getFirstTableCell(bucket_name).should('exist');
- });
-
- it('should edit bucket', () => {
- buckets.edit(bucket_name, BucketsPageHelper.USERS[1]);
- buckets.getDataTables().should('contain.text', BucketsPageHelper.USERS[1]);
- });
-
- it('should delete bucket', () => {
- buckets.delete(bucket_name);
- });
-
- it('should check default encryption is SSE-S3', () => {
- buckets.navigateTo('create');
- buckets.checkForDefaultEncryption();
- });
-
- it('should create bucket with object locking enabled', () => {
- buckets.navigateTo('create');
- buckets.create(bucket_name, BucketsPageHelper.USERS[0], 'default-placement', true);
- buckets.getFirstTableCell(bucket_name).should('exist');
- });
-
- it('should not allow to edit versioning if object locking is enabled', () => {
- buckets.edit(bucket_name, BucketsPageHelper.USERS[1], true);
- buckets.getDataTables().should('contain.text', BucketsPageHelper.USERS[1]);
-
- buckets.delete(bucket_name);
- });
- });
-
- describe('Invalid Input in Create and Edit tests', () => {
- it('should test invalid inputs in create fields', () => {
- buckets.testInvalidCreate();
- });
-
- it('should test invalid input in edit owner field', () => {
- buckets.navigateTo('create');
- buckets.create(bucket_name, BucketsPageHelper.USERS[0], 'default-placement');
- buckets.testInvalidEdit(bucket_name);
- buckets.navigateTo();
- buckets.delete(bucket_name);
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-const pages = {
- index: { url: '#/rgw/bucket', id: 'cd-rgw-bucket-list' },
- create: { url: '#/rgw/bucket/create', id: 'cd-rgw-bucket-form' }
-};
-
-export class BucketsPageHelper extends PageHelper {
- static readonly USERS = ['dashboard', 'testid'];
-
- pages = pages;
-
- versioningStateEnabled = 'Enabled';
- versioningStateSuspended = 'Suspended';
-
- private selectOwner(owner: string) {
- return this.selectOption('owner', owner);
- }
-
- private selectPlacementTarget(placementTarget: string) {
- return this.selectOption('placement-target', placementTarget);
- }
-
- private selectLockMode(lockMode: string) {
- return this.selectOption('lock_mode', lockMode);
- }
-
- @PageHelper.restrictTo(pages.create.url)
- create(name: string, owner: string, placementTarget: string, isLocking = false) {
- // Enter in bucket name
- cy.get('#bid').type(name);
-
- // Select bucket owner
- this.selectOwner(owner);
- cy.get('#owner').should('have.class', 'ng-valid');
-
- // Select bucket placement target:
- this.selectPlacementTarget(placementTarget);
- cy.get('#placement-target').should('have.class', 'ng-valid');
-
- if (isLocking) {
- cy.get('#lock_enabled').click({ force: true });
- // Select lock mode:
- this.selectLockMode('Compliance');
- cy.get('#lock_mode').should('have.class', 'ng-valid');
- cy.get('#lock_retention_period_days').type('3');
- }
-
- // Click the create button and wait for bucket to be made
- cy.contains('button', 'Create Bucket').click();
-
- this.getFirstTableCell(name).should('exist');
- }
-
- @PageHelper.restrictTo(pages.create.url)
- checkForDefaultEncryption() {
- cy.get("cd-helper[aria-label='toggle encryption helper']").click();
- cy.get("a[aria-label='click here']").click();
- cy.get('cd-modal').within(() => {
- cy.get('input[id=s3Enabled]').should('be.checked');
- });
- }
-
- @PageHelper.restrictTo(pages.index.url)
- edit(name: string, new_owner: string, isLocking = false) {
- this.navigateEdit(name);
-
- cy.get('input[name=placement-target]').should('have.value', 'default-placement');
- this.selectOwner(new_owner);
-
- // If object locking is enabled versioning shouldn't be visible
- if (isLocking) {
- cy.get('input[id=versioning]').should('be.disabled');
- cy.contains('button', 'Edit Bucket').click();
-
- // wait to be back on buckets page with table visible and click
- this.getExpandCollapseElement(name).click();
-
- // check its details table for edited owner field
- cy.get('.table.table-striped.table-bordered')
- .first()
- .should('contains.text', new_owner)
- .as('bucketDataTable');
-
- // Check versioning enabled:
- cy.get('@bucketDataTable').find('tr').its(2).find('td').last().should('have.text', new_owner);
- cy.get('@bucketDataTable').find('tr').its(11).find('td').last().as('versioningValueCell');
-
- return cy.get('@versioningValueCell').should('have.text', this.versioningStateEnabled);
- }
- // Enable versioning
- cy.get('input[id=versioning]').should('not.be.checked');
- cy.get('label[for=versioning]').click();
- cy.get('input[id=versioning]').should('be.checked');
-
- cy.contains('button', 'Edit Bucket').click();
-
- // wait to be back on buckets page with table visible and click
- this.getExpandCollapseElement(name).click();
-
- // check its details table for edited owner field
- cy.get('.table.table-striped.table-bordered')
- .first()
- .should('contains.text', new_owner)
- .as('bucketDataTable');
-
- // Check versioning enabled:
- cy.get('@bucketDataTable').find('tr').its(2).find('td').last().should('have.text', new_owner);
- cy.get('@bucketDataTable').find('tr').its(11).find('td').last().as('versioningValueCell');
-
- cy.get('@versioningValueCell').should('have.text', this.versioningStateEnabled);
-
- // Disable versioning:
- this.navigateEdit(name);
-
- cy.get('label[for=versioning]').click();
- cy.get('input[id=versioning]').should('not.be.checked');
- cy.contains('button', 'Edit Bucket').click();
-
- // Check versioning suspended:
- this.getExpandCollapseElement(name).click();
-
- return cy.get('@versioningValueCell').should('have.text', this.versioningStateSuspended);
- }
-
- testInvalidCreate() {
- this.navigateTo('create');
- cy.get('#bid').as('nameInputField'); // Grabs name box field
-
- // Gives an invalid name (too short), then waits for dashboard to determine validity
- cy.get('@nameInputField').type('rq');
-
- cy.contains('button', 'Create Bucket').click(); // To trigger a validation
-
- // Waiting for website to decide if name is valid or not
- // Check that name input field was marked invalid in the css
- cy.get('@nameInputField')
- .should('not.have.class', 'ng-pending')
- .and('have.class', 'ng-invalid');
-
- // Check that error message was printed under name input field
- cy.get('#bid + .invalid-feedback').should(
- 'have.text',
- 'Bucket names must be 3 to 63 characters long.'
- );
-
- // Test invalid owner input
- // select some valid option. The owner drop down error message will not appear unless a valid user was selected at
- // one point before the invalid placeholder user is selected.
- this.selectOwner(BucketsPageHelper.USERS[1]);
-
- // select the first option, which is invalid because it is a placeholder
- this.selectOwner('-- Select a user --');
-
- cy.get('@nameInputField').click();
-
- // Check that owner drop down field was marked invalid in the css
- cy.get('#owner').should('have.class', 'ng-invalid');
-
- // Check that error message was printed under owner drop down field
- cy.get('#owner + .invalid-feedback').should('have.text', 'This field is required.');
-
- // Check invalid placement target input
- this.selectOwner(BucketsPageHelper.USERS[1]);
- // The drop down error message will not appear unless a valid option is previsously selected.
- this.selectPlacementTarget('default-placement');
- this.selectPlacementTarget('-- Select a placement target --');
- cy.get('@nameInputField').click(); // Trigger validation
- cy.get('#placement-target').should('have.class', 'ng-invalid');
- cy.get('#placement-target + .invalid-feedback').should('have.text', 'This field is required.');
-
- // Clicks the Create Bucket button but the page doesn't move.
- // Done by testing for the breadcrumb
- cy.contains('button', 'Create Bucket').click(); // Clicks Create Bucket button
- this.expectBreadcrumbText('Create');
- // content in fields seems to subsist through tests if not cleared, so it is cleared
- cy.get('@nameInputField').clear();
- return cy.contains('button', 'Cancel').click();
- }
-
- testInvalidEdit(name: string) {
- this.navigateEdit(name);
-
- cy.get('input[id=versioning]').should('exist').and('not.be.checked');
-
- // Chooses 'Select a user' rather than a valid owner on Edit Bucket page
- // and checks if it's an invalid input
-
- // select the first option, which is invalid because it is a placeholder
- this.selectOwner('-- Select a user --');
-
- cy.contains('button', 'Edit Bucket').click();
-
- // Check that owner drop down field was marked invalid in the css
- cy.get('#owner').should('have.class', 'ng-invalid');
-
- // Check that error message was printed under owner drop down field
- cy.get('#owner + .invalid-feedback').should('have.text', 'This field is required.');
-
- this.expectBreadcrumbText('Edit');
- }
-}
+++ /dev/null
-import { DaemonsPageHelper } from './daemons.po';
-
-describe('RGW daemons page', () => {
- const daemons = new DaemonsPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- daemons.navigateTo();
- });
-
- describe('breadcrumb and tab tests', () => {
- it('should open and show breadcrumb', () => {
- daemons.expectBreadcrumbText('Gateways');
- });
-
- it('should show two tabs', () => {
- daemons.getTabsCount().should('eq', 2);
- });
-
- it('should show daemons list tab at first', () => {
- daemons.getTabText(0).should('eq', 'Gateways List');
- });
-
- it('should show overall performance as a second tab', () => {
- daemons.getTabText(1).should('eq', 'Overall Performance');
- });
- });
-
- describe('details and performance counters table tests', () => {
- it('should check that details/performance tables are visible when daemon is selected', () => {
- daemons.checkTables();
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class DaemonsPageHelper extends PageHelper {
- pages = {
- index: { url: '#/rgw/daemon', id: 'cd-rgw-daemon-list' }
- };
-
- getTableCell() {
- return cy
- .get('.tab-content')
- .its(1)
- .find('cd-table')
- .should('have.length', 1) // Only 1 table should be renderer
- .find('datatable-body-cell');
- }
-
- checkTables() {
- // click on a daemon so details table appears
- cy.get('.datatable-body-cell-label').first().click();
-
- // check details table is visible
- // check at least one field is present
- this.getTableCell().should('be.visible').should('contain.text', 'ceph_version');
-
- // click on performance counters tab and check table is loaded
- cy.contains('.nav-link', 'Performance Counters').click();
-
- // check at least one field is present
- this.getTableCell().should('be.visible').should('contain.text', 'objecter.op_r');
-
- // click on performance details tab
- cy.contains('.nav-link', 'Performance Details').click();
- }
-}
+++ /dev/null
-import { UsersPageHelper } from './users.po';
-
-describe('RGW users page', () => {
- const users = new UsersPageHelper();
- const tenant = 'e2e_000tenant';
- const user_id = 'e2e_000user_create_edit_delete';
- const user_name = tenant + '$' + user_id;
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- users.navigateTo();
- });
-
- describe('breadcrumb tests', () => {
- it('should open and show breadcrumb', () => {
- users.expectBreadcrumbText('Users');
- });
- });
-
- describe('create, edit & delete user tests', () => {
- it('should create user', () => {
- users.navigateTo('create');
- users.create(tenant, user_id, 'Some Name', 'original@website.com', '1200');
- users.getFirstTableCell(user_id).should('exist');
- });
-
- it('should edit users full name, email and max buckets', () => {
- users.edit(user_name, 'Another Identity', 'changed@othersite.com', '1969');
- });
-
- it('should delete user', () => {
- users.delete(user_name);
- });
- });
-
- describe('Invalid input tests', () => {
- it('should put invalid input into user creation form and check fields are marked invalid', () => {
- users.invalidCreate();
- });
-
- it('should put invalid input into user edit form and check fields are marked invalid', () => {
- users.invalidEdit();
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-const pages = {
- index: { url: '#/rgw/user', id: 'cd-rgw-user-list' },
- create: { url: '#/rgw/user/create', id: 'cd-rgw-user-form' }
-};
-
-export class UsersPageHelper extends PageHelper {
- pages = pages;
-
- @PageHelper.restrictTo(pages.create.url)
- create(tenant: string, user_id: string, fullname: string, email: string, maxbuckets: string) {
- // Enter in user_id
- cy.get('#user_id').type(user_id);
- // Show Tenanat
- cy.get('#show_tenant').click({ force: true });
- // Enter in tenant
- cy.get('#tenant').type(tenant);
- // Enter in full name
- cy.get('#display_name').click().type(fullname);
-
- // Enter in email
- cy.get('#email').click().type(email);
-
- // Enter max buckets
- this.selectOption('max_buckets_mode', 'Custom');
- cy.get('#max_buckets').should('exist').should('have.value', '1000');
- cy.get('#max_buckets').click().clear().type(maxbuckets);
-
- // Click the create button and wait for user to be made
- cy.contains('button', 'Create User').click();
- this.getFirstTableCell(tenant + '$' + user_id).should('exist');
- }
-
- @PageHelper.restrictTo(pages.index.url)
- edit(name: string, new_fullname: string, new_email: string, new_maxbuckets: string) {
- this.navigateEdit(name);
-
- // Change the full name field
- cy.get('#display_name').click().clear().type(new_fullname);
-
- // Change the email field
- cy.get('#email').click().clear().type(new_email);
-
- // Change the max buckets field
- this.selectOption('max_buckets_mode', 'Custom');
- cy.get('#max_buckets').click().clear().type(new_maxbuckets);
-
- cy.contains('button', 'Edit User').click();
-
- // Click the user and check its details table for updated content
- this.getExpandCollapseElement(name).click();
- cy.get('.active.tab-pane')
- .should('contain.text', new_fullname)
- .and('contain.text', new_email)
- .and('contain.text', new_maxbuckets);
- }
-
- invalidCreate() {
- const tenant = '000invalid_tenant';
- const uname = '000invalid_create_user';
- // creating this user in order to check that you can't give two users the same name
- this.navigateTo('create');
- this.create(tenant, uname, 'xxx', 'xxx@xxx', '1');
-
- this.navigateTo('create');
-
- // Username
- cy.get('#user_id')
- // No username had been entered. Field should be invalid
- .should('have.class', 'ng-invalid')
- // Try to give user already taken name. Should make field invalid.
- .type(uname);
- cy.get('#show_tenant').click({ force: true });
- cy.get('#tenant').type(tenant).should('have.class', 'ng-invalid');
- cy.contains('#tenant + .invalid-feedback', 'The chosen user ID exists in this tenant.');
-
- // check that username field is marked invalid if username has been cleared off
- cy.get('#user_id').clear().blur().should('have.class', 'ng-invalid');
- cy.contains('#user_id + .invalid-feedback', 'This field is required.');
-
- // Full name
- cy.get('#display_name')
- // No display name has been given so field should be invalid
- .should('have.class', 'ng-invalid')
- // display name field should also be marked invalid if given input then emptied
- .type('a')
- .clear()
- .blur()
- .should('have.class', 'ng-invalid');
- cy.contains('#display_name + .invalid-feedback', 'This field is required.');
-
- // put invalid email to make field invalid
- cy.get('#email').type('a').blur().should('have.class', 'ng-invalid');
- cy.contains('#email + .invalid-feedback', 'This is not a valid email address.');
-
- // put negative max buckets to make field invalid
- this.expectSelectOption('max_buckets_mode', 'Custom');
- cy.get('#max_buckets').clear().type('-5').blur().should('have.class', 'ng-invalid');
- cy.contains('#max_buckets + .invalid-feedback', 'The entered value must be >= 1.');
-
- this.navigateTo();
- this.delete(tenant + '$' + uname);
- }
-
- invalidEdit() {
- const tenant = '000invalid_tenant';
- const uname = '000invalid_edit_user';
- // creating this user to edit for the test
- this.navigateTo('create');
- this.create(tenant, uname, 'xxx', 'xxx@xxx', '50');
- const name = tenant + '$' + uname;
- this.navigateEdit(name);
-
- // put invalid email to make field invalid
- cy.get('#email')
- .clear()
- .type('a')
- .blur()
- .should('not.have.class', 'ng-pending')
- .should('have.class', 'ng-invalid');
- cy.contains('#email + .invalid-feedback', 'This is not a valid email address.');
-
- // empty the display name field making it invalid
- cy.get('#display_name').clear().blur().should('have.class', 'ng-invalid');
- cy.contains('#display_name + .invalid-feedback', 'This field is required.');
-
- // put negative max buckets to make field invalid
- this.selectOption('max_buckets_mode', 'Disabled');
- cy.get('#max_buckets').should('not.exist');
- this.selectOption('max_buckets_mode', 'Custom');
- cy.get('#max_buckets').should('exist').should('have.value', '50');
- cy.get('#max_buckets').clear().type('-5').blur().should('have.class', 'ng-invalid');
- cy.contains('#max_buckets + .invalid-feedback', 'The entered value must be >= 1.');
-
- this.navigateTo();
- this.delete(tenant + '$' + uname);
- }
-}
+++ /dev/null
-import { ApiDocsPageHelper } from '../ui/api-docs.po';
-
-describe('Api Docs Page', () => {
- const apiDocs = new ApiDocsPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- apiDocs.navigateTo();
- });
-
- it('should show the API Docs description', () => {
- cy.get('.renderedMarkdown').first().contains('This is the official Ceph REST API');
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class ApiDocsPageHelper extends PageHelper {
- pages = { index: { url: '#/api-docs', id: 'cd-api-docs' } };
-}
+++ /dev/null
-import { ManagerModulesPageHelper } from '../cluster/mgr-modules.po';
-import { DashboardV3PageHelper } from './dashboard-v3.po';
-
-describe('Dashboard-v3 Main Page', () => {
- const dashboard = new DashboardV3PageHelper();
- const mgrmodules = new ManagerModulesPageHelper();
-
- before(() => {
- cy.login();
- mgrmodules.navigateTo();
- mgrmodules.navigateEdit('dashboard');
- cy.get('#FEATURE_TOGGLE_DASHBOARD').check();
- cy.contains('button', 'Update').click();
- });
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- dashboard.navigateTo();
- });
-
- describe('Check that all hyperlinks on inventory card lead to the correct page and fields exist', () => {
- it('should ensure that all linked pages in the inventory card lead to correct page', () => {
- const expectationMap = {
- Host: 'Hosts',
- Monitor: 'Monitors',
- OSDs: 'OSDs',
- Pool: 'Pools',
- 'Object Gateway': 'Daemons'
- };
-
- for (const [linkText, breadcrumbText] of Object.entries(expectationMap)) {
- cy.location('hash').should('eq', '#/dashboard');
- dashboard.clickInventoryCardLink(linkText);
- dashboard.expectBreadcrumbText(breadcrumbText);
- dashboard.navigateBack();
- }
- });
-
- it('should verify that cards exist on dashboard in proper order', () => {
- // Ensures that cards are all displayed on the dashboard tab while being in the proper
- // order, checks for card title and position via indexing into a list of all cards.
- const order = ['Details', 'Status', 'Capacity', 'Inventory', 'Cluster utilization'];
-
- for (let i = 0; i < order.length; i++) {
- dashboard.card(i).should('contain.text', order[i]);
- }
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class DashboardV3PageHelper extends PageHelper {
- pages = { index: { url: '#/dashboard', id: 'cd-dashboard-v3' } };
-
- cardTitle(index: number) {
- return cy.get('.card-title').its(index).text();
- }
-
- clickInventoryCardLink(link: string) {
- console.log(link);
- cy.get(`cd-card[title="Inventory"]`).contains('a', link).click();
- }
-
- card(indexOrTitle: number) {
- cy.get('cd-card').as('cards');
-
- return cy.get('@cards').its(indexOrTitle);
- }
-}
+++ /dev/null
-import { IscsiPageHelper } from '../block/iscsi.po';
-import { HostsPageHelper } from '../cluster/hosts.po';
-import { ManagerModulesPageHelper } from '../cluster/mgr-modules.po';
-import { MonitorsPageHelper } from '../cluster/monitors.po';
-import { OSDsPageHelper } from '../cluster/osds.po';
-import { PageHelper } from '../page-helper.po';
-import { PoolPageHelper } from '../pools/pools.po';
-import { DaemonsPageHelper } from '../rgw/daemons.po';
-import { DashboardPageHelper } from './dashboard.po';
-
-describe('Dashboard Main Page', () => {
- const dashboard = new DashboardPageHelper();
- const daemons = new DaemonsPageHelper();
- const hosts = new HostsPageHelper();
- const osds = new OSDsPageHelper();
- const pools = new PoolPageHelper();
- const monitors = new MonitorsPageHelper();
- const iscsi = new IscsiPageHelper();
- const mgrmodules = new ManagerModulesPageHelper();
-
- before(() => {
- cy.login();
- mgrmodules.navigateTo();
- mgrmodules.navigateEdit('dashboard');
- cy.get('#FEATURE_TOGGLE_DASHBOARD').uncheck();
- cy.contains('button', 'Update').click();
- });
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- dashboard.navigateTo();
- });
-
- describe('Check that all hyperlinks on info cards lead to the correct page and fields exist', () => {
- it('should ensure that all linked info cards lead to correct page', () => {
- const expectationMap = {
- Monitors: 'Monitors',
- OSDs: 'OSDs',
- Hosts: 'Hosts',
- 'Object Gateways': 'Daemons',
- 'iSCSI Gateways': 'Overview',
- Pools: 'Pools'
- };
-
- for (const [linkText, breadcrumbText] of Object.entries(expectationMap)) {
- cy.location('hash').should('eq', '#/dashboard');
- dashboard.clickInfoCardLink(linkText);
- dashboard.expectBreadcrumbText(breadcrumbText);
- dashboard.navigateBack();
- }
- });
-
- it('should verify that info cards exist on dashboard in proper order', () => {
- // Ensures that info cards are all displayed on the dashboard tab while being in the proper
- // order, checks for card title and position via indexing into a list of all info cards.
- const order = [
- 'Cluster Status',
- 'Hosts',
- 'Monitors',
- 'OSDs',
- 'Managers',
- 'Object Gateways',
- 'Metadata Servers',
- 'iSCSI Gateways',
- 'Raw Capacity',
- 'Objects',
- 'PG Status',
- 'Pools',
- 'PGs per OSD',
- 'Client Read/Write',
- 'Client Throughput',
- 'Recovery Throughput',
- 'Scrubbing'
- ];
-
- for (let i = 0; i < order.length; i++) {
- dashboard.infoCard(i).should('contain.text', order[i]);
- }
- });
-
- it('should verify that info card group titles are present and in the right order', () => {
- cy.location('hash').should('eq', '#/dashboard');
- dashboard.infoGroupTitle(0).should('eq', 'Status');
- dashboard.infoGroupTitle(1).should('eq', 'Capacity');
- dashboard.infoGroupTitle(2).should('eq', 'Performance');
- });
- });
-
- it('Should check that dashboard cards have correct information', () => {
- interface TestSpec {
- cardName: string;
- regexMatcher?: RegExp;
- pageObject: PageHelper;
- }
- const testSpecs: TestSpec[] = [
- { cardName: 'Object Gateways', regexMatcher: /(\d+)\s+total/, pageObject: daemons },
- { cardName: 'Monitors', regexMatcher: /(\d+)\s+\(quorum/, pageObject: monitors },
- { cardName: 'Hosts', regexMatcher: /(\d+)\s+total/, pageObject: hosts },
- { cardName: 'OSDs', regexMatcher: /(\d+)\s+total/, pageObject: osds },
- { cardName: 'Pools', pageObject: pools },
- { cardName: 'iSCSI Gateways', regexMatcher: /(\d+)\s+total/, pageObject: iscsi }
- ];
- for (let i = 0; i < testSpecs.length; i++) {
- const spec = testSpecs[i];
- dashboard.navigateTo();
-
- dashboard.infoCardBodyText(spec.cardName).then((infoCardBodyText: string) => {
- let dashCount = 0;
-
- if (spec.regexMatcher) {
- const match = infoCardBodyText.match(new RegExp(spec.regexMatcher));
- expect(match).to.length.gt(
- 1,
- `Regex ${spec.regexMatcher} did not find a match for card with name ` +
- `${spec.cardName}`
- );
- dashCount = Number(match[1]);
- } else {
- dashCount = Number(infoCardBodyText);
- }
-
- spec.pageObject.navigateTo();
- spec.pageObject.getTableCount('total').then((tableCount) => {
- expect(tableCount).to.eq(
- dashCount,
- `Text of card "${spec.cardName}" and regex "${spec.regexMatcher}" resulted in ${dashCount} ` +
- `but did not match table count ${tableCount}`
- );
- });
- });
- }
- });
-
- after(() => {
- cy.login();
- mgrmodules.navigateTo();
- mgrmodules.navigateEdit('dashboard');
- cy.get('#FEATURE_TOGGLE_DASHBOARD').click();
- cy.contains('button', 'Update').click();
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class DashboardPageHelper extends PageHelper {
- pages = { index: { url: '#/dashboard', id: 'cd-dashboard' } };
-
- infoGroupTitle(index: number) {
- return cy.get('.info-group-title').its(index).text();
- }
-
- clickInfoCardLink(cardName: string) {
- cy.get(`cd-info-card[cardtitle="${cardName}"]`).contains('a', cardName).click();
- }
-
- infoCard(indexOrTitle: number | string) {
- cy.get('cd-info-card').as('infoCards');
-
- if (typeof indexOrTitle === 'number') {
- return cy.get('@infoCards').its(indexOrTitle);
- } else {
- return cy.contains('cd-info-card a', indexOrTitle).parent().parent().parent().parent();
- }
- }
-
- infoCardBodyText(infoCard: string) {
- return this.infoCard(infoCard).find('.card-text').text();
- }
-
- infoCardBody(infoCard: string) {
- return this.infoCard(infoCard).find('.card-text');
- }
-}
+++ /dev/null
-import { LanguagePageHelper } from './language.po';
-
-describe('Shared pages', () => {
- const language = new LanguagePageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- language.navigateTo();
- });
-
- it('should check default language', () => {
- language.getLanguageBtn().should('contain.text', 'English');
- });
-
- it('should check all available languages', () => {
- language.getLanguageBtn().click();
- language.getAllLanguages().should('have.length', 1).should('contain.text', 'English');
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class LanguagePageHelper extends PageHelper {
- pages = {
- index: { url: '#/dashboard', id: 'cd-dashboard' }
- };
-
- getLanguageBtn() {
- return cy.get('cd-language-selector a').first();
- }
-
- getAllLanguages() {
- return cy.get('cd-language-selector button');
- }
-}
+++ /dev/null
-import { LoginPageHelper } from './login.po';
-
-describe('Login page', () => {
- const login = new LoginPageHelper();
-
- it('should login and navigate to dashboard page', () => {
- login.navigateTo();
- login.doLogin();
- });
-
- it('should logout when clicking the button', () => {
- login.navigateTo();
- login.doLogin();
-
- login.doLogout();
- });
-
- it('should have no accessibility violations', () => {
- login.navigateTo();
- cy.injectAxe();
- cy.checkA11y();
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class LoginPageHelper extends PageHelper {
- pages = {
- index: { url: '#/login', id: 'cd-login' },
- dashboard: { url: '#/dashboard', id: 'cd-dashboard' }
- };
-
- doLogin() {
- cy.get('[name=username]').type('admin');
- cy.get('#password').type('admin');
- cy.get('[type=submit]').click();
- cy.get('cd-dashboard').should('exist');
- }
-
- doLogout() {
- cy.get('cd-identity a').click();
- cy.contains('cd-identity span', 'Sign out').click();
- cy.get('cd-login').should('exist');
- cy.location('hash').should('eq', '#/login');
- }
-}
+++ /dev/null
-import { NavigationPageHelper } from './navigation.po';
-
-describe('Shared pages', () => {
- const shared = new NavigationPageHelper();
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- shared.navigateTo();
- });
-
- it('should display the vertical menu by default', () => {
- shared.getVerticalMenu().should('not.have.class', 'active');
- });
-
- it('should hide the vertical menu', () => {
- shared.getMenuToggler().click();
- shared.getVerticalMenu().should('have.class', 'active');
- });
-
- it('should navigate to the correct page', () => {
- shared.checkNavigations(shared.navigations);
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class NavigationPageHelper extends PageHelper {
- pages = {
- index: { url: '#/dashboard', id: 'cd-dashboard' }
- };
-
- navigations = [
- { menu: 'NFS', component: 'cd-error' },
- {
- menu: 'Object Gateway',
- submenus: [
- { menu: 'Daemons', component: 'cd-rgw-daemon-list' },
- { menu: 'Users', component: 'cd-rgw-user-list' },
- { menu: 'Buckets', component: 'cd-rgw-bucket-list' }
- ]
- },
- { menu: 'Dashboard', component: 'cd-dashboard' },
- {
- menu: 'Cluster',
- submenus: [
- { menu: 'Hosts', component: 'cd-hosts' },
- { menu: 'Physical Disks', component: 'cd-error' },
- { menu: 'Monitors', component: 'cd-monitor' },
- { menu: 'Services', component: 'cd-error' },
- { menu: 'OSDs', component: 'cd-osd-list' },
- { menu: 'Configuration', component: 'cd-configuration' },
- { menu: 'CRUSH map', component: 'cd-crushmap' },
- { menu: 'Manager Modules', component: 'cd-mgr-module-list' },
- { menu: 'Ceph Users', component: 'cd-crud-table' },
- { menu: 'Logs', component: 'cd-logs' },
- { menu: 'Alerts', component: 'cd-prometheus-tabs' }
- ]
- },
- { menu: 'Pools', component: 'cd-pool-list' },
- {
- menu: 'Block',
- submenus: [
- { menu: 'Images', component: 'cd-error' },
- { menu: 'Mirroring', component: 'cd-mirroring' },
- { menu: 'iSCSI', component: 'cd-iscsi' }
- ]
- },
- { menu: 'File Systems', component: 'cd-cephfs-list' }
- ];
-
- getVerticalMenu() {
- return cy.get('nav[id=sidebar]');
- }
-
- getMenuToggler() {
- return cy.get('[aria-label="toggle sidebar visibility"]');
- }
-
- checkNavigations(navs: any) {
- // The nfs-ganesha, RGW, and block/rbd status requests are mocked to ensure that this method runs in time
- cy.intercept('/ui-api/nfs-ganesha/status', { fixture: 'nfs-ganesha-status.json' });
- cy.intercept('/ui-api/rgw/status', { fixture: 'rgw-status.json' });
- cy.intercept('/ui-api/block/rbd/status', { fixture: 'block-rbd-status.json' });
-
- navs.forEach((nav: any) => {
- cy.contains('.simplebar-content li.nav-item a', nav.menu).click();
- if (nav.submenus) {
- this.checkNavSubMenu(nav.menu, nav.submenus);
- } else {
- cy.get(nav.component).should('exist');
- }
- });
- }
-
- checkNavSubMenu(menu: any, submenu: any) {
- submenu.forEach((nav: any) => {
- cy.contains('.simplebar-content li.nav-item', menu).within(() => {
- cy.contains(`ul.list-unstyled li a`, nav.menu).click();
- });
- });
- }
-}
+++ /dev/null
-import { PoolPageHelper } from '../pools/pools.po';
-import { NotificationSidebarPageHelper } from './notification.po';
-
-describe('Notification page', () => {
- const notification = new NotificationSidebarPageHelper();
- const pools = new PoolPageHelper();
- const poolName = 'e2e_notification_pool';
-
- before(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- pools.navigateTo('create');
- pools.create(poolName, 8);
- pools.edit_pool_pg(poolName, 4, false);
- });
-
- after(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- pools.navigateTo();
- pools.delete(poolName);
- });
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- pools.navigateTo();
- });
-
- it('should open notification sidebar', () => {
- notification.getSidebar().should('not.be.visible');
- notification.open();
- notification.getSidebar().should('be.visible');
- });
-
- it('should display a running task', () => {
- notification.getToast().should('not.exist');
-
- // Check that running task is shown.
- notification.open();
- notification.getTasks().contains(poolName).should('exist');
-
- // Delete pool after task is complete (otherwise we get an error).
- notification.getTasks().contains(poolName, { timeout: 300000 }).should('not.exist');
- });
-
- it('should have notifications', () => {
- notification.open();
- notification.getNotifications().should('have.length.gt', 0);
- });
-
- it('should clear notifications', () => {
- notification.getToast().should('not.exist');
- notification.open();
- notification.getNotifications().should('have.length.gt', 0);
- notification.getClearNotficationsBtn().should('be.visible');
- notification.clearNotifications();
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class NotificationSidebarPageHelper extends PageHelper {
- getNotificatinoIcon() {
- return cy.get('cd-notifications a');
- }
-
- getSidebar() {
- return cy.get('cd-notifications-sidebar');
- }
-
- getTasks() {
- return this.getSidebar().find('.card.tc_task');
- }
-
- getNotifications() {
- return this.getSidebar().find('.card.tc_notification');
- }
-
- getClearNotficationsBtn() {
- return this.getSidebar().find('button.btn-block');
- }
-
- getCloseBtn() {
- return this.getSidebar().find('button.close');
- }
-
- open() {
- this.getNotificatinoIcon().click();
- this.getSidebar().should('be.visible');
- }
-
- clearNotifications() {
- // It can happen that although notifications are cleared, by the time we check the notifications
- // amount, another notification can appear, so we check it more than once (if needed).
- this.getClearNotficationsBtn().click();
- this.getNotifications()
- .should('have.length.gte', 0)
- .then(($elems) => {
- if ($elems.length > 0) {
- this.clearNotifications();
- }
- });
- }
-}
+++ /dev/null
-import { RoleMgmtPageHelper } from './role-mgmt.po';
-
-describe('Role Management page', () => {
- const roleMgmt = new RoleMgmtPageHelper();
- const role_name = 'e2e_role_mgmt_role';
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- roleMgmt.navigateTo();
- });
-
- describe('breadcrumb tests', () => {
- it('should check breadcrumb on roles tab on user management page', () => {
- roleMgmt.expectBreadcrumbText('Roles');
- });
-
- it('should check breadcrumb on role creation page', () => {
- roleMgmt.navigateTo('create');
- roleMgmt.expectBreadcrumbText('Create');
- });
- });
-
- describe('role create, edit & delete test', () => {
- it('should create a role', () => {
- roleMgmt.create(role_name, 'An interesting description');
- });
-
- it('should edit a role', () => {
- roleMgmt.edit(role_name, 'A far more interesting description');
- });
-
- it('should delete a role', () => {
- roleMgmt.delete(role_name);
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class RoleMgmtPageHelper extends PageHelper {
- pages = {
- index: { url: '#/user-management/roles', id: 'cd-role-list' },
- create: { url: '#/user-management/roles/create', id: 'cd-role-form' }
- };
-
- create(name: string, description: string) {
- this.navigateTo('create');
- // Waits for data to load
- cy.contains('grafana');
-
- // fill in fields
- cy.get('#name').type(name);
- cy.get('#description').type(description);
-
- // Click the create button and wait for role to be made
- cy.get('[data-cy=submitBtn]').click();
- cy.get('.breadcrumb-item.active').should('not.have.text', 'Create');
-
- this.getFirstTableCell(name).should('exist');
- }
-
- edit(name: string, description: string) {
- this.navigateEdit(name);
- // Waits for data to load
- cy.contains('grafana');
-
- // fill in fields with new values
- cy.get('#description').clear().type(description);
-
- // Click the edit button and check new values are present in table
- cy.get('[data-cy=submitBtn]').click();
- cy.get('.breadcrumb-item.active').should('not.have.text', 'Edit');
-
- this.getFirstTableCell(name).should('exist');
- this.getFirstTableCell(description).should('exist');
- }
-}
+++ /dev/null
-import { UserMgmtPageHelper } from './user-mgmt.po';
-
-describe('User Management page', () => {
- const userMgmt = new UserMgmtPageHelper();
- const user_name = 'e2e_user_mgmt_user';
-
- beforeEach(() => {
- cy.login();
- Cypress.Cookies.preserveOnce('token');
- userMgmt.navigateTo();
- });
-
- describe('breadcrumb tests', () => {
- it('should check breadcrumb on users tab of user management page', () => {
- userMgmt.expectBreadcrumbText('Users');
- });
-
- it('should check breadcrumb on user creation page', () => {
- userMgmt.navigateTo('create');
- userMgmt.expectBreadcrumbText('Create');
- });
- });
-
- describe('user create, edit & delete test', () => {
- it('should create a user', () => {
- userMgmt.create(user_name, 'cool_password', 'Jeff', 'realemail@realwebsite.com');
- });
-
- it('should edit a user', () => {
- userMgmt.edit(user_name, 'cool_password_number_2', 'Geoff', 'w@m');
- });
-
- it('should delete a user', () => {
- userMgmt.delete(user_name);
- });
- });
-});
+++ /dev/null
-import { PageHelper } from '../page-helper.po';
-
-export class UserMgmtPageHelper extends PageHelper {
- pages = {
- index: { url: '#/user-management/users', id: 'cd-user-list' },
- create: { url: '#/user-management/users/create', id: 'cd-user-form' }
- };
-
- create(username: string, password: string, name: string, email: string) {
- this.navigateTo('create');
-
- // fill in fields
- cy.get('#username').type(username);
- cy.get('#password').type(password);
- cy.get('#confirmpassword').type(password);
- cy.get('#name').type(name);
- cy.get('#email').type(email);
-
- // Click the create button and wait for user to be made
- cy.get('[data-cy=submitBtn]').click();
- this.getFirstTableCell(username).should('exist');
- }
-
- edit(username: string, password: string, name: string, email: string) {
- this.navigateEdit(username);
-
- // fill in fields with new values
- cy.get('#password').clear().type(password);
- cy.get('#confirmpassword').clear().type(password);
- cy.get('#name').clear().type(name);
- cy.get('#email').clear().type(email);
-
- // Click the edit button and check new values are present in table
- const editButton = cy.get('[data-cy=submitBtn]');
- editButton.click();
- this.getFirstTableCell(email).should('exist');
- this.getFirstTableCell(name).should('exist');
- }
-}
+++ /dev/null
-import { LoginPageHelper } from '../ui/login.po';
-
-describe('Dashboard Landing Page', () => {
- const login = new LoginPageHelper();
-
- beforeEach(() => {
- cy.eyesOpen({
- testName: 'Dashboard Component'
- });
- });
-
- afterEach(() => {
- cy.eyesClose();
- });
-
- it('should take screenshot of dashboard landing page', () => {
- login.navigateTo();
- login.doLogin();
- cy.get('[aria-label="Status card"]').should('be.visible');
- cy.get('[aria-label="Inventory card"]').should('be.visible');
- cy.get('[aria-label="Cluster utilization card"]').should('be.visible');
- cy.eyesCheckWindow({ tag: 'Dashboard landing page' });
- });
-});
+++ /dev/null
-describe('Login Page', () => {
- beforeEach(() => {
- cy.visit('#/login');
- cy.eyesOpen({
- appName: 'Ceph',
- testName: 'Login Component Check'
- });
- });
-
- afterEach(() => {
- cy.eyesClose();
- });
-
- it('types login credentials and takes screenshot', () => {
- cy.get('[name=username]').type('admin');
- cy.get('#password').type('admin');
- cy.eyesCheckWindow({ tag: 'Login Screen with credentials typed' });
- });
-});
};
Cypress.Commands.add('login', (username, password) => {
- requestAuth(username, password).then((resp) => {
- auth = resp.body;
- auth.permissions = JSON.stringify(new Permissions(auth.permissions));
- auth.pwdExpirationDate = String(auth.pwdExpirationDate);
- auth.pwdUpdateRequired = String(auth.pwdUpdateRequired);
- auth.sso = String(auth.sso);
- fillAuth();
+ cy.session([username, password], () => {
+ requestAuth(username, password).then((resp) => {
+ auth = resp.body;
+ auth.permissions = JSON.stringify(new Permissions(auth.permissions));
+ auth.pwdExpirationDate = String(auth.pwdExpirationDate);
+ auth.pwdUpdateRequired = String(auth.pwdUpdateRequired);
+ auth.sso = String(auth.sso);
+ fillAuth();
+ });
});
});
Cypress.Commands.add('ceph2Login', (username, password) => {
const url: string = Cypress.env('CEPH2_URL');
- requestAuth(username, password, url).then((resp) => {
- auth = resp.body;
- auth.permissions = JSON.stringify(new Permissions(auth.permissions));
- auth.pwdExpirationDate = String(auth.pwdExpirationDate);
- auth.pwdUpdateRequired = String(auth.pwdUpdateRequired);
- auth.sso = String(auth.sso);
- const args = {
- username: auth.username,
- permissions: auth.permissions,
- pwdExpirationDate: auth.pwdExpirationDate,
- pwdUpdateRequired: auth.pwdUpdateRequired,
- sso: auth.sso
- };
- // @ts-ignore
- cy.origin(
- url,
- { args },
- ({ uname, permissions, pwdExpirationDate, pwdUpdateRequired, sso }: any) => {
- window.localStorage.setItem('dashboard_username', uname);
- window.localStorage.setItem('dashboard_permissions', permissions);
- window.localStorage.setItem('user_pwd_expiration_date', pwdExpirationDate);
- window.localStorage.setItem('user_pwd_update_required', pwdUpdateRequired);
- window.localStorage.setItem('sso', sso);
- }
- );
+ cy.session([username, password, url], () => {
+ requestAuth(username, password, url).then((resp) => {
+ auth = resp.body;
+ auth.permissions = JSON.stringify(new Permissions(auth.permissions));
+ auth.pwdExpirationDate = String(auth.pwdExpirationDate);
+ auth.pwdUpdateRequired = String(auth.pwdUpdateRequired);
+ auth.sso = String(auth.sso);
+ const args = {
+ username: auth.username,
+ permissions: auth.permissions,
+ pwdExpirationDate: auth.pwdExpirationDate,
+ pwdUpdateRequired: auth.pwdUpdateRequired,
+ sso: auth.sso
+ };
+ // @ts-ignore
+ cy.origin(
+ url,
+ { args },
+ ({ uname, permissions, pwdExpirationDate, pwdUpdateRequired, sso }: any) => {
+ window.localStorage.setItem('dashboard_username', uname);
+ window.localStorage.setItem('dashboard_permissions', permissions);
+ window.localStorage.setItem('user_pwd_expiration_date', pwdExpirationDate);
+ window.localStorage.setItem('user_pwd_update_required', pwdUpdateRequired);
+ window.localStorage.setItem('sso', sso);
+ }
+ );
+ });
});
});
--- /dev/null
+import '@applitools/eyes-cypress/commands';
+import 'cypress-axe';
+
+import './commands';
+
+afterEach(() => {
+ cy.visit('#/403');
+});
+
+Cypress.on('uncaught:exception', (err: Error) => {
+ if (
+ err.message.includes('ResizeObserver loop limit exceeded') ||
+ err.message.includes('api/prometheus/rules') ||
+ err.message.includes('NG0100: ExpressionChangedAfterItHasBeenCheckedError')
+ ) {
+ return false;
+ }
+ return true;
+});
+++ /dev/null
-import '@applitools/eyes-cypress/commands';
-import 'cypress-axe';
-
-import './commands';
-
-afterEach(() => {
- cy.visit('#/403');
-});
-
-Cypress.on('uncaught:exception', (err: Error) => {
- if (
- err.message.includes('ResizeObserver loop limit exceeded') ||
- err.message.includes('api/prometheus/rules') ||
- err.message.includes('NG0100: ExpressionChangedAfterItHasBeenCheckedError')
- ) {
- return false;
- }
- return true;
-});
"requires": true,
"dependencies": {
"@aduh95/viz.js": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@aduh95/viz.js/-/viz.js-3.7.0.tgz",
- "integrity": "sha512-20Pk2Z98fbPLkECcrZSJszKos/OgtvJJR3NcbVfgCJ6EQjDNzW2P1BKqImOz3tJ952dvO2DWEhcLhQ1Wz1e9ng==",
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@aduh95/viz.js/-/viz.js-3.4.0.tgz",
+ "integrity": "sha512-KI2nVf9JdwWCXqK6RVf+9/096G7VWN4Z84mnynlyZKao2xQENW8WNEjLmvdlxS5X8PNWXFC1zqwm7tveOXw/4A==",
"dev": true
},
"@ampproject/remapping": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
- "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+ "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
"requires": {
- "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
}
},
"@angular-devkit/architect": {
- "version": "0.1303.9",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1303.9.tgz",
- "integrity": "sha512-RMHqCGDxbLqT+250A0a8vagsoTdqGjAxjhrvTeq7PJmClI7uJ/uA1Fs18+t85toIqVKn2hovdY9sNf42nBDD2Q==",
+ "version": "0.1303.11",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1303.11.tgz",
+ "integrity": "sha512-JwrWomNqNGjAeKlqV2pimUFlCgFxQy+Vioz9+QAPIrUkvvjbkQ1dZKOe8Ul8eosb1N3Ln282U6qzOpHKfJ4TOg==",
"dev": true,
"requires": {
- "@angular-devkit/core": "13.3.9",
+ "@angular-devkit/core": "13.3.11",
"rxjs": "6.6.7"
},
"dependencies": {
"webpack-subresource-integrity": "5.1.0"
},
"dependencies": {
- "@angular-devkit/architect": {
- "version": "0.1303.11",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1303.11.tgz",
- "integrity": "sha512-JwrWomNqNGjAeKlqV2pimUFlCgFxQy+Vioz9+QAPIrUkvvjbkQ1dZKOe8Ul8eosb1N3Ln282U6qzOpHKfJ4TOg==",
- "dev": true,
- "requires": {
- "@angular-devkit/core": "13.3.11",
- "rxjs": "6.6.7"
- }
- },
- "@angular-devkit/core": {
- "version": "13.3.11",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.11.tgz",
- "integrity": "sha512-rfqoLMRYhlz0wzKlHx7FfyIyQq8dKTsmbCoIVU1cEIH0gyTMVY7PbVzwRRcO6xp5waY+0hA+0Brriujpuhkm4w==",
+ "@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
"dev": true,
"requires": {
- "ajv": "8.9.0",
- "ajv-formats": "2.1.1",
- "fast-json-stable-stringify": "2.1.0",
- "magic-string": "0.25.7",
- "rxjs": "6.6.7",
- "source-map": "0.7.3"
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
}
},
"@babel/core": {
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
- "dev": true
}
}
},
"@babel/types": "^7.16.8",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
- "dev": true
- }
}
},
"@babel/runtime": {
"@babel/types": "^7.16.7"
}
},
+ "@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
"core-js": {
"version": "3.20.3",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz",
"integrity": "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==",
"dev": true
},
+ "esbuild": {
+ "version": "0.14.22",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.22.tgz",
+ "integrity": "sha512-CjFCFGgYtbFOPrwZNJf7wsuzesx8kqwAffOlbYcFDLFuUtP8xloK1GH+Ai13Qr0RZQf9tE7LMTHJ2iVGJ1SKZA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "esbuild-android-arm64": "0.14.22",
+ "esbuild-darwin-64": "0.14.22",
+ "esbuild-darwin-arm64": "0.14.22",
+ "esbuild-freebsd-64": "0.14.22",
+ "esbuild-freebsd-arm64": "0.14.22",
+ "esbuild-linux-32": "0.14.22",
+ "esbuild-linux-64": "0.14.22",
+ "esbuild-linux-arm": "0.14.22",
+ "esbuild-linux-arm64": "0.14.22",
+ "esbuild-linux-mips64le": "0.14.22",
+ "esbuild-linux-ppc64le": "0.14.22",
+ "esbuild-linux-riscv64": "0.14.22",
+ "esbuild-linux-s390x": "0.14.22",
+ "esbuild-netbsd-64": "0.14.22",
+ "esbuild-openbsd-64": "0.14.22",
+ "esbuild-sunos-64": "0.14.22",
+ "esbuild-windows-32": "0.14.22",
+ "esbuild-windows-64": "0.14.22",
+ "esbuild-windows-arm64": "0.14.22"
+ }
+ },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"lru-cache": "^6.0.0"
}
},
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "dev": true
+ },
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"rxjs": "6.6.7"
},
"dependencies": {
- "@angular-devkit/architect": {
- "version": "0.1303.11",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1303.11.tgz",
- "integrity": "sha512-JwrWomNqNGjAeKlqV2pimUFlCgFxQy+Vioz9+QAPIrUkvvjbkQ1dZKOe8Ul8eosb1N3Ln282U6qzOpHKfJ4TOg==",
- "dev": true,
- "requires": {
- "@angular-devkit/core": "13.3.11",
- "rxjs": "6.6.7"
- }
- },
- "@angular-devkit/core": {
- "version": "13.3.11",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.11.tgz",
- "integrity": "sha512-rfqoLMRYhlz0wzKlHx7FfyIyQq8dKTsmbCoIVU1cEIH0gyTMVY7PbVzwRRcO6xp5waY+0hA+0Brriujpuhkm4w==",
- "dev": true,
- "requires": {
- "ajv": "8.9.0",
- "ajv-formats": "2.1.1",
- "fast-json-stable-stringify": "2.1.0",
- "magic-string": "0.25.7",
- "rxjs": "6.6.7",
- "source-map": "0.7.3"
- }
- },
"rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
}
},
"@angular-devkit/core": {
- "version": "13.3.9",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.9.tgz",
- "integrity": "sha512-XqCuIWyoqIsLABjV3GQL/+EiBCt3xVPPtNp3Mg4gjBsDLW7PEnvbb81yGkiZQmIsq4EIyQC/6fQa3VdjsCshGg==",
+ "version": "13.3.11",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.11.tgz",
+ "integrity": "sha512-rfqoLMRYhlz0wzKlHx7FfyIyQq8dKTsmbCoIVU1cEIH0gyTMVY7PbVzwRRcO6xp5waY+0hA+0Brriujpuhkm4w==",
"dev": true,
"requires": {
"ajv": "8.9.0",
"rxjs": "6.6.7"
},
"dependencies": {
+ "@angular-devkit/core": {
+ "version": "13.3.9",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.9.tgz",
+ "integrity": "sha512-XqCuIWyoqIsLABjV3GQL/+EiBCt3xVPPtNp3Mg4gjBsDLW7PEnvbb81yGkiZQmIsq4EIyQC/6fQa3VdjsCshGg==",
+ "dev": true,
+ "requires": {
+ "ajv": "8.9.0",
+ "ajv-formats": "2.1.1",
+ "fast-json-stable-stringify": "2.1.0",
+ "magic-string": "0.25.7",
+ "rxjs": "6.6.7",
+ "source-map": "0.7.3"
+ }
+ },
"rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true
},
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
"tmp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
"uuid": "8.3.2"
},
"dependencies": {
+ "@angular-devkit/architect": {
+ "version": "0.1303.9",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1303.9.tgz",
+ "integrity": "sha512-RMHqCGDxbLqT+250A0a8vagsoTdqGjAxjhrvTeq7PJmClI7uJ/uA1Fs18+t85toIqVKn2hovdY9sNf42nBDD2Q==",
+ "dev": true,
+ "requires": {
+ "@angular-devkit/core": "13.3.9",
+ "rxjs": "6.6.7"
+ }
+ },
+ "@angular-devkit/core": {
+ "version": "13.3.9",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.9.tgz",
+ "integrity": "sha512-XqCuIWyoqIsLABjV3GQL/+EiBCt3xVPPtNp3Mg4gjBsDLW7PEnvbb81yGkiZQmIsq4EIyQC/6fQa3VdjsCshGg==",
+ "dev": true,
+ "requires": {
+ "ajv": "8.9.0",
+ "ajv-formats": "2.1.1",
+ "fast-json-stable-stringify": "2.1.0",
+ "magic-string": "0.25.7",
+ "rxjs": "6.6.7",
+ "source-map": "0.7.3"
+ }
+ },
"debug": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
"ms": "2.1.2"
}
},
+ "ini": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
+ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
+ "dev": true
+ },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"supports-preserve-symlinks-flag": "^1.0.0"
}
},
+ "rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"lru-cache": "^6.0.0"
}
},
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ },
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
"ms": "2.1.2"
}
},
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true
+ },
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"dev": true
},
"@babel/code-frame": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
- "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "version": "7.21.4",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz",
+ "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==",
"requires": {
"@babel/highlight": "^7.18.6"
}
},
"@babel/compat-data": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz",
- "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g=="
+ "version": "7.21.9",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.9.tgz",
+ "integrity": "sha512-FUGed8kfhyWvbYug/Un/VPJD41rDIgoVVcR+FuzhzOYyRz5uED+Gd3SLZml0Uw2l2aHFb7ZgdW5mGA3G2cCCnQ=="
},
"@babel/core": {
"version": "7.17.2",
}
},
"@babel/generator": {
- "version": "7.21.1",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz",
- "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==",
+ "version": "7.21.9",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.9.tgz",
+ "integrity": "sha512-F3fZga2uv09wFdEjEQIJxXALXfz0+JaOb7SabvVMmjHxeVTuGW8wgE8Vp1Hd7O+zMTYtcfEISGRzPkeiaPPsvg==",
"requires": {
- "@babel/types": "^7.21.0",
+ "@babel/types": "^7.21.5",
"@jridgewell/gen-mapping": "^0.3.2",
"@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
- },
- "dependencies": {
- "@jridgewell/gen-mapping": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
- "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
- "requires": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- }
- }
}
},
"@babel/helper-annotate-as-pure": {
}
},
"@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz",
- "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.21.5.tgz",
+ "integrity": "sha512-uNrjKztPLkUk7bpCNC0jEKDJzzkvel/W+HguzbN8krA+LPfC1CEobJEvAvGka2A/M+ViOqXdcRL0GqPUJSjx9g==",
"dev": true,
"requires": {
- "@babel/helper-explode-assignable-expression": "^7.18.6",
- "@babel/types": "^7.18.9"
+ "@babel/types": "^7.21.5"
}
},
"@babel/helper-compilation-targets": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
- "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz",
+ "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==",
"requires": {
- "@babel/compat-data": "^7.20.5",
- "@babel/helper-validator-option": "^7.18.6",
+ "@babel/compat-data": "^7.21.5",
+ "@babel/helper-validator-option": "^7.21.0",
"browserslist": "^4.21.3",
"lru-cache": "^5.1.1",
"semver": "^6.3.0"
}
},
"@babel/helper-create-class-features-plugin": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz",
- "integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==",
+ "version": "7.21.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.8.tgz",
+ "integrity": "sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-environment-visitor": "^7.21.5",
"@babel/helper-function-name": "^7.21.0",
- "@babel/helper-member-expression-to-functions": "^7.21.0",
+ "@babel/helper-member-expression-to-functions": "^7.21.5",
"@babel/helper-optimise-call-expression": "^7.18.6",
- "@babel/helper-replace-supers": "^7.20.7",
+ "@babel/helper-replace-supers": "^7.21.5",
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
- "@babel/helper-split-export-declaration": "^7.18.6"
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "semver": "^6.3.0"
},
"dependencies": {
"@babel/helper-annotate-as-pure": {
}
},
"@babel/helper-create-regexp-features-plugin": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz",
- "integrity": "sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==",
+ "version": "7.21.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.8.tgz",
+ "integrity": "sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.18.6",
- "regexpu-core": "^5.3.1"
+ "regexpu-core": "^5.3.1",
+ "semver": "^6.3.0"
},
"dependencies": {
"@babel/helper-annotate-as-pure": {
}
},
"@babel/helper-environment-visitor": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
- "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg=="
- },
- "@babel/helper-explode-assignable-expression": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz",
- "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==",
- "dev": true,
- "requires": {
- "@babel/types": "^7.18.6"
- }
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz",
+ "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ=="
},
"@babel/helper-function-name": {
"version": "7.21.0",
}
},
"@babel/helper-member-expression-to-functions": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz",
- "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.5.tgz",
+ "integrity": "sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==",
"dev": true,
"requires": {
- "@babel/types": "^7.21.0"
+ "@babel/types": "^7.21.5"
}
},
"@babel/helper-module-imports": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
- "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
+ "version": "7.21.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz",
+ "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==",
"requires": {
- "@babel/types": "^7.18.6"
+ "@babel/types": "^7.21.4"
}
},
"@babel/helper-module-transforms": {
- "version": "7.21.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz",
- "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz",
+ "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==",
"requires": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-simple-access": "^7.20.2",
+ "@babel/helper-environment-visitor": "^7.21.5",
+ "@babel/helper-module-imports": "^7.21.4",
+ "@babel/helper-simple-access": "^7.21.5",
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/helper-validator-identifier": "^7.19.1",
"@babel/template": "^7.20.7",
- "@babel/traverse": "^7.21.2",
- "@babel/types": "^7.21.2"
+ "@babel/traverse": "^7.21.5",
+ "@babel/types": "^7.21.5"
}
},
"@babel/helper-optimise-call-expression": {
}
},
"@babel/helper-plugin-utils": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
- "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz",
+ "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==",
"dev": true
},
"@babel/helper-remap-async-to-generator": {
}
},
"@babel/helper-replace-supers": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz",
- "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.21.5.tgz",
+ "integrity": "sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg==",
"dev": true,
"requires": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-member-expression-to-functions": "^7.20.7",
+ "@babel/helper-environment-visitor": "^7.21.5",
+ "@babel/helper-member-expression-to-functions": "^7.21.5",
"@babel/helper-optimise-call-expression": "^7.18.6",
"@babel/template": "^7.20.7",
- "@babel/traverse": "^7.20.7",
- "@babel/types": "^7.20.7"
+ "@babel/traverse": "^7.21.5",
+ "@babel/types": "^7.21.5"
}
},
"@babel/helper-simple-access": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
- "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz",
+ "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==",
"requires": {
- "@babel/types": "^7.20.2"
+ "@babel/types": "^7.21.5"
}
},
"@babel/helper-skip-transparent-expression-wrappers": {
}
},
"@babel/helper-string-parser": {
- "version": "7.19.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
- "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw=="
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz",
+ "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w=="
},
"@babel/helper-validator-identifier": {
"version": "7.19.1",
}
},
"@babel/helpers": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz",
- "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz",
+ "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==",
"requires": {
"@babel/template": "^7.20.7",
- "@babel/traverse": "^7.21.0",
- "@babel/types": "^7.21.0"
+ "@babel/traverse": "^7.21.5",
+ "@babel/types": "^7.21.5"
}
},
"@babel/highlight": {
}
},
"@babel/parser": {
- "version": "7.21.2",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz",
- "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ=="
+ "version": "7.21.9",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.9.tgz",
+ "integrity": "sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g=="
},
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
"version": "7.18.6",
}
},
"@babel/plugin-syntax-jsx": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
- "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+ "version": "7.21.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz",
+ "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
+ "@babel/helper-plugin-utils": "^7.20.2"
}
},
"@babel/plugin-syntax-logical-assignment-operators": {
}
},
"@babel/plugin-syntax-typescript": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz",
- "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==",
+ "version": "7.21.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz",
+ "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.19.0"
+ "@babel/helper-plugin-utils": "^7.20.2"
}
},
"@babel/plugin-transform-arrow-functions": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz",
- "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz",
+ "integrity": "sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.20.2"
+ "@babel/helper-plugin-utils": "^7.21.5"
}
},
"@babel/plugin-transform-async-to-generator": {
}
},
"@babel/plugin-transform-computed-properties": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz",
- "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz",
+ "integrity": "sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-plugin-utils": "^7.21.5",
"@babel/template": "^7.20.7"
}
},
"@babel/plugin-transform-destructuring": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz",
- "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==",
+ "version": "7.21.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz",
+ "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.20.2"
}
},
"@babel/plugin-transform-for-of": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz",
- "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz",
+ "integrity": "sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.20.2"
+ "@babel/helper-plugin-utils": "^7.21.5"
}
},
"@babel/plugin-transform-function-name": {
}
},
"@babel/plugin-transform-modules-commonjs": {
- "version": "7.21.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz",
- "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz",
+ "integrity": "sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ==",
"dev": true,
"requires": {
- "@babel/helper-module-transforms": "^7.21.2",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-simple-access": "^7.20.2"
+ "@babel/helper-module-transforms": "^7.21.5",
+ "@babel/helper-plugin-utils": "^7.21.5",
+ "@babel/helper-simple-access": "^7.21.5"
}
},
"@babel/plugin-transform-modules-systemjs": {
}
},
"@babel/plugin-transform-parameters": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz",
- "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==",
+ "version": "7.21.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz",
+ "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.20.2"
}
},
"@babel/plugin-transform-react-jsx": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz",
- "integrity": "sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.5.tgz",
+ "integrity": "sha512-ELdlq61FpoEkHO6gFRpfj0kUgSwQTGoaEU8eMRoS8Dv3v6e7BjEAj5WMtIBRdHUeAioMhKP5HyxNzNnP+heKbA==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-jsx": "^7.18.6",
- "@babel/types": "^7.21.0"
+ "@babel/helper-module-imports": "^7.21.4",
+ "@babel/helper-plugin-utils": "^7.21.5",
+ "@babel/plugin-syntax-jsx": "^7.21.4",
+ "@babel/types": "^7.21.5"
},
"dependencies": {
"@babel/helper-annotate-as-pure": {
}
},
"@babel/plugin-transform-regenerator": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz",
- "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz",
+ "integrity": "sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/helper-plugin-utils": "^7.21.5",
"regenerator-transform": "^0.15.1"
}
},
}
},
"@babel/plugin-transform-unicode-escapes": {
- "version": "7.18.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz",
- "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz",
+ "integrity": "sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.18.9"
+ "@babel/helper-plugin-utils": "^7.21.5"
}
},
"@babel/plugin-transform-unicode-regex": {
"dev": true
},
"@babel/runtime": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
- "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz",
+ "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
"requires": {
"regenerator-runtime": "^0.13.11"
}
},
"@babel/runtime-corejs3": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.21.0.tgz",
- "integrity": "sha512-TDD4UJzos3JJtM+tHX+w2Uc+KWj7GV+VKKFdMVd2Rx8sdA19hcc3P3AHFYd5LVOw+pYuSd5lICC3gm52B6Rwxw==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.21.5.tgz",
+ "integrity": "sha512-FRqFlFKNazWYykft5zvzuEl1YyTDGsIRrjV9rvxvYkUC7W/ueBng1X68Xd6uRMzAaJ0xMKn08/wem5YS1lpX8w==",
"requires": {
"core-js-pure": "^3.25.1",
"regenerator-runtime": "^0.13.11"
}
},
"@babel/template": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
- "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
+ "version": "7.21.9",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.21.9.tgz",
+ "integrity": "sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ==",
"requires": {
- "@babel/code-frame": "^7.18.6",
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7"
+ "@babel/code-frame": "^7.21.4",
+ "@babel/parser": "^7.21.9",
+ "@babel/types": "^7.21.5"
}
},
"@babel/traverse": {
- "version": "7.21.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz",
- "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz",
+ "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==",
"requires": {
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.21.1",
- "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/code-frame": "^7.21.4",
+ "@babel/generator": "^7.21.5",
+ "@babel/helper-environment-visitor": "^7.21.5",
"@babel/helper-function-name": "^7.21.0",
"@babel/helper-hoist-variables": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.21.2",
- "@babel/types": "^7.21.2",
+ "@babel/parser": "^7.21.5",
+ "@babel/types": "^7.21.5",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.21.2",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz",
- "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==",
+ "version": "7.21.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz",
+ "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==",
"requires": {
- "@babel/helper-string-parser": "^7.19.4",
+ "@babel/helper-string-parser": "^7.21.5",
"@babel/helper-validator-identifier": "^7.19.1",
"to-fast-properties": "^2.0.0"
}
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"@compodoc/ngd-core": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@compodoc/ngd-core/-/ngd-core-2.1.0.tgz",
- "integrity": "sha512-nyBH7J7SJJ2AV6OeZhJ02kRtVB7ALnZJKgShjoL9CNmOFEj8AkdhP9qTBIgjaDrbsW5pF4nx32KQL2fT7RFnqw==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@compodoc/ngd-core/-/ngd-core-2.1.1.tgz",
+ "integrity": "sha512-Z+wE6wWZYVnudRYg6qunDlyh3Orw39Ib66Gvrz5kX5u7So+iu3tr6sQJdqH6yGS3hAjig5avlfhWLlgsb6/x1Q==",
"dev": true,
"requires": {
- "ansi-colors": "^4.1.1",
- "fancy-log": "^1.3.3",
- "typescript": "^4.0.3"
+ "ansi-colors": "^4.1.3",
+ "fancy-log": "^2.0.0",
+ "typescript": "^5.0.4"
},
"dependencies": {
- "fancy-log": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
- "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
- "dev": true,
- "requires": {
- "ansi-gray": "^0.1.1",
- "color-support": "^1.1.3",
- "parse-node-version": "^1.0.0",
- "time-stamp": "^1.0.0"
- }
+ "ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true
+ },
+ "typescript": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
+ "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
+ "dev": true
}
}
},
"@compodoc/ngd-transformer": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@compodoc/ngd-transformer/-/ngd-transformer-2.1.0.tgz",
- "integrity": "sha512-Jo4VCMzIUtgIAdRmhHhOoRRE01gCjc5CyrUERRx0VgEzkkCm1Wmu/XHSsQP6tSpCYHBjERghqaDqH5DabkR2oQ==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@compodoc/ngd-transformer/-/ngd-transformer-2.1.3.tgz",
+ "integrity": "sha512-oWxJza7CpWR8/FeWYfE6j+jgncnGBsTWnZLt5rD2GUpsGSQTuGrsFPnmbbaVLgRS5QIVWBJYke7QFBr/7qVMWg==",
"dev": true,
"requires": {
- "@aduh95/viz.js": "^3.1.0",
- "@compodoc/ngd-core": "~2.1.0",
- "dot": "^1.1.3",
- "fs-extra": "^9.0.1"
+ "@aduh95/viz.js": "3.4.0",
+ "@compodoc/ngd-core": "~2.1.1",
+ "dot": "^2.0.0-beta.1",
+ "fs-extra": "^11.1.1"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "11.1.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz",
+ "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ }
}
},
"@csstools/postcss-progressive-custom-properties": {
}
},
"@csstools/selector-specificity": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz",
- "integrity": "sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz",
+ "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==",
"dev": true
},
"@cypress/browserify-preprocessor": {
"dev": true
},
"@esbuild/android-arm": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.10.tgz",
- "integrity": "sha512-7YEBfZ5lSem9Tqpsz+tjbdsEshlO9j/REJrfv4DXgKTt1+/MHqGwbtlyxQuaSlMeUZLxUKBaX8wdzlTfHkmnLw==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
+ "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
"dev": true,
"optional": true
},
"@esbuild/android-arm64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.10.tgz",
- "integrity": "sha512-ht1P9CmvrPF5yKDtyC+z43RczVs4rrHpRqrmIuoSvSdn44Fs1n6DGlpZKdK6rM83pFLbVaSUwle8IN+TPmkv7g==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
+ "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
"dev": true,
"optional": true
},
"@esbuild/android-x64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.10.tgz",
- "integrity": "sha512-CYzrm+hTiY5QICji64aJ/xKdN70IK8XZ6iiyq0tZkd3tfnwwSWTYH1t3m6zyaaBxkuj40kxgMyj1km/NqdjQZA==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
+ "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
"dev": true,
"optional": true
},
"@esbuild/darwin-arm64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.10.tgz",
- "integrity": "sha512-3HaGIowI+nMZlopqyW6+jxYr01KvNaLB5znXfbyyjuo4lE0VZfvFGcguIJapQeQMS4cX/NEispwOekJt3gr5Dg==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
+ "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==",
"dev": true,
"optional": true
},
"@esbuild/darwin-x64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.10.tgz",
- "integrity": "sha512-J4MJzGchuCRG5n+B4EHpAMoJmBeAE1L3wGYDIN5oWNqX0tEr7VKOzw0ymSwpoeSpdCa030lagGUfnfhS7OvzrQ==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
+ "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
"dev": true,
"optional": true
},
"@esbuild/freebsd-arm64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.10.tgz",
- "integrity": "sha512-ZkX40Z7qCbugeK4U5/gbzna/UQkM9d9LNV+Fro8r7HA7sRof5Rwxc46SsqeMvB5ZaR0b1/ITQ/8Y1NmV2F0fXQ==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
+ "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
"dev": true,
"optional": true
},
"@esbuild/freebsd-x64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.10.tgz",
- "integrity": "sha512-0m0YX1IWSLG9hWh7tZa3kdAugFbZFFx9XrvfpaCMMvrswSTvUZypp0NFKriUurHpBA3xsHVE9Qb/0u2Bbi/otg==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
+ "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-arm": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.10.tgz",
- "integrity": "sha512-whRdrrl0X+9D6o5f0sTZtDM9s86Xt4wk1bf7ltx6iQqrIIOH+sre1yjpcCdrVXntQPCNw/G+XqsD4HuxeS+2QA==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
+ "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
"dev": true,
"optional": true
},
"@esbuild/linux-arm64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.10.tgz",
- "integrity": "sha512-g1EZJR1/c+MmCgVwpdZdKi4QAJ8DCLP5uTgLWSAVd9wlqk9GMscaNMEViG3aE1wS+cNMzXXgdWiW/VX4J+5nTA==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
+ "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
"dev": true,
"optional": true
},
"@esbuild/linux-ia32": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.10.tgz",
- "integrity": "sha512-1vKYCjfv/bEwxngHERp7huYfJ4jJzldfxyfaF7hc3216xiDA62xbXJfRlradiMhGZbdNLj2WA1YwYFzs9IWNPw==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
+ "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-loong64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.10.tgz",
- "integrity": "sha512-mvwAr75q3Fgc/qz3K6sya3gBmJIYZCgcJ0s7XshpoqIAIBszzfXsqhpRrRdVFAyV1G9VUjj7VopL2HnAS8aHFA==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
+ "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-mips64el": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.10.tgz",
- "integrity": "sha512-XilKPgM2u1zR1YuvCsFQWl9Fc35BqSqktooumOY2zj7CSn5czJn279j9TE1JEqSqz88izJo7yE4x3LSf7oxHzg==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
+ "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
"dev": true,
"optional": true
},
"@esbuild/linux-ppc64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.10.tgz",
- "integrity": "sha512-kM4Rmh9l670SwjlGkIe7pYWezk8uxKHX4Lnn5jBZYBNlWpKMBCVfpAgAJqp5doLobhzF3l64VZVrmGeZ8+uKmQ==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
+ "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
"dev": true,
"optional": true
},
"@esbuild/linux-riscv64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.10.tgz",
- "integrity": "sha512-r1m9ZMNJBtOvYYGQVXKy+WvWd0BPvSxMsVq8Hp4GzdMBQvfZRvRr5TtX/1RdN6Va8JMVQGpxqde3O+e8+khNJQ==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
+ "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
"dev": true,
"optional": true
},
"@esbuild/linux-s390x": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.10.tgz",
- "integrity": "sha512-LsY7QvOLPw9WRJ+fU5pNB3qrSfA00u32ND5JVDrn/xG5hIQo3kvTxSlWFRP0NJ0+n6HmhPGG0Q4jtQsb6PFoyg==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
+ "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
"dev": true,
"optional": true
},
"@esbuild/linux-x64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.10.tgz",
- "integrity": "sha512-zJUfJLebCYzBdIz/Z9vqwFjIA7iSlLCFvVi7glMgnu2MK7XYigwsonXshy9wP9S7szF+nmwrelNaP3WGanstEg==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
+ "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==",
"dev": true,
"optional": true
},
"@esbuild/netbsd-x64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.10.tgz",
- "integrity": "sha512-lOMkailn4Ok9Vbp/q7uJfgicpDTbZFlXlnKT2DqC8uBijmm5oGtXAJy2ZZVo5hX7IOVXikV9LpCMj2U8cTguWA==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
+ "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
"dev": true,
"optional": true
},
"@esbuild/openbsd-x64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.10.tgz",
- "integrity": "sha512-/VE0Kx6y7eekqZ+ZLU4AjMlB80ov9tEz4H067Y0STwnGOYL8CsNg4J+cCmBznk1tMpxMoUOf0AbWlb1d2Pkbig==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
+ "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
"dev": true,
"optional": true
},
"@esbuild/sunos-x64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.10.tgz",
- "integrity": "sha512-ERNO0838OUm8HfUjjsEs71cLjLMu/xt6bhOlxcJ0/1MG3hNqCmbWaS+w/8nFLa0DDjbwZQuGKVtCUJliLmbVgg==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
+ "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
"dev": true,
"optional": true
},
"@esbuild/win32-arm64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.10.tgz",
- "integrity": "sha512-fXv+L+Bw2AeK+XJHwDAQ9m3NRlNemG6Z6ijLwJAAVdu4cyoFbBWbEtyZzDeL+rpG2lWI51cXeMt70HA8g2MqIg==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
+ "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
"dev": true,
"optional": true
},
"@esbuild/win32-ia32": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.10.tgz",
- "integrity": "sha512-3s+HADrOdCdGOi5lnh5DMQEzgbsFsd4w57L/eLKKjMnN0CN4AIEP0DCP3F3N14xnxh3ruNc32A0Na9zYe1Z/AQ==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
+ "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
"dev": true,
"optional": true
},
"@esbuild/win32-x64": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.10.tgz",
- "integrity": "sha512-oP+zFUjYNaMNmjTwlFtWep85hvwUu19cZklB3QsBOcZSs6y7hmH4LNCJ7075bsqzYaNvZFXJlAVaQ2ApITDXtw==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
+ "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
"dev": true,
"optional": true
},
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
}
}
},
}
},
"@types/node": {
- "version": "14.18.37",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.37.tgz",
- "integrity": "sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==",
+ "version": "14.18.47",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.47.tgz",
+ "integrity": "sha512-OuJi8bIng4wYHHA3YpKauL58dZrPxro3d0tabPHyiNF8rKfGKuVfr83oFlPLmKri1cX+Z3cJP39GXmnqkP11Gw==",
"dev": true
},
"ansi-styles": {
}
},
"@jridgewell/gen-mapping": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
- "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
"requires": {
- "@jridgewell/set-array": "^1.0.0",
- "@jridgewell/sourcemap-codec": "^1.4.10"
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
}
},
"@jridgewell/resolve-uri": {
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="
},
"@jridgewell/source-map": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
- "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz",
+ "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==",
"dev": true,
"requires": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
- },
- "dependencies": {
- "@jridgewell/gen-mapping": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
- "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
- "dev": true,
- "requires": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- }
- }
}
},
"@jridgewell/sourcemap-codec": {
- "version": "1.4.14",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
- "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"@jridgewell/trace-mapping": {
- "version": "0.3.17",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
- "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "version": "0.3.18",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz",
+ "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
"requires": {
"@jridgewell/resolve-uri": "3.1.0",
"@jridgewell/sourcemap-codec": "1.4.14"
+ },
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
+ }
}
},
"@juggle/resize-observer": {
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"@nrwl/cli": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/cli/-/cli-15.8.1.tgz",
- "integrity": "sha512-MB4anWQJ/yqKfusF2b+wYim2/aJGERcEkK/xT9Q7nXwJR/x76cIdggHz/C4zasFAjEHcilwajmF5chk0vArbkA==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/cli/-/cli-15.9.3.tgz",
+ "integrity": "sha512-qiAKHkov3iBx6hroPTitUrkRSUZFQqVgNJiF9gXRFC6pNJe9RS4rlmcIaoUFOboi9CnH5jwblNJVcz8YSVYOvA==",
"dev": true,
"requires": {
- "nx": "15.8.1"
+ "nx": "15.9.3"
},
"dependencies": {
"@nrwl/tao": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-15.8.1.tgz",
- "integrity": "sha512-wSoSTSF3tjVjNk6L1vtdSLHCIxEDl232aZN2LMpsVgU2yHnvrik2s9UJQrSDltsMM6vQ5VNKS5Li/AZWmfI79g==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-15.9.3.tgz",
+ "integrity": "sha512-NcjFCbuMa53C3fBrK7qLUImUBySyr9EVwmiZuAv9sZZtm4eILK8w3qihjrB4FFUuLjPU/SViriYXi+hF2tbP4w==",
"dev": true,
"requires": {
- "nx": "15.8.1"
+ "nx": "15.9.3"
}
},
"@zkochan/js-yaml": {
}
},
"fs-extra": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz",
- "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==",
+ "version": "11.1.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz",
+ "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.0",
}
},
"nx": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/nx/-/nx-15.8.1.tgz",
- "integrity": "sha512-aXFZw2KKf1wQOKmUod+Q6CEBStnu44P5FODOTZ5CRepmn6msFyvxtSwDgOflYW07VvZbNMuLT4mNWgDiQE0BbA==",
- "dev": true,
- "requires": {
- "@nrwl/cli": "15.8.1",
- "@nrwl/nx-darwin-arm64": "15.8.1",
- "@nrwl/nx-darwin-x64": "15.8.1",
- "@nrwl/nx-linux-arm-gnueabihf": "15.8.1",
- "@nrwl/nx-linux-arm64-gnu": "15.8.1",
- "@nrwl/nx-linux-arm64-musl": "15.8.1",
- "@nrwl/nx-linux-x64-gnu": "15.8.1",
- "@nrwl/nx-linux-x64-musl": "15.8.1",
- "@nrwl/nx-win32-arm64-msvc": "15.8.1",
- "@nrwl/nx-win32-x64-msvc": "15.8.1",
- "@nrwl/tao": "15.8.1",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/nx/-/nx-15.9.3.tgz",
+ "integrity": "sha512-GLwbykfTABc7/UZjQEEnV1bQbTVC53W+Zj4xWY640/45I4iZf/TUqKMBCgtLZ9v89gEsKOM4zsx55CqHT3bekA==",
+ "dev": true,
+ "requires": {
+ "@nrwl/cli": "15.9.3",
+ "@nrwl/nx-darwin-arm64": "15.9.3",
+ "@nrwl/nx-darwin-x64": "15.9.3",
+ "@nrwl/nx-linux-arm-gnueabihf": "15.9.3",
+ "@nrwl/nx-linux-arm64-gnu": "15.9.3",
+ "@nrwl/nx-linux-arm64-musl": "15.9.3",
+ "@nrwl/nx-linux-x64-gnu": "15.9.3",
+ "@nrwl/nx-linux-x64-musl": "15.9.3",
+ "@nrwl/nx-win32-arm64-msvc": "15.9.3",
+ "@nrwl/nx-win32-x64-msvc": "15.9.3",
+ "@nrwl/tao": "15.9.3",
"@parcel/watcher": "2.0.4",
"@yarnpkg/lockfile": "^1.1.0",
"@yarnpkg/parsers": "^3.0.0-rc.18",
}
},
"@nrwl/nx-darwin-arm64": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.8.1.tgz",
- "integrity": "sha512-nuubQcXVrxxxjpKHmfQ4bEgCwKsiey1/o9+FB98DoOv70Y2PuxMu/tjXbfNiJBFP72ySrrDmD/vRMKmduOsRSg==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.9.3.tgz",
+ "integrity": "sha512-2htJzVa+S/uLg5tj4nbO/tRz2SRMQIpT6EeWMgDGuEKQdpuRLVj2ez9hMpkRn9tl1tBUwR05hbV28DnOLRESVA==",
"dev": true,
"optional": true
},
"@nrwl/nx-darwin-x64": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.8.1.tgz",
- "integrity": "sha512-qYtTKFoq5i0mtulZs7eWXBFV5OhI/fnZ9RGSD/mPoFt4cHV0MAgqIafiGpQ+Py/a36gIIfdR5U9MLyMRLOMNUQ==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.9.3.tgz",
+ "integrity": "sha512-p+8UkfC6KTLOX4XRt7NSP8DoTzEgs73+SN0csoXT9VsNO35+F0Z5zMZxpEc7RVo5Wen/4PGh2OWA+8gtgntsJQ==",
"dev": true,
"optional": true
},
"@nrwl/nx-linux-arm-gnueabihf": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.8.1.tgz",
- "integrity": "sha512-m4lX38fcrhyzG8K+4Ds8StCIQ0hHxRFFeFUMMR3ZR/RYpGwO5nRcF22l4gRm9DnsL48Vv8qjZ7v9bTNKiD2O7g==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.9.3.tgz",
+ "integrity": "sha512-xwW7bZtggrxhFbYvvWWArtcSWwoxWzi/4wNgP3wPbcZFNZiraahVQSpIyJXrS9aajGbdvuDBM8cbDsMj9v7mwg==",
"dev": true,
"optional": true
},
"@nrwl/nx-linux-arm64-gnu": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.8.1.tgz",
- "integrity": "sha512-nCiObtfk/TBPblhMx7IG5jchgPg9RL5wE38GNf/yl1jjfRTfkvwrS+c0T5VyEBoUjGw7KDlZ/7CY0RBN+usdUg==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.9.3.tgz",
+ "integrity": "sha512-KNxDL2OAHxhFqztEjv2mNwXD6xrzoUury7NsYZYqlxJUNc3YYBfRSLEatnw491crvMBndbxfGVTWEO9S4YmRuw==",
"dev": true,
"optional": true
},
"@nrwl/nx-linux-arm64-musl": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.8.1.tgz",
- "integrity": "sha512-7AguRwMwdNYtYnThm3jMqIaqhA03cJztZqIgxvWwJpbteBANfa6+HtTUeCwN27elHCmSex301Q9K8cIY8irtmg==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.9.3.tgz",
+ "integrity": "sha512-AxoZzfsXH7ZqDE+WrQtRumufIcSIBw4U/LikiDLaWWoGtNpAfKLkD/PHirZiNxHIeGy1Toi4ccMUolXbafLVFw==",
"dev": true,
"optional": true
},
"@nrwl/nx-linux-x64-gnu": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.8.1.tgz",
- "integrity": "sha512-GkJaYuGhW1P9FF8YLMjs6VnMSXZmJz6z0Bsv6GxtZ+6f0W9fOEzoSpXBmPF8aXi3z02uRPAgJC9iKeRh3Xmkdg==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.9.3.tgz",
+ "integrity": "sha512-P8AOPRufvV4a5cSczNsw84zFAI7NgAiEBTybYcyymdNJmo0iArJXEmvj/G4mB20O8VCsCkwqMYAu6nQEnES1Kw==",
"dev": true,
"optional": true
},
"@nrwl/nx-linux-x64-musl": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.8.1.tgz",
- "integrity": "sha512-YQNoPlKLVzvkxn4F3Pc5/wMc7FKoe9mAAME0KjL9DNAYGvOLHSO5fc82a+f0nIOflXlwBusnC/HiGUkcvD+Qxg==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.9.3.tgz",
+ "integrity": "sha512-4ZYDp7T319+xbw7Z7KVtRefzaXJipZfgrM49r+Y1FAfYDc8y18zvKz3slK26wfWz+EUZwKsa/DfA2KmyRG3DvQ==",
"dev": true,
"optional": true
},
"@nrwl/nx-win32-arm64-msvc": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.8.1.tgz",
- "integrity": "sha512-g/zqZpVvmYt8/SjYjKkOxogMzL4XCjoRImXEBAW4t8+SIacLmZt+Rt8BCY1aqcb2TCSLwrZevPyvQGfTa6zfuA==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.9.3.tgz",
+ "integrity": "sha512-UhgxIPgTZBKN1oxlLPSklkSzVL3hA4lAiVc9A0Utumpbp0ob/Xx+2vHzg3cnmNH3jWkZ+9OsC2dKyeMB6gAbSw==",
"dev": true,
"optional": true
},
"@nrwl/nx-win32-x64-msvc": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.8.1.tgz",
- "integrity": "sha512-obgXvryiY5IuvIIojLatGCB9gbzgG8LwlxpcqIIb/ywJ7K6ai74kNRdegPCjlsyca8MZSWqGncI0Hwo5fcGaDQ==",
+ "version": "15.9.3",
+ "resolved": "https://registry.npmjs.org/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.9.3.tgz",
+ "integrity": "sha512-gdnvqURKnu0EQGOFJ6NUKq6wSB+viNb7Z8qtKhzSmFwVjT8akOnLWn7ZhL9v28TAjLM7/s1Mwvmz/IMj1PGlcQ==",
"dev": true,
"optional": true
},
"@angular-devkit/core": "13.3.9",
"@angular-devkit/schematics": "13.3.9",
"jsonc-parser": "3.0.0"
- }
- },
- "@sideway/address": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
- "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
- "dev": true,
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "@sideway/formula": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
- "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
- "dev": true
- },
- "@sideway/pinpoint": {
- "version": "2.0.0",
+ },
+ "dependencies": {
+ "@angular-devkit/core": {
+ "version": "13.3.9",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.9.tgz",
+ "integrity": "sha512-XqCuIWyoqIsLABjV3GQL/+EiBCt3xVPPtNp3Mg4gjBsDLW7PEnvbb81yGkiZQmIsq4EIyQC/6fQa3VdjsCshGg==",
+ "dev": true,
+ "requires": {
+ "ajv": "8.9.0",
+ "ajv-formats": "2.1.1",
+ "fast-json-stable-stringify": "2.1.0",
+ "magic-string": "0.25.7",
+ "rxjs": "6.6.7",
+ "source-map": "0.7.3"
+ }
+ },
+ "rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "@sideway/address": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
+ "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
+ "dev": true,
+ "requires": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "@sideway/formula": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
+ "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
+ "dev": true
+ },
+ "@sideway/pinpoint": {
+ "version": "2.0.0",
"resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
"dev": true
},
"dependencies": {
"@babel/core": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz",
- "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==",
+ "version": "7.21.8",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz",
+ "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==",
"dev": true,
"requires": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.21.0",
- "@babel/helper-compilation-targets": "^7.20.7",
- "@babel/helper-module-transforms": "^7.21.0",
- "@babel/helpers": "^7.21.0",
- "@babel/parser": "^7.21.0",
+ "@babel/code-frame": "^7.21.4",
+ "@babel/generator": "^7.21.5",
+ "@babel/helper-compilation-targets": "^7.21.5",
+ "@babel/helper-module-transforms": "^7.21.5",
+ "@babel/helpers": "^7.21.5",
+ "@babel/parser": "^7.21.8",
"@babel/template": "^7.20.7",
- "@babel/traverse": "^7.21.0",
- "@babel/types": "^7.21.0",
+ "@babel/traverse": "^7.21.5",
+ "@babel/types": "^7.21.5",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
"unist-util-find-all-after": "^3.0.2"
}
},
+ "@swagger-api/apidom-ast": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.69.3.tgz",
+ "integrity": "sha512-orGw/gihk7RmorxibwalthDS58B7QaEBd31fK+/aFx6QqEO1tEO35F850BiL2B5C8TaK8C2Tey01AZTXCxYmfw==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2",
+ "unraw": "=2.0.1"
+ }
+ },
+ "@swagger-api/apidom-core": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.69.3.tgz",
+ "integrity": "sha512-EIQiJUuT/V9nGkHOYYFP0QNgAW7Y4QwrQzldDzy9ltcHbOKY3TNh/QzYvO0+HvKSv9W7u7WTMH/kaRaSsaZsGw==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-ast": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "minim": "=0.23.8",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "short-unique-id": "=4.4.4",
+ "stampit": "=4.3.2"
+ }
+ },
+ "@swagger-api/apidom-json-pointer": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-0.69.3.tgz",
+ "integrity": "sha512-VYXqLY8f2fkaS/d+vVQEMEOEZRXAgGm5tCMx4C7uaU+wC+SKPH/zTh+qElbkaXQr4nfLjbphBsHh31doCyBEjw==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0"
+ }
+ },
+ "@swagger-api/apidom-ns-api-design-systems": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-0.69.3.tgz",
+ "integrity": "sha512-oTwIG8LyKnU4/m8BtAOc+X572+nH4gjxITYtw0L8f4a8Iv1b8LHS0KRzG7c/LVUGtMijpv3aBKPV6QvWhjrrtg==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-openapi-3-1": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2"
+ }
+ },
+ "@swagger-api/apidom-ns-asyncapi-2": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-0.69.3.tgz",
+ "integrity": "sha512-98HgNbZWqPHqf+EyXs/GcAnayA08/mfN7YlXIRRIys+rll4M/1b+ap+BkTnJ+le3Kra7DhIQ8ucQuEJ+Ik1Sxg==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-json-schema-draft-7": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2"
+ }
+ },
+ "@swagger-api/apidom-ns-json-schema-draft-4": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-0.69.3.tgz",
+ "integrity": "sha512-/tMeoz1IHEblc3OwWC812NQFLITOnexjGVujG5Wvsr9ZnTkRb+0g7CbXuooujwfcEY+++o2+kCUgy4SBQFIIlQ==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2"
+ }
+ },
+ "@swagger-api/apidom-ns-json-schema-draft-6": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-0.69.3.tgz",
+ "integrity": "sha512-B/6zPFYW1xE66Uc/jOdZVZMEe0+444heTMlpGJGejTy6pNRxCTOsv+B63QzctJv410dHPxGeMRZMeff9wQPBDA==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-json-schema-draft-4": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2"
+ }
+ },
+ "@swagger-api/apidom-ns-json-schema-draft-7": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-0.69.3.tgz",
+ "integrity": "sha512-EkgPlKPQZ3XBkbxAFh2lXsLcyIwRikARFD3RlupsKjAHVFbH7cImbPxb+MnjacfwgVreMk34OWuXqjnGZ8lG1Q==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-json-schema-draft-6": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2"
+ }
+ },
+ "@swagger-api/apidom-ns-openapi-3-0": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-0.69.3.tgz",
+ "integrity": "sha512-iScwP+SzX8SJMrgChZbdS60Ode/zXfesNaDA+HkNBLbfSrri4/C5FTB0gfWOG0gCGPq+1K5dHlgLrEgogfAARw==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-json-schema-draft-4": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2"
+ }
+ },
+ "@swagger-api/apidom-ns-openapi-3-1": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-0.69.3.tgz",
+ "integrity": "sha512-J+yIsTBTn7rzfj+vaCXRRdOCrL4kxwnS3P/h4lXb82EZnPU/EbJi+C0LK7O24/vXpeBVRr+OpDfnhpospanMJg==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-openapi-3-0": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-api-design-systems-json": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-0.69.3.tgz",
+ "integrity": "sha512-y8xOaSaZVphITajH12T1EHLuZB9kw79DTdQRYoMC+BqZQbsPv3/mLWXS1STQU9oR/PZBA9FJcgAFdThaRgi8UA==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-api-design-systems": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-json": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-0.69.3.tgz",
+ "integrity": "sha512-zMc+Dy7zl7cT8YduaUEpvLkRDVfZp8jZ1v13VjueX/VhsSXK0DW+OX/Mc8CU1Qx6Gg6tUMKxqmILdXZwxCrh6Q==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-api-design-systems": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-asyncapi-json-2": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-0.69.3.tgz",
+ "integrity": "sha512-BbsBxxZxTMX2rKgVKJtqPoAsER0JvCe1pt3NUBLuQssugvpwaqimIsKC65dwspHFGSn0CVdBKA4n/XhZ3aT7tw==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-asyncapi-2": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-json": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-0.69.3.tgz",
+ "integrity": "sha512-lae39qaKrkls+iVzYuc9CUyCbRl80wNK8iBWriSVETv5IwlVS6wywtTxCqtzcpd5K+m9KqXAlSkd+Z2AS9cWuQ==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-asyncapi-2": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-json": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-0.69.3.tgz",
+ "integrity": "sha512-Z1CqG9OcV4WVESdQ1D0s5JUa2jeF8hpw4RupMDJ4lRoKTVeIDS5Qb7OOhIGeKpK2DgMep9SN2ULYJdgldPtq/A==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-ast": "^0.69.3",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2",
+ "tree-sitter": "=0.20.1",
+ "tree-sitter-json": "=0.20.0",
+ "web-tree-sitter": "=0.20.7"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-openapi-json-3-0": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-0.69.3.tgz",
+ "integrity": "sha512-f5Xby5hAGy4VujkV74UA61UkSVRsNzhcBaW0IIapVVepFEclfU7J3dGvfkMIXv5Bg0infGeKddIUZUY61JN88w==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-openapi-3-0": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-json": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-openapi-json-3-1": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-0.69.3.tgz",
+ "integrity": "sha512-Yq3k/d89Nmf+ePD5EIIkhXNti2Ru5XMqOXDbNQGKHH00e252Q+c+QF2A7Pgdy0xP3oA9OoYTGHLtL0ncmzYB9A==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-openapi-3-1": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-json": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-0.69.3.tgz",
+ "integrity": "sha512-X4Qtg/0n0l2leWBBZC8+7Kj6eP3pqB4WCWlacoWuldz8WBDBuffTBmTV/qe6gKdI4DW6mX5ovxDf+tz2tr0ppQ==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-openapi-3-0": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-0.69.3.tgz",
+ "integrity": "sha512-ZW/2T92HZT2RQOPW1VOa78VyDYD5wwR9EGNKXBsfMCnl0zVHwhwwkn/GgsYS0VDk56t43ww5DHM976q4ukF6Ew==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-ns-openapi-3-1": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0"
+ }
+ },
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-0.69.3.tgz",
+ "integrity": "sha512-HJ/OiXnVoUshwKrfaHDq4LfKeKxBsa6Bmo8NVdSZiRfeA1Y/fAx9mWW5xSzTADxmc6yA2MevnfIoq7W0NX6SSQ==",
+ "optional": true,
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-ast": "^0.69.3",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2",
+ "tree-sitter": "=0.20.1",
+ "tree-sitter-yaml": "=0.5.0",
+ "web-tree-sitter": "=0.20.7"
+ }
+ },
+ "@swagger-api/apidom-reference": {
+ "version": "0.69.3",
+ "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-0.69.3.tgz",
+ "integrity": "sha512-dimoVsW4COR4TUTgOqTnXSZAIdYOepIudWOvca2fGOcXg85eBMS4xJlNHx1095Fm664y5y8DVxIYe1oLu9gjVA==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.7",
+ "@swagger-api/apidom-core": "^0.69.3",
+ "@swagger-api/apidom-json-pointer": "^0.69.3",
+ "@swagger-api/apidom-ns-asyncapi-2": "^0.69.3",
+ "@swagger-api/apidom-ns-openapi-3-0": "^0.69.3",
+ "@swagger-api/apidom-ns-openapi-3-1": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-json": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^0.69.3",
+ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.69.3",
+ "@types/ramda": "=0.29.0",
+ "axios": "=1.3.6",
+ "minimatch": "=7.4.3",
+ "process": "=0.11.10",
+ "ramda": "=0.29.0",
+ "ramda-adjunct": "=4.0.0",
+ "stampit": "=4.3.2"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "minimatch": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.3.tgz",
+ "integrity": "sha512-5UB4yYusDtkRPbRiy1cqZ1IpGNcJCGlEMG17RKzPddpyiPKoCdwohbED8g4QXT0ewCt8LTkQXuljsUfQ3FKM4A==",
+ "requires": {
+ "brace-expansion": "^2.0.1"
+ }
+ }
+ }
+ },
"@swimlane/ngx-datatable": {
"version": "18.0.0",
"resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-18.0.0.tgz",
}
},
"@types/babel__traverse": {
- "version": "7.18.3",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
- "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
+ "version": "7.18.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.5.tgz",
+ "integrity": "sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q==",
"dev": true,
"requires": {
"@babel/types": "^7.3.0"
}
},
"@types/connect-history-api-fallback": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz",
- "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz",
+ "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==",
"dev": true,
"requires": {
"@types/express-serve-static-core": "*",
"dev": true
},
"@types/eslint": {
- "version": "8.21.2",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.2.tgz",
- "integrity": "sha512-EMpxUyystd3uZVByZap1DACsMXvb82ypQnGn89e1Y0a+LYu3JJscUd/gqhRsVFDkaD2MIiWo0MT8EfXr3DGRKw==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.0.tgz",
+ "integrity": "sha512-nbq2mvc/tBrK9zQQuItvjJl++GTN5j06DaPtp3hZCpngmG6Q3xoyEmd0TwZI0gAy/G1X0zhGBbr2imsGFdFV0g==",
"dev": true,
"requires": {
"@types/estree": "*",
}
},
"@types/express-serve-static-core": {
- "version": "4.17.33",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz",
- "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==",
+ "version": "4.17.35",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz",
+ "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==",
"dev": true,
"requires": {
"@types/node": "*",
"@types/qs": "*",
- "@types/range-parser": "*"
+ "@types/range-parser": "*",
+ "@types/send": "*"
}
},
"@types/file-saver": {
}
},
"@types/http-proxy": {
- "version": "1.17.10",
- "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.10.tgz",
- "integrity": "sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g==",
+ "version": "1.17.11",
+ "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz",
+ "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==",
"dev": true,
"requires": {
"@types/node": "*"
"dev": true
},
"@types/mdast": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz",
- "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==",
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz",
+ "integrity": "sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==",
"dev": true,
"requires": {
"@types/unist": "*"
}
},
"@types/mime": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
- "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
+ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
"dev": true
},
"@types/minimatch": {
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
"dev": true
},
+ "@types/ramda": {
+ "version": "0.29.0",
+ "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.0.tgz",
+ "integrity": "sha512-TY9eKsklU43CmAbFJPKDUyBjleZ4EFAkbJeQRF4e8byGkOw1CjDcwg5EGa0Bgf0Kgs9BE9OU4UzQWnQDHnvMtA==",
+ "requires": {
+ "types-ramda": "^0.29.1"
+ }
+ },
"@types/range-parser": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
"dev": true
},
"@types/react": {
- "version": "18.0.28",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz",
- "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==",
+ "version": "18.2.6",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.6.tgz",
+ "integrity": "sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA==",
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"dev": true
},
"@types/scheduler": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
- "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ "version": "0.16.3",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
+ "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
+ },
+ "@types/send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==",
+ "dev": true,
+ "requires": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
},
"@types/serve-index": {
"version": "1.9.1",
}
},
"@types/yargs": {
- "version": "17.0.22",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz",
- "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==",
+ "version": "17.0.24",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
+ "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
"dev": true
},
"@yarnpkg/parsers": {
- "version": "3.0.0-rc.39",
- "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.39.tgz",
- "integrity": "sha512-BsD4zq3EVmaHqlynXTceNuEFAtrfToV4fI9GA54moKlWZL4Eb2eXrhgf1jV2nMYx18SZxYO4Jc5Kf1sCDNRjOg==",
+ "version": "3.0.0-rc.44",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.44.tgz",
+ "integrity": "sha512-UVAt9Icc8zfGXioeYJ8XMoSTxOYVmlal2TRNxy9Uh91taS72kQFalK7LpIslcvEBKy4XtarmfIwcFIU3ZY64lw==",
"dev": true,
"requires": {
"js-yaml": "^3.10.0",
}
},
"tslib": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
- "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
+ "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==",
"dev": true
}
}
}
},
"acorn-import-assertions": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
- "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
"dev": true
},
"acorn-jsx": {
}
},
"agentkeepalive": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
- "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz",
+ "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==",
"dev": true,
"requires": {
"debug": "^4.1.0",
- "depd": "^1.1.2",
+ "depd": "^2.0.0",
"humanize-ms": "^1.2.1"
- },
- "dependencies": {
- "depd": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
- "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
- "dev": true
- }
}
},
"aggregate-error": {
}
}
},
- "ansi-gray": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
- "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==",
- "dev": true,
- "requires": {
- "ansi-wrap": "0.1.0"
- }
- },
"ansi-html-community": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
"color-convert": "^1.9.0"
}
},
- "ansi-wrap": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
- "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==",
- "dev": true
- },
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
"dev": true
},
"aproba": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
- "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
- "dev": true
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
},
"arch": {
"version": "2.2.0",
"dev": true
},
"are-we-there-yet": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
- "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
- "dev": true,
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
+ "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
+ "optional": true,
"requires": {
"delegates": "^1.0.0",
- "readable-stream": "^3.6.0"
+ "readable-stream": "^2.0.6"
}
},
"arg": {
"integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==",
"dev": true
},
+ "array-buffer-byte-length": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
+ "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "is-array-buffer": "^3.0.1"
+ }
+ },
"array-differ": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "dev": true
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"at-least-node": {
"version": "1.0.0",
"normalize-range": "^0.1.2",
"picocolors": "^1.0.0",
"postcss-value-parser": "^4.2.0"
- },
- "dependencies": {
- "caniuse-lite": {
- "version": "1.0.30001467",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001467.tgz",
- "integrity": "sha512-cEdN/5e+RPikvl9AHm4uuLXxeCNq8rFsQ+lPHTfe/OtypP3WwnVVbjn+6uBV7PaFL6xUFzTh+sSCOz1rKhcO+Q==",
- "dev": true
- }
}
},
"available-typed-arrays": {
"dev": true
},
"axios": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz",
- "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==",
- "dev": true,
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.6.tgz",
+ "integrity": "sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "dev": true,
"requires": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
}
},
"blink-diff": {
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
+ },
+ "qs": {
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+ "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "dev": true,
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
}
}
},
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
"integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
"dev": true
- },
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- },
- "dependencies": {
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
}
}
},
"parse-asn1": "^5.1.5",
"readable-stream": "^3.6.0",
"safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
}
},
"browserify-zlib": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "dev": true,
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
"unique-filename": "^1.1.1"
},
"dependencies": {
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true
+ },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-ceOhN1DL7Y4O6M0j9ICgmTYziV89WMd96SvSl0REd8PMgrY0B/WBOPoed5S1KUmJqXgUXh8gzSe6E3ae27upsQ=="
},
"caniuse-lite": {
- "version": "1.0.30001458",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz",
- "integrity": "sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w=="
+ "version": "1.0.30001489",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001489.tgz",
+ "integrity": "sha512-x1mgZEXK8jHIfAxm+xgdpHpk50IN3z3q3zP261/WS+uvePxW8izXuCu6AHz0lkuYTlATDehiZ/tNyYBdSQsOUQ=="
},
"caseless": {
"version": "0.12.0",
}
},
"domutils": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
- "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dev": true,
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
- "domhandler": "^5.0.1"
+ "domhandler": "^5.0.3"
}
},
"entities": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
- "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true
},
"parse5": {
}
},
"domutils": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
- "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dev": true,
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
- "domhandler": "^5.0.1"
+ "domhandler": "^5.0.3"
}
},
"entities": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
- "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true
}
}
}
},
"chownr": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
- "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
- "dev": true
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "optional": true
},
"chrome-remote-interface": {
"version": "0.31.1",
}
},
"cli-spinners": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz",
- "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==",
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz",
+ "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==",
"dev": true
},
"cli-table": {
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
- "dev": true
+ "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA=="
},
"coffeeify": {
"version": "3.0.1",
"dev": true
},
"colorette": {
- "version": "2.0.19",
- "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
- "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==",
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
"dev": true
},
"colors": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
"requires": {
"delayed-stream": "~1.0.0"
}
"inherits": "^2.0.3",
"readable-stream": "^2.2.2",
"typedarray": "^0.0.6"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
}
},
"connect": {
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
- "dev": true
+ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
},
"constants-browserify": {
"version": "1.0.0",
}
},
"schema-utils": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
- "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz",
+ "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
- "ajv": "^8.8.0",
+ "ajv": "^8.9.0",
"ajv-formats": "^2.1.1",
- "ajv-keywords": "^5.0.0"
+ "ajv-keywords": "^5.1.0"
}
}
}
},
"core-js": {
- "version": "3.29.0",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.29.0.tgz",
- "integrity": "sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg=="
+ "version": "3.30.2",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz",
+ "integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg=="
},
"core-js-compat": {
- "version": "3.29.0",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.29.0.tgz",
- "integrity": "sha512-ScMn3uZNAFhK2DGoEfErguoiAHhV2Ju+oJo/jK08p7B3f3UhocUrCCkTvnZaiS+edl5nlIoiBXKcwMc6elv4KQ==",
+ "version": "3.30.2",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.2.tgz",
+ "integrity": "sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==",
"dev": true,
"requires": {
"browserslist": "^4.21.5"
}
},
"core-js-pure": {
- "version": "3.29.0",
- "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.29.0.tgz",
- "integrity": "sha512-v94gUjN5UTe1n0yN/opTihJ8QBWD2O8i19RfTZR7foONPWArnjB96QA/wk5ozu1mm6ja3udQCzOzwQXTxi3xOQ=="
+ "version": "3.30.2",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.30.2.tgz",
+ "integrity": "sha512-p/npFUJXXBkCCTIlEGBdghofn00jWG6ZOtdoIXSJmAu2QBvN0IqpZXWweOytcwE6cfx8ZvVUy1vw8zxhe4Y2vg=="
},
"core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
- "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
- "dev": true
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"cors": {
"version": "2.8.5",
}
},
"cross-fetch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
- "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz",
+ "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==",
"requires": {
- "node-fetch": "2.6.7"
+ "node-fetch": "^2.6.11"
}
},
"cross-spawn": {
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"csstype": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
- "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
},
"cucumber": {
"version": "4.2.1",
"dev": true
},
"cypress": {
- "version": "9.7.0",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.7.0.tgz",
- "integrity": "sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==",
+ "version": "10.11.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.11.0.tgz",
+ "integrity": "sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==",
"dev": true,
"requires": {
"@cypress/request": "^2.88.10",
"dayjs": "^1.10.4",
"debug": "^4.3.2",
"enquirer": "^2.3.6",
- "eventemitter2": "^6.4.3",
+ "eventemitter2": "6.4.7",
"execa": "4.1.0",
"executable": "^4.1.1",
"extract-zip": "2.0.1",
},
"dependencies": {
"@types/node": {
- "version": "14.18.37",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.37.tgz",
- "integrity": "sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==",
+ "version": "14.18.47",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.47.tgz",
+ "integrity": "sha512-OuJi8bIng4wYHHA3YpKauL58dZrPxro3d0tabPHyiNF8rKfGKuVfr83oFlPLmKri1cX+Z3cJP39GXmnqkP11Gw==",
"dev": true
},
"ansi-styles": {
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
"dev": true
},
+ "eventemitter2": {
+ "version": "6.4.7",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz",
+ "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==",
+ "dev": true
+ },
"execa": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
"dev": true
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
"dev": true
},
+ "decompress-response": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+ "optional": true,
+ "requires": {
+ "mimic-response": "^2.0.0"
+ }
+ },
"dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
"dev": true
},
"deepmerge": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
- "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="
},
"default-gateway": {
"version": "6.0.3",
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "dev": true
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
},
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
- "dev": true
+ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
},
"depd": {
"version": "2.0.0",
"integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
"dev": true
},
+ "detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+ "optional": true
+ },
"detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
}
},
"dot": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/dot/-/dot-1.1.3.tgz",
- "integrity": "sha512-/nt74Rm+PcfnirXGEdhZleTwGC2LMnuKTeeTIlI82xb5loBBoXNYzr2ezCroPSMtilK8EZIfcNZwOcHN+ib1Lg==",
+ "version": "2.0.0-beta.1",
+ "resolved": "https://registry.npmjs.org/dot/-/dot-2.0.0-beta.1.tgz",
+ "integrity": "sha512-kxM7fSnNQTXOmaeGuBSXM8O3fEsBb7XSDBllkGbRwa0lJSJTxxDE/4eSNGLKZUmlFw0f1vJ5qSV2BljrgQtgIA==",
"dev": true
},
"dotenv": {
"dev": true,
"requires": {
"readable-stream": "^2.0.2"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
}
},
"duration": {
"dev": true
},
"ejs": {
- "version": "3.1.8",
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
- "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
+ "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
"dev": true,
"requires": {
"jake": "^10.8.5"
}
},
"electron-to-chromium": {
- "version": "1.4.315",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.315.tgz",
- "integrity": "sha512-ndBQYz3Eyy3rASjjQ9poMJGoAlsZ/aZnq6GBsGL4w/4sWIAwiUHVSsMuADbxa8WJw7pZ0oxLpGbtoDt4vRTdCg=="
+ "version": "1.4.404",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.404.tgz",
+ "integrity": "sha512-te57sWvQdpxmyd1GiswaodKdXdPgn9cN4ht8JlNa04QgtrfnUdWEo1261rY2vaC6TKaiHn0E7QerJWPKFCvMVw=="
},
"elliptic": {
"version": "6.5.4",
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dev": true,
"requires": {
"once": "^1.4.0"
}
},
"enhanced-resolve": {
- "version": "5.12.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
- "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
+ "version": "5.14.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.0.tgz",
+ "integrity": "sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.4",
}
},
"es-abstract": {
- "version": "1.21.1",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz",
- "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==",
+ "version": "1.21.2",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz",
+ "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==",
"dev": true,
"requires": {
+ "array-buffer-byte-length": "^1.0.0",
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"es-set-tostringtag": "^2.0.1",
"es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
"function.prototype.name": "^1.1.5",
- "get-intrinsic": "^1.1.3",
+ "get-intrinsic": "^1.2.0",
"get-symbol-description": "^1.0.0",
"globalthis": "^1.0.3",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
- "internal-slot": "^1.0.4",
- "is-array-buffer": "^3.0.1",
+ "internal-slot": "^1.0.5",
+ "is-array-buffer": "^3.0.2",
"is-callable": "^1.2.7",
"is-negative-zero": "^2.0.2",
"is-regex": "^1.1.4",
"is-string": "^1.0.7",
"is-typed-array": "^1.1.10",
"is-weakref": "^1.0.2",
- "object-inspect": "^1.12.2",
+ "object-inspect": "^1.12.3",
"object-keys": "^1.1.1",
"object.assign": "^4.1.4",
"regexp.prototype.flags": "^1.4.3",
"safe-regex-test": "^1.0.0",
+ "string.prototype.trim": "^1.2.7",
"string.prototype.trimend": "^1.0.6",
"string.prototype.trimstart": "^1.0.6",
"typed-array-length": "^1.0.4",
"ext": "^1.1.2"
}
},
- "esbuild": {
- "version": "0.14.22",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.22.tgz",
- "integrity": "sha512-CjFCFGgYtbFOPrwZNJf7wsuzesx8kqwAffOlbYcFDLFuUtP8xloK1GH+Ai13Qr0RZQf9tE7LMTHJ2iVGJ1SKZA==",
- "dev": true,
- "optional": true,
- "requires": {
- "esbuild-android-arm64": "0.14.22",
- "esbuild-darwin-64": "0.14.22",
- "esbuild-darwin-arm64": "0.14.22",
- "esbuild-freebsd-64": "0.14.22",
- "esbuild-freebsd-arm64": "0.14.22",
- "esbuild-linux-32": "0.14.22",
- "esbuild-linux-64": "0.14.22",
- "esbuild-linux-arm": "0.14.22",
- "esbuild-linux-arm64": "0.14.22",
- "esbuild-linux-mips64le": "0.14.22",
- "esbuild-linux-ppc64le": "0.14.22",
- "esbuild-linux-riscv64": "0.14.22",
- "esbuild-linux-s390x": "0.14.22",
- "esbuild-netbsd-64": "0.14.22",
- "esbuild-openbsd-64": "0.14.22",
- "esbuild-sunos-64": "0.14.22",
- "esbuild-windows-32": "0.14.22",
- "esbuild-windows-64": "0.14.22",
- "esbuild-windows-arm64": "0.14.22"
- }
- },
"esbuild-android-arm64": {
"version": "0.14.22",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.22.tgz",
"dev": true
},
"eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
+ "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
"dev": true,
"requires": {
"esrecurse": "^4.3.0",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
}
},
"eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
+ "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
"dev": true
},
"espree": {
- "version": "9.4.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
- "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
+ "version": "9.5.2",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
+ "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
"dev": true,
"requires": {
"acorn": "^8.8.0",
"acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.3.0"
+ "eslint-visitor-keys": "^3.4.1"
}
},
"esprima": {
}
}
},
+ "expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "optional": true
+ },
"expand-tilde": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
+ },
+ "qs": {
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+ "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "dev": true,
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
}
}
},
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
- "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
- "dev": true
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"for-each": {
"version": "0.3.3",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
- "dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
}
},
"form-data-encoder": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
- "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A=="
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.9.0.tgz",
+ "integrity": "sha512-rahaRMkN8P8d/tgK/BLPX+WBVM27NbvdXBxqQujBtkDAIFspaRqN7Od7lfdGQA6KAD+f82fYCLBq1ipvcu8qLw=="
},
"format": {
"version": "0.2.2",
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "dev": true
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
},
"fs-extra": {
"version": "9.1.0",
"dev": true
},
"gauge": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
- "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
- "dev": true,
- "requires": {
- "aproba": "^1.0.3 || ^2.0.0",
- "color-support": "^1.1.3",
- "console-control-strings": "^1.1.0",
- "has-unicode": "^2.0.1",
- "signal-exit": "^3.0.7",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "wide-align": "^1.1.5"
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==",
+ "optional": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "optional": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
+ "optional": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "optional": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "optional": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
}
},
"gensync": {
"dev": true
},
"get-intrinsic": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
- "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+ "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
+ "has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
}
},
}
}
},
+ "github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+ "optional": true
+ },
"glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"dev": true,
"requires": {
"ini": "2.0.0"
+ },
+ "dependencies": {
+ "ini": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
+ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
+ "dev": true
+ }
}
},
"global-modules": {
"which": "^1.2.14"
},
"dependencies": {
- "ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true
- },
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
}
},
"graceful-fs": {
- "version": "4.2.10",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
- "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true
},
"growl": {
"has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
- "dev": true
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
},
"has-symbols": {
"version": "1.0.3",
"has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
- "dev": true
+ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
},
"has-value": {
"version": "1.0.0",
"inherits": "^2.0.4",
"readable-stream": "^3.6.0",
"safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
}
},
"hash.js": {
"obuf": "^1.0.0",
"readable-stream": "^2.0.1",
"wbuf": "^1.1.0"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
}
},
"html-encoding-sniffer": {
}
},
"html-tags": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz",
- "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
+ "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
"dev": true
},
"htmlescape": {
"requires": {
"asap": "~2.0.6"
}
+ },
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
}
}
},
}
},
"htmlparser2": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
- "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
+ "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"dev": true,
"requires": {
"domelementtype": "^2.3.0",
- "domhandler": "^5.0.2",
+ "domhandler": "^5.0.3",
"domutils": "^3.0.1",
- "entities": "^4.3.0"
+ "entities": "^4.4.0"
},
"dependencies": {
"dom-serializer": {
}
},
"domutils": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
- "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dev": true,
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
- "domhandler": "^5.0.1"
+ "domhandler": "^5.0.3"
}
},
"entities": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
- "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true
}
}
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
- "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
- "dev": true
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"inline-source-map": {
"version": "0.6.2",
"dev": true
},
"rxjs": {
- "version": "7.8.0",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
- "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+ "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"dev": true,
"requires": {
"tslib": "^2.1.0"
}
},
"is-core-module": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
- "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
+ "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
"dev": true,
"requires": {
"has": "^1.0.3"
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
- "dev": true
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"isexe": {
"version": "2.0.0",
}
},
"jake": {
- "version": "10.8.5",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
- "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==",
+ "version": "10.8.6",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.6.tgz",
+ "integrity": "sha512-G43Ub9IYEFfu72sua6rzooi8V8Gz2lkfk48rW20vEWCGizeaEPlKB1Kh8JIA84yQbiAEfqlPmSpGgCKKxH3rDA==",
"dev": true,
"requires": {
"async": "^3.2.3",
"chalk": "^4.0.2",
- "filelist": "^1.0.1",
- "minimatch": "^3.0.4"
+ "filelist": "^1.0.4",
+ "minimatch": "^3.1.2"
},
"dependencies": {
"ansi-styles": {
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
},
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
},
"dependencies": {
"esbuild": {
- "version": "0.17.10",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.10.tgz",
- "integrity": "sha512-n7V3v29IuZy5qgxx25TKJrEm0FHghAlS6QweUcyIgh/U0zYmQcvogWROitrTyZId1mHSkuhhuyEXtI9OXioq7A==",
+ "version": "0.17.19",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
+ "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
"dev": true,
"optional": true,
"requires": {
- "@esbuild/android-arm": "0.17.10",
- "@esbuild/android-arm64": "0.17.10",
- "@esbuild/android-x64": "0.17.10",
- "@esbuild/darwin-arm64": "0.17.10",
- "@esbuild/darwin-x64": "0.17.10",
- "@esbuild/freebsd-arm64": "0.17.10",
- "@esbuild/freebsd-x64": "0.17.10",
- "@esbuild/linux-arm": "0.17.10",
- "@esbuild/linux-arm64": "0.17.10",
- "@esbuild/linux-ia32": "0.17.10",
- "@esbuild/linux-loong64": "0.17.10",
- "@esbuild/linux-mips64el": "0.17.10",
- "@esbuild/linux-ppc64": "0.17.10",
- "@esbuild/linux-riscv64": "0.17.10",
- "@esbuild/linux-s390x": "0.17.10",
- "@esbuild/linux-x64": "0.17.10",
- "@esbuild/netbsd-x64": "0.17.10",
- "@esbuild/openbsd-x64": "0.17.10",
- "@esbuild/sunos-x64": "0.17.10",
- "@esbuild/win32-arm64": "0.17.10",
- "@esbuild/win32-ia32": "0.17.10",
- "@esbuild/win32-x64": "0.17.10"
+ "@esbuild/android-arm": "0.17.19",
+ "@esbuild/android-arm64": "0.17.19",
+ "@esbuild/android-x64": "0.17.19",
+ "@esbuild/darwin-arm64": "0.17.19",
+ "@esbuild/darwin-x64": "0.17.19",
+ "@esbuild/freebsd-arm64": "0.17.19",
+ "@esbuild/freebsd-x64": "0.17.19",
+ "@esbuild/linux-arm": "0.17.19",
+ "@esbuild/linux-arm64": "0.17.19",
+ "@esbuild/linux-ia32": "0.17.19",
+ "@esbuild/linux-loong64": "0.17.19",
+ "@esbuild/linux-mips64el": "0.17.19",
+ "@esbuild/linux-ppc64": "0.17.19",
+ "@esbuild/linux-riscv64": "0.17.19",
+ "@esbuild/linux-s390x": "0.17.19",
+ "@esbuild/linux-x64": "0.17.19",
+ "@esbuild/netbsd-x64": "0.17.19",
+ "@esbuild/openbsd-x64": "0.17.19",
+ "@esbuild/sunos-x64": "0.17.19",
+ "@esbuild/win32-arm64": "0.17.19",
+ "@esbuild/win32-ia32": "0.17.19",
+ "@esbuild/win32-x64": "0.17.19"
}
}
}
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
"dev": true
},
"joi": {
- "version": "17.8.3",
- "resolved": "https://registry.npmjs.org/joi/-/joi-17.8.3.tgz",
- "integrity": "sha512-q5Fn6Tj/jR8PfrLrx4fpGH4v9qM6o+vDUfD4/3vxxyg34OmKcNqYZ1qn2mpLza96S8tL0p0rIw2gOZX+/cTg9w==",
+ "version": "17.9.2",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.9.2.tgz",
+ "integrity": "sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==",
"dev": true,
"requires": {
"@hapi/hoek": "^9.0.0",
},
"dependencies": {
"rxjs": {
- "version": "7.8.0",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
- "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+ "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"dev": true,
"requires": {
"tslib": "^2.1.0"
}
},
"marked": {
- "version": "4.2.12",
- "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz",
- "integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
+ "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
"dev": true
},
"mathml-tag-names": {
}
},
"memfs": {
- "version": "3.4.13",
- "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz",
- "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==",
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.1.tgz",
+ "integrity": "sha512-UWbFJKvj5k+nETdteFndTpYxdeTMox/ULeqX5k/dpaQJCCFmj5EeKv3dBcyO2xmkRAx2vppRu5dVG7SOtsGOzA==",
"dev": true,
"requires": {
"fs-monkey": "^1.0.3"
"requires": {
"errno": "^0.1.3",
"readable-stream": "^2.0.1"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
}
},
"memorystream": {
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
"mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "dev": true
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
},
"mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "dev": true,
"requires": {
"mime-db": "1.52.0"
}
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true
},
+ "mimic-response": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
+ "optional": true
+ },
"min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
}
},
"schema-utils": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
- "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz",
+ "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
- "ajv": "^8.8.0",
+ "ajv": "^8.9.0",
"ajv-formats": "^2.1.1",
- "ajv-keywords": "^5.0.0"
+ "ajv-keywords": "^5.1.0"
}
}
}
},
+ "minim": {
+ "version": "0.23.8",
+ "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz",
+ "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==",
+ "requires": {
+ "lodash": "^4.15.0"
+ }
+ },
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
"minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "dev": true
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
},
"minimist-options": {
"version": "4.1.0",
"mkdirp-classic": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
- "dev": true
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
"mobx": {
"version": "4.14.1",
"randombytes": "^2.1.0"
}
},
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
"supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"requires": {
"resolve": "^1.17.0"
}
- },
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
}
}
},
"thenify-all": "^1.0.0"
}
},
+ "nan": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
+ "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
+ "optional": true
+ },
"nanoid": {
- "version": "3.3.4",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
- "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+ "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"dev": true
},
"nanomatch": {
"to-regex": "^3.0.1"
}
},
+ "napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
+ "optional": true
+ },
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"lower-case": "^1.1.1"
}
},
+ "node-abi": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz",
+ "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==",
+ "optional": true,
+ "requires": {
+ "semver": "^5.4.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "optional": true
+ }
+ }
+ },
"node-addon-api": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
},
"node-fetch": {
- "version": "2.6.7",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
- "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "version": "2.6.11",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
+ "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
"requires": {
"whatwg-url": "^5.0.0"
}
"which": "^2.0.2"
},
"dependencies": {
+ "are-we-there-yet": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
+ "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
+ "dev": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^3.6.0"
+ }
+ },
+ "gauge": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
+ "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.3",
+ "console-control-strings": "^1.1.0",
+ "has-unicode": "^2.0.1",
+ "signal-exit": "^3.0.7",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1",
+ "wide-align": "^1.1.5"
+ }
+ },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"yallist": "^4.0.0"
}
},
+ "npmlog": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
+ "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
+ "dev": true,
+ "requires": {
+ "are-we-there-yet": "^3.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^4.0.3",
+ "set-blocking": "^2.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
"dev": true
},
"node-releases": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
- "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w=="
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.11.tgz",
+ "integrity": "sha512-+M0PwXeU80kRohZ3aT4J/OnR+l9/KD2nVLNNoRgFtnf+umQVFdGBAO2N8+nCnEi0xlh/Wk3zOGC+vNNx+uM79Q=="
},
"nopt": {
"version": "5.0.0",
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
"unique-filename": "^2.0.0"
}
},
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true
+ },
"glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
}
},
"lru-cache": {
- "version": "7.18.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.1.tgz",
- "integrity": "sha512-8/HcIENyQnfUTCDizRu9rrDyG6XG/21M4X7/YEGZeD76ZJilFPAUVb/2zysFf7VVO1LEjCDFyHp8pMMvozIrvg==",
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
"dev": true
},
"make-fetch-happen": {
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"npmlog": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
- "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
- "dev": true,
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "optional": true,
"requires": {
- "are-we-there-yet": "^3.0.0",
- "console-control-strings": "^1.1.0",
- "gauge": "^4.0.3",
- "set-blocking": "^2.0.0"
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
}
},
"nth-check": {
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
- "dev": true
+ "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ=="
},
"nwsapi": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz",
- "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==",
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.4.tgz",
+ "integrity": "sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g==",
"dev": true
},
"nx": {
"rimraf": "^3.0.2",
"ssri": "^8.0.1",
"tar": "^6.1.0"
+ },
+ "dependencies": {
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true
+ }
}
},
"pad-right": {
"inherits": "^2.0.1",
"readable-stream": "^3.1.1"
}
+ },
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
}
}
},
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
"dev": true
},
"postcss-modules-local-by-default": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz",
- "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.2.tgz",
+ "integrity": "sha512-mR/pcIsQhU2UgKYOPjRCSgacmjn08pyrHk+Vrm8WEKjDWgqO43vdRkzmxyZOZWiKr6Ed9gpReQHhLUGVAcn9jw==",
"dev": true,
"requires": {
"icss-utils": "^5.0.0",
}
},
"postcss-selector-parser": {
- "version": "6.0.11",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz",
- "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==",
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
+ "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
"dev": true,
"requires": {
"cssesc": "^3.0.0",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true
},
+ "prebuild-install": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz",
+ "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==",
+ "optional": true,
+ "requires": {
+ "detect-libc": "^1.0.3",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^2.21.0",
+ "npmlog": "^4.0.1",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^3.0.3",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ }
+ },
"preceptor-core": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/preceptor-core/-/preceptor-core-0.10.1.tgz",
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
- "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
- "dev": true
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
- "dev": true
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"progress": {
"version": "2.0.3",
},
"dependencies": {
"@types/node": {
- "version": "18.14.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.4.tgz",
- "integrity": "sha512-VhCw7I7qO2X49+jaKcAUwi3rR+hbxT5VcYF493+Z5kMLI0DL568b7JI4IDJaxWFH0D/xwmGJNoXisyX+w7GH/g==",
+ "version": "20.2.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz",
+ "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==",
"dev": true
}
}
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
- "dev": true
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"proxy-middleware": {
"version": "0.15.0",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
"integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="
},
"qs": {
- "version": "6.11.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "version": "6.11.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
+ "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
"requires": {
"side-channel": "^1.0.4"
}
"through2": "^2.0.0"
}
},
+ "ramda": {
+ "version": "0.29.0",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz",
+ "integrity": "sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA=="
+ },
+ "ramda-adjunct": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-4.0.0.tgz",
+ "integrity": "sha512-W/NiJAlZdwZ/iUkWEQQgRdH5Szqqet1WoVH9cdqDVjFbVaZHuJfJRvsxqHhvq6tZse+yVbFatLDLdVa30wBlGQ=="
+ },
"randexp": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz",
}
}
},
+ "rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "optional": true,
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ }
+ },
"react": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
},
"read-only-stream": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
- "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==",
- "dev": true,
- "requires": {
- "readable-stream": "^2.0.2"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
+ "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
+ "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.2"
}
},
"read-package-json-fast": {
}
},
"readable-stream": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz",
- "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==",
- "dev": true,
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ }
}
},
"readdirp": {
"dev": true
},
"regexp.prototype.flags": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
- "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
+ "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "functions-have-names": "^1.2.2"
+ "define-properties": "^1.2.0",
+ "functions-have-names": "^1.2.3"
}
},
"regexpp": {
"dev": true
},
"regexpu-core": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.1.tgz",
- "integrity": "sha512-nCOzW2V/X15XpLsK2rlgdwrysrBq+AauCn+omItIz4R1pIcmeot5zvjdmOBRLzEH/CkC6IxMJVmxDe3QcMuNVQ==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
+ "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
"dev": true,
"requires": {
"@babel/regjsgen": "^0.8.0",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
},
"reselect": {
- "version": "4.1.7",
- "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
- "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A=="
+ "version": "4.1.8",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
+ "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
},
"resolve": {
- "version": "1.22.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
- "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
+ "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
"dev": true,
"requires": {
- "is-core-module": "^2.9.0",
+ "is-core-module": "^2.11.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
}
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
- "dev": true
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
},
"set-value": {
"version": "2.0.1",
"dev": true
},
"shell-quote": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.0.tgz",
- "integrity": "sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==",
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
+ "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
"dev": true
},
+ "short-unique-id": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-4.4.4.tgz",
+ "integrity": "sha512-oLF1NCmtbiTWl2SqdXZQbo5KM1b7axdp0RgQLq8qCBBLoq+o3A5wmLrNM6bZIh54/a8BJ3l69kTXuxwZ+XCYuw=="
+ },
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "dev": true
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
"simple-concat": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
- "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
- "dev": true
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
+ },
+ "simple-get": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
+ "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
+ "optional": true,
+ "requires": {
+ "decompress-response": "^4.2.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
},
"simplebar": {
"version": "5.3.9",
"integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA=="
},
"spdx-correct": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
- "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+ "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
"dev": true,
"requires": {
"spdx-expression-parse": "^3.0.0",
}
},
"spdx-license-ids": {
- "version": "3.0.12",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
- "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
+ "version": "3.0.13",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
+ "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
"dev": true
},
"spdy": {
"obuf": "^1.1.2",
"readable-stream": "^3.0.6",
"wbuf": "^1.7.3"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
}
},
"specificity": {
"stacktrace-gps": "^3.0.4"
}
},
+ "stampit": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/stampit/-/stampit-4.3.2.tgz",
+ "integrity": "sha512-pE2org1+ZWQBnIxRPrBM2gVupkuDD0TTNIo1H6GdT/vO82NXli2z8lRE8cu/nBIHrcOCXFBAHpb9ZldrB2/qOA=="
+ },
"start-server-and-test": {
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.12.1.tgz",
"requires": {
"sourcemap-codec": "^1.4.1"
}
- },
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
}
}
},
"requires": {
"inherits": "~2.0.1",
"readable-stream": "^2.0.2"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
}
},
"stream-buffers": {
"requires": {
"duplexer2": "~0.1.0",
"readable-stream": "^2.0.2"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
}
},
"stream-http": {
"inherits": "^2.0.4",
"readable-stream": "^3.6.0",
"xtend": "^4.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
}
},
"stream-splicer": {
"requires": {
"inherits": "^2.0.1",
"readable-stream": "^2.0.2"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
}
},
"streamroller": {
"es-abstract": "^1.20.4"
}
},
+ "string.prototype.trim": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz",
+ "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ }
+ },
"string.prototype.trimend": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
}
},
"string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "dev": true,
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
- "safe-buffer": "~5.2.0"
+ "safe-buffer": "~5.1.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ }
}
},
"strip-ansi": {
}
},
"strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "dev": true
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "optional": true
},
"strong-log-transformer": {
"version": "2.1.0",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
- "ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true
- },
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"dev": true
},
"swagger-client": {
- "version": "3.18.5",
- "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.18.5.tgz",
- "integrity": "sha512-c0txGDtfQTJnaIBaEKCwtRNcUaaAfj+RXI4QVV9p3WW+AUCQqp4naCjaDNNsOfMkE4ySyhnblbL+jGqAVC7snw==",
- "requires": {
- "@babel/runtime-corejs3": "^7.11.2",
+ "version": "3.19.7",
+ "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.19.7.tgz",
+ "integrity": "sha512-5U4+tksrzVODZaLTtivzS9be6u7rX5ZSWFKDIYWsy8HCwt9FH1ANrrGpY1wDHydpOeaySbxMjMaqEM9cGWxOuQ==",
+ "requires": {
+ "@babel/runtime-corejs3": "^7.20.13",
+ "@swagger-api/apidom-core": ">=0.69.3 <1.0.0",
+ "@swagger-api/apidom-json-pointer": ">=0.69.3 <1.0.0",
+ "@swagger-api/apidom-ns-openapi-3-1": ">=0.69.3 <1.0.0",
+ "@swagger-api/apidom-reference": ">=0.69.3 <1.0.0",
"cookie": "~0.5.0",
"cross-fetch": "^3.1.5",
- "deepmerge": "~4.2.2",
+ "deepmerge": "~4.3.0",
"fast-json-patch": "^3.0.0-1",
"form-data-encoder": "^1.4.3",
"formdata-node": "^4.0.0",
"dev": true
},
"tar": {
- "version": "6.1.13",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz",
- "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==",
+ "version": "6.1.15",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz",
+ "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==",
"dev": true,
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
- "minipass": "^4.0.0",
+ "minipass": "^5.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
},
"dependencies": {
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true
+ },
"minipass": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.4.tgz",
- "integrity": "sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"dev": true
},
"yallist": {
}
}
},
+ "tar-fs": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "optional": true,
+ "requires": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
"tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
- "dev": true,
"requires": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
}
},
"terminal-link": {
}
},
"terser-webpack-plugin": {
- "version": "5.3.7",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz",
- "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==",
+ "version": "5.3.9",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
+ "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
"dev": true,
"requires": {
"@jridgewell/trace-mapping": "^0.3.17",
"jest-worker": "^27.4.5",
"schema-utils": "^3.1.1",
"serialize-javascript": "^6.0.1",
- "terser": "^5.16.5"
+ "terser": "^5.16.8"
},
"dependencies": {
"ajv": {
"dev": true
},
"schema-utils": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
- "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz",
+ "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.8",
}
},
"terser": {
- "version": "5.16.6",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.6.tgz",
- "integrity": "sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg==",
+ "version": "5.17.5",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.5.tgz",
+ "integrity": "sha512-NqFkzBX34WExkCbk3K5urmNCpEWqMPZnwGI1pMHwqvJ/zDlXC75u3NI7BrzoR8/pryy8Abx2e1i8ChrWkhH1Hg==",
"dev": true,
"requires": {
"@jridgewell/source-map": "^0.3.2",
"requires": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
}
},
"thunky": {
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
"dev": true
},
- "time-stamp": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
- "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==",
- "dev": true
- },
"timers-browserify": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
"integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
"dev": true
},
+ "tree-sitter": {
+ "version": "0.20.1",
+ "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.1.tgz",
+ "integrity": "sha512-Cmb8V0ocamHbgWMVhZIa+78k/7r8VCQ6+ePG8eYEAO7AccwWi06Ct4ATNiI94KwhIkRl0+OwZ42/5nk3GnEMpQ==",
+ "optional": true,
+ "requires": {
+ "nan": "^2.14.0",
+ "prebuild-install": "^6.0.1"
+ }
+ },
+ "tree-sitter-json": {
+ "version": "0.20.0",
+ "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.20.0.tgz",
+ "integrity": "sha512-PteOLH+Tx6Bz4ZA/d40/DbkiSXXRM/gKahhHI8hQ1lWNfFvdknnz9k3Mz84ol5srRyLboJ8wp8GSkhZ6ht9EGQ==",
+ "optional": true,
+ "requires": {
+ "nan": "^2.14.1"
+ }
+ },
+ "tree-sitter-yaml": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/tree-sitter-yaml/-/tree-sitter-yaml-0.5.0.tgz",
+ "integrity": "sha512-POJ4ZNXXSWIG/W4Rjuyg36MkUD4d769YRUGKRqN+sVaj/VCo6Dh6Pkssn1Rtewd5kybx+jT1BWMyWN0CijXnMA==",
+ "optional": true,
+ "requires": {
+ "nan": "^2.14.0"
+ }
+ },
"trim-newlines": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
},
+ "ts-toolbelt": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz",
+ "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w=="
+ },
"tsconfig-paths": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz",
- "integrity": "sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz",
+ "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==",
"dev": true,
"requires": {
"json5": "^2.2.2",
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
- "dev": true,
"requires": {
"safe-buffer": "^5.0.1"
}
"is-typedarray": "^1.0.0"
}
},
+ "types-ramda": {
+ "version": "0.29.2",
+ "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.29.2.tgz",
+ "integrity": "sha512-HpLcR0ly2EfXQwG8VSI5ov6ml7PvtT+u+cp+7lZLu7q4nhnPDVW+rUTC1uy/SNs4aAyTUXri5M/LyhgvjEXJDg==",
+ "requires": {
+ "ts-toolbelt": "^9.6.0"
+ }
+ },
"typescript": {
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"dev": true
},
+ "unraw": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unraw/-/unraw-2.0.1.tgz",
+ "integrity": "sha512-tdOvLfRzHolwYcHS6HIX860MkK9LQ4+oLuNwFYL7bpgTEO64PZrcQxkisgwJYCfF8sKiWLwwu1c83DvMkbefIQ=="
+ },
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
"dev": true
},
"update-browserslist-db": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
- "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
+ "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
"requires": {
"escalade": "^3.1.1",
"picocolors": "^1.0.0"
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"utils-merge": {
"version": "1.0.1",
"ieee754": "^1.1.4"
}
},
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- },
- "dependencies": {
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
"stream-browserify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
},
"dependencies": {
"readable-stream": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz",
- "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==",
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
},
"dependencies": {
"readable-stream": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz",
- "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==",
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
"integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="
},
+ "web-tree-sitter": {
+ "version": "0.20.7",
+ "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.7.tgz",
+ "integrity": "sha512-flC9JJmTII9uAeeYpWF8hxDJ7bfY+leldQryetll8Nv4WgI+MXc6h7TiyAZASWl9uC9TvmfdgOjZn1DAQecb3A==",
+ "optional": true
+ },
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"dev": true
},
"schema-utils": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
- "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz",
+ "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.8",
}
},
"schema-utils": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
- "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz",
+ "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
- "ajv": "^8.8.0",
+ "ajv": "^8.9.0",
"ajv-formats": "^2.1.1",
- "ajv-keywords": "^5.0.0"
+ "ajv-keywords": "^5.1.0"
}
}
}
"dev": true
},
"schema-utils": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
- "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz",
+ "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
- "ajv": "^8.8.0",
+ "ajv": "^8.9.0",
"ajv-formats": "^2.1.1",
- "ajv-keywords": "^5.0.0"
+ "ajv-keywords": "^5.1.0"
}
},
"strip-ansi": {
}
},
"which-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
+ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
"dev": true
},
"which-typed-array": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
- "dev": true,
"requires": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
"wildcard": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
- "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
+ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
"dev": true
},
"windows-release": {
}
},
"ws": {
- "version": "8.12.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.1.tgz",
- "integrity": "sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==",
+ "version": "8.13.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
+ "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
"dev": true
},
"xliff": {
"dev": true
},
"xmldoc": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.2.0.tgz",
- "integrity": "sha512-2eN8QhjBsMW2uVj7JHLHkMytpvGHLHxKXBy4J3fAT/HujsEtM6yU84iGjpESYGHg6XwK0Vu4l+KgqQ2dv2cCqg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.3.0.tgz",
+ "integrity": "sha512-y7IRWW6PvEnYQZNZFMRLNJw+p3pezM4nKYPfr15g4OOW9i8VpeydycFuipE2297OvZnh3jSb2pxOt9QpkZUVng==",
"dev": true,
"requires": {
"sax": "^1.2.4"
"dev": true
},
"yargs": {
- "version": "17.7.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
- "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"requires": {
"cliui": "^8.0.1",
"escalade": "^3.1.1",
"pree2e:ci": "npm run pree2e",
"e2e:ci": "start-test 4200 'cypress run -b chrome --headless'",
"lint:eslint": "ng lint",
- "lint:gherkin": "gherkin-lint -c .gherkin-lintrc cypress/integration",
+ "lint:gherkin": "gherkin-lint -c .gherkin-lintrc cypress/e2e",
"lint:prettier": "prettier --list-different \"{src,cypress}/**/*.{ts,scss}\"",
"lint:html": "htmllint src/app/**/*.html && html-linter --config html-linter.config.json",
"prelint:tsc": "npm run postinstall",
"@apteco/ngth": "1.5.0",
"@compodoc/compodoc": "1.1.18",
"@cypress/browserify-preprocessor": "3.0.2",
- "@grafana/e2e": "8.4.5",
"@types/brace-expansion": "1.1.0",
"@types/cypress-cucumber-preprocessor": "4.0.1",
"@types/jest": "28.1.3",
"@typescript-eslint/eslint-plugin": "5.27.1",
"@typescript-eslint/parser": "5.27.1",
"axe-core": "4.4.3",
- "cypress": "9.7.0",
+ "cypress": "10.11.0",
"cypress-axe": "0.14.0",
"cypress-cucumber-preprocessor": "4.3.1",
"cypress-iframe": "1.0.1",
"typescript": "4.6.4"
},
"cypress-cucumber-preprocessor": {
- "nonGlobalStepDefinitions": true
+ "stepDefinitions": "cypress/e2e/common"
}
}
<div class="col-sm-6 col-lg-6 metadata"
*ngIf="metadata">
<legend>{{ metadataTitle }}</legend>
- <cd-table-key-value [data]="metadata"></cd-table-key-value>
+ <div>
+ <cd-table-key-value [data]="metadata"></cd-table-key-value>
+ </div>
</div>
</div>
</div>