From c6bce352b0cf362d1dd3226123f2b9c51d2e4455 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Thu, 7 Mar 2024 15:55:58 -0300 Subject: [PATCH 1/4] fallsback --- modules/jwplayerRtdProvider.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/modules/jwplayerRtdProvider.js b/modules/jwplayerRtdProvider.js index a06404e52f2..5f1d878b805 100644 --- a/modules/jwplayerRtdProvider.js +++ b/modules/jwplayerRtdProvider.js @@ -12,7 +12,7 @@ import {submodule} from '../src/hook.js'; import {config} from '../src/config.js'; import {ajaxBuilder} from '../src/ajax.js'; -import {deepAccess, logError} from '../src/utils.js'; +import { deepAccess, logError, logWarn } from '../src/utils.js' import {find} from '../src/polyfill.js'; import {getGlobal} from '../src/prebidGlobal.js'; @@ -436,10 +436,18 @@ function getPlayer(playerDivId) { return; } - const player = jwplayer(playerDivId); - if (!player || !player.getPlaylist) { - logError('player ID did not match any players'); - return; + let player = jwplayer(playerDivId); + if (player && player.getPlaylist) { + return player; } - return player; + + let errorMessage = `player Div ID ${playerID} did not match any players.`; + player = jwplayer(); + + if (player && player.getPlaylist) { + logWarn(`${errorMessage} Targeting player Div ID ${player.id} instead`); + return player; + } + + logError(errorMessage); } From 2e09746e1bf55321015a8a2786c8995579b18189 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Thu, 7 Mar 2024 17:16:33 -0300 Subject: [PATCH 2/4] improves error messaging --- modules/jwplayerRtdProvider.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/jwplayerRtdProvider.js b/modules/jwplayerRtdProvider.js index 5f1d878b805..4129775818b 100644 --- a/modules/jwplayerRtdProvider.js +++ b/modules/jwplayerRtdProvider.js @@ -441,9 +441,20 @@ function getPlayer(playerDivId) { return player; } + const playerOnPageCount = document.getElementsByClassName('jwplayer').length; + if (playerOnPageCount === 0) { + logError('No JWPlayer instances have been detected on the page'); + return; + } + let errorMessage = `player Div ID ${playerID} did not match any players.`; - player = jwplayer(); + // If there are multiple instances on the page, we cannot guess which one should be targeted. + if (playerOnPageCount > 1) { + logError(errorMessage); + return; + } + player = jwplayer(); if (player && player.getPlaylist) { logWarn(`${errorMessage} Targeting player Div ID ${player.id} instead`); return player; From aa627090b811642014c997328476e264ed0fc563 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Thu, 7 Mar 2024 17:40:46 -0300 Subject: [PATCH 3/4] updates div id name --- modules/jwplayerRtdProvider.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/jwplayerRtdProvider.js b/modules/jwplayerRtdProvider.js index 4129775818b..6f1f868266e 100644 --- a/modules/jwplayerRtdProvider.js +++ b/modules/jwplayerRtdProvider.js @@ -447,7 +447,8 @@ function getPlayer(playerDivId) { return; } - let errorMessage = `player Div ID ${playerID} did not match any players.`; + let errorMessage = `player Div ID ${playerDivId} did not match any players.`; + // If there are multiple instances on the page, we cannot guess which one should be targeted. if (playerOnPageCount > 1) { logError(errorMessage); From 5934777509617c962d19546e4c4c22b4d42537d2 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Tue, 2 Jul 2024 20:39:31 -0400 Subject: [PATCH 4/4] adds tests --- modules/jwplayerRtdProvider.js | 2 +- test/spec/modules/jwplayerRtdProvider_spec.js | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/modules/jwplayerRtdProvider.js b/modules/jwplayerRtdProvider.js index 6f1f868266e..78c26cbda6a 100644 --- a/modules/jwplayerRtdProvider.js +++ b/modules/jwplayerRtdProvider.js @@ -429,7 +429,7 @@ export function addTargetingToBid(bid, targeting) { bid.rtd = Object.assign({}, rtd, jwRtd); } -function getPlayer(playerDivId) { +export function getPlayer(playerDivId) { const jwplayer = window.jwplayer; if (!jwplayer) { logError(SUBMODULE_NAME + '.js was not found on page'); diff --git a/test/spec/modules/jwplayerRtdProvider_spec.js b/test/spec/modules/jwplayerRtdProvider_spec.js index 36794ceeae3..58cfc751a4f 100644 --- a/test/spec/modules/jwplayerRtdProvider_spec.js +++ b/test/spec/modules/jwplayerRtdProvider_spec.js @@ -12,6 +12,7 @@ import { getVatFromCache, getVatFromPlayer, setOverrides, + getPlayer, jwplayerSubmodule } from 'modules/jwplayerRtdProvider.js'; import {server} from 'test/mocks/xhr.js'; @@ -1603,6 +1604,66 @@ describe('jwplayerRtdProvider', function() { }); }); + describe('Player detection', function () { + const playerInstanceMock = { + getPlaylist: () => [], + getPlaylistItem: () => ({}) + }; + + beforeEach(function () { + window.jwplayer = sinon.stub(); + }); + + afterEach(function () { + delete window.jwplayer; + }); + + it('should fail if jwplayer global does not exist', function () { + delete window.jwplayer; + expect(getPlayer('divId')).to.be.undefined; + }); + + it('should return the player instance for the specified div id', function () { + window.jwplayer.returns(playerInstanceMock); + const player = getPlayer('divId'); + expect(player).to.deep.equal(playerInstanceMock); + }); + + it('should request a player when the div id does not match a player on the page and only 1 player is in the DOM', function () { + const playerDomElement = document.createElement('div'); + playerDomElement.className = 'jwplayer'; + document.body.appendChild(playerDomElement); + + window.jwplayer.withArgs('invalidDivId').returns(undefined); + window.jwplayer.returns(playerInstanceMock); + + const playerInstance = getPlayer('invalidDivId'); + + expect(playerInstance).to.deep.equal(playerInstanceMock); + + document.body.removeChild(playerDomElement); + }); + + it('should fail when the div id does not match a player on the page, and multiple players are instantiated', function () { + const firstPlayerDomElement = document.createElement('div'); + const secondPlayerDomElement = document.createElement('div'); + firstPlayerDomElement.className = 'jwplayer'; + secondPlayerDomElement.className = 'jwplayer'; + document.body.appendChild(firstPlayerDomElement); + document.body.appendChild(secondPlayerDomElement); + + window.jwplayer.withArgs('invalidDivId').returns(undefined); + window.jwplayer.returns(playerInstanceMock); + + const playerInstance = getPlayer('invalidDivId'); + + expect(playerInstance).to.be.undefined; + + document.body.removeChild(firstPlayerDomElement); + document.body.removeChild(secondPlayerDomElement); + }); + }); + describe('jwplayerSubmodule', function () { it('successfully instantiates', function () { expect(jwplayerSubmodule.init()).to.equal(true);