vite-entry.e2e.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /** Bare Vite must fail before it can present a bootless shell as a working GUI. */
  2. import { fileURLToPath, pathToFileURL } from 'node:url'
  3. import { join } from 'node:path'
  4. import { existsSync, mkdtempSync, rmSync } from 'node:fs'
  5. import { tmpdir } from 'node:os'
  6. import { createServer } from 'node:net'
  7. import { execa } from 'execa'
  8. import { describe, expect, it } from 'vitest'
  9. const WEB_ROOT = fileURLToPath(new URL('..', import.meta.url))
  10. /** Reserve an available loopback port, then release it for the child invocation. */
  11. async function freePort(): Promise<number> {
  12. const server = createServer()
  13. await new Promise<void>((resolve, reject) => {
  14. server.once('error', reject)
  15. server.listen(0, '127.0.0.1', resolve)
  16. })
  17. const address = server.address()
  18. if (address === null || typeof address === 'string') throw new Error('port probe returned no address')
  19. await new Promise<void>((resolve, reject) => server.close((error) => {
  20. if (error === undefined) resolve()
  21. else reject(error)
  22. }))
  23. return address.port
  24. }
  25. describe('Web development entry', () => {
  26. it('rejects the package dev alias with the full-host correction', async () => {
  27. const result = await execa('pnpm', ['run', 'dev'], { cwd: WEB_ROOT, reject: false })
  28. expect(result.exitCode).not.toBe(0)
  29. expect(result.stderr).toContain('apps/web is not a standalone application')
  30. expect(result.stderr).toContain('dsh web')
  31. })
  32. it('rejects the standalone Vite server with the full-host correction', async () => {
  33. const probeRoot = mkdtempSync(join(tmpdir(), 'dsh-vite-listen-probe-'))
  34. const marker = join(probeRoot, 'listen-called')
  35. const port = await freePort()
  36. try {
  37. const probeModule = fileURLToPath(new URL('./support/listen-probe.mjs', import.meta.url))
  38. const result = await execa(join(WEB_ROOT, 'node_modules/.bin/vite'), ['--host', '127.0.0.1', '--port', String(port)], {
  39. cwd: WEB_ROOT,
  40. reject: false,
  41. timeout: 10_000,
  42. env: {
  43. ...process.env,
  44. DSH_LISTEN_PROBE_MARKER: marker,
  45. NODE_OPTIONS: `${process.env.NODE_OPTIONS ?? ''} --import ${pathToFileURL(probeModule).href}`.trim(),
  46. },
  47. })
  48. expect(result.timedOut).toBe(false)
  49. expect(result.exitCode).not.toBe(0)
  50. expect(result.stderr).toContain('apps/web is not a standalone application')
  51. expect(result.stderr).toContain('dsh web')
  52. expect(result.stderr).toContain('window.__DSH_BOOT__')
  53. expect(existsSync(marker), 'Vite called Server.listen before rejecting standalone serve mode').toBe(false)
  54. } finally {
  55. rmSync(probeRoot, { recursive: true, force: true })
  56. }
  57. })
  58. })