mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #19170 from overleaf/jpa-server-ce-re-run-before
[server-ce] make tests more robust GitOrigin-RevId: f070b8bbbf87842a69d88ca56cecf5dd0f3a286c
This commit is contained in:
parent
ebec84540f
commit
9075c82b88
8 changed files with 57 additions and 32 deletions
|
@ -2,6 +2,7 @@ import { startWith } from './helpers/config'
|
|||
import { activateUser, ensureUserExists, login } from './helpers/login'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { createProject } from './helpers/project'
|
||||
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
||||
|
||||
describe('admin panel', function () {
|
||||
describe('in server pro', () => {
|
||||
|
@ -26,7 +27,7 @@ describe('admin panel', function () {
|
|||
ensureUserExists({ email: user1 })
|
||||
ensureUserExists({ email: user2 })
|
||||
|
||||
before(() => {
|
||||
beforeWithReRunOnTestRetry(() => {
|
||||
login(user1)
|
||||
cy.visit('/project')
|
||||
createProject(testProjectName).then(id => (testProjectId = id))
|
||||
|
|
|
@ -2,6 +2,7 @@ import { createProject } from './helpers/project'
|
|||
import { startWith } from './helpers/config'
|
||||
import { ensureUserExists, login } from './helpers/login'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
||||
|
||||
describe('editor', () => {
|
||||
startWith({ pro: true })
|
||||
|
@ -168,7 +169,7 @@ describe('editor', () => {
|
|||
describe('editor', () => {
|
||||
let projectId: string
|
||||
|
||||
before(() => {
|
||||
beforeWithReRunOnTestRetry(() => {
|
||||
login('user@example.com')
|
||||
cy.visit(`/project`)
|
||||
createProject(`project-${uuid()}`, { type: 'Example Project' }).then(
|
||||
|
|
8
server-ce/test/helpers/beforeWithReRunOnTestRetry.ts
Normal file
8
server-ce/test/helpers/beforeWithReRunOnTestRetry.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
export function beforeWithReRunOnTestRetry(fn: () => void | Promise<any>) {
|
||||
let ranOnce = false
|
||||
beforeEach(() => {
|
||||
if (ranOnce && Cypress.currentRetry === 0) return
|
||||
ranOnce = true
|
||||
return fn()
|
||||
})
|
||||
}
|
|
@ -19,5 +19,7 @@ export function throttledRecompile() {
|
|||
cy.wait(Math.max(0, 1_000 - msSinceLastCompile))
|
||||
cy.findByText('Recompile').click()
|
||||
queueReset()
|
||||
cy.log('Wait for recompile to finish')
|
||||
cy.findByText('Recompile')
|
||||
})
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ export function waitUntilScrollingFinished(selector: string, start = -1) {
|
|||
const current = el.scrollTop()!
|
||||
if (current !== prev) {
|
||||
setTimeout(() => waitForStable(current, 0), pollFast)
|
||||
} else if (stableFor < 3) {
|
||||
} else if (stableFor < 5) {
|
||||
setTimeout(() => waitForStable(current, stableFor + 1), pollFast)
|
||||
} else {
|
||||
resolve(current)
|
||||
|
|
|
@ -3,13 +3,14 @@ import { startWith } from './helpers/config'
|
|||
import { ensureUserExists, login } from './helpers/login'
|
||||
import { createProject } from './helpers/project'
|
||||
import { throttledRecompile } from './helpers/compile'
|
||||
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
||||
|
||||
describe('Project Sharing', function () {
|
||||
ensureUserExists({ email: 'user@example.com' })
|
||||
startWith({ withDataDir: true })
|
||||
|
||||
let projectName: string
|
||||
before(function () {
|
||||
beforeWithReRunOnTestRetry(function () {
|
||||
projectName = `Project ${uuid()}`
|
||||
setupTestProject()
|
||||
})
|
||||
|
@ -175,7 +176,7 @@ describe('Project Sharing', function () {
|
|||
const email = 'collaborator-ro@example.com'
|
||||
ensureUserExists({ email })
|
||||
|
||||
before(function () {
|
||||
beforeWithReRunOnTestRetry(function () {
|
||||
shareProjectByEmailAndAcceptInvite(email, 'Read Only')
|
||||
})
|
||||
|
||||
|
@ -192,7 +193,7 @@ describe('Project Sharing', function () {
|
|||
const email = 'collaborator-rw@example.com'
|
||||
ensureUserExists({ email })
|
||||
|
||||
before(function () {
|
||||
beforeWithReRunOnTestRetry(function () {
|
||||
shareProjectByEmailAndAcceptInvite(email, 'Can Edit')
|
||||
})
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import { startWith } from './helpers/config'
|
|||
import { throttledRecompile } from './helpers/compile'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { waitUntilScrollingFinished } from './helpers/waitUntilScrollingFinished'
|
||||
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
||||
|
||||
const LABEL_TEX_LIVE_VERSION = 'TeX Live version'
|
||||
|
||||
|
@ -60,8 +61,9 @@ describe('SandboxedCompiles', function () {
|
|||
|
||||
function checkSyncTeX() {
|
||||
describe('SyncTeX', () => {
|
||||
const projectName = `Project ${uuid()}`
|
||||
before(function () {
|
||||
let projectName: string
|
||||
beforeWithReRunOnTestRetry(function () {
|
||||
projectName = `Project ${uuid()}`
|
||||
login('user@example.com')
|
||||
cy.visit('/project')
|
||||
createProject(projectName)
|
||||
|
@ -101,6 +103,10 @@ describe('SandboxedCompiles', function () {
|
|||
cy.get('@start').then((start: any) => {
|
||||
waitUntilScrollingFinished('.pdfjs-viewer-inner', start)
|
||||
})
|
||||
// The sync button is swapped as the position in the PDF changes.
|
||||
// Cypress appears to click on a button that references a stale position.
|
||||
// Adding a cy.wait() statement is the most reliable "fix" so far :/
|
||||
cy.wait(1000)
|
||||
cy.get('[aria-label^="Go to PDF location in code"]').click()
|
||||
cy.get('.cm-activeLine').should('have.text', '\\section{Section B}')
|
||||
})
|
||||
|
|
|
@ -7,6 +7,7 @@ import { startWith } from './helpers/config'
|
|||
import { dockerCompose, resetData, runScript } from './helpers/hostAdminClient'
|
||||
import { createProject } from './helpers/project'
|
||||
import { throttledRecompile } from './helpers/compile'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
|
||||
const USER = 'user@example.com'
|
||||
const PROJECT_NAME = 'Old Project'
|
||||
|
@ -22,23 +23,25 @@ describe('Upgrading', function () {
|
|||
) {
|
||||
const startOptions = steps.shift()!
|
||||
|
||||
// Reset mongo/redis/on-disk data
|
||||
before(async () => {
|
||||
cy.log('Reset mongo/redis/on-disk data')
|
||||
resetCreatedUsersCache()
|
||||
await resetData()
|
||||
})
|
||||
|
||||
// Create old instance
|
||||
cy.log('Create old instance')
|
||||
})
|
||||
startWith({
|
||||
pro: true,
|
||||
version: startOptions.version,
|
||||
withDataDir: true,
|
||||
vars: startOptions.vars,
|
||||
})
|
||||
before(function () {
|
||||
cy.log('Create initial user after deleting it')
|
||||
})
|
||||
ensureUserExists({ email: USER })
|
||||
|
||||
// Populate old instance
|
||||
before(() => {
|
||||
cy.log('Populate old instance')
|
||||
login(USER)
|
||||
|
||||
cy.visit('/project')
|
||||
|
@ -46,26 +49,25 @@ describe('Upgrading', function () {
|
|||
newProjectButtonMatcher: startOptions.newProjectButtonMatcher,
|
||||
})
|
||||
const recompile = throttledRecompile()
|
||||
// // wait for successful compile
|
||||
cy.log('Wait for successful compile')
|
||||
cy.get('.pdf-viewer').should('contain.text', PROJECT_NAME)
|
||||
|
||||
// Increment the doc version three times
|
||||
cy.log('Increment the doc version three times')
|
||||
for (let i = 0; i < 3; i++) {
|
||||
// Add content
|
||||
cy.log('Add content')
|
||||
cy.findByText('\\maketitle').parent().click()
|
||||
cy.findByText('\\maketitle')
|
||||
.parent()
|
||||
.type(`\n\\section{{}Old Section ${i}}`)
|
||||
|
||||
// Trigger full flush
|
||||
cy.log('Trigger full flush')
|
||||
recompile()
|
||||
cy.get('header').findByText('Menu').click()
|
||||
cy.findByText('Source').click()
|
||||
// close editor menu
|
||||
cy.get('#left-menu-modal').click()
|
||||
}
|
||||
|
||||
// Check compile and history
|
||||
cy.log('Check compile and history')
|
||||
for (let i = 0; i < 3; i++) {
|
||||
cy.get('.pdf-viewer').should('contain.text', `Old Section ${i}`)
|
||||
}
|
||||
|
@ -75,14 +77,15 @@ describe('Upgrading', function () {
|
|||
}
|
||||
})
|
||||
|
||||
// Upgrades
|
||||
for (const step of steps) {
|
||||
before(() => {
|
||||
cy.log(`Upgrade to version ${step.version}`)
|
||||
|
||||
// Navigate way from editor to avoid redirect to /login when the next instance comes up (which slows down tests)
|
||||
cy.visit('/project', {})
|
||||
})
|
||||
// Graceful shutdown
|
||||
before(async function () {
|
||||
cy.log('Graceful shutdown: flush all the things')
|
||||
this.timeout(20 * 1000)
|
||||
// Ideally we could use the container shutdown procedure, but it's too slow and unreliable for tests.
|
||||
// TODO(das7pad): adopt the below after speeding up the graceful shutdown procedure on all supported releases
|
||||
|
@ -126,20 +129,21 @@ describe('Upgrading', function () {
|
|||
})
|
||||
const recompile = throttledRecompile()
|
||||
|
||||
// wait for successful compile
|
||||
cy.log('wait for successful compile')
|
||||
cy.get('.pdf-viewer').should('contain.text', PROJECT_NAME)
|
||||
cy.get('.pdf-viewer').should('contain.text', 'Old Section 2')
|
||||
|
||||
// // Add more content
|
||||
cy.log('Add more content')
|
||||
const newSection = `New Section ${uuid()}`
|
||||
cy.findByText('\\maketitle').parent().click()
|
||||
cy.findByText('\\maketitle').parent().type('\n\\section{{}New Section}')
|
||||
cy.findByText('\\maketitle').parent().type(`\n\\section{{}${newSection}}`)
|
||||
|
||||
// Check compile and history
|
||||
cy.log('Check compile and history')
|
||||
recompile()
|
||||
cy.get('.pdf-viewer').should('contain.text', 'New Section')
|
||||
cy.get('.pdf-viewer').should('contain.text', newSection)
|
||||
cy.findByText('History').click()
|
||||
cy.findByText(/\\section\{Old Section 2}/)
|
||||
cy.findByText(/\\section\{New Section}/)
|
||||
cy.findByText(new RegExp(`\\\\section\\{${newSection}}`))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -170,17 +174,17 @@ describe('Upgrading', function () {
|
|||
cy.findByText(PROJECT_NAME).click()
|
||||
const recompile = throttledRecompile()
|
||||
|
||||
// Make a change
|
||||
cy.log('Make a change')
|
||||
cy.findByText('\\maketitle').parent().click()
|
||||
cy.findByText('\\maketitle')
|
||||
.parent()
|
||||
.type('\n\\section{{}FiveOOne Section}')
|
||||
|
||||
// Trigger flush
|
||||
cy.log('Trigger flush')
|
||||
recompile()
|
||||
cy.get('.pdf-viewer').should('contain.text', 'FiveOOne Section')
|
||||
|
||||
// Check for broken history, i.e. not synced with latest edit
|
||||
cy.log('Check for broken history, i.e. not synced with latest edit')
|
||||
cy.findByText('History').click()
|
||||
cy.findByText(/\\section\{Old Section 2}/) // wait for lazy loading
|
||||
cy.findByText(/\\section\{FiveOOne Section}/).should('not.exist')
|
||||
|
@ -212,11 +216,13 @@ describe('Upgrading', function () {
|
|||
cy.visit('/')
|
||||
cy.findByText(PROJECT_NAME).click()
|
||||
|
||||
// The edit that was made while the history was broken should be there now.
|
||||
cy.log(
|
||||
'The edit that was made while the history was broken should be there now.'
|
||||
)
|
||||
cy.findByText('History').click()
|
||||
cy.findByText(/\\section\{FiveOOne Section}/)
|
||||
|
||||
// Check indicator of force resync
|
||||
cy.log('Check indicator of force resync')
|
||||
cy.findByText('Overleaf History System')
|
||||
})
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue