diff --git a/package.json b/package.json index 27fac9f..a37f51d 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,6 @@ "simple-git-hooks": "^2.13.1", "sockjs-client": "^1.6.1", "style-loader": "^4.0.0", - "supertest": "^6.3.4", "typescript": "^5.9.3", "wait-for-expect": "^3.0.2", "webpack": "^5.105.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a6475a3..d1ee8d5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -147,9 +147,6 @@ importers: style-loader: specifier: ^4.0.0 version: 4.0.0(webpack@5.105.3) - supertest: - specifier: ^6.3.4 - version: 6.3.4 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -804,9 +801,6 @@ packages: array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -815,9 +809,6 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - b4a@1.6.6: resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==} @@ -963,16 +954,9 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - component-emitter@1.3.1: - resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} - compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} @@ -1004,9 +988,6 @@ packages: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} - cookiejar@2.1.4: - resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} - core-js@3.47.0: resolution: {integrity: sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==} @@ -1097,10 +1078,6 @@ packages: resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} engines: {node: '>= 14'} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - depd@1.1.2: resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} engines: {node: '>= 0.6'} @@ -1119,9 +1096,6 @@ packages: devtools-protocol@0.0.1566079: resolution: {integrity: sha512-MJfAEA1UfVhSs7fbSQOG4czavUp1ajfg6prlAN0+cmfa2zNjaIbvq8VneP7do1WAQQIvgNJWSMeP6UyI90gIlQ==} - dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} - dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -1257,9 +1231,6 @@ packages: fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} @@ -1295,14 +1266,6 @@ packages: debug: optional: true - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - - formidable@2.1.2: - resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} - deprecated: 'ACTION REQUIRED: SWITCH TO v3 - v1 and v2 are VULNERABLE! v1 is DEPRECATED FOR OVER 2 YEARS! Use formidable@latest or try formidable-mini for fresh projects' - forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -1400,10 +1363,6 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - hexoid@1.0.0: - resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} - engines: {node: '>=8'} - hono@4.12.3: resolution: {integrity: sha512-SFsVSjp8sj5UumXOOFlkZOG6XS9SJDKw0TbwFeV+AJ8xlST8kxK5Z/5EYa111UY8732lK2S/xB653ceuaoGwpg==} engines: {node: '>=16.9.0'} @@ -1638,11 +1597,6 @@ packages: engines: {node: '>=4'} hasBin: true - mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} @@ -2062,16 +2016,6 @@ packages: peerDependencies: webpack: ^5.27.0 - superagent@8.1.2: - resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} - engines: {node: '>=6.4.0 <13 || >=14'} - deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net - - supertest@6.3.4: - resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==} - engines: {node: '>=6.4.0'} - deprecated: Please upgrade to supertest v7.1.3+, see release notes at https://github.com/forwardemail/supertest/releases/tag/v7.1.3 - maintenance is supported by Forward Email @ https://forwardemail.net - supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -2933,16 +2877,12 @@ snapshots: array-flatten@1.1.1: {} - asap@2.0.6: {} - assertion-error@2.0.1: {} ast-types@0.13.4: dependencies: tslib: 2.8.1 - asynckit@0.4.0: {} - b4a@1.6.6: {} bare-events@2.8.2: {} @@ -3101,14 +3041,8 @@ snapshots: colorette@2.0.20: {} - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - commander@2.20.3: {} - component-emitter@1.3.1: {} - compressible@2.0.18: dependencies: mime-db: 1.54.0 @@ -3146,8 +3080,6 @@ snapshots: cookie@0.7.1: {} - cookiejar@2.1.4: {} - core-js@3.47.0: {} core-util-is@1.0.3: {} @@ -3222,8 +3154,6 @@ snapshots: escodegen: 2.1.0 esprima: 4.0.1 - delayed-stream@1.0.0: {} - depd@1.1.2: {} depd@2.0.0: {} @@ -3234,11 +3164,6 @@ snapshots: devtools-protocol@0.0.1566079: {} - dezalgo@1.0.4: - dependencies: - asap: 2.0.6 - wrappy: 1.0.2 - dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -3385,8 +3310,6 @@ snapshots: fast-fifo@1.3.2: {} - fast-safe-stringify@2.1.1: {} - fast-uri@3.1.0: {} faye-websocket@0.11.4: @@ -3429,19 +3352,6 @@ snapshots: follow-redirects@1.15.9: {} - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - formidable@2.1.2: - dependencies: - dezalgo: 1.0.4 - hexoid: 1.0.0 - once: 1.4.0 - qs: 6.14.1 - forwarded@0.2.0: {} fresh@0.5.2: {} @@ -3536,8 +3446,6 @@ snapshots: dependencies: function-bind: 1.1.2 - hexoid@1.0.0: {} - hono@4.12.3: {} hpack.js@2.1.6: @@ -3762,8 +3670,6 @@ snapshots: mime@1.6.0: {} - mime@2.6.0: {} - minimalistic-assert@1.0.1: {} mitt@3.0.1: {} @@ -4248,28 +4154,6 @@ snapshots: dependencies: webpack: 5.105.3 - superagent@8.1.2: - dependencies: - component-emitter: 1.3.1 - cookiejar: 2.1.4 - debug: 4.4.3 - fast-safe-stringify: 2.1.1 - form-data: 4.0.0 - formidable: 2.1.2 - methods: 1.1.2 - mime: 2.6.0 - qs: 6.14.1 - semver: 7.7.3 - transitivePeerDependencies: - - supports-color - - supertest@6.3.4: - dependencies: - methods: 1.1.2 - superagent: 8.1.2 - transitivePeerDependencies: - - supports-color - supports-color@5.5.0: dependencies: has-flag: 3.0.0 diff --git a/tests/e2e/headers.test.js b/tests/e2e/headers.test.js index 462d9eb..e2a3a46 100644 --- a/tests/e2e/headers.test.js +++ b/tests/e2e/headers.test.js @@ -1,8 +1,8 @@ -const request = require('supertest'); const { rspack } = require('@rspack/core'); const { RspackDevServer: Server } = require('@rspack/dev-server'); const config = require('../fixtures/simple-config/webpack.config'); const runBrowser = require('../helpers/run-browser'); +const request = require('../helpers/http-request'); const port = require('../helpers/ports-map')['headers-option']; describe('headers option', () => { @@ -398,8 +398,6 @@ describe('headers option', () => { let browser; let pageErrors; let consoleMessages; - let req; - beforeEach(async () => { compiler = rspack(config); @@ -413,8 +411,6 @@ describe('headers option', () => { await server.start(); - req = request(server.app); - ({ page, browser } = await runBrowser()); pageErrors = []; @@ -448,7 +444,11 @@ describe('headers option', () => { ); expect(pageErrors).toMatchSnapshot('page errors'); - const responseForHead = await req.get('/'); + const responseForHead = await request({ + port, + path: '/', + method: 'HEAD', + }); expect(responseForHead.headers['x-foo']).toBe('dev-server headers'); }); diff --git a/tests/e2e/range-header.test.js b/tests/e2e/range-header.test.js index 66c7ff2..b18b393 100644 --- a/tests/e2e/range-header.test.js +++ b/tests/e2e/range-header.test.js @@ -1,7 +1,7 @@ -const request = require('supertest'); const { rspack } = require('@rspack/core'); const { RspackDevServer: Server } = require('@rspack/dev-server'); const config = require('../fixtures/static-config/webpack.config'); +const request = require('../helpers/http-request'); const port = require('../helpers/ports-map')['range-header']; const JAVASCRIPT_CONTENT_TYPE_RE = /^(application|text)\/javascript; charset=utf-8$/; @@ -23,7 +23,7 @@ describe("'Range' header", () => { }); it('should work with "Range" header using "GET" method', async () => { - const response = await request(server.app).get('/main.js'); + const response = await request({ port, path: '/main.js' }); expect(response.status).toBe(200); expect(response.headers['content-type']).toMatch( @@ -32,9 +32,13 @@ describe("'Range' header", () => { expect(response.headers['accept-ranges']).toBe('bytes'); const responseContent = response.text; - const responseRange = await request(server.app) - .get('/main.js') - .set('Range', 'bytes=0-499'); + const responseRange = await request({ + port, + path: '/main.js', + headers: { + Range: 'bytes=0-499', + }, + }); expect(responseRange.status).toBe(206); expect(responseRange.headers['content-type']).toMatch( @@ -47,7 +51,11 @@ describe("'Range' header", () => { }); it('should work with "Range" header using "HEAD" method', async () => { - const response = await request(server.app).head('/main.js'); + const response = await request({ + port, + path: '/main.js', + method: 'HEAD', + }); expect(response.status).toBe(200); expect(response.headers['content-type']).toMatch( @@ -55,9 +63,14 @@ describe("'Range' header", () => { ); expect(response.headers['accept-ranges']).toBe('bytes'); - const responseRange = await request(server.app) - .head('/main.js') - .set('Range', 'bytes=0-499'); + const responseRange = await request({ + port, + path: '/main.js', + method: 'HEAD', + headers: { + Range: 'bytes=0-499', + }, + }); expect(responseRange.status).toBe(206); expect(responseRange.headers['content-type']).toMatch( @@ -68,7 +81,7 @@ describe("'Range' header", () => { }); it('should work with unsatisfiable "Range" header using "GET" method', async () => { - const response = await request(server.app).get('/main.js'); + const response = await request({ port, path: '/main.js' }); expect(response.status).toBe(200); expect(response.headers['content-type']).toMatch( @@ -76,9 +89,13 @@ describe("'Range' header", () => { ); expect(response.headers['accept-ranges']).toBe('bytes'); - const responseRange = await request(server.app) - .get('/main.js') - .set('Range', 'bytes=99999999999-'); + const responseRange = await request({ + port, + path: '/main.js', + headers: { + Range: 'bytes=99999999999-', + }, + }); expect(responseRange.status).toBe(416); expect(responseRange.headers['content-type']).toBe( @@ -88,7 +105,7 @@ describe("'Range' header", () => { }); it('should work with malformed "Range" header using "GET" method', async () => { - const response = await request(server.app).get('/main.js'); + const response = await request({ port, path: '/main.js' }); expect(response.status).toBe(200); expect(response.headers['content-type']).toMatch( @@ -97,9 +114,13 @@ describe("'Range' header", () => { expect(response.headers['accept-ranges']).toBe('bytes'); const responseContent = response.text; - const responseRange = await request(server.app) - .get('/main.js') - .set('Range', 'bytes'); + const responseRange = await request({ + port, + path: '/main.js', + headers: { + Range: 'bytes', + }, + }); expect(responseRange.status).toBe(200); expect(responseRange.headers['content-type']).toMatch( diff --git a/tests/e2e/server.test.js b/tests/e2e/server.test.js index f9f8a9b..3834021 100644 --- a/tests/e2e/server.test.js +++ b/tests/e2e/server.test.js @@ -1,7 +1,6 @@ const https = require('node:https'); const path = require('node:path'); const fs = require('node:fs'); -const request = require('supertest'); const spdy = require('spdy'); const { rspack } = require('@rspack/core'); const { RspackDevServer: Server } = require('@rspack/dev-server'); @@ -9,6 +8,7 @@ const config = require('../fixtures/static-config/webpack.config'); const runBrowser = require('../helpers/run-browser'); const { skipTestOnWindows } = require('../helpers/conditional-test'); const customHTTP = require('../helpers/custom-http'); +const request = require('../helpers/http-request'); const normalizeOptions = require('../helpers/normalize-options'); const port = require('../helpers/ports-map')['server-option']; @@ -1215,12 +1215,11 @@ describe('server option', () => { }); }); - // puppeteer having issues accepting SSL here, throwing error net::ERR_BAD_SSL_CLIENT_AUTH_CERT, hence testing with supertest + // puppeteer has issues accepting SSL here, throwing net::ERR_BAD_SSL_CLIENT_AUTH_CERT describe('should support the "requestCert" option', () => { let compiler; let server; let createServerSpy; - let req; beforeEach(async () => { compiler = rspack(config); @@ -1255,8 +1254,6 @@ describe('server option', () => { ); await server.start(); - - req = request(server.app); }); afterEach(async () => { @@ -1272,7 +1269,10 @@ describe('server option', () => { }); it('should handle GET request to index route (/)', async () => { - const response = await req.get('/'); + const response = await request({ + app: server.app, + path: '/', + }); expect(response.status).toMatchSnapshot('response status'); expect(response.text).toMatchSnapshot('response text'); diff --git a/tests/helpers/http-request.js b/tests/helpers/http-request.js new file mode 100644 index 0000000..5780dab --- /dev/null +++ b/tests/helpers/http-request.js @@ -0,0 +1,100 @@ +const http = require('node:http'); +const https = require('node:https'); + +function request({ + app, + protocol = 'http:', + hostname = '127.0.0.1', + port, + path = '/', + method = 'GET', + headers, + rejectUnauthorized = true, + transportOptions = {}, +}) { + if (app) { + return requestByApp({ + app, + path, + method, + headers, + }); + } + + const transport = protocol === 'https:' ? https : http; + const requestOptions = { + hostname, + port, + path, + method, + headers, + ...transportOptions, + }; + + if ( + protocol === 'https:' && + typeof requestOptions.rejectUnauthorized === 'undefined' + ) { + requestOptions.rejectUnauthorized = rejectUnauthorized; + } + + return new Promise((resolve, reject) => { + const req = transport.request(requestOptions, (response) => { + const chunks = []; + + response.on('data', (chunk) => { + chunks.push(chunk); + }); + + response.on('end', () => { + const body = Buffer.concat(chunks); + + resolve({ + status: response.statusCode, + headers: response.headers, + body, + text: body.toString('utf-8'), + }); + }); + }); + + req.on('error', reject); + req.end(); + }); +} + +function requestByApp({ app, path, method, headers }) { + return new Promise((resolve, reject) => { + const tempServer = http.createServer(app); + + tempServer.on('error', reject); + + tempServer.listen(0, '127.0.0.1', async () => { + try { + const address = tempServer.address(); + const response = await request({ + hostname: '127.0.0.1', + port: address.port, + path, + method, + headers, + }); + + tempServer.close((error) => { + if (error) { + reject(error); + return; + } + + resolve(response); + }); + } catch (error) { + tempServer.close(() => { + reject(error); + }); + } + }); + }); +} + +module.exports = request;