Skip to content

Commit c238b66

Browse files
committed
chore: tests for launcher/launch, refactor process spawning for readability
1 parent d5020e5 commit c238b66

File tree

16 files changed

+274
-269
lines changed

16 files changed

+274
-269
lines changed

packages/launcher/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { detect, detectByPath } from './lib/detect'
22

3-
import { launch } from './lib/browsers'
3+
import { launch } from './lib/launch'
44

55
export {
66
detect,

packages/launcher/lib/browsers.ts

Lines changed: 0 additions & 54 deletions
This file was deleted.
File renamed without changes.

packages/launcher/lib/detect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import _, { compact, extend, find } from 'lodash'
33
import os from 'os'
44
import { removeDuplicateBrowsers } from '@packages/data-context/src/sources/BrowserDataSource'
55
import { knownBrowsers } from './known-browsers'
6-
import * as darwinHelper from './darwin'
6+
import * as darwinHelper from './darwinHelpers'
77
import { notDetectedAtPathErr } from './errors'
88
import * as linuxHelper from './linux'
99
import Debug from 'debug'

packages/launcher/lib/launch.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Debug from 'debug'
2+
import type * as cp from 'child_process'
3+
import type { FoundBrowser } from '@packages/types'
4+
import type { Readable } from 'stream'
5+
import { PlatformFactory } from './platforms/PlatformFactory'
6+
7+
export const debug = Debug('cypress:launcher:browsers')
8+
9+
/** starts a found browser and opens URL if given one */
10+
export type LaunchedBrowser = cp.ChildProcessByStdio<null, Readable, Readable>
11+
12+
// NOTE: For Firefox, geckodriver is used to launch the browser
13+
export function launch (
14+
browser: FoundBrowser,
15+
url: string,
16+
args: string[] = [],
17+
browserEnv = {},
18+
) {
19+
debug('launching browser %o', { browser, url })
20+
21+
// We shouldn't need to check this, because FoundBrowser.path is
22+
// not optional.
23+
if (!browser.path) {
24+
throw new Error(`Browser ${browser.name} is missing path`)
25+
}
26+
27+
return PlatformFactory.select().launch(browser, url, args, browserEnv)
28+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// this file is named XDarwin because intellisense gets confused with '../darwin/'
2+
import { ChildProcess, spawn } from 'child_process'
3+
import { Platform } from './Platform'
4+
import type { FoundBrowser } from '@packages/types'
5+
import os from 'os'
6+
7+
export class Darwin extends Platform {
8+
launch (browser: FoundBrowser, url: string, args: string[], env: Record<string, string> = {}): ChildProcess {
9+
if (os.arch() === 'arm64') {
10+
const proc = spawn(
11+
'arch',
12+
[browser.path, url, ...args], {
13+
...Platform.defaultSpawnOpts,
14+
env: {
15+
ARCHPREFERENCE: 'arm64,x86_64',
16+
...Platform.defaultSpawnOpts.env,
17+
...env,
18+
},
19+
},
20+
)
21+
22+
this.addDebugListeners(proc, browser)
23+
24+
return proc
25+
}
26+
27+
return super.launch(browser, url, args, env)
28+
}
29+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { Platform } from './Platform'
2+
3+
export class Linux extends Platform {
4+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import type { FoundBrowser } from '@packages/types'
2+
import { ChildProcess, spawn, SpawnOptions } from 'child_process'
3+
import Debug from 'debug'
4+
5+
export const debug = Debug('cypress:launcher:browsers')
6+
7+
export abstract class Platform {
8+
launch (browser: FoundBrowser, url: string, args: string[], env: Record<string, string> = {}): ChildProcess {
9+
debug('launching browser %o', { browser, url, args, env })
10+
11+
const proc = spawn(browser.path, [url, ...args], {
12+
...Platform.defaultSpawnOpts,
13+
env: {
14+
...Platform.defaultSpawnOpts.env,
15+
...env,
16+
},
17+
})
18+
19+
this.addDebugListeners(proc, browser)
20+
21+
return proc
22+
}
23+
24+
protected addDebugListeners (proc: ChildProcess, browser: FoundBrowser) {
25+
proc.stdout?.on('data', (buf) => {
26+
debug('%s stdout: %s', browser.name, String(buf).trim())
27+
})
28+
29+
proc.stderr?.on('data', (buf) => {
30+
debug('%s stderr: %s', browser.name, String(buf).trim())
31+
})
32+
33+
proc.on('exit', (code, signal) => {
34+
debug('%s exited: %o', browser.name, { code, signal })
35+
})
36+
}
37+
38+
static get defaultSpawnOpts (): SpawnOptions {
39+
return {
40+
stdio: ['ignore', 'pipe', 'pipe'],
41+
env: {
42+
...process.env,
43+
},
44+
}
45+
}
46+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import os from 'os'
2+
import type { Platform } from './Platform'
3+
import { Darwin } from './XDarwin'
4+
import { Linux } from './Linux'
5+
import { Windows } from './Windows'
6+
7+
export class PlatformFactory {
8+
static select (): Platform {
9+
switch (os.platform()) {
10+
case 'darwin':
11+
return new Darwin()
12+
case 'linux':
13+
return new Linux()
14+
case 'win32':
15+
return new Windows()
16+
default:
17+
throw new Error(`Unsupported platform: ${os.platform()} ${os.arch()}`)
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)