Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
eb2b6a9
Added cypress testing init wiht files plugin
Jul 18, 2025
4552139
Updates to Cypress For Load + Files Upload
Jul 29, 2025
76f1843
updated files with test
Aug 1, 2025
865f8f4
Updated files component with working tests + added commands + udpate …
Aug 19, 2025
e159e97
add custom cypress functions to close setting menu, open global setti…
dacowan404 Aug 21, 2025
fdee164
Phylogenetic Tree view testing added
dacowan404 Sep 9, 2025
d4fc45f
Phylogenetic Tree View: updated layout to prevent labels from appeari…
dacowan404 Sep 16, 2025
0aec1a5
Update for 2d network testing + added cypress condition in render for…
Sep 18, 2025
d9c41bb
Merge branch 'cypressTesting' of github.com:CDCgov/MicrobeTrace into …
Sep 18, 2025
359c8dd
updated test cases
Mossy1022 Sep 25, 2025
6aa1fbc
Merge remote-tracking branch 'upstream/angularUpdate' into cypressTes…
Mossy1022 Sep 25, 2025
dacf9e9
Initial commit of automated testing for map view; commented out unuse…
dacowan404 Sep 30, 2025
915324a
Refactor Cypress test helpers and enhance test coverage for 2D networ…
mossy426-cdc Nov 19, 2025
542d460
Added back in 2d test cases (still need to fix some) + foundational t…
mossy426-cdc Dec 5, 2025
abb3a19
syntax fix
mossy426-cdc Dec 5, 2025
58ae691
Refactor 2D network tests to improve accuracy and reliability. Update…
mossy426-cdc Dec 12, 2025
40e70c3
Add a cypress command for adding multiple files at once (attach_files…
dacowan404 Dec 12, 2025
8a2ebe5
Merge branch 'cypressTesting' of https://github.com/CDCgov/MicrobeTra…
dacowan404 Dec 12, 2025
420b80a
Updated tree view testing to check that element in DOM are updated, f…
dacowan404 Dec 16, 2025
7c18363
Refactor 2D network toolbar actions tests by commenting out existing …
Mossy1022 Dec 18, 2025
a4a2917
updated zipcodes.csv to include ~300 new zipcodes obtained from US Ce…
dacowan404 Dec 18, 2025
69f5093
Merge branch 'cypressTesting' of https://github.com/CDCgov/MicrobeTra…
dacowan404 Dec 18, 2025
91a2fea
Map testing update to include timeline mode and additional global set…
dacowan404 Jan 5, 2026
9ecaba1
Updated tree view to: fix node selection, sync widgets and local vari…
dacowan404 Jan 9, 2026
29fcc15
Update file names in Cypress tests for consistency and clarity; remov…
mossy426-cdc Jan 9, 2026
916ce50
added new testing for phylogenetic tree view (tests for node color ch…
dacowan404 Jan 12, 2026
1c6a15e
Merge remote-tracking branch 'origin/master' into cypressTesting
dacowan404 Jan 13, 2026
024bc7c
Refactor node selection logic in TwoDComponent to improve clarity and…
mossy426-cdc Jan 13, 2026
fa7d969
Updated map include button show number of nodes with location data. B…
dacowan404 Jan 13, 2026
f48df10
Merge branch 'dev' of https://github.com/CDCgov/MicrobeTrace into dev
dacowan404 Jan 13, 2026
e642209
Refactor arrow styling logic in TwoDComponent to enhance clarity and …
Mossy1022 Jan 21, 2026
9f18aed
Update Cypress tests and components for grouping functionality. Renam…
mossy426-cdc Jan 28, 2026
0d115e5
Update .gitignore to include additional node_modules directories and …
mossy426-cdc Jan 29, 2026
e8530a0
Merge branch 'cypressTesting' into dev
mossy426-cdc Jan 29, 2026
a09344a
updated gantt chart to allow user control of sizing, font size, opaci…
dacowan404 Jan 29, 2026
f7d0072
Added automatic resizing/recentering for most of the view when in das…
dacowan404 Jan 30, 2026
9bf870a
Merge branch 'dev' of https://github.com/CDCgov/MicrobeTrace into dev
dacowan404 Jan 30, 2026
618bd62
fixed a bug where links were being set to bidirectional incorrectly (…
dacowan404 Feb 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
# dependencies
/node_modules
/node_modules_dev
/node_modules_classic
/node_modules_ang
/dev_node_modules
/Hantavirus_Testing

Expand Down Expand Up @@ -62,4 +64,10 @@ slr/*
slr_linux.tgz
.agignore

.scignore
.scignore

cypress/screenshots/*
cypress/downloads/*

# Maven
target/
12 changes: 12 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from "cypress";

export default defineConfig({
e2e: {
baseUrl: 'http://localhost:4200', // Set your app's base URL
viewportWidth: 1280,
viewportHeight: 720,
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});
32 changes: 32 additions & 0 deletions cypress/e2e/alignment-plugin.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
describe('Alignment View', () => {
const selectors = {
container: '.msa-viewer-container',
settingsBtn: 'a[title="Open Settings"]',
settingsPane: '#alignment-settings-pane',
};

beforeEach(() => {
cy.visit('/');
cy.wait(6000);

cy.contains('button', 'Continue with Sample Dataset', { timeout: 10000 }).click({ force: true });
cy.get('#overlay').should('not.be.visible', { timeout: 10000 });

cy.contains('button', 'View').click();
cy.contains('button[mat-menu-item]', 'Alignment View').click();

cy.get(selectors.container, { timeout: 15000 }).should('be.visible');
});

it('renders the alignment viewer with sample data', () => {
cy.get(selectors.container).find('#msa-viewer').should('exist');
});

it('opens and closes the alignment settings', () => {
cy.get(selectors.settingsBtn).click();
cy.get(selectors.settingsPane, { timeout: 10000 }).should('be.visible');

cy.get(selectors.settingsPane).find('.p-dialog-header-icon').click({ force: true });
cy.get(selectors.settingsPane).should('not.be.visible');
});
});
32 changes: 32 additions & 0 deletions cypress/e2e/bubble-plugin.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
describe('Bubble View', () => {
const selectors = {
container: '#cyBubble',
settingsBtn: 'a[title="Open Settings"]',
settingsPane: '.p-dialog-header:contains("Bubble Settings")',
};

beforeEach(() => {
cy.visit('/');
cy.wait(6000);

cy.contains('button', 'Continue with Sample Dataset', { timeout: 10000 }).click({ force: true });
cy.get('#overlay').should('not.be.visible', { timeout: 10000 });

cy.contains('button', 'View').click();
cy.contains('button[mat-menu-item]', 'Bubble').click();

cy.get(selectors.container, { timeout: 15000 }).should('be.visible');
});

it('renders bubble view canvas', () => {
cy.get(selectors.container).should('exist');
});

it('opens and closes the bubble settings dialog', () => {
cy.get(selectors.settingsBtn).click();
cy.contains('div.p-dialog', 'Bubble Settings', { timeout: 10000 }).should('be.visible');

cy.contains('div.p-dialog', 'Bubble Settings').find('.p-dialog-header-icon').click({ force: true });
cy.contains('div.p-dialog', 'Bubble Settings').should('not.be.visible');
});
});
191 changes: 191 additions & 0 deletions cypress/e2e/files-plugin.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
// cypress/e2e/files-plugin.cy.ts
/// <reference types="cypress" />

describe('File Handling and Processing', () => {
const nodeFile = 'AngularTesting_nodelist_withseqs_TN93_BS.csv';
const linkFile = 'AngularTesting_Epi_linklist_BS.csv';

beforeEach(() => {
cy.visit('/');
// The initial wait is to allow the default session to load,
// which we will clear by uploading our own file.
cy.wait(2000);
});

it('uploads multiple files and then sets the datatype and the fields', () => {
// mostly an example of this function
cy.loadFiles([
{name: 'AngularTesting_DistanceMatrix_TN93_BS.xlsx', datatype: 'matrix'},
{name: 'AngularTesting_seqs_TN93_BS.fasta', datatype: 'fasta'},
{name: 'AngularTesting_nodes_Map.csv', datatype: 'node', field1: 'seq', field2: '_id'}
])
})

it('uploads a single node list, auto-configures it, and enables launch', () => {
// Upload the file from the overlay
cy.attach_file('#fileDropRef', nodeFile);
cy.get('#overlay').should('not.be.visible', { timeout: 10000 });

// Assert the file row is visible
cy.contains('#file-table .file-table-row', nodeFile).should('be.visible');
cy.get('#launch').should('not.be.disabled');

// Assert file type is auto-detected as "Node"
cy.contains('.file-table-row', nodeFile).find('input[data-type="node"]').should('be.checked');

// Use attribute selector to handle special characters in the ID
cy.get(`[id="file-${nodeFile}-field-1"]`).should('have.value', '_id');
cy.get(`[id="file-${nodeFile}-field-2"]`).should('have.value', 'seq');
});

it('updates column mapping labels when file type is changed manually', () => {
cy.attach_file('#fileDropRef', nodeFile);

cy.get('#overlay').should('not.be.visible', { timeout: 10000 });

// Initial state: Node - We re-query the row for each assertion for robustness.
cy.contains('#file-table .file-table-row', nodeFile)
.find('label').contains('ID').should('be.visible');
cy.contains('#file-table .file-table-row', nodeFile)
.find('label').contains('Sequence').should('be.visible');
cy.contains('#file-table .file-table-row', nodeFile)
.find('label:contains("Distance")').parent().should('not.be.visible');

// Change to Link type
cy.contains('#file-table .file-table-row', nodeFile)
.find('input[data-type="link"]').click({ force: true });

// Assert labels changed
cy.contains('#file-table .file-table-row', nodeFile)
.find('label').contains('Source').should('be.visible');
cy.contains('#file-table .file-table-row', nodeFile)
.find('label').contains('Target').should('be.visible');
cy.contains('#file-table .file-table-row', nodeFile)
.find('label').contains('Distance').should('be.visible');
cy.contains('#file-table .file-table-row', nodeFile)
.find('label:contains("Sequence")').should('not.exist');
});

it('allows a file to be removed', () => {
cy.attach_file('#fileDropRef', nodeFile);
cy.get('#overlay').should('not.be.visible', { timeout: 10000 });

// Ensure the file row exists
cy.contains('#file-table .file-table-row', nodeFile).should('be.visible');

// Click the remove button
cy.contains('.file-table-row', nodeFile).find('.flaticon-delete-1').click();

// Assert the file row is gone and the prompt is back
cy.contains('#file-table .file-table-row', nodeFile).should('not.exist');
cy.get('#file-prompt').should('be.visible');
});

it('opens and closes the sequence controls modal', () => {
cy.attach_file('#fileDropRef', nodeFile);
cy.get('#overlay').should('not.be.visible', { timeout: 10000 });

// The p-dialog component exists in the DOM but isn't visible
cy.get('#sequence-controls-modal').should('not.be.visible');

// Click button to open sequence controls
cy.contains('button', 'Sequence Controls').click();

// Assert that content inside the modal is now visible
cy.get('#sequence-controls-modal').contains('Alignment').should('be.visible');

// Click the "Confirm" button to close it
cy.get('#sequence-controls-modal').contains('button', 'Confirm').click();
cy.get('#sequence-controls-modal').should('not.be.visible');
});

it('opens and closes the file settings modal', () => {
cy.attach_file('#fileDropRef', nodeFile);
cy.get('#overlay').should('not.be.visible', { timeout: 10000 });

// Modal should not be visible initially
cy.get('#file-settings-pane').should('not.be.visible');

// Click the settings icon to open the modal
cy.get('a[title="Settings"]').click();
cy.get('#file-settings-pane').contains('Distance Metric').should('be.visible');

// **FIX**: Target the clickable button, not the inner icon span
cy.get('#file-settings-pane').find('button.p-dialog-close-button').click();

cy.get('#file-settings-pane').should('not.be.visible');
});


it('launches a network from separate node and link lists', () => {
cy.attach_file('#fileDropRef', nodeFile);
cy.get('#overlay').should('not.be.visible', { timeout: 10000 });

cy.attach_file('#data-files1', linkFile); // Use the "Add File(s)" button

cy.get('#launch').click();
cy.get('.lm_tab.lm_active', { timeout: 20000 }).should('contain.text', '2D Network');

cy.window().its('commonService.session.data.nodes').should('have.length', 14);
cy.window().its('commonService.session.data.links').should('have.length.greaterThan', 0);

// Verify data from both files was merged
cy.window().then((win) => {
const node = win.commonService.session.data.nodes.find(n => n._id === 'KF773425');
expect(node.subtype).to.equal('C');

const link = win.commonService.session.data.links.find(l =>
(l.source === 'KF773571' && l.target === 'KF773578')
);
expect(link.Contact).to.equal('Bar');
});
});
});

describe('Files Plugin - Settings', () => {
const nodeFile = 'AngularTesting_nodelist_withseqs_TN93_small (2).csv';

beforeEach(() => {
cy.visit('/');
cy.wait(2000); 
cy.attach_file('#fileDropRef', nodeFile);
cy.get('#overlay').should('not.be.visible', { timeout: 10000 });
cy.get('#tool-btn-container a[title="Settings"]').click();
});

it('should change the Distance Metric and update the session', () => {
cy.window().its('commonService.session.style.widgets.default-distance-metric').should('equal', 'snps');
cy.get('#default-distance-metric').select('tn93');
cy.window().its('commonService.session.style.widgets.default-distance-metric').should('equal', 'tn93');
});

it('should change the Ambiguity Resolution Strategy and update the session', () => {
cy.window().its('commonService.session.style.widgets.ambiguity-resolution-strategy').should('equal', 'AVERAGE');
cy.get('#default-distance-metric').select('tn93');
cy.get('#ambiguity-resolution-strategy').select('RESOLVE');
cy.window().its('commonService.session.style.widgets.ambiguity-resolution-strategy').should('equal', 'RESOLVE');
});

// it('should show and update the Ambiguity Threshold when strategy is RESOLVE', () => {
// const newThreshold = '0.025';
// cy.get('#ambiguity-threshold-row').should('not.be.visible');
// cy.get('#ambiguity-resolution-strategy').select('RESOLVE');
// cy.get('#ambiguity-threshold-row').should('be.visible');
// cy.get('#ambiguity-threshold').clear().type(newThreshold);
// cy.window().its('commonService.session.style.widgets.ambiguity-threshold').should('equal', parseFloat(newThreshold));
// });

it('should change the Link Threshold and update the session', () => {
const newThreshold = '4';
// snps initally
cy.window().its('commonService.session.style.widgets.link-threshold').should('equal', 164);
cy.get('#default-distance-threshold').clear().type(newThreshold);
cy.window().its('commonService.session.style.widgets.link-threshold').should('equal', parseFloat(newThreshold));
});

it('should change the View to Launch and update the session', () => {
cy.window().its('commonService.session.style.widgets.default-view').should('equal', '2d_network');
cy.get('#default-view').select('Table');
cy.window().its('commonService.session.style.widgets.default-view').should('equal', 'Table');
});
});
39 changes: 39 additions & 0 deletions cypress/e2e/journeys/datasets/profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// cypress/e2e/journeys/datasets/profile.ts
// Central registry for dataset profiles used by journey tests.
// Re-export types so flows can keep importing from this file.

export * from './types';

import type { DatasetProfile } from './types';

import { NN_PROFILES } from './profiles/nn';
import { STYLE_PROFILES } from './profiles/style';
import { GROUPING_PROFILES } from './profiles/grouping';

export const DATASET_PROFILES: DatasetProfile[] = [
...NN_PROFILES,
...STYLE_PROFILES,
...GROUPING_PROFILES,
];

export const DATASET_PROFILE_MAP: Record<string, DatasetProfile> = DATASET_PROFILES
.reduce((acc, p) => {
acc[p.id] = p;
return acc;
}, {} as Record<string, DatasetProfile>);

export function getProfile(id: string): DatasetProfile {
const p = DATASET_PROFILE_MAP[id];
if (!p) {
throw new Error(`Unknown dataset profile id: ${id}`);
}
return p;
}

export function getProfilesByTag(tag: string): DatasetProfile[] {
return DATASET_PROFILES.filter(p => p.tags.includes(tag));
}

export function getProfilesByTags(tags: string[]): DatasetProfile[] {
return DATASET_PROFILES.filter(p => tags.every(t => p.tags.includes(t)));
}
Empty file.
Loading
Loading