@clappr/player 0.12.9 → 0.13.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clappr/player",
3
- "version": "0.12.9",
3
+ "version": "0.13.0",
4
4
  "description": "An extensible media player for the web",
5
5
  "main": "dist/clappr.js",
6
6
  "scripts": {
@@ -8,9 +8,10 @@
8
8
  "bundle-check": "ANALYZE_BUNDLE=true rollup --config --bundleConfigAsCjs",
9
9
  "lint": "eslint *.js src/",
10
10
  "lint:fix": "npm run lint -- --fix",
11
- "release": "MINIMIZE=true rollup --config --bundleConfigAsCjs",
11
+ "release": "rm -rf dist && MINIMIZE=true rollup --config --bundleConfigAsCjs",
12
12
  "start": "DEV=true rollup --config --bundleConfigAsCjs --watch",
13
13
  "test": "echo 'No tests configured. This project is only for bundling the player components.'",
14
+ "test:smoke": "jest ./src/dist.smoke.test.js --testPathIgnorePatterns=/node_modules/ --silent",
14
15
  "watch": "rollup --config --bundleConfigAsCjs --watch",
15
16
  "prepublishOnly": "lerna run release --scope=@clappr/player"
16
17
  },
@@ -33,9 +34,9 @@
33
34
  },
34
35
  "homepage": "https://github.com/clappr/clappr",
