This commit is contained in:
mario
2025-03-07 13:47:44 +07:00
commit c4efec5a14
3358 changed files with 303774 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
describe('OHIF Context Menu', function () {
beforeEach(function () {
cy.checkStudyRouteInViewer('1.2.840.113619.2.5.1762583153.215519.978957063.78');
cy.expectMinimumThumbnails(3);
cy.initCommonElementsAliases();
cy.initCornerstoneToolsAliases();
cy.waitDicomImage();
});
it('checks context menu customization', function () {
// Add length measurement
cy.addLengthMeasurement();
cy.get('[data-cy="prompt-begin-tracking-yes-btn"]').as('yesBtn').click();
cy.get('[data-cy="data-row"]').as('measurementItem').click();
const [x1, y1] = [150, 100];
cy.get('@viewport')
.trigger('mousedown', x1, y1, {
which: 3,
})
.trigger('mouseup', x1, y1, {
which: 3,
});
// Contextmenu is visible
cy.get('[data-cy="context-menu"]').as('contextMenu').should('be.visible');
// Click "Finding" subMenu
cy.get('[data-cy="context-menu-item"]').as('item').contains('Finding').click();
// Click "Finding" subMenu
cy.get('[data-cy="context-menu-item"]').as('item').contains('Aortic insufficiency').click();
cy.get('[data-cy="data-row"]').as('measure-item').contains('Aortic insufficiency');
});
});

View File

@@ -0,0 +1,154 @@
describe('OHIF Cornerstone Hotkeys', () => {
beforeEach(() => {
cy.checkStudyRouteInViewer('1.2.840.113619.2.5.1762583153.215519.978957063.78');
cy.window()
.its('cornerstone')
.then(cornerstone => {
// For debugging issues where tests pass locally but fail on CI
// - Sometimes Cypress orb seems to use CPU rendering pathway
cy.log(`Cornerstone using CPU Rendering?: ${cornerstone.getShouldUseCPURendering()}`);
});
cy.expectMinimumThumbnails(3);
cy.initCornerstoneToolsAliases();
cy.initCommonElementsAliases();
cy.waitDicomImage();
});
it('checks if hotkeys "R" and "L" can rotate the image', () => {
cy.get('body').type('R');
cy.get('@viewportInfoMidLeft').should('contains.text', 'P');
cy.get('@viewportInfoMidTop').should('contains.text', 'R');
// Hotkey L
cy.get('body').type('L');
cy.get('@viewportInfoMidLeft').should('contains.text', 'R');
cy.get('@viewportInfoMidTop').should('contains.text', 'A');
});
it('checks if hotkeys "ArrowUp" and "ArrowDown" can navigate in the stack', () => {
// Hotkey ArrowDown
cy.get('body').type('{downarrow}');
cy.get('@viewportInfoBottomRight').should('contains.text', 'I:2 (2/26)');
// Hotkey ArrowUp
cy.get('body').type('{uparrow}');
cy.get('@viewportInfoBottomRight').should('contains.text', 'I:1 (1/26)');
});
it('checks if hotkeys "V" and "H" can flip the image', () => {
// Hotkey H
cy.get('body').type('h');
cy.get('@viewportInfoMidLeft').should('contains.text', 'L');
cy.get('@viewportInfoMidTop').should('contains.text', 'A');
// Hotkey V
cy.get('body').type('v');
cy.get('@viewportInfoMidLeft').should('contains.text', 'L');
cy.get('@viewportInfoMidTop').should('contains.text', 'P');
});
// it('checks if hotkeys "+", "-" and "=" can zoom in, out and fit to viewport', () => {
// //Click on button and verify if icon is active on toolbar
// cy.get('@zoomBtn')
// .click()
// .then($zoomBtn => {
// cy.wrap($zoomBtn).should('have.class', 'active');
// });
// // Hotkey +
// cy.get('body').type('+++'); // Press hotkey 3 times
// cy.get('@viewportInfoTopLeft').should('contains.text', 'Zoom:2.30x');
// // Hotkey -
// cy.get('body').type('-');
// cy.get('@viewportInfoTopLeft').should('contains.text', 'Zoom:2.09x');
// // Hotkey =
// cy.get('body').type('=');
// cy.get('@viewportInfoTopLeft').should('contains.text', 'Zoom:1.67x');
// });
it('checks if hotkey "SPACEBAR" can reset the image', () => {
// Press multiples hotkeys
cy.get('body').type('v+++i');
cy.get('@viewportInfoMidLeft').should('contains.text', 'R');
cy.get('@viewportInfoMidTop').should('contains.text', 'P');
// Hotkey SPACEBAR
cy.get('body').type(' ');
cy.get('@viewportInfoMidLeft').should('contains.text', 'R');
cy.get('@viewportInfoMidTop').should('contains.text', 'A');
});
/*
// TODO: Pretty sure this is not implemented yet
// it('uses hotkeys "RightArrow" and "LeftArrow" to navigate between multiple viewports', () => {
//Select viewport layout (3,1)
cy.setLayout(3, 1);
cy.waitViewportImageLoading();
// Press multiples hotkeys on viewport #1
cy.get('body').type('VL+++I');
cy.get('@viewportInfoMidLeft').should('contains.text', 'A');
cy.get('@viewportInfoMidTop').should('contains.text', 'R');
cy.get('@viewportInfoBottomRight').should('contains.text', 'Zoom: 134%');
// Hotkey RightArrow: Move to next viewport
cy.get('body').type('{rightarrow}');
// Get overlay information from viewport #2
cy.get(
':nth-child(2) > .viewport-wrapper > .viewport-element > .ViewportOrientationMarkers.noselect > .top-mid.orientation-marker'
).as('viewport2InfoMidTop');
cy.get(
':nth-child(2) > .viewport-wrapper > .viewport-element > .ViewportOrientationMarkers.noselect > .left-mid.orientation-marker'
).as('viewport2InfoMidLeft');
cy.get(
':nth-child(2) > .viewport-wrapper > .viewport-element > .ViewportOverlay > div.bottom-right.overlay-element > div'
).as('viewport2InfoBottomRight');
// Press multiples hotkeys on viewport #2
cy.get('body').type('RR++H+++I');
cy.get('@viewport2InfoMidLeft').should('contains.text', 'P');
cy.get('@viewport2InfoMidTop').should('contains.text', 'H');
cy.get('@viewport2InfoBottomRight').should('contains.text', 'Zoom: 120%');
// Hotkey LeftArrow: Move to previous viewport
cy.get('body').type('{leftarrow}');
// Hotkey SPACEBAR: Reset viewport #1
cy.get('body').type(' ');
cy.get('@viewportInfoMidLeft').should('contains.text', 'R');
cy.get('@viewportInfoMidTop').should('contains.text', 'A');
cy.get('@viewportInfoBottomRight').should('contains.text', 'Zoom: 89%');
// Hotkey RightArrow: Move to next viewport
cy.get('body').type('{rightarrow}');
// Hotkey SPACEBAR: Reset viewport #2
cy.get('body').type(' ');
cy.get('@viewport2InfoMidLeft').should('contains.text', 'A');
cy.get('@viewport2InfoMidTop').should('contains.text', 'H');
cy.get('@viewport2InfoBottomRight').should('contains.text', 'Zoom: 45%');
//Select viewport layout (1,1)
cy.setLayout(1, 1);
});*/
//TO-DO: This test is blocked by issue #1095 (https://github.com/OHIF/Viewers/issues/1095)
//Once issue is fixed, this test can be uncommented
// it('checks if hotkey "Z" activates zoom tool', () => {
// // Hotkey Z
// cy.get('body').type('Z');
// // Verify if icon is active on toolbar
// cy.get('@zoomBtn').should('have.class', 'active');
// });
//TO-DO: This test is blocked by issue #1095 (https://github.com/OHIF/Viewers/issues/1095)
//Once issue is fixed, this test can be uncommented
// it('checks if hotkeys "PageDown" and "PageUp" can navigate in the series thumbnails', () => {
// // Hotkey PageDown
// cy.get('body').type('{pagedown}{pagedown}'); // press hotkey twice
// cy.get('@viewportInfoBottomLeft').should('contains.text', 'Ser: 3');
// // Hotkey PageUp
// cy.get('body').type('{pageup}');
// cy.get('@viewportInfoBottomLeft').should('contains.text', 'Ser: 2');
// });
});

