compile.ts 5.6 KB

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