Skip to content

Commit

Permalink
ci: Use containerized PACS for running end-to-end tests #1122 (#1290)
Browse files Browse the repository at this point in the history
* ci: Use containerized PACS for running end-to-end tests

* Try to fix cypress test results

Co-authored-by: dannyrb <danny.ri.brown@gmail.com>
  • Loading branch information
swederik and dannyrb committed Dec 3, 2020
1 parent 6c5ad9e commit dfe566e
Show file tree
Hide file tree
Showing 29 changed files with 727 additions and 358 deletions.
56 changes: 37 additions & 19 deletions .circleci/config.yml
Expand Up @@ -13,11 +13,23 @@ version: 2.1
##
orbs:
codecov: codecov/codecov@1.0.5
cypress: cypress-io/cypress@1.13.0
cypress: cypress-io/cypress@1.26.0
executors:
# Custom executor to override Cypress config
deploy-to-prod-executor:
docker:
- image: 'cypress/browsers:node14.15.0-chrome86-ff82'
environment:
CYPRESS_BASE_URL: https://ohif-staging.netlify.com/
chrome-and-pacs:
docker:
# Primary container image where all steps run.
- image: 'cypress/browsers:node14.15.0-chrome86-ff82'
- image: 'ohif/viewer-testdata:0.1-test'

defaults: &defaults
docker:
- image: circleci/node:12.9.1
- image: circleci/node:14.15.0
environment:
TERM: xterm # Enable colors in term
QUICK_BUILD: true
Expand Down Expand Up @@ -170,7 +182,7 @@ jobs:

DEPLOY_TO_DEV:
docker:
- image: circleci/node:12.9.1
- image: circleci/node:14.15.0
environment:
TERM: xterm
NETLIFY_SITE_ID: 32708787-c9b0-4634-b50f-7ca41952da77
Expand All @@ -185,7 +197,7 @@ jobs:

DEPLOY_TO_STAGING:
docker:
- image: circleci/node:12.9.1
- image: circleci/node:14.15.0
environment:
TERM: xterm
NETLIFY_SITE_ID: c7502ae3-b150-493c-8422-05701e44a969
Expand All @@ -200,7 +212,7 @@ jobs:

DEPLOY_TO_PRODUCTION:
docker:
- image: circleci/node:12.9.1
- image: circleci/node:14.15.0
environment:
TERM: xterm
NETLIFY_SITE_ID: 79c4a5da-5c95-4dc9-84f7-45fd9dfe21b0
Expand Down Expand Up @@ -317,16 +329,19 @@ workflows:
# E2E: PWA
- cypress/run:
name: 'E2E: PWA'
executor: cypress/browsers-chrome76
executor: chrome-and-pacs
browser: chrome
pre-steps:
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global
add wait-on' # Use yarn latest
- run: |
# Clear yarn cache; update to latest
rm -rf ~/.yarn
npm i -g yarn
yarn -v
yarn: true
record: false
store_artifacts: false
record: true
store_artifacts: true
working_directory: platform/viewer
build: npx cross-env QUICK_BUILD=true yarn run build
build: npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js yarn run build
start: yarn run test:e2e:serve
spec: 'cypress/integration/common/**/*,cypress/integration/pwa/**/*'
wait-on: 'http://localhost:3000'
Expand All @@ -337,21 +352,22 @@ workflows:
path: platform/viewer/cypress/screenshots
- store_artifacts:
path: platform/viewer/cypress/videos
- store_test_results:
path: platform/viewer/cypress/results
requires:
- UNIT_TESTS
# E2E: script-tag
- cypress/run:
name: 'E2E: Script Tag'
executor: cypress/browsers-chrome76
executor: chrome-and-pacs
browser: chrome
pre-steps:
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global
add wait-on' # Use yarn latest
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v' # Use yarn latest
yarn: true
record: false
store_artifacts: false
record: true
store_artifacts: true
working_directory: platform/viewer
build: npx cross-env QUICK_BUILD=true yarn run build:package
build: npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js yarn run build:package
start: yarn run test:e2e:serve
spec: 'cypress/integration/common/**/*,cypress/integration/script-tag/**/*'
wait-on: 'http://localhost:3000'
Expand All @@ -362,6 +378,8 @@ workflows:
path: platform/viewer/cypress/screenshots
- store_artifacts:
path: platform/viewer/cypress/videos
- store_test_results:
path: platform/viewer/cypress/results
requires:
- UNIT_TESTS

