Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ import * as DebuggerCreateRpcConnection from '../DebuggerCreateRpcConnection/Deb
import { DevtoolsProtocolDebugger, DevtoolsProtocolRuntime } from '../DevtoolsProtocol/DevtoolsProtocol.ts'
import * as MonkeyPatchElectronScript from '../MonkeyPatchElectronScript/MonkeyPatchElectronScript.ts'
import { PortReadStream } from '../PortReadStream/PortReadStream.ts'
import * as SetWindowContentSize from '../SetWindowContentSize/SetWindowContentSize.ts'
import * as WaitForDebuggerListening from '../WaitForDebuggerListening/WaitForDebuggerListening.ts'
import * as WaitForDevtoolsListening from '../WaitForDevtoolsListening/WaitForDevtoolsListening.ts'

const windowWidth = 1024
const windowHeight = 768

export const prepareBoth = async (
secretsPath: string,
headlessMode: boolean,
Expand Down Expand Up @@ -58,6 +62,8 @@ export const prepareBoth = async (
// Wait for the page to be created by the initialization worker's connectDevtools
const { dispose, sessionId, targetId } = await connectDevtoolsPromise

await SetWindowContentSize.setWindowContentSize(electronRpc, electronObjectId, targetId, windowWidth, windowHeight)

await Promise.all([electronRpc.dispose(), dispose()])

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { DevtoolsProtocolRuntime } from '../DevtoolsProtocol/DevtoolsProtocol.ts'

const setWindowContentSizeScript = `async function (targetId, width, height) {
const electron = this
const { BrowserWindow, webContents } = electron
const targetWebContents = webContents.fromDevToolsTargetId?.(targetId)
const browserWindow = targetWebContents
? BrowserWindow.fromWebContents(targetWebContents)
: BrowserWindow.getAllWindows()[0]
if (!browserWindow) {
throw new Error('browser window not found')
}

if (browserWindow.isFullScreen()) {
await new Promise((resolve) => {
browserWindow.once('leave-full-screen', resolve)
browserWindow.setFullScreen(false)
})
}
if (browserWindow.isMaximized()) {
await new Promise((resolve) => {
browserWindow.once('unmaximize', resolve)
browserWindow.unmaximize()
})
}

browserWindow.setContentSize(width, height, false)
const [actualWidth, actualHeight] = browserWindow.getContentSize()
if (actualWidth !== width || actualHeight !== height) {
throw new Error(
\`expected browser window content size \${width}x\${height}, got \${actualWidth}x\${actualHeight}\`
)
}
}`

export const setWindowContentSize = async (
electronRpc: { invoke(method: string, params?: unknown): Promise<unknown> },
electronObjectId: string,
targetId: string,
width: number,
height: number,
): Promise<void> => {
await DevtoolsProtocolRuntime.callFunctionOn(electronRpc, {
arguments: [{ value: targetId }, { value: width }, { value: height }],
awaitPromise: true,
functionDeclaration: setWindowContentSizeScript,
objectId: electronObjectId,
})
}
9 changes: 9 additions & 0 deletions packages/initialization-worker/test/PrepareBoth.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { expect, jest, test } from '@jest/globals'

const mockSetWindowContentSize = jest.fn(async (..._args: unknown[]) => {})

jest.unstable_mockModule('../src/parts/WaitForDebuggerListening/WaitForDebuggerListening.ts', () => {
return {
WaitForDebuggerListening: {},
Expand Down Expand Up @@ -59,6 +61,12 @@ jest.unstable_mockModule('../src/parts/DevtoolsProtocol/DevtoolsProtocol.ts', ()
}
})

jest.unstable_mockModule('../src/parts/SetWindowContentSize/SetWindowContentSize.ts', () => {
return {
setWindowContentSize: mockSetWindowContentSize,
}
})

const { prepareBoth } = await import('../src/parts/PrepareBoth/PrepareBoth.ts')

test('prepareBoth returns real electron process id from runtime evaluation', async () => {
Expand All @@ -79,4 +87,5 @@ test('prepareBoth returns real electron process id from runtime evaluation', asy
)

expect(result.pid).toBe(9876)
expect(mockSetWindowContentSize).toHaveBeenCalledWith(expect.anything(), 'electron-object', 'target-id', 1024, 768)
})
32 changes: 32 additions & 0 deletions packages/initialization-worker/test/SetWindowContentSize.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expect, test } from '@jest/globals'
import * as SetWindowContentSize from '../src/parts/SetWindowContentSize/SetWindowContentSize.ts'

test('setWindowContentSize resizes the window for the target web contents', async () => {
const calls: Array<{ method: string; params: any }> = []
const electronRpc = {
invoke: async (method: string, params: any) => {
calls.push({ method, params })
return {
result: {
result: {
type: 'undefined',
},
},
}
},
}

await SetWindowContentSize.setWindowContentSize(electronRpc, 'electron-object', 'target-id', 1024, 768)

expect(calls).toEqual([
{
method: 'Runtime.callFunctionOn',
params: {
arguments: [{ value: 'target-id' }, { value: 1024 }, { value: 768 }],
awaitPromise: true,
functionDeclaration: expect.stringContaining('browserWindow.setContentSize(width, height, false)'),
objectId: 'electron-object',
},
},
])
})
4 changes: 1 addition & 3 deletions packages/video-recording-worker/src/parts/Ffmpeg/Ffmpeg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ export const start = async (platform: string, outFile: string): Promise<void> =>
throw new Error(`ffmpeg binary not found at ${ffmpegPath}`)
}
const fps = 25
const width = 1024
const height = 768
const options = GetFfmpegOptions.getFfmpegOptions(fps, width, height, outFile)
const options = GetFfmpegOptions.getFfmpegOptions(fps, outFile)
const childProcess = spawn(ffmpegPath, options, {
stdio: ['pipe', 'pipe', 'pipe'],
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import * as Assert from '../Assert/Assert.ts'

export const getFfmpegOptions = (fps: number, width: number, height: number, outFile: string): readonly string[] => {
export const getFfmpegOptions = (fps: number, outFile: string): readonly string[] => {
Assert.number(fps)
Assert.number(width)
Assert.number(height)
Assert.string(outFile)
const args = [
'-loglevel',
Expand Down Expand Up @@ -42,8 +40,6 @@ export const getFfmpegOptions = (fps: number, width: number, height: number, out
'1M',
'-threads',
'1',
'-vf',
`pad=${width}:${height}:0:0:gray,crop=${width}:${height}:0:0`,
outFile,
]
return args
Expand Down
21 changes: 8 additions & 13 deletions packages/video-recording-worker/test/GetFfmpegOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect, test } from '@jest/globals'
import * as GetFfmpegOptions from '../src/parts/GetFfmpegOptions/GetFfmpegOptions.ts'

test('getFfmpegOptions returns array of strings', () => {
const result = GetFfmpegOptions.getFfmpegOptions(25, 1024, 768, '/tmp/test.webm')
const result = GetFfmpegOptions.getFfmpegOptions(25, '/tmp/test.webm')
expect(Array.isArray(result)).toBe(true)
expect(result.length).toBeGreaterThan(0)
for (const arg of result) {
Expand All @@ -12,35 +12,30 @@ test('getFfmpegOptions returns array of strings', () => {

test('getFfmpegOptions includes fps in arguments', () => {
const fps = 30
const result = GetFfmpegOptions.getFfmpegOptions(fps, 1024, 768, '/tmp/test.webm')
const result = GetFfmpegOptions.getFfmpegOptions(fps, '/tmp/test.webm')
expect(result).toContain('30')
})

test('getFfmpegOptions includes output file in arguments', () => {
const outFile = '/tmp/output.webm'
const result = GetFfmpegOptions.getFfmpegOptions(25, 1024, 768, outFile)
const result = GetFfmpegOptions.getFfmpegOptions(25, outFile)
expect(result).toContain(outFile)
})

test('getFfmpegOptions includes video filter with dimensions', () => {
const width = 1920
const height = 1080
const result = GetFfmpegOptions.getFfmpegOptions(25, width, height, '/tmp/test.webm')
const filterArg = result.find((arg) => arg.includes('pad=') && arg.includes('crop='))
expect(filterArg).toBeDefined()
expect(filterArg).toContain(`pad=${width}:${height}`)
expect(filterArg).toContain(`crop=${width}:${height}`)
test('getFfmpegOptions preserves the dimensions provided by Chrome', () => {
const result = GetFfmpegOptions.getFfmpegOptions(25, '/tmp/test.webm')
expect(result).not.toContain('-vf')
})

test('getFfmpegOptions includes required codec arguments', () => {
const result = GetFfmpegOptions.getFfmpegOptions(25, 1024, 768, '/tmp/test.webm')
const result = GetFfmpegOptions.getFfmpegOptions(25, '/tmp/test.webm')
expect(result).toContain('-c:v')
expect(result).toContain('vp8')
expect(result).toContain('mjpeg')
})

test('getFfmpegOptions includes error loglevel', () => {
const result = GetFfmpegOptions.getFfmpegOptions(25, 1024, 768, '/tmp/test.webm')
const result = GetFfmpegOptions.getFfmpegOptions(25, '/tmp/test.webm')
expect(result).toContain('-loglevel')
expect(result).toContain('error')
})
Loading