Repository: manusa/electronim
Pull request #414 (2024-05-19 15:39:45)

⬆ Bump electron to 30.0.6

sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=manusa_electronim&pullRequest=414) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [4 New issues](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=414&resolved=false&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=414&resolutions=WONTFIX)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=manusa_electronim&pullRequest=414&resolved=false&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [96.3% Coverage on New Code](https://sonarcloud.io/component_measures?id=manusa_electronim&pullRequest=414&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=manusa_electronim&pullRequest=414&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=manusa_electronim&pullRequest=414)



Patch:
diff --git a/README.md b/README.md
index b6eadb1..ec21de9 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ electronim
 ## Features
 
 - ⚛ Multi-platform: ElectronIM is available for Linux 🐧, Mac 🍏 and Windows.
-- 🌍 Based on Chromium 122
+- 🌍 Based on Chromium 124
 - 🔔 Desktop notifications: ElectronIM will notify you using your native system notifications.
 - 🧐 Spellchecker: ElectronIM contains spellchecker dictionaries for many languages,
   if your language is not supported, just [file an issue](https://github.com/manusa/electronim/issues/new).
diff --git a/build-config/electronim.nuspec b/build-config/electronim.nuspec
index ed90525..27fe942 100644
--- a/build-config/electronim.nuspec
+++ b/build-config/electronim.nuspec
@@ -24,7 +24,7 @@ Improve your productivity by combining all your instant messaging applications (
 ### Features
 
 - ⚛ Multi-platform: ElectronIM is available for Linux 🐧, Mac 🍏 and Windows.
-- 🌍 Based on Chromium 122
+- 🌍 Based on Chromium 124
 - 🔔 Desktop notifications: ElectronIM will notify you using your native system notifications.
 - 🧐 Spellchecker: ElectronIM contains spellchecker dictionaries for many languages,
   if your language is not supported, just [file an issue](https://github.com/manusa/electronim/issues/new).
diff --git a/package-lock.json b/package-lock.json
index ffdbea2..cce926e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,7 +29,7 @@
         "dictionary-sv": "^3.0.1",
         "dictionary-tr": "^1.3.3",
         "dictionary-uk": "^2.1.1",
-        "electron": "29.3.3",
+        "electron": "30.0.6",
         "htm": "3.1.1",
         "markdown-it": "14.1.0",
         "nodehun": "3.0.2",
@@ -4162,9 +4162,9 @@
       }
     },
     "node_modules/electron": {
-      "version": "29.3.3",
-      "resolved": "https://registry.npmjs.org/electron/-/electron-29.3.3.tgz",
-      "integrity": "sha512-I/USTe9UsQUKb/iuiYnmt074vHxNHCJZWYiU4Xg6lNPKVBsPadAhZcc+g2gYLqC1rA7KT4AvKTmNsY8n7oEUCw==",
+      "version": "30.0.6",
+      "resolved": "https://registry.npmjs.org/electron/-/electron-30.0.6.tgz",
+      "integrity": "sha512-PkhEPFdpYcTzjAO3gMHZ+map7g2+xCrMDedo/L1i0ir2BRXvAB93IkTJX497U6Srb/09r2cFt+k20VPNVCdw3Q==",
       "hasInstallScript": true,
       "dependencies": {
         "@electron/get": "^2.0.0",
@@ -12737,9 +12737,9 @@
       }
     },
     "electron": {
-      "version": "29.3.3",
-      "resolved": "https://registry.npmjs.org/electron/-/electron-29.3.3.tgz",
-      "integrity": "sha512-I/USTe9UsQUKb/iuiYnmt074vHxNHCJZWYiU4Xg6lNPKVBsPadAhZcc+g2gYLqC1rA7KT4AvKTmNsY8n7oEUCw==",
+      "version": "30.0.6",
+      "resolved": "https://registry.npmjs.org/electron/-/electron-30.0.6.tgz",
+      "integrity": "sha512-PkhEPFdpYcTzjAO3gMHZ+map7g2+xCrMDedo/L1i0ir2BRXvAB93IkTJX497U6Srb/09r2cFt+k20VPNVCdw3Q==",
       "requires": {
         "@electron/get": "^2.0.0",
         "@types/node": "^20.9.0",
diff --git a/package.json b/package.json
index 2e6f8e7..95e0db2 100644
--- a/package.json
+++ b/package.json
@@ -222,7 +222,7 @@
     "dictionary-sv": "^3.0.1",
     "dictionary-tr": "^1.3.3",
     "dictionary-uk": "^2.1.1",
-    "electron": "29.3.3",
+    "electron": "30.0.6",
     "htm": "3.1.1",
     "markdown-it": "14.1.0",
     "nodehun": "3.0.2",
diff --git a/src/about/index.js b/src/about/index.js
index be2301c..57059dd 100644
--- a/src/about/index.js
+++ b/src/about/index.js
@@ -13,9 +13,9 @@
    See the License for the specific language governing permissions and
    limitations under the License.
  */
-const {BrowserView, BrowserWindow} = require('electron');
+const {WebContentsView} = require('electron');
 const path = require('path');
-const {showDialog} = require('../browser-window');
+const {showDialog} = require('../base-window');
 const {handleRedirect, windowOpenHandler} = require('../tab-manager/redirect');
 
 const webPreferences = {
@@ -25,12 +25,12 @@ const webPreferences = {
   preload: path.resolve(__dirname, '..', '..', 'bundles', 'about.preload.js')
 };
 
-const openAboutDialog = event => {
-  const aboutView = new BrowserView({webPreferences});
+const openAboutDialog = baseWindow => () => {
+  const aboutView = new WebContentsView({webPreferences});
   aboutView.webContents.loadURL(`file://${__dirname}/index.html`);
   aboutView.webContents.on('will-navigate', handleRedirect(aboutView));
   aboutView.webContents.setWindowOpenHandler(windowOpenHandler(aboutView));
-  showDialog(BrowserWindow.fromWebContents(event.sender), aboutView);
+  showDialog(baseWindow, aboutView);
 };
 
 module.exports = {openAboutDialog};
diff --git a/src/app-menu/index.js b/src/app-menu/index.js
index be8e4dd..d5e3afd 100644
--- a/src/app-menu/index.js
+++ b/src/app-menu/index.js
@@ -14,7 +14,7 @@
    limitations under the License.
  */
 const path = require('path');
-const {BrowserView} = require('electron');
+const {WebContentsView} = require('electron');
 
 const webPreferences = {
   transparent: true,
@@ -25,13 +25,12 @@ const webPreferences = {
 };
 
 /**
- * Creates a new BrowserView instance with the App Menu
- * @returns {Electron.CrossProcessExports.BrowserView}
+ * Creates a new WebContentsView instance with the App Menu
+ * @returns {Electron.CrossProcessExports.WebContentsView}
  */
 const newAppMenu = () => {
-  const appMenu = new BrowserView({webPreferences});
+  const appMenu = new WebContentsView({webPreferences});
   appMenu.isAppMenu = true;
-  appMenu.setAutoResize({width: false, horizontal: false, height: false, vertical: false});
   appMenu.webContents.loadURL(`file://${__dirname}/index.html`);
   return appMenu;
 };
diff --git a/src/browser-window/index.js b/src/base-window/index.js
similarity index 60%
rename from src/browser-window/index.js
rename to src/base-window/index.js
index d0c5e28..1d17c3f 100644
--- a/src/browser-window/index.js
+++ b/src/base-window/index.js
@@ -15,12 +15,14 @@
  */
 const {registerAppShortcuts} = require('./keyboard-shortcuts');
 
-const showDialog = (browserWindow, browserView) => {
-  browserWindow.setBrowserView(browserView);
-  const {width, height} = browserWindow.getContentBounds();
-  browserView.setBounds({x: 0, y: 0, width, height});
-  browserView.setAutoResize({width: false, horizontal: false, height: false, vertical: false});
-  browserView.webContents.focus();
+const findDialog = baseWindow => baseWindow.contentView.children.find(v => v.isDialog);
+
+const showDialog = (baseWindow, dialogView) => {
+  dialogView.isDialog = true;
+  baseWindow.contentView.addChildView(dialogView);
+  const {width, height} = baseWindow.getContentBounds();
+  dialogView.setBounds({x: 0, y: 0, width, height});
+  dialogView.webContents.focus();
 };
 
-module.exports = {registerAppShortcuts, showDialog};
+module.exports = {registerAppShortcuts, findDialog, showDialog};
diff --git a/src/chrome-tabs/index.js b/src/chrome-tabs/index.js
index fbe0d64..0e8c49c 100644
--- a/src/chrome-tabs/index.js
+++ b/src/chrome-tabs/index.js
@@ -13,7 +13,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
  */
-const {BrowserView, Menu, MenuItem, ipcMain: eventBus} = require('electron');
+const {WebContentsView, Menu, MenuItem, ipcMain: eventBus} = require('electron');
 const path = require('path');
 const {APP_EVENTS} = require('../constants');
 const {getLatestRelease} = require('./check-for-updates');
@@ -56,13 +56,12 @@ const handleContextMenu = viewOrWindow => (event, params) => {
 };
 
 /**
- * Creates a new BrowserView instance with the Chrome Tabs
- * @returns {Electron.CrossProcessExports.BrowserView}
+ * Creates a new WebContentsView instance with the Chrome Tabs
+ * @returns {Electron.CrossProcessExports.WebContentsView}
  */
 const newTabContainer = () => {
-  const tabContainer = new BrowserView({webPreferences});
+  const tabContainer = new WebContentsView({webPreferences});
   tabContainer.isTabContainer = true;
-  tabContainer.setAutoResize({width: false, horizontal: false, height: false, vertical: false});
   tabContainer.webContents.loadURL(`file://${__dirname}/index.html`,
     {extraHeaders: 'pragma: no-cache\nCache-control: no-cache'});
   tabContainer.webContents.on('context-menu', handleContextMenu(tabContainer));
diff --git a/src/help/index.js b/src/help/index.js
index c2a50ed..cbe4c47 100644
--- a/src/help/index.js
+++ b/src/help/index.js
@@ -13,9 +13,9 @@
    See the License for the specific language governing permissions and
    limitations under the License.
  */
-const {BrowserView} = require('electron');
+const {WebContentsView} = require('electron');
 const path = require('path');
-const {showDialog} = require('../browser-window');
+const {showDialog} = require('../base-window');
 const {handleRedirect, windowOpenHandler} = require('../tab-manager/redirect');
 
 const webPreferences = {
@@ -25,12 +25,12 @@ const webPreferences = {
   preload: path.resolve(__dirname, '..', '..', 'bundles', 'help.preload.js')
 };
 
-const openHelpDialog = browserWindow => () => {
-  const helpView = new BrowserView({webPreferences});
+const openHelpDialog = baseWindow => () => {
+  const helpView = new WebContentsView({webPreferences});
   helpView.webContents.loadURL(`file://${__dirname}/index.html`);
   helpView.webContents.on('will-navigate', handleRedirect(helpView));
   helpView.webContents.setWindowOpenHandler(windowOpenHandler(helpView));
-  showDialog(browserWindow, helpView);
+  showDialog(baseWindow, helpView);
 };
 
 module.exports = {openHelpDialog};
diff --git a/src/index.js b/src/index.js
index 1e412ae..d4038fb 100644
--- a/src/index.js
+++ b/src/index.js
@@ -14,7 +14,7 @@
    limitations under the License.
  */
 const {app} = require('electron');
-const {registerAppShortcuts} = require('./browser-window');
+const {registerAppShortcuts} = require('./base-window');
 const {init, quit} = require('./main');
 
 app.name = 'ElectronIM';
diff --git a/src/main/index.js b/src/main/index.js
index b843670..bd8ac5d 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -15,11 +15,12 @@
  */
 const path = require('path');
 const {
-  BrowserWindow, Notification, app, desktopCapturer, ipcMain: eventBus, nativeTheme
+  BaseWindow, Notification, app, desktopCapturer, ipcMain: eventBus, nativeTheme
 } = require('electron');
 const {APP_EVENTS, CLOSE_BUTTON_BEHAVIORS} = require('../constants');
 const {openAboutDialog} = require('../about');
 const {newAppMenu, isNotAppMenu} = require('../app-menu');
+const {findDialog} = require('../base-window');
 const {TABS_CONTAINER_HEIGHT, newTabContainer, isNotTabContainer} = require('../chrome-tabs');
 const {openHelpDialog} = require('../help');
 const {getPlatform, loadSettings, updateSettings, openSettingsDialog} = require('../settings');
@@ -48,10 +49,10 @@ const fixUserDataLocation = () => {
 };
 
 const resetMainWindow = () => {
-  const currentViews = mainWindow.getBrowserViews();
-  currentViews.filter(isNotTabContainer).forEach(bv => mainWindow.removeBrowserView(bv));
-  if (mainWindow.getBrowserViews().length === 0) {
-    mainWindow.setBrowserView(tabContainer);
+  const currentViews = mainWindow.contentView.children;
+  currentViews.filter(isNotTabContainer).forEach(view => mainWindow.contentView.removeChildView(view));
+  if (mainWindow.contentView.children.length === 0) {
+    mainWindow.contentView.addChildView(tabContainer);
   }
 };
 
@@ -60,7 +61,7 @@ const activateTab = ({tabId, restoreWindow = true}) => {
   if (activeTab) {
     const {width, height} = mainWindow.getContentBounds();
     resetMainWindow();
-    mainWindow.addBrowserView(activeTab);
+    mainWindow.contentView.addChildView(activeTab);
     tabContainer.setBounds({x: 0, y: 0, width, height: TABS_CONTAINER_HEIGHT});
     activeTab.setBounds({x: 0, y: TABS_CONTAINER_HEIGHT, width, height: height - TABS_CONTAINER_HEIGHT});
     tabManager.setActiveTab(tabId);
@@ -76,12 +77,12 @@ const handleMainWindowResize = () => {
 
   setTimeout(() => {
     const {width: contentWidth, height: contentHeight} = mainWindow.getContentBounds();
-    if (appMenu && appMenu.setBounds) {
+    if (appMenu?.setBounds ?? false) {
       appMenu.setBounds({x: 0, y: 0, width: contentWidth, height: contentHeight});
     }
     let totalHeight = 0;
     const isLast = (idx, array) => idx === array.length - 1;
-    mainWindow.getBrowserViews().filter(isNotAppMenu).forEach((bv, idx, array) => {
+    mainWindow.contentView.children.filter(isNotAppMenu).forEach((bv, idx, array) => {
       const {x: currentX, y: currentY, height: currentHeight} = bv.getBounds();
       let newHeight = currentHeight;
       if (isLast(idx, array)) {
@@ -90,13 +91,17 @@ const handleMainWindowResize = () => {
       bv.setBounds({x: currentX, y: currentY, width: contentWidth, height: newHeight});
       totalHeight += currentHeight;
     });
+    const dialogView = findDialog(mainWindow);
+    if (dialogView) {
+      dialogView.setBounds({x: 0, y: 0, width: contentWidth, height: contentHeight});
+    }
   });
 };
 
 const handleTabReload = event => event.sender.reloadIgnoringCache();
 
 const handleTabTraverse = getTabIdFunction => () => {
-  if (mainWindow.getBrowserViews().length === 1) {
+  if (mainWindow.contentView.children.length === 1) {
     return;
   }
   const tabId = getTabIdFunction();
@@ -171,15 +176,15 @@ const initDesktopCapturerHandler = () => {
 
 const appMenuOpen = () => {
   const {width, height} = mainWindow.getContentBounds();
-  mainWindow.addBrowserView(appMenu);
+  mainWindow.contentView.addChildView(appMenu);
   appMenu.setBounds({x: 0, y: 0, width, height});
 };
 
 const appMenuClose = () => {
-  if (!mainWindow.getBrowserViews().find(bv => bv.isAppMenu)) {
+  if (!mainWindow.contentView.children.find(view => view.isAppMenu)) {
     return;
   }
-  mainWindow.removeBrowserView(appMenu);
+  mainWindow.contentView.removeChildView(appMenu);
   activateTab({tabId: tabManager.getActiveTab()});
 };
 
@@ -188,10 +193,11 @@ const fullscreenToggle = () => {
 };
 
 const closeDialog = () => {
-  if (mainWindow.getBrowserViews().length > 1) {
+  const dialogView = findDialog(mainWindow);
+  if (!dialogView) {
     return;
   }
-  const dialogView = mainWindow.getBrowserView();
+  mainWindow.contentView.removeChildView(dialogView);
   activateTab({tabId: tabManager.getActiveTab()});
   dialogView.webContents.destroy();
 };
@@ -214,17 +220,19 @@ const saveSettings = (_event, settings) => {
   updateSettings(settings);
   loadDictionaries();
   nativeTheme.themeSource = settings.theme;
-  const currentBrowserView = mainWindow.getBrowserView();
-  mainWindow.removeBrowserView(currentBrowserView);
+  closeDialog();
+  appMenuClose();
+  mainWindow.contentView.children.forEach(view => {
+    mainWindow.contentView.removeChildView(view);
+    view.webContents.destroy();
+  });
   tabManager.removeAll();
-  const viewsToDestroy = [currentBrowserView, tabContainer];
-  viewsToDestroy.forEach(view => view.webContents.destroy());
   tabContainer = newTabContainer();
   eventBus.emit(APP_EVENTS.trayInit);
 };
 
 const initGlobalListeners = () => {
-  eventBus.on(APP_EVENTS.aboutOpenDialog, openAboutDialog);
+  eventBus.on(APP_EVENTS.aboutOpenDialog, openAboutDialog(mainWindow));
   eventBus.on(APP_EVENTS.appMenuOpen, appMenuOpen);
   eventBus.on(APP_EVENTS.appMenuClose, appMenuClose);
   eventBus.on(APP_EVENTS.closeDialog, closeDialog);
@@ -248,9 +256,9 @@ const initGlobalListeners = () => {
 };
 
 const browserVersionsReady = () => {
-  app.userAgentFallback = userAgentForWebContents(mainWindow.webContents);
   tabContainer = newTabContainer();
   appMenu = newAppMenu();
+  app.userAgentFallback = userAgentForWebContents(appMenu.webContents);
   eventBus.emit(APP_EVENTS.trayInit);
 };
 
@@ -259,7 +267,7 @@ const init = () => {
   loadDictionaries();
   const {width = 800, height = 600, startMinimized, theme} = loadSettings();
   nativeTheme.themeSource = theme;
-  mainWindow = new BrowserWindow({
+  mainWindow = new BaseWindow({
     width, height, resizable: true, maximizable: true,
     icon: path.resolve(__dirname, '..', 'assets', getPlatform() === 'linux' ? 'icon.png' : 'icon.ico'),
     show: false, paintWhenInitiallyHidden: false,
diff --git a/src/settings/index.js b/src/settings/index.js
index f8706c2..727d8bf 100644
--- a/src/settings/index.js
+++ b/src/settings/index.js
@@ -13,12 +13,12 @@
    See the License for the specific language governing permissions and
    limitations under the License.
  */
-const {BrowserView} = require('electron');
+const {WebContentsView} = require('electron');
 const fs = require('fs');
 const path = require('path');
 const HOME_DIR = require('os').homedir();
 const {CLOSE_BUTTON_BEHAVIORS} = require('../constants');
-const {showDialog} = require('../browser-window');
+const {showDialog} = require('../base-window');
 
 const APP_DIR = '.electronim';
 const SETTINGS_FILE = 'settings.json';
@@ -94,7 +94,7 @@ const updateSettings = settings =>
   writeSettings(ensureDefaultValues({...loadSettings(), ...settings}));
 
 const openSettingsDialog = mainWindow => () => {
-  const settingsView = new BrowserView({webPreferences});
+  const settingsView = new WebContentsView({webPreferences});
   settingsView.webContents.loadURL(`file://${__dirname}/index.html`);
   showDialog(mainWindow, settingsView);
 };
diff --git a/src/spell-check/dictionary.renderer/README.md b/src/spell-check/dictionary.renderer/README.md
index 2cfd253..a1f958f 100644
--- a/src/spell-check/dictionary.renderer/README.md
+++ b/src/spell-check/dictionary.renderer/README.md
@@ -1,4 +1,4 @@
-Fake BrowserWindow that runs long processes (such as loading dictionaries)
+Fake BaseWindow that runs long processes (such as loading dictionaries)
 in an Electron renderer thread.
 
 Communication with the thread happens via events and remote JavaScript execution.
diff --git a/src/spell-check/index.js b/src/spell-check/index.js
index ea65c15..40eab1d 100644
--- a/src/spell-check/index.js
+++ b/src/spell-check/index.js
@@ -13,7 +13,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
  */
-const {BrowserWindow, MenuItem, ipcMain} = require('electron');
+const {WebContentsView, MenuItem, ipcMain} = require('electron');
 const {APP_EVENTS} = require('../constants');
 const {loadSettings} = require('../settings');
 
@@ -93,17 +93,16 @@ const getEnabledDictionaries = () => loadSettings().enabledDictionaries;
 
 const loadDictionaries = () => {
   if (fakeRendererWorker) {
-    fakeRendererWorker.destroy();
+    fakeRendererWorker.webContents.destroy();
   }
-  fakeRendererWorker = new BrowserWindow({
-    show: false,
+  fakeRendererWorker = new WebContentsView({
     webPreferences: {
       contextIsolation: false,
       nativeWindowOpen: true,
       nodeIntegration: true
     }
   });
-  fakeRendererWorker.loadURL(`file://${__dirname}/dictionary.renderer/index.html`);
+  fakeRendererWorker.webContents.loadURL(`file://${__dirname}/dictionary.renderer/index.html`);
   ipcMain.removeHandler(APP_EVENTS.dictionaryGetMisspelled);
   ipcMain.handle(APP_EVENTS.dictionaryGetMisspelled, handleGetMisspelled);
   // Uncomment to debug problems with dictionaries
diff --git a/src/tab-manager/context-menu.js b/src/tab-manager/context-menu.js
index d04284b..49c389c 100644
--- a/src/tab-manager/context-menu.js
+++ b/src/tab-manager/context-menu.js
@@ -77,7 +77,7 @@ const regularContextMenu = ({webContents, params}) => {
 };
 
 /**
- * @param {BrowserView|BrowserWindow} viewOrWindow
+ * @param {WebContentsView|BaseWindow} viewOrWindow
  * @returns {(function(*, *): Promise<void>)|*}
  */
 const handleContextMenu = viewOrWindow => async (_event, params) => {
diff --git a/src/tab-manager/index.js b/src/tab-manager/index.js
index 4a62a0c..d249d15 100644
--- a/src/tab-manager/index.js
+++ b/src/tab-manager/index.js
@@ -13,7 +13,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
  */
-const {app, BrowserView, session} = require('electron');
+const {app, WebContentsView, session} = require('electron');
 const path = require('path');
 const {APP_EVENTS} = require('../constants');
 const {loadSettings, updateSettings} = require('../settings');
@@ -37,19 +37,19 @@ const handlePageTitleUpdated = (ipcSender, tabId) => (_e, title) => {
   ipcSender.send(APP_EVENTS.setTabTitle, {id: tabId, title: title});
 };
 
-const extractFavicon = async browserView => {
-  let favicons = await browserView.webContents
+const extractFavicon = async view => {
+  let favicons = await view.webContents
     .executeJavaScript('Array.from(document.querySelectorAll(\'link[rel="shortcut icon"]\')).map(el => el.href)');
   if (favicons.length === 0) {
-    favicons = await browserView.webContents
+    favicons = await view.webContents
       .executeJavaScript('Array.from(document.querySelectorAll(\'link[rel*="icon"]\')).map(el => el.href)');
   }
   return favicons;
 };
 
-const handlePageFaviconUpdated = (browserView, ipcSender, tabId) => async (_e, favicons = []) => {
+const handlePageFaviconUpdated = (view, ipcSender, tabId) => async (_e, favicons = []) => {
   if (favicons.length === 0) {
-    favicons = await extractFavicon(browserView);
+    favicons = await extractFavicon(view);
   }
   if (favicons.length > 0) {
     ipcSender.send(APP_EVENTS.setTabFavicon, {id: tabId, favicon: favicons[favicons.length - 1]});
@@ -59,9 +59,9 @@ const handlePageFaviconUpdated = (browserView, ipcSender, tabId) => async (_e, f
 // Required for Service Workers -> https://github.com/electron/electron/issues/16196
 const setGlobalUserAgentFallback = userAgent => (app.userAgentFallback = userAgent);
 
-const cleanUserAgent = browserView => {
-  const validUserAgent = userAgentForWebContents(browserView.webContents);
-  browserView.webContents.userAgent = validUserAgent;
+const cleanUserAgent = view => {
+  const validUserAgent = userAgentForWebContents(view.webContents);
+  view.webContents.userAgent = validUserAgent;
   setGlobalUserAgentFallback(validUserAgent);
 };
 
@@ -89,8 +89,7 @@ const addTabs = ipcSender => tabsMetadata => {
     if (tabPreferences.experiment) { // USE NATIVE SPELL CHECKER
       tabPreferences.session.setSpellCheckerDictionaryDownloadURL('file:///home/user/00-MN/projects/manusa/electronim/dictionaries/');
     }
-    const tab = new BrowserView({webPreferences: tabPreferences});
-    tab.setAutoResize({width: false, horizontal: false, height: false, vertical: false});
+    const tab = new WebContentsView({webPreferences: tabPreferences});
 
     cleanUserAgent(tab);
     tab.webContents.loadURL(url);
@@ -166,11 +165,11 @@ const getTabAt = position => {
 };
 
 const removeAll = () => {
-  Object.values(tabs).forEach(browserView => browserView.webContents.destroy());
+  Object.values(tabs).forEach(view => view.webContents.destroy());
   Object.keys(tabs).forEach(key => delete tabs[key]);
 };
 
-const reload = () => Object.values(tabs).forEach(browserView => browserView.webContents.reload());
+const reload = () => Object.values(tabs).forEach(view => view.webContents.reload());
 
 const canNotify = tabId => {
   const {tabs: tabsSettings, disableNotificationsGlobally} = loadSettings();
diff --git a/src/tab-manager/redirect.js b/src/tab-manager/redirect.js
index 6cec087..1e96927 100644
--- a/src/tab-manager/redirect.js
+++ b/src/tab-manager/redirect.js
@@ -15,8 +15,8 @@
  */
 const {shell} = require('electron');
 
-const matchUrls = regexList => (browserViewUrl, url) =>
-  regexList.some(regex => browserViewUrl.href.match(regex) || url.href.match(regex));
+const matchUrls = regexList => (viewUrl, url) =>
+  regexList.some(regex => viewUrl.href.match(regex) || url.href.match(regex));
 
 const isOAuth = matchUrls([
   /^https:\/\/(.+\.)?github\.com\/login\/oauth.*/, // NOSONAR
@@ -42,18 +42,18 @@ const isOAuth = matchUrls([
   /^https:\/\/.+\.zoom\.us\/signin.*/ // NOSONAR
 ]);
 
-const isHandledInternally = (browserViewUrl, url) => [
+const isHandledInternally = (viewUrl, url) => [
   /^https:\/\/app\.slack\.com\/.*/, // NOSONAR
   /^https:\/\/files\.slack\.com\/.*/ // NOSONAR
 ].some(regex => url.href.match(regex));
 
-const isSameOrigin = (browserViewUrl, url) => url.origin === browserViewUrl.origin;
+const isSameOrigin = (viewUrl, url) => url.origin === viewUrl.origin;
 
-const shouldOpenInExternalBrowser = (browserView, url) => {
-  const browserViewUrl = new URL(browserView.webContents.getURL());
+const shouldOpenInExternalBrowser = (view, url) => {
+  const viewUrl = new URL(view.webContents.getURL());
   let ret = true;
   [isSameOrigin, isOAuth, isHandledInternally].forEach(f => {
-    if (ret && f(browserViewUrl, url)) {
+    if (ret && f(viewUrl, url)) {
       ret = false;
     }
   });
@@ -67,16 +67,16 @@ const openExternal = urlString => {
   shell.openExternal(urlString).then(() => {});
 };
 
-const handleRedirect = browserView => (e, urlString) => {
+const handleRedirect = view => (e, urlString) => {
   const url = new URL(urlString);
-  if (shouldOpenInExternalBrowser(browserView, url)) {
+  if (shouldOpenInExternalBrowser(view, url)) {
     e.preventDefault();
     openExternal(urlString);
   }
 };
 
-const windowOpenHandler = browserView => ({url}) => {
-  if (!shouldOpenInExternalBrowser(browserView, new URL(url))) {
+const windowOpenHandler = view => ({url}) => {
+  if (!shouldOpenInExternalBrowser(view, new URL(url))) {
     return {action: 'allow'};
   }
   openExternal(url);


Test patch:
diff --git a/src/__tests__/electron.js b/src/__tests__/electron.js
index 14f567f..8c4673d 100644
--- a/src/__tests__/electron.js
+++ b/src/__tests__/electron.js
@@ -14,29 +14,15 @@
    limitations under the License.
  */
 
-const mockBrowserWindowInstance = () => {
+const mockWebContentsViewInstance = () => {
   const instance = {
     listeners: {},
-    addBrowserView: jest.fn(),
-    destroy: jest.fn(),
-    getContentBounds: jest.fn(() => ({})),
-    isFullScreen: jest.fn(),
-    loadURL: jest.fn(),
-    minimize: jest.fn(),
     on: jest.fn((eventName, func) => {
       instance.listeners[eventName] = func;
     }),
-    removeBrowserView: jest.fn(),
-    removeMenu: jest.fn(),
-    setAutoResize: jest.fn(),
     setBounds: jest.fn(),
-    setBrowserView: jest.fn(),
-    setFullScreen: jest.fn(),
-    show: jest.fn(),
-    showInactive: jest.fn(),
     webContents: {
       loadedUrl: '',
-      browserWindowInstance: () => instance,
       copy: jest.fn(),
       copyImageAt: jest.fn(),
       cut: jest.fn(),
@@ -61,9 +47,36 @@ const mockBrowserWindowInstance = () => {
   return instance;
 };
 
+const mockBaseWindowInstance = () => {
+  const instance = {
+    listeners: {},
+    destroy: jest.fn(),
+    getContentBounds: jest.fn(() => ({})),
+    isFullScreen: jest.fn(),
+    loadURL: jest.fn(),
+    minimize: jest.fn(),
+    on: jest.fn((eventName, func) => {
+      instance.listeners[eventName] = func;
+    }),
+    removeMenu: jest.fn(),
+    setBounds: jest.fn(),
+    setFullScreen: jest.fn(),
+    show: jest.fn(),
+    showInactive: jest.fn(),
+    contentView: {
+      addChildView: jest.fn(view => instance.contentView.children.push(view)),
+      removeChildView: jest.fn(view => {
+        instance.contentView.children = instance.contentView.children.filter(child => child !== view);
+      }),
+      children: []
+    }
+  };
+  return instance;
+};
+
 const mockElectronInstance = ({...overriddenProps} = {}) => {
-  const browserViewInstance = mockBrowserWindowInstance();
-  const browserWindowInstance = mockBrowserWindowInstance();
+  const webContentsViewInstance = mockWebContentsViewInstance();
+  const baseWindowInstance = mockBaseWindowInstance();
   const sessionInstance = {
     clearCache: jest.fn(),
     clearCodeCaches: jest.fn(),
@@ -76,10 +89,10 @@ const mockElectronInstance = ({...overriddenProps} = {}) => {
     on: jest.fn()
   };
   const instance = {
-    BrowserView: jest.fn(() => browserViewInstance),
-    browserViewInstance,
-    BrowserWindow: jest.fn(() => browserWindowInstance),
-    browserWindowInstance,
+    WebContentsView: jest.fn(() => webContentsViewInstance),
+    webContentsViewInstance,
+    BaseWindow: jest.fn(() => baseWindowInstance),
+    baseWindowInstance,
     Menu: jest.fn(),
     MenuItem: jest.fn(),
     Notification: jest.fn(),
@@ -139,8 +152,7 @@ const mockElectronInstance = ({...overriddenProps} = {}) => {
     },
     ...overriddenProps
   };
-  instance.BrowserWindow.fromWebContents = jest.fn(webContents => webContents.browserWindowInstance());
   return instance;
 };
 
-module.exports = {mockBrowserWindowInstance, mockElectronInstance};
+module.exports = {mockBaseWindowInstance, mockWebContentsViewInstance, mockElectronInstance};
diff --git a/src/__tests__/index.js b/src/__tests__/index.js
index 5252657..c5abdd3 100644
--- a/src/__tests__/index.js
+++ b/src/__tests__/index.js
@@ -15,6 +15,7 @@
  */
 
 module.exports = {
-  mockBrowserWindowInstance: require('./electron.js').mockBrowserWindowInstance,
+  mockBaseWindowInstance: require('./electron.js').mockBaseWindowInstance,
+  mockWebContentsViewInstance: require('./electron.js').mockWebContentsViewInstance,
   mockElectronInstance: require('./electron.js').mockElectronInstance
 };
diff --git a/src/__tests__/index.test.js b/src/__tests__/index.test.js
index 6f27f00..d360b25 100644
--- a/src/__tests__/index.test.js
+++ b/src/__tests__/index.test.js
@@ -32,7 +32,7 @@ describe('Entrypoint test suite', () => {
     test('Adds quit event listener', () => expect(app.on).toHaveBeenCalledWith('quit', main.quit));
     test('Registers app keyboard shortcuts on every webContents created (web-contents-created)', () => {
       expect(app.on)
-        .toHaveBeenCalledWith('web-contents-created', require('../browser-window').registerAppShortcuts);
+        .toHaveBeenCalledWith('web-contents-created', require('../base-window').registerAppShortcuts);
     });
   });
 });
diff --git a/src/about/__tests__/index.test.js b/src/about/__tests__/index.test.js
index 9a2bfb6..f1256bc 100644
--- a/src/about/__tests__/index.test.js
+++ b/src/about/__tests__/index.test.js
@@ -15,61 +15,63 @@
  */
 describe('About module test suite', () => {
   let electron;
-  let sender;
   let about;
   beforeEach(() => {
     jest.resetModules();
     jest.mock('electron', () => require('../../__tests__').mockElectronInstance());
     electron = require('electron');
-    sender = electron.browserWindowInstance.webContents;
     about = require('../');
   });
   describe('openAboutDialog', () => {
+    let openAbout;
+    beforeEach(() => {
+      openAbout = about.openAboutDialog(electron.baseWindowInstance);
+    });
     describe('webPreferences', () => {
       test('is sandboxed', () => {
         // When
-        about.openAboutDialog({sender});
+        openAbout();
         // Then
-        const BrowserView = electron.BrowserView;
-        expect(BrowserView).toHaveBeenCalledTimes(1);
-        expect(BrowserView).toHaveBeenCalledWith({
+        const WebContentsView = electron.WebContentsView;
+        expect(WebContentsView).toHaveBeenCalledTimes(1);
+        expect(WebContentsView).toHaveBeenCalledWith({
           webPreferences: expect.objectContaining({sandbox: true, nodeIntegration: false})
         });
       });
       test('has no node integration', () => {
         // When
-        about.openAboutDialog({sender});
+        openAbout();
         // Then
-        expect(electron.BrowserView).toHaveBeenCalledWith({
+        expect(electron.WebContentsView).toHaveBeenCalledWith({
           webPreferences: expect.objectContaining({nodeIntegration: false})
         });
       });
       test('has context isolation', () => {
         // When
-        about.openAboutDialog({sender});
+        openAbout();
         // Then
-        expect(electron.BrowserView).toHaveBeenCalledWith({
+        expect(electron.WebContentsView).toHaveBeenCalledWith({
           webPreferences: expect.objectContaining({contextIsolation: true})
         });
       });
     });
     test('hasWindowOpenHandler', () => {
       // Given
-      electron.browserViewInstance.webContents.getURL.mockReturnValue('file://about/index.html');
-      about.openAboutDialog({sender});
+      electron.webContentsViewInstance.webContents.getURL.mockReturnValue('file://about/index.html');
+      openAbout();
       // When
-      electron.browserViewInstance.webContents.setWindowOpenHandler.mock.calls[0][0]({url: 'https://example.com'});
+      electron.webContentsViewInstance.webContents.setWindowOpenHandler.mock.calls[0][0]({url: 'https://example.com'});
       // Then
       expect(electron.shell.openExternal).toHaveBeenCalledWith('https://example.com');
     });
     test('should open dialog and add event listeners', () => {
       // When
-      about.openAboutDialog({sender: electron.browserWindowInstance.webContents});
+      openAbout();
       // Then
-      expect(electron.browserViewInstance.webContents.loadURL).toHaveBeenCalledTimes(1);
-      expect(electron.browserViewInstance.webContents.loadURL)
+      expect(electron.webContentsViewInstance.webContents.loadURL).toHaveBeenCalledTimes(1);
+      expect(electron.webContentsViewInstance.webContents.loadURL)
         .toHaveBeenCalledWith(expect.stringMatching(/.+?\/index.html$/)); // NOSONAR
-      expect(electron.browserViewInstance.webContents.on).toHaveBeenCalledWith('will-navigate', expect.any(Function));
+      expect(electron.webContentsViewInstance.webContents.on).toHaveBeenCalledWith('will-navigate', expect.any(Function));
     });
   });
 });
diff --git a/src/app-menu/__tests__/app-menu.browser.test.mjs b/src/app-menu/__tests__/app-menu.browser.test.mjs
index befae3b..a5c13c5 100644
--- a/src/app-menu/__tests__/app-menu.browser.test.mjs
+++ b/src/app-menu/__tests__/app-menu.browser.test.mjs
@@ -29,7 +29,7 @@ describe('App Menu in Browser test suite', () => {
     };
     await loadDOM({meta: import.meta, path: ['..', 'index.html']});
   });
-  test('wrapper, click should close menu (BrowserView)', () => {
+  test('wrapper, click should close menu (WebContentsView)', () => {
     // When
     fireEvent.click(document.querySelector('.app-menu .wrapper'));
     // Then
diff --git a/src/browser-window/__tests__/index.test.js b/src/base-window/__tests__/index.test.js
similarity index 61%
rename from src/browser-window/__tests__/index.test.js
rename to src/base-window/__tests__/index.test.js
index e4031be..cbc8ecb 100644
--- a/src/browser-window/__tests__/index.test.js
+++ b/src/base-window/__tests__/index.test.js
@@ -13,26 +13,23 @@
    See the License for the specific language governing permissions and
    limitations under the License.
  */
-describe('browser-window util module test suite', () => {
-  let browserWindow;
+describe('base-window util module test suite', () => {
+  let baseWindow;
   beforeEach(() => {
-    browserWindow = require('../');
+    baseWindow = require('../');
   });
   test('showDialog, should fill provided window with provided BrowserView', () => {
     // Given
-    const window = require('../../__tests__/electron').mockBrowserWindowInstance();
+    const window = require('../../__tests__/electron').mockBaseWindowInstance();
     window.getContentBounds = jest.fn(() => ({width: 13, height: 37}));
-    const dialog = require('../../__tests__/electron').mockBrowserWindowInstance();
+    const dialog = require('../../__tests__/electron').mockWebContentsViewInstance();
     // When
-    browserWindow.showDialog(window, dialog);
+    baseWindow.showDialog(window, dialog);
     // Then
-    expect(window.setBrowserView).toHaveBeenCalledWith(dialog);
-    expect(window.setBrowserView).toHaveBeenCalledBefore(dialog.setBounds);
+    expect(window.contentView.addChildView).toHaveBeenCalledWith(dialog);
+    expect(window.contentView.addChildView).toHaveBeenCalledBefore(dialog.setBounds);
     expect(dialog.setBounds).toHaveBeenCalledTimes(1);
     expect(dialog.setBounds).toHaveBeenCalledWith({x: 0, y: 0, width: 13, height: 37});
-    expect(dialog.setAutoResize).toHaveBeenCalledTimes(1);
-    expect(dialog.setAutoResize)
-      .toHaveBeenCalledWith({width: false, horizontal: false, height: false, vertical: false});
     expect(dialog.webContents.focus).toHaveBeenCalledTimes(1);
   });
 });
diff --git a/src/browser-window/__tests__/keyboard-shortcuts.test.js b/src/base-window/__tests__/keyboard-shortcuts.test.js
similarity index 76%
rename from src/browser-window/__tests__/keyboard-shortcuts.test.js
rename to src/base-window/__tests__/keyboard-shortcuts.test.js
index ea299b6..e01f122 100644
--- a/src/browser-window/__tests__/keyboard-shortcuts.test.js
+++ b/src/base-window/__tests__/keyboard-shortcuts.test.js
@@ -15,14 +15,14 @@
  */
 describe('Main :: Global Keyboard Shortcuts module test suite', () => {
   let electron;
-  let browserWindow;
+  let view;
   let inputEvent;
   beforeEach(() => {
     jest.resetModules();
     jest.mock('electron', () => require('../../__tests__').mockElectronInstance());
     electron = require('electron');
-    browserWindow = require('../../__tests__').mockBrowserWindowInstance();
-    require('../').registerAppShortcuts({}, browserWindow.webContents);
+    view = require('../../__tests__').mockWebContentsViewInstance();
+    require('../').registerAppShortcuts({}, view.webContents);
     inputEvent = {
       preventDefault: jest.fn()
     };
@@ -35,38 +35,38 @@ describe('Main :: Global Keyboard Shortcuts module test suite', () => {
     {key: 'Tab', shift: true, control: true, appEvent: 'tabTraversePrevious'}
   ])('Key "$key" (shift: $shift, ctrl: $control) triggers "$appEvent" app event',
     ({key, control, shift, appEvent}) => {
-      browserWindow.listeners['before-input-event'](inputEvent, {key, control, shift});
+      view.listeners['before-input-event'](inputEvent, {key, control, shift});
       expect(electron.ipcMain.emit).toHaveBeenCalledWith(appEvent);
     });
   describe.each([1, 2, 3, 4, 5, 6, 7, 8, 9])('Key "%s"', key => {
     test('with ctrl, triggers "tabSwitchToPosition" app event', () => {
-      browserWindow.listeners['before-input-event'](inputEvent, {key, control: true});
+      view.listeners['before-input-event'](inputEvent, {key, control: true});
       expect(electron.ipcMain.emit).toHaveBeenCalledWith('tabSwitchToPosition', key);
     });
     test('with meta, triggers "tabSwitchToPosition" app event', () => {
-      browserWindow.listeners['before-input-event'](inputEvent, {key, meta: true});
+      view.listeners['before-input-event'](inputEvent, {key, meta: true});
       expect(electron.ipcMain.emit).toHaveBeenCalledWith('tabSwitchToPosition', key);
     });
     test('with no modifiers, does nothing', () => {
-      browserWindow.listeners['before-input-event'](inputEvent, {key});
+      view.listeners['before-input-event'](inputEvent, {key});
       expect(electron.ipcMain.emit).not.toHaveBeenCalled();
     });
   });
   test('ignores keyUp events', () => {
-    browserWindow.listeners['before-input-event'](inputEvent, {type: 'keyUp', key: 'Escape'});
+    view.listeners['before-input-event'](inputEvent, {type: 'keyUp', key: 'Escape'});
     expect(electron.ipcMain.emit).not.toHaveBeenCalled();
   });
   describe('preventDefault', () => {
     test('calls preventDefault if key is registered', () => {
-      browserWindow.listeners['before-input-event'](inputEvent, {key: 'F11'});
+      view.listeners['before-input-event'](inputEvent, {key: 'F11'});
       expect(inputEvent.preventDefault).toHaveBeenCalled();
     });
     test('doesn\'t call preventDefault if key is registered and preventDefault is disabled', () => {
-      browserWindow.listeners['before-input-event'](inputEvent, {key: 'Esc'});
+      view.listeners['before-input-event'](inputEvent, {key: 'Esc'});
       expect(inputEvent.preventDefault).not.toHaveBeenCalled();
     });
     test('doesn\'t call preventDefault if key is not registered', () => {
-      browserWindow.listeners['before-input-event'](inputEvent, {});
+      view.listeners['before-input-event'](inputEvent, {});
       expect(inputEvent.preventDefault).not.toHaveBeenCalled();
     });
   });
diff --git a/src/browser-window/keyboard-shortcuts.js b/src/base-window/keyboard-shortcuts.js
similarity index 100%
rename from src/browser-window/keyboard-shortcuts.js
rename to src/base-window/keyboard-shortcuts.js
diff --git a/src/chrome-tabs/__tests__/index.test.js b/src/chrome-tabs/__tests__/index.test.js
index 9bd516f..2a93de2 100644
--- a/src/chrome-tabs/__tests__/index.test.js
+++ b/src/chrome-tabs/__tests__/index.test.js
@@ -31,26 +31,26 @@ describe('Chrome Tabs Module module test suite', () => {
       // When
       chromeTabs.newTabContainer();
       // Then
-      const BrowserView = require('electron').BrowserView;
-      expect(BrowserView).toHaveBeenCalledTimes(1);
-      expect(BrowserView).toHaveBeenCalledWith({
+      const WebContentsView = require('electron').WebContentsView;
+      expect(WebContentsView).toHaveBeenCalledTimes(1);
+      expect(WebContentsView).toHaveBeenCalledWith({
         webPreferences: expect.objectContaining({sandbox: true, nodeIntegration: false})
       });
     });
     test('checks for updates', async () => {
       // Given
-      const {browserViewInstance} = require('electron');
+      const {webContentsViewInstance} = require('electron');
       let resolveSend;
       const isSent = new Promise(resolve => {
         resolveSend = resolve;
       });
-      browserViewInstance.webContents.send = jest.fn(() => resolveSend(true));
+      webContentsViewInstance.webContents.send = jest.fn(() => resolveSend(true));
       chromeTabs.newTabContainer();
       // When
       require('electron').ipcMain.listeners.tabsReady();
       // Then
       await expect(isSent).resolves.toBe(true);
-      expect(browserViewInstance.webContents.send).toHaveBeenCalledWith('electronimNewVersionAvailable', true);
+      expect(webContentsViewInstance.webContents.send).toHaveBeenCalledWith('electronimNewVersionAvailable', true);
     });
     test('sets interval to check for updates with unref', () => {
       // Given
diff --git a/src/help/__tests__/index.test.js b/src/help/__tests__/index.test.js
index f72d06f..16f402f 100644
--- a/src/help/__tests__/index.test.js
+++ b/src/help/__tests__/index.test.js
@@ -25,16 +25,16 @@ describe('Help module test suite', () => {
   describe('openHelpDialog', () => {
     let openHelp;
     beforeEach(() => {
-      openHelp = help.openHelpDialog(electron.browserWindowInstance);
+      openHelp = help.openHelpDialog(electron.baseWindowInstance);
     });
     describe('webPreferences', () => {
       test('is sandboxed', () => {
         // When
         openHelp();
         // Then
-        const BrowserView = electron.BrowserView;
-        expect(BrowserView).toHaveBeenCalledTimes(1);
-        expect(BrowserView).toHaveBeenCalledWith({
+        const WebContentsView = electron.WebContentsView;
+        expect(WebContentsView).toHaveBeenCalledTimes(1);
+        expect(WebContentsView).toHaveBeenCalledWith({
           webPreferences: expect.objectContaining({sandbox: true, nodeIntegration: false})
         });
       });
@@ -42,7 +42,7 @@ describe('Help module test suite', () => {
         // When
         openHelp();
         // Then
-        expect(electron.BrowserView).toHaveBeenCalledWith({
+        expect(electron.WebContentsView).toHaveBeenCalledWith({
           webPreferences: expect.objectContaining({nodeIntegration: false})
         });
       });
@@ -50,17 +50,17 @@ describe('Help module test suite', () => {
         // When
         openHelp();
         // Then
-        expect(electron.BrowserView).toHaveBeenCalledWith({
+        expect(electron.WebContentsView).toHaveBeenCalledWith({
           webPreferences: expect.objectContaining({contextIsolation: true})
         });
       });
     });
     test('hasWindowOpenHandler', () => {
       // Given
-      electron.browserViewInstance.webContents.getURL.mockReturnValue('file://help/index.html');
+      electron.webContentsViewInstance.webContents.getURL.mockReturnValue('file://help/index.html');
       openHelp();
       // When
-      electron.browserViewInstance.webContents.setWindowOpenHandler.mock.calls[0][0]({url: 'https://example.com'});
+      electron.webContentsViewInstance.webContents.setWindowOpenHandler.mock.calls[0][0]({url: 'https://example.com'});
       // Then
       expect(electron.shell.openExternal).toHaveBeenCalledWith('https://example.com');
     });
@@ -68,10 +68,10 @@ describe('Help module test suite', () => {
       // When
       openHelp();
       // Then
-      expect(electron.browserViewInstance.webContents.loadURL).toHaveBeenCalledTimes(1);
-      expect(electron.browserViewInstance.webContents.loadURL)
+      expect(electron.webContentsViewInstance.webContents.loadURL).toHaveBeenCalledTimes(1);
+      expect(electron.webContentsViewInstance.webContents.loadURL)
         .toHaveBeenCalledWith(expect.stringMatching(/.+?\/index.html$/)); // NOSONAR
-      expect(electron.browserViewInstance.webContents.on).toHaveBeenCalledWith('will-navigate', expect.any(Function));
+      expect(electron.webContentsViewInstance.webContents.on).toHaveBeenCalledWith('will-navigate', expect.any(Function));
     });
   });
 });
diff --git a/src/main/__tests__/global-listeners.test.js b/src/main/__tests__/global-listeners.test.js
index b3dd1ff..930bdb0 100644
--- a/src/main/__tests__/global-listeners.test.js
+++ b/src/main/__tests__/global-listeners.test.js
@@ -19,7 +19,7 @@
 describe('Main :: Global listeners test suite', () => {
   let electron;
   let main;
-  let browserWindow;
+  let baseWindow;
   let eventBus;
   beforeEach(() => {
     jest.resetModules();
@@ -29,12 +29,9 @@ describe('Main :: Global listeners test suite', () => {
       trayEnabled: true
     }));
     require('../../settings').openSettingsDialog = jest.requireActual('../../settings').openSettingsDialog;
-    jest.mock('electron', () => require('../../__tests__').mockElectronInstance({
-      // Return a **different** instance for each view
-      BrowserView: jest.fn(() => require('../../__tests__').mockBrowserWindowInstance())
-    }));
+    jest.mock('electron', () => require('../../__tests__').mockElectronInstance());
     electron = require('electron');
-    browserWindow = electron.browserWindowInstance;
+    baseWindow = electron.baseWindowInstance;
     eventBus = electron.ipcMain;
     jest.spyOn(require('../../user-agent'), 'initBrowserVersions')
       .mockImplementation(() => Promise.resolve({}));
@@ -45,29 +42,30 @@ describe('Main :: Global listeners test suite', () => {
     // When
     eventBus.listeners.appMenuOpen();
     // Then
-    expect(browserWindow.addBrowserView).toHaveBeenCalledWith(
+    expect(baseWindow.contentView.addChildView).toHaveBeenCalledWith(
       expect.objectContaining({isAppMenu: true})
     );
-    expect(browserWindow.addBrowserView.mock.calls[0][0].setBounds).toHaveBeenCalledWith(expect.objectContaining({
-      x: 0, y: 0
-    }));
+    expect(baseWindow.contentView.addChildView.mock.calls[0][0].setBounds)
+      .toHaveBeenCalledWith(expect.objectContaining({
+        x: 0, y: 0
+      }));
   });
   describe('appMenuClose', () => {
     test('with menu hidden, should return', () => {
       // Given
-      browserWindow.getBrowserViews = jest.fn(() => []);
+      baseWindow.contentView.children = [];
       // When
       eventBus.listeners.appMenuClose();
       // Then
-      expect(browserWindow.removeBrowserView).not.toHaveBeenCalled();
+      expect(baseWindow.contentView.removeChildView).not.toHaveBeenCalled();
     });
     test('with menu visible, should hide app-menu', () => {
       // Given
-      browserWindow.getBrowserViews = jest.fn(() => [{isAppMenu: true}]);
+      baseWindow.contentView.children = [{isAppMenu: true}];
       // When
       eventBus.listeners.appMenuClose();
       // Then
-      expect(browserWindow.removeBrowserView).toHaveBeenCalledWith(
+      expect(baseWindow.contentView.removeChildView).toHaveBeenCalledWith(
         expect.objectContaining({isAppMenu: true})
       );
     });
@@ -76,9 +74,9 @@ describe('Main :: Global listeners test suite', () => {
     describe('with dialog visible (<= 1 view)', () => {
       let dialog;
       beforeEach(() => {
-        dialog = new electron.BrowserView();
-        browserWindow.getBrowserViews = jest.fn(() => [dialog]);
-        browserWindow.getBrowserView = jest.fn(() => (dialog));
+        dialog = new electron.WebContentsView();
+        dialog.isDialog = true;
+        baseWindow.contentView.children = [dialog];
       });
       test('should destroy dialog', () => {
         // When
@@ -107,8 +105,8 @@ describe('Main :: Global listeners test suite', () => {
     });
     test('should return if no dialog is shown (>1 view)', () => {
       // Given
-      const view = new electron.BrowserView();
-      browserWindow.getBrowserViews = jest.fn(() => [view, view]);
+      const view = new electron.WebContentsView();
+      baseWindow.contentView.children = [view, view];
       // When
       eventBus.listeners.closeDialog();
       // Then
@@ -118,29 +116,29 @@ describe('Main :: Global listeners test suite', () => {
   describe('fullscreenToggle', () => {
     test('when not fullscreen, should enter fullscreen', () => {
       // Given
-      browserWindow.isFullScreen.mockReturnValue(false);
+      baseWindow.isFullScreen.mockReturnValue(false);
       // When
       eventBus.listeners.fullscreenToggle();
       // Then
-      expect(browserWindow.setFullScreen).toHaveBeenCalledWith(true);
+      expect(baseWindow.setFullScreen).toHaveBeenCalledWith(true);
     });
     test('when in fullscreen, should leave fullscreen', () => {
       // Given
-      browserWindow.isFullScreen.mockReturnValue(true);
+      baseWindow.isFullScreen.mockReturnValue(true);
       // When
       eventBus.listeners.fullscreenToggle();
       // Then
-      expect(browserWindow.setFullScreen).toHaveBeenCalledWith(false);
+      expect(baseWindow.setFullScreen).toHaveBeenCalledWith(false);
     });
   });
   test('helpOpenDialog, should open help dialog', () => {
     // When
-    eventBus.listeners.helpOpenDialog({sender: browserWindow.webContents});
+    eventBus.listeners.helpOpenDialog({sender: baseWindow.webContents});
     // Then
-    const browserView = electron.BrowserView.mock.results
+    const view = electron.WebContentsView.mock.results
       .map(r => r.value).filter(bv => bv.webContents.loadedUrl.endsWith('help/index.html'))[0];
-    expect(browserWindow.setBrowserView).toHaveBeenCalledWith(browserView);
-    expect(browserView.webContents.loadURL)
+    expect(baseWindow.contentView.addChildView).toHaveBeenCalledWith(view);
+    expect(view.webContents.loadURL)
       .toHaveBeenCalledWith(expect.stringMatching(/help\/index.html$/));
   });
   test('quit, should exit the application', () => {
@@ -153,18 +151,17 @@ describe('Main :: Global listeners test suite', () => {
     // When
     eventBus.listeners.settingsOpenDialog();
     // Then
-    const browserView = electron.BrowserView.mock.results
+    const view = electron.WebContentsView.mock.results
       .map(r => r.value).filter(bv => bv.webContents.loadedUrl.endsWith('settings/index.html'))[0];
-    expect(browserWindow.setBrowserView).toHaveBeenCalledWith(browserView);
-    expect(browserView.webContents.loadURL)
+    expect(baseWindow.contentView.addChildView).toHaveBeenCalledWith(view);
+    expect(view.webContents.loadURL)
       .toHaveBeenCalledWith(expect.stringMatching(/settings\/index.html$/));
   });
   describe('settingsSave', () => {
     let settings;
     beforeEach(() => {
-      settings = new electron.BrowserView();
-      browserWindow.getBrowserViews = jest.fn(() => [settings]);
-      browserWindow.getBrowserView = jest.fn(() => (settings));
+      settings = new electron.WebContentsView();
+      baseWindow.contentView.children = [settings];
     });
     test('should reload settings', () => {
       // Given
@@ -172,10 +169,16 @@ describe('Main :: Global listeners test suite', () => {
       // When
       eventBus.listeners.settingsSave({}, {tabs: [{id: 1337}], enabledDictionaries: []});
       // Then
-      expect(electron.browserWindowInstance.loadURL)
-        .toHaveBeenCalledWith(expect.stringMatching(/spell-check\/dictionary.renderer\/index.html$/));
       expect(settingsModule.updateSettings).toHaveBeenCalledTimes(1);
     });
+    test('should reload fake dictionary renderer', () => {
+      // Given
+      // When
+      eventBus.listeners.settingsSave({}, {tabs: [{id: 1337}], enabledDictionaries: []});
+      // Then
+      expect(electron.webContentsViewInstance.webContents.loadURL)
+        .toHaveBeenCalledWith(expect.stringMatching(/spell-check\/dictionary.renderer\/index.html$/));
+    });
     test('should reset all views', () => {
       // Given
       const tabManagerModule = require('../../tab-manager');
@@ -183,8 +186,8 @@ describe('Main :: Global listeners test suite', () => {
       // When
       eventBus.listeners.settingsSave({}, {tabs: [{id: 1337}], enabledDictionaries: []});
       // Then
-      expect(browserWindow.removeBrowserView).toHaveBeenCalledTimes(1);
-      expect(browserWindow.removeBrowserView).toHaveBeenCalledWith(settings);
+      expect(baseWindow.contentView.removeChildView).toHaveBeenCalledTimes(1);
+      expect(baseWindow.contentView.removeChildView).toHaveBeenCalledWith(settings);
       expect(tabManagerModule.removeAll).toHaveBeenCalledTimes(1);
       expect(settings.webContents.destroy).toHaveBeenCalledTimes(1);
     });
@@ -205,7 +208,7 @@ describe('Main :: Global listeners test suite', () => {
       'tabTraverseNext', 'tabTraversePrevious'
     ])('%s, with dialog visible, should not traverse', event => {
       // Given
-      browserWindow.getBrowserViews = jest.fn(() => [new electron.BrowserView()]);
+      baseWindow.contentView.children = [new electron.WebContentsView()];
       main.init();
       // When
       eventBus.listeners[event]();
@@ -214,7 +217,7 @@ describe('Main :: Global listeners test suite', () => {
     });
     describe('with tabs visible, should traverse', () => {
       beforeEach(() => {
-        browserWindow.getBrowserViews = jest.fn(() => [new electron.BrowserView(), new electron.BrowserView()]);
+        baseWindow.getBrowserViews = jest.fn(() => [new electron.BrowserView(), new electron.BrowserView()]);
       });
       test('tabTraverseNext', () => {
         jest.spyOn(tabManagerModule, 'getNextTab').mockImplementation(() => 'nextTabId');
diff --git a/src/main/__tests__/index.test.js b/src/main/__tests__/index.test.js
index 69fd69f..1e91af4 100644
--- a/src/main/__tests__/index.test.js
+++ b/src/main/__tests__/index.test.js
@@ -19,8 +19,8 @@
 describe('Main module test suite', () => {
   let mockNotification;
   let electron;
-  let mockBrowserView;
-  let mockBrowserWindow;
+  let mockView;
+  let mockBaseWindow;
   let mockDesktopCapturer;
   let mockIpc;
   let mockNativeTheme;
@@ -42,8 +42,8 @@ describe('Main module test suite', () => {
       nativeTheme: mockNativeTheme
     }));
     electron = require('electron');
-    mockBrowserView = electron.browserViewInstance;
-    mockBrowserWindow = electron.browserWindowInstance;
+    mockView = electron.webContentsViewInstance;
+    mockBaseWindow = electron.baseWindowInstance;
     mockIpc = electron.ipcMain;
     appMenuModule = require('../../app-menu');
     jest.spyOn(appMenuModule, 'newAppMenu');
@@ -80,7 +80,7 @@ describe('Main module test suite', () => {
         // When
         main.init();
         // Then
-        expect(electron.BrowserWindow).toHaveBeenCalledWith(expect.objectContaining({
+        expect(electron.BaseWindow).toHaveBeenCalledWith(expect.objectContaining({
           icon: expect.stringMatching(/icon\.png$/)
         }));
       });
@@ -90,7 +90,7 @@ describe('Main module test suite', () => {
         // When
         main.init();
         // Then
-        expect(electron.BrowserWindow).toHaveBeenCalledWith(expect.objectContaining({
+        expect(electron.BaseWindow).toHaveBeenCalledWith(expect.objectContaining({
           icon: expect.stringMatching(/icon\.ico$/)
         }));
       });
@@ -100,7 +100,7 @@ describe('Main module test suite', () => {
         // When
         main.init();
         // Then
-        expect(electron.BrowserWindow).toHaveBeenCalledWith(expect.objectContaining({
+        expect(electron.BaseWindow).toHaveBeenCalledWith(expect.objectContaining({
           show: false, paintWhenInitiallyHidden: false
         }));
       });
@@ -110,13 +110,13 @@ describe('Main module test suite', () => {
           main.init();
         });
         test('should call showInactive', () => {
-          expect(mockBrowserWindow.showInactive).toHaveBeenCalledTimes(1);
+          expect(mockBaseWindow.showInactive).toHaveBeenCalledTimes(1);
         });
         test('should call minimize after showInactive', () => {
-          expect(mockBrowserWindow.minimize).toHaveBeenCalledAfter(mockBrowserWindow.showInactive);
+          expect(mockBaseWindow.minimize).toHaveBeenCalledAfter(mockBaseWindow.showInactive);
         });
         test('should not call show', () => {
-          expect(mockBrowserWindow.show).not.toHaveBeenCalled();
+          expect(mockBaseWindow.show).not.toHaveBeenCalled();
         });
       });
       describe('=false', () => {
@@ -125,13 +125,13 @@ describe('Main module test suite', () => {
           main.init();
         });
         test('should call show', () => {
-          expect(mockBrowserWindow.show).toHaveBeenCalledTimes(1);
+          expect(mockBaseWindow.show).toHaveBeenCalledTimes(1);
         });
         test('should not call showInactive', () => {
-          expect(mockBrowserWindow.showInactive).not.toHaveBeenCalled();
+          expect(mockBaseWindow.showInactive).not.toHaveBeenCalled();
         });
         test('should not call minimize', () => {
-          expect(mockBrowserWindow.minimize).not.toHaveBeenCalled();
+          expect(mockBaseWindow.minimize).not.toHaveBeenCalled();
         });
       });
     });
@@ -161,13 +161,13 @@ describe('Main module test suite', () => {
     beforeEach(() => {
       jest.spyOn(global, 'setTimeout');
       views = [];
-      mockBrowserWindow.getSize = jest.fn(() => ([13, 37]));
-      mockBrowserWindow.getContentBounds = jest.fn(() => ({x: 0, y: 0, width: 10, height: 34}));
-      mockBrowserWindow.getBrowserViews = jest.fn(() => (views));
+      mockBaseWindow.getSize = jest.fn(() => ([13, 37]));
+      mockBaseWindow.getContentBounds = jest.fn(() => ({x: 0, y: 0, width: 10, height: 34}));
+      mockBaseWindow.contentView.children = views;
       main.init();
     });
     describe('maximize', () => {
-      test('single view, should set BrowserView to fit window', () => {
+      test('single view, should set View to fit window', () => {
         // Given
         const singleView = {
           getBounds: jest.fn(() => ({x: 0, y: 0, width: 1, height: 1})),
@@ -175,14 +175,14 @@ describe('Main module test suite', () => {
         };
         views.push(singleView);
         // When
-        mockBrowserWindow.listeners.maximize({sender: mockBrowserWindow});
+        mockBaseWindow.listeners.maximize({sender: mockBaseWindow});
         jest.runAllTimers();
         // Then
         expect(singleView.setBounds).toHaveBeenCalledWith({x: 0, y: 0, width: 10, height: 34});
       });
       test('should store new size in configuration file', () => {
         // When
-        mockBrowserWindow.listeners.maximize({sender: mockBrowserWindow});
+        mockBaseWindow.listeners.maximize({sender: mockBaseWindow});
         jest.runAllTimers();
         // Then
         expect(settingsModule.updateSettings).toHaveBeenCalledWith({width: 13, height: 37});
@@ -191,31 +191,38 @@ describe('Main module test suite', () => {
     describe('restore (required for windows when starting minimized)', () => {
       let mockAppMenu;
       beforeEach(() => {
-        mockAppMenu = {
-          setBounds: jest.fn()
-        };
+        mockAppMenu = new electron.WebContentsView();
+        mockAppMenu.isAppMenu = true;
         jest.spyOn(appMenuModule, 'newAppMenu').mockImplementation(() => mockAppMenu);
         main.init();
       });
       test('should set app-menu bounds', () => {
         // When
-        mockBrowserWindow.listeners.restore({sender: mockBrowserWindow});
+        mockBaseWindow.listeners.restore({sender: mockBaseWindow});
         jest.runAllTimers();
         // Then
         expect(mockAppMenu.setBounds).toHaveBeenCalledWith({x: 0, y: 0, width: 10, height: 34});
       });
     });
     describe('resize', () => {
-      test('#78: should be run in separate setTimeout timer function to resize properly in Linux', () => {
+      test('#78: should be run in separate setTimeout timer function to resize properly in Linux (no timers)', () => {
         // When
-        mockBrowserWindow.listeners.resize({sender: mockBrowserWindow});
+        mockBaseWindow.listeners.resize({sender: mockBaseWindow});
+        // Then
+        expect(setTimeout).toHaveBeenCalledTimes(1);
+        expect(mockBaseWindow.getContentBounds).not.toHaveBeenCalled();
+      });
+      test('#78: should be run in separate setTimeout timer function to resize properly in Linux (timers)', () => {
+        // When
+        mockBaseWindow.listeners.resize({sender: mockBaseWindow});
+        jest.runAllTimers();
         // Then
         expect(setTimeout).toHaveBeenCalledTimes(1);
-        expect(mockBrowserWindow.getBrowserViews).not.toHaveBeenCalled();
+        expect(mockBaseWindow.getContentBounds).toHaveBeenCalledTimes(1);
       });
       test('should store new size in configuration file', () => {
         // When
-        mockBrowserWindow.listeners.resize({sender: mockBrowserWindow});
+        mockBaseWindow.listeners.resize({sender: mockBaseWindow});
         jest.runAllTimers();
         // Then
         expect(settingsModule.updateSettings).toHaveBeenCalledWith({width: 13, height: 37});
@@ -223,15 +230,14 @@ describe('Main module test suite', () => {
       describe('app-menu', () => {
         let mockAppMenu;
         beforeEach(() => {
-          mockAppMenu = {
-            setBounds: jest.fn()
-          };
+          mockAppMenu = new electron.WebContentsView();
+          mockAppMenu.isAppMenu = true;
           jest.spyOn(appMenuModule, 'newAppMenu').mockImplementation(() => mockAppMenu);
           main.init();
         });
         test('should set app-menu bounds', () => {
           // When
-          mockBrowserWindow.listeners.resize({sender: mockBrowserWindow});
+          mockBaseWindow.listeners.resize({sender: mockBaseWindow});
           jest.runAllTimers();
           // Then
           expect(mockAppMenu.setBounds).toHaveBeenCalledWith({x: 0, y: 0, width: 10, height: 34});
@@ -240,13 +246,13 @@ describe('Main module test suite', () => {
           // Given
           mockAppMenu.setBounds = null;
           // When
-          mockBrowserWindow.listeners.resize({sender: mockBrowserWindow});
+          mockBaseWindow.listeners.resize({sender: mockBaseWindow});
           jest.runAllTimers();
           // Then
-          expect(mockBrowserWindow.setBounds).not.toHaveBeenCalled();
+          expect(mockBaseWindow.setBounds).not.toHaveBeenCalled();
         });
       });
-      test('single view, should set BrowserView to fit window', () => {
+      test('single view, should set View to fit window', () => {
         // Given
         const singleView = {
           getBounds: jest.fn(() => ({x: 0, y: 0, width: 1, height: 1})),
@@ -254,12 +260,12 @@ describe('Main module test suite', () => {
         };
         views.push(singleView);
         // When
-        mockBrowserWindow.listeners.resize({sender: mockBrowserWindow});
+        mockBaseWindow.listeners.resize({sender: mockBaseWindow});
         jest.runAllTimers();
         // Then
         expect(singleView.setBounds).toHaveBeenCalledWith({x: 0, y: 0, width: 10, height: 34});
       });
-      test('multiple views, should set last BrowserView to fit window and store new size in configuration file', () => {
+      test('multiple views, should set last View to fit window and store new size in configuration file', () => {
         // Given
         const topBar = {
           getBounds: jest.fn(() => ({x: 0, y: 0, width: 1, height: 1})),
@@ -271,7 +277,7 @@ describe('Main module test suite', () => {
         };
         views.push(topBar, content);
         // When
-        mockBrowserWindow.listeners.resize({sender: mockBrowserWindow});
+        mockBaseWindow.listeners.resize({sender: mockBaseWindow});
         jest.runAllTimers();
         // Then
         expect(settingsModule.updateSettings).toHaveBeenCalledWith({width: 13, height: 37});
@@ -297,7 +303,7 @@ describe('Main module test suite', () => {
         // Then
         expect(tabManagerModule.addTabs).not.toHaveBeenCalled();
         expect(addTabsNested).not.toHaveBeenCalled();
-        expect(mockBrowserView.webContents.loadURL)
+        expect(mockView.webContents.loadURL)
           .toHaveBeenCalledWith(expect.stringMatching(/settings\/index.html$/));
       });
       test('Previous saved tabs in loaded settings, should add tabs to manager and activate them as they are added', () => {
@@ -314,7 +320,7 @@ describe('Main module test suite', () => {
         expect(tabManagerModule.addTabs).toHaveBeenCalledWith(event.sender);
         expect(addTabsNested).toHaveBeenCalledTimes(1);
         expect(addTabsNested).toHaveBeenCalledWith([{id: '1337', otherInfo: 'A Tab', active: false}]);
-        expect(mockBrowserWindow.webContents.loadURL)
+        expect(mockView.webContents.loadURL)
           .not.toHaveBeenCalledWith(expect.stringMatching(/settings\/index.html$/));
       });
     });
@@ -325,9 +331,9 @@ describe('Main module test suite', () => {
           setBounds: jest.fn(),
           webContents: {focus: jest.fn()}
         };
-        mockBrowserWindow.getBrowserViews = jest.fn(() => ([]));
-        mockBrowserWindow.setBrowserView = jest.fn();
-        mockBrowserWindow.addBrowserView = jest.fn();
+        mockBaseWindow.getBrowserViews = jest.fn(() => ([]));
+        mockBaseWindow.setBrowserView = jest.fn();
+        mockBaseWindow.addBrowserView = jest.fn();
         tabManagerModule.getTab = jest.fn(id => (id === 'validId' ? activeTab : null));
       });
       test('no active tab, should do nothing', () => {
@@ -336,32 +342,33 @@ describe('Main module test suite', () => {
         // When
         mockIpc.listeners.activateTab({}, {id: 'not here'});
         // Then
-        expect(mockBrowserWindow.setBrowserView).not.toHaveBeenCalled();
-        expect(mockBrowserWindow.addBrowserView).not.toHaveBeenCalled();
+        expect(mockBaseWindow.setBrowserView).not.toHaveBeenCalled();
+        expect(mockBaseWindow.addBrowserView).not.toHaveBeenCalled();
       });
       test('active tab, should resize tab and set it as the main window browser view', () => {
         // Given
-        mockBrowserWindow.getContentBounds = jest.fn(() => ({width: 13, height: 83}));
+        mockBaseWindow.getContentBounds = jest.fn(() => ({width: 13, height: 83}));
         main.init();
         // When
         mockIpc.listeners.activateTab({}, {id: 'validId'});
         // Then
         expect(activeTab.setBounds).toHaveBeenCalledWith({x: 0, y: 46, width: 13, height: 37});
-        expect(mockBrowserWindow.setBrowserView).toHaveBeenCalledWith(expect.objectContaining({isTabContainer: true}));
-        expect(mockBrowserWindow.addBrowserView).toHaveBeenCalledWith(activeTab);
+        expect(mockBaseWindow.contentView.addChildView)
+          .toHaveBeenCalledWith(expect.objectContaining({isTabContainer: true}));
+        expect(mockBaseWindow.contentView.addChildView).toHaveBeenCalledWith(activeTab);
         expect(activeTab.webContents.focus).toHaveBeenCalledTimes(1);
       });
-      test('#23, setBounds should be called AFTER adding view to BrowserWindow', () => {
+      test('#23, setBounds should be called AFTER adding view to BaseWindow', () => {
         // Given
-        mockBrowserWindow.getContentBounds = jest.fn(() => ({width: 13, height: 83}));
+        mockBaseWindow.getContentBounds = jest.fn(() => ({width: 13, height: 83}));
         main.init();
         // When
         mockIpc.listeners.activateTab({}, {id: 'validId'});
         // Then
-        expect(mockBrowserWindow.setBrowserView).toHaveBeenCalledBefore(mockBrowserView.setBounds);
-        expect(mockBrowserWindow.addBrowserView).toHaveBeenCalledBefore(mockBrowserView.setBounds);
-        expect(mockBrowserWindow.setBrowserView).toHaveBeenCalledBefore(activeTab.setBounds);
-        expect(mockBrowserWindow.addBrowserView).toHaveBeenCalledBefore(activeTab.setBounds);
+        expect(mockBaseWindow.contentView.addChildView).toHaveBeenCalledBefore(mockView.setBounds);
+        expect(mockBaseWindow.contentView.addChildView).toHaveBeenCalledBefore(mockView.setBounds);
+        expect(mockBaseWindow.contentView.addChildView).toHaveBeenCalledBefore(activeTab.setBounds);
+        expect(mockBaseWindow.contentView.addChildView).toHaveBeenCalledBefore(activeTab.setBounds);
       });
     });
     test('canNotify, should call to the canNotify method of the tabManager', () => {
@@ -378,17 +385,17 @@ describe('Main module test suite', () => {
     test('notificationClick, should restore window and activate tab', () => {
       // Given
       mockSettings.startMinimized = true;
-      mockBrowserWindow.restore = jest.fn();
-      mockBrowserWindow.show = jest.fn();
+      mockBaseWindow.restore = jest.fn();
+      mockBaseWindow.show = jest.fn();
       jest.spyOn(tabManagerModule, 'getTab').mockImplementation();
       main.init();
       // When
       mockIpc.listeners.notificationClick({}, {tabId: 'validId'});
       // Then
-      expect(mockBrowserView.webContents.send).toHaveBeenCalledWith('activateTabInContainer', {tabId: 'validId'});
-      expect(mockBrowserWindow.restore).toHaveBeenCalledTimes(1);
-      expect(mockBrowserWindow.show).toHaveBeenCalledTimes(1);
-      expect(mockBrowserWindow.show).toHaveBeenCalledAfter(mockBrowserWindow.restore);
+      expect(mockView.webContents.send).toHaveBeenCalledWith('activateTabInContainer', {tabId: 'validId'});
+      expect(mockBaseWindow.restore).toHaveBeenCalledTimes(1);
+      expect(mockBaseWindow.show).toHaveBeenCalledTimes(1);
+      expect(mockBaseWindow.show).toHaveBeenCalledAfter(mockBaseWindow.restore);
       expect(tabManagerModule.getTab).toHaveBeenCalledWith('validId');
     });
     test('handleReload', () => {
diff --git a/src/main/__tests__/main-window-listeners.test.js b/src/main/__tests__/main-window-listeners.test.js
index ba44908..1ac118f 100644
--- a/src/main/__tests__/main-window-listeners.test.js
+++ b/src/main/__tests__/main-window-listeners.test.js
@@ -19,7 +19,7 @@
 describe('Main :: Main window listeners test suite', () => {
   let electron;
   let main;
-  let browserWindow;
+  let baseWindow;
   beforeEach(() => {
     jest.resetModules();
     // Always mock settings unless we want to overwrite the real settings file !
@@ -27,10 +27,10 @@ describe('Main :: Main window listeners test suite', () => {
     require('../../settings').loadSettings.mockImplementation(() => ({}));
     jest.mock('electron', () => require('../../__tests__').mockElectronInstance({
       // Return a **different** instance for each view
-      BrowserView: jest.fn(() => require('../../__tests__').mockBrowserWindowInstance())
+      BrowserView: jest.fn(() => require('../../__tests__').mockBaseWindowInstance())
     }));
     electron = require('electron');
-    browserWindow = electron.browserWindowInstance;
+    baseWindow = electron.baseWindowInstance;
     jest.spyOn(require('../../user-agent'), 'initBrowserVersions')
       .mockImplementation(() => Promise.resolve({}));
     main = require('../');
@@ -43,16 +43,16 @@ describe('Main :: Main window listeners test suite', () => {
     });
     test('always calls event.preventDefault', () => {
       // When
-      browserWindow.listeners.close(event);
+      baseWindow.listeners.close(event);
       // Then
       expect(event.preventDefault).toHaveBeenCalled();
     });
     test('with quit, should exit app', () => {
       // When
-      browserWindow.listeners.close(event);
+      baseWindow.listeners.close(event);
       // Then
       expect(electron.app.exit).toHaveBeenCalled();
-      expect(browserWindow.minimize).not.toHaveBeenCalled();
+      expect(baseWindow.minimize).not.toHaveBeenCalled();
     });
     test('with minimize, should minimize the window', () => {
       // Given
@@ -60,10 +60,10 @@ describe('Main :: Main window listeners test suite', () => {
         closeButtonBehavior: 'minimize'
       }));
       // When
-      browserWindow.listeners.close(event);
+      baseWindow.listeners.close(event);
       // Then
       expect(electron.app.exit).not.toHaveBeenCalled();
-      expect(browserWindow.minimize).toHaveBeenCalled();
+      expect(baseWindow.minimize).toHaveBeenCalled();
     });
   });
 });
diff --git a/src/settings/__tests__/index.test.js b/src/settings/__tests__/index.test.js
index b43ac1c..d632ae9 100644
--- a/src/settings/__tests__/index.test.js
+++ b/src/settings/__tests__/index.test.js
@@ -169,7 +169,7 @@ describe('Settings module test suite', () => {
     let mainWindow;
     let openSettings;
     beforeEach(() => {
-      mainWindow = electron.browserWindowInstance;
+      mainWindow = electron.baseWindowInstance;
       mainWindow.getContentBounds = jest.fn(() => ({width: 13, height: 37}));
       openSettings = settings.openSettingsDialog(mainWindow);
     });
@@ -177,9 +177,9 @@ describe('Settings module test suite', () => {
       // When
       openSettings();
       // Then
-      const BrowserView = require('electron').BrowserView;
-      expect(BrowserView).toHaveBeenCalledTimes(1);
-      expect(BrowserView).toHaveBeenCalledWith({
+      const WebContentsView = require('electron').WebContentsView;
+      expect(WebContentsView).toHaveBeenCalledTimes(1);
+      expect(WebContentsView).toHaveBeenCalledWith({
         webPreferences: expect.objectContaining({sandbox: true, nodeIntegration: false})
       });
     });
@@ -187,8 +187,8 @@ describe('Settings module test suite', () => {
       // When
       openSettings();
       // Then
-      expect(electron.browserViewInstance.webContents.loadURL).toHaveBeenCalledTimes(1);
-      expect(electron.browserViewInstance.webContents.loadURL)
+      expect(electron.webContentsViewInstance.webContents.loadURL).toHaveBeenCalledTimes(1);
+      expect(electron.webContentsViewInstance.webContents.loadURL)
         .toHaveBeenCalledWith(expect.stringMatching(/.+?\/index.html$/));
     });
   });
diff --git a/src/spell-check/__tests__/index.test.js b/src/spell-check/__tests__/index.test.js
index 92cf5ce..143bf74 100644
--- a/src/spell-check/__tests__/index.test.js
+++ b/src/spell-check/__tests__/index.test.js
@@ -14,25 +14,17 @@
    limitations under the License.
  */
 describe('Spell-check module test suite', () => {
-  let mockBrowserWindow;
-  let mockIpc;
+  let electron;
   let mockSettings;
   let spellCheck;
   beforeEach(() => {
     jest.resetModules();
-    mockBrowserWindow = require('../../__tests__').mockBrowserWindowInstance();
-    mockIpc = {
-      handle: jest.fn(),
-      removeHandler: jest.fn()
-    };
     mockSettings = {
       enabledDictionaries: []
     };
-    jest.mock('electron', () => ({
-      BrowserWindow: jest.fn(() => mockBrowserWindow),
-      ipcMain: mockIpc,
-      MenuItem: jest.fn(({label, click}) => ({label, click}))
-    }));
+    jest.mock('electron', () => require('../../__tests__').mockElectronInstance());
+    electron = require('electron');
+    electron.MenuItem = jest.fn(({label, click}) => ({label, click}));
     jest.mock('../../settings', () => ({
       loadSettings: jest.fn(() => mockSettings)
     }));
@@ -53,37 +45,37 @@ describe('Spell-check module test suite', () => {
       // When
       spellCheck.loadDictionaries();
       // Then
-      expect(mockBrowserWindow.destroy).toHaveBeenCalledTimes(1);
+      expect(electron.webContentsViewInstance.webContents.destroy).toHaveBeenCalledTimes(1);
     });
     test('should not destroy non-existing previous fakeRenderer', () => {
       // When
       spellCheck.loadDictionaries();
       // Then
-      expect(mockBrowserWindow.destroy).not.toHaveBeenCalled();
+      expect(electron.webContentsViewInstance.webContents.destroy).not.toHaveBeenCalled();
     });
     test('should remove and then add handler', () => {
       // When
       spellCheck.loadDictionaries();
       // Then
-      expect(mockIpc.handle).toHaveBeenCalledAfter(mockIpc.removeHandler);
+      expect(electron.ipcMain.handle).toHaveBeenCalledAfter(electron.ipcMain.removeHandler);
     });
     test('should remove dictionaryGetMisspelled handler', () => {
       // When
       spellCheck.loadDictionaries();
       // Then
-      expect(mockIpc.removeHandler).toHaveBeenCalledWith('dictionaryGetMisspelled');
+      expect(electron.ipcMain.removeHandler).toHaveBeenCalledWith('dictionaryGetMisspelled');
     });
     test('should handle dictionaryGetMisspelled', () => {
       // When
       spellCheck.loadDictionaries();
       // Then
-      expect(mockIpc.handle).toHaveBeenCalledWith('dictionaryGetMisspelled', expect.any(Function));
+      expect(electron.ipcMain.handle).toHaveBeenCalledWith('dictionaryGetMisspelled', expect.any(Function));
     });
     test('should load dictionary.renderer URL', () => {
       // When
       spellCheck.loadDictionaries();
       // Then
-      expect(mockBrowserWindow.loadURL)
+      expect(electron.webContentsViewInstance.webContents.loadURL)
         .toHaveBeenCalledWith(expect.stringMatching(/\/dictionary.renderer\/index.html$/));
     });
   });
@@ -92,8 +84,7 @@ describe('Spell-check module test suite', () => {
     let webContents;
     beforeEach(() => {
       params = {};
-      webContents = {};
-      mockBrowserWindow.webContents = webContents;
+      webContents = electron.webContentsViewInstance.webContents;
       spellCheck.loadDictionaries();
     });
     describe('contextMenuHandler', () => {
@@ -109,7 +100,7 @@ describe('Spell-check module test suite', () => {
         });
         test('and no suggestions, should return empty array', async () => {
           // Given
-          mockBrowserWindow.webContents.executeJavaScript = jest.fn(async () => []);
+          webContents.executeJavaScript = jest.fn(async () => []);
           // When
           const result = await spellCheck.contextMenuHandler({}, params, webContents);
           // Then
@@ -117,7 +108,7 @@ describe('Spell-check module test suite', () => {
         });
         test('and suggestions, should return array of MenuItems', async () => {
           // Given
-          mockBrowserWindow.webContents.executeJavaScript = jest.fn(async () => ['the-suggestion']);
+          webContents.executeJavaScript = jest.fn(async () => ['the-suggestion']);
           // When
           const result = await spellCheck.contextMenuHandler({}, params, webContents);
           // Then
diff --git a/src/tab-manager/__tests__/context-menu.test.js b/src/tab-manager/__tests__/context-menu.test.js
index 69e664e..b60c253 100644
--- a/src/tab-manager/__tests__/context-menu.test.js
+++ b/src/tab-manager/__tests__/context-menu.test.js
@@ -40,8 +40,8 @@ describe('Tab Manager context-menu test suite', () => {
     }));
     jest.mock('../../spell-check');
     electron = require('electron');
-    electron.browserViewInstance.webContents.canGoBack = jest.fn(() => false);
-    listeners = electron.browserViewInstance.listeners;
+    electron.webContentsViewInstance.webContents.canGoBack = jest.fn(() => false);
+    listeners = electron.webContentsViewInstance.listeners;
     event = new Event('');
     params = {x: 13, y: 37};
     tabManager = require('../');
@@ -62,7 +62,7 @@ describe('Tab Manager context-menu test suite', () => {
     });
     describe('with native spellcheck', () => {
       beforeEach(() => {
-        electron.browserViewInstance.webContents.session.spellcheck = true;
+        electron.webContentsViewInstance.webContents.session.spellcheck = true;
       });
       test('Spelling suggestions, should open a Menu with all suggestions', async () => {
         // Given
@@ -122,7 +122,7 @@ describe('Tab Manager context-menu test suite', () => {
         }));
       });
       test('enabled when canGoBack returns true', async () => {
-        electron.browserViewInstance.webContents.canGoBack = jest.fn(() => true);
+        electron.webContentsViewInstance.webContents.canGoBack = jest.fn(() => true);
         await listeners['context-menu'](event, params);
         expect(electron.MenuItem).toHaveBeenCalledWith(expect.objectContaining({
           enabled: false,
@@ -133,20 +133,20 @@ describe('Tab Manager context-menu test suite', () => {
         // When
         electron.MenuItem.mock.calls.filter(c => c[0].label === 'Back')[0][0].click();
         // Then
-        expect(electron.browserViewInstance.webContents.goBack).toHaveBeenCalledTimes(1);
+        expect(electron.webContentsViewInstance.webContents.goBack).toHaveBeenCalledTimes(1);
       });
     });
     test('Reload click, should trigger reload', async () => {
       // When
       electron.MenuItem.mock.calls.filter(c => c[0].label === 'Reload')[0][0].click();
       // Then
-      expect(electron.browserViewInstance.webContents.reload).toHaveBeenCalledTimes(1);
+      expect(electron.webContentsViewInstance.webContents.reload).toHaveBeenCalledTimes(1);
     });
     test('DevTools click, should open devtools', async () => {
       // When
       electron.MenuItem.mock.calls.filter(c => c[0].label === 'DevTools')[0][0].click();
       // Then
-      expect(electron.browserViewInstance.webContents.openDevTools).toHaveBeenCalledTimes(1);
+      expect(electron.webContentsViewInstance.webContents.openDevTools).toHaveBeenCalledTimes(1);
     });
     describe('Clipboard related', () => {
       describe('Cut', () => {
@@ -162,7 +162,7 @@ describe('Tab Manager context-menu test suite', () => {
           // When
           electron.MenuItem.mock.calls.filter(c => c[0].label === 'Cut')[0][0].click();
           // Then
-          expect(electron.browserViewInstance.webContents.cut).toHaveBeenCalledTimes(1);
+          expect(electron.webContentsViewInstance.webContents.cut).toHaveBeenCalledTimes(1);
         });
       });
       describe('Copy', () => {
@@ -178,7 +178,7 @@ describe('Tab Manager context-menu test suite', () => {
           // When
           electron.MenuItem.mock.calls.filter(c => c[0].label === 'Copy')[0][0].click();
           // Then
-          expect(electron.browserViewInstance.webContents.copy).toHaveBeenCalledTimes(1);
+          expect(electron.webContentsViewInstance.webContents.copy).toHaveBeenCalledTimes(1);
         });
       });
       describe('Copy image', () => {
@@ -194,7 +194,7 @@ describe('Tab Manager context-menu test suite', () => {
           // When
           electron.MenuItem.mock.calls.filter(c => c[0].label === 'Copy image')[0][0].click();
           // Then
-          expect(electron.browserViewInstance.webContents.copyImageAt).toHaveBeenCalledTimes(1);
+          expect(electron.webContentsViewInstance.webContents.copyImageAt).toHaveBeenCalledTimes(1);
         });
       });
     });
@@ -211,7 +211,7 @@ describe('Tab Manager context-menu test suite', () => {
         // When
         electron.MenuItem.mock.calls.filter(c => c[0].label === 'Paste')[0][0].click();
         // Then
-        expect(electron.browserViewInstance.webContents.paste).toHaveBeenCalledTimes(1);
+        expect(electron.webContentsViewInstance.webContents.paste).toHaveBeenCalledTimes(1);
       });
     });
   });
diff --git a/src/tab-manager/__tests__/index.test.js b/src/tab-manager/__tests__/index.test.js
index effeb02..2f6c834 100644
--- a/src/tab-manager/__tests__/index.test.js
+++ b/src/tab-manager/__tests__/index.test.js
@@ -15,14 +15,14 @@
  */
 /* eslint-disable no-console */
 describe('Tab Manager module test suite', () => {
-  let mockBrowserView;
+  let mockView;
   let userAgent;
   let tabManager;
   let mockSettings;
   beforeEach(() => {
     jest.resetModules();
     jest.mock('electron', () => require('../../__tests__').mockElectronInstance());
-    mockBrowserView = require('electron').browserViewInstance;
+    mockView = require('electron').webContentsViewInstance;
     mockSettings = {
       tabs: [{id: '1337', disableNotifications: false}],
       disableNotificationsGlobally: false
@@ -130,9 +130,9 @@ describe('Tab Manager module test suite', () => {
       // When
       tabManager.addTabs({send: jest.fn()})([{id: 1337, url: 'https://localhost'}]);
       // Then
-      const BrowserView = require('electron').BrowserView;
-      expect(BrowserView).toHaveBeenCalledTimes(1);
-      expect(BrowserView).toHaveBeenCalledWith({
+      const WebContentsView = require('electron').WebContentsView;
+      expect(WebContentsView).toHaveBeenCalledTimes(1);
+      expect(WebContentsView).toHaveBeenCalledWith({
         webPreferences: expect.objectContaining({sandbox: true, nodeIntegration: false})
       });
     });
@@ -141,7 +141,7 @@ describe('Tab Manager module test suite', () => {
       tabManager.addTabs({send: jest.fn()})([{id: 1337, url: 'https://localhost'}]);
       // Then
       expect(require('electron').session.fromPartition).not.toHaveBeenCalled();
-      expect(require('electron').BrowserView).toHaveBeenCalledWith({
+      expect(require('electron').WebContentsView).toHaveBeenCalledWith({
         webPreferences: expect.objectContaining({session: expect.anything()})});
     });
     test('sandboxed, should use isolated session', () => {
@@ -149,7 +149,7 @@ describe('Tab Manager module test suite', () => {
       tabManager.addTabs({send: jest.fn()})([{id: 1337, url: 'https://localhost', sandboxed: true}]);
       // Then
       expect(require('electron').session.fromPartition).toHaveBeenCalledTimes(1);
-      expect(require('electron').BrowserView).toHaveBeenCalledWith({
+      expect(require('electron').WebContentsView).toHaveBeenCalledWith({
         webPreferences: expect.objectContaining({session: expect.anything()})});
     });
     test('Tab webContents should be configured and loaded', () => {
@@ -158,9 +158,7 @@ describe('Tab Manager module test suite', () => {
       // When
       tabManager.addTabs(mockIpcSender)([{id: 1337, url: 'https://localhost'}]);
       // Then
-      expect(mockBrowserView.webContents.loadURL).toHaveBeenCalledWith('https://localhost');
-      expect(mockBrowserView.setAutoResize)
-        .toHaveBeenCalledWith({width: false, horizontal: false, height: false, vertical: false});
+      expect(mockView.webContents.loadURL).toHaveBeenCalledWith('https://localhost');
       expect(mockIpcSender.send).toHaveBeenCalledTimes(1);
       expect(mockIpcSender.send).toHaveBeenCalledWith('addTabs', [{id: 1337, url: 'https://localhost'}]);
     });
@@ -168,8 +166,8 @@ describe('Tab Manager module test suite', () => {
       // When
       tabManager.addTabs({send: jest.fn()})([{id: 1337, url: 'https://localhost'}]);
       // Then
-      expect(mockBrowserView.webContents.executeJavaScript).toHaveBeenCalledTimes(1);
-      expect(mockBrowserView.webContents.executeJavaScript).toHaveBeenCalledWith('window.tabId = \'1337\';');
+      expect(mockView.webContents.executeJavaScript).toHaveBeenCalledTimes(1);
+      expect(mockView.webContents.executeJavaScript).toHaveBeenCalledWith('window.tabId = \'1337\';');
     });
     describe('cleanUserAgent', () => {
       test('chromium version available, should remove non-standard tokens from user-agent header and set version', () => {
@@ -199,14 +197,14 @@ describe('Tab Manager module test suite', () => {
       });
       test('handlePageTitleUpdated, should send setTabTitle event', () => {
         // When
-        mockBrowserView.listeners['page-title-updated'](new Event(''), 'Dr.');
+        mockView.listeners['page-title-updated'](new Event(''), 'Dr.');
         // Then
         expect(mockIpcSender.send).toHaveBeenCalledWith('setTabTitle', {id: '1337', title: 'Dr.'});
       });
       describe('handlePageFaviconUpdated', () => {
         test('Favicons provided, should send setTabFavicon with the last of the provided favicons', () => {
           // When
-          mockBrowserView.listeners['page-favicon-updated'](new Event(''), [
+          mockView.listeners['page-favicon-updated'](new Event(''), [
             'http://url-to-favicon/aitana.png',
             'http://url-to-favicon/alex.png'
           ]);
@@ -216,14 +214,14 @@ describe('Tab Manager module test suite', () => {
         });
         test('No favicons provided, should send setTabFavicon with the last of the extracted favicons', async () => {
           // Given
-          mockBrowserView.webContents.executeJavaScript = jest.fn(arg => {
+          mockView.webContents.executeJavaScript = jest.fn(arg => {
             if (arg === 'Array.from(document.querySelectorAll(\'link[rel*="icon"]\')).map(el => el.href)') {
               return ['http://url-to-favicon/julia-128.png', 'http://url-to-favicon/julia.png'];
             }
             return [];
           });
           // When
-          await mockBrowserView.listeners['page-favicon-updated'](new Event(''));
+          await mockView.listeners['page-favicon-updated'](new Event(''));
           // Then
           expect(mockIpcSender.send)
             .toHaveBeenCalledWith('setTabFavicon', {id: '1337', favicon: 'http://url-to-favicon/julia.png'});
@@ -231,9 +229,9 @@ describe('Tab Manager module test suite', () => {
       });
       test('windowOpen (was new-window)', () => {
         // Given
-        mockBrowserView.webContents.getURL.mockReturnValue('file://tab/index.html');
+        mockView.webContents.getURL.mockReturnValue('file://tab/index.html');
         // When
-        mockBrowserView.webContents.setWindowOpenHandler.mock.calls[0][0]({url: 'https://example.com'});
+        mockView.webContents.setWindowOpenHandler.mock.calls[0][0]({url: 'https://example.com'});
         // Then
         expect(require('electron').shell.openExternal).toHaveBeenCalledWith('https://example.com');
       });
@@ -274,15 +272,15 @@ describe('Tab Manager module test suite', () => {
       // When
       tabManager.removeAll();
       // Then
-      expect(mockBrowserView.webContents.destroy).not.toHaveBeenCalled();
+      expect(mockView.webContents.destroy).not.toHaveBeenCalled();
     });
-    test('Existing tabs, should delete all tabs entries and destroy their BrowserView', () => {
+    test('Existing tabs, should delete all tabs entries and destroy their Views', () => {
       // Given
       tabManager.addTabs({send: jest.fn()})([{id: 1337, url: 'https://localhost'}]);
       // When
       tabManager.removeAll();
       // Then
-      expect(mockBrowserView.webContents.destroy).toHaveBeenCalledTimes(1);
+      expect(mockView.webContents.destroy).toHaveBeenCalledTimes(1);
     });
   });
   describe('canNotify', () => {
diff --git a/src/tab-manager/__tests__/redirect.test.js b/src/tab-manager/__tests__/redirect.test.js
index 48115de..f33ab31 100644
--- a/src/tab-manager/__tests__/redirect.test.js
+++ b/src/tab-manager/__tests__/redirect.test.js
@@ -15,22 +15,22 @@
  */
 describe('Tab Manager Redirect module test suite', () => {
   let redirect;
-  let mockBrowserView;
-  let mockBrowserViewUrl;
+  let mockView;
+  let mockViewUrl;
   beforeEach(() => {
-    mockBrowserViewUrl = 'http://localhost';
+    mockViewUrl = 'http://localhost';
     jest.mock('electron', () => require('../../__tests__').mockElectronInstance());
-    mockBrowserView = require('electron').browserViewInstance;
-    mockBrowserView.webContents.getURL.mockImplementation(() => mockBrowserViewUrl);
+    mockView = require('electron').webContentsViewInstance;
+    mockView.webContents.getURL.mockImplementation(() => mockViewUrl);
     redirect = require('../redirect');
   });
   describe('shouldOpenInExternalBrowser', () => {
     describe('External Navigation', () => {
       test('From Slack to external URL, should return true', () => {
         // Given
-        mockBrowserViewUrl = 'https://aitana.slack.com';
+        mockViewUrl = 'https://aitana.slack.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://www.external.url.com'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://www.external.url.com'));
         // Then
         expect(result).toBe(true);
       });
@@ -40,24 +40,24 @@ describe('Tab Manager Redirect module test suite', () => {
       'https://files.slack.com/files-pri/ID123/download/image.png?origin_team=ID456'
     ])('URLs handled internally -isHandledInternally- (%s) , should return false', url => {
       // When
-      const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL(url));
+      const result = redirect.shouldOpenInExternalBrowser(mockView, new URL(url));
       // Then
       expect(result).toBe(false);
     });
     describe('Google OAuth', () => {
       test('From OAuth to Slack, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://acc.google.com/signin/oauth/?redirect=https://slack.com';
+        mockViewUrl = 'https://acc.google.com/signin/oauth/?redirect=https://slack.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://aitana.slack.com'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://aitana.slack.com'));
         // Then
         expect(result).toBe(false);
       });
       test('From Slack to OAuth, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://aitana.slack.com';
+        mockViewUrl = 'https://aitana.slack.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://accounts.google.com/o/oauth2/auth'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://accounts.google.com/o/oauth2/auth'));
         // Then
         expect(result).toBe(false);
       });
@@ -65,17 +65,17 @@ describe('Tab Manager Redirect module test suite', () => {
     describe('GitHub OAuth', () => {
       test('From OAuth to Slack, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://github.com/login/oauth';
+        mockViewUrl = 'https://github.com/login/oauth';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://aitana.slack.com'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://aitana.slack.com'));
         // Then
         expect(result).toBe(false);
       });
       test('From Slack to OAuth, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://aitana.slack.com';
+        mockViewUrl = 'https://aitana.slack.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://github.com/login/oauth'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://github.com/login/oauth'));
         // Then
         expect(result).toBe(false);
       });
@@ -84,17 +84,17 @@ describe('Tab Manager Redirect module test suite', () => {
       describe('godaddy.com', () => {
         test('From OAuth to Slack, should return false', () => {
           // Given
-          mockBrowserViewUrl = 'https://sso.godaddy.com/';
+          mockViewUrl = 'https://sso.godaddy.com/';
           // When
-          const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://a-and-a.slack.com'));
+          const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://a-and-a.slack.com'));
           // Then
           expect(result).toBe(false);
         });
         test('From Slack to OAuth, should return false', () => {
           // Given
-          mockBrowserViewUrl = 'https://a-and-a.slack.com';
+          mockViewUrl = 'https://a-and-a.slack.com';
           // When
-          const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://sso.godaddy.com'));
+          const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://sso.godaddy.com'));
           // Then
           expect(result).toBe(false);
         });
@@ -102,17 +102,17 @@ describe('Tab Manager Redirect module test suite', () => {
       describe('secureserver.net', () => {
         test('From OAuth to Slack, should return false', () => {
           // Given
-          mockBrowserViewUrl = 'https://sso.secureserver.net/';
+          mockViewUrl = 'https://sso.secureserver.net/';
           // When
-          const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://julia.slack.com'));
+          const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://julia.slack.com'));
           // Then
           expect(result).toBe(false);
         });
         test('From Slack to OAuth, should return false', () => {
           // Given
-          mockBrowserViewUrl = 'https://julia.slack.com';
+          mockViewUrl = 'https://julia.slack.com';
           // When
-          const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://sso.secureserver.net/'));
+          const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://sso.secureserver.net/'));
           // Then
           expect(result).toBe(false);
         });
@@ -121,9 +121,9 @@ describe('Tab Manager Redirect module test suite', () => {
     describe('OpenAI OAuth', () => {
       test.each(['auth0', 'auth'])('From Slack to OAuth (%s), should return false', subdomain => {
         // Given
-        mockBrowserViewUrl = 'https://alberto.slack.com';
+        mockViewUrl = 'https://alberto.slack.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView,
+        const result = redirect.shouldOpenInExternalBrowser(mockView,
           new URL(`https://${subdomain}.openai.com/u/login/identifier?state=1337`));
         // Then
         expect(result).toBe(false);
@@ -132,9 +132,9 @@ describe('Tab Manager Redirect module test suite', () => {
     describe('Red Hat OAuth', () => {
       test('From Slack to OAuth, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://alex.slack.com';
+        mockViewUrl = 'https://alex.slack.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView,
+        const result = redirect.shouldOpenInExternalBrowser(mockView,
           new URL('https://auth.redhat.com/auth/realms/EmployeeIDP/login-actions/authenticate?execution=1337'));
         // Then
         expect(result).toBe(false);
@@ -143,18 +143,18 @@ describe('Tab Manager Redirect module test suite', () => {
     describe('Skype OAuth', () => {
       test('From Skype to OAuth, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://web.skype.com';
+        mockViewUrl = 'https://web.skype.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView,
+        const result = redirect.shouldOpenInExternalBrowser(mockView,
           new URL('https://login.skype.com/login/oauth/microsoft?client_id=313373'));
         // Then
         expect(result).toBe(false);
       });
       test('From Skype OAuth to Microsoft, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://web.skype.com';
+        mockViewUrl = 'https://web.skype.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView,
+        const result = redirect.shouldOpenInExternalBrowser(mockView,
           new URL('https://login.live.com/login.srf?wa=wsignin1.0&rpsnv=13&ct=1610780563'));
         // Then
         expect(result).toBe(false);
@@ -163,18 +163,18 @@ describe('Tab Manager Redirect module test suite', () => {
     describe('Teams OAuth', () => {
       test('From Teams to Microsoft Online, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://teams.microsoft.com';
+        mockViewUrl = 'https://teams.microsoft.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView,
+        const result = redirect.shouldOpenInExternalBrowser(mockView,
           new URL('https://login.microsoftonline.com/common/oauth2/authorize?response_type=id_token'));
         // Then
         expect(result).toBe(false);
       });
       test('From Teams to Microsoft Login, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://teams.microsoft.com';
+        mockViewUrl = 'https://teams.microsoft.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView,
+        const result = redirect.shouldOpenInExternalBrowser(mockView,
           new URL('https://login.live.com/Me.htm?v=3'));
         // Then
         expect(result).toBe(false);
@@ -183,25 +183,25 @@ describe('Tab Manager Redirect module test suite', () => {
     describe('Twitter login', () => {
       test('From Tweet Deck to Twitter, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://tweetdeck.twitter.com';
+        mockViewUrl = 'https://tweetdeck.twitter.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://mobile.twitter.com/login?hide_message=true&redirect_after_login=https%3A%2F%2Ftweetdeck.twitter.com%2F%3Fvia_twitter_login%3Dtrue'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://mobile.twitter.com/login?hide_message=true&redirect_after_login=https%3A%2F%2Ftweetdeck.twitter.com%2F%3Fvia_twitter_login%3Dtrue'));
         // Then
         expect(result).toBe(false);
       });
       test('From Twitter to Tweet Deck , should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://mobile.twitter.com/login';
+        mockViewUrl = 'https://mobile.twitter.com/login';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://tweetdeck.twitter.com?via_twitter_login=true'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://tweetdeck.twitter.com?via_twitter_login=true'));
         // Then
         expect(result).toBe(false);
       });
       test('From Tweet Deck to logout, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://tweetdeck.twitter.com';
+        mockViewUrl = 'https://tweetdeck.twitter.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://mobile.twitter.com/logout'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://mobile.twitter.com/logout'));
         // Then
         expect(result).toBe(false);
       });
@@ -209,17 +209,17 @@ describe('Tab Manager Redirect module test suite', () => {
     describe('Zoho login', () => {
       test('From Zoho mail to login, should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://mail.zoho.com';
+        mockViewUrl = 'https://mail.zoho.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://accounts.zoho.com/signin?servicename&serviceurl=https://mail.zoho.com'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://accounts.zoho.com/signin?servicename&serviceurl=https://mail.zoho.com'));
         // Then
         expect(result).toBe(false);
       });
       test('From Zoho mail to login (eu), should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://mail.zoho.com';
+        mockViewUrl = 'https://mail.zoho.com';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://accounts.zoho.eu/signin?servicename&serviceurl=https://mail.zoho.eu'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://accounts.zoho.eu/signin?servicename&serviceurl=https://mail.zoho.eu'));
         // Then
         expect(result).toBe(false);
       });
@@ -227,17 +227,17 @@ describe('Tab Manager Redirect module test suite', () => {
     describe('Zoom login', () => {
       test('From Zoom home to login (profile), should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://zoom.us/signin';
+        mockViewUrl = 'https://zoom.us/signin';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://us04web.zoom.us/profile'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://us04web.zoom.us/profile'));
         // Then
         expect(result).toBe(false);
       });
       test('From Zoom home to one time password (OTP), should return false', () => {
         // Given
-        mockBrowserViewUrl = 'https://zoom.us/signin';
+        mockViewUrl = 'https://zoom.us/signin';
         // When
-        const result = redirect.shouldOpenInExternalBrowser(mockBrowserView, new URL('https://us04web.zoom.us/signin/otp/verify_help'));
+        const result = redirect.shouldOpenInExternalBrowser(mockView, new URL('https://us04web.zoom.us/signin/otp/verify_help'));
         // Then
         expect(result).toBe(false);
       });
@@ -250,7 +250,7 @@ describe('Tab Manager Redirect module test suite', () => {
     });
     describe('different origin and not handled', () => {
       beforeEach(() => {
-        redirect.handleRedirect(mockBrowserView)(event, 'https://example.com/site-page');
+        redirect.handleRedirect(mockView)(event, 'https://example.com/site-page');
       });
       test('should prevent default', () => {
         expect(event.preventDefault).toHaveBeenCalled();
@@ -261,7 +261,7 @@ describe('Tab Manager Redirect module test suite', () => {
     });
     describe('different origin, not handled, and invalid protocol', () => {
       beforeEach(() => {
-        redirect.handleRedirect(mockBrowserView)(event, 'smb://example.com/share');
+        redirect.handleRedirect(mockView)(event, 'smb://example.com/share');
       });
       test('should prevent default', () => {
         expect(event.preventDefault).toHaveBeenCalled();
@@ -274,25 +274,25 @@ describe('Tab Manager Redirect module test suite', () => {
   describe('windowOpenHandler', () => {
     test('same origin, opens window in Electron popup', () => {
       // When
-      const result = redirect.windowOpenHandler(mockBrowserView)({url: 'http://localhost/terms-and-conditions'});
+      const result = redirect.windowOpenHandler(mockView)({url: 'http://localhost/terms-and-conditions'});
       // Then
       expect(result).toEqual({action: 'allow'});
     });
     test('handled oauth, opens window in Electron popup', () => {
       // When
-      const result = redirect.windowOpenHandler(mockBrowserView)({url: 'https://accounts.google.com/o/oauth2/auth'});
+      const result = redirect.windowOpenHandler(mockView)({url: 'https://accounts.google.com/o/oauth2/auth'});
       // Then
       expect(result).toEqual({action: 'allow'});
     });
     test('handled internally, opens window in Electron popup', () => {
       // When
-      const result = redirect.windowOpenHandler(mockBrowserView)({url: 'https://files.slack.com/files-pri/ID123/download/image.png?origin_team=ID456'});
+      const result = redirect.windowOpenHandler(mockView)({url: 'https://files.slack.com/files-pri/ID123/download/image.png?origin_team=ID456'});
       // Then
       expect(result).toEqual({action: 'allow'});
     });
     test('different origin and not handled, opens window in external browser', () => {
       // When
-      const result = redirect.windowOpenHandler(mockBrowserView)({url: 'https://example.com/site-page'});
+      const result = redirect.windowOpenHandler(mockView)({url: 'https://example.com/site-page'});
       // Then
       expect(require('electron').shell.openExternal).toHaveBeenCalledWith('https://example.com/site-page');
       expect(result).toEqual({action: 'deny'});