]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/client.ts
Improve release doc
[github/Chocobozzz/PeerTube.git] / server / tests / client.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
0e1dc3e7
C
2
3import 'mocha'
4import * as chai from 'chai'
012580d9 5import { omit } from 'lodash'
4c7e60bc 6import { Account, HTMLServerConfig, HttpStatusCode, ServerConfig, VideoPlaylistCreateResult, VideoPlaylistPrivacy } from '@shared/models'
0e1dc3e7 7import {
7c3b7976 8 cleanupTests,
254d3579 9 createMultipleServers,
4c7e60bc 10 doubleFollow,
012580d9 11 makeGetRequest,
590fb506 12 makeHTMLRequest,
254d3579 13 PeerTubeServer,
a59f210f 14 setAccessTokensToServers,
39433fa5 15 setDefaultVideoChannel,
a59f210f 16 waitJobs
94565d52 17} from '../../shared/extra-utils'
590fb506
C
18
19const expect = chai.expect
5bcfd029 20
aea0b0e7 21function checkIndexTags (html: string, title: string, description: string, css: string, config: ServerConfig) {
5bcfd029
C
22 expect(html).to.contain('<title>' + title + '</title>')
23 expect(html).to.contain('<meta name="description" content="' + description + '" />')
24 expect(html).to.contain('<style class="custom-css-style">' + css + '</style>')
aea0b0e7
C
25
26 const htmlConfig: HTMLServerConfig = omit(config, 'signup')
27 expect(html).to.contain(`<script type="application/javascript">window.PeerTubeServerConfig = '${JSON.stringify(htmlConfig)}'</script>`)
5bcfd029 28}
0e1dc3e7
C
29
30describe('Test a client controllers', function () {
254d3579 31 let servers: PeerTubeServer[] = []
39433fa5
C
32 let account: Account
33
34 const videoName = 'my super name for server 1'
a073c912
RK
35 const videoDescription = 'my<br> super __description__ for *server* 1<p></p>'
36 const videoDescriptionPlainText = 'my super description for server 1'
39433fa5
C
37
38 const playlistName = 'super playlist name'
39 const playlistDescription = 'super playlist description'
d4a8e7a6 40 let playlist: VideoPlaylistCreateResult
39433fa5
C
41
42 const channelDescription = 'my super channel description'
0e1dc3e7 43
a1eda903
C
44 const watchVideoBasePaths = [ '/videos/watch/', '/w/' ]
45 const watchPlaylistBasePaths = [ '/videos/watch/playlist/', '/w/p/' ]
46
d4a8e7a6
C
47 let videoIds: (string | number)[] = []
48 let playlistIds: (string | number)[] = []
49
0e1dc3e7
C
50 before(async function () {
51 this.timeout(120000)
52
254d3579 53 servers = await createMultipleServers(2)
e5024f51
TC
54
55 await setAccessTokensToServers(servers)
56
e5024f51
TC
57 await doubleFollow(servers[0], servers[1])
58
a59f210f 59 await setDefaultVideoChannel(servers)
0e1dc3e7 60
89d241a7
C
61 await servers[0].channels.update({
62 channelName: servers[0].store.channel.name,
a5461888
C
63 attributes: { description: channelDescription }
64 })
8d987ec6 65
39433fa5 66 // Video
8d987ec6 67
d23dd9fb
C
68 {
69 const attributes = { name: videoName, description: videoDescription }
89d241a7 70 await servers[0].videos.upload({ attributes })
0e1dc3e7 71
89d241a7 72 const { data } = await servers[0].videos.list()
d23dd9fb 73 expect(data.length).to.equal(1)
0e1dc3e7 74
d23dd9fb 75 const video = data[0]
89d241a7 76 servers[0].store.video = video
d23dd9fb
C
77 videoIds = [ video.id, video.uuid, video.shortUUID ]
78 }
8d987ec6
K
79
80 // Playlist
81
d23dd9fb
C
82 {
83 const attributes = {
84 displayName: playlistName,
85 description: playlistDescription,
86 privacy: VideoPlaylistPrivacy.PUBLIC,
89d241a7 87 videoChannelId: servers[0].store.channel.id
d23dd9fb 88 }
8d987ec6 89
89d241a7 90 playlist = await servers[0].playlists.create({ attributes })
d23dd9fb 91 playlistIds = [ playlist.id, playlist.shortUUID, playlist.uuid ]
8d987ec6 92
89d241a7 93 await servers[0].playlists.addElement({ playlistId: playlist.shortUUID, attributes: { videoId: servers[0].store.video.id } })
d23dd9fb 94 }
8d987ec6
K
95
96 // Account
97
d23dd9fb 98 {
89d241a7 99 await servers[0].users.updateMe({ description: 'my account description' })
8d987ec6 100
89d241a7 101 account = await servers[0].accounts.get({ accountName: `${servers[0].store.user.username}@${servers[0].host}` })
d23dd9fb 102 }
a59f210f
C
103
104 await waitJobs(servers)
0e1dc3e7
C
105 })
106
6fad8e51 107 describe('oEmbed', function () {
a1eda903 108
6fad8e51 109 it('Should have valid oEmbed discovery tags for videos', async function () {
a1eda903 110 for (const basePath of watchVideoBasePaths) {
d4a8e7a6
C
111 for (const id of videoIds) {
112 const res = await makeGetRequest({
113 url: servers[0].url,
114 path: basePath + id,
115 accept: 'text/html',
c0e8b12e 116 expectedStatus: HttpStatusCode.OK_200
d4a8e7a6 117 })
0e1dc3e7 118
d4a8e7a6 119 const port = servers[0].port
0e1dc3e7 120
d4a8e7a6 121 const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
a892c54a 122 `url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2F${servers[0].store.video.shortUUID}" ` +
89d241a7 123 `title="${servers[0].store.video.name}" />`
8d987ec6 124
d4a8e7a6
C
125 expect(res.text).to.contain(expectedLink)
126 }
a1eda903 127 }
6fad8e51 128 })
8d987ec6 129
6fad8e51 130 it('Should have valid oEmbed discovery tags for a playlist', async function () {
a1eda903 131 for (const basePath of watchPlaylistBasePaths) {
d4a8e7a6
C
132 for (const id of playlistIds) {
133 const res = await makeGetRequest({
134 url: servers[0].url,
135 path: basePath + id,
136 accept: 'text/html',
c0e8b12e 137 expectedStatus: HttpStatusCode.OK_200
d4a8e7a6 138 })
6fad8e51 139
d4a8e7a6 140 const port = servers[0].port
8d987ec6 141
d4a8e7a6 142 const expectedLink = '<link rel="alternate" type="application/json+oembed" href="http://localhost:' + port + '/services/oembed?' +
a892c54a 143 `url=http%3A%2F%2Flocalhost%3A${port}%2Fw%2Fp%2F${playlist.shortUUID}" ` +
d4a8e7a6 144 `title="${playlistName}" />`
8d987ec6 145
d4a8e7a6
C
146 expect(res.text).to.contain(expectedLink)
147 }
a1eda903 148 }
6fad8e51 149 })
8d987ec6
K
150 })
151
6fad8e51 152 describe('Open Graph', function () {
8d987ec6 153
012580d9 154 async function accountPageTest (path: string) {
c0e8b12e 155 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
012580d9 156 const text = res.text
9a911038 157
012580d9
C
158 expect(text).to.contain(`<meta property="og:title" content="${account.displayName}" />`)
159 expect(text).to.contain(`<meta property="og:description" content="${account.description}" />`)
160 expect(text).to.contain('<meta property="og:type" content="website" />')
89d241a7 161 expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/accounts/${servers[0].store.user.username}" />`)
012580d9 162 }
9a911038 163
012580d9 164 async function channelPageTest (path: string) {
c0e8b12e 165 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
012580d9 166 const text = res.text
0e1dc3e7 167
89d241a7 168 expect(text).to.contain(`<meta property="og:title" content="${servers[0].store.channel.displayName}" />`)
012580d9
C
169 expect(text).to.contain(`<meta property="og:description" content="${channelDescription}" />`)
170 expect(text).to.contain('<meta property="og:type" content="website" />')
89d241a7 171 expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/video-channels/${servers[0].store.channel.name}" />`)
012580d9
C
172 }
173
a1eda903 174 async function watchVideoPageTest (path: string) {
c0e8b12e 175 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
a1eda903
C
176 const text = res.text
177
178 expect(text).to.contain(`<meta property="og:title" content="${videoName}" />`)
179 expect(text).to.contain(`<meta property="og:description" content="${videoDescriptionPlainText}" />`)
180 expect(text).to.contain('<meta property="og:type" content="video" />')
a892c54a 181 expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/w/${servers[0].store.video.shortUUID}" />`)
a1eda903
C
182 }
183
184 async function watchPlaylistPageTest (path: string) {
c0e8b12e 185 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
a1eda903
C
186 const text = res.text
187
188 expect(text).to.contain(`<meta property="og:title" content="${playlistName}" />`)
189 expect(text).to.contain(`<meta property="og:description" content="${playlistDescription}" />`)
190 expect(text).to.contain('<meta property="og:type" content="video" />')
a892c54a 191 expect(text).to.contain(`<meta property="og:url" content="${servers[0].url}/w/p/${playlist.shortUUID}" />`)
a1eda903
C
192 }
193
012580d9 194 it('Should have valid Open Graph tags on the account page', async function () {
89d241a7
C
195 await accountPageTest('/accounts/' + servers[0].store.user.username)
196 await accountPageTest('/a/' + servers[0].store.user.username)
197 await accountPageTest('/@' + servers[0].store.user.username)
6fad8e51 198 })
d8755eed 199
6fad8e51 200 it('Should have valid Open Graph tags on the channel page', async function () {
89d241a7
C
201 await channelPageTest('/video-channels/' + servers[0].store.channel.name)
202 await channelPageTest('/c/' + servers[0].store.channel.name)
203 await channelPageTest('/@' + servers[0].store.channel.name)
6fad8e51 204 })
d8755eed 205
a1eda903 206 it('Should have valid Open Graph tags on the watch page', async function () {
d4a8e7a6
C
207 for (const path of watchVideoBasePaths) {
208 for (const id of videoIds) {
209 await watchVideoPageTest(path + id)
210 }
211 }
6fad8e51 212 })
8d987ec6 213
6fad8e51 214 it('Should have valid Open Graph tags on the watch playlist page', async function () {
d4a8e7a6
C
215 for (const path of watchPlaylistBasePaths) {
216 for (const id of playlistIds) {
217 await watchPlaylistPageTest(path + id)
218 }
219 }
6fad8e51 220 })
8d987ec6
K
221 })
222
6fad8e51 223 describe('Twitter card', async function () {
8d987ec6 224
012580d9 225 describe('Not whitelisted', function () {
8d987ec6 226
012580d9 227 async function accountPageTest (path: string) {
c0e8b12e 228 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
012580d9 229 const text = res.text
8d987ec6 230
012580d9
C
231 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
232 expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
233 expect(text).to.contain(`<meta property="twitter:title" content="${account.name}" />`)
234 expect(text).to.contain(`<meta property="twitter:description" content="${account.description}" />`)
235 }
8be1afa1 236
012580d9 237 async function channelPageTest (path: string) {
c0e8b12e 238 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
012580d9 239 const text = res.text
8be1afa1 240
012580d9
C
241 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
242 expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
89d241a7 243 expect(text).to.contain(`<meta property="twitter:title" content="${servers[0].store.channel.displayName}" />`)
012580d9 244 expect(text).to.contain(`<meta property="twitter:description" content="${channelDescription}" />`)
9a911038
K
245 }
246
a1eda903 247 async function watchVideoPageTest (path: string) {
c0e8b12e 248 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
a1eda903 249 const text = res.text
8be1afa1 250
a1eda903
C
251 expect(text).to.contain('<meta property="twitter:card" content="summary_large_image" />')
252 expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
253 expect(text).to.contain(`<meta property="twitter:title" content="${videoName}" />`)
254 expect(text).to.contain(`<meta property="twitter:description" content="${videoDescriptionPlainText}" />`)
255 }
256
257 async function watchPlaylistPageTest (path: string) {
c0e8b12e 258 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
a1eda903
C
259 const text = res.text
260
261 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
262 expect(text).to.contain('<meta property="twitter:site" content="@Chocobozzz" />')
263 expect(text).to.contain(`<meta property="twitter:title" content="${playlistName}" />`)
264 expect(text).to.contain(`<meta property="twitter:description" content="${playlistDescription}" />`)
265 }
266
267 it('Should have valid twitter card on the watch video page', async function () {
d4a8e7a6
C
268 for (const path of watchVideoBasePaths) {
269 for (const id of videoIds) {
270 await watchVideoPageTest(path + id)
271 }
272 }
012580d9 273 })
9a911038 274
012580d9 275 it('Should have valid twitter card on the watch playlist page', async function () {
d4a8e7a6
C
276 for (const path of watchPlaylistBasePaths) {
277 for (const id of playlistIds) {
278 await watchPlaylistPageTest(path + id)
279 }
280 }
012580d9
C
281 })
282
283 it('Should have valid twitter card on the account page', async function () {
284 await accountPageTest('/accounts/' + account.name)
285 await accountPageTest('/a/' + account.name)
286 await accountPageTest('/@' + account.name)
287 })
288
289 it('Should have valid twitter card on the channel page', async function () {
89d241a7
C
290 await channelPageTest('/video-channels/' + servers[0].store.channel.name)
291 await channelPageTest('/c/' + servers[0].store.channel.name)
292 await channelPageTest('/@' + servers[0].store.channel.name)
012580d9 293 })
6fad8e51 294 })
8d987ec6 295
012580d9 296 describe('Whitelisted', function () {
8d987ec6 297
012580d9 298 before(async function () {
89d241a7 299 const config = await servers[0].config.getCustomConfig()
012580d9
C
300 config.services.twitter = {
301 username: '@Kuja',
302 whitelisted: true
303 }
8d987ec6 304
89d241a7 305 await servers[0].config.updateCustomConfig({ newCustomConfig: config })
012580d9 306 })
8d987ec6 307
012580d9 308 async function accountPageTest (path: string) {
c0e8b12e 309 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
012580d9 310 const text = res.text
8be1afa1 311
012580d9
C
312 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
313 expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
9a911038
K
314 }
315
012580d9 316 async function channelPageTest (path: string) {
c0e8b12e 317 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
012580d9 318 const text = res.text
9a911038 319
012580d9
C
320 expect(text).to.contain('<meta property="twitter:card" content="summary" />')
321 expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
322 }
9a911038 323
a1eda903 324 async function watchVideoPageTest (path: string) {
c0e8b12e 325 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
a1eda903 326 const text = res.text
6fad8e51 327
a1eda903
C
328 expect(text).to.contain('<meta property="twitter:card" content="player" />')
329 expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
330 }
331
332 async function watchPlaylistPageTest (path: string) {
c0e8b12e 333 const res = await makeGetRequest({ url: servers[0].url, path, accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
a1eda903
C
334 const text = res.text
335
336 expect(text).to.contain('<meta property="twitter:card" content="player" />')
337 expect(text).to.contain('<meta property="twitter:site" content="@Kuja" />')
338 }
339
340 it('Should have valid twitter card on the watch video page', async function () {
d4a8e7a6
C
341 for (const path of watchVideoBasePaths) {
342 for (const id of videoIds) {
343 await watchVideoPageTest(path + id)
344 }
345 }
012580d9 346 })
9a911038 347
012580d9 348 it('Should have valid twitter card on the watch playlist page', async function () {
d4a8e7a6
C
349 for (const path of watchPlaylistBasePaths) {
350 for (const id of playlistIds) {
351 await watchPlaylistPageTest(path + id)
352 }
353 }
012580d9
C
354 })
355
356 it('Should have valid twitter card on the account page', async function () {
357 await accountPageTest('/accounts/' + account.name)
358 await accountPageTest('/a/' + account.name)
359 await accountPageTest('/@' + account.name)
360 })
361
362 it('Should have valid twitter card on the channel page', async function () {
89d241a7
C
363 await channelPageTest('/video-channels/' + servers[0].store.channel.name)
364 await channelPageTest('/c/' + servers[0].store.channel.name)
365 await channelPageTest('/@' + servers[0].store.channel.name)
012580d9 366 })
6fad8e51 367 })
5bcfd029
C
368 })
369
6fad8e51
C
370 describe('Index HTML', function () {
371
372 it('Should have valid index html tags (title, description...)', async function () {
89d241a7 373 const config = await servers[0].config.getConfig()
a59f210f 374 const res = await makeHTMLRequest(servers[0].url, '/videos/trending')
6fad8e51
C
375
376 const description = 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.'
65e6e260 377 checkIndexTags(res.text, 'PeerTube', description, '', config)
590fb506 378 })
5bcfd029 379
6fad8e51 380 it('Should update the customized configuration and have the correct index html tags', async function () {
89d241a7 381 await servers[0].config.updateCustomSubConfig({
65e6e260
C
382 newConfig: {
383 instance: {
384 name: 'PeerTube updated',
385 shortDescription: 'my short description',
386 description: 'my super description',
387 terms: 'my super terms',
388 defaultNSFWPolicy: 'blur',
389 defaultClientRoute: '/videos/recently-added',
390 customizations: {
391 javascript: 'alert("coucou")',
392 css: 'body { background-color: red; }'
393 }
6fad8e51
C
394 }
395 }
396 })
5bcfd029 397
89d241a7 398 const config = await servers[0].config.getConfig()
a59f210f 399 const res = await makeHTMLRequest(servers[0].url, '/videos/trending')
6fad8e51 400
65e6e260 401 checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }', config)
6fad8e51 402 })
5bcfd029 403
6fad8e51 404 it('Should have valid index html updated tags (title, description...)', async function () {
89d241a7 405 const config = await servers[0].config.getConfig()
a59f210f 406 const res = await makeHTMLRequest(servers[0].url, '/videos/trending')
5bcfd029 407
65e6e260 408 checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }', config)
6fad8e51 409 })
e5024f51
TC
410
411 it('Should use the original video URL for the canonical tag', async function () {
a1eda903 412 for (const basePath of watchVideoBasePaths) {
d4a8e7a6
C
413 for (const id of videoIds) {
414 const res = await makeHTMLRequest(servers[1].url, basePath + id)
89d241a7 415 expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/videos/watch/${servers[0].store.video.uuid}" />`)
d4a8e7a6 416 }
a1eda903 417 }
a59f210f
C
418 })
419
420 it('Should use the original account URL for the canonical tag', async function () {
65e6e260 421 const accountURLtest = res => {
9a911038
K
422 expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/accounts/root" />`)
423 }
424
425 accountURLtest(await makeHTMLRequest(servers[1].url, '/accounts/root@' + servers[0].host))
426 accountURLtest(await makeHTMLRequest(servers[1].url, '/a/root@' + servers[0].host))
427 accountURLtest(await makeHTMLRequest(servers[1].url, '/@root@' + servers[0].host))
a59f210f
C
428 })
429
430 it('Should use the original channel URL for the canonical tag', async function () {
65e6e260 431 const channelURLtests = res => {
9a911038
K
432 expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-channels/root_channel" />`)
433 }
434
435 channelURLtests(await makeHTMLRequest(servers[1].url, '/video-channels/root_channel@' + servers[0].host))
436 channelURLtests(await makeHTMLRequest(servers[1].url, '/c/root_channel@' + servers[0].host))
437 channelURLtests(await makeHTMLRequest(servers[1].url, '/@root_channel@' + servers[0].host))
a59f210f
C
438 })
439
440 it('Should use the original playlist URL for the canonical tag', async function () {
a1eda903 441 for (const basePath of watchPlaylistBasePaths) {
d4a8e7a6
C
442 for (const id of playlistIds) {
443 const res = await makeHTMLRequest(servers[1].url, basePath + id)
444 expect(res.text).to.contain(`<link rel="canonical" href="${servers[0].url}/video-playlists/${playlist.uuid}" />`)
445 }
a1eda903 446 }
e5024f51 447 })
352819ef
C
448
449 it('Should add noindex meta tag for remote accounts', async function () {
450 const handle = 'root@' + servers[0].host
451 const paths = [ '/accounts/', '/a/', '/@' ]
452
453 for (const path of paths) {
454 {
455 const { text } = await makeHTMLRequest(servers[1].url, path + handle)
456 expect(text).to.contain('<meta name="robots" content="noindex" />')
457 }
458
459 {
460 const { text } = await makeHTMLRequest(servers[0].url, path + handle)
461 expect(text).to.not.contain('<meta name="robots" content="noindex" />')
462 }
463 }
464 })
465
466 it('Should add noindex meta tag for remote accounts', async function () {
467 const handle = 'root_channel@' + servers[0].host
468 const paths = [ '/video-channels/', '/c/', '/@' ]
469
470 for (const path of paths) {
471 {
472 const { text } = await makeHTMLRequest(servers[1].url, path + handle)
473 expect(text).to.contain('<meta name="robots" content="noindex" />')
474 }
475
476 {
477 const { text } = await makeHTMLRequest(servers[0].url, path + handle)
478 expect(text).to.not.contain('<meta name="robots" content="noindex" />')
479 }
480 }
481 })
5bcfd029
C
482 })
483
aea0b0e7
C
484 describe('Embed HTML', function () {
485
486 it('Should have the correct embed html tags', async function () {
89d241a7
C
487 const config = await servers[0].config.getConfig()
488 const res = await makeHTMLRequest(servers[0].url, servers[0].store.video.embedPath)
aea0b0e7 489
65e6e260 490 checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }', config)
aea0b0e7
C
491 })
492 })
493
7c3b7976 494 after(async function () {
a59f210f 495 await cleanupTests(servers)
0e1dc3e7
C
496 })
497})