Repository: electron/fiddle
Pull request #608 (2021-03-18 01:55:55)

fix: nullptr dereference in runner's cleanup function
Was previously erroring out upon passing undefined into `path.join()`.

Related to the appData -> appPaths improvements in https://github.com/electron/fiddle/pull/602

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

Coverage remained the same at 93.158% when pulling **86681e18ad5d9838918e45d302c7ba81b8fdb3f9 on fix/runner-appData-cleanup** into **858e4b1834832e0ea5ccf64825c2bd7d201a8a2b on master**.


Patch:
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/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));


Test patch:
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);
-  });
-});