prerender.test.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. import * as assert from 'node:assert/strict';
  2. import { describe, it, before, after } from 'node:test';
  3. import nodejs from '../dist/index.js';
  4. import { loadFixture, waitServerListen } from './test-utils.js';
  5. import * as cheerio from 'cheerio';
  6. /**
  7. * @typedef {import('../../../astro/test/test-utils').Fixture} Fixture
  8. */
  9. async function load() {
  10. const mod = await import(`./fixtures/prerender/dist/server/entry.mjs?dropcache=${Date.now()}`);
  11. return mod;
  12. }
  13. describe('Prerendering', () => {
  14. /** @type {import('./test-utils').Fixture} */
  15. let fixture;
  16. let server;
  17. describe('With base', async () => {
  18. before(async () => {
  19. process.env.PRERENDER = true;
  20. fixture = await loadFixture({
  21. base: '/some-base',
  22. root: './fixtures/prerender/',
  23. output: 'server',
  24. adapter: nodejs({ mode: 'standalone' }),
  25. });
  26. await fixture.build();
  27. const { startServer } = await load();
  28. let res = startServer();
  29. server = res.server;
  30. await waitServerListen(server.server);
  31. });
  32. after(async () => {
  33. await server.stop();
  34. await fixture.clean();
  35. delete process.env.PRERENDER;
  36. });
  37. it('Can render SSR route', async () => {
  38. const res = await fetch(`http://${server.host}:${server.port}/some-base/one`);
  39. const html = await res.text();
  40. const $ = cheerio.load(html);
  41. assert.equal(res.status, 200);
  42. assert.equal($('h1').text(), 'One');
  43. });
  44. it('Can render prerendered route', async () => {
  45. const res = await fetch(`http://${server.host}:${server.port}/some-base/two`);
  46. const html = await res.text();
  47. const $ = cheerio.load(html);
  48. assert.equal(res.status, 200);
  49. assert.equal($('h1').text(), 'Two');
  50. });
  51. it('Can render prerendered route with redirect and query params', async () => {
  52. const res = await fetch(`http://${server.host}:${server.port}/some-base/two?foo=bar`);
  53. const html = await res.text();
  54. const $ = cheerio.load(html);
  55. assert.equal(res.status, 200);
  56. assert.equal($('h1').text(), 'Two');
  57. });
  58. it('Can render prerendered route with query params', async () => {
  59. const res = await fetch(`http://${server.host}:${server.port}/some-base/two/?foo=bar`);
  60. const html = await res.text();
  61. const $ = cheerio.load(html);
  62. assert.equal(res.status, 200);
  63. assert.equal($('h1').text(), 'Two');
  64. });
  65. it('Can render prerendered route without trailing slash', async () => {
  66. const res = await fetch(`http://${server.host}:${server.port}/some-base/two`, {
  67. redirect: 'manual',
  68. });
  69. const html = await res.text();
  70. const $ = cheerio.load(html);
  71. assert.equal(res.status, 200);
  72. assert.equal($('h1').text(), 'Two');
  73. });
  74. });
  75. describe('Without base', async () => {
  76. before(async () => {
  77. process.env.PRERENDER = true;
  78. fixture = await loadFixture({
  79. root: './fixtures/prerender/',
  80. output: 'server',
  81. adapter: nodejs({ mode: 'standalone' }),
  82. });
  83. await fixture.build();
  84. const { startServer } = await await load();
  85. let res = startServer();
  86. server = res.server;
  87. await waitServerListen(server.server);
  88. });
  89. after(async () => {
  90. await server.stop();
  91. await fixture.clean();
  92. delete process.env.PRERENDER;
  93. });
  94. it('Can render SSR route', async () => {
  95. const res = await fetch(`http://${server.host}:${server.port}/one`);
  96. const html = await res.text();
  97. const $ = cheerio.load(html);
  98. assert.equal(res.status, 200);
  99. assert.equal($('h1').text(), 'One');
  100. });
  101. it('Can render prerendered route', async () => {
  102. const res = await fetch(`http://${server.host}:${server.port}/two`);
  103. const html = await res.text();
  104. const $ = cheerio.load(html);
  105. assert.equal(res.status, 200);
  106. assert.equal($('h1').text(), 'Two');
  107. });
  108. it('Can render prerendered route with redirect and query params', async () => {
  109. const res = await fetch(`http://${server.host}:${server.port}/two?foo=bar`);
  110. const html = await res.text();
  111. const $ = cheerio.load(html);
  112. assert.equal(res.status, 200);
  113. assert.equal($('h1').text(), 'Two');
  114. });
  115. it('Can render prerendered route with query params', async () => {
  116. const res = await fetch(`http://${server.host}:${server.port}/two/?foo=bar`);
  117. const html = await res.text();
  118. const $ = cheerio.load(html);
  119. assert.equal(res.status, 200);
  120. assert.equal($('h1').text(), 'Two');
  121. });
  122. });
  123. describe('Dev', () => {
  124. let devServer;
  125. before(async () => {
  126. process.env.PRERENDER = true;
  127. fixture = await loadFixture({
  128. root: './fixtures/prerender/',
  129. output: 'server',
  130. adapter: nodejs({ mode: 'standalone' }),
  131. });
  132. devServer = await fixture.startDevServer();
  133. });
  134. after(async () => {
  135. await devServer.stop();
  136. delete process.env.PRERENDER;
  137. });
  138. it('Can render SSR route', async () => {
  139. const res = await fixture.fetch(`/one`);
  140. const html = await res.text();
  141. const $ = cheerio.load(html);
  142. assert.equal(res.status, 200);
  143. assert.equal($('h1').text(), 'One');
  144. });
  145. it('Can render prerendered route', async () => {
  146. const res = await fixture.fetch(`/two`);
  147. const html = await res.text();
  148. const $ = cheerio.load(html);
  149. assert.equal(res.status, 200);
  150. assert.equal($('h1').text(), 'Two');
  151. });
  152. });
  153. });
  154. describe('Hybrid rendering', () => {
  155. /** @type {import('./test-utils').Fixture} */
  156. let fixture;
  157. let server;
  158. describe('With base', () => {
  159. before(async () => {
  160. process.env.PRERENDER = false;
  161. fixture = await loadFixture({
  162. base: '/some-base',
  163. root: './fixtures/prerender/',
  164. output: 'hybrid',
  165. adapter: nodejs({ mode: 'standalone' }),
  166. });
  167. await fixture.build();
  168. const { startServer } = await load();
  169. let res = startServer();
  170. server = res.server;
  171. await waitServerListen(server.server);
  172. });
  173. after(async () => {
  174. await server.stop();
  175. await fixture.clean();
  176. delete process.env.PRERENDER;
  177. });
  178. it('Can render SSR route', async () => {
  179. const res = await fetch(`http://${server.host}:${server.port}/some-base/two`);
  180. const html = await res.text();
  181. const $ = cheerio.load(html);
  182. assert.equal(res.status, 200);
  183. assert.equal($('h1').text(), 'Two');
  184. });
  185. it('Can render prerendered route', async () => {
  186. const res = await fetch(`http://${server.host}:${server.port}/some-base/one`);
  187. const html = await res.text();
  188. const $ = cheerio.load(html);
  189. assert.equal(res.status, 200);
  190. assert.equal($('h1').text(), 'One');
  191. });
  192. it('Can render prerendered route with redirect and query params', async () => {
  193. const res = await fetch(`http://${server.host}:${server.port}/some-base/one?foo=bar`);
  194. const html = await res.text();
  195. const $ = cheerio.load(html);
  196. assert.equal(res.status, 200);
  197. assert.equal($('h1').text(), 'One');
  198. });
  199. it('Can render prerendered route with query params', async () => {
  200. const res = await fetch(`http://${server.host}:${server.port}/some-base/one/?foo=bar`);
  201. const html = await res.text();
  202. const $ = cheerio.load(html);
  203. assert.equal(res.status, 200);
  204. assert.equal($('h1').text(), 'One');
  205. });
  206. it('Can render prerendered route without trailing slash', async () => {
  207. const res = await fetch(`http://${server.host}:${server.port}/some-base/one`, {
  208. redirect: 'manual',
  209. });
  210. const html = await res.text();
  211. const $ = cheerio.load(html);
  212. assert.equal(res.status, 200);
  213. assert.equal($('h1').text(), 'One');
  214. });
  215. });
  216. describe('Without base', () => {
  217. before(async () => {
  218. process.env.PRERENDER = false;
  219. fixture = await loadFixture({
  220. root: './fixtures/prerender/',
  221. output: 'hybrid',
  222. adapter: nodejs({ mode: 'standalone' }),
  223. });
  224. await fixture.build();
  225. const { startServer } = await load();
  226. let res = startServer();
  227. server = res.server;
  228. await waitServerListen(server.server);
  229. });
  230. after(async () => {
  231. await server.stop();
  232. await fixture.clean();
  233. delete process.env.PRERENDER;
  234. });
  235. it('Can render SSR route', async () => {
  236. const res = await fetch(`http://${server.host}:${server.port}/two`);
  237. const html = await res.text();
  238. const $ = cheerio.load(html);
  239. assert.equal(res.status, 200);
  240. assert.equal($('h1').text(), 'Two');
  241. });
  242. it('Can render prerendered route', async () => {
  243. const res = await fetch(`http://${server.host}:${server.port}/one`);
  244. const html = await res.text();
  245. const $ = cheerio.load(html);
  246. assert.equal(res.status, 200);
  247. assert.equal($('h1').text(), 'One');
  248. });
  249. it('Can render prerendered route with redirect and query params', async () => {
  250. const res = await fetch(`http://${server.host}:${server.port}/one?foo=bar`);
  251. const html = await res.text();
  252. const $ = cheerio.load(html);
  253. assert.equal(res.status, 200);
  254. assert.equal($('h1').text(), 'One');
  255. });
  256. it('Can render prerendered route with query params', async () => {
  257. const res = await fetch(`http://${server.host}:${server.port}/one/?foo=bar`);
  258. const html = await res.text();
  259. const $ = cheerio.load(html);
  260. assert.equal(res.status, 200);
  261. assert.equal($('h1').text(), 'One');
  262. });
  263. });
  264. describe('Shared modules', () => {
  265. before(async () => {
  266. process.env.PRERENDER = false;
  267. fixture = await loadFixture({
  268. root: './fixtures/prerender/',
  269. output: 'hybrid',
  270. adapter: nodejs({ mode: 'standalone' }),
  271. });
  272. await fixture.build();
  273. const { startServer } = await load();
  274. let res = startServer();
  275. server = res.server;
  276. });
  277. after(async () => {
  278. await server.stop();
  279. await fixture.clean();
  280. delete process.env.PRERENDER;
  281. });
  282. it('Can render SSR route', async () => {
  283. const res = await fetch(`http://${server.host}:${server.port}/third`);
  284. const html = await res.text();
  285. const $ = cheerio.load(html);
  286. assert.equal(res.status, 200);
  287. assert.equal($('h1').text(), 'shared');
  288. });
  289. });
  290. });