View File

@@ -0,0 +1,462 @@
describe('OHIF Cornerstone Toolbar', () => {
beforeEach(() => {
cy.checkStudyRouteInViewer('1.2.840.113619.2.5.1762583153.215519.978957063.78');
cy.expectMinimumThumbnails(3);
cy.initCornerstoneToolsAliases();
cy.initCommonElementsAliases();
cy.get('[data-cy="study-browser-thumbnail"]').eq(1).click();
//const expectedText = 'Ser: 1';
//cy.get('@viewportInfoBottomLeft').should('contains.text', expectedText);
cy.waitDicomImage();
});
it('checks if all primary buttons are being displayed', () => {
cy.get('@zoomBtn').should('be.visible');
cy.get('@wwwcBtnPrimary').should('be.visible');
cy.get('@wwwcBtnSecondary').should('be.visible');
cy.get('@panBtn').should('be.visible');
cy.get('@measurementToolsBtnPrimary').should('be.visible');
cy.get('@measurementToolsBtnSecondary').should('be.visible');
cy.get('@moreBtnPrimary').should('be.visible');
cy.get('@moreBtnSecondary').should('be.visible');
cy.get('@layoutBtn').should('be.visible');
});
/*it('checks if Stack Scroll tool will navigate across all series in the viewport', () => {
//Click on button and verify if icon is active on toolbar
cy.get('@stackScrollBtn')
.click()
.then($stackScrollBtn => {
cy.wrap($stackScrollBtn).should('have.class', 'active');
});
//drags the mouse inside the viewport to be able to interact with series
cy.get('@viewport')
.trigger('mousedown', 'center', { buttons: 1 })
.trigger('mousemove', 'top', { buttons: 1 })
.trigger('mouseup');
const expectedText =
'Ser: 1Img: 1 1/26256 x 256Loc: -30.00 mm Thick: 5.00 mm';
cy.get('@viewportInfoBottomLeft').should('have.text', expectedText);
});*/
// it('checks if Zoom tool will zoom in/out an image in the viewport', () => {
// //Click on button and verify if icon is active on toolbar
// cy.get('@zoomBtn')
// .click()
// .then($zoomBtn => {
// cy.wrap($zoomBtn).should('have.class', 'active');
// });
// // IMPORTANT: Cypress sends out a mouseEvent which doesn't have the buttons
// // property. This is a workaround to simulate a mouseEvent with the buttons property
// // which is consumed by cornerstone
// cy.get('@viewport')
// .trigger('mousedown', 'center', { buttons: 1 })
// .trigger('mousemove', 'top', {
// buttons: 1,
// })
// .trigger('mouseup', {
// buttons: 1,
// });
// const expectedText = 'Zoom:0.96x';
// cy.get('@viewportInfoTopLeft').should('have.text', expectedText);
// });
it('checks if Levels tool will change the window width and center of an image', () => {
// Wait for the DICOM image to load
// Assign an alias to the button element
cy.get('@wwwcBtnPrimary').as('wwwcButton');
cy.get('@wwwcButton').click();
cy.get('@wwwcButton').should('have.class', 'bg-primary-light');
//drags the mouse inside the viewport to be able to interact with series
cy.get('@viewport')
.trigger('mousedown', 'center', { buttons: 1 })
// Since we have scrollbar on the right side of the viewport, we need to
// force the mousemove since it goes to another element
.trigger('mousemove', 'right', { buttons: 1, force: true })
.trigger('mouseup', { buttons: 1 });
// The exact text is slightly dependent on the viewport resolution, so leave a range
cy.get('@viewportInfoBottomLeft').should($txt => {
const text = $txt.text();
expect(text).to.include('L:479');
});
});
it('checks if Pan tool will move the image inside the viewport', () => {
// Assign an alias to the button element
cy.get('@panBtn').as('panButton');
// Click on the button
cy.get('@panButton').click();
// Assert that the button has the 'active' class
cy.get('@panButton').should('have.class', 'bg-primary-light');
// Trigger the pan actions on the viewport
cy.get('@viewport')
.trigger('mousedown', 'center', { buttons: 1 })
.trigger('mousemove', 'bottom', { buttons: 1 })
.trigger('mouseup', 'bottom');
});
it('checks if Length annotation can be added to viewport and shows up in the measurements panel', () => {
//Click on button and verify if icon is active on toolbar
cy.addLengthMeasurement();
cy.get('[data-cy="viewport-notification"]').as('notif').should('exist');
// cy.get('[data-cy="viewport-notification"]').as('notif').should('be.visible');
cy.get('[data-cy="prompt-begin-tracking-yes-btn"]').as('yesBtn').click();
//Verify the measurement exists in the table
cy.get('@measurementsPanel').should('be.visible');
cy.get('[data-cy="data-row"]').as('measure').its('length').should('be.at.least', 1);
});
/*it('checks if angle annotation can be added on viewport without causing any errors', () => {
//Click on button and verify if icon is active on toolbar
cy.get('@angleBtn')
.click()
.then($angleBtn => {
cy.wrap($angleBtn).should('have.class', 'active'); // TODO: should we just add the 'active' class back? Or use a data property?
});
//Add annotation on the viewport
const initPos = [180, 390];
const midPos = [300, 410];
const finalPos = [180, 450];
cy.addAngle('@viewport', initPos, midPos, finalPos);
});*/
it('checks if Reset tool will reset all changes made on the image', () => {
//Make some changes by zooming in and rotating the image
cy.imageZoomIn();
cy.imageContrast();
//Click on reset button
cy.resetViewport();
const expectedText = 'W:958L:479';
cy.get('@viewportInfoBottomLeft').should('have.text', expectedText);
});
/*it('checks if CINE tool will prompt a modal with working controls', () => {
cy.server();
cy.route('GET', '/!**!/studies/!**!/').as('studies');
//Click on button
cy.get('@cineBtn').click();
// Verify if cine control overlay is being displayed
cy.get('.cine-controls')
.as('cineControls')
.should('be.visible');
//Test PLAY button
cy.get('[title="Play / Stop"]').then($btn => {
$btn.click();
cy.wait(100);
$btn.click();
});
let expectedText = 'Img: 1 1/26';
cy.get('@viewportInfoBottomLeft', { timeout: 15000 }).should(
'not.have.text',
expectedText
);
//Test SKIP TO FIRST IMAGE button
cy.get('[title="Skip to first Image"]')
.click()
.wait(1000);
cy.get('@viewportInfoBottomLeft', { timeout: 15000 }).should(
'contain.text',
expectedText
);
//Test NEXT IMAGE button
cy.get('[title="Next Image"]')
.click()
.wait(1000);
expectedText = 'Img: 2 2/26';
cy.get('@viewportInfoBottomLeft', { timeout: 15000 }).should(
'contain.text',
expectedText
);
//Test SKIP TO LAST IMAGE button
cy.get('[title="Skip to last Image"]')
.click()
.wait(2000);
expectedText = 'Img: 27 26/26';
cy.get('@viewportInfoBottomLeft', { timeout: 15000 }).should(
'contain.text',
expectedText
);
//Test PREVIOUS IMAGE button
cy.get('[title="Previous Image"]')
.click()
.wait(1000);
expectedText = 'Img: 26 25/26';
cy.get('@viewportInfoBottomLeft', { timeout: 15000 }).should(
'contain.text',
expectedText
);
//Click on Cine button
cy.get('@cineBtn')
.click()
.then(() => {
// Verify that cine control overlay is hidden
cy.get('@cineControls').should('not.exist');
});
});*/
/**
it('checks if More button will prompt a modal with secondary tools', () => {
//Click on More button
cy.get('@moreBtnSecondary').click();
//Verify if overlay is displayed
cy.get('[data-cy="MoreTools-list-menu"]')
.as('toolbarOverlay')
.should('be.visible');
// Click on one of the secondary tools from the overlay
cy.get('[data-cy="Magnify"]').click();
// Check if More button is active and if it has same icon as the secondary tool selected
cy.get('@moreBtnPrimary').then($moreBtn => {
cy.wrap($moreBtn)
.should('have.class', 'active')
.should('have.attr', 'data-tool', 'Magnify');
});
// Verify if overlay is hidden
cy.get('@toolbarOverlay').should('not.be.visible');
});
*/
/*it('checks if Layout tool will multiply the number of viewports displayed', () => {
//Click on Layout button and verify if overlay is displayed
cy.get('@layoutBtn')
.click()
.then(() => {
cy.get('.layoutChooser')
.as('layoutChooser')
.should('be.visible')
.find('td')
.its('length')
.should('be.eq', 9);
cy.get('@layoutBtn').click();
});
//verify if layout has changed to 2 viewports
cy.setLayout(1, 2);
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 2);
});
cy.setLayout(2, 1);
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 2);
});
//verify if layout has changed to 3 viewports
cy.setLayout(1, 3);
cy.get('.viewport-container').then($viewport => {
cy.wait(1000);
cy.wrap($viewport)
.its('length')
.should('be.eq', 3);
});
cy.setLayout(3, 1);
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 3);
});
//verify if layout has changed to 4 viewports
cy.setLayout(2, 2);
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 4);
});
//verify if layout has changed to 6 viewports
cy.setLayout(2, 3);
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 6);
});
cy.setLayout(3, 2);
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 6);
});
//verify if layout has changed to 9 viewports
cy.setLayout(3, 3);
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 9);
});
//verify if layout has changed to 1 viewport
cy.setLayout(1, 1);
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 1);
});
});
it('checks if the available viewport was set to active when layout is decreased', () => {
cy.setLayout(3, 3);
// activate the ninth viewport
cy.get('[data-cy=viewport-container-8]')
.click()
.should('have.class', 'active');
cy.setLayout(1, 1);
// first viewport should be active
cy.get('[data-cy=viewport-container-0]').should('have.class', 'active');
});
it('checks if Clear tool will delete all measurements added in the viewport', () => {
//Add measurements in the viewport
cy.addLengthMeasurement();
cy.addAngleMeasurement();
//Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('[data-cy="data-row"]')
.its('length')
.should('be.at.least', 2);
//Click on More button
cy.get('@moreBtn').click();
//Verify if overlay is displayed
cy.get('.tooltip-toolbar-overlay')
.as('toolbarOverlay')
.should('be.visible');
//Click on Clear button
cy.get('[data-cy="clear"]').click();
//Verify if measurements were removed from the measurements panel
//cy.get('.measurementItem'); //.should('not.exist');
//Close More button overlay
cy.get('@moreBtn').click();
//Close the measurements panel
cy.get('@measurementsBtn').then($btn => {
$btn.click();
cy.get('@measurementsPanel').should('not.be.enabled');
});
});
it('check if Rotate tool will change the image orientation in the viewport', () => {
//Click on More button
cy.get('@moreBtn').click();
//Verify if overlay is displayed
cy.get('.tooltip-toolbar-overlay')
.should('be.visible')
.then(() => {
//Click on Rotate button
cy.get('[data-cy="rotate right"]').click({ force: true });
cy.get('@viewportInfoMidLeft').should('contains.text', 'F');
cy.get('@viewportInfoMidTop').should('contains.text', 'R');
});
//Click on More button to close it
cy.get('@moreBtn').click();
});
it('check if Flip H tool will flip the image horizontally in the viewport', () => {
//Click on More button
cy.get('@moreBtn').click();
//Verify if overlay is displayed
cy.get('.tooltip-toolbar-overlay').should('be.visible');
//Click on Flip H button
cy.get('[data-cy="flip h"]').click();
cy.get('@viewportInfoMidLeft').should('contains.text', 'L');
cy.get('@viewportInfoMidTop').should('contains.text', 'H');
//Click on More button to close it
cy.get('@moreBtn').click();
cy.get('.tooltip-toolbar-overlay').should('not.exist');
});
*/
it('check if Flip tool will flip the image in the viewport', () => {
cy.get('@viewportInfoMidLeft').should('contains.text', 'R');
cy.get('@viewportInfoMidTop').should('contains.text', 'A');
//Click on More button
cy.get('@moreBtnSecondary').click();
//Click on Flip button
cy.get('[data-cy="flipHorizontal"]').click();
cy.waitDicomImage();
cy.get('@viewportInfoMidLeft').should('contains.text', 'L');
cy.get('@viewportInfoMidTop').should('contains.text', 'A');
});
// it('checks if stack sync is preserved on new display set and uses FOR', () => {
// // Active stack image sync and reference lines
// cy.get('[data-cy="MoreTools-split-button-secondary"]').click();
// cy.get('[data-cy="ImageSliceSync"]').click();
// // Add reference lines as that sometimes throws an exception
// cy.get('[data-cy="MoreTools-split-button-secondary"]').click();
// cy.get('[data-cy="ReferenceLines"]').click();
// cy.get('[data-cy="study-browser-thumbnail"]:nth-child(2)').dblclick();
// cy.get('body').type('{downarrow}{downarrow}');
// // Change the layout and double load the first
// cy.setLayout(2, 1);
// cy.get('body').type('{rightarrow}');
// cy.get('[data-cy="study-browser-thumbnail"]:nth-child(2)').dblclick();
// cy.waitDicomImage();
// // Now navigate down once and check that the left hand pane navigated
// cy.get('body').focus().type('{downarrow}');
// // The following lines assist in troubleshooting when/if this test were to fail.
// cy.get('[data-cy="viewport-pane"]')
// .eq(0)
// .find('[data-cy="viewport-overlay-top-right"]')
// .should('contains.text', 'I:2 (2/20)');
// cy.get('[data-cy="viewport-pane"]')
// .eq(1)
// .find('[data-cy="viewport-overlay-top-right"]')
// .should('contains.text', 'I:2 (2/20)');
// cy.get('body').type('{leftarrow}');
// cy.setLayout(1, 1);
// cy.get('@viewportInfoTopRight').should('contains.text', 'I:2 (2/20)');
// });
});

