2019-07-26 16:37:59 +03:00
import { expect } from 'chai' ;
2020-04-07 03:04:09 +03:00
import { dialog , BrowserWindow } from 'electron/main' ;
2023-01-26 00:01:25 +03:00
import { closeAllWindows } from './lib/window-helpers' ;
2023-02-24 02:53:53 +03:00
import { ifit } from './lib/spec-helpers' ;
2023-06-15 17:42:27 +03:00
import { setTimeout } from 'node:timers/promises' ;
2016-12-02 01:15:05 +03:00
describe ( 'dialog module' , ( ) = > {
describe ( 'showOpenDialog' , ( ) = > {
2019-07-26 16:37:59 +03:00
afterEach ( closeAllWindows ) ;
ifit ( process . platform !== 'win32' ) ( 'should not throw for valid cases' , ( ) = > {
2019-05-21 17:08:22 +03:00
expect ( ( ) = > {
dialog . showOpenDialog ( { title : 'i am title' } ) ;
} ) . to . not . throw ( ) ;
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
const w = new BrowserWindow ( ) ;
2019-05-21 17:08:22 +03:00
dialog . showOpenDialog ( w , { title : 'i am title' } ) ;
} ) . to . not . throw ( ) ;
} ) ;
2016-12-02 01:15:05 +03:00
it ( 'throws errors when the options are invalid' , ( ) = > {
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showOpenDialog ( { properties : false as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Properties must be an array/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showOpenDialog ( { title : 300 as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Title must be a string/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showOpenDialog ( { buttonLabel : [ ] as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Button label must be a string/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showOpenDialog ( { defaultPath : { } as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Default path must be a string/ ) ;
2017-02-09 16:23:02 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showOpenDialog ( { message : { } as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Message must be a string/ ) ;
2016-12-02 01:15:05 +03:00
} ) ;
} ) ;
describe ( 'showSaveDialog' , ( ) = > {
2019-07-26 16:37:59 +03:00
afterEach ( closeAllWindows ) ;
ifit ( process . platform !== 'win32' ) ( 'should not throw for valid cases' , ( ) = > {
2019-05-21 17:08:22 +03:00
expect ( ( ) = > {
dialog . showSaveDialog ( { title : 'i am title' } ) ;
} ) . to . not . throw ( ) ;
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
const w = new BrowserWindow ( ) ;
2019-05-21 17:08:22 +03:00
dialog . showSaveDialog ( w , { title : 'i am title' } ) ;
} ) . to . not . throw ( ) ;
} ) ;
2016-12-02 01:15:05 +03:00
it ( 'throws errors when the options are invalid' , ( ) = > {
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showSaveDialog ( { title : 300 as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Title must be a string/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showSaveDialog ( { buttonLabel : [ ] as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Button label must be a string/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showSaveDialog ( { defaultPath : { } as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Default path must be a string/ ) ;
2017-02-09 16:23:02 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showSaveDialog ( { message : { } as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Message must be a string/ ) ;
2017-02-09 16:23:02 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showSaveDialog ( { nameFieldLabel : { } as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Name field label must be a string/ ) ;
2016-12-02 01:15:05 +03:00
} ) ;
} ) ;
describe ( 'showMessageBox' , ( ) = > {
2019-11-01 23:37:02 +03:00
afterEach ( closeAllWindows ) ;
2019-05-21 17:08:22 +03:00
2019-07-26 16:37:59 +03:00
// parentless message boxes are synchronous on macOS
2023-02-12 05:52:32 +03:00
// dangling message boxes on windows cause a DCHECK: https://source.chromium.org/chromium/chromium/src/+/main:base/win/message_window.cc;drc=7faa4bf236a866d007dc5672c9ce42660e67a6a6;l=68
2019-07-26 16:37:59 +03:00
ifit ( process . platform !== 'darwin' && process . platform !== 'win32' ) ( 'should not throw for a parentless message box' , ( ) = > {
2019-05-21 17:08:22 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showMessageBox ( { message : 'i am message' } ) ;
2019-05-21 17:08:22 +03:00
} ) . to . not . throw ( ) ;
2019-07-26 16:37:59 +03:00
} ) ;
2019-05-21 17:08:22 +03:00
2019-07-26 16:37:59 +03:00
ifit ( process . platform !== 'win32' ) ( 'should not throw for valid cases' , ( ) = > {
2019-05-21 17:08:22 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
const w = new BrowserWindow ( ) ;
dialog . showMessageBox ( w , { message : 'i am message' } ) ;
2019-05-21 17:08:22 +03:00
} ) . to . not . throw ( ) ;
} ) ;
2016-12-02 01:15:05 +03:00
it ( 'throws errors when the options are invalid' , ( ) = > {
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2023-05-17 20:33:30 +03:00
dialog . showMessageBox ( undefined as any , { type : 'not-a-valid-type' as any , message : '' } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Invalid message box type/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showMessageBox ( null as any , { buttons : false as any , message : '' } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Buttons must be an array/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showMessageBox ( { title : 300 as any , message : '' } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Title must be a string/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showMessageBox ( { message : [ ] as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Message must be a string/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showMessageBox ( { detail : 3.14 as any , message : '' } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Detail must be a string/ ) ;
2017-02-06 18:35:36 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showMessageBox ( { checkboxLabel : false as any , message : '' } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /checkboxLabel must be a string/ ) ;
2016-12-02 01:15:05 +03:00
} ) ;
} ) ;
2021-07-15 01:59:27 +03:00
describe ( 'showMessageBox with signal' , ( ) = > {
afterEach ( closeAllWindows ) ;
it ( 'closes message box immediately' , async ( ) = > {
const controller = new AbortController ( ) ;
const signal = controller . signal ;
const w = new BrowserWindow ( ) ;
const p = dialog . showMessageBox ( w , { signal , message : 'i am message' } ) ;
controller . abort ( ) ;
const result = await p ;
expect ( result . response ) . to . equal ( 0 ) ;
} ) ;
it ( 'closes message box after a while' , async ( ) = > {
const controller = new AbortController ( ) ;
const signal = controller . signal ;
const w = new BrowserWindow ( ) ;
const p = dialog . showMessageBox ( w , { signal , message : 'i am message' } ) ;
2023-02-24 02:53:53 +03:00
await setTimeout ( 500 ) ;
2021-07-15 01:59:27 +03:00
controller . abort ( ) ;
2024-01-18 15:21:15 +03:00
const result = await p ;
expect ( result . response ) . to . equal ( 0 ) ;
} ) ;
it ( 'does not crash when there is a defaultId but no buttons' , async ( ) = > {
const controller = new AbortController ( ) ;
const signal = controller . signal ;
const w = new BrowserWindow ( ) ;
const p = dialog . showMessageBox ( w , {
signal ,
message : 'i am message' ,
type : 'info' ,
defaultId : 0 ,
title : 'i am title'
} ) ;
controller . abort ( ) ;
2021-07-15 01:59:27 +03:00
const result = await p ;
expect ( result . response ) . to . equal ( 0 ) ;
} ) ;
it ( 'cancels message box' , async ( ) = > {
const controller = new AbortController ( ) ;
const signal = controller . signal ;
const w = new BrowserWindow ( ) ;
const p = dialog . showMessageBox ( w , {
signal ,
message : 'i am message' ,
buttons : [ 'OK' , 'Cancel' ] ,
cancelId : 1
} ) ;
controller . abort ( ) ;
const result = await p ;
expect ( result . response ) . to . equal ( 1 ) ;
} ) ;
it ( 'cancels message box after a while' , async ( ) = > {
const controller = new AbortController ( ) ;
const signal = controller . signal ;
const w = new BrowserWindow ( ) ;
const p = dialog . showMessageBox ( w , {
signal ,
message : 'i am message' ,
buttons : [ 'OK' , 'Cancel' ] ,
cancelId : 1
} ) ;
2023-02-24 02:53:53 +03:00
await setTimeout ( 500 ) ;
2021-07-15 01:59:27 +03:00
controller . abort ( ) ;
const result = await p ;
expect ( result . response ) . to . equal ( 1 ) ;
} ) ;
} ) ;
2016-12-02 01:15:05 +03:00
describe ( 'showErrorBox' , ( ) = > {
it ( 'throws errors when the options are invalid' , ( ) = > {
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
( dialog . showErrorBox as any ) ( ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Insufficient number of arguments/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showErrorBox ( 3 as any , 'four' ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Error processing argument at index 0/ ) ;
2016-12-02 01:15:05 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showErrorBox ( 'three' , 4 as any ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /Error processing argument at index 1/ ) ;
2016-12-02 01:15:05 +03:00
} ) ;
} ) ;
2017-04-04 20:49:21 +03:00
describe ( 'showCertificateTrustDialog' , ( ) = > {
it ( 'throws errors when the options are invalid' , ( ) = > {
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
( dialog . showCertificateTrustDialog as any ) ( ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /options must be an object/ ) ;
2017-04-04 20:49:21 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showCertificateTrustDialog ( { } as any ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /certificate must be an object/ ) ;
2017-04-04 20:49:21 +03:00
2018-06-18 17:56:03 +03:00
expect ( ( ) = > {
2019-07-26 16:37:59 +03:00
dialog . showCertificateTrustDialog ( { certificate : { } as any , message : false as any } ) ;
2018-06-18 17:56:03 +03:00
} ) . to . throw ( /message must be a string/ ) ;
2017-04-04 20:49:21 +03:00
} ) ;
} ) ;
2016-12-02 01:15:05 +03:00
} ) ;