mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-22 21:43:47 +00:00
Merge pull request #19778 from overleaf/jpa-e2e-reuse-sessions
[server-pro] tests: implement session re-usage GitOrigin-RevId: 81f2feb39e413c858eb287784e378cf43423d0a4
This commit is contained in:
parent
399e834e36
commit
37f486ca9a
8 changed files with 58 additions and 35 deletions
|
@ -11,6 +11,9 @@ describe('Accounts', function () {
|
|||
cy.visit('/project')
|
||||
cy.findByText('Account').click()
|
||||
cy.findByText('Log Out').click()
|
||||
cy.url().should('include', '/login')
|
||||
cy.visit('/project')
|
||||
cy.url().should('include', '/login')
|
||||
})
|
||||
|
||||
it('should render the email on the user activate screen', () => {
|
||||
|
|
|
@ -134,9 +134,8 @@ describe('admin panel', function () {
|
|||
})
|
||||
|
||||
describe('manage site', () => {
|
||||
let resumeAdminSession: () => void
|
||||
beforeEach(() => {
|
||||
resumeAdminSession = login(admin)
|
||||
login(admin)
|
||||
cy.visit('/project')
|
||||
cy.get('nav').findByText('Admin').click()
|
||||
cy.get('nav').findByText('Manage Site').click()
|
||||
|
@ -151,12 +150,12 @@ describe('admin panel', function () {
|
|||
cy.get('button').contains('Post Message').click()
|
||||
cy.findByText(message)
|
||||
|
||||
const resumeUser1Session = login(user1)
|
||||
login(user1)
|
||||
cy.visit('/project')
|
||||
cy.findByText(message)
|
||||
|
||||
cy.log('clear system messages')
|
||||
resumeAdminSession()
|
||||
login(admin)
|
||||
cy.visit('/project')
|
||||
cy.get('nav').findByText('Admin').click()
|
||||
cy.get('nav').findByText('Manage Site').click()
|
||||
|
@ -164,7 +163,7 @@ describe('admin panel', function () {
|
|||
cy.get('button').contains('Clear all messages').click()
|
||||
|
||||
cy.log('verify system messages are no longer displayed')
|
||||
resumeUser1Session()
|
||||
login(user1)
|
||||
cy.visit('/project')
|
||||
cy.findByText(message).should('not.exist')
|
||||
})
|
||||
|
@ -260,7 +259,7 @@ describe('admin panel', function () {
|
|||
})
|
||||
|
||||
it('restore deleted projects', () => {
|
||||
const resumeUserSession = login(user1)
|
||||
login(user1)
|
||||
cy.visit('/project')
|
||||
|
||||
cy.log('select project to delete')
|
||||
|
@ -299,7 +298,7 @@ describe('admin panel', function () {
|
|||
cy.url().should('contain', `/admin/project/${projectToDeleteId}`)
|
||||
|
||||
cy.log('login as the user and verify the project is restored')
|
||||
resumeUserSession()
|
||||
login(user1)
|
||||
cy.visit('/project')
|
||||
cy.get('.project-list-sidebar-react').within(() => {
|
||||
cy.findByText('Trashed Projects').click()
|
||||
|
|
|
@ -66,11 +66,9 @@ describe('editor', () => {
|
|||
|
||||
describe('collaboration', () => {
|
||||
let projectId: string
|
||||
let resumeUserSession: () => void
|
||||
let resumeCollaboratorSession: () => void
|
||||
|
||||
beforeEach(() => {
|
||||
resumeUserSession = login('user@example.com')
|
||||
login('user@example.com')
|
||||
cy.visit(`/project`)
|
||||
createProject('test-editor', { type: 'Example Project' }).then(
|
||||
(id: string) => {
|
||||
|
@ -86,7 +84,7 @@ describe('editor', () => {
|
|||
.should('contain.text', 'http://') // wait for the link to appear
|
||||
.then(el => {
|
||||
const linkSharingReadAndWrite = el.text()
|
||||
resumeCollaboratorSession = login('collaborator@example.com')
|
||||
login('collaborator@example.com')
|
||||
cy.visit(linkSharingReadAndWrite)
|
||||
cy.get('button').contains('Join Project').click()
|
||||
cy.log(
|
||||
|
@ -95,7 +93,7 @@ describe('editor', () => {
|
|||
cy.visit('/project')
|
||||
})
|
||||
|
||||
resumeUserSession()
|
||||
login('user@example.com')
|
||||
cy.visit(`/project/${projectId}`)
|
||||
}
|
||||
)
|
||||
|
@ -112,7 +110,7 @@ describe('editor', () => {
|
|||
.within(() => cy.get('.input-switch').click())
|
||||
cy.wait('@enableTrackChanges')
|
||||
|
||||
resumeCollaboratorSession()
|
||||
login('collaborator@example.com')
|
||||
cy.visit(`/project/${projectId}`)
|
||||
|
||||
cy.log('make changes in main file')
|
||||
|
@ -127,7 +125,7 @@ describe('editor', () => {
|
|||
cy.log('recompile to force flush')
|
||||
cy.findByText('Recompile').click()
|
||||
|
||||
resumeUserSession()
|
||||
login('user@example.com')
|
||||
cy.visit(`/project/${projectId}`)
|
||||
|
||||
cy.log('reject changes')
|
||||
|
@ -151,7 +149,7 @@ describe('editor', () => {
|
|||
.within(() => cy.get('.input-switch').click())
|
||||
cy.wait('@enableTrackChanges')
|
||||
|
||||
resumeCollaboratorSession()
|
||||
login('collaborator@example.com')
|
||||
cy.visit(`/project/${projectId}`)
|
||||
|
||||
cy.log('enable visual editor and make changes in main file')
|
||||
|
@ -168,7 +166,7 @@ describe('editor', () => {
|
|||
cy.log('recompile to force flush')
|
||||
cy.findByText('Recompile').click()
|
||||
|
||||
resumeUserSession()
|
||||
login('user@example.com')
|
||||
cy.visit(`/project/${projectId}`)
|
||||
|
||||
cy.log('reject changes')
|
||||
|
|
|
@ -19,7 +19,7 @@ export function isExcludedBySharding(
|
|||
return SHARD && shard !== SHARD
|
||||
}
|
||||
|
||||
let lastConfig: string
|
||||
let previousConfigFrontend: string
|
||||
|
||||
export function startWith({
|
||||
pro = false,
|
||||
|
@ -36,18 +36,28 @@ export function startWith({
|
|||
version,
|
||||
vars,
|
||||
withDataDir,
|
||||
resetData,
|
||||
})
|
||||
if (resetData) {
|
||||
resetCreatedUsersCache()
|
||||
resetActivateUserRateLimit()
|
||||
// no return here, always reconfigure when resetting data
|
||||
} else if (lastConfig === cfg) {
|
||||
} else if (previousConfigFrontend === cfg) {
|
||||
return
|
||||
}
|
||||
|
||||
this.timeout(STARTUP_TIMEOUT)
|
||||
await reconfigure({ pro, version, vars, withDataDir, resetData })
|
||||
lastConfig = cfg
|
||||
const { previousConfigServer } = await reconfigure({
|
||||
pro,
|
||||
version,
|
||||
vars,
|
||||
withDataDir,
|
||||
resetData,
|
||||
})
|
||||
if (previousConfigServer !== cfg) {
|
||||
await Cypress.session.clearAllSavedSessions()
|
||||
}
|
||||
previousConfigFrontend = cfg
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ export async function reconfigure({
|
|||
vars = {},
|
||||
withDataDir = false,
|
||||
resetData = false,
|
||||
}) {
|
||||
}): Promise<{ previousConfigServer: string }> {
|
||||
return await fetchJSON(`${hostAdminUrl}/reconfigure`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
|
@ -28,15 +28,15 @@ export async function reconfigure({
|
|||
})
|
||||
}
|
||||
|
||||
async function fetchJSON(
|
||||
async function fetchJSON<T = { stdout: string; stderr: string }>(
|
||||
input: RequestInfo,
|
||||
init?: RequestInit
|
||||
): Promise<{ stdout: string; stderr: string }> {
|
||||
): Promise<T> {
|
||||
if (init?.body) {
|
||||
init.headers = { 'Content-Type': 'application/json' }
|
||||
}
|
||||
const res = await fetch(input, init)
|
||||
const { error, stdout, stderr } = await res.json()
|
||||
const { error, stdout, stderr, ...rest } = await res.json()
|
||||
if (error) {
|
||||
console.error(input, init, 'failed:', error)
|
||||
if (stdout) console.log(stdout)
|
||||
|
@ -45,7 +45,7 @@ async function fetchJSON(
|
|||
Object.assign(err, error)
|
||||
throw err
|
||||
}
|
||||
return { stdout, stderr }
|
||||
return { stdout, stderr, ...rest }
|
||||
}
|
||||
|
||||
export async function runScript({
|
||||
|
|
|
@ -56,18 +56,26 @@ export function ensureUserExists({
|
|||
}
|
||||
|
||||
export function login(username: string, password = DEFAULT_PASSWORD) {
|
||||
const id = [username, password, new Date()]
|
||||
function startOrResumeSession() {
|
||||
cy.session(id, () => {
|
||||
cy.session(
|
||||
[username, password],
|
||||
() => {
|
||||
cy.visit('/login')
|
||||
cy.get('input[name="email"]').type(username)
|
||||
cy.get('input[name="password"]').type(password)
|
||||
cy.findByRole('button', { name: 'Login' }).click()
|
||||
cy.url().should('contain', '/project')
|
||||
})
|
||||
}
|
||||
startOrResumeSession()
|
||||
return startOrResumeSession
|
||||
},
|
||||
{
|
||||
cacheAcrossSpecs: true,
|
||||
async validate() {
|
||||
cy.request({ url: '/project', followRedirect: false }).then(
|
||||
response => {
|
||||
expect(response.status).to.equal(200)
|
||||
}
|
||||
)
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
let activateRateLimitState = { count: 0, reset: 0 }
|
||||
|
|
|
@ -29,6 +29,7 @@ const IMAGES = {
|
|||
PRO: process.env.IMAGE_TAG_PRO.replace(/:.+/, ''),
|
||||
}
|
||||
|
||||
let previousConfig = ''
|
||||
let mongoIsInitialized = false
|
||||
|
||||
function readDockerComposeOverride() {
|
||||
|
@ -295,6 +296,7 @@ function maybeResetData(resetData, callback) {
|
|||
return callback(error)
|
||||
}
|
||||
|
||||
previousConfig = ''
|
||||
mongoIsInitialized = false
|
||||
runDockerCompose(
|
||||
'down',
|
||||
|
@ -336,7 +338,9 @@ app.post(
|
|||
'up',
|
||||
['--detach', '--wait', 'sharelatex'],
|
||||
(error, stdout, stderr) => {
|
||||
res.json({ error, stdout, stderr })
|
||||
const previousConfigServer = previousConfig
|
||||
previousConfig = JSON.stringify(req.body)
|
||||
res.json({ error, stdout, stderr, previousConfigServer })
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('Templates', () => {
|
|||
})
|
||||
|
||||
it('should have templates feature', () => {
|
||||
const resumeTemplatesUserSession = login(TEMPLATES_USER)
|
||||
login(TEMPLATES_USER)
|
||||
const name = `Template ${Date.now()}`
|
||||
const description = `Template Description ${Date.now()}`
|
||||
|
||||
|
@ -182,7 +182,8 @@ describe('Templates', () => {
|
|||
cy.findByText('Manage Template').click()
|
||||
cy.findByText('Unpublish')
|
||||
|
||||
resumeTemplatesUserSession()
|
||||
// Back to templates user
|
||||
login(TEMPLATES_USER)
|
||||
|
||||
// Unpublish via editor
|
||||
cy.get('@templateProjectId').then(projectId =>
|
||||
|
|
Loading…
Reference in a new issue