Skip to content

Commit e8530a0

Browse files
committed
Merge branch 'cypressTesting' into dev
2 parents f48df10 + 0d115e5 commit e8530a0

10 files changed

Lines changed: 503 additions & 121 deletions

File tree

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
# dependencies
99
/node_modules
1010
/node_modules_dev
11+
/node_modules_classic
12+
/node_modules_ang
1113
/dev_node_modules
1214
/Hantavirus_Testing
1315

@@ -65,4 +67,7 @@ slr_linux.tgz
6567
.scignore
6668

6769
cypress/screenshots/*
68-
cypress/downloads/*
70+
cypress/downloads/*
71+
72+
# Maven
73+
target/

cypress/e2e/journeys/datasets/profiles/grouping.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export const GROUPING_PROFILES: DatasetProfile[] = [
1313
datatype: 'link',
1414
field1: 'source',
1515
field2: 'target',
16-
// no field3 needed for this fixture if "Distance" is not present/used
1716
},
1817
],
1918
preLaunch: {
@@ -33,6 +32,12 @@ export const GROUPING_PROFILES: DatasetProfile[] = [
3332
showGroups: true,
3433
showGroupColors: false,
3534
showGroupLabels: false,
35+
36+
expectedGroups: {
37+
'2': ['KF773429', 'KF773432', 'KF773430'],
38+
'1': ['KF773576', 'KF773579'],
39+
'0': ['KF773427', 'KF773425', 'KF773426', 'KF773578', 'KF773571'],
40+
},
3641
},
3742
},
3843
}),

cypress/e2e/journeys/datasets/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ export type JourneyExpectations = {
7373
showGroupColors: boolean;
7474
showGroupLabels: boolean;
7575

76+
/**
77+
* Explicit membership expectations:
78+
* key is the group label (cluster id or subtype, etc).
79+
* The parent cytoscape id might be either '<key>' or `group-<key>` depending on the code path.
80+
*/
81+
expectedGroups?: Record<string, string[]>;
82+
7683
thresholdChange?: {
7784
from: number;
7885
to: number;
@@ -84,6 +91,8 @@ export type JourneyExpectations = {
8491
groups: string[];
8592
};
8693
};
94+
95+
8796
};
8897

8998
export type DatasetProfile = {

cypress/e2e/journeys/flows/grouping-basic-cluster.cy.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import type { DatasetProfile } from '../datasets/profile';
55

66
import {
77
visitAppAndAcceptEula,
8-
applyPreLaunchFileSettings,
98
launchAndWaitForProcessing,
109
goTo2DNetworkView,
1110
assertAfterLaunchCounts,
1211
enableGroupingShow,
13-
assertGroupedByCluster
12+
assertGroupedByCluster,
13+
applyPreLaunchSessionSettings,
14+
applyTwoDGroupingFromProfile,
15+
assertGroupingMembershipFromProfile
1416
} from '../../../support/journey-helpers';
1517

1618
describe('Journey Flow - Grouping (basic) - Cluster', () => {
@@ -22,17 +24,21 @@ describe('Journey Flow - Grouping (basic) - Cluster', () => {
2224

2325
cy.loadFiles(profile.files);
2426

25-
applyPreLaunchFileSettings(profile);
27+
applyPreLaunchSessionSettings(profile);
2628

2729
launchAndWaitForProcessing(60000);
2830

2931
goTo2DNetworkView();
30-
// cy.waitForNetworkToRender(30000);
3132

3233
assertAfterLaunchCounts(profile);
3334

35+
// Either keep the old explicit calls...
3436
enableGroupingShow('cluster');
3537
assertGroupedByCluster();
38+
assertGroupingMembershipFromProfile(profile);
39+
40+
// ...or let the profile drive grouping behavior (including colors/labels):
41+
// applyTwoDGroupingFromProfile(profile);
3642
});
3743
});
3844
});