Expand All @@ -380,7 +398,7 @@ workflows:
yarn: true
store_artifacts: false
working_directory: platform/viewer
build: npx cross-env QUICK_BUILD=true yarn run build
build: npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js yarn run build
# start server --> verify running --> percy + chrome + cypress
command: yarn run test:e2e:dist
cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}'
Expand Down Expand Up @@ -457,7 +475,7 @@ workflows:
yarn: true
store_artifacts: false
working_directory: platform/viewer
build: npx cross-env QUICK_BUILD=true yarn run build
build: npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js yarn run build
# start server --> verify running --> percy + chrome + cypress
command: yarn run test:e2e:dist
cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}'
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -28,6 +28,7 @@
"test:unit": "jest --collectCoverage",
"test:unit:ci": "lerna run test:unit:ci --parallel --stream",
"test:e2e": "lerna run test:e2e --stream",
"test:e2e:script-tag": "lerna run test:e2e:script-tag --stream",
"test:e2e:ci": "lerna run test:e2e:ci --stream",
"test:e2e:dist": "lerna run test:e2e:dist --stream",
"test:e2e:serve": "lerna run test:e2e:serve --stream",
Expand Down
24 changes: 12 additions & 12 deletions platform/core/src/utils/Queue.test.js
Expand Up @@ -21,28 +21,28 @@ describe('Queue', () => {
const mockedTimeout = jest.fn(timeout);
const timer = queue.bind(mockedTimeout);
const start = Date.now();
timer(120).then(now => {
timer(1200).then(now => {
const elapsed = now - start;
expect(elapsed >= 120 && elapsed < 240).toBe(true);
expect(elapsed >= 1200 && elapsed < 2400).toBe(true);
});
const end = await timer(120);
expect(end - start > 240).toBe(true);
const end = await timer(1200);
expect(end - start > 2400).toBe(true);
expect(mockedTimeout).toBeCalledTimes(2);
});
it('should prevent task execution when queue limit is reached', async () => {
const queue = new Queue(1);
const mockedTimeout = jest.fn(timeout);
const timer = queue.bind(mockedTimeout);
const start = Date.now();
const promise = timer(120).then(time => time - start);
const promise = timer(1200).then(time => time - start);
try {
await timer(120);
await timer(1200);
} catch (e) {
expect(Date.now() - start < 120).toBe(true);
expect(Date.now() - start < 1200).toBe(true);
expect(e.message).toBe('Queue limit reached');
}
const elapsed = await promise;
expect(elapsed >= 120 && elapsed < 240).toBe(true);
expect(elapsed >= 1200 && elapsed < 2400).toBe(true);
expect(mockedTimeout).toBeCalledTimes(1);
});
it('should safely bind tasks to the queue', async () => {
Expand All @@ -51,16 +51,16 @@ describe('Queue', () => {
const mockedTimeout = jest.fn(timeout);
const timer = queue.bindSafe(mockedTimeout, mockedErrorHandler);
const start = Date.now();
const promise = timer(120).then(time => time - start);
await timer(120);
expect(Date.now() - start < 120).toBe(true);
const promise = timer(1200).then(time => time - start);
await timer(1200);
expect(Date.now() - start < 1200).toBe(true);
expect(mockedErrorHandler).toBeCalledTimes(1);
expect(mockedErrorHandler).nthCalledWith(
1,
expect.objectContaining({ message: 'Queue limit reached' })
);
const elapsed = await promise;
expect(elapsed >= 120 && elapsed < 240).toBe(true);
expect(elapsed >= 1200 && elapsed < 2400).toBe(true);
expect(mockedTimeout).toBeCalledTimes(1);
});
});
7 changes: 6 additions & 1 deletion platform/viewer/cypress.json
Expand Up @@ -6,5 +6,10 @@
"requestTimeout": 10000,
"responseTimeout": 10000,
"projectId": "4oe38f",
"video": false
"video": false,
"reporter": "junit",
"reporterOptions": {
"mochaFile": "cypress/results/test-output.xml",
"toConsole": true
}
}
Expand Up @@ -3,7 +3,7 @@ describe('OHIF Cornerstone Hotkeys', () => {
cy.checkStudyRouteInViewer(
'1.2.840.113619.2.5.1762583153.215519.978957063.78'
);
cy.expectMinimumThumbnails(5);
cy.expectMinimumThumbnails(3);
});

beforeEach(() => {
Expand Down
Expand Up @@ -3,12 +3,18 @@ describe('OHIF Cornerstone Toolbar', () => {
cy.checkStudyRouteInViewer(
'1.2.840.113619.2.5.1762583153.215519.978957063.78'
);
cy.expectMinimumThumbnails(5);
cy.expectMinimumThumbnails(3);
});

beforeEach(() => {
cy.initCornerstoneToolsAliases();
cy.initCommonElementsAliases();

cy.get('[data-cy="thumbnail-list"]:nth-child(1)').click();

const expectedText = 'Ser: 1';
cy.get('@viewportInfoBottomLeft').should('contains.text', expectedText);

cy.resetViewport();
});

Expand Down Expand Up @@ -49,7 +55,7 @@ describe('OHIF Cornerstone Toolbar', () => {
});

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
//Click on button and verify if icon is active on toolbar
cy.get('@stackScrollBtn')
.click()
.then($stackScrollBtn => {
Expand Down Expand Up @@ -85,7 +91,7 @@ describe('OHIF Cornerstone Toolbar', () => {
});

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
//Click on button and verify if icon is active on toolbar
cy.get('@levelsBtn')
.click()
.then($levelsBtn => {
Expand All @@ -106,7 +112,7 @@ describe('OHIF Cornerstone Toolbar', () => {
});

it('checks if Pan tool will move the image inside the viewport', () => {
//Click on button and vefiry if icon is active on toolbar
//Click on button and verify if icon is active on toolbar
cy.get('@panBtn')
.click()
.then($panBtn => {
Expand All @@ -120,7 +126,7 @@ describe('OHIF Cornerstone Toolbar', () => {
});

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
//Click on button and verify if icon is active on toolbar
cy.get('@lengthBtn')
.click()
.then($lengthbtn => {
Expand All @@ -147,7 +153,7 @@ describe('OHIF Cornerstone Toolbar', () => {
});

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
//Click on button and verify if icon is active on toolbar
cy.get('@angleBtn')
.click()
.then($angleBtn => {
Expand Down Expand Up @@ -192,7 +198,8 @@ describe('OHIF Cornerstone Toolbar', () => {

//Click on button
cy.get('@cineBtn').click();
//Vefiry if cine control overlay is being displayed

// Verify if cine control overlay is being displayed
cy.get('.cine-controls')
.as('cineControls')
.should('be.visible');
Expand Down Expand Up @@ -253,13 +260,15 @@ describe('OHIF Cornerstone Toolbar', () => {
cy.get('@cineBtn')
.click()
.then(() => {
//Vefiry if cine control overlay is hidden
cy.get('@cineControls').should('not.be.visible');
// 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('@moreBtn').click();

//Verify if overlay is displayed
cy.get('.tooltip-toolbar-overlay')
.as('toolbarOverlay')
Expand Down Expand Up @@ -288,9 +297,10 @@ describe('OHIF Cornerstone Toolbar', () => {
});

//Verify if overlay is hidden
cy.get('@toolbarOverlay').should('not.be.visible');
cy.get('@toolbarOverlay').should('not.exist');
});


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')
Expand Down Expand Up @@ -415,7 +425,7 @@ describe('OHIF Cornerstone Toolbar', () => {
// TODO: We need a seperate test server for this to work.
// As anyone can save measurements on a different slice.

cy.get('.measurementItem'); //.should('not.exist');
//cy.get('.measurementItem'); //.should('not.exist');

//Close More button overlay
cy.get('@moreBtn').click();
Expand All @@ -439,6 +449,9 @@ describe('OHIF Cornerstone Toolbar', () => {
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', () => {
Expand All @@ -451,6 +464,10 @@ describe('OHIF Cornerstone Toolbar', () => {
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 V tool will flip the image vertically in the viewport', () => {
Expand All @@ -463,5 +480,9 @@ describe('OHIF Cornerstone Toolbar', () => {
cy.get('[data-cy="flip v"]').click();
cy.get('@viewportInfoMidLeft').should('contains.text', 'R');
cy.get('@viewportInfoMidTop').should('contains.text', 'F');

//Click on More button to close it
cy.get('@moreBtn').click();
cy.get('.tooltip-toolbar-overlay').should('not.exist');
});
});
Expand Up @@ -3,7 +3,7 @@ describe('OHIF Download Snapshot File', () => {
cy.checkStudyRouteInViewer(
'1.2.840.113619.2.5.1762583153.215519.978957063.78'
);
cy.expectMinimumThumbnails(5);
cy.expectMinimumThumbnails(3);
});

beforeEach(() => {
Expand Down

0 comments on commit dfe566e

Please sign in to comment.