Repository: electron/fiddle
Pull request #606 (2021-03-16 17:42:38)

fix: setupBinary() resolves when download completes
Right now there is an edge case where setupBinary() can resolve before a download is done: if called while a download for that version is already running, setupBinary() returns to avoid parallel downloads. Because of this return, the caller may find their RunnableVersion does not have the state that was expected.
    
This PR keeps track of pending downloads so that when a duplicate call occurs, all callers get a Promise that settles when the download does.
    
This is similar to how renderer/content [safeguards against parallel downloads](https://github.com/electron/fiddle/blob/858e4b1834832e0ea5ccf64825c2bd7d201a8a2b/src/renderer/content.ts#L57) of the same zipfile.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/37986685/badge)](https://coveralls.io/builds/37986685)

Coverage increased (+0.02%) to 93.18% when pulling **90cc9c03c81b849910dac70385a056581a2759c0 on fix/setup-binary** into **858e4b1834832e0ea5ccf64825c2bd7d201a8a2b on master**.


Patch:
diff --git a/src/renderer/binary.ts b/src/renderer/binary.ts
index 08e1a534..6d7b875d 100644
--- a/src/renderer/binary.ts
+++ b/src/renderer/binary.ts
@@ -9,6 +9,8 @@ import { USER_DATA_PATH } from './constants';
 import { removeTypeDefsForVersion } from './fetch-types';
 import { AppState } from './state';
 
+const pendingDownloads: Record<string, Promise<void>> = {};
+
 /**
  * General setup, called with a version. Is called during construction
  * to ensure that we always have or download at least one version.
@@ -21,23 +23,29 @@ export async function setupBinary(
   iVersion: string,
 ): Promise<void> {
   const version = normalizeVersion(iVersion);
-  const fs = await fancyImport<typeof fsType>('fs-extra');
-
-  await fs.mkdirp(getDownloadPath(version));
-
-  const { state } = appState.versions[version];
-  if (state === VersionState.downloading || state === VersionState.unzipping) {
-    console.log(`Binary: Electron ${version} already downloading.`);
-    return;
-  }
 
+  // If we already have it, then we're done
   if (await getIsDownloaded(version)) {
     console.log(`Binary: Electron ${version} already downloaded.`);
     appState.versions[version].state = VersionState.ready;
     return;
   }
 
-  console.log(`Binary: Electron ${version} not present, downloading`);
+  // Return a promise that resolves when the download completes
+  let pending = pendingDownloads[version];
+  if (pending) {
+    console.log(`Binary: Electron ${version} already downloading.`);
+  } else {
+    console.log(`Binary: Electron ${version} not present, downloading`);
+    pending = pendingDownloads[version] = downloadBinary(appState, version);
+  }
+  return pending;
+}
+
+async function downloadBinary(
+  appState: AppState,
+  version: string,
+): Promise<void> {
   appState.versions[version].state = VersionState.downloading;
 
   const zipPath = await download(appState, version);
@@ -49,19 +57,23 @@ export async function setupBinary(
   try {
     appState.versions[version].state = VersionState.unzipping;
 
+    // Ensure the target path exists
+    const fs = await fancyImport<typeof fsType>('fs-extra');
+    await fs.mkdirp(extractPath);
+
     // Ensure the target path is empty
     await fs.emptyDir(extractPath);
 
     const electronFiles = await unzip(zipPath, extractPath);
-    console.log(`Unzipped ${version}`, electronFiles);
+    console.log(`Binary: Unzipped ${version}`, electronFiles);
+    appState.versions[version].state = VersionState.ready;
   } catch (error) {
-    console.warn(`Failure while unzipping ${version}`, error);
+    console.warn(`Binary: Failure while unzipping ${version}`, error);
     appState.versions[version].state = VersionState.unknown;
-
-    return;
+  } finally {
+    // This task is done, so remove it from the pending tasks list
+    delete pendingDownloads[version];
   }
-
-  appState.versions[version].state = VersionState.ready;
 }
 
 /**
diff --git a/src/renderer/components/editors.tsx b/src/renderer/components/editors.tsx
index 7f98b27d..3de9173c 100644
--- a/src/renderer/components/editors.tsx
+++ b/src/renderer/components/editors.tsx
@@ -28,7 +28,6 @@ import {
   MaximizeButton,
   RemoveButton,
 } from './editors-toolbar-button';
-import { ShowMe } from './show-me';
 
 const defaultMonacoOptions: MonacoType.editor.IEditorOptions = {
   minimap: {
@@ -72,7 +71,6 @@ export class Editors extends React.Component<EditorsProps, EditorsState> {
     this.onChange = this.onChange.bind(this);
     this.renderEditor = this.renderEditor.bind(this);
     this.renderTile = this.renderTile.bind(this);
-    this.renderGenericPanel = this.renderGenericPanel.bind(this);
     this.setFocused = this.setFocused.bind(this);
 
     this.state = { monacoOptions: defaultMonacoOptions };
@@ -233,10 +231,7 @@ export class Editors extends React.Component<EditorsProps, EditorsState> {
    * @returns {JSX.Element | null}
    */
   public renderTile(id: MosaicId, path: Array<MosaicBranch>): JSX.Element {
-    const { appState } = this.props;
-    const content = isEditorId(id)
-      ? this.renderEditor(id)
-      : this.renderGenericPanel(id, appState);
+    const content = isEditorId(id) && this.renderEditor(id);
 
     return (
       <MosaicWindow<EditorId>
@@ -252,17 +247,6 @@ export class Editors extends React.Component<EditorsProps, EditorsState> {
     );
   }
 
-  /**
-   * Renders a generic panel – so not an editor, but something else
-   *
-   * @param {PanelId} _id
-   * @param {AppState} _appState
-   * @returns {JSX.Element}
-   */
-  public renderGenericPanel(_id: PanelId, appState: AppState): JSX.Element {
-    return <ShowMe appState={appState} />;
-  }
-
   /**
    * Render an editor
    *
diff --git a/src/renderer/components/show-me.tsx b/src/renderer/components/show-me.tsx
deleted file mode 100644
index b52079d0..00000000
--- a/src/renderer/components/show-me.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { observer } from 'mobx-react';
-import * as React from 'react';
-
-import { AppState } from '../state';
-import { DOCS_DEMO_COMPONENTS } from './show-me/index';
-
-export interface ShowMeProps {
-  appState: AppState;
-}
-
-/**3
- * The root component for "show me" content - the fourth helpful
- * panel.
- *
- * @class ShowMe
- * @extends {React.Component<ShowMeProps>}
- */
-@observer
-export class ShowMe extends React.Component<ShowMeProps> {
-  public render() {
-    const { currentDocsDemoPage: showMeName } = this.props.appState;
-    const Content =
-      DOCS_DEMO_COMPONENTS[showMeName] || DOCS_DEMO_COMPONENTS.DEFAULT;
-
-    return (
-      <div className="show-me-panel">
-        <Content appState={this.props.appState} />
-      </div>
-    );
-  }
-}
diff --git a/src/renderer/components/show-me/app.tsx b/src/renderer/components/show-me/app.tsx
deleted file mode 100644
index ca64a73f..00000000
--- a/src/renderer/components/show-me/app.tsx
+++ /dev/null
@@ -1,141 +0,0 @@
-import * as React from 'react';
-
-import { Button, Callout, Icon } from '@blueprintjs/core';
-import { remote } from 'electron';
-
-import { renderMoreDocumentation } from './more-information';
-import { getSubsetOnly } from './subset-only';
-
-/**
- * Show and hide button examples, only rendered on macOS
- *
- * @returns {JSX.Element | null}
- */
-function ShowHide() {
-  if (process.platform !== 'darwin') return null;
-
-  const onClick = () => {
-    remote.app.hide();
-    setTimeout(() => {
-      remote.app.show();
-      remote.app.focus();
-    }, 1500);
-  };
-
-  return (
-    <>
-      <p>
-        This button hides Electron Fiddle right away, showing it again in two
-        seconds.
-      </p>
-      <Button
-        id="show-hide"
-        icon="eye-off"
-        text="Hide Electron Fiddle"
-        onClick={onClick}
-      />
-    </>
-  );
-}
-export function ShowMeApp(): JSX.Element {
-  const [secondsLeft, setSeconds] = React.useState(-1);
-
-  const playFocus = () => {
-    setSeconds(3);
-    setTimeout(() => setSeconds(2), 1000);
-    setTimeout(() => setSeconds(1), 2000);
-    setTimeout(() => {
-      remote.app.focus();
-      setSeconds(-1);
-    }, 3000);
-  };
-
-  const [paths, setPaths] = React.useState('');
-  const playPaths = () => {
-    const pathsToQuery = [
-      'home',
-      'appData',
-      'userData',
-      'temp',
-      'downloads',
-      'desktop',
-    ];
-
-    let result = '';
-    pathsToQuery.forEach((item) => {
-      result += `${item}: ${remote.app.getPath(item as any)}\n`;
-    });
-
-    setPaths(result);
-  };
-
-  const [metrics, setMetrics] = React.useState('');
-  const playMetrics = () => {
-    setMetrics(JSON.stringify(remote.app.getAppMetrics(), undefined, 2));
-  };
-
-  return (
-    <>
-      <Icon
-        icon="help"
-        iconSize={40}
-        style={{ float: 'left', margin: '0 10px 0 0' }}
-      />
-      <p className="bp3r-running-text">
-        The <code>app</code> module controls the app&apos;s application
-        life-cycle. Most of the events and methods available on this module are
-        responsible for handling how your interacts with the operating system or
-        to set application-wide settings.
-      </p>
-      <h3>API Demos</h3>
-      {getSubsetOnly('app')}
-      <Callout title="Hiding, Showing, Focussing" icon="eye-open">
-        <p>
-          The app can ask the operating system for window focus. On macOS, it
-          can additionally request that the app be hidden or shown. Give it a
-          try: Click on the button below, focus another app, and wait for two
-          seconds to see Electron Fiddle become the focused app again.
-        </p>
-        <Button
-          id="focus"
-          icon="lightbulb"
-          text={`Focus Electron Fiddle${
-            secondsLeft > 0 ? ` in ${secondsLeft}s` : ''
-          }`}
-          onClick={playFocus}
-        />
-        <ShowHide />
-      </Callout>
-      <Callout title="Paths" icon="folder-open">
-        <p>
-          Need to query information about various paths in a cross-platform
-          manner? Electron can help. The button queries the operating system for
-          some of them.
-        </p>
-        <Button
-          id="special-paths"
-          icon="play"
-          text={`Get special directory paths`}
-          onClick={playPaths}
-        />
-        <pre id="special-paths-content">{paths}</pre>
-      </Callout>
-      <Callout title="Process & Device Information" icon="pulse">
-        <p>
-          Need to query information about the process or system? The{' '}
-          <code>app</code> module lets developers query for information about
-          the running app, hardware, and operating system. A good example are
-          process metrics.
-        </p>
-        <Button
-          id="process-metrics"
-          icon="play"
-          text={`Get process metrics`}
-          onClick={playMetrics}
-        />
-        <pre id="process-metrics-content">{metrics}</pre>
-      </Callout>
-      {renderMoreDocumentation()}
-    </>
-  );
-}
diff --git a/src/renderer/components/show-me/default.tsx b/src/renderer/components/show-me/default.tsx
deleted file mode 100644
index 0f0c8a87..00000000
--- a/src/renderer/components/show-me/default.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Button, Icon } from '@blueprintjs/core';
-import * as React from 'react';
-
-import { DocsDemoPage } from '../../../interfaces';
-import { AppState } from '../../state';
-import { DOCS_DEMO_COMPONENTS, DOCS_DEMO_NAMES } from './index';
-import { renderMoreDocumentation } from './more-information';
-
-export function ShowMeDefault(props: { appState: AppState }): JSX.Element {
-  const showMeMenu: Array<JSX.Element> = Object.keys(DOCS_DEMO_COMPONENTS)
-    .filter((key) => key !== DocsDemoPage.DEFAULT)
-    .map((key) => {
-      return (
-        <li key={key}>
-          <Button
-            minimal={true}
-            icon="play"
-            text={DOCS_DEMO_NAMES[key]}
-            onClick={() =>
-              (props.appState.currentDocsDemoPage = key as DocsDemoPage)
-            }
-          />
-        </li>
-      );
-    });
-
-  return (
-    <>
-      <Icon
-        icon="help"
-        iconSize={40}
-        style={{ float: 'left', margin: '0 10px 0 0' }}
-      />
-      <p className="bp3r-running-text">
-        This panel offers useful information about Electron APIs – and easy way
-        to try some of the methods it offers. Fiddle has an example fiddle for
-        every module available in Electron.
-      </p>
-      <p>
-        Clicking on any of the modules below will open up a fiddle showcasing
-        that particular module.
-      </p>
-      <ul className="show-me-list">{...showMeMenu}</ul>
-      {renderMoreDocumentation()}
-    </>
-  );
-}
diff --git a/src/renderer/components/show-me/index.tsx b/src/renderer/components/show-me/index.tsx
deleted file mode 100644
index d51e4494..00000000
--- a/src/renderer/components/show-me/index.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { DocsDemoPage } from '../../../interfaces';
-
-import { ShowMeApp } from './app';
-import { ShowMeDefault } from './default';
-
-export const DOCS_DEMO_COMPONENTS: Record<DocsDemoPage, any> = {
-  DEFAULT: ShowMeDefault,
-  DEMO_APP: ShowMeApp,
-};
-
-export const DOCS_DEMO_NAMES: Record<DocsDemoPage, string> = {
-  DEFAULT: 'Home',
-  DEMO_APP: 'App Demos',
-};
diff --git a/src/renderer/components/show-me/more-information.tsx b/src/renderer/components/show-me/more-information.tsx
deleted file mode 100644
index 31b10c1d..00000000
--- a/src/renderer/components/show-me/more-information.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import * as React from 'react';
-
-import { shell } from 'electron';
-
-/**
- * Renders a "more documentation" block, typically used at the end of a "show me" documentation piece.
- *
- * @export
- * @param {string} [url='electronjs.org/docs']
- * @returns {JSX.Element}
- */
-export function renderMoreDocumentation(
-  url = 'electronjs.org/docs',
-): JSX.Element {
-  const fullUrl = `https://${url}`;
-  const gitHubUrl = `https://github.com/electron/fiddle`;
-
-  return (
-    <>
-      <br />
-      <p className="b3-running-text">
-        For more documentation, visit{' '}
-        <a id="open-url" onClick={() => shell.openExternal(fullUrl)}>
-          {url}
-        </a>
-        , where you can find the full documentation for Electron.
-      </p>
-      <p className="bp3-text-muted">
-        By the way, Electron Fiddle and the documentation you see here is
-        entirely open source. If you have ideas on how to improve it, we&apos;d
-        love to have your contributions! You can find the repository on{' '}
-        <a id="open-github" onClick={() => shell.openExternal(gitHubUrl)}>
-          GitHub
-        </a>
-        .
-      </p>
-    </>
-  );
-}
diff --git a/src/renderer/components/show-me/subset-only.tsx b/src/renderer/components/show-me/subset-only.tsx
deleted file mode 100644
index a50d8a56..00000000
--- a/src/renderer/components/show-me/subset-only.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import * as React from 'react';
-
-import { shell } from 'electron';
-
-import { getDocsUrlForModule } from '../../../utils/docs-urls';
-
-/**
- * Returns a common string we use as a disclaimer to explain that this set of demos
- * is only meant to be a short demonstration, not displaying all of the modules
- * abilities.
- *
- * @export
- * @param {string} moduleName
- * @returns {JSX.Element}
- */
-export function getSubsetOnly(moduleName: string): JSX.Element {
-  const { full, short } = getDocsUrlForModule(moduleName);
-
-  return (
-    <p className="bp3-running-text">
-      The following demos display only a subset of what the{' '}
-      <code>{moduleName}</code>
-      module is capable of. If you want to see its full abilities, check out the
-      documentation on{' '}
-      <a id="open-url" onClick={() => shell.openExternal(full)}>
-        {short}
-      </a>
-      .
-    </p>
-  );
-}
diff --git a/src/renderer/remote-loader.ts b/src/renderer/remote-loader.ts
index e1c779dc..d61a8c68 100644
--- a/src/renderer/remote-loader.ts
+++ b/src/renderer/remote-loader.ts
@@ -7,6 +7,7 @@ import {
   PRELOAD_JS_NAME,
   RENDERER_JS_NAME,
   STYLES_CSS_NAME,
+  FILENAME_KEYS,
 } from '../shared-constants';
 import { getOctokit } from '../utils/octokit';
 import { sortedElectronMap } from '../utils/sorted-electron-map';
@@ -71,72 +72,29 @@ export class RemoteLoader {
 
       const values = await getTemplate(this.appState.version);
 
-      const loaders: Array<Promise<void>> = [];
       if (!Array.isArray(folder.data)) {
         throw new Error(
           'The example Fiddle tried to launch is not a valid Electron example',
         );
       }
 
+      const loaders: Array<Promise<void>> = [];
+
       for (const child of folder.data) {
         if (!child.download_url) {
           console.warn(`Could not find download_url for ${child.name}`);
           continue;
         }
 
-        switch (child.name) {
-          case MAIN_JS_NAME:
-            loaders.push(
-              fetch(child.download_url)
-                .then((r) => r.text())
-                .then((t) => {
-                  values.main = t;
-                }),
-            );
-
-            break;
-          case INDEX_HTML_NAME:
-            loaders.push(
-              fetch(child.download_url)
-                .then((r) => r.text())
-                .then((t) => {
-                  values.html = t;
-                }),
-            );
-
-            break;
-          case RENDERER_JS_NAME:
-            loaders.push(
-              fetch(child.download_url)
-                .then((r) => r.text())
-                .then((t) => {
-                  values.renderer = t;
-                }),
-            );
-
-            break;
-
-          case PRELOAD_JS_NAME:
-            loaders.push(
-              fetch(child.download_url)
-                .then((r) => r.text())
-                .then((t) => {
-                  values.preload = t;
-                }),
-            );
-
-          case STYLES_CSS_NAME:
-            loaders.push(
-              fetch(child.download_url)
-                .then((r) => r.text())
-                .then((t) => {
-                  values.css = t;
-                }),
-            );
-
-            break;
-          default:
-            break;
+        const valueKey = FILENAME_KEYS[child.name];
+        if (valueKey) {
+          loaders.push(
+            fetch(child.download_url)
+              .then((r) => r.text())
+              .then((t) => {
+                values[valueKey] = t;
+              }),
+          );
         }
       }
 
diff --git a/src/renderer/runner.ts b/src/renderer/runner.ts
index 1d0b7b53..6d616349 100644
--- a/src/renderer/runner.ts
+++ b/src/renderer/runner.ts
@@ -317,7 +317,7 @@ export class Runner {
     }
 
     const name = await this.appState.getName();
-    const appData = path.join(this.appState.appData, name);
+    const appData = path.join(window.ElectronFiddle.appPaths.appData, name);
 
     console.log(`Cleanup: Deleting data dir ${appData}`);
     await window.ElectronFiddle.app.fileManager.cleanup(appData);
diff --git a/src/renderer/state.ts b/src/renderer/state.ts
index ac4cc432..971a7ef0 100644
--- a/src/renderer/state.ts
+++ b/src/renderer/state.ts
@@ -206,9 +206,6 @@ export class AppState {
       this.toggleBisectCommands,
     );
     ipcRendererManager.on(IpcEvents.BEFORE_QUIT, this.setIsQuitting);
-    ipcRendererManager.once(IpcEvents.GET_APP_PATHS, (_event, dir) => {
-      this.appData = dir;
-    });
 
     // Setup auto-runs
     autorun(() => this.save('theme', this.theme));
diff --git a/src/shared-constants.ts b/src/shared-constants.ts
index 3c051f5f..2181d0f0 100644
--- a/src/shared-constants.ts
+++ b/src/shared-constants.ts
@@ -4,3 +4,11 @@ export const RENDERER_JS_NAME = 'renderer.js';
 export const PRELOAD_JS_NAME = 'preload.js';
 export const STYLES_CSS_NAME = 'styles.css';
 export const PACKAGE_NAME = 'package.json';
+
+export const FILENAME_KEYS = Object.freeze({
+  [INDEX_HTML_NAME]: 'html',
+  [MAIN_JS_NAME]: 'main',
+  [PRELOAD_JS_NAME]: 'preload',
+  [RENDERER_JS_NAME]: 'renderer',
+  [STYLES_CSS_NAME]: 'css',
+});
diff --git a/src/utils/read-fiddle.ts b/src/utils/read-fiddle.ts
index bd5f7f49..eb6aa053 100644
--- a/src/utils/read-fiddle.ts
+++ b/src/utils/read-fiddle.ts
@@ -1,24 +1,10 @@
 import { EditorValues } from '../interfaces';
-import {
-  INDEX_HTML_NAME,
-  MAIN_JS_NAME,
-  PRELOAD_JS_NAME,
-  RENDERER_JS_NAME,
-  STYLES_CSS_NAME,
-} from '../shared-constants';
+import { FILENAME_KEYS } from '../shared-constants';
 import { fancyImport } from './import';
 
 import * as fsType from 'fs-extra';
 import * as path from 'path';
 
-const FILENAME_KEYS = Object.freeze({
-  [INDEX_HTML_NAME]: 'html',
-  [MAIN_JS_NAME]: 'main',
-  [PRELOAD_JS_NAME]: 'preload',
-  [RENDERER_JS_NAME]: 'renderer',
-  [STYLES_CSS_NAME]: 'css',
-});
-
 /**
  * Reads a Fiddle from a directory.
  *


Test patch:
diff --git a/tests/renderer/binary-spec.ts b/tests/renderer/binary-spec.ts
index 36b34b88..7b666367 100644
--- a/tests/renderer/binary-spec.ts
+++ b/tests/renderer/binary-spec.ts
@@ -192,7 +192,7 @@ describe('binary', () => {
       expect(mockState.versions['3.0.0'].state).toBe('ready');
     });
 
-    it(`does not download a version while already downloading`, async () => {
+    it(`waits if asked for a version is already downloading`, async () => {
       const fs = require('fs-extra');
       const { download } = require('@electron/get');
 
@@ -202,7 +202,7 @@ describe('binary', () => {
       await setupBinary(mockState, 'v3.0.0');
 
       expect(download).toHaveBeenCalledTimes(0);
-      expect(mockState.versions['3.0.0'].state).toBe('downloading');
+      expect(mockState.versions['3.0.0'].state).toBe('ready');
     });
 
     it('handles an error in the zip file', async () => {
diff --git a/tests/renderer/components/__snapshots__/editors-spec.tsx.snap b/tests/renderer/components/__snapshots__/editors-spec.tsx.snap
index ec68b5ea..de8aed61 100644
--- a/tests/renderer/components/__snapshots__/editors-spec.tsx.snap
+++ b/tests/renderer/components/__snapshots__/editors-spec.tsx.snap
@@ -1022,118 +1022,7 @@ exports[`Editors component renders 1`] = `
         </div>
         <div
           className="mosaic-window-body"
-        >
-          <div
-            className="show-me-panel"
-          >
-            Array [
-              <span
-                className="bp3-icon bp3-icon-help"
-                icon="help"
-                style={
-                  Object {
-                    "float": "left",
-                    "margin": "0 10px 0 0",
-                  }
-                }
-              >
-                <svg
-                  data-icon="help"
-                  height={40}
-                  viewBox="0 0 20 20"
-                  width={40}
-                >
-                  <desc>
-                    help
-                  </desc>
-                  <path
-                    d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zM7.41 4.62c.65-.54 1.51-.82 2.56-.82.54 0 1.03.08 1.48.25.44.17.83.39 1.14.68.32.29.56.63.74 1.02.17.39.26.82.26 1.27s-.08.87-.24 1.23c-.16.37-.4.73-.71 1.11l-1.21 1.58c-.14.17-.28.33-.32.48-.05.15-.11.35-.11.6v.97H9v-2s.06-.58.24-.81l1.21-1.64c.25-.3.41-.56.51-.77s.14-.44.14-.67c0-.35-.11-.63-.32-.85s-.5-.33-.88-.33c-.37 0-.67.11-.89.33-.22.23-.37.54-.46.94-.03.12-.11.17-.23.16l-1.95-.29c-.12-.01-.16-.08-.14-.22.13-.93.52-1.67 1.18-2.22zM9 14h2.02L11 16H9v-2z"
-                    fillRule="evenodd"
-                    key="0"
-                  />
-                </svg>
-              </span>,
-              <p
-                className="bp3r-running-text"
-              >
-                This panel offers useful information about Electron APIs – and easy way to try some of the methods it offers. Fiddle has an example fiddle for every module available in Electron.
-              </p>,
-              <p>
-                Clicking on any of the modules below will open up a fiddle showcasing that particular module.
-              </p>,
-              <ul
-                className="show-me-list"
-              >
-                <li
-                  key="DEMO_APP"
-                >
-                  <button
-                    className="bp3-button bp3-minimal"
-                    onBlur={[Function]}
-                    onClick={[Function]}
-                    onKeyDown={[Function]}
-                    onKeyUp={[Function]}
-                    type="button"
-                  >
-                    <span
-                      className="bp3-icon bp3-icon-play"
-                      icon="play"
-                    >
-                      <svg
-                        data-icon="play"
-                        height={16}
-                        viewBox="0 0 16 16"
-                        width={16}
-                      >
-                        <desc>
-                          play
-                        </desc>
-                        <path
-                          d="M12 8c0-.35-.19-.64-.46-.82l.01-.02-6-4-.01.02A.969.969 0 005 3c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1 .21 0 .39-.08.54-.18l.01.02 6-4-.01-.02c.27-.18.46-.47.46-.82z"
-                          fillRule="evenodd"
-                          key="0"
-                        />
-                      </svg>
-                    </span>
-                    <span
-                      className="bp3-button-text"
-                      key="text"
-                    >
-                      App Demos
-                    </span>
-                  </button>
-                </li>
-              </ul>,
-              <br />,
-              <p
-                className="b3-running-text"
-              >
-                For more documentation, visit
-                 
-                <a
-                  id="open-url"
-                  onClick={[Function]}
-                >
-                  electronjs.org/docs
-                </a>
-                , where you can find the full documentation for Electron.
-              </p>,
-              <p
-                className="bp3-text-muted"
-              >
-                By the way, Electron Fiddle and the documentation you see here is entirely open source. If you have ideas on how to improve it, we'd love to have your contributions! You can find the repository on
-                 
-                <a
-                  id="open-github"
-                  onClick={[Function]}
-                >
-                  GitHub
-                </a>
-                .
-              </p>,
-            ]
-          </div>
-        </div>
+        />
         <div
           className="mosaic-window-body-overlay"
           onClick={[Function]}
diff --git a/tests/renderer/components/__snapshots__/show-me-spec.tsx.snap b/tests/renderer/components/__snapshots__/show-me-spec.tsx.snap
deleted file mode 100644
index 76f313ef..00000000
--- a/tests/renderer/components/__snapshots__/show-me-spec.tsx.snap
+++ /dev/null
@@ -1,25 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`ShowMe component renders 1`] = `
-<div
-  className="show-me-panel"
->
-  <ShowMeDefault
-    appState={Object {}}
-  />
-</div>
-`;
-
-exports[`ShowMe component renders a template spec 1`] = `
-<div
-  className="show-me-panel"
->
-  <ShowMeDefault
-    appState={
-      Object {
-        "templateName": "app",
-      }
-    }
-  />
-</div>
-`;
diff --git a/tests/renderer/components/show-me-spec.tsx b/tests/renderer/components/show-me-spec.tsx
deleted file mode 100644
index 928d611c..00000000
--- a/tests/renderer/components/show-me-spec.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { shallow } from 'enzyme';
-import * as React from 'react';
-
-import { ShowMe } from '../../../src/renderer/components/show-me';
-
-describe('ShowMe component', () => {
-  let mockState: any = {};
-
-  beforeAll(() => {
-    mockState = {};
-  });
-
-  it('renders', () => {
-    const wrapper = shallow(<ShowMe appState={mockState} />);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  it('renders a template spec', () => {
-    mockState.templateName = 'app';
-    const wrapper = shallow(<ShowMe appState={mockState} />);
-    expect(wrapper).toMatchSnapshot();
-  });
-});
diff --git a/tests/renderer/components/show-me/__snapshots__/app-spec.tsx.snap b/tests/renderer/components/show-me/__snapshots__/app-spec.tsx.snap
deleted file mode 100644
index b8a4e72d..00000000
--- a/tests/renderer/components/show-me/__snapshots__/app-spec.tsx.snap
+++ /dev/null
@@ -1,345 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`getSubsetOnly() renders 1`] = `
-Array [
-  <span
-    className="bp3-icon bp3-icon-help"
-    icon="help"
-    style={
-      Object {
-        "float": "left",
-        "margin": "0 10px 0 0",
-      }
-    }
-  >
-    <svg
-      data-icon="help"
-      height={40}
-      viewBox="0 0 20 20"
-      width={40}
-    >
-      <desc>
-        help
-      </desc>
-      <path
-        d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zM7.41 4.62c.65-.54 1.51-.82 2.56-.82.54 0 1.03.08 1.48.25.44.17.83.39 1.14.68.32.29.56.63.74 1.02.17.39.26.82.26 1.27s-.08.87-.24 1.23c-.16.37-.4.73-.71 1.11l-1.21 1.58c-.14.17-.28.33-.32.48-.05.15-.11.35-.11.6v.97H9v-2s.06-.58.24-.81l1.21-1.64c.25-.3.41-.56.51-.77s.14-.44.14-.67c0-.35-.11-.63-.32-.85s-.5-.33-.88-.33c-.37 0-.67.11-.89.33-.22.23-.37.54-.46.94-.03.12-.11.17-.23.16l-1.95-.29c-.12-.01-.16-.08-.14-.22.13-.93.52-1.67 1.18-2.22zM9 14h2.02L11 16H9v-2z"
-        fillRule="evenodd"
-        key="0"
-      />
-    </svg>
-  </span>,
-  <p
-    className="bp3r-running-text"
-  >
-    The 
-    <code>
-      app
-    </code>
-     module controls the app's application life-cycle. Most of the events and methods available on this module are responsible for handling how your interacts with the operating system or to set application-wide settings.
-  </p>,
-  <h3>
-    API Demos
-  </h3>,
-  <p
-    className="bp3-running-text"
-  >
-    The following demos display only a subset of what the
-     
-    <code>
-      app
-    </code>
-    module is capable of. If you want to see its full abilities, check out the documentation on
-     
-    <a
-      id="open-url"
-      onClick={[Function]}
-    >
-      electronjs.org/docs/api/app
-    </a>
-    .
-  </p>,
-  <div
-    className="bp3-callout bp3-callout-icon"
-  >
-    <span
-      className="bp3-icon bp3-icon-eye-open"
-      icon="eye-open"
-    >
-      <svg
-        data-icon="eye-open"
-        height={20}
-        viewBox="0 0 20 20"
-        width={20}
-      >
-        <desc>
-          eye-open
-        </desc>
-        <path
-          d="M10.01 7.984A2.008 2.008 0 008.012 9.99c0 1.103.9 2.006 1.998 2.006a2.008 2.008 0 001.998-2.006c0-1.103-.9-2.006-1.998-2.006zM20 9.96v-.03-.01-.02-.02a.827.827 0 00-.21-.442c-.64-.802-1.398-1.514-2.168-2.166-1.658-1.404-3.566-2.587-5.664-3.058a8.982 8.982 0 00-3.656-.05c-1.11.2-2.178.641-3.177 1.183-1.569.852-2.997 2.016-4.246 3.33-.23.25-.46.49-.67.761-.279.351-.279.773 0 1.124.64.802 1.4 1.514 2.169 2.166 1.658 1.404 3.566 2.577 5.664 3.058 1.209.271 2.438.281 3.656.05 1.11-.21 2.178-.651 3.177-1.193 1.569-.852 2.997-2.016 4.246-3.33.23-.24.46-.49.67-.751.11-.12.179-.271.209-.442v-.02-.02-.01-.03V10v-.04zM10.01 14A4.003 4.003 0 016.014 9.99a4.003 4.003 0 013.996-4.011 4.003 4.003 0 013.996 4.011 4.003 4.003 0 01-3.996 4.011z"
-          fillRule="evenodd"
-          key="0"
-        />
-      </svg>
-    </span>
-    <h4
-      className="bp3-heading"
-    >
-      Hiding, Showing, Focussing
-    </h4>
-    <p>
-      The app can ask the operating system for window focus. On macOS, it can additionally request that the app be hidden or shown. Give it a try: Click on the button below, focus another app, and wait for two seconds to see Electron Fiddle become the focused app again.
-    </p>
-    <button
-      className="bp3-button"
-      id="focus"
-      onBlur={[Function]}
-      onClick={[Function]}
-      onKeyDown={[Function]}
-      onKeyUp={[Function]}
-      type="button"
-    >
-      <span
-        className="bp3-icon bp3-icon-lightbulb"
-        icon="lightbulb"
-      >
-        <svg
-          data-icon="lightbulb"
-          height={16}
-          viewBox="0 0 16 16"
-          width={16}
-        >
-          <desc>
-            lightbulb
-          </desc>
-          <path
-            d="M9.01 14h-2c-.55 0-1 .45-1 1s.45 1 1 1h2c.55 0 1-.45 1-1s-.44-1-1-1zm1-3h-4c-.55 0-1 .45-1 1s.45 1 1 1h4c.55 0 1-.45 1-1s-.44-1-1-1zm-2-11C5.26 0 3.03 1.95 3.03 4.35c0 2.37 1.63 2.64 1.94 5.22 0 .24.22.44.5.44h5.09c.28 0 .5-.19.5-.44C11.37 6.99 13 6.72 13 4.35 13 1.95 10.77 0 8.01 0z"
-            fillRule="evenodd"
-            key="0"
-          />
-        </svg>
-      </span>
-      <span
-        className="bp3-button-text"
-        key="text"
-      >
-        Focus Electron Fiddle
-      </span>
-    </button>
-    Array [
-      <p>
-        This button hides Electron Fiddle right away, showing it again in two seconds.
-      </p>,
-      <button
-        className="bp3-button"
-        id="show-hide"
-        onBlur={[Function]}
-        onClick={[Function]}
-        onKeyDown={[Function]}
-        onKeyUp={[Function]}
-        type="button"
-      >
-        <span
-          className="bp3-icon bp3-icon-eye-off"
-          icon="eye-off"
-        >
-          <svg
-            data-icon="eye-off"
-            height={16}
-            viewBox="0 0 16 16"
-            width={16}
-          >
-            <desc>
-              eye-off
-            </desc>
-            <path
-              d="M16 7.97v-.02-.01-.02-.02a.672.672 0 00-.17-.36c-.49-.63-1.07-1.2-1.65-1.72l-3.16 2.26a2.978 2.978 0 01-2.98 2.9c-.31 0-.6-.06-.88-.15L5.09 12.3c.44.19.9.36 1.37.47.97.23 1.94.24 2.92.05.88-.17 1.74-.54 2.53-.98 1.25-.7 2.39-1.67 3.38-2.75.18-.2.37-.41.53-.62.09-.1.15-.22.17-.36v-.02-.02-.01-.02-.03c.01-.02.01-.03.01-.04zm-.43-4.17c.25-.18.43-.46.43-.8 0-.55-.45-1-1-1-.22 0-.41.08-.57.2l-.01-.01-2.67 1.91c-.69-.38-1.41-.69-2.17-.87a6.8 6.8 0 00-2.91-.05c-.88.18-1.74.54-2.53.99-1.25.7-2.39 1.67-3.38 2.75-.18.2-.37.41-.53.62-.23.29-.23.63-.01.92.51.66 1.11 1.25 1.73 1.79.18.16.38.29.56.44l-2.09 1.5.01.01c-.25.18-.43.46-.43.8 0 .55.45 1 1 1 .22 0 .41-.08.57-.2l.01.01 14-10-.01-.01zm-10.41 5a3.03 3.03 0 01-.11-.8 2.99 2.99 0 012.99-2.98c.62 0 1.19.21 1.66.53L5.16 8.8z"
-              fillRule="evenodd"
-              key="0"
-            />
-          </svg>
-        </span>
-        <span
-          className="bp3-button-text"
-          key="text"
-        >
-          Hide Electron Fiddle
-        </span>
-      </button>,
-    ]
-  </div>,
-  <div
-    className="bp3-callout bp3-callout-icon"
-  >
-    <span
-      className="bp3-icon bp3-icon-folder-open"
-      icon="folder-open"
-    >
-      <svg
-        data-icon="folder-open"
-        height={20}
-        viewBox="0 0 20 20"
-        width={20}
-      >
-        <desc>
-          folder-open
-        </desc>
-        <path
-          d="M20 9c0-.55-.45-1-1-1H5c-.43 0-.79.27-.93.65h-.01l-3 8h.01c-.04.11-.07.23-.07.35 0 .55.45 1 1 1h14c.43 0 .79-.27.93-.65h.01l3-8h-.01c.04-.11.07-.23.07-.35zM3.07 7.63C3.22 7.26 3.58 7 4 7h14V5c0-.55-.45-1-1-1H8.41l-1.7-1.71A.997.997 0 006 2H1c-.55 0-1 .45-1 1v12.31l3.07-7.68z"
-          fillRule="evenodd"
-          key="0"
-        />
-      </svg>
-    </span>
-    <h4
-      className="bp3-heading"
-    >
-      Paths
-    </h4>
-    <p>
-      Need to query information about various paths in a cross-platform manner? Electron can help. The button queries the operating system for some of them.
-    </p>
-    <button
-      className="bp3-button"
-      id="special-paths"
-      onBlur={[Function]}
-      onClick={[Function]}
-      onKeyDown={[Function]}
-      onKeyUp={[Function]}
-      type="button"
-    >
-      <span
-        className="bp3-icon bp3-icon-play"
-        icon="play"
-      >
-        <svg
-          data-icon="play"
-          height={16}
-          viewBox="0 0 16 16"
-          width={16}
-        >
-          <desc>
-            play
-          </desc>
-          <path
-            d="M12 8c0-.35-.19-.64-.46-.82l.01-.02-6-4-.01.02A.969.969 0 005 3c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1 .21 0 .39-.08.54-.18l.01.02 6-4-.01-.02c.27-.18.46-.47.46-.82z"
-            fillRule="evenodd"
-            key="0"
-          />
-        </svg>
-      </span>
-      <span
-        className="bp3-button-text"
-        key="text"
-      >
-        Get special directory paths
-      </span>
-    </button>
-    <pre
-      id="special-paths-content"
-    />
-  </div>,
-  <div
-    className="bp3-callout bp3-callout-icon"
-  >
-    <span
-      className="bp3-icon bp3-icon-pulse"
-      icon="pulse"
-    >
-      <svg
-        data-icon="pulse"
-        height={20}
-        viewBox="0 0 20 20"
-        width={20}
-      >
-        <desc>
-          pulse
-        </desc>
-        <path
-          d="M19 10h-2.38L14.9 6.55h-.01c-.17-.32-.5-.55-.89-.55-.43 0-.79.28-.93.66h-.01l-2.75 7.57L7.98 1.82h-.02A.978.978 0 007 1c-.44 0-.8.29-.94.69h-.01L3.28 10H1c-.55 0-1 .45-1 1s.45 1 1 1h3c.44 0 .8-.29.94-.69h.01l1.78-5.34 2.29 12.21h.02c.08.46.47.82.96.82.43 0 .79-.28.93-.66h.01l3.21-8.82.96 1.92h.01c.16.33.49.56.88.56h3c.55 0 1-.45 1-1s-.45-1-1-1z"
-          fillRule="evenodd"
-          key="0"
-        />
-      </svg>
-    </span>
-    <h4
-      className="bp3-heading"
-    >
-      Process & Device Information
-    </h4>
-    <p>
-      Need to query information about the process or system? The
-       
-      <code>
-        app
-      </code>
-       module lets developers query for information about the running app, hardware, and operating system. A good example are process metrics.
-    </p>
-    <button
-      className="bp3-button"
-      id="process-metrics"
-      onBlur={[Function]}
-      onClick={[Function]}
-      onKeyDown={[Function]}
-      onKeyUp={[Function]}
-      type="button"
-    >
-      <span
-        className="bp3-icon bp3-icon-play"
-        icon="play"
-      >
-        <svg
-          data-icon="play"
-          height={16}
-          viewBox="0 0 16 16"
-          width={16}
-        >
-          <desc>
-            play
-          </desc>
-          <path
-            d="M12 8c0-.35-.19-.64-.46-.82l.01-.02-6-4-.01.02A.969.969 0 005 3c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1 .21 0 .39-.08.54-.18l.01.02 6-4-.01-.02c.27-.18.46-.47.46-.82z"
-            fillRule="evenodd"
-            key="0"
-          />
-        </svg>
-      </span>
-      <span
-        className="bp3-button-text"
-        key="text"
-      >
-        Get process metrics
-      </span>
-    </button>
-    <pre
-      id="process-metrics-content"
-    />
-  </div>,
-  <br />,
-  <p
-    className="b3-running-text"
-  >
-    For more documentation, visit
-     
-    <a
-      id="open-url"
-      onClick={[Function]}
-    >
-      electronjs.org/docs
-    </a>
-    , where you can find the full documentation for Electron.
-  </p>,
-  <p
-    className="bp3-text-muted"
-  >
-    By the way, Electron Fiddle and the documentation you see here is entirely open source. If you have ideas on how to improve it, we'd love to have your contributions! You can find the repository on
-     
-    <a
-      id="open-github"
-      onClick={[Function]}
-    >
-      GitHub
-    </a>
-    .
-  </p>,
-]
-`;
diff --git a/tests/renderer/components/show-me/__snapshots__/default-spec.tsx.snap b/tests/renderer/components/show-me/__snapshots__/default-spec.tsx.snap
deleted file mode 100644
index 3d66483a..00000000
--- a/tests/renderer/components/show-me/__snapshots__/default-spec.tsx.snap
+++ /dev/null
@@ -1,110 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`getSubsetOnly() renders 1`] = `
-Array [
-  <span
-    className="bp3-icon bp3-icon-help"
-    icon="help"
-    style={
-      Object {
-        "float": "left",
-        "margin": "0 10px 0 0",
-      }
-    }
-  >
-    <svg
-      data-icon="help"
-      height={40}
-      viewBox="0 0 20 20"
-      width={40}
-    >
-      <desc>
-        help
-      </desc>
-      <path
-        d="M10 0C4.48 0 0 4.48 0 10s4.48 10 10 10 10-4.48 10-10S15.52 0 10 0zM7.41 4.62c.65-.54 1.51-.82 2.56-.82.54 0 1.03.08 1.48.25.44.17.83.39 1.14.68.32.29.56.63.74 1.02.17.39.26.82.26 1.27s-.08.87-.24 1.23c-.16.37-.4.73-.71 1.11l-1.21 1.58c-.14.17-.28.33-.32.48-.05.15-.11.35-.11.6v.97H9v-2s.06-.58.24-.81l1.21-1.64c.25-.3.41-.56.51-.77s.14-.44.14-.67c0-.35-.11-.63-.32-.85s-.5-.33-.88-.33c-.37 0-.67.11-.89.33-.22.23-.37.54-.46.94-.03.12-.11.17-.23.16l-1.95-.29c-.12-.01-.16-.08-.14-.22.13-.93.52-1.67 1.18-2.22zM9 14h2.02L11 16H9v-2z"
-        fillRule="evenodd"
-        key="0"
-      />
-    </svg>
-  </span>,
-  <p
-    className="bp3r-running-text"
-  >
-    This panel offers useful information about Electron APIs – and easy way to try some of the methods it offers. Fiddle has an example fiddle for every module available in Electron.
-  </p>,
-  <p>
-    Clicking on any of the modules below will open up a fiddle showcasing that particular module.
-  </p>,
-  <ul
-    className="show-me-list"
-  >
-    <li
-      key="DEMO_APP"
-    >
-      <button
-        className="bp3-button bp3-minimal"
-        onBlur={[Function]}
-        onClick={[Function]}
-        onKeyDown={[Function]}
-        onKeyUp={[Function]}
-        type="button"
-      >
-        <span
-          className="bp3-icon bp3-icon-play"
-          icon="play"
-        >
-          <svg
-            data-icon="play"
-            height={16}
-            viewBox="0 0 16 16"
-            width={16}
-          >
-            <desc>
-              play
-            </desc>
-            <path
-              d="M12 8c0-.35-.19-.64-.46-.82l.01-.02-6-4-.01.02A.969.969 0 005 3c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1 .21 0 .39-.08.54-.18l.01.02 6-4-.01-.02c.27-.18.46-.47.46-.82z"
-              fillRule="evenodd"
-              key="0"
-            />
-          </svg>
-        </span>
-        <span
-          className="bp3-button-text"
-          key="text"
-        >
-          App Demos
-        </span>
-      </button>
-    </li>
-  </ul>,
-  <br />,
-  <p
-    className="b3-running-text"
-  >
-    For more documentation, visit
-     
-    <a
-      id="open-url"
-      onClick={[Function]}
-    >
-      electronjs.org/docs
-    </a>
-    , where you can find the full documentation for Electron.
-  </p>,
-  <p
-    className="bp3-text-muted"
-  >
-    By the way, Electron Fiddle and the documentation you see here is entirely open source. If you have ideas on how to improve it, we'd love to have your contributions! You can find the repository on
-     
-    <a
-      id="open-github"
-      onClick={[Function]}
-    >
-      GitHub
-    </a>
-    .
-  </p>,
-]
-`;
diff --git a/tests/renderer/components/show-me/__snapshots__/more-information-spec.tsx.snap b/tests/renderer/components/show-me/__snapshots__/more-information-spec.tsx.snap
deleted file mode 100644
index e52936c5..00000000
--- a/tests/renderer/components/show-me/__snapshots__/more-information-spec.tsx.snap
+++ /dev/null
@@ -1,33 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renderMoreDocumentation() renders 1`] = `
-Array [
-  <br />,
-  <p
-    className="b3-running-text"
-  >
-    For more documentation, visit
-     
-    <a
-      id="open-url"
-      onClick={[Function]}
-    >
-      electronjs.org/docs
-    </a>
-    , where you can find the full documentation for Electron.
-  </p>,
-  <p
-    className="bp3-text-muted"
-  >
-    By the way, Electron Fiddle and the documentation you see here is entirely open source. If you have ideas on how to improve it, we'd love to have your contributions! You can find the repository on
-     
-    <a
-      id="open-github"
-      onClick={[Function]}
-    >
-      GitHub
-    </a>
-    .
-  </p>,
-]
-`;
diff --git a/tests/renderer/components/show-me/__snapshots__/subset-only-spec.tsx.snap b/tests/renderer/components/show-me/__snapshots__/subset-only-spec.tsx.snap
deleted file mode 100644
index 1a50dab8..00000000
--- a/tests/renderer/components/show-me/__snapshots__/subset-only-spec.tsx.snap
+++ /dev/null
@@ -1,22 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`getSubsetOnly() renders 1`] = `
-<p
-  className="bp3-running-text"
->
-  The following demos display only a subset of what the
-   
-  <code>
-    app
-  </code>
-  module is capable of. If you want to see its full abilities, check out the documentation on
-   
-  <a
-    id="open-url"
-    onClick={[Function]}
-  >
-    electronjs.org/docs/api/app
-  </a>
-  .
-</p>
-`;
diff --git a/tests/renderer/components/show-me/app-spec.tsx b/tests/renderer/components/show-me/app-spec.tsx
deleted file mode 100644
index c9430609..00000000
--- a/tests/renderer/components/show-me/app-spec.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-import * as electron from 'electron';
-import * as React from 'react';
-
-import { act } from 'react-dom/test-utils';
-
-import { mount } from 'enzyme';
-
-import { ShowMeApp as ShowMeAppType } from '../../../../src/renderer/components/show-me/app';
-import { overridePlatform, resetPlatform } from '../../../utils';
-
-describe('getSubsetOnly()', () => {
-  let ShowMeApp: typeof ShowMeAppType;
-
-  beforeAll(async () => {
-    jest.useFakeTimers();
-    overridePlatform('darwin');
-
-    ({
-      ShowMeApp,
-    } = require('../../../../src/renderer/components/show-me/app'));
-  });
-
-  afterAll(() => {
-    jest.useRealTimers();
-    resetPlatform();
-  });
-
-  it('renders', () => {
-    const wrapper = mount(<ShowMeApp />);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  it('does not render the show/hide on non-darwin', async () => {
-    overridePlatform('win32');
-
-    const wrapper = mount(<ShowMeApp />);
-    const element = wrapper.find('button#show-hide');
-
-    expect(element.length).toBe(0);
-
-    overridePlatform('darwin');
-  });
-
-  it('handles the show/hide example', async () => {
-    const wrapper = mount(<ShowMeApp />);
-
-    wrapper.find('button#show-hide').simulate('click');
-
-    expect(setTimeout).toHaveBeenCalledTimes(1);
-
-    for (const [method] of (setTimeout as any).mock.calls) {
-      act(method);
-    }
-
-    expect(electron.remote.app.show).toHaveBeenCalled();
-    expect(electron.remote.app.hide).toHaveBeenCalled();
-  });
-
-  it('handles the focus example', async () => {
-    const wrapper = mount(<ShowMeApp />);
-
-    wrapper.find('button#focus').simulate('click');
-
-    expect(setTimeout).toHaveBeenCalledTimes(3);
-
-    for (const [method] of (setTimeout as any).mock.calls) {
-      act(method);
-    }
-
-    expect(electron.remote.app.focus).toHaveBeenCalled();
-  });
-
-  it('handles the paths example', () => {
-    (electron.remote.app.getPath as jest.Mock).mockImplementation(
-      (name) => name,
-    );
-    const wrapper = mount(<ShowMeApp />);
-
-    wrapper.find('button#special-paths').simulate('click');
-    const specialPaths = wrapper
-      .find('pre#special-paths-content')
-      .text()
-      .trim();
-
-    expect(specialPaths).toEqual(
-      `
-home: home
-appData: appData
-userData: ${electron.app.getPath('userData')}
-temp: temp
-downloads: downloads
-desktop: desktop`.trim(),
-    );
-  });
-
-  it('handles the metrics example', () => {
-    (electron.remote.app.getAppMetrics as jest.Mock).mockReturnValue({
-      metrics: 123,
-    });
-
-    const wrapper = mount(<ShowMeApp />);
-
-    wrapper.find('button#process-metrics').simulate('click');
-    const specialPaths = wrapper
-      .find('pre#process-metrics-content')
-      .text()
-      .trim();
-
-    expect(JSON.parse(specialPaths)).toEqual({ metrics: 123 });
-  });
-});
diff --git a/tests/renderer/components/show-me/default-spec.tsx b/tests/renderer/components/show-me/default-spec.tsx
deleted file mode 100644
index d7725cad..00000000
--- a/tests/renderer/components/show-me/default-spec.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import { mount } from 'enzyme';
-
-import { DocsDemoPage } from '../../../../src/interfaces';
-import { ShowMeDefault } from '../../../../src/renderer/components/show-me/default';
-
-describe('getSubsetOnly()', () => {
-  it('renders', () => {
-    const mockState = { currentDocsDemoPage: undefined };
-    const wrapper = mount(ShowMeDefault({ appState: mockState } as any));
-    expect(wrapper).toMatchSnapshot();
-
-    wrapper.find('button').simulate('click');
-
-    expect(mockState.currentDocsDemoPage).toBe(DocsDemoPage.DEMO_APP);
-  });
-});
diff --git a/tests/renderer/components/show-me/more-information-spec.tsx b/tests/renderer/components/show-me/more-information-spec.tsx
deleted file mode 100644
index 2d709fd2..00000000
--- a/tests/renderer/components/show-me/more-information-spec.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import * as electron from 'electron';
-import { mount } from 'enzyme';
-
-import { renderMoreDocumentation } from '../../../../src/renderer/components/show-me/more-information';
-
-describe('renderMoreDocumentation()', () => {
-  it('renders', () => {
-    const wrapper = mount(renderMoreDocumentation());
-    expect(wrapper).toMatchSnapshot();
-
-    wrapper.find('a#open-url').simulate('click');
-    expect(electron.shell.openExternal).toHaveBeenCalledTimes(1);
-
-    wrapper.find('a#open-github').simulate('click');
-    expect(electron.shell.openExternal).toHaveBeenCalledTimes(2);
-  });
-});
diff --git a/tests/renderer/components/show-me/subset-only-spec.tsx b/tests/renderer/components/show-me/subset-only-spec.tsx
deleted file mode 100644
index 14a161b1..00000000
--- a/tests/renderer/components/show-me/subset-only-spec.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import * as electron from 'electron';
-import { mount } from 'enzyme';
-
-import { getSubsetOnly } from '../../../../src/renderer/components/show-me/subset-only';
-
-describe('getSubsetOnly()', () => {
-  it('renders', () => {
-    const wrapper = mount(getSubsetOnly('app'));
-    expect(wrapper).toMatchSnapshot();
-
-    wrapper.find('a#open-url').simulate('click');
-    expect(electron.shell.openExternal).toHaveBeenCalledTimes(1);
-  });
-});
diff --git a/tests/renderer/remote-loader-spec.ts b/tests/renderer/remote-loader-spec.ts
index e8d750e1..35715481 100644
--- a/tests/renderer/remote-loader-spec.ts
+++ b/tests/renderer/remote-loader-spec.ts
@@ -59,6 +59,10 @@ const mockRepos = [
     name: STYLES_CSS_NAME,
     download_url: 'https://css',
   },
+  {
+    name: PRELOAD_JS_NAME,
+    download_url: 'https://preload',
+  },
   {
     name: 'other_stuff',
     download_url: 'https://google.com',
@@ -145,6 +149,7 @@ describe('RemoteLoader', () => {
       mockFetchOnce('renderer');
       mockFetchOnce('index');
       mockFetchOnce('css');
+      mockFetchOnce('preload');
     });
 
     it('loads an Electron example', async () => {
@@ -163,6 +168,7 @@ describe('RemoteLoader', () => {
             main: 'main',
             renderer: 'renderer',
             css: 'css',
+            preload: 'preload',
           }),
         ]),
       );