compile.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import { v4 as uuid } from 'uuid'
  2. const outputFiles = () => {
  3. const build = uuid().slice(0, 13) // first two groups of UUID
  4. return [
  5. {
  6. path: 'output.pdf',
  7. build,
  8. url: `/build/${build}/output.pdf`,
  9. type: 'pdf',
  10. },
  11. {
  12. path: 'output.bbl',
  13. build,
  14. url: `/build/${build}/output.bbl`,
  15. type: 'bbl',
  16. },
  17. {
  18. path: 'output.bib',
  19. build,
  20. url: `/build/${build}/output.bib`,
  21. type: 'bib',
  22. },
  23. {
  24. path: 'example.txt',
  25. build,
  26. url: `/build/${build}/example.txt`,
  27. type: 'txt',
  28. },
  29. {
  30. path: 'output.log',
  31. build,
  32. url: `/build/${build}/output.log`,
  33. type: 'log',
  34. },
  35. {
  36. path: 'output.blg',
  37. build,
  38. url: `/build/${build}/output.blg`,
  39. type: 'blg',
  40. },
  41. ]
  42. }
  43. const compileFromCacheResponse = () => {
  44. return {
  45. fromCache: true,
  46. status: 'success',
  47. clsiServerId: 'foo',
  48. clsiCacheShard: 'clsi-cache-zone-b-shard-1',
  49. compileGroup: 'priority',
  50. pdfDownloadDomain: 'https://clsi.test-overleaf.com',
  51. outputFiles: outputFiles(),
  52. options: {
  53. rootResourcePath: 'main.tex',
  54. imageName: 'texlive-full:2024.1',
  55. compiler: 'pdflatex',
  56. stopOnFirstError: false,
  57. draft: false,
  58. },
  59. }
  60. }
  61. export const interceptCompileFromCacheRequest = ({
  62. times,
  63. promise,
  64. }: {
  65. times: number
  66. promise: Promise<void>
  67. }) => {
  68. return cy.intercept(
  69. { path: '/project/*/output/cached/output.overleaf.json', times },
  70. async req => {
  71. await promise
  72. req.reply({ body: compileFromCacheResponse() })
  73. }
  74. )
  75. }
  76. export const interceptCompileRequest = ({ times = 1 } = {}) => {
  77. return cy.intercept(
  78. { method: 'POST', pathname: '/project/*/compile', times },
  79. {
  80. body: {
  81. status: 'success',
  82. clsiServerId: 'foo',
  83. compileGroup: 'priority',
  84. pdfDownloadDomain: 'https://clsi.test-overleaf.com',
  85. outputFiles: outputFiles(),
  86. },
  87. }
  88. )
  89. }
  90. export const interceptCompile = ({
  91. prefix = 'compile',
  92. times = 1,
  93. cached = false,
  94. regular = true,
  95. outputPDFFixture = 'output.pdf',
  96. } = {}) => {
  97. if (cached) {
  98. cy.intercept(
  99. { path: '/project/*/output/cached/output.overleaf.json', times },
  100. { body: compileFromCacheResponse() }
  101. ).as(`${prefix}-cached`)
  102. } else {
  103. cy.intercept(
  104. { pathname: '/project/*/output/cached/output.overleaf.json', times },
  105. { statusCode: 404 }
  106. ).as(`${prefix}-cached`)
  107. }
  108. if (regular) {
  109. interceptCompileRequest({ times }).as(`${prefix}`)
  110. } else {
  111. cy.intercept(
  112. { method: 'POST', pathname: '/project/*/compile', times },
  113. {
  114. body: {
  115. status: 'unavailable',
  116. clsiServerId: 'foo',
  117. compileGroup: 'priority',
  118. pdfDownloadDomain: 'https://clsi.test-overleaf.com',
  119. outputFiles: [],
  120. },
  121. }
  122. ).as(`${prefix}`)
  123. }
  124. cy.intercept(
  125. { pathname: '/build/*/output.pdf', times },
  126. { fixture: `build/${outputPDFFixture},null` }
  127. ).as(`${prefix}-pdf`)
  128. cy.intercept(
  129. { pathname: '/build/*/output.log', times },
  130. { fixture: 'build/output.log' }
  131. ).as(`${prefix}-log`)
  132. cy.intercept(
  133. { pathname: '/build/*/output.blg', times },
  134. { fixture: 'build/output.blg' }
  135. ).as(`${prefix}-blg`)
  136. }
  137. export const waitForCompile = ({
  138. prefix = 'compile',
  139. pdf = false,
  140. cached = false,
  141. regular = true,
  142. } = {}) => {
  143. if (cached) {
  144. cy.wait(`@${prefix}-cached`)
  145. }
  146. if (regular) {
  147. cy.wait(`@${prefix}`)
  148. }
  149. return waitForCompileOutput({ prefix, pdf, cached })
  150. }
  151. export const waitForCompileOutput = ({
  152. prefix = 'compile',
  153. pdf = false,
  154. cached = false,
  155. } = {}) => {
  156. cy.wait(`@${prefix}-log`)
  157. .its('request.query.clsiserverid')
  158. .should('eq', cached ? 'clsi-cache-zone-b-shard-1' : 'foo') // straight from cache if cached
  159. cy.wait(`@${prefix}-blg`)
  160. .its('request.query.clsiserverid')
  161. .should('eq', cached ? 'clsi-cache-zone-b-shard-1' : 'foo') // straight from cache if cached
  162. if (pdf) {
  163. cy.wait(`@${prefix}-pdf`)
  164. .its('request.query.clsiserverid')
  165. .should('eq', 'foo') // always from VM first
  166. }
  167. return cy.wrap(null)
  168. }
  169. export const interceptDeferredCompile = (beforeResponse?: () => void) => {
  170. const { promise, resolve } = Promise.withResolvers<void>()
  171. cy.intercept(
  172. { method: 'POST', url: '/project/*/compile*', times: 1 },
  173. req => {
  174. if (beforeResponse) {
  175. beforeResponse()
  176. }
  177. // only reply once the Promise is resolved
  178. promise.then(() => {
  179. req.reply({
  180. body: {
  181. status: 'success',
  182. clsiServerId: 'foo',
  183. compileGroup: 'priority',
  184. pdfDownloadDomain: 'https://clsi.test-overleaf.com',
  185. outputFiles: [
  186. {
  187. path: 'output.pdf',
  188. build: '1234-5678',
  189. url: '/build/123/output.pdf',
  190. type: 'pdf',
  191. },
  192. {
  193. path: 'output.log',
  194. build: '1234-5678',
  195. url: '/build/123/output.log',
  196. type: 'log',
  197. },
  198. {
  199. path: 'output.blg',
  200. build: '1234-5678',
  201. url: '/build/123/output.blg',
  202. type: 'log',
  203. },
  204. ],
  205. },
  206. })
  207. })
  208. return promise
  209. }
  210. ).as('compile')
  211. cy.intercept(
  212. { pathname: '/build/*/output.pdf', times: 1 },
  213. { fixture: 'build/output.pdf,null' }
  214. ).as(`compile-pdf`)
  215. cy.intercept(
  216. { pathname: '/build/*/output.log', times: 1 },
  217. { fixture: 'build/output.log' }
  218. ).as(`compile-log`)
  219. cy.intercept(
  220. { pathname: '/build/*/output.blg', times: 1 },
  221. { fixture: 'build/output.blg' }
  222. ).as(`compile-blg`)
  223. return cy.wrap(resolve)
  224. }