View File

@@ -0,0 +1,108 @@
describe('OHIF Download Snapshot File', () => {
beforeEach(() => {
cy.checkStudyRouteInViewer('1.2.840.113619.2.5.1762583153.215519.978957063.78');
cy.expectMinimumThumbnails(3);
cy.openDownloadImageModal();
});
it('checks displayed information for Desktop experience', function () {
// Set Desktop resolution
// cy.viewport(1750, 720);
// Visual comparison
// cy.screenshot('Download Image Modal - Desktop experience');
//Check if all elements are displayed
// TODO: need to add this attribute to the modal
cy.get('[data-cy=modal-header]')
.as('downloadImageModal')
.should('contain.text', 'Download High Quality Image');
// Check input fields
// TODO: select2
// cy.get('[data-cy="file-type"]')
// .select('png')
// .should('have.value', 'png')
// .select('jpg')
// .should('have.value', 'jpg');
// Check image preview
cy.get('[data-cy="image-preview"]').should('contain.text', 'Image preview');
//TODO: This is a canvas now, not an img with src
// cy.get('[data-cy="viewport-preview-img"]')
// .should('have.attr', 'src')
// .and('include', 'data:image');
// Check buttons
cy.get('[data-cy="cancel-btn"]').scrollIntoView().should('be.visible');
cy.get('[data-cy="download-btn"]').scrollIntoView().should('be.visible');
cy.get('[data-cy="cancel-btn"]').click();
});
/*it('cancel changes on download modal', function() {
//Change Image Width, Filename and File Type
cy.get('[data-cy="image-width"]')
.clear()
.type('300');
cy.get('[data-cy="image-height"]') //Image Height should be the same as width
.should('have.value', '300');
cy.get('[data-cy="file-name"]')
.clear()
.type('new-filename');
cy.get('[data-cy="file-type"]').select('png');
//Click on Cancel button
cy.get('[data-cy="cancel-btn"]')
.scrollIntoView()
.click();
//Check modal is closed
cy.get('[data-cy="modal"]').should('not.exist');
//Open Modal
cy.openDownloadImageModal();
//Verify default values was restored
cy.get('[data-cy="image-width"]').should('have.value', '512');
cy.get('[data-cy="file-name"]').should('have.value', 'image');
cy.get('[data-cy=file-type]').should('have.value', 'jpg');
});*/
// TO-DO once issue is fixed: https://github.com/OHIF/Viewers/issues/1217
// it('checks error messages for empty fields', function() {
// //Clear fields Image Width and Filename
// cy.get('[data-cy="image-width"]').clear();
// cy.get('[data-cy="file-name"]').clear();
// //Click on Download button
// cy.get('[data-cy="download-btn"]')
// .scrollIntoView()
// .click();
// //Check error message
// });
/*it('checks if "Show Annotations" checkbox will display annotations', function() {
// Close modal that is initially opened
cy.get('[data-cy="close-button"]').click();
// Add measurements in the viewport
cy.addLengthMeasurement();
cy.addAngleMeasurement();
// Open Modal
cy.openDownloadImageModal();
// Select "Show Annotations" option
cy.get('[data-cy="show-annotations"]').check();
// Check image preview
cy.get('[data-cy="image-preview"]').scrollIntoView();
//Compare classes that exists on Image Preview with Annotations and Without Annotation
cy.get('[data-cy="modal-content"]')
.find('canvas')
.should('have.class', 'magnifyTool'); //Class "MagnifyTool" exists with annotations displayed on Image preview
// Uncheck "Show Annotations" option
cy.get('[data-cy="show-annotations"]')
.uncheck()
.wait(300);
// Check that class "MagnifyTool" should not exist
cy.get('[data-cy="modal-content"]')
.find('canvas')
.should('not.have.class', 'magnifyTool');
});*/
});

