tests: Test cases implemented: Cornerstone tools Clear and Eraser; Measurement panel Relabel and Description (#1014)

* Fix for test scripts that were failing in CI

* Test cases for tools: Length and Angle

* Test cases implemented: Scroll series, Levels, Pan, Reset, Zoom

* Added test cases for tools: Cine, More, Layout, Invert, Rotate, FlipH, FlipV

* Fixes made according to comments on PR review

* Fixes for failing scenarios: Layout and Cine

* Test cases implemented: Cornerstone tools Clear and Eraser; Measurement panel Relabel and Description

* Fix for CI failure
This commit is contained in:
Mirna Silva 2019-10-10 16:46:41 -03:00 committed by Danny Brown
parent e51529e6c9
commit a36cb63926
4 changed files with 590 additions and 404 deletions

View File

@ -1,407 +1,457 @@
describe('OHIF Cornerstone Toolbar', () => {
before(() => {
cy.openStudy("MISTER^MR");
cy.waitDicomImage();
cy.openStudy('MISTER^MR');
cy.waitDicomImage();
});
beforeEach(() => {
cy.initCornerstoneToolsAliases();
cy.initCommonElementsAliases();
//Following best practices, reset should be done before each test
cy.resetViewport();
});
it('checks if all primary buttons are being displayed', () => {
cy.get('@stackScrollBtn')
.should('be.visible')
.contains('Stack Scroll');
cy.get('@zoomBtn')
.should('be.visible')
.contains('Zoom');
cy.get('@levelsBtn')
.should('be.visible')
.contains('Levels');
cy.get('@panBtn')
.should('be.visible')
.contains('Pan');
cy.get('@lengthBtn')
.should('be.visible')
.contains('Length');
cy.get('@annotateBtn')
.should('be.visible')
.contains('Annotate');
cy.get('@angleBtn')
.should('be.visible')
.contains('Angle');
cy.get('@resetBtn')
.should('be.visible')
.contains('Reset');
cy.get('@cineBtn')
.should('be.visible')
.contains('CINE');
cy.get('@moreBtn')
.should('be.visible')
.contains('More');
cy.get('@twodmprBtn')
.should('be.visible')
.contains('2D MPR');
cy.get('@layoutBtn')
.should('be.visible')
.contains('Layout');
});
it('checks if Stack Scroll tool will navigate across all series in the viewport', () => {
//Click on button and vefiry 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', 'top', { which: 1 })
.trigger('mousemove', 'center', { which: 1 })
.trigger('mouseup');
const expectedText =
'Ser: 1Img: 14 14/26256 x 256Loc: 0.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 vefiry if icon is active on toolbar
cy.get('@zoomBtn')
.click()
.then($zoomBtn => {
cy.wrap($zoomBtn).should('have.class', 'active');
});
//drags the mouse inside the viewport to be able to interact with series
cy.get('@viewport')
.trigger('mousedown', 'top', { which: 1 })
.trigger('mousemove', 'center', { which: 1 })
.trigger('mouseup');
const expectedText = 'Zoom: 884%W: 820 L: 410Lossless / Uncompressed';
cy.get('@viewportInfoBottomRight').should('have.text', expectedText);
});
it('checks if Levels tool will change the contrast and brightness of an image in the viewport', () => {
//Click on button and vefiry if icon is active on toolbar
cy.get('@levelsBtn')
.click()
.then($levelsBtn => {
cy.wrap($levelsBtn).should('have.class', 'active');
});
//drags the mouse inside the viewport to be able to interact with series
cy.get('@viewport')
.trigger('mousedown', 'top', { which: 1 })
.trigger('mousemove', 'center', { which: 1 })
.trigger('mouseup')
.trigger('mousedown', 'center', { which: 1 })
.trigger('mousemove', 'left', { which: 1 })
.trigger('mouseup');
const expectedText = 'Zoom: 211%W: 544 L: 626Lossless / Uncompressed';
cy.get('@viewportInfoBottomRight').should('have.text', expectedText);
});
it('checks if Pan tool will move the image inside the viewport', () => {
//Click on button and vefiry if icon is active on toolbar
cy.get('@panBtn')
.click()
.then($panBtn => {
cy.wrap($panBtn).should('have.class', 'active');
});
//Get image position from cornerstone and check if y axis was modified
let cornerstone;
let currentPan;
cy.window()
.its('cornerstone')
.then(c => {
cornerstone = c;
currentPan = () =>
cornerstone.getEnabledElements()[0].viewport.translation;
});
cy.get('@viewport')
.trigger('mousedown', 'center', { which: 1 })
.trigger('mousemove', 'bottom', { which: 1 })
.trigger('mouseup', 'bottom')
.then(() => {
expect(currentPan().y > 0).to.eq(true);
});
});
it('checks if Length annotation can be added on viewport and on measurements panel', () => {
//Click on button and vefiry if icon is active on toolbar
cy.get('@lengthBtn')
.click()
.then($lengthbtn => {
cy.wrap($lengthbtn).should('have.class', 'active');
});
//Add annotation on the viewport
const firstClick = [150, 100];
const secondClick = [130, 170];
cy.addLine('.cornerstone-canvas', firstClick, secondClick);
//Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn')
.click()
.then($measurementsBtn => {
cy.get('@measurementsPanel').should('be.visible');
cy.get('.measurementItem')
.its('length')
.should('be.eq', 1);
cy.wrap($measurementsBtn).click();
});
});
it('checks if Angle annotation can be added on viewport and on measurements panel', () => {
//Click on button and vefiry if icon is active on toolbar
cy.get('@angleBtn')
.click()
.then($angleBtn => {
cy.wrap($angleBtn).should('have.class', 'active');
});
//Add annotation on the viewport
const initPos = [180, 390];
const midPos = [300, 410];
const finalPos = [180, 450];
cy.addAngle('.cornerstone-canvas', initPos, midPos, finalPos);
//Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn')
.click()
.then($measurementsBtn => {
cy.get('@measurementsPanel').should('be.visible');
cy.get('.measurementItem')
.its('length')
.should('be.eq', 1);
cy.wrap($measurementsBtn).click();
});
});
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.get('@resetBtn').click();
const expectedText = 'Zoom: 211%W: 820 L: 410Lossless / Uncompressed';
cy.get('@viewportInfoBottomRight').should('have.text', expectedText);
});
it('checks if CINE tool will prompt a modal with working controls', () => {
//Click on button
cy.get('@cineBtn').click();
//Vefiry if cine control overlay is being displayed
cy.get('.cine-controls')
.as('cineControls')
.should('be.visible');
//Test PLAY button
cy.get('[title="Play / Stop"]')
.click()
.wait(100)
.click();
let expectedText = 'Img: 1 1/26';
cy.get('@viewportInfoBottomLeft').should('not.have.text', expectedText);
//Test SKIP TO FIRST IMAGE button
cy.get('[title="Skip to first Image"]').click();
cy.get('@viewportInfoBottomLeft').should('contain.text', expectedText);
//Test NEXT IMAGE button
cy.get('[title="Next Image"]').click();
expectedText = 'Img: 2 2/26';
cy.get('@viewportInfoBottomLeft').should('contain.text', expectedText);
//Test SKIP TO LAST IMAGE button
cy.get('[title="Skip to last Image"]').click();
expectedText = 'Img: 27 26/26';
cy.get('@viewportInfoBottomLeft').should('contain.text', expectedText);
//Test PREVIOUS IMAGE button
cy.get('[title="Previous Image"]').click();
expectedText = 'Img: 26 25/26';
cy.get('@viewportInfoBottomLeft').should('contain.text', expectedText);
//Click on Cine button
cy.get('@cineBtn').click();
//Vefiry if cine control overlay is hidden
cy.get('@cineControls').should('not.be.visible');
});
it('checks if More button will prompt a modal with secondary tools', () => {
cy.get('@moreBtn').click();
//Verify if overlay is displayed
cy.get('.tooltip-toolbar-overlay')
.as('toolbarOverlay')
.should('be.visible');
let iconName;
//Click on one of the secondary tools from the overlay
cy.get('.tooltip-inner > :nth-child(1)')
.click()
.then($magnifyBtn => {
cy.wrap($magnifyBtn)
.should('have.class', 'active')
.find('svg')
.then($icon => {
iconName = $icon.text();
});
});
//Check if More button is active and if it has same icon as the secondary tool selected
cy.get('@moreBtn')
.click()
.then($moreBtn => {
cy.wrap($moreBtn)
.should('have.class', 'active')
.contains(iconName);
});
//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);
});
//verify if layout has changed to 2 viewports
cy.get('tbody > :nth-child(1) > :nth-child(2)').click();
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 2);
});
beforeEach(() => {
//Creating aliases for Cornerstone tools buttons
cy.get('.toolbar-button:nth-child(2)').as('stackScrollBtn');
cy.get('.toolbar-button:nth-child(3)').as('zoomBtn');
cy.get('.toolbar-button:nth-child(4)').as('levelsBtn');
cy.get('.toolbar-button:nth-child(5)').as('panBtn');
cy.get('.toolbar-button:nth-child(6)').as('lengthBtn');
cy.get('.toolbar-button:nth-child(7)').as('annotateBtn');
cy.get('.toolbar-button:nth-child(8)').as('angleBtn');
cy.get('.toolbar-button:nth-child(9)').as('resetBtn');
cy.get('.toolbar-button:nth-child(10)').as('cineBtn');
cy.get('.expandableToolMenu').as('moreBtn');
cy.get('.PluginSwitch > .toolbar-button').as('twodmprBtn');
cy.get('.btn-group > .toolbar-button').as('layoutBtn');
cy.get('.pull-right > .RoundedButtonGroup > .roundedButtonWrapper > .roundedButton').as('measurementsBtn');
cy.get('.viewport-element').as('viewport');
cy.get('section.sidepanel.from-right').as('measurementsPanel')
//Following best practices, reset should be done before each test
cy.resetViewport();
})
it('checks if all primary buttons are being displayed', () => {
cy.get('@stackScrollBtn').should('be.visible').contains('Stack Scroll');
cy.get('@zoomBtn').should('be.visible').contains('Zoom');
cy.get('@levelsBtn').should('be.visible').contains('Levels');
cy.get('@panBtn').should('be.visible').contains('Pan');
cy.get('@lengthBtn').should('be.visible').contains('Length');
cy.get('@annotateBtn').should('be.visible').contains('Annotate');
cy.get('@angleBtn').should('be.visible').contains('Angle');
cy.get('@resetBtn').should('be.visible').contains('Reset');
cy.get('@cineBtn').should('be.visible').contains('CINE');
cy.get('@moreBtn').should('be.visible').contains('More');
cy.get('@twodmprBtn').should('be.visible').contains('2D MPR');
cy.get('@layoutBtn').should('be.visible').contains('Layout');
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(2) > :nth-child(1)').click();
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 2);
});
it('checks if Stack Scroll tool will navigate across all series in the viewport', () => {
//Click on button and vefiry 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', 'top', { which: 1 })
.trigger('mousemove', 'center', { which: 1 })
.trigger('mouseup');
const overlaySeriesInformation = 'div.ViewportOverlay > div.bottom-left.overlay-element > div';
const expectedText = 'Ser: 1Img: 14 14/26256 x 256Loc: 0.00 mm Thick: 5.00 mm';
cy.get(overlaySeriesInformation)
.should('have.text', expectedText);
//verify if layout has changed to 3 viewports
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(1) > :nth-child(3)').click();
cy.get('.viewport-container').then($viewport => {
cy.wait(1000);
cy.wrap($viewport)
.its('length')
.should('be.eq', 3);
});
it('checks if Zoom tool will zoom in/out an image in the viewport', () => {
//Click on button and vefiry if icon is active on toolbar
cy.get('@zoomBtn')
.click()
.then(($zoomBtn) =>{
cy.wrap($zoomBtn)
.should('have.class', 'active')
})
//drags the mouse inside the viewport to be able to interact with series
cy.get('@viewport')
.trigger('mousedown', 'top', { which: 1 })
.trigger('mousemove', 'center', { which: 1 })
.trigger('mouseup');
const overlaySeriesInformation = 'div.ViewportOverlay > div.bottom-right.overlay-element > div';
const expectedText = 'Zoom: 884%W: 820 L: 410Lossless / Uncompressed';
cy.get(overlaySeriesInformation)
.should('have.text', expectedText);
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(3) > :nth-child(1)').click();
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 3);
});
it('checks if Levels tool will change the contrast and brightness of an image in the viewport', () => {
//Click on button and vefiry if icon is active on toolbar
cy.get('@levelsBtn')
.click()
.then(($levelsBtn) =>{
cy.wrap($levelsBtn)
.should('have.class', 'active')
})
//drags the mouse inside the viewport to be able to interact with series
cy.get('@viewport')
.trigger('mousedown', 'top', { which: 1 })
.trigger('mousemove', 'center', { which: 1 })
.trigger('mouseup')
.trigger('mousedown', 'center', { which: 1 })
.trigger('mousemove', 'left', { which: 1 })
.trigger('mouseup');
const overlaySeriesInformation = 'div.ViewportOverlay > div.bottom-right.overlay-element > div';
const expectedText = 'Zoom: 211%W: 544 L: 626Lossless / Uncompressed';
cy.get(overlaySeriesInformation)
.should('have.text', expectedText);
});
it('checks if Pan tool will move the image inside the viewport', () => {
//Click on button and vefiry if icon is active on toolbar
cy.get('@panBtn')
.click()
.then(($panBtn) =>{
cy.wrap($panBtn)
.should('have.class', 'active')
})
//Get image position from cornerstone and check if y axis was modified
let cornerstone;
let currentPan;
cy.window()
.its('cornerstone')
.then((c) => {
cornerstone = c;
currentPan = () => cornerstone.getEnabledElements()[0].viewport.translation;
});
cy.get('@viewport')
.trigger('mousedown', 'center', { which: 1 })
.trigger('mousemove', 'bottom', { which: 1 })
.trigger('mouseup', 'bottom')
.then(() => {
expect(currentPan().y > 0).to.eq(true);
});
//verify if layout has changed to 4 viewports
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(2) > :nth-child(2)').click();
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 4);
});
it('checks if Length annotation can be added on viewport and on measurements panel', () => {
//Click on button and vefiry if icon is active on toolbar
cy.get('@lengthBtn')
.click()
.then(($lengthbtn) =>{
cy.wrap($lengthbtn)
.should('have.class', 'active')
})
//Add annotation on the viewport
const firstClick = [150, 100];
const secondClick = [130, 170];
cy.addLine('.cornerstone-canvas', firstClick, secondClick)
//Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn')
.click()
.then($measurementsBtn => {
cy.get('@measurementsPanel')
.should('be.visible');
cy.get('.measurementItem')
.its('length')
.should('be.eq', 1);
cy.wrap($measurementsBtn)
.click();
})
//verify if layout has changed to 6 viewports
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(2) > :nth-child(3)').click();
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 6);
});
it('checks if Angle annotation can be added on viewport and on measurements panel', () => {
//Click on button and vefiry if icon is active on toolbar
cy.get('@angleBtn')
.click()
.then(($angleBtn) =>{
cy.wrap($angleBtn)
.should('have.class', 'active')
})
//Add annotation on the viewport
const initPos = [180, 390];
const midPos = [300, 410];
const finalPos = [180, 450];
cy.addAngle('.cornerstone-canvas', initPos, midPos, finalPos);
//Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn')
.click()
.then($measurementsBtn => {
cy.get('@measurementsPanel')
.should('be.visible');
cy.get('.measurementItem')
.its('length')
.should('be.eq', 2);
cy.wrap($measurementsBtn)
.click();
})
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(3) > :nth-child(2)').click();
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 6);
});
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.get('@resetBtn').click()
const overlaySeriesInformation = 'div.ViewportOverlay > div.bottom-right.overlay-element > div';
const expectedText = 'Zoom: 211%W: 820 L: 410Lossless / Uncompressed';
cy.get(overlaySeriesInformation)
.should('have.text', expectedText);
});
it('checks if CINE tool will prompt a modal with working controls', () => {
//Click on button
cy.get('@cineBtn')
.click();
//Vefiry if cine control overlay is being displayed
cy.get('.cine-controls').as('cineControls')
.should('be.visible');
//Test PLAY button
cy.get('[title="Play / Stop"]')
.click()
.wait(100)
.click();
const overlaySeriesInformation = 'div.ViewportOverlay > div.bottom-left.overlay-element > div';
let expectedText = 'Img: 1 1/26';
cy.get(overlaySeriesInformation)
.should('not.have.text', expectedText);
//Test SKIP TO FIRST IMAGE button
cy.get('[title="Skip to first Image"]')
.click()
cy.get(overlaySeriesInformation)
.should('contain.text', expectedText);
//Test NEXT IMAGE button
cy.get('[title="Next Image"]') //Title is wrong and was reported on bug #995: https://github.com/OHIF/Viewers/issues/995
.click()
expectedText = 'Img: 2 2/26';
cy.get(overlaySeriesInformation)
.should('contain.text', expectedText);
//Test SKIP TO LAST IMAGE button
cy.get('[title="Skip to last Image"]') //Title is wrong and was reported on bug #995: https://github.com/OHIF/Viewers/issues/995
.click()
expectedText = 'Img: 27 26/26';
cy.get(overlaySeriesInformation)
.should('contain.text', expectedText);
//Test PREVIOUS IMAGE button
cy.get('[title="Previous Image"]')
.click()
expectedText = 'Img: 26 25/26';
cy.get(overlaySeriesInformation)
.should('contain.text', expectedText);
//Click on Cine button
cy.get('@cineBtn')
.click();
//Vefiry if cine control overlay is hidden
cy.get('@cineControls')
.should('not.be.visible');
});
it('checks if More button will prompt a modal with secondary tools', () => {
cy.get('@moreBtn')
.click();
//Verify if overlay is displayed
cy.get('.tooltip-toolbar-overlay').as('toolbarOverlay')
.should('be.visible');
let iconName;
//Click on one of the secondary tools from the overlay
cy.get('.tooltip-inner > :nth-child(1)')
.click()
.then(($magnifyBtn) =>{
cy.wrap($magnifyBtn)
.should('have.class', 'active')
.find('svg').then(($icon)=>{
iconName = $icon.text();
})
})
//Check if More button is active and if it has same icon as the secondary tool selected
cy.get('@moreBtn')
.click()
.then(($moreBtn) =>{
cy.wrap($moreBtn)
.should('have.class', 'active')
.contains(iconName);
})
//Verify if overlay is hidden
cy.get('@toolbarOverlay')
.should('not.be.visible');
//verify if layout has changed to 9 viewports
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(3) > :nth-child(3)').click();
cy.get('.viewport-container').then($viewport => {
cy.wrap($viewport)
.its('length')
.should('be.eq', 9);
});
//Commented this to avoid throwing an wrong exception at the end of "Layout button" test
//this commented section should be uncommented once issue #999 is fixed. (https://github.com/OHIF/Viewers/issues/999)
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);
})
//verify if layout has changed to 2 viewports
cy.get('tbody > :nth-child(1) > :nth-child(2)').click();
cy.get('.viewport-container').then(($viewport) =>{
cy.wrap($viewport)
.its('length')
.should('be.eq', 2);
})
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(2) > :nth-child(1)').click();
cy.get('.viewport-container').then(($viewport) =>{
cy.wrap($viewport)
.its('length')
.should('be.eq', 2);
})
//verify if layout has changed to 1 viewport
// cy.get('@layoutBtn').click();
// cy.get('tbody > :nth-child(1) > :nth-child(1)').click();
// cy.get('.viewport-container').then(($viewport) =>{
// cy.wrap($viewport)
// .its('length')
// .should('be.eq', 1);
// })
cy.reload();
cy.waitDicomImage();
});
//verify if layout has changed to 3 viewports
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(1) > :nth-child(3)').click();
cy.get('.viewport-container').then(($viewport) =>{
cy.wait(1000);
cy.wrap($viewport)
.its('length')
.should('be.eq', 3);
})
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(3) > :nth-child(1)').click();
cy.get('.viewport-container').then(($viewport) =>{
cy.wrap($viewport)
.its('length')
.should('be.eq', 3);
})
it('checks if Clear tool will delete all measurements added in the viewport', () => {
//Add measurements in the viewport
cy.get('@lengthBtn').click();
const firstClick = [150, 100];
const secondClick = [130, 170];
cy.addLine('.cornerstone-canvas', firstClick, secondClick);
//verify if layout has changed to 4 viewports
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(2) > :nth-child(2)').click();
cy.get('.viewport-container').then(($viewport) =>{
cy.wrap($viewport)
.its('length')
.should('be.eq', 4);
})
cy.get('@angleBtn').click();
const initPos = [180, 390];
const midPos = [300, 410];
const finalPos = [180, 450];
cy.addAngle('.cornerstone-canvas', initPos, midPos, finalPos);
//verify if layout has changed to 6 viewports
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(2) > :nth-child(3)').click();
cy.get('.viewport-container').then(($viewport) =>{
cy.wrap($viewport)
.its('length')
.should('be.eq', 6);
})
//Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.eq', 2);
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(3) > :nth-child(2)').click();
cy.get('.viewport-container').then(($viewport) =>{
cy.wrap($viewport)
.its('length')
.should('be.eq', 6);
})
//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('.tooltip-inner > :nth-child(10)').click();
//verify if layout has changed to 9 viewports
cy.get('@layoutBtn').click();
cy.get('tbody > :nth-child(3) > :nth-child(3)').click();
cy.get('.viewport-container').then(($viewport) =>{
cy.wrap($viewport)
.its('length')
.should('be.eq', 9);
})
//Verify if measurements were removed from the measurements panel
cy.get('.measurementItem').should('not.exist');
//Commented this to avoid throwing an wrong exception at the end of "Layout button" test
//this commented section should be uncommented once issue #999 is fixed. (https://github.com/OHIF/Viewers/issues/999)
//verify if layout has changed to 1 viewport
// cy.get('@layoutBtn').click();
// cy.get('tbody > :nth-child(1) > :nth-child(1)').click();
// cy.get('.viewport-container').then(($viewport) =>{
// cy.wrap($viewport)
// .its('length')
// .should('be.eq', 1);
// })
//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('checks if Eraser tool will remove the measurements added in the viewport', () => {
//Add measurements in the viewport
cy.get('@lengthBtn').click();
const firstClick = [150, 100];
const secondClick = [130, 170];
cy.addLine('.cornerstone-canvas', firstClick, secondClick);
cy.get('@angleBtn').click();
const initPos = [180, 390];
const midPos = [300, 410];
const finalPos = [180, 450];
cy.addAngle('.cornerstone-canvas', initPos, midPos, finalPos);
//Verify if measurement annotation was added into the measurements panel
cy.get('@measurementsBtn').click();
cy.get('.measurementItem')
.its('length')
.should('be.eq', 2);
cy.get('@measurementsBtn').click();
//Click More button
cy.get('@moreBtn').click();
//Click Eraser button
cy.get('.tooltip-inner > :nth-child(12)').click();
//Erase measurement #1 and Verify if it was removed from the measurements panel
const [x1, y1] = firstClick;
cy.get('@viewport').click(x1, y1, { force: true });
cy.get('.measurementItem')
.its('length')
.should('be.eq', 1);
//Erase measurement #2 and Verify if it was removed from the measurements panel
const [x2, y2] = initPos;
cy.get('@viewport').click(x2, y2, { force: true });
cy.get('.measurementItem').should('not.exist');
});
});

