cloudinary-video-player 1.6.2-edge.13

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.
Files changed (226) hide show
  1. package/.eslintignore +4 -0
  2. package/.snyk +19 -0
  3. package/.travis.yml +8 -0
  4. package/CHANGELOG.md +329 -0
  5. package/LICENSE +21 -0
  6. package/README.md +87 -0
  7. package/dist/cld-video-player.css +2110 -0
  8. package/dist/cld-video-player.js +5249 -0
  9. package/dist/cld-video-player.light.css +1766 -0
  10. package/dist/cld-video-player.light.js +1399 -0
  11. package/dist/cld-video-player.light.min.css +1 -0
  12. package/dist/cld-video-player.light.min.js +2 -0
  13. package/dist/cld-video-player.light.min.js.LICENSE.txt +23 -0
  14. package/dist/cld-video-player.min.css +1 -0
  15. package/dist/cld-video-player.min.js +2 -0
  16. package/dist/cld-video-player.min.js.LICENSE.txt +26 -0
  17. package/dist/fonts/cloudinary_icon_for_black_bg.svg +69 -0
  18. package/dist/fonts/cloudinary_icon_for_white_bg.svg +69 -0
  19. package/docs/360.html +102 -0
  20. package/docs/_template.html +93 -0
  21. package/docs/adaptive-streaming.html +297 -0
  22. package/docs/analytics.html +140 -0
  23. package/docs/api.html +302 -0
  24. package/docs/audio.html +136 -0
  25. package/docs/autoplay-fallback.html +138 -0
  26. package/docs/autoplay-on-scroll.html +107 -0
  27. package/docs/codec-fallback.html +158 -0
  28. package/docs/colors.html +135 -0
  29. package/docs/components.html +284 -0
  30. package/docs/custom-cld-errors.html +134 -0
  31. package/docs/floating-player.html +98 -0
  32. package/docs/fluid.html +117 -0
  33. package/docs/force-hls-subtitles-ios.html +159 -0
  34. package/docs/index.html +83 -0
  35. package/docs/interaction-area.html +398 -0
  36. package/docs/live-customer.html +128 -0
  37. package/docs/multiple-players.html +125 -0
  38. package/docs/playlist-by-tag-cap.html +182 -0
  39. package/docs/playlist-by-tag.html +133 -0
  40. package/docs/playlist.html +133 -0
  41. package/docs/poster.html +155 -0
  42. package/docs/raw-url.html +104 -0
  43. package/docs/recommendations.html +155 -0
  44. package/docs/scripts.js +156 -0
  45. package/docs/seek-thumbs.html +90 -0
  46. package/docs/shoppable.html +335 -0
  47. package/docs/subtitles-and-captions.html +267 -0
  48. package/docs/transformations.html +171 -0
  49. package/docs/ui-config.html +108 -0
  50. package/docs/vast-vpaid.html +149 -0
  51. package/env.example.js +6 -0
  52. package/env.js +6 -0
  53. package/jest-puppeteer.config.js +14 -0
  54. package/jest.config.js +196 -0
  55. package/package.json +99 -0
  56. package/sandbox.config.json +3 -0
  57. package/setupJest.js +1 -0
  58. package/src/assets/fonts/VideoJS.svg +120 -0
  59. package/src/assets/fonts/VideoJS.ttf +0 -0
  60. package/src/assets/fonts/VideoJS.woff +0 -0
  61. package/src/assets/fonts/icons.json +120 -0
  62. package/src/assets/icons/cloudinary_icon_for_black_bg.svg +69 -0
  63. package/src/assets/icons/cloudinary_icon_for_white_bg.svg +69 -0
  64. package/src/assets/icons/cloudinary_logo_for_dark_bg.svg +188 -0
  65. package/src/assets/icons/cloudinary_logo_for_white_bg.svg +188 -0
  66. package/src/assets/icons/info-circle.svg +17 -0
  67. package/src/assets/styles/ads-label.scss +16 -0
  68. package/src/assets/styles/components/interaction-areas.scss +158 -0
  69. package/src/assets/styles/components/playlist.scss +213 -0
  70. package/src/assets/styles/components/themedButton.scss +48 -0
  71. package/src/assets/styles/components/thumbnail.scss +94 -0
  72. package/src/assets/styles/components/title-bar.scss +67 -0
  73. package/src/assets/styles/components/triangle-volume-bar.scss +52 -0
  74. package/src/assets/styles/icons.scss +257 -0
  75. package/src/assets/styles/main.scss +324 -0
  76. package/src/assets/styles/mixins/aspect-ratio.scss +16 -0
  77. package/src/assets/styles/mixins/disable-transition.scss +3 -0
  78. package/src/assets/styles/mixins/mixins.scss +5 -0
  79. package/src/assets/styles/mixins/skin.scss +64 -0
  80. package/src/assets/styles/variables.scss +2 -0
  81. package/src/assets/styles/videojs-ima.scss +252 -0
  82. package/src/components/component-utils.js +20 -0
  83. package/src/components/index.js +21 -0
  84. package/src/components/interaction-area/interaction-area.const.js +30 -0
  85. package/src/components/interaction-area/interaction-area.service.js +223 -0
  86. package/src/components/interaction-area/interaction-area.utils.js +236 -0
  87. package/src/components/jumpButtons/jump-10-minus.js +21 -0
  88. package/src/components/jumpButtons/jump-10-plus.js +20 -0
  89. package/src/components/logoButton/logo-button.const.js +3 -0
  90. package/src/components/logoButton/logo-button.js +30 -0
  91. package/src/components/logoButton/logo-button.scss +15 -0
  92. package/src/components/playlist/components/playlist-button.js +34 -0
  93. package/src/components/playlist/components/playlist-next-button.js +18 -0
  94. package/src/components/playlist/components/playlist-previous-button.js +18 -0
  95. package/src/components/playlist/components/playlist.js +5 -0
  96. package/src/components/playlist/components/playlist.scss +15 -0
  97. package/src/components/playlist/components/upcoming-video-overlay.js +149 -0
  98. package/src/components/playlist/components/upcoming-video-overlay.scss +86 -0
  99. package/src/components/playlist/layout/playlist-layout-custom.js +21 -0
  100. package/src/components/playlist/layout/playlist-layout-horizontal.js +16 -0
  101. package/src/components/playlist/layout/playlist-layout-vertical.js +19 -0
  102. package/src/components/playlist/layout/playlist-layout.js +110 -0
  103. package/src/components/playlist/panel/playlist-panel-item.js +86 -0
  104. package/src/components/playlist/panel/playlist-panel.js +92 -0
  105. package/src/components/playlist/playlist-widget.js +119 -0
  106. package/src/components/playlist/playlist.const.js +14 -0
  107. package/src/components/playlist/playlist.js +413 -0
  108. package/src/components/playlist/thumbnail/thumbnail.js +69 -0
  109. package/src/components/progress-control-events-blocker/progress-control-events-blocker.js +17 -0
  110. package/src/components/qualitySelector/quality-selector.scss +10 -0
  111. package/src/components/qualitySelector/qualitySelector.js +152 -0
  112. package/src/components/recommendations-overlay/index.js +3 -0
  113. package/src/components/recommendations-overlay/recommendations-overlay-content.js +57 -0
  114. package/src/components/recommendations-overlay/recommendations-overlay-hide-button.js +18 -0
  115. package/src/components/recommendations-overlay/recommendations-overlay-item.js +35 -0
  116. package/src/components/recommendations-overlay/recommendations-overlay-primary-item.js +81 -0
  117. package/src/components/recommendations-overlay/recommendations-overlay-secondary-item.js +48 -0
  118. package/src/components/recommendations-overlay/recommendations-overlay-secondary-items-container.js +35 -0
  119. package/src/components/recommendations-overlay/recommendations-overlay.js +94 -0
  120. package/src/components/recommendations-overlay/recommendations-overlay.scss +182 -0
  121. package/src/components/shoppable-bar/layout/bar-layout.js +111 -0
  122. package/src/components/shoppable-bar/layout/shoppable-panel-toggle.js +64 -0
  123. package/src/components/shoppable-bar/layout/shoppable-products-overlay.js +87 -0
  124. package/src/components/shoppable-bar/panel/shoppable-panel-item.js +105 -0
  125. package/src/components/shoppable-bar/panel/shoppable-panel.js +172 -0
  126. package/src/components/shoppable-bar/shoppable-post-widget.js +110 -0
  127. package/src/components/shoppable-bar/shoppable-widget.const.js +52 -0
  128. package/src/components/shoppable-bar/shoppable-widget.js +111 -0
  129. package/src/components/shoppable-bar/shoppable-widget.scss +359 -0
  130. package/src/components/themeButton/themedButton.const.js +3 -0
  131. package/src/components/themeButton/themedButton.js +25 -0
  132. package/src/components/title-bar/title-bar.js +79 -0
  133. package/src/config/defaults.js +25 -0
  134. package/src/extended-events.js +228 -0
  135. package/src/index.js +18 -0
  136. package/src/mixins/eventable.js +54 -0
  137. package/src/mixins/playlistable.js +106 -0
  138. package/src/plugins/analytics/index.js +245 -0
  139. package/src/plugins/autoplay-on-scroll/index.js +86 -0
  140. package/src/plugins/cloudinary/common.js +216 -0
  141. package/src/plugins/cloudinary/event-handler-registry.js +46 -0
  142. package/src/plugins/cloudinary/index.js +345 -0
  143. package/src/plugins/cloudinary/models/audio-source/audio-source.const.js +11 -0
  144. package/src/plugins/cloudinary/models/audio-source/audio-source.js +82 -0
  145. package/src/plugins/cloudinary/models/base-source.js +107 -0
  146. package/src/plugins/cloudinary/models/image-source.js +26 -0
  147. package/src/plugins/cloudinary/models/video-source/video-source.const.js +32 -0
  148. package/src/plugins/cloudinary/models/video-source/video-source.js +239 -0
  149. package/src/plugins/cloudinary/models/video-source/video-source.utils.js +57 -0
  150. package/src/plugins/colors/index.js +303 -0
  151. package/src/plugins/context-menu/components/context-menu-item.js +12 -0
  152. package/src/plugins/context-menu/components/context-menu.js +63 -0
  153. package/src/plugins/context-menu/context-menu.scss +30 -0
  154. package/src/plugins/context-menu/contextMenuContent.js +53 -0
  155. package/src/plugins/context-menu/index.js +134 -0
  156. package/src/plugins/dash/index.js +26 -0
  157. package/src/plugins/dash/setup-audio-tracks.js +112 -0
  158. package/src/plugins/dash/setup-text-tracks.js +195 -0
  159. package/src/plugins/dash/videojs-dash.js +372 -0
  160. package/src/plugins/floating-player/floating-player.scss +74 -0
  161. package/src/plugins/floating-player/index.js +129 -0
  162. package/src/plugins/ima/index.js +1775 -0
  163. package/src/plugins/index.js +31 -0
  164. package/src/plugins/interactive-plugin/index.js +10 -0
  165. package/src/plugins/videojs-http-source-selector/components/SourceMenuButton.js +98 -0
  166. package/src/plugins/videojs-http-source-selector/components/SourceMenuItem.js +52 -0
  167. package/src/plugins/videojs-http-source-selector/plugin.js +82 -0
  168. package/src/plugins/videojs-http-source-selector/plugin.scss +9 -0
  169. package/src/plugins/vtt-thumbnails/index.js +526 -0
  170. package/src/plugins/vtt-thumbnails/vtt-thumbnails.scss +29 -0
  171. package/src/utils/api.js +32 -0
  172. package/src/utils/apply-with-props.js +32 -0
  173. package/src/utils/array.js +22 -0
  174. package/src/utils/assign.js +27 -0
  175. package/src/utils/attributes-normalizer.js +72 -0
  176. package/src/utils/cloudinary.js +165 -0
  177. package/src/utils/css-prefix.js +43 -0
  178. package/src/utils/dom.js +74 -0
  179. package/src/utils/find.js +28 -0
  180. package/src/utils/fontFace.js +25 -0
  181. package/src/utils/groupBy.js +12 -0
  182. package/src/utils/index.js +29 -0
  183. package/src/utils/matches.js +11 -0
  184. package/src/utils/mixin.js +5 -0
  185. package/src/utils/object.js +26 -0
  186. package/src/utils/playButton.js +9 -0
  187. package/src/utils/positioning.js +78 -0
  188. package/src/utils/querystring.js +12 -0
  189. package/src/utils/slicing.js +21 -0
  190. package/src/utils/string.js +15 -0
  191. package/src/utils/throttle.js +30 -0
  192. package/src/utils/time.js +77 -0
  193. package/src/utils/type-inference.js +35 -0
  194. package/src/validators/validators-functions.js +48 -0
  195. package/src/validators/validators-types.js +78 -0
  196. package/src/validators/validators.js +110 -0
  197. package/src/video-player.const.js +68 -0
  198. package/src/video-player.js +761 -0
  199. package/src/video-player.utils.js +123 -0
  200. package/test/adaptive-streaming.test.js +38 -0
  201. package/test/ads.test.js +35 -0
  202. package/test/analytics.test.js +111 -0
  203. package/test/api.test.js +111 -0
  204. package/test/autoplay.scroll.test.js +23 -0
  205. package/test/basic-ui.test.js +59 -0
  206. package/test/colors.test.js +58 -0
  207. package/test/components.test.js +21 -0
  208. package/test/custom-error.test.js +24 -0
  209. package/test/fluid.test.js +36 -0
  210. package/test/isValidConfig.test.js +224 -0
  211. package/test/mocks/cloudinary-core-mock.js +0 -0
  212. package/test/mocks/styleMock.js +1 -0
  213. package/test/multiplayer.test.js +25 -0
  214. package/test/playlist.test.js +60 -0
  215. package/test/puppeteer/vp-env.js +19 -0
  216. package/test/recommendations.test.js +38 -0
  217. package/test/title-bar.test.js +28 -0
  218. package/test/ui-conf.test.js +49 -0
  219. package/test/unit/cloudinaryConfig.test.js +22 -0
  220. package/test/unit/cloudinaryUtils.test.js +53 -0
  221. package/test/unit/utils.test.js +27 -0
  222. package/test/unit/videoSource.test.js +454 -0
  223. package/tsconfig.json +15 -0
  224. package/types/video-player-tests.js +12 -0
  225. package/types/video-player-tests.ts +31 -0
  226. package/types/video-player.d.ts +570 -0
