@gcorevideo/player 2.28.29 → 2.28.35

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.
@@ -1,7 +1,7 @@
1
- import { beforeEach, describe, expect, it, vi } from 'vitest'
1
+ import { beforeEach, describe, expect, it, vi, afterEach } from 'vitest'
2
2
 
3
3
  import { ClosedCaptions } from '../ClosedCaptions.js'
4
- import { createMockCore, createMockMediaControl } from '../../../testUtils.js'
4
+ import { createMockContainer, createMockCore, createMockMediaControl } from '../../../testUtils.js'
5
5
  import { ExtendedEvents } from '../../media-control/MediaControl.js'
6
6
 
7
7
  import { Events } from '@clappr/core'
@@ -254,10 +254,297 @@ describe('ClosedCaptions', () => {
254
254
  })
255
255
  })
256
256
  })
257
+ describe('when language is configured', () => {
258
+ describe("and is set to 'none'", () => {
259
+ beforeEach(() => {
260
+ vi.useFakeTimers()
261
+ core.options.cc = { language: 'none' }
262
+ emitSubtitleAvailable(core)
263
+ vi.advanceTimersByTime(1)
264
+ })
265
+ it('should disable subtitles', () => {
266
+ expect(core.activePlayback.closedCaptionsTrackId).toEqual(-1)
267
+ expect(
268
+ core.activeContainer.$el.find('#gplayer-cc-line').text().trim(),
269
+ ).toBe('')
270
+ })
271
+ it('should have all tracks disabled', () => {
272
+ expect(core.activePlayback.closedCaptionsTracks[0].track.mode).toBe(
273
+ 'disabled',
274
+ )
275
+ expect(core.activePlayback.closedCaptionsTracks[1].track.mode).toBe(
276
+ 'disabled',
277
+ )
278
+ })
279
+ it('should hide subtitles', () => {
280
+ expect(cc.$el.find('#gplayer-cc-menu').css('display')).toBe('none')
281
+ })
282
+ })
283
+ describe('when language is undefined', () => {
284
+ // let spyClosedCaptionsTrackId: any // TODO
285
+ beforeEach(() => {
286
+ // spyClosedCaptionsTrackId = vi.spyOn(core.activePlayback, 'closedCaptionsTrackId')
287
+ core.options.cc = {}
288
+ core.activePlayback.closedCaptionsTrackId = undefined
289
+ emitSubtitleAvailable(core, 1)
290
+ })
291
+ // The native engine will decide
292
+ it('should not automatically select any track', () => {
293
+ expect(core.activePlayback.closedCaptionsTrackId).toEqual(undefined)
294
+ })
295
+ it('should not activate any tracks', () => {
296
+ expect(core.activePlayback.closedCaptionsTracks[0].track.mode).toBe(
297
+ 'hidden', // showing is reset to hidden since the plugin manages rendition
298
+ )
299
+ expect(core.activePlayback.closedCaptionsTracks[1].track.mode).toBe(
300
+ 'hidden',
301
+ )
302
+ })
303
+ })
304
+ describe('when language matches a track', () => {
305
+ beforeEach(() => {
306
+ vi.useFakeTimers()
307
+ core.options.cc = { language: 'en' }
308
+ emitSubtitleAvailable(core)
309
+ vi.advanceTimersByTime(1)
310
+ })
311
+ // afterEach(() => {
312
+ // vi.useRealTimers()
313
+ // })
314
+ it('should activate the matching track', () => {
315
+ expect(core.activePlayback.closedCaptionsTrackId).toEqual(1)
316
+ })
317
+ it('should set the matching track mode appropriately', () => {
318
+ // The matching track should be activated
319
+ expect(core.activePlayback.closedCaptionsTracks[0].track.mode).toBe(
320
+ 'hidden',
321
+ )
322
+ expect(core.activePlayback.closedCaptionsTracks[1].track.mode).toBe(
323
+ 'disabled',
324
+ )
325
+ })
326
+ it('should highlight the matching track in menu', () => {
327
+ expect(
328
+ cc.$el.find('#gplayer-cc-menu li:nth-child(1)').hasClass('current'),
329
+ ).toBe(true)
330
+ })
331
+ })
332
+ describe('when language does not match any track', () => {
333
+ beforeEach(() => {
334
+ vi.useFakeTimers()
335
+ core.options.cc = { language: 'fr' }
336
+ cc = new ClosedCaptions(core)
337
+ core.emit(Events.CORE_READY)
338
+ core.activePlayback.el = document.createElement('video')
339
+ core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
340
+ emitSubtitleAvailable(core)
341
+ vi.advanceTimersByTime(1)
342
+ })
343
+ afterEach(() => {
344
+ vi.useRealTimers()
345
+ })
346
+ it('should disable subtitles', () => {
347
+ expect(core.activePlayback.closedCaptionsTrackId).toEqual(-1)
348
+ })
349
+ it('should have all tracks disabled', () => {
350
+ expect(core.activePlayback.closedCaptionsTracks[0].track.mode).toBe(
351
+ 'disabled',
352
+ )
353
+ expect(core.activePlayback.closedCaptionsTracks[1].track.mode).toBe(
354
+ 'disabled',
355
+ )
356
+ })
357
+ it('should hide subtitle text', () => {
358
+ expect(
359
+ core.activeContainer.$el.find('#gplayer-cc-line').text().trim(),
360
+ ).toBe('')
361
+ })
362
+ })
363
+ })
364
+ describe('when subtitle available event occurs after user selection', () => {
365
+ describe('if user selected track before event', () => {
366
+ beforeEach(() => {
367
+ vi.useFakeTimers()
368
+ core.options.cc = { language: 'en' }
369
+ // First subtitle available event
370
+ emitSubtitleAvailable(core)
371
+ vi.advanceTimersByTime(1)
372
+ cc.$el.find('#gplayer-cc-button').click()
373
+ vi.advanceTimersByTime(1)
374
+ // User manually selects Spanish track
375
+ cc.$el.find('#gplayer-cc-menu li:nth-child(2) a').click()
376
+ vi.advanceTimersByTime(1)
377
+
378
+ core.activeContainer = createMockContainer()
379
+ // Reset isPreselectedApplied by emitting container changed
380
+ core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
381
+ // Second subtitle available event (e.g., after source switch)
382
+ emitSubtitleAvailable(core)
383
+ vi.advanceTimersByTime(1)
384
+ })
385
+ afterEach(() => {
386
+ vi.useRealTimers()
387
+ })
388
+ it('should run preselected language matching algorithm', () => {
389
+ // Should activate track selected by user
390
+ expect(core.activePlayback.closedCaptionsTrackId).toEqual(2)
391
+ })
392
+ it('should select track based on configured language', () => {
393
+ expect(
394
+ cc.$el.find('#gplayer-cc-menu li:nth-child(2)').hasClass('current'),
395
+ ).toBe(true)
396
+ })
397
+ it('should activate the track matching the selected', () => {
398
+ expect(core.activePlayback.closedCaptionsTracks[0].track.mode).toBe(
399
+ 'disabled',
400
+ )
401
+ // not 'showing' because the plugin manages the subtitles rendition
402
+ expect(core.activePlayback.closedCaptionsTracks[1].track.mode).toBe(
403
+ 'hidden',
404
+ )
405
+ })
406
+ })
407
+ describe('when multiple subtitle available events occur', () => {
408
+ beforeEach(() => {
409
+ vi.useFakeTimers()
410
+ core.options.cc = { language: 'en' }
411
+ // cc = new ClosedCaptions(core)
412
+ // core.emit(Events.CORE_READY)
413
+ // core.activePlayback.el = document.createElement('video')
414
+ // core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
415
+ // First subtitle available event
416
+ emitSubtitleAvailable(core)
417
+ vi.advanceTimersByTime(1)
418
+ // User changes selection
419
+ // cc.$el.find('#gplayer-cc-menu li:nth-child(2) a').click()
420
+ // Container changed (simulating source switch)
421
+ core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
422
+ vi.advanceTimersByTime(1)
423
+ core.activePlayback.closedCaptionsTrackId = undefined
424
+ // Second subtitle available event
425
+ emitSubtitleAvailable(core)
426
+ vi.advanceTimersByTime(1)
427
+ })
428
+ afterEach(() => {
429
+ vi.useRealTimers()
430
+ })
431
+ it('should reapply preselected language matching', () => {
432
+ expect(core.activePlayback.closedCaptionsTrackId).toEqual(1)
433
+ // Should select English track based on configured language
434
+ expect(
435
+ cc.$el.find('#gplayer-cc-menu li:nth-child(1)').hasClass('current'),
436
+ ).toBe(true)
437
+ })
438
+ it('should activate the matching track', () => {
439
+ expect(core.activePlayback.closedCaptionsTracks[0].track.mode).toBe(
440
+ 'hidden',
441
+ )
442
+ expect(core.activePlayback.closedCaptionsTracks[1].track.mode).toBe(
443
+ 'disabled',
444
+ )
445
+ })
446
+ })
447
+ })
448
+ describe.each(['dash', 'hls'] as const)(
449
+ 'when playback engine is %s',
450
+ (playbackEngine) => {
451
+ beforeEach(() => {
452
+ // core.emit(Events.CORE_READY)
453
+ core.activePlayback.el = document.createElement('video')
454
+ core.activePlayback.name = playbackEngine
455
+ core.activePlayback.setTextTrack = vi.fn()
456
+ // core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
457
+ })
458
+ describe('when language is configured and matches a track', () => {
459
+ beforeEach(() => {
460
+ vi.useFakeTimers()
461
+ core.options.cc = { language: 'en' }
462
+ // cc = new ClosedCaptions(core)
463
+ // core.emit(Events.CORE_READY)
464
+ // core.activePlayback.el = document.createElement('video')
465
+ // core.activePlayback.name = playbackEngine
466
+ // core.activePlayback.setTextTrack = vi.fn()
467
+ // core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
468
+ emitSubtitleAvailable(core)
469
+ vi.advanceTimersByTime(1)
470
+ })
471
+ afterEach(() => {
472
+ vi.useRealTimers()
473
+ })
474
+ it('should call setTextTrack with matching track id', () => {
475
+ expect(core.activePlayback.setTextTrack).toHaveBeenCalledWith(1)
476
+ })
477
+ it('should set closedCaptionsTrackId to matching track id', () => {
478
+ expect(core.activePlayback.closedCaptionsTrackId).toEqual(1)
479
+ })
480
+ it('should not touch native tracks', () => {
481
+ expect(core.activePlayback.closedCaptionsTracks[0].track.mode).toBe('hidden')
482
+ expect(core.activePlayback.closedCaptionsTracks[1].track.mode).toBe('hidden')
483
+ })
484
+ })
485
+ describe('when language is configured but does not match any track', () => {
486
+ beforeEach(() => {
487
+ vi.useFakeTimers()
488
+ core.options.cc = { language: 'fr' }
489
+ cc = new ClosedCaptions(core)
490
+ core.emit(Events.CORE_READY)
491
+ core.activePlayback.el = document.createElement('video')
492
+ core.activePlayback.name = playbackEngine
493
+ core.activePlayback.setTextTrack = vi.fn()
494
+ core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
495
+ emitSubtitleAvailable(core)
496
+ vi.advanceTimersByTime(1)
497
+ })
498
+ afterEach(() => {
499
+ vi.useRealTimers()
500
+ })
501
+ it('should disable subtitles', () => {
502
+ expect(core.activePlayback.setTextTrack).toHaveBeenCalledWith(-1)
503
+ expect(core.activePlayback.closedCaptionsTrackId).toEqual(-1)
504
+ })
505
+ })
506
+ describe('when user selects a track from menu', () => {
507
+ beforeEach(() => {
508
+ core.activePlayback.setTextTrack = vi.fn()
509
+ emitSubtitleAvailable(core)
510
+ cc.$el.find('#gplayer-cc-menu li:nth-child(2) a').click()
511
+ })
512
+ it('should call setTextTrack with selected track id', () => {
513
+ // TODO: Implement assertion
514
+ // expect(core.activePlayback.setTextTrack).toHaveBeenCalledWith(2)
515
+ })
516
+ it('should update closedCaptionsTrackId', () => {
517
+ // TODO: Implement assertion
518
+ // expect(core.activePlayback.closedCaptionsTrackId).toEqual(2)
519
+ })
520
+ })
521
+ describe('when language is set to none', () => {
522
+ beforeEach(() => {
523
+ vi.useFakeTimers()
524
+ core.options.cc = { language: 'none' }
525
+ cc = new ClosedCaptions(core)
526
+ core.emit(Events.CORE_READY)
527
+ core.activePlayback.el = document.createElement('video')
528
+ core.activePlayback.name = playbackEngine
529
+ core.activePlayback.setTextTrack = vi.fn()
530
+ core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
531
+ emitSubtitleAvailable(core)
532
+ vi.advanceTimersByTime(1)
533
+ })
534
+ afterEach(() => {
535
+ vi.useRealTimers()
536
+ })
537
+ it('should call setTextTrack with -1 to disable subtitles', () => {
538
+ // TODO: Implement assertion
539
+ // expect(core.activePlayback.setTextTrack).toHaveBeenCalledWith(-1)
540
+ })
541
+ })
542
+ },
543
+ )
257
544
  })
