• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

electron / fiddle / 16349153970

17 Jul 2025 03:21PM UTC coverage: 80.235% (-7.8%) from 87.992%
16349153970

push

github

web-flow
test: switch to Vitest (#1718)

* test: switch to Vitest

* chore: update code comment

Co-authored-by: Kevin Cui <158blackhole@gmail.com>

* test: make use of vi.useFakeTimers to improve test

---------

Co-authored-by: Kevin Cui <158blackhole@gmail.com>

1520 of 1645 branches covered (92.4%)

Branch coverage included in aggregate %.

15 of 16 new or added lines in 12 files covered. (93.75%)

504 existing lines in 45 files now uncovered.

8807 of 11226 relevant lines covered (78.45%)

32.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.73
/src/main/protocol.ts
1
import * as fs from 'node:fs';
2✔
2
import * as path from 'node:path';
2✔
3

4
import { app } from 'electron';
2✔
5

6
import { openFiddle } from './files';
2✔
7
import { ipcMainManager } from './ipc';
2✔
8
import { isDevMode } from './utils/devmode';
2✔
9
import { getOrCreateMainWindow } from './windows';
2✔
10
import { IpcEvents } from '../ipc-events';
2✔
11

12
const PROTOCOL = 'electron-fiddle';
2✔
13
const squirrelPath = path.resolve(
2✔
14
  path.dirname(process.execPath),
2✔
15
  '..',
2✔
16
  'electron-fiddle.exe',
2✔
17
);
2✔
18

19
const handlePotentialProtocolLaunch = (url: string) => {
2✔
20
  if (!app.isReady()) {
13✔
21
    app.once('ready', () => handlePotentialProtocolLaunch(url));
1✔
22
    return;
1✔
23
  }
1✔
24

25
  const parsed = new URL(url.replace(/\/$/, ''));
12✔
26
  if (!parsed.pathname || !parsed.hostname) return;
13✔
27

28
  const pathParts = parsed.pathname.split('/').slice(1);
10✔
29

30
  switch (parsed.hostname) {
10✔
31
    // electron-fiddle://gist/blub
32
    case 'gist':
13✔
33
      if (pathParts.length === 1) {
6✔
34
        // We only have a gist ID
35
        ipcMainManager.send(IpcEvents.LOAD_GIST_REQUEST, [
4✔
36
          {
4✔
37
            id: pathParts[0],
4✔
38
          },
4✔
39
        ]);
4✔
40
      } else if (pathParts.length === 2) {
6✔
41
        // We have a gist owner and gist ID, we can ignore the owner
42
        ipcMainManager.send(IpcEvents.LOAD_GIST_REQUEST, [
1✔
43
          {
1✔
44
            id: pathParts[1],
1✔
45
          },
1✔
46
        ]);
1✔
47
      } else {
1✔
48
        // This is a super invalid gist launch
49
        return;
1✔
50
      }
1✔
51
      break;
5✔
52
    // electron-fiddle://electron/{tag}/{path}
53
    case 'electron':
13✔
54
      if (pathParts.length > 1) {
3✔
55
        // First part is the tag name (e.g. v22.0.0)
56
        // Rest is the path to the example
57
        ipcMainManager.send(IpcEvents.LOAD_ELECTRON_EXAMPLE_REQUEST, [
2✔
58
          {
2✔
59
            tag: pathParts[0],
2✔
60
            path: pathParts.slice(1).join('/'),
2✔
61
          },
2✔
62
        ]);
2✔
63
      } else {
3✔
64
        // This is an invalid electron launch
65
        return;
1✔
66
      }
1✔
67
      break;
2✔
68
    default:
13✔
69
      return;
1✔
70
  }
13✔
71
  getOrCreateMainWindow().then((window) => window.focus());
7✔
72
};
7✔
73

74
const isProtocolString = (arg: string) => arg.startsWith(`${PROTOCOL}://`);
2✔
75

76
export const findProtocolArg = (argv: string[]) => {
2✔
77
  return argv.find((arg) => isProtocolString(arg));
25✔
78
};
25✔
79

80
const scanArgv = (argv: Array<string>) => {
2✔
81
  const protocolArg = findProtocolArg(argv);
4✔
82
  if (protocolArg) {
4✔
83
    console.info('Found protocol arg in argv:', protocolArg);
2✔
84
    handlePotentialProtocolLaunch(protocolArg);
2✔
85
  }
2✔
86
};
4✔
87

88
const scanNpmArgv = (argv: string) => {
2✔
89
  const parsedArgv = JSON.parse(argv);
×
90
  const { original: args } = parsedArgv;
×
91
  scanArgv(args);
×
UNCOV
92
};
×
93

94
export const listenForProtocolHandler = () => {
2✔
95
  const gotTheLock = app.requestSingleInstanceLock();
12✔
96
  if (!gotTheLock) app.quit();
12✔
97

98
  app.removeAllListeners('open-url');
12✔
99
  app.on('open-url', (_, url) => {
12✔
100
    if (isProtocolString(url)) {
10✔
101
      handlePotentialProtocolLaunch(url);
10✔
102
    }
10✔
103
  });
12✔
104

105
  app.removeAllListeners('second-instance');
12✔
106
  app.on('second-instance', (_event, commandLine, _workingDirectory) => {
12✔
107
    // Someone tried to run a second instance
108
    scanArgv(commandLine);
1✔
109
  });
12✔
110

111
  app.on('open-file', async (_, path) => {
12✔
112
    if (!path || path.length < 1) {
×
113
      return;
×
UNCOV
114
    }
×
115
    const files = await openFiddle(path);
×
116
    ipcMainManager.send(IpcEvents.FS_OPEN_FIDDLE, [path, files]);
×
117
  });
12✔
118

119
  // pass protocol URL via npm start args in dev mode
120
  if (isDevMode() && process.env.npm_config_argv) {
12!
121
    scanNpmArgv(process.env.npm_config_argv);
×
122
  } else if (process.platform === 'win32') {
12✔
123
    scanArgv(process.argv);
3✔
124
  }
3✔
125
};
12✔
126

127
export const setupProtocolHandler = () => {
2✔
128
  if (process.platform === 'win32' && !fs.existsSync(squirrelPath)) return;
3✔
129
  if (!app.isDefaultProtocolClient(PROTOCOL, squirrelPath)) {
1✔
130
    app.setAsDefaultProtocolClient(PROTOCOL, squirrelPath);
1✔
131
  }
1✔
132
};
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc