From 697690c9779223ac41a118b205efa5a5e377a7f0 Mon Sep 17 00:00:00 2001
From: Xiao Gui <xgui3783@gmail.com>
Date: Fri, 27 Mar 2020 17:09:00 +0100
Subject: [PATCH] fix e2e inconsistencies

---
 e2e/src/layout/layout.e2e-spec.js             | 14 ++++++++++
 e2e/src/util.js                               | 28 ++++++++++++++-----
 .../atlasViewer.constantService.service.ts    |  6 +++-
 src/services/state/viewerState.store.ts       |  2 +-
 .../splashScreen/splashScreen.component.ts    | 25 +++++++++++++++--
 .../splashScreen/splashScreen.template.html   |  7 +++++
 6 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/e2e/src/layout/layout.e2e-spec.js b/e2e/src/layout/layout.e2e-spec.js
index 148a11d4c..45949849d 100644
--- a/e2e/src/layout/layout.e2e-spec.js
+++ b/e2e/src/layout/layout.e2e-spec.js
@@ -11,6 +11,13 @@ describe('> sidenav', () => {
     await layoutPage.goto('/?templateSelected=MNI+152+ICBM+2009c+Nonlinear+Asymmetric&parcellationSelected=JuBrain+Cytoarchitectonic+Atlas')
     await layoutPage.wait(MAT_SIDENAV_TIMEOUT)
     await layoutPage.dismissModal()
+
+    do {
+
+    } while(
+      await this.wait(100),
+      !(await this.viewerIsPopulated())
+    )
   })
 
   it('> on init, side panel should be visible', async () => {
@@ -49,6 +56,13 @@ describe('> status panel', () => {
     await layoutPage.goto('/?templateSelected=MNI+152+ICBM+2009c+Nonlinear+Asymmetric&parcellationSelected=JuBrain+Cytoarchitectonic+Atlas')
     await layoutPage.wait(MAT_SIDENAV_TIMEOUT)
     await layoutPage.dismissModal()
+
+    do {
+
+    } while(
+      await this.wait(100),
+      !(await this.viewerIsPopulated())
+    )
   })
 
   afterEach(() => {
diff --git a/e2e/src/util.js b/e2e/src/util.js
index 00f524b8e..6d4a1a336 100644
--- a/e2e/src/util.js
+++ b/e2e/src/util.js
@@ -133,10 +133,14 @@ class WdBase{
       await this._browser.get(actualUrl)
     }
 
+    // if doNotAutomate is not set
+    // should wait for async operations to end 
     if (!doNotAutomate) {
       await this.wait(200)
       await this.dismissModal()
       await this.wait(200)
+      await this.waitForAsync()
+      
     }
   }
 
@@ -620,13 +624,23 @@ class WdIavPage extends WdLayoutPage{
   }
 
   async viewerIsPopulated() {
-    const ngContainer = await this._browser.findElement(
-      By.id('neuroglancer-container')
-    )
-    const canvas = await ngContainer.findElement(
-      By.tagName('canvas')
-    )
-    return !!canvas
+    try {
+      const ngContainer = await this._browser.findElement(
+        By.id('neuroglancer-container')
+      )
+      if (! (await ngContainer.isDisplayed())) {
+        return false
+      }
+      const canvas = await ngContainer.findElement(
+        By.tagName('canvas')
+      )
+      if (!(await canvas.isDisplayed())) {
+        return false
+      }
+      return true
+    } catch (e) {
+      return false
+    }
   }
 
   async getNavigationState() {
diff --git a/src/atlasViewer/atlasViewer.constantService.service.ts b/src/atlasViewer/atlasViewer.constantService.service.ts
index d198eaa62..56057d3be 100644
--- a/src/atlasViewer/atlasViewer.constantService.service.ts
+++ b/src/atlasViewer/atlasViewer.constantService.service.ts
@@ -101,7 +101,11 @@ export class AtlasViewerConstantsServices implements OnDestroy {
     })
   )
 
-  public initFetchTemplate$ = this.http.get(`${this.backendUrl}templates`, { responseType: 'json' }).pipe(
+  public getTemplateEndpoint$ = this.http.get(`${this.backendUrl}templates`, { responseType: 'json' }).pipe(
+    shareReplay(1)
+  )
+
+  public initFetchTemplate$ = this.getTemplateEndpoint$.pipe(
     tap((arr: any[]) => this.totalTemplates = arr.length),
     switchMap((templates: string[]) => merge(
       ...templates.map(templateName => this.fetchTemplate(templateName).pipe(
diff --git a/src/services/state/viewerState.store.ts b/src/services/state/viewerState.store.ts
index 32aa24588..455ea30b8 100644
--- a/src/services/state/viewerState.store.ts
+++ b/src/services/state/viewerState.store.ts
@@ -7,7 +7,7 @@ import { IUserLandmark } from 'src/atlasViewer/atlasViewer.apiService.service';
 import { INgLayerInterface } from 'src/atlasViewer/atlasViewer.component';
 import { getViewer } from 'src/util/fn';
 import { LoggingService } from 'src/logging';
-import { generateLabelIndexId, IavRootStoreInterface, viewerState } from '../stateStore.service';
+import { generateLabelIndexId, IavRootStoreInterface } from '../stateStore.service';
 import { GENERAL_ACTION_TYPES } from '../stateStore.service'
 import { MOUSEOVER_USER_LANDMARK, CLOSE_SIDE_PANEL } from './uiState.store';
 
diff --git a/src/ui/nehubaContainer/splashScreen/splashScreen.component.ts b/src/ui/nehubaContainer/splashScreen/splashScreen.component.ts
index f20cb3bc4..8681248e7 100644
--- a/src/ui/nehubaContainer/splashScreen/splashScreen.component.ts
+++ b/src/ui/nehubaContainer/splashScreen/splashScreen.component.ts
@@ -1,7 +1,7 @@
 import { AfterViewInit, Component, ElementRef, Pipe, PipeTransform, ViewChild } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { fromEvent, Observable, Subject, Subscription } from "rxjs";
-import { bufferTime, filter, map, switchMap, take, withLatestFrom } from 'rxjs/operators'
+import { fromEvent, Observable, Subject, Subscription, combineLatest } from "rxjs";
+import { bufferTime, filter, map, switchMap, take, withLatestFrom, shareReplay, startWith } from 'rxjs/operators'
 import { AtlasViewerConstantsServices } from "src/atlasViewer/atlasViewer.constantService.service";
 import { NEWVIEWER, ViewerStateInterface } from "src/services/stateStore.service";
 
@@ -15,6 +15,7 @@ import { NEWVIEWER, ViewerStateInterface } from "src/services/stateStore.service
 
 export class SplashScreen implements AfterViewInit {
 
+  public stillLoadingTemplates$: Observable<any>
   public loadedTemplate$: Observable<any[]>
   @ViewChild('parentContainer', {read: ElementRef})
   private parentContainer: ElementRef
@@ -25,11 +26,29 @@ export class SplashScreen implements AfterViewInit {
   constructor(
     private store: Store<ViewerStateInterface>,
     private constanceService: AtlasViewerConstantsServices,
-    private constantsService: AtlasViewerConstantsServices,
   ) {
     this.loadedTemplate$ = this.store.pipe(
       select('viewerState'),
       select('fetchedTemplates'),
+      shareReplay(1),
+    )
+
+    this.stillLoadingTemplates$ = combineLatest(
+      this.constanceService.getTemplateEndpoint$.pipe(
+        startWith(null)
+      ),
+      this.loadedTemplate$.pipe(
+        startWith([])
+      )
+    ).pipe(
+      map(([templateEndpoints, loadedTemplates]) => {
+        if (templateEndpoints && Array.isArray(templateEndpoints)) {
+          // TODO this is not exactly correct
+          return templateEndpoints.slice(loadedTemplates.length)
+        } else {
+          return null
+        }
+      })
     )
   }
 
diff --git a/src/ui/nehubaContainer/splashScreen/splashScreen.template.html b/src/ui/nehubaContainer/splashScreen/splashScreen.template.html
index 9d4a9b4ce..af7271b05 100644
--- a/src/ui/nehubaContainer/splashScreen/splashScreen.template.html
+++ b/src/ui/nehubaContainer/splashScreen/splashScreen.template.html
@@ -43,5 +43,12 @@
       <mat-card-footer>
       </mat-card-footer>
     </mat-card>
+    <ng-container *ngIf="stillLoadingTemplates$ | async as stillLoadingTemplates">
+      <div class="d-flex align-items-center p-4" *ngFor="let t of stillLoadingTemplates">
+        <h1 class="mat-h1">
+          <div class="spinnerAnimationCircle"></div>
+        </h1>
+      </div>
+    </ng-container>
   </div>
 </div>
\ No newline at end of file
-- 
GitLab