View File

@@ -0,0 +1,92 @@
describe('OHIF General Viewer', function () {
beforeEach(() =>
cy.initViewer('1.2.840.113619.2.5.1762583153.215519.978957063.78', {
minimumThumbnails: 3,
})
);
it('scrolls series stack using scrollbar', function () {
cy.scrollToIndex(13);
cy.get('@viewportInfoBottomRight').should('contains.text', '14');
});
it('performs right click to zoom', function () {
// This is not used to activate the tool, it is used to ensure the
// top left viewport info shows the zoom values (it only shows up
// when the zoom tool is active)
cy.get('@zoomBtn')
.click()
.then($zoomBtn => {
cy.wrap($zoomBtn).should('have.class', 'bg-primary-light');
});
const zoomLevelInitial = cy.get('@viewportInfoTopLeft').then($viewportInfo => {
return $viewportInfo.text().substring(6, 9);
});
//Right click on viewport
cy.get('@viewport')
.trigger('mousedown', 'top', { buttons: 2 })
.trigger('mousemove', 'center', { buttons: 2 })
.trigger('mouseup');
// make sure the new zoom level is less than the initial
cy.get('@viewportInfoBottomLeft').then($viewportInfo => {
const zoomLevelFinal = $viewportInfo.text().substring(6, 9);
expect(zoomLevelFinal < zoomLevelInitial).to.eq(true);
});
});
/*it('performs middle click to pan', function() {
//Get image position from cornerstone and check if y axis was modified
let cornerstone;
let currentPan;
// TO DO: Replace the cornerstone pan check by Percy snapshot comparison
cy.window()
.its('cornerstone')
.then(c => {
cornerstone = c;
currentPan = () =>
cornerstone.getEnabledElements()[0].viewport.translation;
});
//pan image with middle click
cy.get('@viewport')
.trigger('mousedown', 'center', { buttons: 3 })
.trigger('mousemove', 'bottom', { buttons: 3 })
.trigger('mouseup', 'bottom')
.then(() => {
expect(currentPan().y > 0).to.eq(true);
});
});*/
/*it('opens About modal and verify the displayed information', function() {
cy.get('[data-cy="options-dropdown"]')
.first()
.click();
cy.get('[data-cy="about-modal"]')
.as('aboutOverlay')
.should('be.visible');
//check buttons and links
cy.get('[data-cy="about-modal"]')
.should('contains.text', 'Visit the forum')
.and('contains.text', 'Report an issue')
.and('contains.text', 'https://github.com/OHIF/Viewers/');
//check version number
cy.get('[data-cy="about-modal"]').then($modal => {
cy.get('[data-cy="header-version-info"]').should($headerVersionNumber => {
$headerVersionNumber = $headerVersionNumber.text().substring(1);
expect($modal).to.contain($headerVersionNumber);
});
});
//close modal
cy.get('[data-cy="close-button"]').click();
cy.get('@aboutOverlay').should('not.exist');
});
*/
});

