mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Improve compile request mocking in Cypress tests (#12095)
GitOrigin-RevId: fdbc53148e5437e451dab4889232923c823d649e
This commit is contained in:
parent
cff49bd9c1
commit
488c6ff919
9 changed files with 378 additions and 248 deletions
|
@ -43,8 +43,10 @@ const outputFiles = () => {
|
|||
]
|
||||
}
|
||||
|
||||
export const interceptCompile = (prefix = 'compile') => {
|
||||
cy.intercept('POST', '/project/*/compile*', {
|
||||
export const interceptCompile = (prefix = 'compile', times = 1) => {
|
||||
cy.intercept(
|
||||
{ method: 'POST', url: '/project/*/compile*', times },
|
||||
{
|
||||
body: {
|
||||
status: 'success',
|
||||
clsiServerId: 'foo',
|
||||
|
@ -52,17 +54,100 @@ export const interceptCompile = (prefix = 'compile') => {
|
|||
pdfDownloadDomain: 'https://clsi.test-overleaf.com',
|
||||
outputFiles: outputFiles(),
|
||||
},
|
||||
}).as(`${prefix}`)
|
||||
|
||||
cy.intercept('/build/*/output.pdf*', {
|
||||
fixture: 'build/output.pdf,null',
|
||||
}).as(`${prefix}-pdf`)
|
||||
|
||||
cy.intercept('/build/*/output.log*', {
|
||||
fixture: 'build/output.log',
|
||||
}).as(`${prefix}-log`)
|
||||
|
||||
cy.intercept('/build/*/output.blg*', {
|
||||
fixture: 'build/output.blg',
|
||||
}).as(`${prefix}-blg`)
|
||||
}
|
||||
).as(`${prefix}`)
|
||||
|
||||
cy.intercept(
|
||||
{ url: '/build/*/output.pdf*', times },
|
||||
{ fixture: 'build/output.pdf,null' }
|
||||
).as(`${prefix}-pdf`)
|
||||
|
||||
cy.intercept(
|
||||
{ url: '/build/*/output.log*', times },
|
||||
{ fixture: 'build/output.log' }
|
||||
).as(`${prefix}-log`)
|
||||
|
||||
cy.intercept(
|
||||
{ url: '/build/*/output.blg*', times },
|
||||
{ fixture: 'build/output.blg' }
|
||||
).as(`${prefix}-blg`)
|
||||
}
|
||||
|
||||
export const waitForCompile = ({ prefix = 'compile', pdf = false } = {}) => {
|
||||
cy.wait(`@${prefix}`)
|
||||
cy.wait(`@${prefix}-log`)
|
||||
cy.wait(`@${prefix}-blg`)
|
||||
if (pdf) {
|
||||
cy.wait(`@${prefix}-pdf`)
|
||||
}
|
||||
return cy.wrap(null)
|
||||
}
|
||||
|
||||
export const interceptDeferredCompile = (beforeResponse?: () => void) => {
|
||||
let resolveDeferredCompile: (value?: unknown) => void
|
||||
|
||||
const promise = new Promise(resolve => {
|
||||
resolveDeferredCompile = resolve
|
||||
})
|
||||
|
||||
cy.intercept(
|
||||
{ method: 'POST', url: '/project/*/compile*', times: 1 },
|
||||
req => {
|
||||
if (beforeResponse) {
|
||||
beforeResponse()
|
||||
}
|
||||
|
||||
// only reply once the Promise is resolved
|
||||
promise.then(() => {
|
||||
req.reply({
|
||||
body: {
|
||||
status: 'success',
|
||||
clsiServerId: 'foo',
|
||||
compileGroup: 'priority',
|
||||
pdfDownloadDomain: 'https://clsi.test-overleaf.com',
|
||||
outputFiles: [
|
||||
{
|
||||
path: 'output.pdf',
|
||||
build: '123',
|
||||
url: '/build/123/output.pdf',
|
||||
type: 'pdf',
|
||||
},
|
||||
{
|
||||
path: 'output.log',
|
||||
build: '123',
|
||||
url: '/build/123/output.log',
|
||||
type: 'log',
|
||||
},
|
||||
{
|
||||
path: 'output.blg',
|
||||
build: '123',
|
||||
url: '/build/123/output.blg',
|
||||
type: 'log',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
return promise
|
||||
}
|
||||
).as('compile')
|
||||
|
||||
cy.intercept(
|
||||
{ url: '/build/*/output.pdf*', times: 1 },
|
||||
{ fixture: 'build/output.pdf,null' }
|
||||
).as(`compile-pdf`)
|
||||
|
||||
cy.intercept(
|
||||
{ url: '/build/*/output.log*', times: 1 },
|
||||
{ fixture: 'build/output.log' }
|
||||
).as(`compile-log`)
|
||||
|
||||
cy.intercept(
|
||||
{ url: '/build/*/output.blg*', times: 1 },
|
||||
{ fixture: 'build/output.blg' }
|
||||
).as(`compile-blg`)
|
||||
|
||||
// @ts-ignore
|
||||
return cy.wrap(resolveDeferredCompile)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import '@testing-library/cypress/add-commands'
|
||||
import { interceptCompile } from './compile'
|
||||
import {
|
||||
interceptCompile,
|
||||
waitForCompile,
|
||||
interceptDeferredCompile,
|
||||
} from './compile'
|
||||
import { interceptEvents } from './events'
|
||||
import { interceptSpelling } from './spelling'
|
||||
|
||||
|
@ -12,6 +16,8 @@ declare global {
|
|||
interceptCompile: typeof interceptCompile
|
||||
interceptEvents: typeof interceptEvents
|
||||
interceptSpelling: typeof interceptSpelling
|
||||
waitForCompile: typeof waitForCompile
|
||||
interceptDeferredCompile: typeof interceptDeferredCompile
|
||||
index: () => Chainable<number>
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +26,8 @@ declare global {
|
|||
Cypress.Commands.add('interceptCompile', interceptCompile)
|
||||
Cypress.Commands.add('interceptEvents', interceptEvents)
|
||||
Cypress.Commands.add('interceptSpelling', interceptSpelling)
|
||||
Cypress.Commands.add('waitForCompile', waitForCompile)
|
||||
Cypress.Commands.add('interceptDeferredCompile', interceptDeferredCompile)
|
||||
Cypress.Commands.add('index', { prevSubject: true }, subject => {
|
||||
return cy.wrap(subject).invoke('index')
|
||||
})
|
||||
|
|
|
@ -5,7 +5,7 @@ import { testDetachChannel } from '../../helpers/detach-channel'
|
|||
|
||||
describe('<DetachCompileButtonWrapper />', function () {
|
||||
beforeEach(function () {
|
||||
cy.interceptCompile()
|
||||
window.metaAttributesCache = new Map()
|
||||
cy.interceptEvents()
|
||||
})
|
||||
|
||||
|
@ -14,6 +14,8 @@ describe('<DetachCompileButtonWrapper />', function () {
|
|||
})
|
||||
|
||||
it('detacher mode and not linked: does not show button ', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
cy.window().then(win => {
|
||||
win.metaAttributesCache = new Map([['ol-detachRole', 'detacher']])
|
||||
})
|
||||
|
@ -26,10 +28,14 @@ describe('<DetachCompileButtonWrapper />', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' }).should('not.exist')
|
||||
})
|
||||
|
||||
it('detacher mode and linked: show button', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
cy.window().then(win => {
|
||||
win.metaAttributesCache = new Map([['ol-detachRole', 'detacher']])
|
||||
})
|
||||
|
@ -42,6 +48,8 @@ describe('<DetachCompileButtonWrapper />', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.wrap(null).then(() => {
|
||||
testDetachChannel.postMessage({
|
||||
role: 'detached',
|
||||
|
@ -53,6 +61,8 @@ describe('<DetachCompileButtonWrapper />', function () {
|
|||
})
|
||||
|
||||
it('not detacher mode and linked: does not show button ', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
cy.window().then(win => {
|
||||
win.metaAttributesCache = new Map([['ol-detachRole', 'detached']])
|
||||
})
|
||||
|
@ -65,6 +75,8 @@ describe('<DetachCompileButtonWrapper />', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.wrap(null).then(() => {
|
||||
testDetachChannel.postMessage({
|
||||
role: 'detacher',
|
||||
|
|
|
@ -6,11 +6,12 @@ import { unmountComponentAtNode } from 'react-dom'
|
|||
|
||||
describe('<PdfJSViewer/>', function () {
|
||||
beforeEach(function () {
|
||||
cy.interceptCompile()
|
||||
cy.interceptEvents()
|
||||
})
|
||||
|
||||
it('loads all PDF pages', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -21,6 +22,8 @@ describe('<PdfJSViewer/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.findByLabelText('Page 1')
|
||||
cy.findByLabelText('Page 2')
|
||||
cy.findByLabelText('Page 3')
|
||||
|
@ -30,6 +33,8 @@ describe('<PdfJSViewer/>', function () {
|
|||
})
|
||||
|
||||
it('renders pages in a "loading" state', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -40,10 +45,14 @@ describe('<PdfJSViewer/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.findByLabelText('Loading…')
|
||||
})
|
||||
|
||||
it('can be unmounted while loading a document', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -54,10 +63,14 @@ describe('<PdfJSViewer/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.then(() => unmountComponentAtNode(getContainerEl()))
|
||||
})
|
||||
|
||||
it('can be unmounted after loading a document', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -68,6 +81,8 @@ describe('<PdfJSViewer/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.findByLabelText('Page 1')
|
||||
|
||||
cy.then(() => unmountComponentAtNode(getContainerEl()))
|
||||
|
|
|
@ -11,9 +11,9 @@ describe('<PdfPreviewDetachedRoot/>', function () {
|
|||
['ol-project_id', 'project1'],
|
||||
['ol-detachRole', 'detached'],
|
||||
['ol-projectName', 'Project Name'],
|
||||
['ol-preventCompileOnLoad', true],
|
||||
])
|
||||
|
||||
cy.interceptCompile()
|
||||
cy.interceptEvents()
|
||||
})
|
||||
|
||||
|
@ -22,6 +22,8 @@ describe('<PdfPreviewDetachedRoot/>', function () {
|
|||
})
|
||||
|
||||
it('syncs compiling state', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
cy.mount(<PdfPreviewDetachedRoot />)
|
||||
|
||||
cy.wrap(null).then(() => {
|
||||
|
@ -51,6 +53,8 @@ describe('<PdfPreviewDetachedRoot/>', function () {
|
|||
})
|
||||
|
||||
it('sends a clear cache request when the button is pressed', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
cy.mount(<PdfPreviewDetachedRoot />)
|
||||
|
||||
cy.wrap(null).then(() => {
|
||||
|
|
|
@ -4,7 +4,8 @@ import { testDetachChannel } from '../../helpers/detach-channel'
|
|||
|
||||
describe('<PdfPreviewHybridToolbar/>', function () {
|
||||
beforeEach(function () {
|
||||
cy.interceptCompile()
|
||||
window.metaAttributesCache = new Map()
|
||||
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
|
||||
cy.interceptEvents()
|
||||
})
|
||||
|
||||
|
|
|
@ -22,11 +22,18 @@ const Layout: FC<{ layout: string; view?: string }> = ({ layout, view }) => {
|
|||
|
||||
describe('<PdfPreview/>', function () {
|
||||
beforeEach(function () {
|
||||
cy.interceptCompile()
|
||||
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
|
||||
cy.interceptEvents()
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
window.metaAttributesCache = new Map()
|
||||
})
|
||||
|
||||
it('renders the PDF preview', function () {
|
||||
window.metaAttributesCache.set('ol-preventCompileOnLoad', false)
|
||||
cy.interceptCompile('compile')
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -38,13 +45,14 @@ describe('<PdfPreview/>', function () {
|
|||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.wait('@compile')
|
||||
cy.waitForCompile({ pdf: true })
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
cy.wait('@compile-pdf')
|
||||
})
|
||||
|
||||
it('runs a compile when the Recompile button is pressed', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -55,28 +63,18 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.wait('@compile')
|
||||
cy.wait('@compile-pdf')
|
||||
|
||||
cy.interceptCompile('recompile')
|
||||
|
||||
// press the Recompile button => compile
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
|
||||
// wait for "recompile" to finish
|
||||
// cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.wait('@recompile-pdf')
|
||||
cy.wait('@recompile-log')
|
||||
cy.wait('@recompile-blg')
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
// wait for compile to finish
|
||||
cy.waitForCompile({ pdf: true })
|
||||
|
||||
cy.contains('Your Paper')
|
||||
})
|
||||
|
||||
it('runs a compile on `pdf:recompile` event', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -87,70 +85,20 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.wait('@compile')
|
||||
cy.wait('@compile-pdf')
|
||||
|
||||
cy.interceptCompile('recompile')
|
||||
|
||||
cy.window().then(win => {
|
||||
win.dispatchEvent(new CustomEvent('pdf:recompile'))
|
||||
})
|
||||
|
||||
// wait for "recompile" to finish
|
||||
// cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.wait('@recompile')
|
||||
// wait for compile to finish
|
||||
cy.waitForCompile({ pdf: true })
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
|
||||
cy.wait('@recompile-pdf')
|
||||
cy.contains('Your Paper')
|
||||
})
|
||||
|
||||
it('does not compile while compiling', function () {
|
||||
let compileResolve: (value?: unknown) => void
|
||||
let counter = 0
|
||||
|
||||
const promise = new Promise(resolve => {
|
||||
compileResolve = resolve
|
||||
})
|
||||
|
||||
cy.intercept(
|
||||
'POST',
|
||||
'/project/project123/compile?auto_compile=true',
|
||||
req => {
|
||||
counter++
|
||||
|
||||
promise.then(() => {
|
||||
req.reply({
|
||||
body: {
|
||||
status: 'success',
|
||||
clsiServerId: 'foo',
|
||||
compileGroup: 'priority',
|
||||
pdfDownloadDomain: 'https://clsi.test-overleaf.com',
|
||||
outputFiles: [
|
||||
{
|
||||
path: 'output.pdf',
|
||||
build: '123',
|
||||
url: '/build/123/output.pdf',
|
||||
type: 'pdf',
|
||||
},
|
||||
{
|
||||
path: 'output.log',
|
||||
build: '123',
|
||||
url: '/build/123/output.log',
|
||||
type: 'log',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
return promise
|
||||
}
|
||||
).as('compile')
|
||||
|
||||
cy.interceptDeferredCompile(() => counter++).then(
|
||||
resolveDeferredCompile => {
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -159,24 +107,34 @@ describe('<PdfPreview/>', function () {
|
|||
<PdfPreview />
|
||||
</div>
|
||||
</EditorProviders>
|
||||
).then(() => {
|
||||
)
|
||||
|
||||
// start compiling
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
|
||||
// trigger a recompile
|
||||
cy.window().then(win => {
|
||||
win.dispatchEvent(new CustomEvent('pdf:recompile'))
|
||||
})
|
||||
|
||||
compileResolve()
|
||||
// finish the original compile
|
||||
resolveDeferredCompile()
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
// wait for the original compile to finish
|
||||
cy.waitForCompile({ pdf: true })
|
||||
|
||||
cy.contains('Your Paper').should(() => {
|
||||
// NOTE: difficult to assert that a second request won't be sent, at some point
|
||||
expect(counter).to.equal(1)
|
||||
})
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('disables compile button while compile is running', function () {
|
||||
cy.interceptDeferredCompile().then(resolveDeferredCompile => {
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -187,11 +145,19 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.findByRole('button', { name: 'Compiling…' }).should('be.disabled')
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
.should('be.disabled')
|
||||
.then(resolveDeferredCompile)
|
||||
|
||||
cy.waitForCompile()
|
||||
cy.findByRole('button', { name: 'Recompile' }).should('not.be.disabled')
|
||||
})
|
||||
})
|
||||
|
||||
it('runs a compile on doc change if autocompile is enabled', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -202,11 +168,6 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.wait('@compile')
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
|
||||
cy.window().then(win => {
|
||||
cy.clock()
|
||||
|
||||
|
@ -216,16 +177,21 @@ describe('<PdfPreview/>', function () {
|
|||
// fire a doc:changed event => compile
|
||||
win.dispatchEvent(new CustomEvent('doc:changed'))
|
||||
|
||||
// wait enough time for the compile to start
|
||||
cy.tick(6000) // > AUTO_COMPILE_DEBOUNCE
|
||||
|
||||
cy.clock().invoke('restore')
|
||||
})
|
||||
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
// wait for compile to finish
|
||||
cy.waitForCompile({ pdf: true })
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
})
|
||||
|
||||
it('does not run a compile on doc change if autocompile is disabled', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -236,10 +202,6 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
|
||||
cy.window().then(win => {
|
||||
cy.clock()
|
||||
|
||||
|
@ -249,15 +211,19 @@ describe('<PdfPreview/>', function () {
|
|||
// fire a doc:changed event => no compile
|
||||
win.dispatchEvent(new CustomEvent('doc:changed'))
|
||||
|
||||
cy.tick(5000) // AUTO_COMPILE_DEBOUNCE
|
||||
// wait enough time for the compile to start
|
||||
cy.tick(6000) // AUTO_COMPILE_DEBOUNCE
|
||||
|
||||
cy.clock().invoke('restore')
|
||||
})
|
||||
|
||||
// NOTE: difficult to assert that a request hasn't been sent
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
})
|
||||
|
||||
it('does not run a compile on doc change if autocompile is blocked by syntax check', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
// enable linting in the editor
|
||||
scope.settings.syntaxValidation = true
|
||||
|
@ -272,10 +238,6 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
|
||||
cy.window().then(win => {
|
||||
cy.clock()
|
||||
|
||||
|
@ -288,16 +250,21 @@ describe('<PdfPreview/>', function () {
|
|||
// fire a doc:changed event => no compile
|
||||
win.dispatchEvent(new CustomEvent('doc:changed'))
|
||||
|
||||
cy.tick(5000) // AUTO_COMPILE_DEBOUNCE
|
||||
// wait enough time for the compile to start
|
||||
cy.tick(6000) // AUTO_COMPILE_DEBOUNCE
|
||||
|
||||
cy.clock().invoke('restore')
|
||||
})
|
||||
|
||||
// NOTE: difficult to assert that a request hasn't been sent
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
|
||||
cy.findByText('Code check failed')
|
||||
})
|
||||
|
||||
it('does not run a compile on doc change if the PDF preview is not open', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -309,11 +276,6 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.wait('@compile')
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
|
||||
cy.window().then(win => {
|
||||
cy.clock()
|
||||
|
||||
|
@ -323,15 +285,17 @@ describe('<PdfPreview/>', function () {
|
|||
// fire a doc:changed event => compile
|
||||
win.dispatchEvent(new CustomEvent('doc:changed'))
|
||||
|
||||
// wait enough time for the compile to start
|
||||
cy.tick(6000) // > AUTO_COMPILE_DEBOUNCE
|
||||
|
||||
cy.clock().invoke('restore')
|
||||
})
|
||||
|
||||
// NOTE: difficult to assert that a request hasn't been sent
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
})
|
||||
|
||||
describe('displays error messages', function () {
|
||||
describe('error messages', function () {
|
||||
const compileErrorStatuses = {
|
||||
'clear-cache':
|
||||
'Sorry, something went wrong and your project could not be compiled. Please try again in a few moments.',
|
||||
|
@ -355,7 +319,7 @@ describe('<PdfPreview/>', function () {
|
|||
|
||||
for (const [status, message] of Object.entries(compileErrorStatuses)) {
|
||||
it(`displays error message for '${status}' status`, function () {
|
||||
cy.intercept('POST', '/project/*/compile?*', {
|
||||
cy.intercept('POST', '/project/*/compile*', {
|
||||
body: {
|
||||
status,
|
||||
clsiServerId: 'foo',
|
||||
|
@ -373,15 +337,16 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.wait('@compile')
|
||||
cy.findByText(message)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('displays expandable raw logs', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -392,9 +357,8 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.waitForCompile({ pdf: true })
|
||||
|
||||
cy.findByRole('button', { name: 'View logs' }).click()
|
||||
cy.findByRole('button', { name: 'View PDF' })
|
||||
|
@ -422,7 +386,7 @@ describe('<PdfPreview/>', function () {
|
|||
],
|
||||
}
|
||||
|
||||
cy.intercept('POST', '/project/*/compile?*', {
|
||||
cy.intercept('POST', '/project/*/compile*', {
|
||||
body: {
|
||||
status: 'validation-problems',
|
||||
validationProblems,
|
||||
|
@ -441,10 +405,7 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.wait('@compile')
|
||||
|
||||
cy.findByText('Project too large')
|
||||
|
@ -452,7 +413,10 @@ describe('<PdfPreview/>', function () {
|
|||
cy.findByText('Conflicting Paths Found')
|
||||
})
|
||||
|
||||
describe('clear cache', function () {
|
||||
it('sends a clear cache request when the button is pressed', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -463,16 +427,15 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.waitForCompile({ pdf: true })
|
||||
|
||||
cy.findByRole('button', { name: 'View logs' }).click()
|
||||
cy.findByRole('button', { name: 'Clear cached files' }).should(
|
||||
'not.be.disabled'
|
||||
)
|
||||
|
||||
cy.intercept('DELETE', 'project/*/output?*', {
|
||||
cy.intercept('DELETE', '/project/*/output*', {
|
||||
statusCode: 204,
|
||||
delay: 100,
|
||||
}).as('clear-cache')
|
||||
|
@ -489,6 +452,8 @@ describe('<PdfPreview/>', function () {
|
|||
})
|
||||
|
||||
it('handle "recompile from scratch"', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -499,10 +464,13 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
// wait for "compile on load" to finish
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.wait('@compile')
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.waitForCompile({ pdf: true })
|
||||
cy.interceptCompile('recompile')
|
||||
cy.intercept('DELETE', '/project/*/output*', {
|
||||
statusCode: 204,
|
||||
delay: 100,
|
||||
}).as('clear-cache')
|
||||
|
||||
// show the logs UI
|
||||
cy.findByRole('button', { name: 'View logs' }).click()
|
||||
|
@ -511,13 +479,6 @@ describe('<PdfPreview/>', function () {
|
|||
'not.be.disabled'
|
||||
)
|
||||
|
||||
cy.interceptCompile()
|
||||
|
||||
cy.intercept('DELETE', 'project/*/output?*', {
|
||||
statusCode: 204,
|
||||
delay: 100,
|
||||
}).as('clear-cache')
|
||||
|
||||
// TODO: open the menu?
|
||||
cy.findByRole('menuitem', {
|
||||
name: 'Recompile from scratch',
|
||||
|
@ -530,14 +491,19 @@ describe('<PdfPreview/>', function () {
|
|||
|
||||
cy.findByRole('button', { name: 'Compiling…' })
|
||||
cy.wait('@clear-cache')
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
|
||||
cy.wait('@compile')
|
||||
cy.wait('@compile-pdf')
|
||||
// wait for recompile from scratch to finish
|
||||
cy.waitForCompile({ pdf: true, prefix: 'recompile' })
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' })
|
||||
})
|
||||
})
|
||||
|
||||
describe('invalid URLs and broken PDFs', function () {
|
||||
it('shows an error for an invalid URL', function () {
|
||||
cy.intercept('/build/*/output.pdf?*', {
|
||||
cy.interceptCompile()
|
||||
|
||||
cy.intercept('/build/*/output.pdf*', {
|
||||
statusCode: 500,
|
||||
body: {
|
||||
message: 'something awful happened',
|
||||
|
@ -555,6 +521,8 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.waitForCompile()
|
||||
cy.wait('@compile-pdf-error')
|
||||
|
||||
cy.contains('Something went wrong while rendering this PDF.')
|
||||
|
@ -565,7 +533,9 @@ describe('<PdfPreview/>', function () {
|
|||
})
|
||||
|
||||
it('shows an error for a corrupt PDF', function () {
|
||||
cy.intercept('/build/*/output.pdf?*', {
|
||||
cy.interceptCompile()
|
||||
|
||||
cy.intercept('/build/*/output.pdf*', {
|
||||
fixture: 'build/output-corrupt.pdf,null',
|
||||
}).as('compile-pdf-corrupt')
|
||||
|
||||
|
@ -579,6 +549,8 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.waitForCompile()
|
||||
cy.wait('@compile-pdf-corrupt')
|
||||
|
||||
cy.contains('Something went wrong while rendering this PDF.')
|
||||
|
@ -591,9 +563,11 @@ describe('<PdfPreview/>', function () {
|
|||
|
||||
describe('human readable logs', function () {
|
||||
it('shows human readable hint for undefined reference errors', function () {
|
||||
cy.intercept('/build/*/output.log?*', {
|
||||
cy.interceptCompile()
|
||||
|
||||
cy.intercept('/build/*/output.log*', {
|
||||
fixture: 'build/output-human-readable.log',
|
||||
}).as('log')
|
||||
}).as('compile-log')
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
|
@ -605,7 +579,8 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.wait('@log')
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.waitForCompile()
|
||||
cy.findByRole('button', { name: 'View logs' }).click()
|
||||
|
||||
cy.findByText(
|
||||
|
@ -622,9 +597,10 @@ describe('<PdfPreview/>', function () {
|
|||
})
|
||||
|
||||
it('does not show human readable hint when no undefined reference errors', function () {
|
||||
cy.interceptCompile()
|
||||
cy.intercept('/build/*/output.log?*', {
|
||||
fixture: 'build/output-undefined-references.log',
|
||||
}).as('log')
|
||||
}).as('compile-log')
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
|
@ -636,7 +612,8 @@ describe('<PdfPreview/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.wait('@log')
|
||||
cy.findByRole('button', { name: 'Recompile' }).click()
|
||||
cy.waitForCompile()
|
||||
cy.findByRole('button', { name: 'View logs' }).click()
|
||||
|
||||
cy.findByText(
|
||||
|
|
|
@ -77,7 +77,7 @@ const WithSelectedEntities = ({
|
|||
}
|
||||
|
||||
const interceptSyncCodeAsync = () => {
|
||||
const output: { resolve: () => void } = {
|
||||
const deferred: { resolve: () => void } = {
|
||||
resolve: () => {
|
||||
// do nothing
|
||||
},
|
||||
|
@ -85,7 +85,7 @@ const interceptSyncCodeAsync = () => {
|
|||
|
||||
cy.intercept('/project/*/sync/code?*', req => {
|
||||
return new Promise(resolve => {
|
||||
output.resolve = () => {
|
||||
deferred.resolve = () => {
|
||||
req.reply({
|
||||
body: { pdf: cloneDeep(mockHighlights) },
|
||||
})
|
||||
|
@ -94,7 +94,7 @@ const interceptSyncCodeAsync = () => {
|
|||
})
|
||||
}).as('sync-code')
|
||||
|
||||
return output
|
||||
return deferred
|
||||
}
|
||||
|
||||
const interceptSyncPdfAsync = () => {
|
||||
|
@ -127,12 +127,10 @@ const interceptSyncPdf = () => {
|
|||
}).as('sync-pdf')
|
||||
}
|
||||
|
||||
// eslint-disable-next-line mocha/no-skipped-tests
|
||||
describe.skip('<PdfSynctexControls/>', function () {
|
||||
describe('<PdfSynctexControls/>', function () {
|
||||
beforeEach(function () {
|
||||
window.metaAttributesCache = new Map()
|
||||
|
||||
cy.interceptCompile()
|
||||
window.metaAttributesCache.set('ol-preventCompileOnLoad', false)
|
||||
cy.interceptEvents()
|
||||
})
|
||||
|
||||
|
@ -141,6 +139,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
})
|
||||
|
||||
it('handles clicks on sync buttons', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -151,6 +151,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.get('.synctex-control-icon').should('have.length', 2)
|
||||
|
||||
// mock editor cursor position update
|
||||
|
@ -162,7 +164,7 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
)
|
||||
})
|
||||
|
||||
cy.wait('@compile').then(() => {
|
||||
cy.wrap(null).then(() => {
|
||||
setDetachedPosition(mockPosition)
|
||||
})
|
||||
|
||||
|
@ -190,6 +192,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
})
|
||||
|
||||
it('disables button when multiple entities are selected', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -202,12 +206,16 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.findByRole('button', { name: 'Go to code location in PDF' }).should(
|
||||
'be.disabled'
|
||||
)
|
||||
})
|
||||
|
||||
it('disables button when a file is selected', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -218,6 +226,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.findByRole('button', { name: 'Go to code location in PDF' }).should(
|
||||
'be.disabled'
|
||||
)
|
||||
|
@ -229,6 +239,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
})
|
||||
|
||||
it('does not have go to PDF location button nor arrow icon', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -239,6 +251,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.findByRole('button', { name: /^Go to PDF location in code/ }).should(
|
||||
'not.exist'
|
||||
)
|
||||
|
@ -247,6 +261,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
})
|
||||
|
||||
it('send set highlights action', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -257,7 +273,7 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.wait('@compile')
|
||||
cy.waitForCompile()
|
||||
|
||||
// mock editor cursor position update
|
||||
cy.window().then(win => {
|
||||
|
@ -302,6 +318,7 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
})
|
||||
|
||||
it('reacts to sync to code action', function () {
|
||||
cy.interceptCompile()
|
||||
interceptSyncPdf()
|
||||
|
||||
const scope = mockScope()
|
||||
|
@ -312,7 +329,9 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
<WithSelectedEntities mockSelectedEntities={mockSelectedEntities} />
|
||||
<PdfSynctexControls />
|
||||
</EditorProviders>
|
||||
).then(() => {
|
||||
)
|
||||
|
||||
cy.waitForCompile().then(() => {
|
||||
testDetachChannel.postMessage({
|
||||
role: 'detached',
|
||||
event: 'action-sync-to-code',
|
||||
|
@ -332,6 +351,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
})
|
||||
|
||||
it('does not have go to code location button nor arrow icon', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -341,6 +362,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.waitForCompile()
|
||||
|
||||
cy.findByRole('button', {
|
||||
name: 'Go to code location in PDF',
|
||||
}).should('not.exist')
|
||||
|
@ -349,6 +372,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
})
|
||||
|
||||
it('send go to code line action', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -357,7 +382,7 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.wait('@compile').then(() => {
|
||||
cy.waitForCompile().then(() => {
|
||||
testDetachChannel.postMessage({
|
||||
role: 'detacher',
|
||||
event: `state-position`,
|
||||
|
@ -394,6 +419,8 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
})
|
||||
|
||||
it('update inflight state', function () {
|
||||
cy.interceptCompile()
|
||||
|
||||
const scope = mockScope()
|
||||
|
||||
cy.mount(
|
||||
|
@ -403,7 +430,7 @@ describe.skip('<PdfSynctexControls/>', function () {
|
|||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.wrap(null).then(() => {
|
||||
cy.waitForCompile().then(() => {
|
||||
testDetachChannel.postMessage({
|
||||
role: 'detacher',
|
||||
event: `state-position`,
|
||||
|
|
|
@ -34,12 +34,13 @@ const DetachLayoutTest = () => {
|
|||
)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line mocha/no-skipped-tests
|
||||
describe.skip('useDetachLayout', function () {
|
||||
describe('useDetachLayout', function () {
|
||||
beforeEach(function () {
|
||||
window.metaAttributesCache = new Map()
|
||||
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
|
||||
cy.stub(window, 'open').as('openWindow')
|
||||
cy.stub(window, 'close').as('closeWindow')
|
||||
cy.interceptEvents()
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
|
|
Loading…
Reference in a new issue