@vpalmisano/webrtcperf 4.3.2 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/docker.ts ADDED
@@ -0,0 +1,131 @@
1
+ import path from 'path'
2
+ import Docker from 'dockerode'
3
+ import { logger, resolvePackagePath } from './utils'
4
+ import { loadConfig } from './config'
5
+ import fs from 'fs'
6
+
7
+ const log = logger('webrtcperf:docker')
8
+
9
+ export async function runWithDocker(argv: string[]) {
10
+ const docker = new Docker()
11
+ const configPath = argv.filter(s => s !== '--docker')[0]
12
+ if (!configPath) throw new Error('No configuration file specified')
13
+ const configName = path.basename(configPath)
14
+ const config = (await loadConfig(configPath))[0]
15
+
16
+ const startTimestamp = Date.now()
17
+ const dataDir = path.resolve(path.dirname(configPath), 'logs', `${startTimestamp}`)
18
+ await fs.promises.mkdir(dataDir, { recursive: true })
19
+
20
+ const binds: string[] = [
21
+ `${path.resolve(configPath)}:/config/${configName}:ro`,
22
+ '/dev/shm:/dev/shm',
23
+ `${dataDir}:/data`,
24
+ '/tmp/webrtcperf-cache:/root/.webrtcperf',
25
+ ]
26
+
27
+ if (config.scriptPath) {
28
+ const scriptName = path.basename(config.scriptPath)
29
+ binds.push(`${path.resolve(config.scriptPath)}:/scripts/${scriptName}:ro`)
30
+ }
31
+
32
+ if (process.env.DEBUG_SRC) {
33
+ binds.push(`${resolvePackagePath('app.min.js')}:/app/app.min.js:ro`)
34
+ }
35
+
36
+ const portBindings: Docker.PortMap = {}
37
+ const exposedPorts: { [portAndProtocol: string]: object } = {}
38
+ if (config.debuggingPort) {
39
+ for (let i = 0; i < config.sessions; i++) {
40
+ const port = `${config.debuggingPort + i}/tcp`
41
+ portBindings[port] = [{ HostPort: `${config.debuggingPort + i}` }]
42
+ exposedPorts[port] = {}
43
+ }
44
+ }
45
+
46
+ const env = [
47
+ `DEBUG_LEVEL=${process.env.DEBUG_LEVEL || 'info'}`,
48
+ 'SHOW_PAGE_LOG=false',
49
+ 'SHOW_STATS=false',
50
+ 'SERVER_PORT=5000',
51
+ 'SERVER_USE_HTTPS=true',
52
+ 'SERVER_DATA=/data',
53
+ `START_TIMESTAMP=${startTimestamp}`,
54
+ `STATS_PATH=/data/stats.csv`,
55
+ `PAGE_LOG_PATH=/data/page.log`,
56
+ `DETAILED_STATS_PATH=/data/detailed-stats.csv`,
57
+ ]
58
+
59
+ if (config.scriptPath) {
60
+ const scriptName = path.basename(config.scriptPath)
61
+ env.push(`SCRIPT_PATH=/scripts/${scriptName}`)
62
+ }
63
+
64
+ if (config.debuggingPort) {
65
+ env.push(`DEBUGGING_PORT=${config.debuggingPort}`)
66
+ }
67
+
68
+ if (config.prometheusPushgateway.startsWith('http://localhost')) {
69
+ env.push('PROMETHEUS_PUSHGATEWAY=http://pushgateway:9091')
70
+ }
71
+
72
+ const containerConfig: Docker.ContainerCreateOptions = {
73
+ Image: 'ghcr.io/vpalmisano/webrtcperf:devel',
74
+ name: 'webrtcperf',
75
+ Cmd: [`/config/${configName}`],
76
+ HostConfig: {
77
+ Binds: binds,
78
+ PortBindings: portBindings,
79
+ CapAdd: ['NET_ADMIN'],
80
+ NetworkMode: config.prometheusPushgateway.startsWith('http://localhost') ? 'prometheus-stack_default' : 'bridge',
81
+ },
82
+ Env: env,
83
+ AttachStdin: true,
84
+ AttachStdout: true,
85
+ AttachStderr: true,
86
+ Tty: true,
87
+ OpenStdin: true,
88
+ StdinOnce: true,
89
+ ExposedPorts: exposedPorts,
90
+ }
91
+
92
+ try {
93
+ if (!process.env.DEBUG_SRC) {
94
+ log.info('Pulling latest development image...')
95
+ await docker.pull('ghcr.io/vpalmisano/webrtcperf:devel')
96
+ }
97
+
98
+ try {
99
+ const existingContainer = await docker.getContainer('webrtcperf')
100
+ await existingContainer.remove({ force: true })
101
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
102
+ } catch (err: unknown) {
103
+ // Container doesn't exist, continue
104
+ }
105
+
106
+ const container = await docker.createContainer(containerConfig)
107
+ await container.start()
108
+
109
+ const stream = await container.attach({
110
+ stream: true,
111
+ stdin: true,
112
+ stdout: true,
113
+ stderr: true,
114
+ })
115
+
116
+ process.stdin.pipe(stream)
117
+ stream.pipe(process.stdout)
118
+
119
+ await new Promise(resolve => {
120
+ container.wait((err: Error, data: { StatusCode: number }) => {
121
+ if (err) log.error('Error waiting for container:', data, err.stack)
122
+ resolve(data)
123
+ })
124
+ })
125
+
126
+ await container.remove()
127
+ } catch (error) {
128
+ log.error('Docker operation failed:', error)
129
+ throw error
130
+ }
131
+ }
package/src/session.ts CHANGED
@@ -676,7 +676,7 @@ export class Session extends EventEmitter {
676
676
  deviceScaleFactor: this.deviceScaleFactor,
677
677
  isMobile: false,
678
678
  hasTouch: false,
679
- isLandscape: false,
679
+ isLandscape: true,
680
680
  },
681
681
  })
682
682
  } catch (err) {
@@ -803,7 +803,7 @@ try {
803
803
  } catch (err) {
804
804
  console.error('[webrtcperf] Error parsing scriptParams:', err);
805
805
  webrtcperf.params = {};
806
- }
806
+ };
807
807
  `
808
808
 
809
809
  if (this.serverPort) {
@@ -910,15 +910,22 @@ webrtcperf.config.AUDIO_URL = "http${this.serverUseHttps ? 's' : ''}://localhost
910
910
  if (this.localStorage) {
911
911
  log.debug('Using localStorage:', this.localStorage)
912
912
  Object.entries(this.localStorage).map(([key, value]) => {
913
- cmd += `localStorage.setItem('${key}', '${JSON.stringify(value)}');\n`
913
+ cmd += `window.localStorage.setItem('${key}', ${JSON.stringify(value)});\n`
914
914
  })
915
915
  }
916
916
  if (this.sessionStorage) {
917
917
  log.debug('Using sessionStorage:', this.sessionStorage)
918
918
  Object.entries(this.sessionStorage).map(([key, value]) => {
919
- cmd += `sessionStorage.setItem('${key}', '${JSON.stringify(value)}');\n`
919
+ cmd += `window.sessionStorage.setItem('${key}', ${JSON.stringify(value)});\n`
920
920
  })
921
921
  }
922
+ cmd += `
923
+ Object.defineProperty(window.screen, 'width', { value: ${this.windowWidth}, writable: false });
924
+ Object.defineProperty(window.screen, 'height', { value: ${this.windowHeight}, writable: false });
925
+ Object.defineProperty(window.screen, 'availWidth', { value: ${this.windowWidth}, writable: false });
926
+ Object.defineProperty(window.screen, 'availHeight', { value: ${this.windowHeight}, writable: false });
927
+ Object.defineProperty(window.screen.orientation, 'type', { value: 'landscape-primary', writable: false });
928
+ `
922
929
  log.debug('init command:', cmd)
923
930
  await page.evaluateOnNewDocument(cmd)
924
931
 
@@ -1305,7 +1312,7 @@ webrtcperf.config.AUDIO_URL = "http${this.serverUseHttps ? 's' : ''}://localhost
1305
1312
  if (this.showPageLog || saveFile) {
1306
1313
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1307
1314
  page.on('pageerror', async (error: any) => {
1308
- const text = `pageerror: ${error.message?.message || error.message} - ${error.message?.stack || error.stack}`
1315
+ const text = `pageerror: ${error?.message?.message || error?.message || error} - ${error?.message?.stack || error?.stack}`
1309
1316
  await this.onPageMessage(index, 'error', text, saveFile)
1310
1317
  })
1311
1318
 
package/src/utils.ts CHANGED
@@ -651,28 +651,37 @@ export async function runShellCommand(
651
651
  cmd: string,
652
652
  verbose = false,
653
653
  maxBuffer = 1024 * 1024,
654
+ { provideStdin = false, returnStdout = true, returnStderr = true } = {},
654
655
  ): Promise<{ stdout: string; stderr: string }> {
655
656
  if (verbose) log.debug(`runShellCommand cmd: ${cmd}`)
656
657
  return new Promise((resolve, reject) => {
657
658
  const p = spawn(cmd, {
658
659
  shell: true,
659
- stdio: ['ignore', 'pipe', 'pipe'],
660
+ stdio: [
661
+ provideStdin ? 'inherit' : 'ignore',
662
+ returnStdout ? 'pipe' : 'inherit',
663
+ returnStderr ? 'pipe' : 'inherit',
664
+ ],
660
665
  detached: true,
661
666
  })
662
667
  let stdout = ''
663
668
  let stderr = ''
664
- p.stdout.on('data', data => {
665
- if (maxBuffer && stdout.length > maxBuffer) {
666
- stdout = stdout.slice(data.length)
667
- }
668
- stdout += data
669
- })
670
- p.stderr.on('data', data => {
671
- if (maxBuffer && stderr.length > maxBuffer) {
672
- stderr = stderr.slice(data.length)
673
- }
674
- stderr += data
675
- })
669
+ if (returnStdout) {
670
+ p.stdout?.on('data', data => {
671
+ if (maxBuffer && stdout.length > maxBuffer) {
672
+ stdout = stdout.slice(data.length)
673
+ }
674
+ stdout += data
675
+ })
676
+ }
677
+ if (returnStderr) {
678
+ p.stderr?.on('data', data => {
679
+ if (maxBuffer && stderr.length > maxBuffer) {
680
+ stderr = stderr.slice(data.length)
681
+ }
682
+ stderr += data
683
+ })
684
+ }
676
685
  p.once('error', err => reject(err))
677
686
  p.once('close', code => {
678
687
  if (code !== 0) {