1
1
/* @flow */
2
2
3
+ import path from 'path' ;
3
4
import EventEmitter from 'events' ;
4
5
5
6
import { assert } from 'chai' ;
6
7
import { describe , it , beforeEach , afterEach } from 'mocha' ;
7
8
import deepcopy from 'deepcopy' ;
8
- import fs from 'mz/fs ' ;
9
+ import fs from 'fs-extra ' ;
9
10
import sinon from 'sinon' ;
10
11
import WebSocket from 'ws' ;
11
12
@@ -24,6 +25,9 @@ import type {
24
25
import {
25
26
consoleStream , // instance is imported to inspect logged messages
26
27
} from '../../../src/util/logger' ;
28
+ import { TempDir , withTempDir } from '../../../src/util/temp-dir' ;
29
+ import fileExists from '../../../src/util/file-exists' ;
30
+ import isDirectory from '../../../src/util/is-directory' ;
27
31
28
32
function prepareExtensionRunnerParams ( { params} = { } ) {
29
33
const fakeChromeInstance = {
@@ -357,33 +361,257 @@ describe('util/extension-runners/chromium', async () => {
357
361
await runnerInstance . exit ( ) ;
358
362
} ) ;
359
363
360
- it ( 'does pass a user-data-dir flag to chrome' , async ( ) => {
364
+ it ( 'does use a random user-data-dir' , async ( ) => {
365
+
366
+ const { params} = prepareExtensionRunnerParams ( {
367
+ params : { } ,
368
+ } ) ;
369
+
370
+ const spy = sinon . spy ( TempDir . prototype , 'path' ) ;
371
+
372
+ const runnerInstance = new ChromiumExtensionRunner ( params ) ;
373
+ await runnerInstance . run ( ) ;
374
+
375
+ const usedTempPath = spy . returnValues [ 2 ] ;
376
+
377
+ sinon . assert . calledWithMatch ( params . chromiumLaunch , {
378
+ userDataDir : usedTempPath ,
379
+ } ) ;
380
+
381
+ await runnerInstance . exit ( ) ;
382
+ spy . restore ( ) ;
383
+ } ) ;
384
+
385
+ it ( 'does pass a user-data-dir flag to chrome' , async ( ) => withTempDir (
386
+ async ( tmpDir ) => {
387
+
388
+ const { params} = prepareExtensionRunnerParams ( {
389
+ params : {
390
+ chromiumProfile : tmpDir . path ( ) ,
391
+ } ,
392
+ } ) ;
393
+
394
+ const spy = sinon . spy ( TempDir . prototype , 'path' ) ;
395
+
396
+ const runnerInstance = new ChromiumExtensionRunner ( params ) ;
397
+ await runnerInstance . run ( ) ;
398
+
399
+ const usedTempPath = spy . returnValues [ 2 ] ;
400
+
401
+ const { reloadManagerExtension} = runnerInstance ;
402
+
403
+ sinon . assert . calledOnce ( params . chromiumLaunch ) ;
404
+ sinon . assert . calledWithMatch ( params . chromiumLaunch , {
405
+ ignoreDefaultFlags : true ,
406
+ enableExtensions : true ,
407
+ chromePath : undefined ,
408
+ userDataDir : usedTempPath ,
409
+ chromeFlags : [
410
+ ...DEFAULT_CHROME_FLAGS ,
411
+ `--load-extension=${ reloadManagerExtension } ,/fake/sourceDir` ,
412
+ ] ,
413
+ startingUrl : undefined ,
414
+ } ) ;
415
+
416
+ await runnerInstance . exit ( ) ;
417
+ spy . restore ( ) ;
418
+ } )
419
+ ) ;
420
+
421
+ it ( 'does pass existing user-data-dir and profile-directory flag' +
422
+ ' to chrome' , async ( ) => withTempDir (
423
+ async ( tmpDir ) => {
424
+ const tmpPath = tmpDir . path ( ) ;
425
+ await fs . mkdirs ( path . join ( tmpPath , 'userDataDir/Default' ) ) ;
426
+ await fs . outputFile ( path . join ( tmpPath , 'userDataDir/Local State' ) , '' ) ;
427
+ await fs . mkdirs ( path . join ( tmpPath , 'userDataDir/profile' ) ) ;
428
+ await fs . outputFile ( path . join (
429
+ tmpPath , 'userDataDir/profile/Secure Preferences' ) , '' ) ;
430
+
431
+ const { params} = prepareExtensionRunnerParams ( {
432
+ params : {
433
+ chromiumProfile : path . join ( tmpPath , 'userDataDir/profile' ) ,
434
+ keepProfileChanges : true ,
435
+ } ,
436
+ } ) ;
437
+
438
+ const runnerInstance = new ChromiumExtensionRunner ( params ) ;
439
+ await runnerInstance . run ( ) ;
440
+
441
+ const { reloadManagerExtension} = runnerInstance ;
442
+
443
+ sinon . assert . calledOnce ( params . chromiumLaunch ) ;
444
+ sinon . assert . calledWithMatch ( params . chromiumLaunch , {
445
+ ignoreDefaultFlags : true ,
446
+ enableExtensions : true ,
447
+ chromePath : undefined ,
448
+ userDataDir : path . join ( tmpPath , 'userDataDir' ) ,
449
+ chromeFlags : [
450
+ ...DEFAULT_CHROME_FLAGS ,
451
+ `--load-extension=${ reloadManagerExtension } ,/fake/sourceDir` ,
452
+ '--profile-directory=profile' ,
453
+ ] ,
454
+ startingUrl : undefined ,
455
+ } ) ;
456
+
457
+ await runnerInstance . exit ( ) ;
458
+
459
+ } )
460
+ ) ;
461
+
462
+ it ( 'does support some special chars in profile-directory flag' ,
463
+ async ( ) => withTempDir (
464
+ async ( tmpDir ) => {
465
+ const tmpPath = tmpDir . path ( ) ;
466
+ // supported to test: [ _-]
467
+ // not supported by Chromium: [ßäé]
468
+ const profileDirName = ' profile _-\' ' ;
469
+ await fs . mkdirs ( path . join ( tmpPath , 'userDataDir/Default' ) ) ;
470
+ await fs . outputFile ( path . join ( tmpPath , 'userDataDir/Local State' ) , '' ) ;
471
+ await fs . mkdirs ( path . join ( tmpPath , 'userDataDir' , profileDirName ) ) ;
472
+ await fs . outputFile ( path . join (
473
+ tmpPath , 'userDataDir' , profileDirName , 'Secure Preferences' ) , '' ) ;
474
+
475
+ const { params} = prepareExtensionRunnerParams ( {
476
+ params : {
477
+ chromiumProfile : path . join ( tmpPath , 'userDataDir' , profileDirName ) ,
478
+ keepProfileChanges : true ,
479
+ } ,
480
+ } ) ;
481
+
482
+ const runnerInstance = new ChromiumExtensionRunner ( params ) ;
483
+ await runnerInstance . run ( ) ;
484
+
485
+ const { reloadManagerExtension} = runnerInstance ;
486
+
487
+ sinon . assert . calledOnce ( params . chromiumLaunch ) ;
488
+ sinon . assert . calledWithMatch ( params . chromiumLaunch , {
489
+ ignoreDefaultFlags : true ,
490
+ enableExtensions : true ,
491
+ chromePath : undefined ,
492
+ userDataDir : path . join ( tmpPath , 'userDataDir' ) ,
493
+ chromeFlags : [
494
+ ...DEFAULT_CHROME_FLAGS ,
495
+ `--load-extension=${ reloadManagerExtension } ,/fake/sourceDir` ,
496
+ `--profile-directory=${ profileDirName } ` ,
497
+ ] ,
498
+ startingUrl : undefined ,
499
+ } ) ;
500
+
501
+ await runnerInstance . exit ( ) ;
502
+
503
+ } )
504
+ ) ;
505
+
506
+ it ( 'does recognize a UserData dir' , async ( ) => withTempDir (
507
+ async ( tmpDir ) => {
508
+
509
+ const tmpPath = tmpDir . path ( ) ;
510
+ await fs . mkdirs ( path . join ( tmpPath , 'Default' ) ) ;
511
+ await fs . outputFile ( path . join ( tmpPath , 'Local State' ) , '' ) ;
512
+
513
+ assert . isTrue ( await ChromiumExtensionRunner . isUserDataDir ( tmpPath ) ) ;
514
+
515
+ } ) ,
516
+ ) ;
517
+
518
+ it ( 'does reject a UserData dir with Local State dir' , async ( ) => withTempDir (
519
+ async ( tmpDir ) => {
520
+
521
+ const tmpPath = tmpDir . path ( ) ;
522
+ await fs . mkdirs ( path . join ( tmpPath , 'Default' ) ) ;
523
+ // Local State should be a file
524
+ await fs . mkdirs ( path . join ( tmpPath , 'Local State' ) ) ;
525
+
526
+ assert . isFalse ( await ChromiumExtensionRunner . isUserDataDir ( tmpPath ) ) ;
527
+
528
+ } ) ,
529
+ ) ;
530
+
531
+ it ( 'does reject a UserData dir with Default file' , async ( ) => withTempDir (
532
+ async ( tmpDir ) => {
533
+
534
+ const tmpPath = tmpDir . path ( ) ;
535
+ await fs . mkdirs ( path . join ( tmpPath , 'Local State' ) ) ;
536
+ // Default should be a directory
537
+ await fs . outputFile ( path . join ( tmpPath , 'Default' ) , '' ) ;
538
+
539
+ assert . isFalse ( await ChromiumExtensionRunner . isUserDataDir ( tmpPath ) ) ;
540
+
541
+ } ) ,
542
+ ) ;
543
+
544
+ it ( 'throws an error on profile in invalid user-data-dir' ,
545
+ async ( ) => withTempDir ( async ( tmpDir ) => {
546
+ const tmpPath = tmpDir . path ( ) ;
547
+ await fs . mkdirs (
548
+ path . join ( tmpPath , 'userDataDir/profile' ) ) ;
549
+ // the userDataDir is missing a file Local State to be validated as such
550
+ await fs . outputFile ( path . join (
551
+ tmpPath , 'userDataDir/profile/Secure Preferences' ) , '' ) ;
552
+
553
+ const { params} = prepareExtensionRunnerParams ( {
554
+ params : {
555
+ chromiumProfile : path . join ( tmpPath , 'userDataDir/profile' ) ,
556
+ keepProfileChanges : true ,
557
+ } ,
558
+ } ) ;
559
+
560
+ const runnerInstance = new ChromiumExtensionRunner ( params ) ;
561
+
562
+ await assert . isRejected ( runnerInstance . run ( ) , / n o t i n a u s e r - d a t a - d i r / ) ;
563
+
564
+ await runnerInstance . exit ( ) ;
565
+
566
+ } )
567
+ ) ;
568
+
569
+ it ( 'does copy the profile and pass user-data-dir and profile-directory' +
570
+ ' flags' , async ( ) => withTempDir ( async ( tmpDir ) => {
571
+
572
+ const tmpPath = tmpDir . path ( ) ;
573
+ await fs . mkdirs (
574
+ path . join ( tmpPath , 'userDataDir/profile' ) ) ;
575
+ await fs . outputFile ( path . join (
576
+ tmpPath , 'userDataDir/profile/Secure Preferences' ) , '' ) ;
577
+
361
578
const { params} = prepareExtensionRunnerParams ( {
362
579
params : {
363
- chromiumProfile : '/fake/chrome/ profile',
580
+ chromiumProfile : path . join ( tmpPath , 'userDataDir/ profile') ,
364
581
} ,
365
582
} ) ;
366
583
584
+ const spy = sinon . spy ( TempDir . prototype , 'path' ) ;
585
+
367
586
const runnerInstance = new ChromiumExtensionRunner ( params ) ;
368
587
await runnerInstance . run ( ) ;
369
588
589
+ const usedTempPath = spy . returnValues [ 2 ] ;
590
+
370
591
const { reloadManagerExtension} = runnerInstance ;
371
592
372
593
sinon . assert . calledOnce ( params . chromiumLaunch ) ;
373
594
sinon . assert . calledWithMatch ( params . chromiumLaunch , {
374
595
ignoreDefaultFlags : true ,
375
596
enableExtensions : true ,
376
597
chromePath : undefined ,
598
+ userDataDir : usedTempPath ,
377
599
chromeFlags : [
378
600
...DEFAULT_CHROME_FLAGS ,
379
601
`--load-extension=${ reloadManagerExtension } ,/fake/sourceDir` ,
380
- '--user-data-dir=/fake/chrome/ profile' ,
602
+ '--profile-directory= profile' ,
381
603
] ,
382
604
startingUrl : undefined ,
383
605
} ) ;
384
606
607
+ assert . isTrue ( await isDirectory ( path . join ( usedTempPath , 'profile' ) ) ) ;
608
+ assert . isTrue ( await fileExists ( path . join (
609
+ usedTempPath , 'profile/Secure Preferences' ) ) ) ;
610
+
385
611
await runnerInstance . exit ( ) ;
386
- } ) ;
612
+ spy . restore ( ) ;
613
+ } )
614
+ ) ;
387
615
388
616
describe ( 'reloadAllExtensions' , ( ) => {
389
617
let runnerInstance ;
0 commit comments