Skip to content

Commit

Permalink
test(dcmqi-browser): add e2e browser tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jadh4v committed Aug 22, 2024
1 parent 796707d commit cc6836c
Show file tree
Hide file tree
Showing 34 changed files with 1,430 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ function typescriptBindings(
options,
forNode = false
) {
console.log('wasmBinaries: ', wasmBinaries);
// index module
let indexContent = ''
let indexCommonContent = "export { default as version } from './version.js'\n"
Expand Down
2 changes: 1 addition & 1 deletion packages/dicom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"build:python:versionSync": "itk-wasm pnpm-script build:python:versionSync",
"publish:python": "itk-wasm pnpm-script publish:python",
"test": "pnpm test:data:download && pnpm build:gen:python && pnpm test:python",
"test:data:download": "dam download test/data test/data.tar.gz bafybeicskxufnvuem6342pkfwgeo3siiozgzmfo5f34woge6aptuzuwzzu https://github.com/InsightSoftwareConsortium/ITK-Wasm/releases/download/itk-wasm-v1.0.0-b.119/dicom-test-data.tar.gz https://w3s.link/ipfs/bafybeiby67winzvozowf4moqthwunuxxscssitnb6wahxv4ugvfxhu2vki/data.tar.gz",
"test:data:download": "dam download test/data test/data.tar.gz bafybeicfhacth6jwhtqd2caxwtepoydf54kv3zzr36zpoj7og5iuzptv7u https://data.kitware.com/api/v1/file/66c62d8faf422925a42121ab/download",
"test:data:pack": "dam pack test/data test/data.tar.gz",
"test:python:wasi": "itk-wasm pnpm-script test:python:wasi",
"test:python:emscripten": "itk-wasm pnpm-script test:python:emscripten",
Expand Down

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { demoServer } from './common.ts'

describe('readOverlappingSegmentation', () => {
beforeEach(function() {
cy.visit(demoServer)

const testPathPrefix = '../test/data/output/'

// Read the input file
const inputFile = 'liver_heart_seg.dcm'
const inputFilePath = `${testPathPrefix}${inputFile}`
cy.readFile(inputFilePath, null).as('inputFile')
})

it('reads segmentation from a dicom file', function () {
cy.get('sl-tab[panel="readOverlappingSegmentation-panel"]').click()

cy.get('#readOverlappingSegmentationInputs input[name="dicom-file-file"]').selectFile({ contents: new Uint8Array(this.inputFile), fileName: 'inputData.dcm' }, { force: true })

cy.get('#readOverlappingSegmentationInputs sl-button[name="run"]').click()

cy.get('#readOverlappingSegmentation-seg-image-details').should('exist')
//cy.get('#readOverlappingSegmentation-seg-image-details').should('contain', '"pixelType": "VariableLengthVector"')

cy.get('#readOverlappingSegmentation-meta-info-details').should('contain', '"SegmentLabel": "Liver"')
cy.get('#readOverlappingSegmentation-meta-info-details').should('contain', '"labelID": 1')
cy.get('#readOverlappingSegmentation-meta-info-details').should('contain', '"SegmentLabel": "Thoracic spine"')
cy.get('#readOverlappingSegmentation-meta-info-details').should('contain', '"labelID": 2')
cy.get('#readOverlappingSegmentation-meta-info-details').should('contain', '"SegmentLabel": "Heart"')
cy.get('#readOverlappingSegmentation-meta-info-details').should('contain', '"labelID": 3')
})
})
27 changes: 27 additions & 0 deletions packages/dicom/typescript/cypress/e2e/read-segmentation.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { demoServer } from './common.ts'

describe('readSegmentation', () => {
beforeEach(function() {
cy.visit(demoServer)

const testPathPrefix = '../test/data/input/dicom-images/'

// Read the input file
const inputFile = 'SEG/ReMIND-001/tumor_seg_MR_ref_3DSAGT2SPACE/1-1.dcm'
const inputFilePath = `${testPathPrefix}${inputFile}`
cy.readFile(inputFilePath, null).as('inputFile')
})

it('reads segmentation from a dicom file', function () {
cy.get('sl-tab[panel="readSegmentation-panel"]').click()

cy.get('#readSegmentationInputs input[name="dicom-file-file"]').selectFile({ contents: new Uint8Array(this.inputFile), fileName: 'inputData.dcm' }, { force: true })

cy.get('#readSegmentationInputs sl-button[name="run"]').click()

cy.get('#readSegmentation-seg-image-details').should('exist')

cy.get('#readSegmentation-meta-info-details').should('contain', '"labelID": 1')
cy.get('#readSegmentation-meta-info-details').should('contain', '"BodyPartExamined": "BRAIN"')
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { demoServer } from './common.ts'

describe('writeMultiSegmentation', () => {
beforeEach(function() {
cy.visit(demoServer)

const dcmqi_lib_SOURCE_DIR = '../emscripten-build/_deps/dcmqi_lib-src/'

// Read the input file
const segImages = [
'data/segmentations/partial_overlaps-1.nrrd',
'data/segmentations/partial_overlaps-2.nrrd',
'data/segmentations/partial_overlaps-3.nrrd',
]
cy.readFile(`${dcmqi_lib_SOURCE_DIR}${segImages[0]}`, null).as('input0.nrrd')
cy.readFile(`${dcmqi_lib_SOURCE_DIR}${segImages[1]}`, null).as('input1.nrrd')
cy.readFile(`${dcmqi_lib_SOURCE_DIR}${segImages[2]}`, null).as('input2.nrrd')

/*
const inputFile = 'SEG/overlapping/overlapping-seg.nrrd'
const inputFilePath = `${dcmqi_lib_SOURCE_DIR}${inputFile}`
cy.readFile(inputFilePath, null).as('inputFile')
*/

const metaInfoFile = 'doc/examples/seg-example_partial_overlaps.json'
const metaInfoFilePath = `${dcmqi_lib_SOURCE_DIR}${metaInfoFile}`
cy.readFile(metaInfoFilePath, null).as('metaInfoFile')//.should('not.equal', null)

const refFiles = [
'data/segmentations/ct-3slice/01.dcm',
'data/segmentations/ct-3slice/02.dcm',
'data/segmentations/ct-3slice/03.dcm',
]
cy.readFile(`${dcmqi_lib_SOURCE_DIR}${refFiles[0]}`, null).as('ref0.dcm')
cy.readFile(`${dcmqi_lib_SOURCE_DIR}${refFiles[1]}`, null).as('ref1.dcm')
cy.readFile(`${dcmqi_lib_SOURCE_DIR}${refFiles[2]}`, null).as('ref2.dcm')
})

it('writes a segmentation image to a dicom file', function () {
cy.get('sl-tab[panel="writeMultiSegmentation-panel"]').click()

const inputFiles = []
for(let i = 0; i < 3; i++) {
inputFiles.push({ contents: new Uint8Array(this[`input${i}.nrrd`]), fileName: `input${i}.nrrd` })
}
cy.get('#writeMultiSegmentationInputs input[name="seg-images-file"]').selectFile( inputFiles, { force: true })
cy.get('#writeMultiSegmentationInputs input[name=meta-info-file]').selectFile({ contents: new Uint8Array(this.metaInfoFile), fileName: 'input-metainfo.json' }, { force: true })
cy.get('#writeMultiSegmentationInputs sl-input[name=output-dicom-file]').find('input', { includeShadowDom: true }).type('output-write-segmentation.dcm', { force: true })

const refFiles = []
for(let i = 0; i < 3; i++) {
refFiles.push({ contents: new Uint8Array(this[`ref${i}.dcm`]), fileName: `ref${i}.dcm` })
}
cy.get('#writeMultiSegmentationInputs input[name="ref-dicom-series-file"]').selectFile( refFiles, { force: true })

//cy.get('#writeMultiSegmentationInputs sl-button[name="run"]').should('be.enabled')
cy.get('#writeMultiSegmentationInputs sl-button[name=run]').find('button', { includeShadowDom: true }).should('be.enabled')
cy.get('#writeMultiSegmentationInputs sl-button[name="run"]').click()

//cy.get('#writeMultiSegmentation-seg-images-details').should('exist')
cy.get('#writeMultiSegmentation-output-dicom-file-details').should('exist')
cy.get('#writeMultiSegmentation-output-dicom-file-details').should('contain', '0,0,0,0,0,0,0,0,0,0,0,')
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { demoServer } from './common.ts'

describe('writeOverlappingSegmentation', () => {
beforeEach(function() {
cy.visit(demoServer)

const testPathPrefix1 = '../test/data/input/dicom-images/SEG/writeOverlappingSegmentation/'
const dcmqi_lib_SOURCE_DIR = '../emscripten-build/_deps/dcmqi_lib-src/'

// Read the input file
const inputFile = 'segImage.nrrd'
cy.readFile(`${testPathPrefix1}${inputFile}`, null).as('inputFile')

const metaInfoFile = 'metaInfo.json'
cy.readFile(`${testPathPrefix1}${metaInfoFile}`, null).as('metaInfoFile')

const refFiles = [
'data/segmentations/ct-3slice/01.dcm',
'data/segmentations/ct-3slice/02.dcm',
'data/segmentations/ct-3slice/03.dcm',
]
cy.readFile(`${dcmqi_lib_SOURCE_DIR}${refFiles[0]}`, null).as('ref0.dcm')
cy.readFile(`${dcmqi_lib_SOURCE_DIR}${refFiles[1]}`, null).as('ref1.dcm')
cy.readFile(`${dcmqi_lib_SOURCE_DIR}${refFiles[2]}`, null).as('ref2.dcm')
})

it('writes a segmentation image to a dicom file', function () {
cy.get('sl-tab[panel="writeOverlappingSegmentation-panel"]').click()

cy.get('#writeOverlappingSegmentationInputs input[name=seg-image-file]').selectFile({ contents: new Uint8Array(this.inputFile), fileName: 'segImage.nrrd' }, { force: true })
cy.get('#writeOverlappingSegmentationInputs input[name=meta-info-file]').selectFile({ contents: new Uint8Array(this.metaInfoFile), fileName: 'metaInfo.json' }, { force: true })
cy.get('#writeOverlappingSegmentationInputs sl-input[name=output-dicom-file]').find('input', { includeShadowDom: true }).type('output-write-segmentation.dcm', { force: true })

const refFiles = []
for(let i = 0; i < 3; i++) {
refFiles.push({ contents: new Uint8Array(this[`ref${i}.dcm`]), fileName: `ref${i}.dcm` })
}
cy.get('#writeOverlappingSegmentationInputs input[name="ref-dicom-series-file"]').selectFile( refFiles, { force: true })

// need to click twice for some reason `\/O\/`
cy.get('#writeOverlappingSegmentationInputs sl-button[name=run]').find('button', { includeShadowDom: true }).should('be.enabled')
cy.get('#writeOverlappingSegmentationInputs sl-button[name=run]').click()

//cy.get('#writeOverlappingSegmentation-seg-image-details').should('exist')
cy.get('#writeOverlappingSegmentation-output-dicom-file-details').should('exist')
cy.get('#writeOverlappingSegmentation-output-dicom-file-details').should('contain', '0,0,0,0,0,0,0,0,0,0,0,')
})
})
54 changes: 54 additions & 0 deletions packages/dicom/typescript/cypress/e2e/write-segmentation.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { demoServer } from './common.ts'

describe('writeSegmentation', () => {
beforeEach(function() {
cy.visit(demoServer)

const testPathPrefix = '../test/data/input/dicom-images/'

// Read the input file
const inputFile = 'SEG/ReMIND-001/tumor_seg_MR_ref_3DSAGT2SPACE.nrrd'
const inputFilePath = `${testPathPrefix}${inputFile}`
cy.readFile(inputFilePath, null).as('inputFile')

const metaInfoFile = 'SEG/MR_ref_3DSAGT2SPACE_tumor_seg.json'
const metaInfoFilePath = `../test/data/baseline/dicom-images/${metaInfoFile}`
cy.readFile(metaInfoFilePath, null).as('metaInfoFile')//.should('not.equal', null)

const refFiles = [
"SEG/ReMIND-001/3DSAGT2SPACE/1-001.dcm",
"SEG/ReMIND-001/3DSAGT2SPACE/1-002.dcm",
"SEG/ReMIND-001/3DSAGT2SPACE/1-003.dcm",
]
cy.readFile(`${testPathPrefix}${refFiles[0]}`, null).as('ref0.dcm')
cy.readFile(`${testPathPrefix}${refFiles[1]}`, null).as('ref1.dcm')
cy.readFile(`${testPathPrefix}${refFiles[2]}`, null).as('ref2.dcm')
})

it('writes a segmentation image to a dicom file', function () {
cy.get('sl-tab[panel="writeSegmentation-panel"]').click()

cy.get('#writeSegmentationInputs input[name=seg-image-file]').selectFile({ contents: new Uint8Array(this.inputFile), fileName: 'inputData.nrrd' }, { force: true })
cy.get('#writeSegmentationInputs input[name=meta-info-file]').selectFile({ contents: new Uint8Array(this.metaInfoFile), fileName: 'inputData.json' }, { force: true })

cy.get('#writeSegmentationInputs sl-input[name=output-dicom-file]').find('input', { includeShadowDom: true }).type('output_write_segmentation.dcm', { force: true })
//cy.get('#niftiWriteImageInputs sl-input[name="serialized-image"]').find('input', { includeShadowDom: true }).type('r16slice.nii.gz', { force: true })
//cy.get('#writeSegmentationInputs input[name="output-dicom-file"]').type('output_tumor_seg_MR_ref_3DSAGT2SPACE.dcm')

const inputFiles = []
for(let i = 0; i < 3; i++) {
inputFiles.push({ contents: new Uint8Array(this[`ref${i}.dcm`]), fileName: `ref${i}.dcm` })
}
cy.get('#writeSegmentationInputs input[name="ref-dicom-series-file"]').selectFile( inputFiles, { force: true })

// need to click twice for some reason `\/O\/`
cy.get('#writeSegmentationInputs sl-button[name="run"]').click()
cy.get('#writeSegmentationInputs sl-button[name="run"]').click()

cy.get('#writeSegmentation-seg-image-details').should('exist')
cy.get('#writeSegmentation-output-dicom-file-details').should('exist')
cy.get('#writeSegmentation-output-dicom-file-details').should('contain', '0,0,0,0,0,0,0,0,0,0,0,')
//cy.get('#writeSegmentation-meta-info-details').should('contain', '"labelID": 1')
//cy.get('#writeSegmentation-meta-info-details').should('contain', '"BodyPartExamined": "BRAIN"')
})
})
2 changes: 1 addition & 1 deletion packages/dicom/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"scripts": {
"start": "pnpm copyDemoAppAssets && vite",
"test": "pnpm test:node && pnpm test:browser",
"test:node": "ava test/node/dcmqi.js",
"test:node": "ava test/node/*.js",
"test:browser": "pnpm test:browser:chrome && pnpm test:browser:firefox",
"test:browser:firefox": "start-server-and-test start http-get://localhost:5177 cypress:runFirefox",
"test:browser:chrome": "start-server-and-test start http-get://localhost:5177 cypress:runChrome",
Expand Down
52 changes: 52 additions & 0 deletions packages/dicom/typescript/src/index-only.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,55 @@ export { readImageDicomFileSeries }

import readImageDicomFileSeriesWorkerFunction from './read-image-dicom-file-series-worker-function.js'
export { readImageDicomFileSeriesWorkerFunction }



import ReadSegmentationResult from './read-segmentation-result.js'
export type { ReadSegmentationResult }

import ReadSegmentationOptions from './read-segmentation-options.js'
export type { ReadSegmentationOptions }

import readSegmentation from './read-segmentation.js'
export { readSegmentation }

import ReadOverlappingSegmentationResult from './read-overlapping-segmentation-result.js'
export type { ReadOverlappingSegmentationResult }

import ReadOverlappingSegmentationOptions from './read-overlapping-segmentation-options.js'
export type { ReadOverlappingSegmentationOptions }

import readOverlappingSegmentation from './read-overlapping-segmentation.js'
export { readOverlappingSegmentation }



import WriteSegmentationResult from './write-segmentation-result.js'
export type { WriteSegmentationResult }

import WriteSegmentationOptions from './write-segmentation-options.js'
export type { WriteSegmentationOptions }

import writeSegmentation from './write-segmentation.js'
export { writeSegmentation }



import WriteOverlappingSegmentationResult from './write-overlapping-segmentation-result.js'
export type { WriteOverlappingSegmentationResult }

import WriteOverlappingSegmentationOptions from './write-overlapping-segmentation-options.js'
export type { WriteOverlappingSegmentationOptions }

import writeOverlappingSegmentation from './write-overlapping-segmentation.js'
export { writeOverlappingSegmentation }


import WriteMultiSegmentationResult from './write-multi-segmentation-result.js'
export type { WriteMultiSegmentationResult }

import WriteMultiSegmentationOptions from './write-multi-segmentation-options.js'
export type { WriteMultiSegmentationOptions }

import writeMultiSegmentation from './write-multi-segmentation.js'
export { writeMultiSegmentation }
3 changes: 1 addition & 2 deletions packages/dicom/typescript/test/browser/demo-app/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
<!-- Generated file. To retain edits, remove this comment. -->

<!DOCTYPE html>
<html lang="en">
<head>
Expand All @@ -16,6 +14,7 @@
</head>
<body>

<script type="module" src="/utilities.js"></script>
<!-- https://tholman.com/github-corners/ -->
<a href="https://github.com/InsightSoftwareConsortium/ITK-Wasm" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>

Expand Down
8 changes: 6 additions & 2 deletions packages/dicom/typescript/test/browser/demo-app/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// Generated file. To retain edits, remove this comment.

import * as dicom from '../../../dist/index.js'
globalThis.dicom = dicom

import { readImage } from '@itk-wasm/image-io'
globalThis.readImage = readImage

import { castImage } from "itk-wasm"
globalThis.castImage = castImage

// Use local, vendored WebAssembly module assets
const viteBaseUrl = import.meta.env.BASE_URL
const pipelinesBaseUrl: string | URL = new URL(`${viteBaseUrl}pipelines`, document.location.origin).href
Expand Down
Loading

0 comments on commit cc6836c

Please sign in to comment.