diff --git a/.changeset/seven-bottles-warn.md b/.changeset/seven-bottles-warn.md new file mode 100644 index 0000000000..653618200d --- /dev/null +++ b/.changeset/seven-bottles-warn.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes dev server not stopping cleanly diff --git a/packages/astro/src/core/dev/index.ts b/packages/astro/src/core/dev/index.ts index 56808fd784..a7856bf332 100644 --- a/packages/astro/src/core/dev/index.ts +++ b/packages/astro/src/core/dev/index.ts @@ -26,7 +26,7 @@ export interface DevOptions { logging: LogOptions; } -interface DevServer { +export interface DevServer { hostname: string; port: number; server: connect.Server; @@ -96,7 +96,7 @@ export class AstroDevServer { await this.viteServer.close(); } if (this.httpServer) { - await promisify(this.httpServer.close)(); + await promisify(this.httpServer.close.bind(this.httpServer))(); } } diff --git a/packages/astro/test/astro-styles-ssr.test.js b/packages/astro/test/astro-styles-ssr.test.js index 168cded3e0..ad9e0b7ee9 100644 --- a/packages/astro/test/astro-styles-ssr.test.js +++ b/packages/astro/test/astro-styles-ssr.test.js @@ -3,7 +3,7 @@ import cheerio from 'cheerio'; import { loadFixture } from './test-utils.js'; describe('Styles SSR', function () { - this.timeout(5000); + this.timeout(10000); let fixture; let index$; diff --git a/packages/astro/test/dev-routing.test.js b/packages/astro/test/dev-routing.test.js new file mode 100644 index 0000000000..0a96aefdb4 --- /dev/null +++ b/packages/astro/test/dev-routing.test.js @@ -0,0 +1,129 @@ +import { expect } from 'chai'; +import cheerio from 'cheerio'; +import { loadFixture } from './test-utils.js'; + +describe('Development Routing', () => { + describe('No site config', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture + /** @type {import('./test-utils').DevServer} */ + let devServer; + + before(async () => { + fixture = await loadFixture({ projectRoot: './fixtures/without-site-config/' }); + devServer = await fixture.startDevServer(); + }); + + after(async () => { + devServer && await devServer.stop(); + }); + + it('200 when loading /', async () => { + const response = await fixture.fetch('/'); + expect(response.status).to.equal(200); + }); + + it('200 when loading non-root page', async () => { + const response = await fixture.fetch('/another'); + expect(response.status).to.equal(200); + }) + }); + + describe('No subpath used', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture + /** @type {import('./test-utils').DevServer} */ + let devServer; + + before(async () => { + fixture = await loadFixture({ projectRoot: './fixtures/without-subpath/' }); + devServer = await fixture.startDevServer(); + }); + + after(async () => { + devServer && await devServer.stop(); + }); + + it('200 when loading /', async () => { + const response = await fixture.fetch('/'); + expect(response.status).to.equal(200); + }); + + it('200 when loading non-root page', async () => { + const response = await fixture.fetch('/another'); + expect(response.status).to.equal(200); + }) + }); + + describe('Subpath with trailing slash', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture + /** @type {import('./test-utils').DevServer} */ + let devServer; + + before(async () => { + fixture = await loadFixture({ projectRoot: './fixtures/with-subpath-trailing-slash/' }); + devServer = await fixture.startDevServer(); + }); + + after(async () => { + devServer && await devServer.stop(); + }); + + it('404 when loading /', async () => { + const response = await fixture.fetch('/'); + expect(response.status).to.equal(404); + }); + + it('200 when loading subpath root', async () => { + const response = await fixture.fetch('/blog/'); + expect(response.status).to.equal(200); + }); + + it('404 when loading subpath root without trailing slash', async () => { + const response = await fixture.fetch('/blog'); + expect(response.status).to.equal(404); + }); + + it('200 when loading another page with subpath used', async () => { + const response = await fixture.fetch('/blog/another/'); + expect(response.status).to.equal(200); + }); + }); + + describe('Subpath without trailing slash', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture + /** @type {import('./test-utils').DevServer} */ + let devServer; + + before(async () => { + fixture = await loadFixture({ projectRoot: './fixtures/with-subpath-no-trailing-slash/' }); + devServer = await fixture.startDevServer(); + }); + + after(async () => { + devServer && await devServer.stop(); + }); + + it('404 when loading /', async () => { + const response = await fixture.fetch('/'); + expect(response.status).to.equal(404); + }); + + it('200 when loading subpath root with trailing slash', async () => { + const response = await fixture.fetch('/blog/'); + expect(response.status).to.equal(200); + }); + + it('200 when loading subpath root without trailing slash', async () => { + const response = await fixture.fetch('/blog'); + expect(response.status).to.equal(200); + }); + + it('200 when loading another page with subpath used', async () => { + const response = await fixture.fetch('/blog/another/'); + expect(response.status).to.equal(200); + }); + }); +}); \ No newline at end of file diff --git a/packages/astro/test/fixtures/with-subpath-no-trailing-slash/astro.config.mjs b/packages/astro/test/fixtures/with-subpath-no-trailing-slash/astro.config.mjs new file mode 100644 index 0000000000..616285e2b4 --- /dev/null +++ b/packages/astro/test/fixtures/with-subpath-no-trailing-slash/astro.config.mjs @@ -0,0 +1,6 @@ + +export default { + buildOptions: { + site: 'http://example.com/blog' + } +} \ No newline at end of file diff --git a/packages/astro/test/fixtures/with-subpath-no-trailing-slash/src/pages/another.astro b/packages/astro/test/fixtures/with-subpath-no-trailing-slash/src/pages/another.astro new file mode 100644 index 0000000000..d0563f4145 --- /dev/null +++ b/packages/astro/test/fixtures/with-subpath-no-trailing-slash/src/pages/another.astro @@ -0,0 +1 @@ +