35
36
  "devDependencies": {
36
- "@clappr/core": "^0.14.8",
37
- "@clappr/hlsjs-playback": "^1.9.13",
38
- "@clappr/plugins": "^0.9.8",
37
+ "@clappr/core": "^0.15.0",
38
+ "@clappr/hlsjs-playback": "^2.0.1",
39
+ "@clappr/plugins": "^0.9.9",
39
40
  "@rollup/plugin-replace": "^2.4.2",
40
41
  "rollup-plugin-filesize": "^9.1.1",
41
42
  "rollup-plugin-serve": "^1.1.0"
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Smoke-tests the published dist/ artifacts. The player bundle embeds core,
3
+ * plugins and playbacks, so identity checks are against the same module.
4
+ */
5
+ const fs = require('fs')
6
+ const path = require('path')
7
+ const vm = require('vm')
8
+ const { TextEncoder, TextDecoder } = require('util')
9
+
10
+ // jest-environment-jsdom omits these; must run before the require below —
11
+ // jsdom's whatwg-url throws on load without TextEncoder/TextDecoder.
12
+ global.TextEncoder = global.TextEncoder || TextEncoder
13
+ global.TextDecoder = global.TextDecoder || TextDecoder
14
+ const { JSDOM } = require('jsdom')
15
+
16
+ const DIST = path.join(__dirname, '..', 'dist')
17
+ const pkg = require('../package.json')
18
+
19
+ const ARTIFACTS = {
20
+ main: 'clappr.js',
21
+ mainMin: 'clappr.min.js',
22
+ plainhtml5: 'clappr.plainhtml5.js',
23
+ plainhtml5Min: 'clappr.plainhtml5.min.js'
24
+ }
25
+
26
+ const FULL_PLAYER = [ARTIFACTS.main, ARTIFACTS.mainMin]
27
+ const PLAINHTML5 = [ARTIFACTS.plainhtml5, ARTIFACTS.plainhtml5Min]
28
+ const UMD_ARTIFACTS = Object.values(ARTIFACTS)
29
+
30
+ // Demo-only unminified entry: no map per AGENTS.md sourcemap policy.
31
+ const EXPECTED_SOURCEMAPS = [
32
+ 'clappr.js.map',
33
+ 'clappr.min.js.map',
34
+ 'clappr.plainhtml5.min.js.map'
35
+ ].sort()
36
+
37
+ function readArtifact(name) {
38
+ return fs.readFileSync(path.join(DIST, name), 'utf8')
39
+ }
40
+
41
+ function loadArtifact(name) {
42
+ jest.resetModules()
43
+ return require(path.join(DIST, name))
44
+ }
45
+
46
+ function resolveClappr(mod) {
47
+ return mod.default || mod
48
+ }
49
+
50
+ function loadUmdInSandbox(filename, { amd = false } = {}) {
51
+ const code = readArtifact(filename)
52
+ const dom = new JSDOM('<!doctype html><html><body></body></html>', {
53
+ url: 'http://localhost/',
54
+ pretendToBeVisual: true,
55
+ runScripts: 'outside-only'
56
+ })
57
+ const sandbox = dom.getInternalVMContext()
58
+
59
+ let amdExports
60
+ if (amd) {
61
+ sandbox.define = (depsOrFactory, maybeFactory) => {
62
+ if (typeof depsOrFactory === 'function') {
63
+ amdExports = depsOrFactory()
64
+ return
65
+ }
66
+ const factory = maybeFactory
67
+ const args = depsOrFactory.map(dep => {
68
+ if (dep === 'exports') {
69
+ amdExports = {}
70
+ return amdExports
71
+ }
72
+ return undefined
73
+ })
74
+ factory(...args)
75
+ }
76
+ sandbox.define.amd = {}
77
+ }
78
+
79
+ vm.runInContext(code, sandbox, { filename: path.join(DIST, filename) })
80
+ return { sandbox, amdExports }
81
+ }
82
+
83
+ function prototypeChainContains(pluginProto, baseProto) {
84
+ let proto = pluginProto
85
+ while (proto) {
86
+ if (proto === baseProto) return true
87
+ proto = Object.getPrototypeOf(proto)
88
+ }
89
+ return false
90
+ }
91
+
92
+ function assertSharedBundleContract(C) {
93
+ expect(C.version).toBe(pkg.version)
94
+
95
+ const bases = [
96
+ C.ContainerPlugin.prototype,
97
+ C.CorePlugin.prototype,
98
+ C.UIContainerPlugin.prototype,
99
+ C.UICorePlugin.prototype
100
+ ]
101
+
102
+ for (const Plugin of Object.values(C.Plugins)) {
103
+ expect(typeof Plugin).toBe('function')
104
+ const matchesBase = bases.some(base =>
105
+ prototypeChainContains(Object.getPrototypeOf(Plugin.prototype), base)
106
+ )
107
+ expect(matchesBase).toBe(true)
108
+ }
109
+ }
110
+
111
+ function assertSourceMappingURL(filename) {
112
+ expect(readArtifact(filename)).toContain(`sourceMappingURL=${filename}.map`)
113
+ }
114
+
115
+ describe.each([
116
+ ['main UMD', ARTIFACTS.main],
117
+ ['main UMD minified', ARTIFACTS.mainMin],
118
+ ['plainhtml5 UMD', ARTIFACTS.plainhtml5],
119
+ ['plainhtml5 UMD minified', ARTIFACTS.plainhtml5Min]
120
+ ])('%s (%s)', (_label, filename) => {
121
+ test('exports plugins that extend the same-bundle plugin bases', () => {
122
+ assertSharedBundleContract(resolveClappr(loadArtifact(filename)))
123
+ })
124
+ })
125
+
126
+ describe('full player HLS', () => {
127
+ test.each(FULL_PLAYER)('%s HLS extends HTML5Video', filename => {
128
+ const C = resolveClappr(loadArtifact(filename))
129
+ expect(Object.getPrototypeOf(C.HLS.prototype)).toBe(C.HTML5Video.prototype)
130
+ })
131
+ })
132
+
133
+ describe('plainhtml5 bundle', () => {
134
+ test.each(PLAINHTML5)('%s has no HLS', filename => {
135
+ const C = resolveClappr(loadArtifact(filename))
136
+ expect(C.HLS).toBeUndefined()
137
+ })
138
+ })
139
+
140
+ describe('UMD global and AMD branches', () => {
141
+ test.each(UMD_ARTIFACTS)('%s sets global Clappr without an AMD loader', filename => {
142
+ const { sandbox } = loadUmdInSandbox(filename, { amd: false })
143
+ expect(typeof sandbox.Clappr).toBe('object')
144
+ expect(typeof sandbox.Clappr.Player).toBe('function')
145
+ })
146
+
147
+ test.each(UMD_ARTIFACTS)('%s does not set global Clappr when define.amd is present', filename => {
148
+ const { sandbox, amdExports } = loadUmdInSandbox(filename, { amd: true })
149
+ expect(sandbox.Clappr).toBeUndefined()
150
+ expect(typeof amdExports.Player).toBe('function')
151
+ })
152
+ })
153
+
154
+ describe('sourcemap comments', () => {
155
+ test.each([ARTIFACTS.main, ARTIFACTS.mainMin, ARTIFACTS.plainhtml5Min])(
156
+ '%s publishes a sourcemap comment',
157
+ filename => {
158
+ assertSourceMappingURL(filename)
159
+ }
160
+ )
161
+ })
162
+
163
+ describe('dist sourcemap inventory', () => {
164
+ test('ships exactly the expected .map files', () => {
165
+ const maps = fs
166
+ .readdirSync(DIST)
167
+ .filter(f => f.endsWith('.map'))
168
+ .sort()
169
+ expect(maps).toEqual(EXPECTED_SOURCEMAPS)
170
+ })
171
+ })