lively 0.2.1 → 0.3.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.
@@ -0,0 +1,285 @@
1
+ import {describe, before, after, it} from 'node:test';
2
+ import {ok, strict, strictEqual} from 'node:assert';
3
+
4
+ import {WebSocket} from 'ws';
5
+ import {JSDOM} from 'jsdom';
6
+ import {Live} from '../Live.js';
7
+
8
+ describe('Live', function () {
9
+ let dom;
10
+ let webSocketServer;
11
+
12
+ const webSocketServerConfig = {port: 3000};
13
+ const webSocketServerURL = `ws://localhost:${webSocketServerConfig.port}/live`;
14
+
15
+ before(async function () {
16
+ const listening = new Promise(resolve => {
17
+ webSocketServer = new WebSocket.Server(webSocketServerConfig, resolve);
18
+ });
19
+
20
+ dom = new JSDOM('<!DOCTYPE html><html><body><div id="my"><p>Hello World</p></div></body></html>');
21
+ // Ensure the WebSocket class is available:
22
+ dom.window.WebSocket = WebSocket;
23
+
24
+ await new Promise(resolve => dom.window.addEventListener('load', resolve));
25
+
26
+ await listening;
27
+ });
28
+
29
+ after(function () {
30
+ webSocketServer.close();
31
+ });
32
+
33
+ it('should start the live connection', function () {
34
+ const live = Live.start({window: dom.window, base: 'http://localhost/'});
35
+ ok(live);
36
+
37
+ strictEqual(live.window, dom.window);
38
+ strictEqual(live.document, dom.window.document);
39
+ strictEqual(live.url.href, 'ws://localhost/live');
40
+ });
41
+
42
+ it('should connect to the WebSocket server', function () {
43
+ const live = new Live(dom.window, webSocketServerURL);
44
+
45
+ const server = live.connect();
46
+ ok(server);
47
+
48
+ live.disconnect();
49
+ });
50
+
51
+ it('should handle visibility changes', function () {
52
+ const live = new Live(dom.window, webSocketServerURL);
53
+
54
+ var hidden = false;
55
+ Object.defineProperty(dom.window.document, "hidden", {
56
+ get() {return hidden},
57
+ });
58
+
59
+ live.handleVisibilityChange();
60
+
61
+ ok(live.server);
62
+
63
+ hidden = true;
64
+
65
+ live.handleVisibilityChange();
66
+
67
+ ok(!live.server);
68
+ });
69
+
70
+ it('should handle updates', async function () {
71
+ const live = new Live(dom.window, webSocketServerURL);
72
+
73
+ live.connect();
74
+
75
+ const connected = new Promise(resolve => {
76
+ webSocketServer.on('connection', resolve);
77
+ });
78
+
79
+ let socket = await connected;
80
+
81
+ const reply = new Promise((resolve, reject) => {
82
+ socket.on('message', message => {
83
+ let payload = JSON.parse(message);
84
+ if (payload.reply) resolve(payload);
85
+ });
86
+ });
87
+
88
+ socket.send(
89
+ JSON.stringify(['update', 'my', '<div id="my"><p>Goodbye World!</p></div>', {reply: true}])
90
+ );
91
+
92
+ await reply;
93
+
94
+ strictEqual(dom.window.document.getElementById('my').innerHTML, '<p>Goodbye World!</p>');
95
+
96
+ live.disconnect();
97
+ });
98
+
99
+ it('should handle replacements', async function () {
100
+ const live = new Live(dom.window, webSocketServerURL);
101
+
102
+ live.connect();
103
+
104
+ const connected = new Promise(resolve => {
105
+ webSocketServer.on('connection', resolve);
106
+ });
107
+
108
+ let socket = await connected;
109
+
110
+ const reply = new Promise((resolve, reject) => {
111
+ socket.on('message', message => {
112
+ let payload = JSON.parse(message);
113
+ if (payload.reply) resolve(payload);
114
+ });
115
+ });
116
+
117
+ socket.send(
118
+ JSON.stringify(['replace', '#my p', '<p>Replaced!</p>', {reply: true}])
119
+ );
120
+
121
+ await reply;
122
+
123
+ strictEqual(dom.window.document.getElementById('my').innerHTML, '<p>Replaced!</p>');
124
+
125
+ live.disconnect();
126
+ });
127
+
128
+ it('should handle prepends', async function () {
129
+ const live = new Live(dom.window, webSocketServerURL);
130
+
131
+ live.connect();
132
+
133
+ const connected = new Promise(resolve => {
134
+ webSocketServer.on('connection', resolve);
135
+ });
136
+
137
+ let socket = await connected;
138
+
139
+ socket.send(
140
+ JSON.stringify(['update', 'my', '<div id="my"><p>Middle</p></div>'])
141
+ );
142
+
143
+ const reply = new Promise((resolve, reject) => {
144
+ socket.on('message', message => {
145
+ let payload = JSON.parse(message);
146
+ if (payload.reply) resolve(payload);
147
+ });
148
+ });
149
+
150
+ socket.send(
151
+ JSON.stringify(['prepend', '#my', '<p>Prepended!</p>', {reply: true}])
152
+ );
153
+
154
+ await reply;
155
+
156
+ strictEqual(dom.window.document.getElementById('my').innerHTML, '<p>Prepended!</p><p>Middle</p>');
157
+
158
+ live.disconnect();
159
+ });
160
+
161
+ it('should handle appends', async function () {
162
+ const live = new Live(dom.window, webSocketServerURL);
163
+
164
+ live.connect();
165
+
166
+ const connected = new Promise(resolve => {
167
+ webSocketServer.on('connection', resolve);
168
+ });
169
+
170
+ let socket = await connected;
171
+
172
+ socket.send(
173
+ JSON.stringify(['update', 'my', '<div id="my"><p>Middle</p></div>'])
174
+ );
175
+
176
+ const reply = new Promise((resolve, reject) => {
177
+ socket.on('message', message => {
178
+ let payload = JSON.parse(message);
179
+ if (payload.reply) resolve(payload);
180
+ });
181
+ });
182
+
183
+ socket.send(
184
+ JSON.stringify(['append', '#my', '<p>Appended!</p>', {reply: true}])
185
+ );
186
+
187
+ await reply;
188
+
189
+ strictEqual(dom.window.document.getElementById('my').innerHTML, '<p>Middle</p><p>Appended!</p>');
190
+
191
+ live.disconnect();
192
+ });
193
+
194
+ it ('should handle removals', async function () {
195
+ const live = new Live(dom.window, webSocketServerURL);
196
+
197
+ live.connect();
198
+
199
+ const connected = new Promise(resolve => {
200
+ webSocketServer.on('connection', resolve);
201
+ });
202
+
203
+ let socket = await connected;
204
+
205
+ socket.send(
206
+ JSON.stringify(['update', 'my', '<div id="my"><p>Middle</p></div>'])
207
+ );
208
+
209
+ const reply = new Promise((resolve, reject) => {
210
+ socket.on('message', message => {
211
+ let payload = JSON.parse(message);
212
+ if (payload.reply) resolve(payload);
213
+ });
214
+ });
215
+
216
+ socket.send(
217
+ JSON.stringify(['remove', '#my p', {reply: true}])
218
+ );
219
+
220
+ await reply;
221
+
222
+ strictEqual(dom.window.document.getElementById('my').innerHTML, '');
223
+
224
+ live.disconnect();
225
+ });
226
+
227
+ it ('can dispatch custom events', async function () {
228
+ const live = new Live(dom.window, webSocketServerURL);
229
+
230
+ live.connect();
231
+
232
+ const connected = new Promise(resolve => {
233
+ webSocketServer.on('connection', resolve);
234
+ });
235
+
236
+ let socket = await connected;
237
+
238
+ const reply = new Promise((resolve, reject) => {
239
+ socket.on('message', message => {
240
+ let payload = JSON.parse(message);
241
+ if (payload.reply) resolve(payload);
242
+ });
243
+ });
244
+
245
+ socket.send(
246
+ JSON.stringify(['dispatchEvent', '#my', 'click', {reply: true}])
247
+ );
248
+
249
+ await reply;
250
+
251
+ live.disconnect();
252
+ });
253
+
254
+ it ('can forward events', async function () {
255
+ const live = new Live(dom.window, webSocketServerURL);
256
+
257
+ live.connect();
258
+
259
+ const connected = new Promise(resolve => {
260
+ webSocketServer.on('connection', resolve);
261
+ });
262
+
263
+ let socket = await connected;
264
+
265
+ const reply = new Promise((resolve, reject) => {
266
+ socket.on('message', message => {
267
+ let payload = JSON.parse(message);
268
+ if (payload.event) resolve(payload);
269
+ });
270
+ });
271
+
272
+ dom.window.document.getElementById('my').addEventListener('click', event => {
273
+ live.forwardEvent('my', event);
274
+ });
275
+
276
+ dom.window.document.getElementById('my').click();
277
+
278
+ let payload = await reply;
279
+
280
+ strictEqual(payload.id, 'my');
281
+ strictEqual(payload.event.type, 'click');
282
+
283
+ live.disconnect();
284
+ });
285
+ });