2021-11-03 00:45:52 +08:00
require ( 'dotenv' ) . config ( ) ;
const sha1 = require ( 'sha1' ) ;
const axios = require ( 'axios' ) ;
2023-02-14 21:59:46 +08:00
const { test , expect } = require ( '@playwright/test' ) ;
2022-09-06 11:45:53 +08:00
const xml2js = require ( 'xml2js' ) ;
2023-06-09 01:27:18 +08:00
const { runScript } = require ( './util' ) ;
2023-07-31 22:24:25 +08:00
const { env } = require ( 'node:process' ) ;
2022-09-06 11:45:53 +08:00
2023-07-31 22:24:25 +08:00
const { format } = require ( 'node:util' ) ;
// This is version 4 of chalk, not version 5, which uses ESM
const chalk = require ( 'chalk' ) ;
2022-09-06 11:45:53 +08:00
const parameters = require ( './parameters' ) ;
2021-11-03 00:45:52 +08:00
function getRandomInt ( min , max ) {
min = Math . ceil ( min ) ;
max = Math . floor ( max ) ;
return Math . floor ( Math . random ( ) * ( max - min ) ) + min ;
}
2022-10-10 03:10:05 +08:00
function apiCallUrl ( name , callParams ) {
2022-09-06 11:45:53 +08:00
const query = new URLSearchParams ( callParams ) . toString ( ) ;
2023-02-14 21:59:46 +08:00
const apiCall = ` ${ name } ${ query } ${ parameters . secret } ` ;
const checksum = sha1 ( apiCall ) ;
2022-09-06 11:45:53 +08:00
const url = ` ${ parameters . server } / ${ name } ? ${ query } &checksum= ${ checksum } ` ;
2022-10-10 03:10:05 +08:00
return url ;
}
function apiCall ( name , callParams ) {
const url = apiCallUrl ( name , callParams ) ;
2022-12-15 02:51:26 +08:00
return axios . get ( url , { adapter : 'http' } ) . then ( response => xml2js . parseStringPromise ( response . data ) ) ;
2022-09-06 11:45:53 +08:00
}
2023-07-31 22:24:25 +08:00
function createMeetingUrl ( params , createParameter , customMeetingId ) {
2023-02-14 21:59:46 +08:00
const meetingID = ( customMeetingId ) ? customMeetingId : ` random- ${ getRandomInt ( 1000000 , 10000000 ) . toString ( ) } ` ;
2021-11-03 00:45:52 +08:00
const mp = params . moderatorPW ;
const ap = params . attendeePW ;
2023-02-14 21:59:46 +08:00
const baseQuery = ` name= ${ meetingID } &meetingID= ${ meetingID } &attendeePW= ${ ap } &moderatorPW= ${ mp } `
2021-12-15 01:10:44 +08:00
+ ` &allowStartStopRecording=true&autoStartRecording=false&welcome= ${ params . welcome } ` ;
2023-07-31 22:24:25 +08:00
const query = createParameter !== undefined ? ` ${ baseQuery } & ${ createParameter } ` : baseQuery ;
2023-02-14 21:59:46 +08:00
const apiCall = ` create ${ query } ${ params . secret } ` ;
const checksum = sha1 ( apiCall ) ;
2021-11-03 00:45:52 +08:00
const url = ` ${ params . server } /create? ${ query } &checksum= ${ checksum } ` ;
2022-10-10 03:10:05 +08:00
return url ;
}
2023-07-31 22:24:25 +08:00
function createMeetingPromise ( params , createParameter , customMeetingId ) {
const url = createMeetingUrl ( params , createParameter , customMeetingId ) ;
2022-12-15 02:51:26 +08:00
return axios . get ( url , { adapter : 'http' } ) ;
2022-10-10 03:10:05 +08:00
}
2023-07-31 22:24:25 +08:00
async function createMeeting ( params , createParameter , page ) {
const promise = createMeetingPromise ( params , createParameter ) ;
2022-11-08 05:59:16 +08:00
const response = await promise ;
2022-11-08 07:22:14 +08:00
expect ( response . status ) . toEqual ( 200 ) ;
2023-02-14 21:59:46 +08:00
const xmlResponse = await xml2js . parseStringPromise ( response . data ) ;
return xmlResponse . response . meetingID [ 0 ] ;
2021-11-03 00:45:52 +08:00
}
2023-07-31 22:24:25 +08:00
function getJoinURL ( meetingID , params , moderator , joinParameter ) {
2021-11-03 00:45:52 +08:00
const pw = moderator ? params . moderatorPW : params . attendeePW ;
2023-02-14 21:59:46 +08:00
const baseQuery = ` fullName= ${ params . fullName } &meetingID= ${ meetingID } &password= ${ pw } ` ;
2023-07-31 22:24:25 +08:00
const query = joinParameter !== undefined ? ` ${ baseQuery } & ${ joinParameter } ` : baseQuery ;
2023-02-14 21:59:46 +08:00
const apiCall = ` join ${ query } ${ params . secret } ` ;
const checksum = sha1 ( apiCall ) ;
2021-11-03 00:45:52 +08:00
return ` ${ params . server } /join? ${ query } &checksum= ${ checksum } ` ;
}
2023-06-09 01:27:18 +08:00
async function checkRootPermission ( ) {
const checkSudo = await runScript ( 'timeout -k 1 1 sudo id' , {
handleOutput : ( output ) => output ? true : false
} )
await expect ( checkSudo , 'Sudo failed: need to run this test with root permission (can be fixed by running "sudo -v" and entering the password)' ) . toBeTruthy ( ) ;
}
2023-07-31 22:24:25 +08:00
async function console _format ( msg , CONSOLE _options ) {
const args = await Promise . all ( msg . args ( ) . map ( itm => itm . jsonValue ( ) ) ) ;
// For Chrome, args[0] is a format string that we will process using
// node.js's util.format, but that function discards css style
// information from "%c" format specifiers. So first loop over the
// format string, replacing every "%c" with "%s" and replacing the
// corresponding css style with an ANSI color sequence.
//
// See https://console.spec.whatwg.org/ sections 2.2.1 and 2.3.4
let split _arg0 = args [ 0 ] . split ( "%" ) ;
for ( let i = 1 , j = 1 ; i < split _arg0 . length ; i ++ , j ++ ) {
if ( split _arg0 [ i ] . startsWith ( 'c' ) ) {
split _arg0 [ i ] = 's' + split _arg0 [ i ] . substr ( 1 ) ;
const styles = args [ j ] . split ( ';' ) ;
args [ j ] = '' ;
for ( const style of styles ) {
const stdStyle = style . trim ( ) . toLowerCase ( ) ;
if ( stdStyle . startsWith ( 'color:' ) && CONSOLE _options . colorize ) {
const color = stdStyle . substr ( 6 ) . trim ( ) ;
args [ j ] = chalk . keyword ( color ) . _styler . open ;
} else if ( stdStyle . startsWith ( 'font-size:' ) && CONSOLE _options . drop _references ) {
// For Chrome, we "drop references" by discarding everything after a font size change
split _arg0 . length = i ;
args . length = j ;
}
}
} else if ( split _arg0 [ i ] == "" ) {
// format is "%%", so don't do special processing for
// split_arg0[i+1], and only increment i, not j
i ++ ; // NOSONAR
}
}
args [ 0 ] = split _arg0 . join ( '%' ) ;
// see playwright consoleMessage class documentation
let result = format ( ... args ) ;
if ( CONSOLE _options . drop _references ) {
// For Firefox, we "drop references" by discarding a URL at the end of the line
result = result . replace ( /https:\/\/\S*$/ , '' ) ;
}
if ( CONSOLE _options . noClientLogger ) {
result = result . replace ( /clientLogger: / , '' ) ;
}
if ( CONSOLE _options . drop _timestamps ) {
// timestamp formatting is a bit complicated, with four "%s" fields and corresponding arguments,
// so just filter them out (if requested) after all the other formatting is done
result = result . replace ( /\[\d\d:\d\d:\d\d:\d\d\d\d\] / , '' ) ;
}
if ( CONSOLE _options . line _label ) {
if ( CONSOLE _options . colorize ) {
result = chalk . keyword ( 'green' ) ( CONSOLE _options . line _label ) + result ;
} else {
result = CONSOLE _options . line _label + result ;
}
}
return result ;
}
async function setBrowserLogs ( page ) {
const CONSOLE _strings = env . CONSOLE . split ( ',' ) . map ( opt => opt . trim ( ) . toLowerCase ( ) ) ;
const CONSOLE _options = {
colorize : CONSOLE _strings . includes ( 'color' ) || CONSOLE _strings . includes ( 'colour' ) ,
drop _references : CONSOLE _strings . includes ( 'norefs' ) ,
drop _timestamps : CONSOLE _strings . includes ( 'nots' ) ,
line _label : CONSOLE _strings . includes ( 'label' ) ? this . username + " " : undefined ,
noClientLogger : CONSOLE _strings . includes ( 'nocl' ) || CONSOLE _strings . includes ( 'noclientlogger' ) ,
} ;
page . on ( 'console' , async ( msg ) => console . log ( await console _format ( msg , CONSOLE _options ) ) ) ;
}
2022-12-01 21:43:36 +08:00
function linkIssue ( issueNumber ) {
test . info ( ) . annotations . push ( {
type : 'Issue/PR' ,
description : ` https://github.com/bigbluebutton/bigbluebutton/issues/ ${ issueNumber } ` ,
} ) ;
}
2021-11-27 04:01:41 +08:00
function sleep ( time ) {
return new Promise ( ( resolve ) => {
setTimeout ( resolve , time ) ;
} ) ;
}
2024-01-20 00:42:01 +08:00
async function initializePages ( testInstance , browser , initOptions ) {
const { isMultiUser , createParameter , joinParameter } = initOptions || { } ;
const context = await browser . newContext ( ) ;
const page = await context . newPage ( ) ;
await testInstance . initModPage ( page , true , { createParameter , joinParameter } ) ;
if ( isMultiUser ) await testInstance . initUserPage ( true , context , { createParameter , joinParameter } ) ;
return {
context ,
} ;
}
2021-11-03 00:45:52 +08:00
exports . getRandomInt = getRandomInt ;
2022-10-10 03:10:05 +08:00
exports . apiCallUrl = apiCallUrl ;
2022-09-06 11:45:53 +08:00
exports . apiCall = apiCall ;
2022-10-10 03:10:05 +08:00
exports . createMeetingUrl = createMeetingUrl ;
exports . createMeetingPromise = createMeetingPromise ;
2021-11-03 00:45:52 +08:00
exports . createMeeting = createMeeting ;
exports . getJoinURL = getJoinURL ;
2023-06-09 01:27:18 +08:00
exports . checkRootPermission = checkRootPermission ;
2022-12-01 21:43:36 +08:00
exports . linkIssue = linkIssue ;
2021-11-27 04:01:41 +08:00
exports . sleep = sleep ;
2023-07-31 22:24:25 +08:00
exports . setBrowserLogs = setBrowserLogs ;
2024-01-20 00:42:01 +08:00
exports . initializePages = initializePages ;