diff --git a/e2e/src/layout/layout.e2e-spec.js b/e2e/src/layout/layout.e2e-spec.js new file mode 100644 index 0000000000000000000000000000000000000000..5da91629a1c9d2c28ceb314d1641da09282d737d --- /dev/null +++ b/e2e/src/layout/layout.e2e-spec.js @@ -0,0 +1,131 @@ +const chromeOpts = require('../../chromeOpts') +const pptr = require('puppeteer') +const ATLAS_URL = (process.env.ATLAS_URL || 'http://localhost:3000').replace(/\/$/, '') +if (ATLAS_URL.length === 0) throw new Error(`ATLAS_URL must either be left unset or defined.`) +if (ATLAS_URL[ATLAS_URL.length - 1] === '/') throw new Error(`ATLAS_URL should not trail with a slash: ${ATLAS_URL}`) + +const MAT_SIDENAV_TIMEOUT = 500 + +const getVisibility = page => async selector => await page.evaluate(sel => { + const el = document.querySelector(sel) + if (el) return el.style.visibility + else return null +}, selector) + +const clickTab = async page => { + await page.evaluate(() => { + const el = document.querySelector('button[mat-drawer-trigger]') + el.click() + }) +} + +let browser +describe('IAV layout e2e', () => { + beforeAll(async () => { + browser = await pptr.launch({ + ...( + chromeOpts.indexOf('--headless') >= 0 + ? { headless: true } + : {} + ), + args: [ + ...chromeOpts + ] + }) + }) + + describe('toggling side panel', () => { + let page + + beforeAll(async () => { + const urlMni152JuBrain = `${ATLAS_URL}/?templateSelected=MNI+152+ICBM+2009c+Nonlinear+Asymmetric&parcellationSelected=JuBrain+Cytoarchitectonic+Atlas&cRegionsSelected=%7B%22jubrain+mni152+v18+left%22%3A%222%22%2C%22jubrain+mni152+v18+right%22%3A%222%22%7D&cNavigation=0.0.0.-W000..2_ZG29.-ASCS.2-8jM2._aAY3..BSR0..70hl~.1w4W0~.70hk..1Pl9` + page = await browser.newPage() + await page.goto(urlMni152JuBrain, {waitUntil: 'networkidle2'}) + await page.waitFor('mat-drawer') + }) + + it('on init, side drawer should be visible', async () => { + const visibility = await (getVisibility(page))('mat-drawer[mat-drawer-opened]') + expect( + visibility + ).toBe('visible') + }) + + it('toggle tab should hide', async () => { + await clickTab(page) + await page.waitFor('mat-drawer[mat-drawer-opened=false]') + await page.waitFor(MAT_SIDENAV_TIMEOUT) + + const visibility = await (getVisibility(page))('mat-drawer[mat-drawer-opened]') + expect( + visibility + ).toBe('hidden') + }) + + it('toggle tab should show', async () => { + await clickTab(page) + await page.waitFor('mat-drawer[mat-drawer-opened=true]') + await page.waitFor(MAT_SIDENAV_TIMEOUT) + + const visibility = await (getVisibility(page))('mat-drawer[mat-drawer-opened]') + expect( + visibility + ).toBe('visible') + }) + + it('sidepanel property window should be hidden when side panel is shown', async () => { + + const visibility = await (getVisibility(page))('mat-drawer[mat-drawer-opened]') + expect( + visibility + ).toBe('visible') + + const statusPanel = await page.$('[mat-drawer-status-panel]') + expect(statusPanel).toBeNull + }) + + it('side panel property window should be visible when panel is hidden', async () => { + await clickTab(page) + + await page.waitFor('mat-drawer[mat-drawer-opened=false]') + await page.waitFor(MAT_SIDENAV_TIMEOUT) + const visibility = await (getVisibility(page))('mat-drawer[mat-drawer-opened]') + expect( + visibility + ).toBe('hidden') + + const statusPanel = await page.$('[mat-drawer-status-panel]') + expect(statusPanel).toBeTruthy + }) + + it('side panel, if visible, should open side panel', async () => { + + const statusPanel = await page.$('[mat-drawer-status-panel]') + expect(statusPanel).toBeTruthy + + await page.evaluate(() => { + const el = document.querySelector('[mat-drawer-status-panel]') + if (el) el.click() + else throw new Error(`mat-drawer-status-panel not found`) + }) + + await page.waitFor(MAT_SIDENAV_TIMEOUT) + + const visibility = await (getVisibility(page))('mat-drawer[mat-drawer-opened]') + expect( + visibility + ).toBe('visible') + }) + + it('after open with status panel, tag should continue to work', async () => { + await clickTab(page) + + await page.waitFor('mat-drawer[mat-drawer-opened=false]') + await page.waitFor(MAT_SIDENAV_TIMEOUT) + const visibility = await (getVisibility(page))('mat-drawer[mat-drawer-opened]') + expect( + visibility + ).toBe('hidden') + }) + }) +}) diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html index dfa7199be935d6cf46f9a577e0f4004a3229b99d..96b10dffc10f27312e86939e481bada9e1215bba 100644 --- a/src/atlasViewer/atlasViewer.template.html +++ b/src/atlasViewer/atlasViewer.template.html @@ -42,22 +42,29 @@ <ng-template #viewerBody> <div class="atlas-container" (drag-drop)="localFileService.handleFileDrop($event)"> - <ui-nehuba-container iav-mouse-hover #iavMouseHoverEl="iavMouseHover" - [currentOnHoverObs$]="iavMouseHoverEl.currentOnHoverObs$" - [currentOnHover]="iavMouseHoverEl.currentOnHoverObs$ | async" - iav-captureClickListenerDirective - (iav-captureClickListenerDirective-onMousedown)="mouseDownNehuba($event)" - (iav-captureClickListenerDirective-onClick)="mouseClickNehuba($event)"> + <ui-nehuba-container iav-mouse-hover + #iavMouseHoverEl="iavMouseHover" + [currentOnHoverObs$]="iavMouseHoverEl.currentOnHoverObs$" + [currentOnHover]="iavMouseHoverEl.currentOnHoverObs$ | async" + iav-captureClickListenerDirective + (iav-captureClickListenerDirective-onMousedown)="mouseDownNehuba($event)" + (iav-captureClickListenerDirective-onClick)="mouseClickNehuba($event)"> </ui-nehuba-container> <div class="z-index-10 position-absolute pe-none w-100 h-100"> <!-- dataset search side nav --> - <mat-drawer-container *ngIf="newViewer$ | async" [hasBackdrop]="false" + <mat-drawer-container + *ngIf="newViewer$ | async" + [hasBackdrop]="false" class="w-100 h-100 bg-none mat-drawer-content-overflow-visible"> <mat-drawer mode="push" class="col-10 col-sm-10 col-md-4 col-lg-3 col-xl-2 p-2 bg-none box-shadow-none overflow-visible" - [disableClose]="true" [autoFocus]="false" [opened]="sidePanelIsOpen$ | async" #sideNavDrawer> + [disableClose]="true" + [autoFocus]="false" + [opened]="sidePanelIsOpen$ | async" + [attr.mat-drawer-opened]="sidePanelIsOpen$ | async" + #sideNavDrawer> <search-side-nav (dismiss)="toggleSideNavMenu(true)" class="h-100 d-block overflow-visible" #searchSideNav> </search-side-nav> @@ -67,17 +74,25 @@ <!-- tag for opening and closing side nav --> <div class="d-flex h-100 align-items-start bg-none pe-none"> - <button mat-flat-button matBadgePosition="above after" matBadgeColor="accent" + <button mat-flat-button + matBadgePosition="above after" + matBadgeColor="accent" [matBadge]="!sideNavDrawer.opened && (selectedRegions$ | async)?.length ? (selectedRegions$ | async)?.length : null" [matTooltip]="!sideNavDrawer.opened ? (selectedRegions$ | async)?.length ? ('Explore ' + (selectedRegions$ | async)?.length + ' selected regions.') : 'Explore current view' : null" [ngClass]="{'translate-x-6-n': !sideNavDrawer.opened, 'translate-x-7-n': sideNavDrawer.opened}" - class="pe-all mt-5" (click)="toggleSideNavMenu(sideNavDrawer.opened)"> + class="pe-all mt-5" + (click)="toggleSideNavMenu(sideNavDrawer.opened)" + mat-drawer-trigger> <i [ngClass]="{'fa-chevron-left': sideNavDrawer.opened, 'fa-chevron-right': !sideNavDrawer.opened}" class="fas translate-x-3"></i> </button> - <mat-card *ngIf="!sideNavDrawer.opened" (click)="toggleSideNavMenu(false)" mat-ripple + <mat-card + *ngIf="!sideNavDrawer.opened" + (click)="toggleSideNavMenu(false)" + mat-ripple + mat-drawer-status-panel class="pe-all mt-4 muted translate-x-4-n"> <mat-card-content> <viewer-state-mini> @@ -93,8 +108,8 @@ <div class="d-flex flex-row justify-content-end z-index-10 position-absolute pe-none w-100 h-100"> <signin-banner - signinWrapper - [parcellationIsSelected]="selectedParcellation? true : false"> + signinWrapper + [parcellationIsSelected]="selectedParcellation? true : false"> </signin-banner> </div> diff --git a/src/components/dropdown/dropdown.component.spec.ts b/src/components/dropdown/dropdown.component.spec.ts index 6bf288d0648e3b7db0196b3abb14ad61a3ff389b..d4d9e9381441ed2c67cd5fee24c6e3d967182ab0 100644 --- a/src/components/dropdown/dropdown.component.spec.ts +++ b/src/components/dropdown/dropdown.component.spec.ts @@ -6,9 +6,6 @@ import { RadioList } from '../radiolist/radiolist.component' import { DropdownComponent } from './dropdown.component'; describe('dropdown component', () => { - it('jasmine works', () => { - expect(1).toBe(1) - }) beforeEach(async(() => { TestBed.configureTestingModule({ imports: [