lively 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ });