2020-03-20 20:28:31 +00:00
import { expect } from 'chai' ;
2023-06-15 14:42:27 +00:00
import * as http from 'node:http' ;
import * as fs from 'node:fs' ;
import * as os from 'node:os' ;
import * as path from 'node:path' ;
import * as ChildProcess from 'node:child_process' ;
2020-04-07 00:04:09 +00:00
import { session , net } from 'electron/main' ;
2023-06-15 14:42:27 +00:00
import { Socket } from 'node:net' ;
2023-02-20 11:30:57 +00:00
import { ifit , listen } from './lib/spec-helpers' ;
2023-06-15 14:42:27 +00:00
import { once } from 'node:events' ;
2020-03-20 20:28:31 +00:00
const appPath = path . join ( __dirname , 'fixtures' , 'api' , 'net-log' ) ;
const dumpFile = path . join ( os . tmpdir ( ) , 'net_log.json' ) ;
const dumpFileDynamic = path . join ( os . tmpdir ( ) , 'net_log_dynamic.json' ) ;
const testNetLog = ( ) = > session . fromPartition ( 'net-log' ) . netLog ;
2018-06-19 01:45:58 +00:00
describe ( 'netLog module' , ( ) = > {
2020-03-20 20:28:31 +00:00
let server : http.Server ;
let serverUrl : string ;
const connections : Set < Socket > = new Set ( ) ;
2018-06-19 01:45:58 +00:00
2023-02-20 11:30:57 +00:00
before ( async ( ) = > {
2020-03-20 20:28:31 +00:00
server = http . createServer ( ) ;
2018-06-19 01:45:58 +00:00
server . on ( 'connection' , ( connection ) = > {
2020-03-20 20:28:31 +00:00
connections . add ( connection ) ;
2018-06-19 01:45:58 +00:00
connection . once ( 'close' , ( ) = > {
2020-03-20 20:28:31 +00:00
connections . delete ( connection ) ;
} ) ;
} ) ;
2018-06-19 01:45:58 +00:00
server . on ( 'request' , ( request , response ) = > {
2020-03-20 20:28:31 +00:00
response . end ( ) ;
} ) ;
2023-02-20 11:30:57 +00:00
serverUrl = ( await listen ( server ) ) . url ;
2020-03-20 20:28:31 +00:00
} ) ;
2018-06-19 01:45:58 +00:00
2018-06-28 22:40:30 +00:00
after ( done = > {
2018-06-19 01:45:58 +00:00
for ( const connection of connections ) {
2020-03-20 20:28:31 +00:00
connection . destroy ( ) ;
2018-06-19 01:45:58 +00:00
}
server . close ( ( ) = > {
2020-03-20 20:28:31 +00:00
server = null as any ;
done ( ) ;
} ) ;
} ) ;
2018-06-19 01:45:58 +00:00
2019-05-23 22:31:38 +00:00
beforeEach ( ( ) = > {
2020-03-20 20:28:31 +00:00
expect ( testNetLog ( ) . currentlyLogging ) . to . be . false ( 'currently logging' ) ;
} ) ;
2018-06-19 01:45:58 +00:00
afterEach ( ( ) = > {
try {
2018-10-04 18:08:56 +00:00
if ( fs . existsSync ( dumpFile ) ) {
2020-03-20 20:28:31 +00:00
fs . unlinkSync ( dumpFile ) ;
2018-10-04 18:08:56 +00:00
}
if ( fs . existsSync ( dumpFileDynamic ) ) {
2020-03-20 20:28:31 +00:00
fs . unlinkSync ( dumpFileDynamic ) ;
2018-10-04 18:08:56 +00:00
}
2023-07-27 14:53:45 +00:00
} catch {
2018-06-19 01:45:58 +00:00
// Ignore error
}
2020-03-20 20:28:31 +00:00
expect ( testNetLog ( ) . currentlyLogging ) . to . be . false ( 'currently logging' ) ;
} ) ;
2018-06-19 01:45:58 +00:00
2019-02-19 10:48:27 +00:00
it ( 'should begin and end logging to file when .startLogging() and .stopLogging() is called' , async ( ) = > {
2020-03-20 20:28:31 +00:00
await testNetLog ( ) . startLogging ( dumpFileDynamic ) ;
2019-02-19 10:48:27 +00:00
2020-03-20 20:28:31 +00:00
expect ( testNetLog ( ) . currentlyLogging ) . to . be . true ( 'currently logging' ) ;
2019-05-23 22:31:38 +00:00
2020-03-20 20:28:31 +00:00
await testNetLog ( ) . stopLogging ( ) ;
2019-02-19 10:48:27 +00:00
2020-03-20 20:28:31 +00:00
expect ( fs . existsSync ( dumpFileDynamic ) ) . to . be . true ( 'currently logging' ) ;
} ) ;
2019-02-19 10:48:27 +00:00
2019-05-23 22:31:38 +00:00
it ( 'should throw an error when .stopLogging() is called without calling .startLogging()' , async ( ) = > {
2020-03-20 20:28:31 +00:00
await expect ( testNetLog ( ) . stopLogging ( ) ) . to . be . rejectedWith ( 'No net log in progress' ) ;
} ) ;
2019-02-19 10:48:27 +00:00
2019-05-23 22:31:38 +00:00
it ( 'should throw an error when .startLogging() is called with an invalid argument' , ( ) = > {
2020-03-20 20:28:31 +00:00
expect ( ( ) = > testNetLog ( ) . startLogging ( '' ) ) . to . throw ( ) ;
expect ( ( ) = > testNetLog ( ) . startLogging ( null as any ) ) . to . throw ( ) ;
expect ( ( ) = > testNetLog ( ) . startLogging ( [ ] as any ) ) . to . throw ( ) ;
expect ( ( ) = > testNetLog ( ) . startLogging ( 'aoeu' , { captureMode : 'aoeu' as any } ) ) . to . throw ( ) ;
expect ( ( ) = > testNetLog ( ) . startLogging ( 'aoeu' , { maxFileSize : null as any } ) ) . to . throw ( ) ;
} ) ;
2019-07-25 23:06:39 +00:00
it ( 'should include cookies when requested' , async ( ) = > {
2020-03-20 20:28:31 +00:00
await testNetLog ( ) . startLogging ( dumpFileDynamic , { captureMode : 'includeSensitive' } ) ;
const unique = require ( 'uuid' ) . v4 ( ) ;
2021-01-22 19:25:47 +00:00
await new Promise < void > ( ( resolve ) = > {
2020-03-20 20:28:31 +00:00
const req = net . request ( serverUrl ) ;
req . setHeader ( 'Cookie' , ` foo= ${ unique } ` ) ;
2019-07-25 23:06:39 +00:00
req . on ( 'response' , ( response ) = > {
2020-03-20 20:28:31 +00:00
response . on ( 'data' , ( ) = > { } ) ; // https://github.com/electron/electron/issues/19214
response . on ( 'end' , ( ) = > resolve ( ) ) ;
} ) ;
req . end ( ) ;
} ) ;
await testNetLog ( ) . stopLogging ( ) ;
expect ( fs . existsSync ( dumpFileDynamic ) ) . to . be . true ( 'dump file exists' ) ;
const dump = fs . readFileSync ( dumpFileDynamic , 'utf8' ) ;
expect ( dump ) . to . contain ( ` foo= ${ unique } ` ) ;
} ) ;
2019-07-25 23:06:39 +00:00
it ( 'should include socket bytes when requested' , async ( ) = > {
2020-03-20 20:28:31 +00:00
await testNetLog ( ) . startLogging ( dumpFileDynamic , { captureMode : 'everything' } ) ;
const unique = require ( 'uuid' ) . v4 ( ) ;
2021-01-22 19:25:47 +00:00
await new Promise < void > ( ( resolve ) = > {
2020-03-20 20:28:31 +00:00
const req = net . request ( { method : 'POST' , url : serverUrl } ) ;
2019-07-25 23:06:39 +00:00
req . on ( 'response' , ( response ) = > {
2020-03-20 20:28:31 +00:00
response . on ( 'data' , ( ) = > { } ) ; // https://github.com/electron/electron/issues/19214
response . on ( 'end' , ( ) = > resolve ( ) ) ;
} ) ;
req . end ( Buffer . from ( unique ) ) ;
} ) ;
await testNetLog ( ) . stopLogging ( ) ;
expect ( fs . existsSync ( dumpFileDynamic ) ) . to . be . true ( 'dump file exists' ) ;
const dump = fs . readFileSync ( dumpFileDynamic , 'utf8' ) ;
expect ( JSON . parse ( dump ) . events . some ( ( x : any ) = > x . params && x . params . bytes && Buffer . from ( x . params . bytes , 'base64' ) . includes ( unique ) ) ) . to . be . true ( 'uuid present in dump' ) ;
} ) ;
2019-02-19 10:48:27 +00:00
2019-10-30 23:38:21 +00:00
ifit ( process . platform !== 'linux' ) ( 'should begin and end logging automatically when --log-net-log is passed' , async ( ) = > {
2019-05-23 22:31:38 +00:00
const appProcess = ChildProcess . spawn ( process . execPath ,
2018-10-04 18:08:56 +00:00
[ appPath ] , {
2018-06-19 01:45:58 +00:00
env : {
2019-08-05 00:47:42 +00:00
TEST_REQUEST_URL : serverUrl ,
2018-10-04 18:08:56 +00:00
TEST_DUMP_FILE : dumpFile
2018-06-19 01:45:58 +00:00
}
2020-03-20 20:28:31 +00:00
} ) ;
2018-06-19 01:45:58 +00:00
2023-02-23 23:53:53 +00:00
await once ( appProcess , 'exit' ) ;
2020-03-20 20:28:31 +00:00
expect ( fs . existsSync ( dumpFile ) ) . to . be . true ( 'dump file exists' ) ;
} ) ;
2018-06-19 01:45:58 +00:00
2022-06-16 07:46:11 +00:00
ifit ( process . platform !== 'linux' ) ( 'should begin and end logging automatically when --log-net-log is passed, and behave correctly when .startLogging() and .stopLogging() is called' , async ( ) = > {
2019-05-23 22:31:38 +00:00
const appProcess = ChildProcess . spawn ( process . execPath ,
2018-10-04 18:08:56 +00:00
[ appPath ] , {
2018-06-19 01:45:58 +00:00
env : {
2019-08-05 00:47:42 +00:00
TEST_REQUEST_URL : serverUrl ,
2018-10-04 18:08:56 +00:00
TEST_DUMP_FILE : dumpFile ,
TEST_DUMP_FILE_DYNAMIC : dumpFileDynamic ,
2019-08-05 00:47:42 +00:00
TEST_MANUAL_STOP : 'true'
2018-06-19 01:45:58 +00:00
}
2020-03-20 20:28:31 +00:00
} ) ;
2018-06-19 01:45:58 +00:00
2023-02-23 23:53:53 +00:00
await once ( appProcess , 'exit' ) ;
2020-03-20 20:28:31 +00:00
expect ( fs . existsSync ( dumpFile ) ) . to . be . true ( 'dump file exists' ) ;
expect ( fs . existsSync ( dumpFileDynamic ) ) . to . be . true ( 'dynamic dump file exists' ) ;
} ) ;
2018-06-19 01:45:58 +00:00
2019-10-30 23:38:21 +00:00
ifit ( process . platform !== 'linux' ) ( 'should end logging automatically when only .startLogging() is called' , async ( ) = > {
2019-05-23 22:31:38 +00:00
const appProcess = ChildProcess . spawn ( process . execPath ,
2018-06-19 01:45:58 +00:00
[ appPath ] , {
env : {
2019-08-05 00:47:42 +00:00
TEST_REQUEST_URL : serverUrl ,
2018-10-04 18:08:56 +00:00
TEST_DUMP_FILE_DYNAMIC : dumpFileDynamic
2018-06-19 01:45:58 +00:00
}
2020-03-20 20:28:31 +00:00
} ) ;
2018-06-19 01:45:58 +00:00
2023-02-23 23:53:53 +00:00
await once ( appProcess , 'exit' ) ;
2020-03-20 20:28:31 +00:00
expect ( fs . existsSync ( dumpFileDynamic ) ) . to . be . true ( 'dynamic dump file exists' ) ;
} ) ;
} ) ;