View File

@ -4,45 +4,90 @@ describe('OHIF Study Viewer Page', () => {
cy.waitDicomImage();
});
beforeEach(() => {
cy.initCommonElementsAliases();
//Following best practices, reset should be done before each test
cy.resetViewport();
});
it('checks if series thumbnails are being displayed', () => {
cy.get('[data-cy="thumbnail-list"]')
cy.get('.ThumbnailEntryContainer')
.its('length')
.should('be.gt', 1);
});
it('drags and drop a series thumbnail into viewport', () => {
cy.get('[data-cy="thumbnail-list"]:nth-child(2)') //element to be dragged
cy.get('.ThumbnailEntryContainer:nth-child(2)') //element to be dragged
.drag('.cornerstone-canvas'); //dropzone element
const overlaySeriesInformation =
'div.ViewportOverlay > div.bottom-left.overlay-element > div';
const expectedText =
'Ser: 2Img: 1 1/13512 x 512Loc: -17.60 mm Thick: 3.00 mm';
cy.get(overlaySeriesInformation).should('have.text', expectedText);
cy.get('@viewportInfoBottomLeft').should('contain.text', expectedText);
});
it('checks if Series left panel can be hidden/displayed', () => {
const seriesButton =
'.pull-left > .RoundedButtonGroup > .roundedButtonWrapper > .roundedButton';
const leftPanel = 'section.sidepanel.from-left';
cy.get('@seriesBtn').click();
cy.get('@seriesPanel').should('not.be.enabled');
cy.get(seriesButton).click();
cy.get(leftPanel).should('not.be.enabled');
cy.get(seriesButton).click();
cy.get(leftPanel).should('be.visible');
cy.get('@seriesBtn').click();
cy.get('@seriesPanel').should('be.visible');
});
it('checks if Measurements right panel can be hidden/displayed', () => {
const measurementsButton =
'.pull-right > .RoundedButtonGroup > .roundedButtonWrapper > .roundedButton';
const rightPanel = 'section.sidepanel.from-right';
cy.get('@measurementsBtn').click();
cy.get('@measurementsPanel').should('be.visible');
cy.get(measurementsButton).click();
cy.get(rightPanel).should('be.visible');
cy.get(measurementsButton).click();
cy.get(rightPanel).should('not.be.enabled');
cy.get('@measurementsBtn').click();
cy.get('@measurementsPanel').should('not.be.enabled');
});
it('checks if measurement item can be Relabeled under Measurements panel', () => {
cy.addLengthMeasurement(); //Adding measurement in the viewport
cy.get('@measurementsBtn').click();
cy.get('.measurementItem').click();
// Click "Relabel"
cy.get('.btnAction')
.contains('Relabel')
.click();
// Search for "Bone"
cy.get('.searchInput').type('Bone');
// Select "Bone" Result
cy.get('.treeInputs > .wrapperLabel')
.contains('Bone')
.click();
// Confirm Selection
cy.get('.checkIconWrapper').click();
//Verify if 'Bone' label was added
cy.get('.measurementLocation').should('contain.text', 'Bone');
});
//TO-DO: Test case will fail due to issue #1013: https://github.com/OHIF/Viewers/issues/1013
// 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);
// });
});

