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.
- package/.eslintignore +4 -0
- package/.snyk +19 -0
- package/.travis.yml +8 -0
- package/CHANGELOG.md +329 -0
- package/LICENSE +21 -0
- package/README.md +87 -0
- package/dist/cld-video-player.css +2110 -0
- package/dist/cld-video-player.js +5249 -0
- package/dist/cld-video-player.light.css +1766 -0
- package/dist/cld-video-player.light.js +1399 -0
- package/dist/cld-video-player.light.min.css +1 -0
- package/dist/cld-video-player.light.min.js +2 -0
- package/dist/cld-video-player.light.min.js.LICENSE.txt +23 -0
- package/dist/cld-video-player.min.css +1 -0
- package/dist/cld-video-player.min.js +2 -0
- package/dist/cld-video-player.min.js.LICENSE.txt +26 -0
- package/dist/fonts/cloudinary_icon_for_black_bg.svg +69 -0
- package/dist/fonts/cloudinary_icon_for_white_bg.svg +69 -0
- package/docs/360.html +102 -0
- package/docs/_template.html +93 -0
- package/docs/adaptive-streaming.html +297 -0
- package/docs/analytics.html +140 -0
- package/docs/api.html +302 -0
- package/docs/audio.html +136 -0
- package/docs/autoplay-fallback.html +138 -0
- package/docs/autoplay-on-scroll.html +107 -0
- package/docs/codec-fallback.html +158 -0
- package/docs/colors.html +135 -0
- package/docs/components.html +284 -0
- package/docs/custom-cld-errors.html +134 -0
- package/docs/floating-player.html +98 -0
- package/docs/fluid.html +117 -0
- package/docs/force-hls-subtitles-ios.html +159 -0
- package/docs/index.html +83 -0
- package/docs/interaction-area.html +398 -0
- package/docs/live-customer.html +128 -0
- package/docs/multiple-players.html +125 -0
- package/docs/playlist-by-tag-cap.html +182 -0
- package/docs/playlist-by-tag.html +133 -0
- package/docs/playlist.html +133 -0
- package/docs/poster.html +155 -0
- package/docs/raw-url.html +104 -0
- package/docs/recommendations.html +155 -0
- package/docs/scripts.js +156 -0
- package/docs/seek-thumbs.html +90 -0
- package/docs/shoppable.html +335 -0
- package/docs/subtitles-and-captions.html +267 -0
- package/docs/transformations.html +171 -0
- package/docs/ui-config.html +108 -0
- package/docs/vast-vpaid.html +149 -0
- package/env.example.js +6 -0
- package/env.js +6 -0
- package/jest-puppeteer.config.js +14 -0
- package/jest.config.js +196 -0
- package/package.json +99 -0
- package/sandbox.config.json +3 -0
- package/setupJest.js +1 -0
- package/src/assets/fonts/VideoJS.svg +120 -0
- package/src/assets/fonts/VideoJS.ttf +0 -0
- package/src/assets/fonts/VideoJS.woff +0 -0
- package/src/assets/fonts/icons.json +120 -0
- package/src/assets/icons/cloudinary_icon_for_black_bg.svg +69 -0
- package/src/assets/icons/cloudinary_icon_for_white_bg.svg +69 -0
- package/src/assets/icons/cloudinary_logo_for_dark_bg.svg +188 -0
- package/src/assets/icons/cloudinary_logo_for_white_bg.svg +188 -0
- package/src/assets/icons/info-circle.svg +17 -0
- package/src/assets/styles/ads-label.scss +16 -0
- package/src/assets/styles/components/interaction-areas.scss +158 -0
- package/src/assets/styles/components/playlist.scss +213 -0
- package/src/assets/styles/components/themedButton.scss +48 -0
- package/src/assets/styles/components/thumbnail.scss +94 -0
- package/src/assets/styles/components/title-bar.scss +67 -0
- package/src/assets/styles/components/triangle-volume-bar.scss +52 -0
- package/src/assets/styles/icons.scss +257 -0
- package/src/assets/styles/main.scss +324 -0
- package/src/assets/styles/mixins/aspect-ratio.scss +16 -0
- package/src/assets/styles/mixins/disable-transition.scss +3 -0
- package/src/assets/styles/mixins/mixins.scss +5 -0
- package/src/assets/styles/mixins/skin.scss +64 -0
- package/src/assets/styles/variables.scss +2 -0
- package/src/assets/styles/videojs-ima.scss +252 -0
- package/src/components/component-utils.js +20 -0
- package/src/components/index.js +21 -0
- package/src/components/interaction-area/interaction-area.const.js +30 -0
- package/src/components/interaction-area/interaction-area.service.js +223 -0
- package/src/components/interaction-area/interaction-area.utils.js +236 -0
- package/src/components/jumpButtons/jump-10-minus.js +21 -0
- package/src/components/jumpButtons/jump-10-plus.js +20 -0
- package/src/components/logoButton/logo-button.const.js +3 -0
- package/src/components/logoButton/logo-button.js +30 -0
- package/src/components/logoButton/logo-button.scss +15 -0
- package/src/components/playlist/components/playlist-button.js +34 -0
- package/src/components/playlist/components/playlist-next-button.js +18 -0
- package/src/components/playlist/components/playlist-previous-button.js +18 -0
- package/src/components/playlist/components/playlist.js +5 -0
- package/src/components/playlist/components/playlist.scss +15 -0
- package/src/components/playlist/components/upcoming-video-overlay.js +149 -0
- package/src/components/playlist/components/upcoming-video-overlay.scss +86 -0
- package/src/components/playlist/layout/playlist-layout-custom.js +21 -0
- package/src/components/playlist/layout/playlist-layout-horizontal.js +16 -0
- package/src/components/playlist/layout/playlist-layout-vertical.js +19 -0
- package/src/components/playlist/layout/playlist-layout.js +110 -0
- package/src/components/playlist/panel/playlist-panel-item.js +86 -0
- package/src/components/playlist/panel/playlist-panel.js +92 -0
- package/src/components/playlist/playlist-widget.js +119 -0
- package/src/components/playlist/playlist.const.js +14 -0
- package/src/components/playlist/playlist.js +413 -0
- package/src/components/playlist/thumbnail/thumbnail.js +69 -0
- package/src/components/progress-control-events-blocker/progress-control-events-blocker.js +17 -0
- package/src/components/qualitySelector/quality-selector.scss +10 -0
- package/src/components/qualitySelector/qualitySelector.js +152 -0
- package/src/components/recommendations-overlay/index.js +3 -0
- package/src/components/recommendations-overlay/recommendations-overlay-content.js +57 -0
- package/src/components/recommendations-overlay/recommendations-overlay-hide-button.js +18 -0
- package/src/components/recommendations-overlay/recommendations-overlay-item.js +35 -0
- package/src/components/recommendations-overlay/recommendations-overlay-primary-item.js +81 -0
- package/src/components/recommendations-overlay/recommendations-overlay-secondary-item.js +48 -0
- package/src/components/recommendations-overlay/recommendations-overlay-secondary-items-container.js +35 -0
- package/src/components/recommendations-overlay/recommendations-overlay.js +94 -0
- package/src/components/recommendations-overlay/recommendations-overlay.scss +182 -0
- package/src/components/shoppable-bar/layout/bar-layout.js +111 -0
- package/src/components/shoppable-bar/layout/shoppable-panel-toggle.js +64 -0
- package/src/components/shoppable-bar/layout/shoppable-products-overlay.js +87 -0
- package/src/components/shoppable-bar/panel/shoppable-panel-item.js +105 -0
- package/src/components/shoppable-bar/panel/shoppable-panel.js +172 -0
- package/src/components/shoppable-bar/shoppable-post-widget.js +110 -0
- package/src/components/shoppable-bar/shoppable-widget.const.js +52 -0
- package/src/components/shoppable-bar/shoppable-widget.js +111 -0
- package/src/components/shoppable-bar/shoppable-widget.scss +359 -0
- package/src/components/themeButton/themedButton.const.js +3 -0
- package/src/components/themeButton/themedButton.js +25 -0
- package/src/components/title-bar/title-bar.js +79 -0
- package/src/config/defaults.js +25 -0
- package/src/extended-events.js +228 -0
- package/src/index.js +18 -0
- package/src/mixins/eventable.js +54 -0
- package/src/mixins/playlistable.js +106 -0
- package/src/plugins/analytics/index.js +245 -0
- package/src/plugins/autoplay-on-scroll/index.js +86 -0
- package/src/plugins/cloudinary/common.js +216 -0
- package/src/plugins/cloudinary/event-handler-registry.js +46 -0
- package/src/plugins/cloudinary/index.js +345 -0
- package/src/plugins/cloudinary/models/audio-source/audio-source.const.js +11 -0
- package/src/plugins/cloudinary/models/audio-source/audio-source.js +82 -0
- package/src/plugins/cloudinary/models/base-source.js +107 -0
- package/src/plugins/cloudinary/models/image-source.js +26 -0
- package/src/plugins/cloudinary/models/video-source/video-source.const.js +32 -0
- package/src/plugins/cloudinary/models/video-source/video-source.js +239 -0
- package/src/plugins/cloudinary/models/video-source/video-source.utils.js +57 -0
- package/src/plugins/colors/index.js +303 -0
- package/src/plugins/context-menu/components/context-menu-item.js +12 -0
- package/src/plugins/context-menu/components/context-menu.js +63 -0
- package/src/plugins/context-menu/context-menu.scss +30 -0
- package/src/plugins/context-menu/contextMenuContent.js +53 -0
- package/src/plugins/context-menu/index.js +134 -0
- package/src/plugins/dash/index.js +26 -0
- package/src/plugins/dash/setup-audio-tracks.js +112 -0
- package/src/plugins/dash/setup-text-tracks.js +195 -0
- package/src/plugins/dash/videojs-dash.js +372 -0
- package/src/plugins/floating-player/floating-player.scss +74 -0
- package/src/plugins/floating-player/index.js +129 -0
- package/src/plugins/ima/index.js +1775 -0
- package/src/plugins/index.js +31 -0
- package/src/plugins/interactive-plugin/index.js +10 -0
- package/src/plugins/videojs-http-source-selector/components/SourceMenuButton.js +98 -0
- package/src/plugins/videojs-http-source-selector/components/SourceMenuItem.js +52 -0
- package/src/plugins/videojs-http-source-selector/plugin.js +82 -0
- package/src/plugins/videojs-http-source-selector/plugin.scss +9 -0
- package/src/plugins/vtt-thumbnails/index.js +526 -0
- package/src/plugins/vtt-thumbnails/vtt-thumbnails.scss +29 -0
- package/src/utils/api.js +32 -0
- package/src/utils/apply-with-props.js +32 -0
- package/src/utils/array.js +22 -0
- package/src/utils/assign.js +27 -0
- package/src/utils/attributes-normalizer.js +72 -0
- package/src/utils/cloudinary.js +165 -0
- package/src/utils/css-prefix.js +43 -0
- package/src/utils/dom.js +74 -0
- package/src/utils/find.js +28 -0
- package/src/utils/fontFace.js +25 -0
- package/src/utils/groupBy.js +12 -0
- package/src/utils/index.js +29 -0
- package/src/utils/matches.js +11 -0
- package/src/utils/mixin.js +5 -0
- package/src/utils/object.js +26 -0
- package/src/utils/playButton.js +9 -0
- package/src/utils/positioning.js +78 -0
- package/src/utils/querystring.js +12 -0
- package/src/utils/slicing.js +21 -0
- package/src/utils/string.js +15 -0
- package/src/utils/throttle.js +30 -0
- package/src/utils/time.js +77 -0
- package/src/utils/type-inference.js +35 -0
- package/src/validators/validators-functions.js +48 -0
- package/src/validators/validators-types.js +78 -0
- package/src/validators/validators.js +110 -0
- package/src/video-player.const.js +68 -0
- package/src/video-player.js +761 -0
- package/src/video-player.utils.js +123 -0
- package/test/adaptive-streaming.test.js +38 -0
- package/test/ads.test.js +35 -0
- package/test/analytics.test.js +111 -0
- package/test/api.test.js +111 -0
- package/test/autoplay.scroll.test.js +23 -0
- package/test/basic-ui.test.js +59 -0
- package/test/colors.test.js +58 -0
- package/test/components.test.js +21 -0
- package/test/custom-error.test.js +24 -0
- package/test/fluid.test.js +36 -0
- package/test/isValidConfig.test.js +224 -0
- package/test/mocks/cloudinary-core-mock.js +0 -0
- package/test/mocks/styleMock.js +1 -0
- package/test/multiplayer.test.js +25 -0
- package/test/playlist.test.js +60 -0
- package/test/puppeteer/vp-env.js +19 -0
- package/test/recommendations.test.js +38 -0
- package/test/title-bar.test.js +28 -0
- package/test/ui-conf.test.js +49 -0
- package/test/unit/cloudinaryConfig.test.js +22 -0
- package/test/unit/cloudinaryUtils.test.js +53 -0
- package/test/unit/utils.test.js +27 -0
- package/test/unit/videoSource.test.js +454 -0
- package/tsconfig.json +15 -0
- package/types/video-player-tests.js +12 -0
- package/types/video-player-tests.ts +31 -0
- 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
|
+
});
|