View File

@@ -0,0 +1,218 @@
describe('OHIF Measurement Panel', function () {
beforeEach(function () {
cy.checkStudyRouteInViewer('1.2.840.113619.2.5.1762583153.215519.978957063.78');
cy.expectMinimumThumbnails(3);
cy.initCommonElementsAliases();
cy.initCornerstoneToolsAliases();
cy.waitDicomImage();
});
it('checks if Measurements right panel can be hidden/displayed', function () {
cy.get('@measurementsPanel').should('exist');
cy.get('@measurementsPanel').should('be.visible');
cy.get('@RightCollapseBtn').click();
cy.get('@measurementsPanel').should('not.exist');
cy.get('@RightCollapseBtn').click();
// segmentation panel should be visible
cy.get('@segmentationPanel').should('be.visible');
// measurements panel should be clickable
cy.get('@measurementsBtn').click();
cy.get('@measurementsPanel').should('be.visible');
});
it('checks if measurement item can be Relabeled under Measurements panel', function () {
// Add length measurement
cy.addLengthMeasurement();
cy.get('[data-cy="viewport-notification"]').as('viewportNotification').should('exist');
cy.get('[data-cy="viewport-notification"]').as('viewportNotification').should('be.visible');
cy.get('[data-cy="prompt-begin-tracking-yes-btn"]').as('yesBtn').click();
cy.get('[data-cy="data-row"]').as('measurementItem').click();
cy.get('[data-cy="data-row"]').find('svg').eq(0).as('measurementItemSvg').click();
// enter Bone label
// Todo: move it to the new annotation input with drop down
// cy.get('[data-cy="input-annotation"]').should('exist');
// cy.get('[data-cy="input-annotation"]').should('be.visible');
// cy.get('[data-cy="input-annotation"]').type('Bone{enter}');
// cy.get('[data-cy="data-row"]').as('measurementItem').should('contain.text', 'Bone');
});
it('checks if image would jump when clicked on a measurement item', function () {
cy.get('[data-cy="study-browser-thumbnail"][data-series="1"]').dblclick();
cy.wait(250);
cy.scrollToIndex(0);
// Add length measurement
cy.addLengthMeasurement().wait(250);
cy.get('[data-cy="prompt-begin-tracking-yes-btn"]').as('yesBtn').click();
cy.scrollToIndex(13);
// Reset to default tool so that the new add length works
cy.addLengthMeasurement([100, 100], [200, 200]); //Adding measurement in the viewport
cy.get('@viewportInfoBottomRight').should('contains.text', '(14/');
// Click on first measurement item
cy.get('[data-cy="data-row"]').eq(0).click();
cy.get('@viewportInfoBottomRight').should('contains.text', '(1/');
cy.get('@viewportInfoBottomRight').should('not.contains.text', '(14/');
});
/*
TODO: Not sure why this is failing
it('checks if Description can be added to measurement item under Measurements panel', () => {
cy.addLengthMeasurement(); //Adding measurement in the viewport
cy.get('@measurementsBtn').click();
cy.get('.measurementItem').click();
// Click "Description"
cy.get('.btnAction')
.contains('Description')
.click();
// Enter description text
const descriptionText = 'Adding text for description test';
cy.get('#description').type(descriptionText);
// Confirm
cy.get('.btn-confirm').click();
//Verify if descriptionText was added
cy.get('.measurementLocation').should('contain.text', descriptionText);
// Remove the measurement we just added
cy.get('.btnAction')
.last()
.contains('Delete')
.click()
// Close panel
cy.get('@measurementsBtn').click();
cy.get('@measurementsPanel').should('not.be.enabled');
});
*/
/*it('checks if measurement item can be deleted through the context menu on the viewport', function() {
cy.addLengthMeasurement([100, 100], [200, 100]); //Adding measurement in the viewport
//Right click on measurement annotation
const [x1, y1] = [150, 100];
cy.get('@viewport')
.trigger('mousedown', x1, y1, {
which: 3,
})
.trigger('mouseup', x1, y1, {
which: 3,
})
.wait(300)
.then(() => {
//Contextmenu is visible
cy.get('.ToolContextMenu').should('be.visible');
});
//Click "Delete measurement"
cy.get('.form-action')
.contains('Delete measurement')
.click();
//Open measurements menu
cy.get('@measurementsBtn').click();
//Verify measurements was removed from panel
cy.get('.measurementItem')
.should('not.exist')
.log('Annotation successfully removed');
//Close panel
cy.get('@measurementsBtn').click();
cy.get('@measurementsPanel').should('not.exist');
});*/
/*it('adds relabel and description to measurement item through the context menu on the viewport', function() {
cy.addLengthMeasurement([100, 100], [200, 100]); //Adding measurement in the viewport
// Relabel
// Right click on measurement annotation
const [x1, y1] = [150, 100];
cy.get('@viewport')
.trigger('mousedown', x1, y1, {
which: 3,
})
.trigger('mouseup', x1, y1, {
which: 3,
});
// Contextmenu is visible
cy.get('.ToolContextMenu').should('be.visible');
// Click "Relabel"
cy.get('.form-action')
.contains('Relabel')
.click();
// Search for "Brain"
cy.get('.searchInput').type('Brain');
// Select "Brain" Result
cy.get('.treeInputs > .wrapperLabel')
.contains('Brain')
.click();
// Confirm Selection
cy.get('.checkIconWrapper').click();
// Description
// Right click on measurement annotation
cy.get('@viewport')
.trigger('mousedown', x1, y1, {
which: 3,
})
.trigger('mouseup', x1, y1, {
which: 3,
});
// Contextmenu is visible
cy.get('.ToolContextMenu').should('be.visible');
// Click "Description"
cy.get('.form-action')
.contains('Add Description')
.click();
// Enter description text
const descriptionText = 'Adding text for description test';
cy.get('#description').type(descriptionText);
// Confirm
cy.get('.btn-confirm').click();
//Open measurements menu
cy.get('@measurementsBtn').click();
// Verify if label was added
cy.get('.measurementLocation')
.should('contain.text', 'Brain')
.log('Relabel added with success');
//Verify if descriptionText was added
cy.get('.measurementLocation')
.should('contain.text', descriptionText)
.log('Description added with success');
// Close panel
cy.get('@measurementsBtn').click();
cy.get('@measurementsPanel').should('not.exist');
});*/
});