View File

@ -0,0 +1,34 @@
//Creating aliases for Cornerstone tools buttons
export function initCornerstoneToolsAliases() {
cy.get('.ToolbarRow > :nth-child(2)').as('stackScrollBtn');
cy.get('.ToolbarRow > :nth-child(3)').as('zoomBtn');
cy.get('.ToolbarRow > :nth-child(4)').as('levelsBtn');
cy.get('.ToolbarRow > :nth-child(5)').as('panBtn');
cy.get('.ToolbarRow > :nth-child(6)').as('lengthBtn');
cy.get('.ToolbarRow > :nth-child(7)').as('annotateBtn');
cy.get('.ToolbarRow > :nth-child(8)').as('angleBtn');
cy.get('.ToolbarRow > :nth-child(9)').as('resetBtn');
cy.get('.ToolbarRow > :nth-child(10)').as('cineBtn');
cy.get('.expandableToolMenu').as('moreBtn');
cy.get('.PluginSwitch > .toolbar-button').as('twodmprBtn');
cy.get('.btn-group > .toolbar-button').as('layoutBtn');
}
//Creating aliases for Common page elements
export function initCommonElementsAliases() {
cy.get(
'.pull-right > .RoundedButtonGroup > .roundedButtonWrapper > .roundedButton'
).as('measurementsBtn');
cy.get('.viewport-element').as('viewport');
cy.get('section.sidepanel.from-right').as('measurementsPanel');
cy.get(
'.pull-left > .RoundedButtonGroup > .roundedButtonWrapper > .roundedButton'
).as('seriesBtn');
cy.get('section.sidepanel.from-left').as('seriesPanel');
cy.get('div.ViewportOverlay > div.bottom-left.overlay-element > div').as(
'viewportInfoBottomLeft'
);
cy.get('div.ViewportOverlay > div.bottom-right.overlay-element > div').as(
'viewportInfoBottomRight'
);
}

