Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: port websocket tests to node test runner #2553

Merged
merged 13 commits into from
Dec 30, 2023
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"test:tap": "tap test/*.js test/diagnostics-channel/*.js",
"test:tdd": "tap test/*.js test/diagnostics-channel/*.js -w",
"test:typescript": "tsd && tsc --skipLibCheck test/imports/undici-import.ts",
"test:websocket": "tap test/websocket/*.js",
"test:websocket": "borp --coverage -p \"test/websocket/*.js\"",
"test:wpt": "node test/wpt/start-fetch.mjs && node test/wpt/start-FileAPI.mjs && node test/wpt/start-mimesniff.mjs && node test/wpt/start-xhr.mjs && node test/wpt/start-websockets.mjs",
"coverage": "nyc --reporter=text --reporter=html npm run test",
"coverage:ci": "nyc --reporter=lcov npm run test",
Expand All @@ -100,6 +100,7 @@
"@types/node": "^18.0.3",
"abort-controller": "^3.0.0",
"atomic-sleep": "^1.0.0",
"borp": "^0.4.2",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"chai-iterator": "^3.0.2",
Expand Down
185 changes: 93 additions & 92 deletions test/websocket/close.js
Original file line number Diff line number Diff line change
@@ -1,130 +1,131 @@
'use strict'

const { test } = require('tap')
const { describe, test } = require('node:test')
const assert = require('node:assert')
const { WebSocketServer } = require('ws')
const { WebSocket } = require('../..')

