feat(OHIFv3):Add static e2e data (#2665)

This change wraps the E2E test data into a github repository, which is then included in the test builds as static data.
That makes running the e2e tests as simple as:
yarn test:e2e:server
yarn test:e2e

without any need to have docker etc installed/running.
This commit is contained in:
Bill Wallace authored and GitHub committed 2022-01-31 14:29:20 -05:00
1 parent 72bb074f21
commit 0e2c31939c
14 files changed
+888 -108

No files matched your search

+25 -16
View File
@@ -24,26 +24,14 @@ Running unit test will generate a report at the end showing the successful and
unsuccessful tests with detailed explanations.
## End-to-end test
For running the OHIF e2e test you need to run the following steps:
- Create a mini-pacs for OHIF to access the images for testing. We download and
run our lightweight implementation which provides a collection of DICOM
studies ([source code][mini-pacs]).
```bash
docker run -p 5985:5985 -p 5984:5984 -e USE_POUCHDB=true -e DB_SERVER=http://0.0.0.0 ohif/viewer-testdata:0.1-test
```
Successful execution should be
![](../assets/img/docker-pacs.png)
- Open a new terminal, navigate to the OHIF project, and run OHIF with the
dicom-server config
e2e config. The test:data only needs to be run once and checks the data out.
```bash
APP_CONFIG=config/dicomweb-server.js yarn start
yarn test:data
APP_CONFIG=config/e2e.js yarn start
```
You should be able to see test studies in the study list
@@ -53,7 +41,7 @@ For running the OHIF e2e test you need to run the following steps:
- Open a new terminal inside the OHIF project, and run the e2e cypress test
```bash
yarn run test:e2e
yarn test:e2e
```
You should be able to see the cypress window open
@@ -67,6 +55,27 @@ For running the OHIF e2e test you need to run the following steps:
![e2e-cypress-final](../assets/img/e2e-cypress-final.png)
## Test Data
The testing data is stored in two OHIF repositories. The first contains the
binary DICOM data, at [viewer-testdata](https://github.com/OHIF/viewer-testdata.git)
while the second module contains data in the DICOMweb format, installed as a submodule
into OHIF in the `testdata` directory. This is retrieved via the command
```bash
yarn test:data
```
or the equivalent command `git submodule update --init`
When adding new data, run:
```
npm install -g dicomp10-to-dicomweb
mkdicomweb -d dicomweb dcm
```
to update the local dicomweb submodule in viewer-testdata. Then, commit
that data and update the submodules used in OHIF and in the viewer-testdata
parent modules.
All data MUST be fully anonymized and allowed to be used for open access.
Any attributions should be included in the DCM directory.
## Testing Philosophy
> Testing is an opinionated topic. Here is a rough overview of our testing
+37 -4
View File
@@ -23,6 +23,15 @@ const PROXY_DOMAIN = process.env.PROXY_DOMAIN;
const ENTRY_TARGET = process.env.ENTRY_TARGET || `${SRC_DIR}/index.js`;
const Dotenv = require('dotenv-webpack');
const setHeaders = (res, path) => {
res.setHeader('Content-Type', 'text/plain')
if (path.indexOf('.gz') !== -1) {
res.setHeader('Content-Encoding', 'gzip')
} else if (path.indexOf('.br') !== -1) {
res.setHeader('Content-Encoding', 'br')
}
}
module.exports = (env, argv) => {
const baseConfig = webpackBase(env, argv, { SRC_DIR, DIST_DIR });
const isProdBuild = process.env.NODE_ENV === 'production';
@@ -36,7 +45,7 @@ module.exports = (env, argv) => {
path: DIST_DIR,
filename: isProdBuild ? '[name].bundle.[chunkhash].js' : '[name].js',
publicPath: PUBLIC_URL, // Used by HtmlWebPackPlugin for asset prefix
devtoolModuleFilenameTemplate: function(info) {
devtoolModuleFilenameTemplate: function (info) {
if (isProdBuild) {
return `webpack:///${info.resourcePath}`;
} else {
@@ -110,8 +119,32 @@ module.exports = (env, argv) => {
hot: true,
open: true,
port: 3000,
host: '0.0.0.0',
public: 'http://localhost:' + 3000,
client: {
overlay: { errors: true, warnings: false },
},
'static': [
{
directory: path.join(require('os').homedir(), 'dicomweb'),
staticOptions: {
extensions: ['gz', 'br'],
index: "index.json.gz",
redirect: true,
setHeaders,
},
publicPath: '/dicomweb',
},
{
directory: '../../testdata',
staticOptions: {
extensions: ['gz', 'br'],
index: "index.json.gz",
redirect: true,
setHeaders,
},
publicPath: '/viewer-testdata',
},
],
//public: 'http://localhost:' + 3000,
//writeToDisk: true,
historyApiFallback: {
disableDotRule: true,
@@ -124,7 +157,7 @@ module.exports = (env, argv) => {
});
if (hasProxy) {
mergedConfig.devServer.proxy = {};
mergedConfig.devServer.proxy = mergedConfig.devServer.proxy || {};
mergedConfig.devServer.proxy[PROXY_TARGET] = PROXY_DOMAIN;
}
+11 -4
View File
@@ -202,10 +202,17 @@ Cypress.Commands.add('waitDicomImage', (timeout = 50000) => {
element.addEventListener('cornerstoneimagerendered', onEvent);
};
$cornerstone.events.addEventListener(
'cornerstoneelementenabled',
onEnabled
);
const enabledElements = $cornerstone.getEnabledElements();
if (enabledElements && enabledElements.length && !enabledElements[0].invalid) {
// Sometimes the page finishes rendering before this gets run,
// if so, just resolve immediately.
resolve();
} else {
$cornerstone.events.addEventListener(
'cornerstoneelementenabled',
onEnabled
);
}
});
});
}
+1 -1
View File
@@ -35,7 +35,7 @@
"test:e2e:ci": "percy exec -- cypress run --config video=false --record --browser chrome --spec 'cypress/integration/visual-regression/**/*'",
"test:e2e:local": "cypress run --config video=false --browser chrome --spec 'cypress/integration/common/**/*,cypress/integration/pwa/**/*'",
"test:e2e:dist": "start-server-and-test test:e2e:serve http://localhost:3000 test:e2e:ci",
"test:e2e:serve": "serve -n -l 3000 -s dist",
"test:e2e:serve": "cross-env APP_CONFIG=config/e2e.js yarn start",
"test:unit": "jest --watchAll",
"test:unit:ci": "jest --ci --runInBand --collectCoverage",
"ci:generateSuccessVersion": "node -p -e \"require('./package.json').version\" > success_version.txt"
+177
View File
@@ -0,0 +1,177 @@
window.config = {
routerBasename: '/',
// whiteLabelling: {},
extensions: [],
modes: [],
showStudyList: true,
// filterQueryParam: false,
dataSources: [
{
friendlyName: 'StaticWado test data',
namespace: 'org.ohif.default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
name: 'DCM4CHEE',
wadoUriRoot: '/viewer-testdata',
qidoRoot: '/viewer-testdata',
wadoRoot: '/viewer-testdata',
qidoSupportsIncludeField: false,
supportsReject: false,
imageRendering: 'wadors',
thumbnailRendering: 'wadors',
enableStudyLazyLoad: true,
supportsFuzzyMatching: false,
supportsWildcard: true,
staticWado: true,
},
},
// {
// friendlyName: 'StaticWado default data',
// namespace: 'org.ohif.default.dataSourcesModule.dicomweb',
// sourceName: 'dicomweb',
// configuration: {
// name: 'DCM4CHEE',
// wadoUriRoot: '/dicomweb',
// qidoRoot: '/dicomweb',
// wadoRoot: '/dicomweb',
// qidoSupportsIncludeField: false,
// supportsReject: false,
// imageRendering: 'wadors',
// thumbnailRendering: 'wadors',
// enableStudyLazyLoad: true,
// supportsFuzzyMatching: false,
// supportsWildcard: true,
// staticWado: true,
// },
// },
{
friendlyName: 'dicom json',
namespace: 'org.ohif.default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: 'org.ohif.default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
},
],
httpErrorHandler: error => {
// This is 429 when rejected from the public idc sandbox too often.
console.warn(error.status);
// Could use services manager here to bring up a dialog/modal if needed.
console.warn('test, navigate to https://ohif.org/');
},
// whiteLabeling: {
// /* Optional: Should return a React component to be rendered in the "Logo" section of the application's Top Navigation bar */
// createLogoComponentFn: function (React) {
// return React.createElement(
// 'a',
// {
// target: '_self',
// rel: 'noopener noreferrer',
// className: 'text-purple-600 line-through',
// href: '/',
// },
// React.createElement('img',
// {
// src: './customLogo.svg',
// className: 'w-8 h-8',
// }
// ))
// },
// },
defaultDataSourceName: 'dicomweb',
hotkeys: [
{
commandName: 'incrementActiveViewport',
label: 'Next Viewport',
keys: ['right'],
},
{
commandName: 'decrementActiveViewport',
label: 'Previous Viewport',
keys: ['left'],
},
{ commandName: 'rotateViewportCW', label: 'Rotate Right', keys: ['r'] },
{ commandName: 'rotateViewportCCW', label: 'Rotate Left', keys: ['l'] },
{ commandName: 'invertViewport', label: 'Invert', keys: ['i'] },
{
commandName: 'flipViewportVertical',
label: 'Flip Horizontally',
keys: ['h'],
},
{
commandName: 'flipViewportHorizontal',
label: 'Flip Vertically',
keys: ['v'],
},
{ commandName: 'scaleUpViewport', label: 'Zoom In', keys: ['+'] },
{ commandName: 'scaleDownViewport', label: 'Zoom Out', keys: ['-'] },
{ commandName: 'fitViewportToWindow', label: 'Zoom to Fit', keys: ['='] },
{ commandName: 'resetViewport', label: 'Reset', keys: ['space'] },
{ commandName: 'nextImage', label: 'Next Image', keys: ['down'] },
{ commandName: 'previousImage', label: 'Previous Image', keys: ['up'] },
{
commandName: 'previousViewportDisplaySet',
label: 'Previous Series',
keys: ['pagedown'],
},
{
commandName: 'nextViewportDisplaySet',
label: 'Next Series',
keys: ['pageup'],
},
{ commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] },
// ~ Window level presets
{
commandName: 'windowLevelPreset1',
label: 'W/L Preset 1',
keys: ['1'],
},
{
commandName: 'windowLevelPreset2',
label: 'W/L Preset 2',
keys: ['2'],
},
{
commandName: 'windowLevelPreset3',
label: 'W/L Preset 3',
keys: ['3'],
},
{
commandName: 'windowLevelPreset4',
label: 'W/L Preset 4',
keys: ['4'],
},
{
commandName: 'windowLevelPreset5',
label: 'W/L Preset 5',
keys: ['5'],
},
{
commandName: 'windowLevelPreset6',
label: 'W/L Preset 6',
keys: ['6'],
},
{
commandName: 'windowLevelPreset7',
label: 'W/L Preset 7',
keys: ['7'],
},
{
commandName: 'windowLevelPreset8',
label: 'W/L Preset 8',
keys: ['8'],
},
{
commandName: 'windowLevelPreset9',
label: 'W/L Preset 9',
keys: ['9'],
},
],
};
@@ -7,21 +7,21 @@ window.config = {
// filterQueryParam: false,
dataSources: [
{
friendlyName: 'dcmjs DICOMWeb Server',
friendlyName: 'Static WADO Local Data',
namespace: 'org.ohif.default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
name: 'DCM4CHEE',
wadoUriRoot: 'http://localhost:5000',
qidoRoot: 'http://localhost:5000',
wadoRoot: 'http://localhost:5000',
wadoUriRoot: '/dicomweb',
qidoRoot: '/dicomweb',
wadoRoot: '/dicomweb',
qidoSupportsIncludeField: false,
supportsReject: false,
imageRendering: 'wadors',
thumbnailRendering: 'wadors',
enableStudyLazyLoad: true,
supportsFuzzyMatching: false,
supportsWildcard: false,
supportsWildcard: true,
staticWado: true,
},
},