View File

@ -1,6 +1,8 @@
import { DragSimulator } from '../helpers/DragSimulator.js';
import { doesNotReject } from 'assert';
import { disconnect } from 'cluster';
import {
initCornerstoneToolsAliases,
initCommonElementsAliases,
} from './aliases.js';
// ***********************************************
// This example commands.js shows you how to
@ -28,6 +30,11 @@ import { disconnect } from 'cluster';
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
/**
* Command to search for a patient name and open his/her study.
*
* @param {string} PatientName - Patient name that we would like to search for
*/
Cypress.Commands.add('openStudy', patientName => {
cy.visit('/');
cy.get('#patientName').type(patientName);
@ -39,6 +46,12 @@ Cypress.Commands.add('openStudy', patientName => {
});
});
/**
* Command to perform a drag and drop action. Before using this command, we must get the element that should be dragged first.
* Example of usage: cy.get(element-to-be-dragged).drag(dropzone-element)
*
* @param {*} element - Selector for element that we want to use as dropzone
*/
Cypress.Commands.add('drag', { prevSubject: 'element' }, (...args) =>
DragSimulator.simulate(...args)
);
@ -119,12 +132,26 @@ Cypress.Commands.add('waitDicomImage', (timeout = 20000) => {
});
});
//Command to reset the viewport changes throught the cornerstone method
//Command to reset and clear all the changes made to the viewport
Cypress.Commands.add('resetViewport', () => {
cy.initCornerstoneToolsAliases();
cy.get('@resetBtn').click();
//Click on More button
cy.get('@moreBtn').click();
//Verify if overlay is displayed
cy.get('body').then(body => {
if (body.find('.tooltip-toolbar-overlay').length == 0) {
cy.get('@moreBtn').click();
}
});
//Click on Clear button
cy.get('.tooltip-inner > :nth-child(10)')
.as('clearBtn')
.click();
});
Cypress.Commands.add('imageZoomIn', () => {
cy.initCornerstoneToolsAliases();
cy.get('@zoomBtn').click();
//drags the mouse inside the viewport to be able to interact with series
@ -135,6 +162,7 @@ Cypress.Commands.add('imageZoomIn', () => {
});
Cypress.Commands.add('imageContrast', () => {
cy.initCornerstoneToolsAliases();
cy.get('@levelsBtn').click();
//drags the mouse inside the viewport to be able to interact with series
@ -143,3 +171,32 @@ Cypress.Commands.add('imageContrast', () => {
.trigger('mousemove', 'top', { which: 1 })
.trigger('mouseup');
});
//Initialize aliases for Cornerstone tools buttons
Cypress.Commands.add('initCornerstoneToolsAliases', () => {
initCornerstoneToolsAliases();
});
//Initialize aliases for Common page elements
Cypress.Commands.add('initCommonElementsAliases', () => {
initCommonElementsAliases();
});
//Add measurements in the viewport
Cypress.Commands.add('addLengthMeasurement', () => {
cy.initCornerstoneToolsAliases();
cy.get('@lengthBtn').click();
const firstClick = [150, 100];
const secondClick = [130, 170];
cy.addLine('.cornerstone-canvas', firstClick, secondClick);
});
//Add measurements in the viewport
Cypress.Commands.add('addAngleMeasurement', () => {
cy.initCornerstoneToolsAliases();
cy.get('@angleBtn').click();
const initPos = [180, 390];
const midPos = [300, 410];
const finalPos = [180, 450];
cy.addAngle('.cornerstone-canvas', initPos, midPos, finalPos);
});