258
545
  })
259
546
 
260
- function emitSubtitleAvailable(core: any) {
547
+ function emitSubtitleAvailable(core: any, selectedTrackId?: number) {
261
548
  core.activePlayback.closedCaptionsTracks = [
262
549
  {
263
550
  id: 1,
@@ -266,7 +553,7 @@ function emitSubtitleAvailable(core: any) {
266
553
  language: 'en',
267
554
  kind: 'subtitles',
268
555
  label: 'English',
269
- mode: 'hidden',
556
+ mode: selectedTrackId === 1 ? 'showing' : 'hidden',
270
557
  cues: [],
271
558
  },
272
559
  },
@@ -276,8 +563,8 @@ function emitSubtitleAvailable(core: any) {
276
563
  track: {
277
564
  language: 'es',
278
565
  kind: 'subtitles',
279
- label: 'Spanish',
280
- mode: 'hidden',
566
+ label: 'Español',
567
+ mode: selectedTrackId === 2 ? 'showing' : 'hidden',
281
568
  cues: [],
282
569
  },
283
570
  },
@@ -0,0 +1,5 @@
1
+ import { Browser } from '@clappr/core'
2
+
3
+ export function isMobile() {
4
+ return Browser.isMobile
5
+ }
package/src/testUtils.ts CHANGED
@@ -23,6 +23,7 @@ export function createMockCore(
23
23
  configure: vi.fn(),
24
24
  getPlaybackType: vi.fn(),
25
25
  getPlugin: vi.fn(),
26
+ isFullscreen: vi.fn().mockReturnValue(false),
26
27
  load: vi.fn(),
27
28
  trigger: emitter.emit,
28
29
  })