test('Close', (t) => {
t.plan(6)

t.test('Close with code', (t) => {
t.plan(1)

const server = new WebSocketServer({ port: 0 })

server.on('connection', (ws) => {
ws.on('close', (code) => {
t.equal(code, 1000)
describe('Close', () => {
test('Close with code', () => {
return new Promise((resolve) => {
const server = new WebSocketServer({ port: 0 })

server.on('connection', (ws) => {
ws.on('close', (code) => {
assert.equal(code, 1000)
server.close()
resolve()
})
})
})

t.teardown(server.close.bind(server))

const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.addEventListener('open', () => ws.close(1000))
const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.addEventListener('open', () => ws.close(1000))
})
})

t.test('Close with code and reason', (t) => {
t.plan(2)

const server = new WebSocketServer({ port: 0 })

server.on('connection', (ws) => {
ws.on('close', (code, reason) => {
t.equal(code, 1000)
t.same(reason, Buffer.from('Goodbye'))
test('Close with code and reason', () => {
return new Promise((resolve) => {
const server = new WebSocketServer({ port: 0 })

server.on('connection', (ws) => {
ws.on('close', (code, reason) => {
assert.equal(code, 1000)
assert.deepStrictEqual(reason, Buffer.from('Goodbye'))
server.close()
resolve()
})
})
})

t.teardown(server.close.bind(server))

const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.addEventListener('open', () => ws.close(1000, 'Goodbye'))
const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.addEventListener('open', () => ws.close(1000, 'Goodbye'))
})
})

t.test('Close with invalid code', (t) => {
t.plan(2)

test('Close with invalid code', () => {
const server = new WebSocketServer({ port: 0 })

t.teardown(server.close.bind(server))

const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.addEventListener('open', () => {
t.throws(
() => ws.close(2999),
{
name: 'InvalidAccessError',
constructor: DOMException
}
)

t.throws(
() => ws.close(5000),
{
name: 'InvalidAccessError',
constructor: DOMException
}
)

ws.close()

return new Promise((resolve) => {
ws.addEventListener('open', () => {
assert.throws(
() => ws.close(2999),
{
name: 'InvalidAccessError',
constructor: DOMException
}
)

assert.throws(
() => ws.close(5000),
{
name: 'InvalidAccessError',
constructor: DOMException
}
)

ws.close()
server.close()
resolve()
})
})
})

t.test('Close with invalid reason', (t) => {
t.plan(1)

test('Close with invalid reason', () => {
const server = new WebSocketServer({ port: 0 })

t.teardown(server.close.bind(server))
const ws = new WebSocket(`ws://localhost:${server.address().port}`)

ws.addEventListener('open', () => {
t.throws(
() => ws.close(1000, 'a'.repeat(124)),
{
name: 'SyntaxError',
constructor: DOMException
}
)

ws.close(1000)
return new Promise((resolve) => {
ws.addEventListener('open', () => {
assert.throws(
() => ws.close(1000, 'a'.repeat(124)),
{
name: 'SyntaxError',
constructor: DOMException
}
)

ws.close(1000)
server.close()
resolve()
})
})
})

t.test('Close with no code or reason', (t) => {
t.plan(2)

test('Close with no code or reason', () => {
const server = new WebSocketServer({ port: 0 })

server.on('connection', (ws) => {
ws.on('close', (code, reason) => {
t.equal(code, 1005)
t.same(reason, Buffer.alloc(0))
return new Promise((resolve) => {
server.on('connection', (ws) => {
ws.on('close', (code, reason) => {
assert.equal(code, 1005)
assert.deepStrictEqual(reason, Buffer.alloc(0))
server.close()
resolve()
})
})
})

t.teardown(server.close.bind(server))

const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.addEventListener('open', () => ws.close())
const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.addEventListener('open', () => ws.close())
})
})

t.test('Close with a 3000 status code', (t) => {
t.plan(2)

test('Close with a 3000 status code', () => {
const server = new WebSocketServer({ port: 0 })

server.on('connection', (ws) => {
ws.on('close', (code, reason) => {
t.equal(code, 3000)
t.same(reason, Buffer.alloc(0))
return new Promise((resolve) => {
server.on('connection', (ws) => {
ws.on('close', (code, reason) => {
assert.equal(code, 3000)
assert.deepStrictEqual(reason, Buffer.alloc(0))
server.close()
resolve()
})
})
})

t.teardown(server.close.bind(server))

const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.addEventListener('open', () => ws.close(3000))
const ws = new WebSocket(`ws://localhost:${server.address().port}`)
ws.addEventListener('open', () => ws.close(3000))
})
})
})
17 changes: 8 additions & 9 deletions test/websocket/constructor.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,47 @@
'use strict'

const { test } = require('tap')
const { test } = require('node:test')
const assert = require('node:assert')
const { WebSocket } = require('../..')

test('Constructor', (t) => {
t.throws(
test('Constructor', () => {
assert.throws(
() => new WebSocket('abc'),
{
name: 'SyntaxError',
constructor: DOMException
}
)

t.throws(
assert.throws(
() => new WebSocket('wss://echo.websocket.events/#a'),
{
name: 'SyntaxError',
constructor: DOMException
}
)

t.throws(
assert.throws(
() => new WebSocket('wss://echo.websocket.events', ''),
{
name: 'SyntaxError',
constructor: DOMException
}
)

t.throws(
assert.throws(
() => new WebSocket('wss://echo.websocket.events', ['chat', 'chat']),
{
name: 'SyntaxError',
constructor: DOMException
}
)

t.throws(
assert.throws(
() => new WebSocket('wss://echo.websocket.events', ['<>@,;:\\"/[]?={}\t']),
{
name: 'SyntaxError',
constructor: DOMException
}
)

t.end()
})
30 changes: 15 additions & 15 deletions test/websocket/custom-headers.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
'use strict'

const { test } = require('tap')
const { test } = require('node:test')
const assert = require('assert')
const { Agent, WebSocket } = require('../..')

test('Setting custom headers', (t) => {
t.plan(1)

const headers = {
'x-khafra-hello': 'hi',
Authorization: 'Bearer base64orsomethingitreallydoesntmatter'
}

class TestAgent extends Agent {
dispatch (options) {
t.match(options.headers, headers)

return false
return new Promise((resolve, reject) => {
class TestAgent extends Agent {
dispatch (options) {
assert.deepStrictEqual(options.headers['x-khafra-hello'], headers['x-khafra-hello'])
assert.deepStrictEqual(options.headers.Authorization, headers.Authorization)
resolve()
return false
}
}
}

const ws = new WebSocket('wss://echo.websocket.events', {
headers,
dispatcher: new TestAgent()
})
const ws = new WebSocket('wss://echo.websocket.events', {
headers,
dispatcher: new TestAgent()
})

// We don't want to make a request, just ensure the headers are set.
ws.onclose = ws.onerror = ws.onmessage = assert.fail
ws.onclose = ws.onerror = ws.onmessage = reject
})
})