diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9be196849aa969eaf5cc2466f3d0bf411706dc4f..0523303cd667948b867187e57ab486af76bf65a9 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,91 +1,49 @@ -name: e2e +name: "[e2e] prod-specs" on: - pull_request: - branches: - - dev - -env: - DOCKER_IMAGE_NAME: gha-iav-image - DOCKER_IMAGE_TAG: ${{ github.sha }} - DOCKER_CONTAINER_NAME: gha-iav-built-${{ github.sha }} - DOCKER_E2E_PPTR: gha-iav-e2e-pptr-${{ github.sha }} - DOCKER_E2E_NETWORK: gha-dkr-network - ATLAS_URL: http://gha-iav-built-${{ github.sha }}:3000/ - CHROMIUM_VERSION: "80.0.3987.106" - PPTR_VERSION: "2.1.0" + workflow_dispatch: + inputs: + branch: + required: true + default: dev + url: + required: true + default: https://interactive-viewer-next.apps-dev.hbp.eu/ jobs: - buildimage: - if: "!contains(github.event.head_commit.message, '[skip ci]')" - runs-on: self-hosted + e2e: + runs-on: [self-hosted, headless] + strategy: + matrix: + protractor-spec: [ + './src/advanced/urlParsing.prod.e2e-spec.js', + './src/advanced/pluginApi.prod.e2e-spec.js', + './src/advanced/nonAtlasImages.prod.e2e-spec.js', + './src/advanced/browsingForDatasets.prod.e2e-spec.js', + './src/advanced/favDatasets.prod.e2e-spec.js', + + './src/selecting/region.prod.e2e-spec.js', + './src/selecting/template.prod.e2e-spec.js', + './src/selecting/atlas.prod.e2e-spec.js', + + './src/layout/home.prod.e2e-spec.js' + ] + env: + PROTRACTOR_SPECS: ${{ matrix.protractor-spec }} + ATLAS_URL: ${{ github.event.inputs.url }} + PPTR_VERSION: "5.3.1" + CHROMIUM_VERSION: "86.0.4240.0" + steps: - - uses: actions/checkout@v1 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + - uses: actions/checkout@v2 with: - node-version: ${{ matrix.node-version }} - - name: build docker image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }} - run: | - docker build --build-arg BACKEND_URL=${BACKEND_URL} -t ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} . - env: - BACKEND_URL: ${{ env.ATLAS_URL }} - test: - if: "!contains(github.event.head_commit.message, '[skip ci]')" - runs-on: self-hosted - needs: buildimage - steps: - - name: clean up previous - run: | - GHA_CONTAINERS=$( docker ps | grep gha | awk '{print $1}' ) - if [ -z "$GHA_CONTAINERS" ]; then for f in $GHA_CONTAINERS; do docker stop $f; done; fi - - name: run docker image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }} as container ${{ env.DOCKER_CONTAINER_NAME }} - run: | - docker run \ - --rm \ - --name ${DOCKER_CONTAINER_NAME} \ - --env HBP_CLIENTID=${{ secrets.HBP_CLIENTID }} \ - --env HBP_CLIENTSECRET=${{ secrets.HBP_CLIENTSECRET }} \ - --env REFRESH_TOKEN=${{ secrets.REFRESH_TOKEN }} \ - --env PLUGIN_URLS=${{ env.ATLAS_URL }}/res/plugin_examples/plugin1/manifest.json \ - -dit \ - ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} - - uses: actions/checkout@v1 - - name: Start pptr docker container with name ${{ env.DOCKER_E2E_PPTR }} - run: | - docker run --rm \ - -v /dev/shm:/dev/shm \ - --name ${DOCKER_E2E_PPTR} \ - -dt \ - puppeteer - docker cp . ${DOCKER_E2E_PPTR}:/iav - docker exec -u root ${DOCKER_E2E_PPTR} chown -R pptruser:pptruser /iav - docker exec -t -w /iav ${DOCKER_E2E_PPTR} npm i - docker exec -t -w /iav ${DOCKER_E2E_PPTR} npm run wd -- update --versions.chrome=${{ env.CHROMIUM_VERSION }} - docker exec -t ${DOCKER_E2E_PPTR} npm i --no-save puppeteer@${{ env.PPTR_VERSION }} - - name: Setup docker network - run: | - docker network connect ${{ env.DOCKER_E2E_NETWORK }} ${{ env.DOCKER_E2E_PPTR }} - docker network connect ${{ env.DOCKER_E2E_NETWORK }} ${{ env.DOCKER_CONTAINER_NAME }} - - name: run pptr tests - ${{ env.ATLAS_URL }} - run: | - docker exec --env ATLAS_URL=${ATLAS_URL} -t -w /iav ${DOCKER_E2E_PPTR} npm run e2e - - name : make screenshot, if success - if: success() - run: | - docker exec --env ATLAS_URL=${ATLAS_URL} -t -w /iav ${DOCKER_E2E_PPTR} npm run e2e -- --specs ./e2e/screenshots/gen.js - docker cp ${DOCKER_E2E_PPTR}:/iav/docs/autogen_images ./autogen_images - - uses: actions/upload-artifact@v1 - if: success() - with: - name: screenshots-${{ github.sha }} - path: ./autogen_images - - name: cleanup, stop container ${{ env.DOCKER_CONTAINER_NAME }} && ${{ env.DOCKER_E2E_PPTR }} - if: success() - run: | - docker stop ${DOCKER_CONTAINER_NAME} - docker stop ${DOCKER_E2E_PPTR} - - name: cleanup, remove image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }} - if: success() - run: | - docker rmi ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} + ref: ${{ github.event.inputs.branch }} + + - name: Install dep + run: | + npm i + npm run wd -- update --versions.chrome=${CHROMIUM_VERSION} + npm i --no-save puppeteer@${PPTR_VERSION} + + - name: 'Run e2e for ${{ matrix.protractor-spec }} on ${{ github.event.inputs.url }}' + run: npm run e2e diff --git a/Dockerfile b/Dockerfile index f6bad9ab6d0db5a0534eb1baafe774b8080f3627..b5e5eb91a76f2a0263954e426b575f6b5b32711d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ COPY . /iv WORKDIR /iv ARG VERSION -ENV VERSION=${VERSION:-devNext} +ENV VERSION=${VERSION} RUN npm i RUN npm run build-aot diff --git a/common/constants.js b/common/constants.js index 5734896dff5a3729ddd0a0c244af30df0ce8a0c4..2e81cecddf7789edfe3d2a903ce6f03f4e099a1a 100644 --- a/common/constants.js +++ b/common/constants.js @@ -44,6 +44,8 @@ SHARE_CUSTOM_URL_DIALOG: 'Dialog for creating a custom URL', // parcellation region specific + PARC_VER_SELECT: 'Select parcellation versions', + PARC_VER_CONTAINER: 'List of parcellation versions', GO_TO_REGION_CENTROID: 'Navigate to region centroid', SHOW_ORIGIN_DATASET: `Show probabilistic map`, SHOW_CONNECTIVITY_DATA: `Show connectivity data`, diff --git a/e2e/src/advanced/pluginApi.prod.e2e-spec.js b/e2e/src/advanced/pluginApi.prod.e2e-spec.js index a5c14f975d1730239ce243bf972670ee3c90c515..3abcab7e33d34fbd737699e18360a4f750af662b 100644 --- a/e2e/src/advanced/pluginApi.prod.e2e-spec.js +++ b/e2e/src/advanced/pluginApi.prod.e2e-spec.js @@ -1,5 +1,6 @@ const { AtlasPage } = require('../util') -const template = 'ICBM 2009c Nonlinear Asymmetric' +const atlasName = 'Multilevel Human Atlas' +const template = 'ICBM 152 2009c Nonlinear Asymmetric' const pluginName = `fzj.xg.testWidget` const pluginDisplayName = `Test Widget Title` @@ -24,7 +25,7 @@ describe('> plugin api', () => { iavPage = new AtlasPage() await iavPage.init() await iavPage.goto() - await iavPage.selectTitleCard(template) + await iavPage.setAtlasSpecifications(atlasName) await iavPage.wait(500) await iavPage.waitUntilAllChunksLoaded() }) @@ -76,6 +77,8 @@ describe('> plugin api', () => { describe('> getUserToSelectARegion', () => { let originalTitle + const cursorPos = [250, 660] + const cursorRegion = 'Area hOc1 (V1, 17, CalcS)' beforeEach(async () => { originalTitle = await iavPage.execScript(() => window.document.title) @@ -114,10 +117,10 @@ describe('> plugin api', () => { }) it('> on clicking region, resolves pr', async () => { - await iavPage.cursorMoveToAndClick({ position: [600, 490] }) + await iavPage.cursorMoveToAndClick({ position: cursorPos }) await iavPage.wait(500) const newTitle = await iavPage.execScript(() => window.document.title) - expect(newTitle).toEqual(`success Area 6ma (preSMA, mesial SFG) - left hemisphere`) + expect(newTitle).toEqual(`success ${cursorRegion}`) }) it('> on failusre, clears modal', async () => { @@ -134,7 +137,7 @@ describe('> plugin api', () => { it('> on success, clears modal', async () => { - await iavPage.cursorMoveToAndClick({ position: [600, 490] }) + await iavPage.cursorMoveToAndClick({ position: cursorPos }) await iavPage.wait(500) try { diff --git a/e2e/src/advanced/urlParsing.prod.e2e-spec.js b/e2e/src/advanced/urlParsing.prod.e2e-spec.js index d9ba92944895e5efe00c9b9bf2086fd20d9e0a56..421797049ace21c96f1252c40d05445108500433 100644 --- a/e2e/src/advanced/urlParsing.prod.e2e-spec.js +++ b/e2e/src/advanced/urlParsing.prod.e2e-spec.js @@ -121,32 +121,38 @@ describe('> url parsing', () => { )) }) - it('> if datasetPreview is set, should load with previews', async () => { - const url = `http://localhost:3000/?templateSelected=MNI+152+ICBM+2009c+Nonlinear+Asymmetric&parcellationSelected=JuBrain+Cytoarchitectonic+Atlas&previewingDatasetFiles=%5B%7B%22datasetId%22%3A%22e715e1f7-2079-45c4-a67f-f76b102acfce%22%2C%22filename%22%3A%22fingerprint%22%7D%2C%7B%22datasetId%22%3A%22e715e1f7-2079-45c4-a67f-f76b102acfce%22%2C%22filename%22%3A%22GABA%E1%B4%80%28BZ%29%2Fautoradiography%22%7D%2C%7B%22datasetId%22%3A%22e715e1f7-2079-45c4-a67f-f76b102acfce%22%2C%22filename%22%3A%22GABA%E1%B4%80%28BZ%29%2Fprofile%22%7D%5D` - const datasetPreview = [ - { - "datasetId": "e715e1f7-2079-45c4-a67f-f76b102acfce", - "filename": "fingerprint" - }, - { - "datasetId": "e715e1f7-2079-45c4-a67f-f76b102acfce", - "filename": "GABAá´€(BZ)/autoradiography" - }, - { - "datasetId": "e715e1f7-2079-45c4-a67f-f76b102acfce", - "filename": "GABAá´€(BZ)/profile" - } - ] - - const searchParam = new URLSearchParams() - - searchParam.set('templateSelected', 'MNI 152 ICBM 2009c Nonlinear Asymmetric') - searchParam.set('parcellationSelected', 'JuBrain Cytoarchitectonic Atlas') - searchParam.set('previewingDatasetFiles', JSON.stringify(datasetPreview)) - await iavPage.goto(`/?${searchParam.toString()}`) - - const visibleArr = await iavPage.areVisible(`[aria-label="${ARIA_LABELS.DATASET_FILE_PREVIEW}"]`) - expect(visibleArr.length).toEqual(3) - expect(visibleArr).toEqual([true, true, true]) - }) + /** + * encoding of dataset previews in url is current not enabled + */ + it('> if datasetPreview is set, should load with previews', + // async () => { + // const url = `http://localhost:3000/?templateSelected=MNI+152+ICBM+2009c+Nonlinear+Asymmetric&parcellationSelected=JuBrain+Cytoarchitectonic+Atlas&previewingDatasetFiles=%5B%7B%22datasetId%22%3A%22e715e1f7-2079-45c4-a67f-f76b102acfce%22%2C%22filename%22%3A%22fingerprint%22%7D%2C%7B%22datasetId%22%3A%22e715e1f7-2079-45c4-a67f-f76b102acfce%22%2C%22filename%22%3A%22GABA%E1%B4%80%28BZ%29%2Fautoradiography%22%7D%2C%7B%22datasetId%22%3A%22e715e1f7-2079-45c4-a67f-f76b102acfce%22%2C%22filename%22%3A%22GABA%E1%B4%80%28BZ%29%2Fprofile%22%7D%5D` + // const datasetPreview = [ + // { + // "datasetId": "e715e1f7-2079-45c4-a67f-f76b102acfce", + // "filename": "fingerprint" + // }, + // { + // "datasetId": "e715e1f7-2079-45c4-a67f-f76b102acfce", + // "filename": "GABAá´€(BZ)/autoradiography" + // }, + // { + // "datasetId": "e715e1f7-2079-45c4-a67f-f76b102acfce", + // "filename": "GABAá´€(BZ)/profile" + // } + // ] + + // const searchParam = new URLSearchParams() + + // searchParam.set('templateSelected', 'MNI 152 ICBM 2009c Nonlinear Asymmetric') + // searchParam.set('parcellationSelected', 'JuBrain Cytoarchitectonic Atlas') + // searchParam.set('previewingDatasetFiles', JSON.stringify(datasetPreview)) + // await iavPage.goto(`/?${searchParam.toString()}`) + + // const visibleArr = await iavPage.areVisible(`[aria-label="${ARIA_LABELS.DATASET_FILE_PREVIEW}"]`) + // expect(visibleArr.length).toEqual(3) + // expect(visibleArr).toEqual([true, true, true]) + // } + + ) }) diff --git a/e2e/src/navigating/btnZoomInOut.prod.e2e-spec.js b/e2e/src/navigating/btnZoomInOut.prod.e2e-spec.js index e54ee6f0d684ee588297745de1c36296f172aec6..d8349964da698991f33631ca33365f6b4f0fbacb 100644 --- a/e2e/src/navigating/btnZoomInOut.prod.e2e-spec.js +++ b/e2e/src/navigating/btnZoomInOut.prod.e2e-spec.js @@ -15,16 +15,13 @@ describe('> zoom in btns on panels', () => { }) it('> panel btns do not show', async () => { - await iavPage.cursorMoveTo({ - position: [width / 4, height/4] - }) + await iavPage.cursorMoveToElement(`[aria-label="${ARIA_LABELS.SELECT_ATLAS}"]`) await iavPage.wait(500) const visibleFlags = await iavPage.areVisible(`[aria-label="${ARIA_LABELS.ZOOM_IN}"]`) expect(visibleFlags.length).toBe(4) expect(visibleFlags).toEqual([false, false, false, false]) - await iavPage.clickSideNavTab() }) }) diff --git a/e2e/src/selecting/region.prod.e2e-spec.js b/e2e/src/selecting/region.prod.e2e-spec.js index 01b30f83e3db64a1b83854b939403adeec744d3b..9b6e0d535042a9346c0891fe2a5da75d06daee4c 100644 --- a/e2e/src/selecting/region.prod.e2e-spec.js +++ b/e2e/src/selecting/region.prod.e2e-spec.js @@ -7,6 +7,7 @@ describe('> selecting regions', () => { const duplicatedRegion = { atlas: 'Multilevel Human Atlas', template: `ICBM 152 2009c Nonlinear Asymmetric`, + parcVersion: 'v1.18', position: [-0.256, 26.028, -11.678] } describe(`> when selecting duplicated regions at ${duplicatedRegion.atlas} / ${duplicatedRegion.template} / ${JSON.stringify(duplicatedRegion.position)}`, () => { @@ -14,7 +15,7 @@ describe('> selecting regions', () => { const newPage = new AtlasPage() await newPage.init() await newPage.goto() - await newPage.setAtlasSpecifications(duplicatedRegion.atlas, [ duplicatedRegion.template ]) + await newPage.setAtlasSpecifications(duplicatedRegion.atlas, [ duplicatedRegion.template ], duplicatedRegion.parcVersion) await newPage.wait(500) await newPage.waitForAsync() await newPage.execScript(`interactiveViewer.viewerHandle.setNavigationLoc(${JSON.stringify(duplicatedRegion.position.map(v => v*1e6))}, true)`) diff --git a/e2e/src/selecting/template.prod.e2e-spec.js b/e2e/src/selecting/template.prod.e2e-spec.js index 6009f709fa4ee07450a0c83a96ad74db7bfff7b1..08e8028d7b039af8aa455fc05fbb917415569cc3 100644 --- a/e2e/src/selecting/template.prod.e2e-spec.js +++ b/e2e/src/selecting/template.prod.e2e-spec.js @@ -1,5 +1,11 @@ +const { isatty } = require("tty") const { AtlasPage } = require("../util") +const atlasName = 'Multilevel Human Atlas' +const tNameIcbm152 = 'ICBM 152 2009c Nonlinear Asymmetric' +const tNameColin = 'MNI Colin 27' +const tNameBB = 'Big Brain (Histology)' + describe('templates > ', () => { let iavPage @@ -12,7 +18,7 @@ describe('templates > ', () => { it('can select template by clicking main card', async () => { await iavPage.goto() - await iavPage.selectTitleCard('ICBM 2009c Nonlinear Asymmetric') + await iavPage.setAtlasSpecifications(atlasName) await iavPage.wait(1000) const viewerIsPopulated = await iavPage.viewerIsPopulated() @@ -24,10 +30,10 @@ describe('templates > ', () => { await iavPage.goto() - await iavPage.selectTitleCard('ICBM 2009c Nonlinear Asymmetric') + await iavPage.setAtlasSpecifications(atlasName, [ tNameIcbm152 ]) await iavPage.wait(1000) - await iavPage.selectDropdownTemplate('Big Brain (Histology)') + await iavPage.setAtlasSpecifications(atlasName, [ tNameBB ]) await iavPage.wait(7000) const viewerIsPopulated = await iavPage.viewerIsPopulated() @@ -40,10 +46,10 @@ describe('templates > ', () => { await iavPage.goto() - await iavPage.selectTitleCard('ICBM 2009c Nonlinear Asymmetric') + await iavPage.setAtlasSpecifications(atlasName, [ tNameIcbm152 ]) await iavPage.wait(1000) - const info = await iavPage.getTemplateInfo() + const info = await iavPage.getAtlasTileInfo(tNameIcbm152) expect( info.indexOf(expectedDesc) @@ -51,29 +57,50 @@ describe('templates > ', () => { }) }) - describe('switching template > ', () => { - it('works in history navigation', async () => { + describe('> switching template > ', () => { + beforeEach(async () => { + await iavPage.goto() - await iavPage.selectTitleCard('ICBM 2009c Nonlinear Asymmetric') + await iavPage.setAtlasSpecifications(atlasName, [ tNameIcbm152 ]) await iavPage.wait(500) await iavPage.waitUntilAllChunksLoaded() + }) + it('> activeFlag works', async () => { + const isActive = await iavPage.atlasTileIsActive(tNameIcbm152) + expect(isActive.toString()).toEqual('true') + const isNotActive = await iavPage.atlasTileIsActive(tNameColin) + expect(isNotActive.toString()).toEqual('false') + + }) + it('> works in regular navigation', async () => { - await iavPage.selectDropdownTemplate('MNI Colin 27') + await iavPage.setAtlasSpecifications(atlasName, [ tNameColin ]) await iavPage.wait(500) await iavPage.waitUntilAllChunksLoaded() - await iavPage.historyBack() + const isActive = await iavPage.atlasTileIsActive(tNameColin) + expect(isActive.toString()).toEqual('true') + + const isNotActive = await iavPage.atlasTileIsActive(tNameIcbm152) + expect(isNotActive.toString()).toEqual('false') + + }) + + it('> works in history navigation', async () => { + + await iavPage.setAtlasSpecifications(atlasName, [ tNameColin ]) await iavPage.wait(500) + await iavPage.waitUntilAllChunksLoaded() + await iavPage.historyBack() - await iavPage.wait(2000) - - const visible = await iavPage.sideNavIsVisible() - if (!visible) await iavPage.clickSideNavTab() - const templateInfo = await iavPage.getTemplateInfo() + await iavPage.wait(500) + await iavPage.waitForAsync() - expect( - templateInfo.indexOf('ICBM 2009c Nonlinear Asymmetric') - ).toBeGreaterThanOrEqual(0) + const isActive = await iavPage.atlasTileIsActive(tNameIcbm152) + expect(isActive.toString()).toEqual('true') + const isNotActive = await iavPage.atlasTileIsActive(tNameColin) + expect(isNotActive.toString()).toEqual('false') }) }) + }) \ No newline at end of file diff --git a/e2e/util/selenium/layout.js b/e2e/util/selenium/layout.js index 6a16ae056362dd19b8bc9745761657c6ea71cbb6..2b102b6245845b4ec55a57d7b99df3c249292381 100644 --- a/e2e/util/selenium/layout.js +++ b/e2e/util/selenium/layout.js @@ -362,23 +362,68 @@ class WdLayoutPage extends WdBase{ } } - async selectTile(tileName){ + /** + * + * @param {WebElement} webEl + * @description Look for child element fas.fa-info, click, then get modal text + */ + async _getInfo(webEl) { + const infoBtn = await webEl.findElement( + By.css(`.fas.fa-info`) + ) + if (!infoBtn) { + return null + } + await infoBtn.click() + await this.wait(500) + await this.waitForAsync() + const text = await this.getModalText() + await this.clearAlerts() + await this.wait(500) + return text + } + + async _getAtlasSelectorTile(tileName) { + if (!tileName) throw new Error(`tileName needs to be provided`) await this._setAtlasSelectorExpanded(true) await this.wait(1000) const allTiles = await this._browser.findElements( By.css(`mat-grid-tile`) ) const idx = await _getIndexFromArrayOfWebElements(tileName, allTiles) - if (idx >= 0) await allTiles[idx].click() - else throw new Error(`#selectTile: tileName ${tileName} cannot be found.`) + + if (idx < 0) throw new Error(`#selectTile: tileName ${tileName} cannot be found.`) + return allTiles[idx] + } + + async selectTile(tileName){ + const el = await this._getAtlasSelectorTile(tileName) + await el.click() + } + + async getAtlasTileInfo(tileName){ + const el = await this._getAtlasSelectorTile(tileName) + return this._getInfo(el) + } + + async atlasTileIsActive(tileName) { + const el = await this._getAtlasSelectorTile(tileName) + return await el.getAttribute('aria-checked') } async changeParc(parcName) { throw new Error(`changeParc NYI`) } - async changeParcVersion(parcVerion) { - throw new Error(`changeParcVersion NYI`) + async changeParcVersion(parcVersion) { + await this._browser.findElement( + By.css(`[aria-label="${ARIA_LABELS.PARC_VER_SELECT}"]`) + ).click() + await this.wait(500) + this._browser.findElement( + By.css(`[aria-label="${ARIA_LABELS.PARC_VER_CONTAINER}"] [aria-label="${parcVersion}"]`) + ).click() + await this.wait(500) } async setAtlasSpecifications(atlasName, atlasSpecifications = [], parcVersion = null) { @@ -393,7 +438,7 @@ class WdLayoutPage extends WdBase{ * if not at title screen * select from dropdown */ - console.log(e) + console.log(`selecting from ui-splash screen errored, try selecting from dropdown`) await this.selectDropdownOption(`[aria-label="${ARIA_LABELS.SELECT_ATLAS}"]`, atlasName) } @@ -494,10 +539,6 @@ class WdLayoutPage extends WdBase{ return this._getStatusPanel().click() } - async getTemplateInfo(){ - throw new Error(`getTemplateInfo has been deprecated. Implmenet new method of getting info`) - } - // will throw if additional layer control is not visible additionalLayerControlIsExpanded() { throw new Error(`additionalLayerControlIsExpanded is deprecated`) diff --git a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html index d73fda145cd10295d6f6494643a289e723a11066..350ed7322fe270dbe4a56c140693d99685954b30 100644 --- a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html +++ b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html @@ -11,7 +11,8 @@ </mat-card-subtitle> <mat-grid-list cols="3" rowHeight="3:4"> <!-- template tiles --> - <mat-grid-tile *ngFor="let template of availableTemplates$ | async; trackBy: trackbyAtId"> + <mat-grid-tile *ngFor="let template of availableTemplates$ | async; trackBy: trackbyAtId" + [attr.aria-checked]="selectedTemplateSpaceId === template['@id']"> <ng-container *ngTemplateOutlet="tileTmpl; context: { tileSrc: template, selected: selectedTemplateSpaceId === template['@id'], @@ -31,7 +32,8 @@ <mat-grid-list cols="3" rowHeight="3:4"> <!-- non grouped layers --> - <mat-grid-tile *ngFor="let layer of (nonGroupedLayers$ | async); trackBy: trackbyAtId"> + <mat-grid-tile *ngFor="let layer of (nonGroupedLayers$ | async); trackBy: trackbyAtId" + [attr.aria-checked]="selectedLayersIncludes(layer['@id'])"> <ng-container *ngTemplateOutlet="tileTmpl; context: { tileSrc: layer, selected: selectedLayersIncludes(layer['@id']), @@ -43,7 +45,8 @@ </mat-grid-tile> <!-- grouped layers --> - <mat-grid-tile *ngFor="let group of (groupedLayers$ | async); trackBy: trackbyName"> + <mat-grid-tile *ngFor="let group of (groupedLayers$ | async); trackBy: trackbyName" + [attr.aria-checked]="selectedOneOfTheLayers(group.parcellations)"> <ng-container *ngTemplateOutlet="tileTmpl; context: { tileSrc: group, selected: selectedOneOfTheLayers(group.parcellations), @@ -175,7 +178,8 @@ rowHeight="1:1" iav-stop="click" (iav-outsideClick)="collapseExpandedGroup()"> - <mat-grid-tile *ngFor="let layer of layerGroupItems"> + <mat-grid-tile *ngFor="let layer of layerGroupItems" + [attr.aria-checked]="selectedLayersIncludes(layer['@id'])"> <ng-container *ngTemplateOutlet="tileTmpl; context: { tileSrc: layer, diff --git a/src/atlasViewer/atlasViewer.style.css b/src/atlasViewer/atlasViewer.style.css index 1a6915506e6049e60f33fca36781b9fa6e29ba80..d89f76ce6b5edcc4463c44fd0c80db2465b002a8 100644 --- a/src/atlasViewer/atlasViewer.style.css +++ b/src/atlasViewer/atlasViewer.style.css @@ -8,6 +8,7 @@ :host[darktheme="true"] { background-color:black; + display: block; } ui-nehuba-container diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html index f708a821af35d357e808a68a1d15d2d5689937da..0bf240e6463c1762fc33a339b5e0518633e255da 100644 --- a/src/viewerModule/viewerCmp/viewerCmp.template.html +++ b/src/viewerModule/viewerCmp/viewerCmp.template.html @@ -252,7 +252,6 @@ </ng-template> <!-- parcellation chip / region chip --> -<!-- TODO maybe migrate to atlas cmp... later? --> <ng-template #currParcellationTmpl let-parc="parc" let-addParc="addParc"> <div [matMenuTriggerFor]="layerVersionMenu" [matMenuTriggerData]="{ layerVersionMenuTrigger: layerVersionMenuTrigger }" @@ -264,6 +263,7 @@ parcel: p, selected: true, dismissable: true, + ariaLabel: ARIA_LABELS.PARC_VER_SELECT, onclick: layerVersionMenuTrigger.toggleMenu.bind(layerVersionMenuTrigger) }"> </ng-container> @@ -274,6 +274,7 @@ parcel: parc, selected: false, dismissable: false, + ariaLabel: ARIA_LABELS.PARC_VER_SELECT, onclick: layerVersionMenuTrigger.toggleMenu.bind(layerVersionMenuTrigger) }"> </ng-container> @@ -285,6 +286,7 @@ <!-- layer version selector --> <mat-menu #layerVersionMenu class="bg-none box-shadow-none" + [aria-label]="ARIA_LABELS.PARC_VER_CONTAINER" [hasBackdrop]="false"> <ng-template matMenuContent let-layerVersionMenuTrigger="layerVersionMenuTrigger"> <div (iav-outsideClick)="layerVersionMenuTrigger.closeMenu()"> @@ -296,6 +298,7 @@ selected: selectedParcellation['@id'] === parcVer['@id'], dismissable: false, class: 'w-100', + ariaLabel: parcVer.displayName || parcVer.name, onclick: bindFns([ [ selectParcellation.bind(this), parcVer ], [ layerVersionMenuTrigger.closeMenu.bind(layerVersionMenuTrigger) ] @@ -315,9 +318,11 @@ let-selected="selected" let-dismissable="dismissable" let-chipClass="class" + let-ariaLabel="ariaLabel" let-onclick="onclick"> <mat-chip class="pe-all position-relative z-index-2 d-inline-flex justify-content-between" [ngClass]="chipClass" + [attr.aria-label]="ariaLabel" (click)="onclick && onclick()" [selected]="selected">