View File

@@ -0,0 +1,150 @@
/*describe('OHIF Save Measurements', function() {
before(() => {
cy.checkStudyRouteInViewer(
'1.2.840.113619.2.5.1762583153.215519.978957063.78'
);
cy.expectMinimumThumbnails(3);
});
beforeEach(() => {
// Wait image to load on viewport
cy.wait(2000);
cy.resetViewport();
cy.initCommonElementsAliases();
});
it('saves new measurement annotation', function() {
// Add measurement in the viewport
cy.addLengthMeasurement();
// Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.at.least', 1);
// TODO: Don't save until we're using in-memory data store
// Save new measurement
// cy.get('[data-cy="save-measurements-btn"]').click();
// Verify that success message overlay is displayed
// cy.get('.sb-success')
// .should('be.visible')
// .and('contains.text', 'Measurements saved successfully');
// Visual test comparison
cy.screenshot('Save Measurements - new measurement added');
cy.percyCanvasSnapshot('Save Measurements - new measurement added');
});
// it('retrieves saved measurements', function() {
// // Add measurement in the viewport
// cy.addLengthMeasurement();
// // Verify if measurement annotation was added into the measurements panel
// cy.get('@measurementsBtn').click();
// cy.get('.measurementDisplayText') // Get label size of the recently added measurement
// .last()
// .then($measurementSizeLabel => {
// // Save new measurement
// // TODO: Do not save
// cy.get('[data-cy="save-measurements-btn"]')
// .click()
// .then(() => {
// // Verify that success message overlay is displayed
// cy.get('.sb-success').should('be.visible');
// });
// // Reload the page
// cy.reload()
// .wait(1000) //Wait page to load
// .expectMinimumThumbnails(2); //wait all thumbnails to load
// // Verify that recently added measurement was retrieved
// cy.get('@measurementsBtn').click();
// cy.get('.measurementDisplayText') // Get label size of the recently added measurement
// .last()
// .then($retrivedMeasurementSizeLabel => {
// expect($retrivedMeasurementSizeLabel.textContent).to.eq(
// $measurementSizeLabel.textContent
// );
// });
// });
// });
// it('checks error message when saving without any measurement', function() {
// // Checks that measurement list is empty
// cy.get('.numberOfItems').should('have.text', '0');
// // Click on Save Measurement button
// cy.get('[data-cy="save-measurements-btn"]').click();
// // Verify that error message overlay is displayed
// cy.get('.sb-error')
// .should('be.visible')
// .and('contains.text', 'Error while saving the measurements');
// // Close message overlay
// cy.get('.sb-closeIcon').click();
// });
it('checks if warning message is displayed on measurements of unsupported tools', function() {
// Add measurement for unsupported tool in the viewport
cy.addAngleMeasurement();
// Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.at.least', 1);
// Check that warning is displayed for unsupported tool
cy.get('.hasWarnings').should('be.visible');
// // Save new measurement
// cy.get('[data-cy="save-measurements-btn"]').click();
// // Verify that error message overlay is displayed
// cy.get('.sb-error')
// .should('be.visible')
// .and('contains.text', 'Error while saving the measurements');
// Close Measurements panel
cy.get('@measurementsBtn').click();
});
/*it('checks if measurements of unsupported tools were not saved', function() {
// Add measurement for supported tool in the viewport
cy.addLengthMeasurement();
// Add measurement for unsupported tool in the viewport
cy.addAngleMeasurement();
// Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.eq', 2);
// Check that warning is displayed for unsupported tool
cy.get('.hasWarnings').should('be.visible');
// Save new measurement
cy.get('[data-cy="save-measurements-btn"]').click();
// Verify that success message overlay is displayed
cy.get('.sb-success')
.should('be.visible')
.and('contains.text', 'Measurements saved successfully');
// Reload the page
cy.reload()
.wait(1000) //Wait page to load
.expectMinimumThumbnails(2); //wait all thumbnails to load
//Verify that measurement for unsupported tool was not saved
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.eq', 1);
// Close Measurements panel
cy.get('@measurementsBtn').click();
});
});*/