@@ -0,0 +1,224 @@
1
+ import { isValidConfig } from '../src/validators/validators-functions';
2
+ import { validator } from '../src/validators/validators-types';
3
+ import { noop } from '../src/utils/type-inference';
4
+
5
+ describe('test isValidConfig method', () => {
6
+
7
+ describe('should be a number', () => {
8
+
9
+ const validators = {
10
+ test: validator.isNumber
11
+ };
12
+
13
+ it('is valid number', () => {
14
+ const isValid = isValidConfig({
15
+ test: 1
16
+ }, validators);
17
+
18
+ expect(isValid).toBe(true);
19
+ });
20
+
21
+ it('is invalid number', () => {
22
+ const isValid = isValidConfig({
23
+ test: 'a'
24
+ }, validators);
25
+
26
+ expect(isValid).toBe(false);
27
+ });
28
+ });
29
+
30
+ describe('should be a string', () => {
31
+
32
+ const validators = {
33
+ test: validator.isString
34
+ };
35
+
36
+ it('is valid string', () => {
37
+ const isValid = isValidConfig({
38
+ test: 'a'
39
+ }, validators);
40
+
41
+ expect(isValid).toBe(true);
42
+ });
43
+
44
+ it('is invalid string', () => {
45
+ const isValid = isValidConfig({
46
+ test: 1
47
+ }, validators);
48
+
49
+ expect(isValid).toBe(false);
50
+ });
51
+ });
52
+
53
+ describe('should be a boolean', () => {
54
+
55
+ const validators = {
56
+ test: validator.isBoolean
57
+ };
58
+
59
+ it('is valid boolean', () => {
60
+ const isValid = isValidConfig({
61
+ test: true
62
+ }, validators);
63
+
64
+ expect(isValid).toBe(true);
65
+ });
66
+
67
+ it('is invalid boolean', () => {
68
+ const isValid = isValidConfig({
69
+ test: 1
70
+ }, validators);
71
+
72
+ expect(isValid).toBe(false);
73
+ });
74
+ });
75
+
76
+ describe('should be a function', () => {
77
+
78
+ const validators = {
79
+ test: validator.isFunction
80
+ };
81
+
82
+ it('is valid function', () => {
83
+ const isValid = isValidConfig({
84
+ test: noop
85
+ }, validators);
86
+
87
+ expect(isValid).toBe(true);
88
+ });
89
+
90
+ it('is invalid function', () => {
91
+ const isValid = isValidConfig({
92
+ test: 1
93
+ }, validators);
94
+
95
+ expect(isValid).toBe(false);
96
+ });
97
+ });
98
+
99
+ describe('should be an array Of strings', () => {
100
+
101
+ const validators = {
102
+ test: validator.isArrayOfStrings
103
+ };
104
+
105
+ it('is valid array of strings', () => {
106
+ const isValid = isValidConfig({
107
+ test: ['a', 'b', 'c']
108
+ }, validators);
109
+
110
+ expect(isValid).toBe(true);
111
+ });
112
+
113
+ it('is invalid array of strings', () => {
114
+ const isValid = isValidConfig({
115
+ test: 1
116
+ }, validators);
117
+
118
+ expect(isValid).toBe(false);
119
+ });
120
+ });
121
+
122
+ describe('should be an array Of numbers', () => {
123
+
124
+ const validators = {
125
+ test: validator.isArrayOfNumbers
126
+ };
127
+
128
+ it('is valid array of numbers', () => {
129
+ const isValid = isValidConfig({
130
+ test: [1, 1, 1]
131
+ }, validators);
132
+
133
+ expect(isValid).toBe(true);
134
+ });
135
+
136
+ it('is invalid array of numbers', () => {
137
+ const isValid = isValidConfig({
138
+ test: 1
139
+ }, validators);
140
+
141
+ expect(isValid).toBe(false);
142
+ });
143
+ });
144
+
145
+ describe('should be an object', () => {
146
+ const validators = {
147
+ test: validator.isPlainObject
148
+ };
149
+
150
+ it('is valid object', () => {
151
+ const isValid = isValidConfig({
152
+ test: { a: 1 }
153
+ }, validators);
154
+
155
+ expect(isValid).toBe(true);
156
+ });
157
+
158
+ it('is invalid object', () => {
159
+ const isValid = isValidConfig({
160
+ test: 1
161
+ }, validators);
162
+
163
+ expect(isValid).toBe(false);
164
+ });
165
+ });
166
+
167
+ describe('should be an array of object', () => {
168
+ const validators = {
169
+ test: validator.isArrayOfObjects({
170
+ a: validator.isString,
171
+ b: validator.isNumber,
172
+ c: validator.isBoolean
173
+ })
174
+ };
175
+ it('is valid array of object', () => {
176
+ const isValid = isValidConfig({
177
+ test: [{ a: 'a', b: 1, c: true }]
178
+ }, validators);
179
+
180
+ expect(isValid).toBe(true);
181
+ });
182
+
183
+ it('is invalid object', () => {
184
+ const isValid = isValidConfig({
185
+ test: [{ a: 'a', b: 1, c: 1 }]
186
+ }, validators);
187
+
188
+ expect(isValid).toBe(false);
189
+ });
190
+ });
191
+
192
+
193
+ describe('or validator', () => {
194
+ const validators = {
195
+ test: validator.or(validator.isNumber, validator.isString)
196
+ };
197
+
198
+ it('could be a number', () => {
199
+ const isValid = isValidConfig({
200
+ test: 1
201
+ }, validators);
202
+
203
+ expect(isValid).toBe(true);
204
+ });
205
+
206
+ it('could be a string', () => {
207
+ const isValid = isValidConfig({
208
+ test: 'a'
209
+ }, validators);
210
+
211
+ expect(isValid).toBe(true);
212
+ });
213
+
214
+ it('is invalid or', () => {
215
+ const isValid = isValidConfig({
216
+ test: true
217
+ }, validators);
218
+
219
+ expect(isValid).toBe(false);
220
+ });
221
+ });
222
+
223
+
224
+ });
File without changes
@@ -0,0 +1 @@
1
+ module.exports = {};
@@ -0,0 +1,25 @@
1
+ describe('Multi-player tests', () => {
2
+
3
+ beforeEach(async () => {
4
+ await page.setViewport({ width: 1280, height: 1800 });
5
+ await page.goto('http://localhost:3000/multiple-players.html', { waitUntil: 'load' });
6
+ await page.evaluate(() => {
7
+ Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
8
+ get: function() {
9
+ return !!(this.currentTime > 0 && !this.paused && !this.ended &&
10
+ this.readyState > 2);
11
+ }
12
+ });
13
+ });
14
+ }, 10000);
15
+
16
+ it('Test play', async () => {
17
+ page.waitFor(1500);
18
+ const players = await page.$$eval('video', v => v);
19
+ for (const player of players) {
20
+ const id = '#' + player.playerId + '_html5_api';
21
+ await page.waitFor(1500);
22
+ expect(await page.$eval(id, el => el.playing)).toBe(true);
23
+ }
24
+ });
25
+ });
@@ -0,0 +1,60 @@
1
+ describe('Playlist tests', () => {
2
+
3
+ beforeEach(async () => {
4
+ await page.setViewport({ width: 1280, height: 800 });
5
+ await page.goto('http://localhost:3000/playlist.html', { waitUntil: 'load' });
6
+ await page.evaluate(() => {
7
+ Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
8
+ get: function() {
9
+ return !!(this.currentTime > 0 && !this.paused && !this.ended &&
10
+ this.readyState > 2);
11
+ }
12
+ });
13
+ });
14
+ }, 30000);
15
+
16
+ it('Test playlist layout', async () => {
17
+ await page.waitForSelector('#player_html5_api', { visible: true, timeout: 35000 });
18
+ expect(await page.$('.cld-plw-col-player')).not.toBeNull();
19
+ expect(await page.$('.cld-plw-col-list')).not.toBeNull();
20
+ });
21
+
22
+ /* it('Test direction', async () => {
23
+ await page.waitForSelector('#player_html5_api', { visible: true, timeout: 35000 });
24
+ expect(await page.$('.cld-plw-horizontal')).not.toBeNull();
25
+ expect(await page.$('.cld-plw-vertical')).toBeNull();
26
+ await page.select('select#changePlaylistDirection', 'vertical');
27
+ expect(await page.$('.cld-plw-horizontal')).toBeNull();
28
+ expect(await page.$('.cld-plw-vertical')).not.toBeNull();
29
+ });*/
30
+ /* it('Test number of items', async () => {
31
+ await page.waitForSelector('#player_html5_api', { visible: true, timeout: 35000 });
32
+ let numberOfItems = await page.$eval('input#changePlaylistTotal', inp => parseInt(inp.value, 10));
33
+ let numberOfChildren = await page.$$eval('.cld-plw-panel-item', items => Array.from(items).length);
34
+ expect(numberOfChildren).toEqual(numberOfItems);
35
+ await page.focus('input#changePlaylistTotal');
36
+ await page.keyboard.press('Delete');
37
+ await page.keyboard.type('3');
38
+ numberOfChildren = await page.$$eval('.cld-plw-panel-item', items => Array.from(items).length);
39
+ expect(numberOfChildren).toEqual(3);
40
+ });*/
41
+
42
+ /* it('Test skin', async () => {
43
+ await page.waitForSelector('#player_html5_api', { visible: true, timeout: 35000 });
44
+ expect(await page.$('.cld-video-player-skin-dark')).not.toBeNull();
45
+ expect(await page.$('.cld-video-player-skin-light')).toBeNull();
46
+ await page.select('select#changePlaylistSkin', 'light');
47
+ expect(await page.$('.cld-video-player-skin-dark')).toBeNull();
48
+ expect(await page.$('.cld-video-player-skin-light')).not.toBeNull();
49
+ });*/
50
+
51
+ it('Test video change', async () => {
52
+ await page.waitForSelector('#player_html5_api', { visible: true, timeout: 35000 });
53
+ const curruntVideoUrl = await page.$eval('#player_html5_api', vid => vid.src);
54
+ await page.click('div.cld-plw-col-list > div > a:nth-child(2)');
55
+ const nextVideoUrl = await page.$eval('#player_html5_api', vid => vid.src);
56
+ expect(curruntVideoUrl).not.toEqual(nextVideoUrl);
57
+ });
58
+ });
59
+
60
+
@@ -0,0 +1,19 @@
1
+ const PuppeteerEnvironment = require('jest-environment-puppeteer');
2
+
3
+ class VideoPlayerEnvironment extends PuppeteerEnvironment {
4
+ async setup() {
5
+ await super.setup();
6
+ // Your setup
7
+ }
8
+
9
+ async teardown() {
10
+ // Your teardown
11
+ try {
12
+ await super.teardown();
13
+ } catch (e) {
14
+ console.log(e);
15
+ }
16
+ }
17
+ }
18
+
19
+ module.exports = VideoPlayerEnvironment;
@@ -0,0 +1,38 @@
1
+ describe('Recommendations tests', () => {
2
+ beforeEach(async () => {
3
+ await page.setViewport({width: 1280, height: 1800});
4
+ await page.goto('http://localhost:3000/recommendations.html', {waitUntil: 'load'});
5
+ jest.setTimeout(10000);
6
+ await page.evaluate(() => {
7
+ Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
8
+ get: function() {
9
+ return !!(this.currentTime > 0 && !this.paused && !this.ended &&
10
+ this.readyState > 2);
11
+ }
12
+ });
13
+ });
14
+ }, 10000);
15
+ it('Test recommendations visibility', async () => {
16
+ await page.waitFor(1000);
17
+ let duration = Math.floor(await page.evaluate(() => player.duration()));
18
+ await page.waitFor(1000);
19
+ expect(await page.$eval('.vjs-recommendations-overlay', (o => o.style.visibility))).toEqual('hidden');
20
+ await page.evaluate((dur) => player.currentTime(dur), duration - 1);
21
+ await page.waitForSelector('.vjs-recommendations-overlay', {visible: true});
22
+ expect(await page.$eval('.vjs-recommendations-overlay', (o => o.style.visibility))).toEqual('visible');
23
+ });
24
+ it('Test recommendations click', async () => {
25
+ await page.waitFor(1000);
26
+ let duration = Math.floor(await page.evaluate(() => player.duration()));
27
+ let currentSrcUrl = await page.evaluate(() => player.currentSourceUrl());
28
+ await page.waitFor(1000);
29
+ await page.evaluate((dur) => player.currentTime(dur), duration - 1);
30
+ await page.waitFor('.vjs-recommendations-overlay', {visible: true});
31
+ await page.click('#player > div.vjs-recommendations-overlay > div > div > .vjs-recommendations-overlay-item.vjs-recommendations-overlay-item-primary > .vjs-recommendations-overlay-item-primary-image');
32
+ await page.waitForFunction('player.videojs.readyState() === 4');
33
+ await page.waitFor(1000);
34
+ let recSourceUrl = await page.evaluate(() => player.currentSourceUrl());
35
+ expect(currentSrcUrl).not.toEqual(recSourceUrl);
36
+ expect(await page.$eval('#player_html5_api', el => el.playing)).toBe(true);
37
+ });
38
+ });
@@ -0,0 +1,28 @@
1
+ describe('basic player tests', () => {
2
+ beforeAll(async () => {
3
+ jest.setTimeout(35000);
4
+ await page.setViewport({width: 1280, height: 800});
5
+ await page.goto('http://localhost:3000/', {waitUntil: 'load'});
6
+ await page.evaluate(() => {
7
+ Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
8
+ get: function() {
9
+ return !!(this.currentTime > 0 && !this.paused && !this.ended &&
10
+ this.readyState > 2);
11
+ }
12
+ });
13
+ });
14
+ }, 10000);
15
+ it('Test title bar title', async () => {
16
+ let ds = JSON.parse(await page.$eval('#player', v => v.getAttribute('data-cld-source')));
17
+ let titlebarTitle = await page.$eval('#player > .vjs-title-bar > .vjs-title-bar-title', t => t.textContent);
18
+ await expect(ds.info.title).toEqual(titlebarTitle);
19
+ });
20
+ it('Test title bar subtitle', async () => {
21
+ let ds = JSON.parse(await page.$eval('#player', v => v.getAttribute('data-cld-source')));
22
+ let sub = await page.$eval('#player > .vjs-title-bar > .vjs-title-bar-subtitle', t => t.textContent);
23
+ await expect(ds.info.subtitle).toEqual(sub);
24
+ });
25
+
26
+ });
27
+
28
+
@@ -0,0 +1,49 @@
1
+ describe('UI configuration tests', () => {
2
+ beforeAll(async () => {
3
+ jest.setTimeout(35000);
4
+ await page.setViewport({width: 1280, height: 800});
5
+ await page.goto('http://localhost:3000/docs/ui-config.html', {waitUntil: 'load'});
6
+ await page.evaluate(() => {
7
+ Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
8
+ get: function() {
9
+ return !!(this.currentTime > 0 && !this.paused && !this.ended &&
10
+ this.readyState > 2);
11
+ }
12
+ });
13
+ });
14
+ }, 10000);
15
+ it('Test +/-10 sec', async () => {
16
+ jest.setTimeout(35000);
17
+ await page.waitForFunction('player.videojs.readyState() === 4');
18
+ await page.waitFor(1000);
19
+ await page.click('#player > div.vjs-control-bar > button.vjs-play-control.vjs-control.vjs-button');
20
+ let time = await page.$eval('#player > .vjs-control-bar > .vjs-current-time.vjs-time-control.vjs-control > .vjs-current-time-display', vt => Number(vt.textContent.replace('0:', '')));
21
+ await page.click('#player > div.vjs-control-bar > button.vjs-control.vjs-icon-skip-10-plus.vjs-button');
22
+ await page.waitFor(1000);
23
+ await page.waitForFunction('player.videojs.readyState() === 4');
24
+ let newTime = await page.$eval('#player > .vjs-control-bar > .vjs-current-time.vjs-time-control.vjs-control > .vjs-current-time-display', vt => Number(vt.textContent.replace('0:', '')));
25
+ expect(newTime).toEqual(time + 10);
26
+ await page.click('#player > div.vjs-control-bar > button.vjs-control.vjs-icon-skip-10-min.vjs-button');
27
+ await page.waitFor(1000);
28
+ await page.waitForFunction('player.videojs.readyState() === 4');
29
+ newTime = await page.$eval('#player > .vjs-control-bar > .vjs-current-time.vjs-time-control.vjs-control > .vjs-current-time-display', vt => Number(vt.textContent.replace('0:', '')));
30
+ expect(newTime).toEqual(time);
31
+ });
32
+ it('Test right click no context menu', async () => {
33
+ await page.waitForFunction('player.videojs.readyState() === 4');
34
+ await page.waitFor(1000);
35
+ await page.click('#player_html5_api', {button: 'right'});
36
+ expect(await page.$('div.vjs-menu.vjs-context-menu-ui')).toEqual(null);
37
+ });
38
+ it('Test logo and logo click url', async () => {
39
+ await page.waitForFunction('player.videojs.readyState() === 4');
40
+ await page.waitFor(1000);
41
+ let opts = await page.evaluate(() => player.videojs.options_);
42
+ let href = await page.$eval('#player > div.vjs-control-bar > a', (a) => a.href);
43
+ let backImage = await page.$eval('#player > div.vjs-control-bar > a', (a) => a.style.backgroundImage);
44
+ expect(opts.logoOnclickUrl).toEqual(href.slice(0, href.length - 1));
45
+ expect(opts.logoImageUrl).toEqual(backImage.replace('url\("', ''). replace('"\)', ''));
46
+ });
47
+ });
48
+
49
+
@@ -0,0 +1,22 @@
1
+ import cloudinary from 'cloudinary-core';
2
+ import VideoPlayer from '../../src/video-player';
3
+ cloudinary.VideoPlayer = VideoPlayer;
4
+
5
+ describe('secure true test', () => {
6
+ it('test force secure true', async () => {
7
+ jest.useFakeTimers();
8
+ const cld = cloudinary.Cloudinary.new({ cloud_name: 'demo' });
9
+ document.body.innerHTML = '<div><video id="test"/></div>';
10
+ let vp = new VideoPlayer('test', { hideContextMenu: true, cloudinaryConfig: cld }, false);
11
+ let conf = vp.videojs.cloudinary.cloudinaryConfig().config();
12
+ expect(conf.secure).toEqual(true);
13
+ });
14
+ it('test explicit secure false', async () => {
15
+ jest.useFakeTimers();
16
+ const cld = cloudinary.Cloudinary.new({ cloud_name: 'demo' });
17
+ document.body.innerHTML = '<div><video id="test"/></div>';
18
+ let vp = new VideoPlayer('test', { hideContextMenu: true, cloudinaryConfig: cld, secure: false }, false);
19
+ let conf = vp.videojs.cloudinary.cloudinaryConfig().config();
20
+ expect(conf.secure).toEqual(false);
21
+ });
22
+ });
@@ -0,0 +1,53 @@
1
+ const tracks = [
2
+ {
3
+ default: false,
4
+ kind: 'subtitles',
5
+ label: 'German subtitles',
6
+ src: 'https://res.cloudinary.com/yaronr/raw/upload/v1558966008/Meetup_german.vtt',
7
+ srclang: 'de'
8
+ },
9
+ {
10
+ default: false,
11
+ kind: 'subtitles',
12
+ label: 'Hebrew subtitles',
13
+ src: 'https://res.cloudinary.com/yaronr/raw/upload/v1558966008/Meetup_hebrew.vtt',
14
+ srclang: 'he'
15
+ },
16
+ {
17
+ default: false,
18
+ kind: 'subtitles',
19
+ label: 'Swedish subtitles',
20
+ src: 'https://res.cloudinary.com/yaronr/raw/upload/v1558966008/Meetup_swedish.vtt',
21
+ srclang: 'se'
22
+ }
23
+ ];
24
+ jest.mock('fetch-ponyfill/build/fetch-browser', () => (() => {
25
+ return {
26
+ fetch: jest.fn((url, options) => {
27
+ return new Promise((resolve) => {
28
+ if (url === tracks[2].src) {
29
+ resolve({ status: 404 });
30
+ } else {
31
+ resolve({ status: 200 });
32
+ }
33
+ });
34
+ }),
35
+ default: jest.fn()
36
+ };
37
+ }));
38
+ import { fetch } from 'fetch-ponyfill/build/fetch-browser';
39
+ import { filterAndAddTextTracks } from '../../src/utils/cloudinary';
40
+
41
+ describe('video source tests', () => {
42
+ it('test filter out bad vtt', async (done) => {
43
+ let vjs = jest.createMockFromModule('video.js');
44
+ vjs.addRemoteTextTrack = jest.fn();
45
+ jest.spyOn(vjs, 'addRemoteTextTrack');
46
+ filterAndAddTextTracks(tracks, vjs);
47
+ setTimeout(() => {
48
+ expect(vjs.addRemoteTextTrack).toBeCalledTimes(2);
49
+ done();
50
+ }, 1000);
51
+ });
52
+
53
+ });
@@ -0,0 +1,27 @@
1
+ import { get } from '../../src/utils/object.js';
2
+
3
+ describe('test get utils function', () => {
4
+ const value = { a: { b: [{ c: 2 }], d: undefined } };
5
+
6
+ it('should get primitive value', () => {
7
+ expect(get(value, 'a.b.0.c')).toBe(value.a.b[0].c);
8
+ });
9
+
10
+ it('should get object value', () => {
11
+ expect(get(value, 'a.b')).toBe(value.a.b);
12
+ });
13
+
14
+ it('should get default value', () => {
15
+ const defaultValue = 10;
16
+ expect(get(value, 'a.c', defaultValue)).toBe(defaultValue);
17
+ });
18
+
19
+ it('should get default value if value is undefined', () => {
20
+ expect(get(value, 'a.d', 10)).toBe(10);
21
+ });
22
+
23
+ it('should get default value if the value is not an object', () => {
24
+ expect(get(1, 'a.b', 12)).toBe(12);
25
+ });
26
+
27
+ });