diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 500d8035fd9c241b9bc56ef90c428b7c99209e1f..c5cec5a833039b574591fec54deb1a73a24bcc03 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -12,6 +12,8 @@ env:
   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"
 
 jobs:
   buildimage:
@@ -58,8 +60,8 @@ jobs:
         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 latest
-        docker exec -t ${DOCKER_E2E_PPTR} npm i puppeteer
+        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 }}
diff --git a/e2e/chromeOpts.js b/e2e/chromeOpts.js
index b6900fed9e9fd916c9ffec56222e5b8afa5dea35..eccfe512b1c0bd422f441252f3b5dc70431ab590 100644
--- a/e2e/chromeOpts.js
+++ b/e2e/chromeOpts.js
@@ -4,5 +4,5 @@ module.exports = [
   '--disable-gpu',
   '--disable-setuid-sandbox',
   "--disable-extensions",
-  '--window-size=1600,900'
+  '--window-size=800,796'
 ]
\ No newline at end of file
diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js
index 59fdb6a18bc9fb074e53db97076b0b9c56b3d7f9..bf84a28140cb73eed761e39cc108f6c2559d934d 100644
--- a/e2e/protractor.conf.js
+++ b/e2e/protractor.conf.js
@@ -18,7 +18,7 @@ exports.config = {
 
     // Use headless chrome
     browserName: 'chrome',
-    chromeOptions: {
+    'goog:chromeOptions': {
       args: [
         ...chromeOpts
       ],
diff --git a/e2e/src/advanced/browsingForDatasets.e2e-spec.js b/e2e/src/advanced/browsingForDatasets.e2e-spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..d6ec2e81070f009530a6d5461b8a96a6a948261d
--- /dev/null
+++ b/e2e/src/advanced/browsingForDatasets.e2e-spec.js
@@ -0,0 +1,63 @@
+const { AtlasPage } = require('../util')
+
+const templates = [
+  'MNI Colin 27',
+  'ICBM 2009c Nonlinear Asymmetric'
+]
+
+const areasShouldHaveRecptor = [
+  'Area 7A (SPL)',
+  'Area 3b (PostCG)',
+  'Area PFm (IPL)',
+  'Area PFop (IPL)',
+  'Area PF (IPL)',
+  'Area PGp (IPL)',
+  'Area PGa (IPL)',
+  'Area PFt (IPL)',
+  'Area PFcm (IPL)',
+  'Area hOc1 (V1, 17, CalcS)',
+  'Area 44 (IFG)',
+  'Area 45 (IFG)',
+  'Area 4p (PreCG)',
+  'Area TE 1.0 (HESCHL)',
+  'Area FG1 (FusG)',
+  'Area FG2 (FusG)'
+]
+
+describe('dataset browser', () => {
+  let iavPage
+  beforeAll(async () => {
+    iavPage = new AtlasPage()
+    await iavPage.init()
+  })
+
+  for (const template of templates) {
+    describe(`in template: ${template}`, () => {
+      beforeAll(async () => {
+        await iavPage.goto()
+        await iavPage.selectTitleCard(template)
+        await iavPage.wait(500)
+        await iavPage.waitUntilAllChunksLoaded()
+      })
+
+      afterEach(async () => {
+        await iavPage.clearSearchRegionWithText()
+        await iavPage.clearAllSelectedRegions()
+      })
+      for (const area of areasShouldHaveRecptor) {
+        it(`receptor data ${area} should be able to be found`, async () => {
+          await iavPage.searchRegionWithText(area)
+          await iavPage.wait(2000)
+          await iavPage.selectSearchRegionAutocompleteWithText()
+          await iavPage.dismissModal()
+          await iavPage.searchRegionWithText('')
+
+          const datasets = await iavPage.getVisibleDatasets()
+          const filteredDs = datasets.filter(ds => ds.toLowerCase().indexOf('receptor') >= 0)
+          expect(filteredDs.length).toBeGreaterThan(0)
+          //TODO
+        })
+      }
+    })
+  }
+})
\ No newline at end of file
diff --git a/e2e/src/advanced/urlParsing.e2e-spec.js b/e2e/src/advanced/urlParsing.e2e-spec.js
index 3608b8dd1c16b1b0bc41183a7a769de3d8ae4bd3..46b4bd13d8dbc85d0d161a3f4758d8f458f12ddb 100644
--- a/e2e/src/advanced/urlParsing.e2e-spec.js
+++ b/e2e/src/advanced/urlParsing.e2e-spec.js
@@ -47,7 +47,7 @@ describe('url parsing', () => {
       ]
     }
 
-    await iavPage.goto(searchParam)
+    await iavPage.goto(searchParam, { doNotAutomate: true })
     await iavPage.wait(2000)
     const actualNav = await iavPage.getNavigationState()
 
@@ -69,7 +69,7 @@ describe('url parsing', () => {
     searchParam.set('parcellationSelected', 'JuBrain Cytoarchitectonic Atlas')
     searchParam.set('pluginStates', 'http://localhost:3001/manifest.json')
 
-    await iavPage.goto(`/?${searchParam.toString()}`, { interceptHttp: true })
+    await iavPage.goto(`/?${searchParam.toString()}`, { interceptHttp: true, doNotAutomate: true })
     await iavPage.wait(10000)
     const interceptedCalls = await iavPage.getInterceptedHttpCalls()
     expect(
diff --git a/e2e/src/iv.e2e-spec.js b/e2e/src/iv.e2e-spec.js
deleted file mode 100644
index aac418a0d43619dfe18d78b1c1e1c21d1d32d739..0000000000000000000000000000000000000000
--- a/e2e/src/iv.e2e-spec.js
+++ /dev/null
@@ -1,125 +0,0 @@
-const chromeOpts = require('../chromeOpts')
-const noErrorLog = require('./noErrorLog')
-const { getSelectedTemplate, getSelectedParcellation, getSelectedRegions, getCurrentNavigationState, awaitNehubaViewer } = require('./ivApi')
-const { getSearchParam, wait } = require('./util')
-const { URLSearchParams } = require('url')
-
-const { waitMultiple } = require('./util')
-
-describe('protractor works', () => {
-  it('protractor works', () => {
-    expect(true).toEqual(true)
-  })
-})
-
-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}`)
-
-let browser
-describe('IAV', () => {
-  beforeAll(async () => {
-    browser = await pptr.launch({
-      ...(
-        chromeOpts.indexOf('--headless') >= 0
-          ? { headless: true }
-          : {}
-      ),
-      args: [
-        ...chromeOpts
-      ]
-    })
-  })
-
-  // TODO figure out how to get jasmine to compare array members
-  describe('api', () => {
-    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`
-    describe('selectRegion obs', () => {
-      it('should populate selected region with inherited properties', async () => {
-        const page = await browser.newPage()
-        await page.goto(urlMni152JuBrain, {waitUntil: 'networkidle2'})
-        const regions = await getSelectedRegions(page)
-        for (const region of regions){
-          expect(region.relatedAreas).toBeDefined()
-          expect(
-            region.relatedAreas.map(({ name }) => name).sort()
-          ).toEqual(
-            [
-              'Area 44v',
-              'Area 44d'
-            ].sort()
-          )
-        }
-      })
-    })
-  })
-  
-  describe('Url parsing', () => {
-    
-
-    it('pluginStates should result in call to fetch pluginManifest', async () => {
-      const searchParam = new URLSearchParams()
-      searchParam.set('templateSelected', 'MNI 152 ICBM 2009c Nonlinear Asymmetric')
-      searchParam.set('parcellationSelected', 'JuBrain Cytoarchitectonic Atlas')
-      searchParam.set('pluginStates', 'http://localhost:3001/manifest.json')
-      
-      const page = await browser.newPage()
-
-      await page.setRequestInterception(true)
-
-      const externalApi = {
-        manifestCalled: false,
-        templateCalled: false,
-        scriptCalled: false
-      }
-
-      page.on('request', async req => {
-        const url = await req.url()
-        switch (url) {
-          case 'http://localhost:3001/manifest.json': {
-            externalApi.manifestCalled = true
-            req.respond({
-              content: 'application/json',
-              headers: { 'Access-Control-Allow-Origin': '*' },
-              body: JSON.stringify({
-                name: 'test plugin',
-                templateURL: 'http://localhost:3001/template.html',
-                scriptURL: 'http://localhost:3001/script.js'
-              })
-            })
-            break;
-          }
-          case 'http://localhost:3001/template.html': {
-            externalApi.templateCalled = true
-            req.respond({
-              content: 'text/html; charset=UTF-8',
-              headers: { 'Access-Control-Allow-Origin': '*' },
-              body: ''
-            })
-            break;
-          }
-          case 'http://localhost:3001/script.js': {
-            externalApi.scriptCalled = true
-            req.respond({
-              content: 'application/javascript',
-              headers: { 'Access-Control-Allow-Origin': '*' },
-              body: ''
-            })
-            break;
-          }
-          default: req.continue()
-        }
-      })
-
-      await page.goto(`${ATLAS_URL}/?${searchParam.toString()}`, { waitUntil: 'networkidle2' })
-      // await awaitNehubaViewer(page)
-      await page.waitFor(500 * waitMultiple)
-
-      expect(externalApi.manifestCalled).toBe(true)
-      expect(externalApi.templateCalled).toBe(true)
-      expect(externalApi.scriptCalled).toBe(true)
-
-    })
-  })
-})
diff --git a/e2e/src/ivApi.js b/e2e/src/ivApi.js
deleted file mode 100644
index 83d5a48a81f9195f7c9d98c61f6be37bc487b694..0000000000000000000000000000000000000000
--- a/e2e/src/ivApi.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const { retry } = require('../../common/util')
-const { waitMultiple } = require('./util')
-
-exports.getSelectedTemplate = (browser) => new Promise((resolve, reject) => {
-  browser.executeAsyncScript('let sub = window.interactiveViewer.metadata.selectedTemplateBSubject.subscribe(obj => arguments[arguments.length - 1](obj));sub.unsubscribe()')
-    .then(resolve)
-    .catch(reject)
-})
-
-exports.getSelectedParcellation = (browser) => new Promise((resolve, reject) => {
-  browser.executeAsyncScript('let sub = window.interactiveViewer.metadata.selectedParcellationBSubject.subscribe(obj => arguments[arguments.length - 1](obj));sub.unsubscribe()')
-    .then(resolve)
-    .catch(reject)
-})
-
-exports.getSelectedRegions = async (page) => {
-  return await page.evaluate(async () => {
-    let region, sub
-    const getRegion = () => new Promise(rs => {
-      sub = interactiveViewer.metadata.selectedRegionsBSubject.subscribe(rs)
-    })
-
-    region = await getRegion()
-    sub.unsubscribe()
-    return region
-  })
-}
-
-exports.getCurrentNavigationState = page => new Promise(async rs => {
-  const rObj = await page.evaluate(async () => {
-
-    let returnObj, sub
-    const getPr = () =>  new Promise(rs => {
-
-      sub = nehubaViewer.navigationState.all
-        .subscribe(({ orientation, perspectiveOrientation, perspectiveZoom, position, zoom }) => {
-          returnObj = {
-            orientation: Array.from(orientation),
-            perspectiveOrientation: Array.from(perspectiveOrientation),
-            perspectiveZoom,
-            zoom,
-            position: Array.from(position)
-          }
-          rs()
-        })
-    })
-
-    await getPr()
-    sub.unsubscribe()
-
-    return returnObj
-  })
-  rs(rObj)
-})
-
-exports.awaitNehubaViewer = async (page) => {
-  const getNVAvailable = () => new Promise(async (rs, rj) => {
-    const result = await page.evaluate(() => {
-      return !!window.nehubaViewer
-    })
-    if (result) return rs()
-    else return rj()
-  })
-
-  await retry(getNVAvailable, { timeout: 2000 * waitMultiple, retries: 10 })
-}
diff --git a/e2e/src/navigating/mouseOverNehuba.e2e-spec.js b/e2e/src/navigating/mouseOverNehuba.e2e-spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..593246a03df98cbed08abb6a00d3a182115a26f2
--- /dev/null
+++ b/e2e/src/navigating/mouseOverNehuba.e2e-spec.js
@@ -0,0 +1,189 @@
+const { AtlasPage } = require('../util')
+
+const dictionary = {
+  "Allen Mouse Common Coordinate Framework v3": {
+    "Allen Mouse Common Coordinate Framework v3 2017": {
+      tests: [
+        {
+          position: [530, 530],
+          expectedLabelName: 'Primary somatosensory area, barrel field, layer 4',
+        },
+        {
+          position: [590, 120],
+          expectedLabelName: 'Retrosplenial area, ventral part, layer 2/3',
+        }
+      ]
+    },
+    "Allen Mouse Common Coordinate Framework v3 2015": {
+      tests: [
+        {
+          position: [520, 530],
+          expectedLabelName: 'Primary somatosensory area, barrel field',
+        },
+        {
+          position: [588, 115],
+          expectedLabelName: 'Retrosplenial area, ventral part',
+        }
+      ]
+    }
+  },
+  "Waxholm Space rat brain MRI/DTI": {
+    "Waxholm Space rat brain atlas v3": {
+      tests: [
+        {
+          position: [350, 170],
+          expectedLabelName: 'neocortex',
+        },
+        {
+          position: [320, 560],
+          expectedLabelName: 'corpus callosum and associated subcortical white matter',
+        }
+      ]
+    },
+    "Waxholm Space rat brain atlas v2": {
+      tests: [
+        {
+          position: [500, 630],
+          expectedLabelName: 'lateral entorhinal cortex',
+        },
+        {
+          position: [300, 200],
+          expectedLabelName: 'dentate gyrus',
+        }
+      ]
+    },
+    "Waxholm Space rat brain atlas v1": {
+      tests: [
+        {
+          position: [480, 680],
+          expectedLabelName: 'inner ear',
+        },
+        {
+          position: [550, 550],
+          expectedLabelName: 'corpus callosum and associated subcortical white matter',
+        }
+      ]
+    }
+  },
+  "ICBM 2009c Nonlinear Asymmetric": {
+    "JuBrain Cytoarchitectonic Atlas": {
+      tests:[
+        {
+          position: [550, 270],
+          expectedLabelName: 'Fastigial Nucleus (Cerebellum) - right hemisphere',
+        },
+        {
+          position: [600, 490],
+          expectedLabelName: 'Area 6ma (preSMA, mesial SFG) - left hemisphere',
+        }
+      ]
+    },
+    "Fibre Bundle Atlas - Long Bundle": {
+      tests: [
+        {
+          position: [300, 210],
+          expectedLabelName: 'InferiorFrontoOccipital - Right',
+        },
+        {
+          position: [680, 590],
+          expectedLabelName: 'InferiorLongitudinal - Left',
+        }
+      ]
+    },
+    "Fibre Bundle Atlas - Short Bundle": {
+      tests: [
+        {
+          position: [300, 100],
+          expectedLabelName: 'rh_SP-SM_0',
+        },
+        {
+          position: [642, 541],
+          expectedLabelName: 'lh_PoCi-PrCu_0',
+        }
+      ]
+    }
+  },
+  // TODO big brain cytomap occassionally resets center position to -20mm. investigate why
+  "Big Brain (Histology)": {
+    "Cytoarchitectonic Maps": {
+      url: "/?templateSelected=Big+Brain+%28Histology%29&parcellationSelected=Cytoarchitectonic+Maps&cNavigation=0.0.0.-W000.._eCwg.2-FUe3._-s_W.2_evlu..7LIx..1n5q~.1FYC.2Is-..1B9C",
+      tests: [
+        {
+          position: [686, 677],
+          expectedLabelName: 'Area STS1 (STS)'
+        },
+        {
+          position: [617,682],
+          expectedLabelName: 'Entorhinal Cortex'
+        }
+      ]
+    },
+    "BigBrain Cortical Layers Segmentation": {
+      url: "/?templateSelected=Big+Brain+%28Histology%29&parcellationSelected=BigBrain+Cortical+Layers+Segmentation&cNavigation=0.0.0.-W000.._eCwg.2-FUe3._-s_W.2_evlu..7LIx..2c8U8.1FYC.wfmi..91G",
+      tests: [
+        {
+          position: [330, 550],
+          expectedLabelName: 'cortical layer 6',
+        },
+        {
+          position: [475, 244],
+          expectedLabelName: 'cortical layer 1',
+        }
+      ]
+    },
+    "Grey/White matter": {
+      url: "/?templateSelected=Big+Brain+%28Histology%29&parcellationSelected=Grey%2FWhite+matter&cNavigation=0.0.0.-W000.._eCwg.2-FUe3._-s_W.2_evlu..7LIx..3cX1m.1FYC.Cr8t..5Jn",
+      tests: [
+        {
+          position: [210, 238],
+          expectedLabelName: 'White matter'
+        },
+        {
+          position: [293, 598],
+          expectedLabelName: 'Grey matter'
+        }
+      ]
+    }
+  }
+}
+
+describe('mouse over viewer show area name', () => {
+  let iavPage
+  beforeAll(async () => {
+    iavPage = new AtlasPage()
+    await iavPage.init()
+  })
+
+  for (const templateName in dictionary) {
+    for (const parcellationName in dictionary[templateName]) {
+      describe(`testing template: ${templateName} & parcellation: ${parcellationName}`, () => {
+
+        const {url, tests} = dictionary[templateName][parcellationName]
+        beforeAll(async () => {
+          if (url) {
+            await iavPage.goto(url)
+          } else {
+            await iavPage.goto()
+            await iavPage.selectTitleTemplateParcellation(templateName, parcellationName)
+          }
+          
+          const tag = await iavPage.getSideNavTag()
+          await tag.click()
+          await iavPage.wait(1000)
+          await iavPage.waitUntilAllChunksLoaded()
+        })
+        for (const { position, expectedLabelName } of tests ) {          
+          it(`at cursor position: ${JSON.stringify(position)}, expect label name: ${expectedLabelName}`, async () => {
+
+            await iavPage.cursorMoveTo({ position })
+            await iavPage.wait(2000)
+            const text = await iavPage.getFloatingCtxInfoAsText()
+            expect(
+              text.indexOf(expectedLabelName)
+            ).toBeGreaterThanOrEqual(0)
+          })
+        }
+      })
+    }
+  }
+})
diff --git a/e2e/src/noErrorLog.js b/e2e/src/noErrorLog.js
deleted file mode 100644
index d7bc1ef7dc223d3f66aece5994623fbaea239823..0000000000000000000000000000000000000000
--- a/e2e/src/noErrorLog.js
+++ /dev/null
@@ -1,14 +0,0 @@
-module.exports = (browser) => {
-  if (!browser) {
-    fail('browser not defined')
-    throw new Error('browser not defined')
-  }
-  browser.manage().logs().get('browser')
-    .then(browserLogs => {
-      const errorLogs = browserLogs
-        .filter(log => !(/favicon/.test(log.message)))
-        .filter(log => log.level.value > 900)
-      expect(errorLogs.length).toEqual(0)
-    })
-    .catch(fail)
-}
\ No newline at end of file
diff --git a/e2e/src/selecting/template.e2e-spec.js b/e2e/src/selecting/template.e2e-spec.js
index 31241bead68deb923332df633389d214e1c4df82..433571e3f2b1417f260ba25af65616c1d44ebd1f 100644
--- a/e2e/src/selecting/template.e2e-spec.js
+++ b/e2e/src/selecting/template.e2e-spec.js
@@ -10,10 +10,6 @@ describe('selecting template', () => {
 
   it('can select template by clicking main card', async () => {
     await iavPage.goto()
-    await iavPage.wait(200)
-    await iavPage.dismissModal()
-    await iavPage.wait(200)
-
     await iavPage.selectTitleCard('ICBM 2009c Nonlinear Asymmetric')
     await iavPage.wait(1000)
 
@@ -25,9 +21,6 @@ describe('selecting template', () => {
   it('switching template after template init by clicking select should work', async () => {
 
     await iavPage.goto()
-    await iavPage.wait(200)
-    await iavPage.dismissModal()
-    await iavPage.wait(200)
 
     await iavPage.selectTitleCard('ICBM 2009c Nonlinear Asymmetric')
     await iavPage.wait(1000)
diff --git a/e2e/src/util.js b/e2e/src/util.js
index d7a147e765a9b9dab7ef3529b81b1ed606708e08..b43524d943ba41018329e023a37d55450f0d7f5a 100644
--- a/e2e/src/util.js
+++ b/e2e/src/util.js
@@ -4,7 +4,7 @@ const ATLAS_URL = (process.env.ATLAS_URL || 'http://localhost:3000').replace(/\/
 const USE_SELENIUM = !!process.env.SELENIUM_ADDRESS
 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 { By, WebDriver } = require('selenium-webdriver')
+const { By, WebDriver, Key } = require('selenium-webdriver')
 
 function getActualUrl(url) {
   return /^http\:\/\//.test(url) ? url : `${ATLAS_URL}/${url.replace(/^\//, '')}`
@@ -17,15 +17,52 @@ async function getIndexFromArrayOfWebElements(search, webElements) {
   return texts.findIndex(text => text.indexOf(search) >= 0)
 }
 
+const regionSearchAriaLabelText = 'Search for any region of interest in the atlas selected'
+
 class WdBase{
   constructor() {
     browser.waitForAngularEnabled(false)
   }
   get browser(){
-    return this.driver || browser
+    return browser
+  }
+  get driver(){
+    return this.browser.driver
   }
   async init() {
+    const wSizeArg = chromeOpts.find(arg => arg.indexOf('--window-size') >= 0)
+    const [ _, width, height ] = /\=([0-9]{1,})\,([0-9]{1,})$/.exec(wSizeArg)
+
+    const newDim = await this.browser.executeScript(async () => {
+      return [
+        window.outerWidth - window.innerWidth + (+ arguments[0]),
+        window.outerHeight - window.innerHeight + (+ arguments[1]),
+      ]
+    }, width, height)
+
+    await this.browser.manage()
+      .window()
+      .setRect({
+        width: newDim[0],
+        height: newDim[1]
+      })
+  }
 
+  async cursorMoveTo({ position }) {
+    if (!position) throw new Error(`cursorGoto: position must be defined!`)
+    const x = Array.isArray(position) ? position[0] : position.x
+    const y = Array.isArray(position)? position[1] : position.y
+    if (!x) throw new Error(`cursorGoto: position.x or position[0] must be defined`)
+    if (!y) throw new Error(`cursorGoto: position.y or position[1] must be defined`)
+
+    return this.driver.actions()
+      .move()
+      .move({
+        x,
+        y,
+        duration: 1000
+      })
+      .perform()
   }
 
   async initHttpInterceptor(){
@@ -55,7 +92,7 @@ class WdBase{
       return window['__interceptedXhr__']
     })
   }
-  async goto(url = '/', { interceptHttp } = {}){
+  async goto(url = '/', { interceptHttp, doNotAutomate } = {}){
     const actualUrl = getActualUrl(url)
     if (interceptHttp) {
       this.browser.get(actualUrl)
@@ -63,7 +100,14 @@ class WdBase{
     } else {
       await this.browser.get(actualUrl)
     }
+
+    if (!doNotAutomate) {
+      await this.wait(200)
+      await this.dismissModal()
+      await this.wait(200)
+    }
   }
+
   async wait(ms) {
     if (!ms) throw new Error(`wait duration must be specified!`)
     await this.browser.sleep(ms)
@@ -102,13 +146,28 @@ class WdLayoutPage extends WdBase{
       .findElements( By.tagName('mat-card') )
   }
 
-  async selectTitleCard( title ) {
+  async findTitleCard(title) {
     const titleCards = await this.findTitleCards()
     const idx = await getIndexFromArrayOfWebElements(title, titleCards)
-    if (idx >= 0) await titleCards[idx].click()
+    if (idx >= 0) return titleCards[idx]
     else throw new Error(`${title} does not fit any titleCards`)
   }
 
+  async selectTitleCard( title ) {
+    const titleCard = await this.findTitleCard(title)
+    await titleCard.click()
+  }
+
+  async selectTitleTemplateParcellation(templateName, parcellationName){
+    const titleCard = await this.findTitleCard(templateName)
+    const parcellations = await titleCard
+      .findElement( By.css('mat-card-content.available-parcellations-container') )
+      .findElements( By.tagName('button') )
+    const idx = await getIndexFromArrayOfWebElements( parcellationName, parcellations )
+    if (idx >= 0) await parcellations[idx].click()
+    else throw new Error(`parcellationName ${parcellationName} does not exist`)
+  }
+
   async getSideNav() {
     return await this.browser.findElement( By.tagName('search-side-nav') )
   }
@@ -129,6 +188,39 @@ class WdIavPage extends WdLayoutPage{
     super()
   }
 
+  async clearAllSelectedRegions() {
+    const clearAllRegionBtn = await this.browser.findElement(
+      By.css('[aria-label="Clear all regions"]')
+    )
+    await clearAllRegionBtn.click()
+    await this.wait(500)
+  }
+
+  async waitUntilAllChunksLoaded(){
+    const checkReady = async () => {
+      const el = await this.browser.findElements(
+        By.css('div.loadingIndicator')
+      )
+      return !el.length
+    }
+
+    do {
+      // Do nothing, until ready
+    } while (
+      await this.wait(1000),
+      !(await checkReady())
+    )
+  }
+
+  async getFloatingCtxInfoAsText(){
+    const floatingContainer = await this.browser.findElement(
+      By.css('div[floatingMouseContextualContainerDirective]')
+    )
+
+    const text = await floatingContainer.getText()
+    return text
+  }
+
   async selectDropdownTemplate(title) {
     const templateBtn = await (await this.getSideNav())
       .findElement( By.tagName('viewer-state-controller') )
@@ -143,14 +235,66 @@ class WdIavPage extends WdLayoutPage{
     else throw new Error(`${title} is not found as one of the dropdown templates`)
   }
 
-  async getViewerContainer() {
-    return await this.browser.findElement(
-      By.id('neuroglancer-container')
-    )
+  async getSearchRegionInput(){
+    return await (await this.getSideNav())
+      .findElement( By.css(`[aria-label="${regionSearchAriaLabelText}"]`) )
+  }
+
+  async searchRegionWithText(text=''){
+    const searchRegionInput = await this.getSearchRegionInput()
+    await searchRegionInput
+      .sendKeys(
+        Key.chord(Key.CONTROL, 'a'),
+        text
+      )
+  }
+
+  async clearSearchRegionWithText() {
+    const searchRegionInput = await this.getSearchRegionInput()
+    await searchRegionInput
+      .sendKeys(
+        Key.chord(Key.CONTROL, 'a'),
+        Key.BACK_SPACE,
+        Key.ESCAPE
+      )
+  }
+
+  async getSearchRegionInputAutoCompleteOptions(){
+  }
+
+  async selectSearchRegionAutocompleteWithText(text = ''){
+
+    const input = await this.getSearchRegionInput()
+    const autocompleteId = await input.getAttribute('aria-owns')
+    const options = await this.browser
+      .findElement( By.id( autocompleteId ) )
+      .findElements( By.tagName('mat-option') )
+
+    const idx = await getIndexFromArrayOfWebElements(text, options)
+    if (idx >= 0) {
+      await options[idx].click()
+    } else {
+      throw new Error(`getIndexFromArrayOfWebElements ${text} option not founds`)
+    }
+  }
+
+  async getVisibleDatasets() {
+    const singleDatasetListView = await this.browser
+      .findElement( By.tagName('data-browser') )
+      .findElement( By.css('div.cdk-virtual-scroll-content-wrapper') )
+      .findElements( By.tagName('single-dataset-list-view') )
+
+    const returnArr = []
+    for (const item of singleDatasetListView) {
+      returnArr.push( await item.getText() )
+    }
+    return returnArr
   }
 
   async viewerIsPopulated() {
-    const ngContainer = await this.getViewerContainer()
+    const ngContainer = await this.browser.findElement(
+      By.id('neuroglancer-container')
+    )
     const canvas = await ngContainer.findElement(
       By.tagName('canvas')
     )
diff --git a/package.json b/package.json
index a2b59d27eb77ed6feeab5616f03f8127b38e1043..69cd4628c3087ae7e0a45c66171ff9fa6f8f43f5 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
     "lodash.merge": "^4.6.2",
     "mini-css-extract-plugin": "^0.8.0",
     "node-sass": "^4.12.0",
-    "protractor": "^5.4.2",
+    "protractor": "^6.0.0",
     "raw-loader": "^0.5.1",
     "reflect-metadata": "^0.1.12",
     "rxjs": "6.5.4",
diff --git a/src/ui/nehubaContainer/splashScreen/splashScreen.template.html b/src/ui/nehubaContainer/splashScreen/splashScreen.template.html
index 90dfb6b6cba80c3c4979146bd7cef5826d7af42d..9d4a9b4ce15e5d02305353964bb1595d1fc598d1 100644
--- a/src/ui/nehubaContainer/splashScreen/splashScreen.template.html
+++ b/src/ui/nehubaContainer/splashScreen/splashScreen.template.html
@@ -24,7 +24,7 @@
         {{ template.properties.description }}
       </mat-card-content>
 
-      <mat-card-content>
+      <mat-card-content class="available-parcellations-container">
         <mat-card-subtitle class="text-nowrap">
           Parcellations available
         </mat-card-subtitle>
diff --git a/src/ui/searchSideNav/searchSideNav.template.html b/src/ui/searchSideNav/searchSideNav.template.html
index d504105a6a72b6ff19ec6dcb48fff8d778529fde..195f2e5d5c3bb4036f3e9eef72cd624e62d97270 100644
--- a/src/ui/searchSideNav/searchSideNav.template.html
+++ b/src/ui/searchSideNav/searchSideNav.template.html
@@ -117,6 +117,7 @@
             class="position-absolute"
             (click)="deselectAllRegions()"
             matTooltip="Clear all regions"
+            aria-label="Clear all regions"
             color="primary">
             <i class="fas fa-times-circle"></i>
           </button>
diff --git a/src/ui/viewerStateController/regionSearch/regionSearch.component.ts b/src/ui/viewerStateController/regionSearch/regionSearch.component.ts
index 0b013fd3c6a2f82a9c1fb6f913c0a45a002e62fe..01cdf6d3745179591209349a536e84073d79944c 100644
--- a/src/ui/viewerStateController/regionSearch/regionSearch.component.ts
+++ b/src/ui/viewerStateController/regionSearch/regionSearch.component.ts
@@ -30,6 +30,7 @@ export class RegionTextSearchAutocomplete {
 
   public compareFn = compareFn
 
+  @Input() public ariaLabel: string = `Search for any region of interest in the atlas selected`
   @Input() public showBadge: boolean = false
   @Input() public showAutoComplete: boolean = true
 
diff --git a/src/ui/viewerStateController/regionSearch/regionSearch.template.html b/src/ui/viewerStateController/regionSearch/regionSearch.template.html
index db6ec9747c3573769c1a3dfbaf36869a3694cc7e..25c2cf5fec6f1bf275c251344d6d6fccfa9ef089 100644
--- a/src/ui/viewerStateController/regionSearch/regionSearch.template.html
+++ b/src/ui/viewerStateController/regionSearch/regionSearch.template.html
@@ -8,6 +8,7 @@
         #trigger="matAutocompleteTrigger"
         type="text"
         matInput
+        [attr.aria-label]="ariaLabel"
         [formControl]="formControl"
         [matAutocomplete]="auto">
     </mat-form-field>
diff --git a/src/ui/viewerStateController/viewerStateCFull/viewerState.template.html b/src/ui/viewerStateController/viewerStateCFull/viewerState.template.html
index 3da00c0c9a7475f7107fc717feb2ab5f35d6cf2f..2e11b8d7db09d47acfcf857f90fd244e44e59483 100644
--- a/src/ui/viewerStateController/viewerStateCFull/viewerState.template.html
+++ b/src/ui/viewerStateController/viewerStateCFull/viewerState.template.html
@@ -31,6 +31,7 @@
           <!-- shown when off -->
           <div sleight-of-hand-front>
             <button
+              aria-label="Hover to find out more info on the selected template"
               mat-icon-button>
               <i class="fas fa-info"></i>
             </button>
@@ -38,7 +39,10 @@
     
           <!-- shown on hover -->
           <div class="d-flex flex-row align-items-start" sleight-of-hand-back>
-            <button class="flex-grow-0 flex-shrink-0" mat-icon-button>
+            <button
+              aria-label="Hover to find out more info on the selected template"
+              class="flex-grow-0 flex-shrink-0"
+              mat-icon-button>
               <i class="fas fa-info"></i>
             </button>