cypress/e2e/twod-plugin.cy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const selector : any = {
6666
nodeLabelVar: '#node-label-variable',
6767
nodeRadiusSize: '#node-radius',
6868
linkWidthSize: '#link-width',
69-
showGroupsToggle: '#colorPolygonsTable',
69+
showGroupsToggle: '#polygons-show-toggle',
7070
groupByVar: '#polygons-foci',
7171
nodeBorderWidth: '#node-border-width',
7272
showArrowsToggle: '#link-directed-undirected',

cypress/support/commands.ts

Lines changed: 90 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,47 @@ declare global {
5858
}
5959
}
6060
}
61+
62+
const getMimeTypeFromFilename = (name: string): string => {
63+
const ext = (name.split('.').pop() || '').toLowerCase();
64+
65+
if (ext === 'csv') return 'text/csv';
66+
if (ext === 'json' || ext === 'microbetrace' || ext === 'style') return 'application/json';
67+
68+
if (ext === 'fasta' || ext === 'fas' || ext === 'fa' || ext === 'nwk' || ext === 'newick') {
69+
return 'text/plain';
70+
}
6171

62-
Cypress.Commands.add('attach_file', (target_selector, fixture_path, mime_type = 'text/csv') => {
63-
return cy.fixture(fixture_path, 'base64').then((base64) => {
64-
const binary = Cypress.Blob.base64StringToBlob(base64, mime_type);
65-
const file = new File([binary], fixture_path, { type: mime_type });
66-
const data = new DataTransfer();
72+
if (ext === 'xlsx') return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
73+
if (ext === 'xls') return 'application/vnd.ms-excel';
74+
75+
return 'application/octet-stream';
76+
};
77+
78+
Cypress.Commands.add('attach_files', (target_selector, fixture_paths, mime_type) => {
79+
const mimeTypes = (mime_type && mime_type.length)
80+
? mime_type
81+
: fixture_paths.map(getMimeTypeFromFilename);
82+
83+
const data = new DataTransfer();
84+
85+
// Important: chain fixtures so the DataTransfer is fully populated before dispatching change
86+
cy.wrap(fixture_paths, { log: false }).each((fixture_path, idx) => {
87+
const mt = mimeTypes[idx] || 'application/octet-stream';
88+
89+
cy.fixture(fixture_path, 'base64').then((base64) => {
90+
const binary = Cypress.Blob.base64StringToBlob(base64, mt);
91+
const file = new File([binary], fixture_path, { type: mt });
6792
data.items.add(file);
68-
cy.get(target_selector).then(($input) => {
69-
const el = $input.get(0) as HTMLInputElement;
70-
el.files = data.files;
71-
el.dispatchEvent(new Event('change', { bubbles: true }));
72-
});
7393
});
74-
}
75-
);
94+
}).then(() => {
95+
cy.get(target_selector).then(($input) => {
96+
const el = $input.get(0) as HTMLInputElement;
97+
el.files = data.files;
98+
el.dispatchEvent(new Event('change', { bubbles: true }));
99+
});
100+
});
101+
});
76102

77103
// Similar to attach_files(), but allow multiple files to be attached/loaded at once
78104
Cypress.Commands.add('attach_files', (target_selector, fixture_paths, mime_type = ['text/csv']) => {
@@ -92,53 +118,65 @@ declare global {
92118
});
93119

94120
// haven't tested newick, might need some more work when loading json, microbetrace, or auspice datatype
95-
Cypress.Commands.add('loadFiles', (opts: {name: string, datatype: 'link'|'node'|'matrix'|'fasta'|'newick'|'MT/other', field1 ?: string, field2?: string, field3?: string}[]) => {
96-
let fileNames = opts.map(file => file.name);
97-
let mime_types = fileNames.map(name => {
98-
let ext = name.split('.').pop();
99-
if (ext == 'fasta' || 'fas' || 'nwk' || 'newick') return 'text/plain';
100-
if (ext == 'csv') return 'text/csv';
101-
if (ext == 'json' || ext == 'microbetrace') return 'application/json'
102-
return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
103-
})
104-
cy.attach_files('#fileDropRef', fileNames, mime_types);
105-
cy.get('#overlay').should('not.be.visible', { timeout: 10000 });
106-
cy.get('#launch').should('not.be.disabled');
107-
108-
opts.forEach((file, i) => {
109-
cy.contains('#file-table .file-table-row', file.name)
110-
.should('be.visible')
121+
Cypress.Commands.add('loadFiles', (opts: {
122+
name: string,
123+
datatype: 'link'|'node'|'matrix'|'fasta'|'newick'|'MT/other',
124+
field1?: string,
125+
field2?: string,
126+
field3?: string
127+
}[]) => {
128+
const fileNames = opts.map(f => f.name);
129+
const mimeTypes = fileNames.map(getMimeTypeFromFilename);
130+
131+
// Upload (waits until all fixtures are actually attached)
132+
cy.attach_files('#fileDropRef', fileNames, mimeTypes);
133+
134+
// Overlay goes away when file processing is done
135+
cy.get('#overlay', { timeout: 20000 }).should('not.be.visible');
136+
137+
// Launch enabled is a stronger signal than "row is visible"
138+
cy.get('#launch', { timeout: 20000 }).should('not.be.disabled');
139+
140+
// For each row: assert it exists (NOT visible), then set datatype/fields with force
141+
opts.forEach((file) => {
142+
cy.contains('#file-table .file-table-row', file.name, { timeout: 20000 })
143+
.should('exist')
111144
.then(($fileRow) => {
112145
const $row = cy.wrap($fileRow);
113-
114-
// First confirms/sets file.datatype
115-
let activeField: string = $fileRow.find('label.active input').attr('data-type');
116-
if (activeField != file.datatype) {
117-
$row.find(`input[data-type="${file.datatype}"]`).click({force: true})
146+
147+
// datatype toggle
148+
const activeType = $fileRow.find('label.active input').attr('data-type');
149+
if (activeType !== file.datatype) {
150+
$row.find(`input[data-type="${file.datatype}"]`).click({ force: true });
118151
}
119-
cy.wait(5).then(() => expect($fileRow.find('label.active input').attr('data-type')).to.equal(file.datatype))
120-
121-
// Next confirms/sets each field
122-
if (file.datatype == 'link' || file.datatype == 'node') {
123-
let checkField = (expectedValue: string, fieldNumber: number) => {
152+
153+
// field mapping
154+
if (file.datatype === 'link' || file.datatype === 'node') {
155+
const setField = (expectedValue: string, fieldNumber: number) => {
124156
const selectId = `file-${file.name}-field-${fieldNumber}`;
125-
cy.wrap($fileRow).find(`select[id="${selectId}"]`).invoke('val').then((fieldValue) => {
126-
if (fieldValue != expectedValue) {
127-
cy.wrap($fileRow).find(`select[id="${selectId}"]`).select(expectedValue)
128-
}
129-
}).then(() => cy.get(`select[id="${selectId}"]`).should('have.value', expectedValue))
130-
}
131-
132-
if (file.field1) checkField(file.field1, 1)
133-
if (file.field2) checkField(file.field2, 2)
134-
if ( file.datatype== 'link' && file.field3) checkField(file.field3, 3)
157+
158+
cy.wrap($fileRow)
159+
.find(`select[id="${selectId}"]`)
160+
.should('exist')
161+
.then(($sel) => {
162+
const current = String($sel.val());
163+
if (current !== expectedValue) {
164+
cy.wrap($sel).select(expectedValue, { force: true });
165+
}
166+
});
167+
168+
cy.get(`select[id="${selectId}"]`).should('have.value', expectedValue);
169+
};
170+
171+
if (file.field1) setField(file.field1, 1);
172+
if (file.field2) setField(file.field2, 2);
173+
if (file.datatype === 'link' && file.field3) setField(file.field3, 3);
135174
}
136175
});
137176
});
138-
139-
cy.get('#launch').should('not.be.disabled');
140-
}
141-
)
177+
178+
cy.get('#launch', { timeout: 20000 }).should('not.be.disabled');
179+
});
142180

143181
Cypress.Commands.add('closeSettingsPane', (dialogTitle: string) => {
144182
cy.contains('.p-dialog-title', dialogTitle)

0 commit comments

Comments
 (0)