View File

@@ -0,0 +1,60 @@
describe('OHIF Study Browser', function () {
beforeEach(function () {
cy.checkStudyRouteInViewer('1.2.840.113619.2.5.1762583153.215519.978957063.78');
cy.expectMinimumThumbnails(3);
cy.initCommonElementsAliases();
cy.initCornerstoneToolsAliases();
});
it('checks if series thumbnails are being displayed', function () {
cy.get('[data-cy="study-browser-thumbnail"]').its('length').should('be.gt', 1);
});
it('drags and drop a series thumbnail into viewport', function () {
// Can't use the native drag version as the element should be rerendered
// cy.get('[data-cy="study-browser-thumbnail"]:nth-child(2)') //element to be dragged
// .drag('.cornerstone-canvas'); //dropzone element
const dataTransfer = new DataTransfer();
cy.get('[data-cy="study-browser-thumbnail"]:nth-child(2)').as('seriesThumbnail');
cy.get('@seriesThumbnail')
.first()
.trigger('mousedown', { which: 1, button: 0 })
.trigger('dragstart', { dataTransfer })
.trigger('drag', {});
cy.get('.cornerstone-canvas').as('viewport');
cy.get('@viewport')
.trigger('mousemove', 'center')
.trigger('dragover', { dataTransfer, force: true })
.trigger('drop', { dataTransfer, force: true });
//const expectedText =
// 'Ser: 2Img: 1 1/13512 x 512Loc: -17.60 mm Thick: 3.00 mm';
//cy.get('@viewportInfoBottomLeft').should('contain.text', expectedText);
});
it('checks if Series left panel can be hidden/displayed', function () {
cy.get('@seriesPanel').should('exist');
cy.get('@seriesPanel').should('be.visible');
cy.get('@seriesBtn').click();
cy.get('@seriesPanel').should('not.exist');
cy.get('@seriesBtn').click();
cy.get('@seriesPanel').should('exist');
cy.get('@seriesPanel').should('be.visible');
});
it('performs double-click to load thumbnail in active viewport', () => {
// Have to finish rendering the image before this works
cy.wait(350);
cy.get('[data-cy="study-browser-thumbnail"]:nth-child(2)').dblclick();
//cy.get('@viewportInfoBottomLeft').should('contains.text', expectedText);
});
});