mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 09:09:36 +02:00
Merge pull request #29038 from overleaf/td-eslint-e2e-tests
Enable ESLint for all end-to-end tests GitOrigin-RevId: 5d085f52fabcc794b0457edbbb551500477d4110
This commit is contained in:
145
package-lock.json
generated
145
package-lock.json
generated
@@ -13174,32 +13174,35 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@napi-rs/canvas": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.68.tgz",
|
||||
"integrity": "sha512-LQESrePLEBLvhuFkXx9jjBXRC2ClYsO5mqQ1m/puth5z9SOuM3N/B3vDuqnC3RJFktDktyK9khGvo7dTkqO9uQ==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.80.tgz",
|
||||
"integrity": "sha512-DxuT1ClnIPts1kQx8FBmkk4BQDTfI5kIzywAaMjQSXfNnra5UFU9PwurXrl+Je3bJ6BGsp/zmshVVFbCmyI+ww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"workspaces": [
|
||||
"e2e/*"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@napi-rs/canvas-android-arm64": "0.1.68",
|
||||
"@napi-rs/canvas-darwin-arm64": "0.1.68",
|
||||
"@napi-rs/canvas-darwin-x64": "0.1.68",
|
||||
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.68",
|
||||
"@napi-rs/canvas-linux-arm64-gnu": "0.1.68",
|
||||
"@napi-rs/canvas-linux-arm64-musl": "0.1.68",
|
||||
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.68",
|
||||
"@napi-rs/canvas-linux-x64-gnu": "0.1.68",
|
||||
"@napi-rs/canvas-linux-x64-musl": "0.1.68",
|
||||
"@napi-rs/canvas-win32-x64-msvc": "0.1.68"
|
||||
"@napi-rs/canvas-android-arm64": "0.1.80",
|
||||
"@napi-rs/canvas-darwin-arm64": "0.1.80",
|
||||
"@napi-rs/canvas-darwin-x64": "0.1.80",
|
||||
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.80",
|
||||
"@napi-rs/canvas-linux-arm64-gnu": "0.1.80",
|
||||
"@napi-rs/canvas-linux-arm64-musl": "0.1.80",
|
||||
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.80",
|
||||
"@napi-rs/canvas-linux-x64-gnu": "0.1.80",
|
||||
"@napi-rs/canvas-linux-x64-musl": "0.1.80",
|
||||
"@napi-rs/canvas-win32-x64-msvc": "0.1.80"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-android-arm64": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.68.tgz",
|
||||
"integrity": "sha512-h1KcSR4LKLfRfzeBH65xMxbWOGa1OtMFQbCMVlxPCkN1Zr+2gK+70pXO5ktojIYcUrP6KDcOwoc8clho5ccM/w==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.80.tgz",
|
||||
"integrity": "sha512-sk7xhN/MoXeuExlggf91pNziBxLPVUqF2CAVnB57KLG/pz7+U5TKG8eXdc3pm0d7Od0WreB6ZKLj37sX9muGOQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -13214,9 +13217,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-darwin-arm64": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.68.tgz",
|
||||
"integrity": "sha512-/VURlrAD4gDoxW1GT/b0nP3fRz/fhxmHI/xznTq2FTwkQLPOlLkDLCvTmQ7v6LtGKdc2Ed6rvYpRan+JXThInQ==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.80.tgz",
|
||||
"integrity": "sha512-O64APRTXRUiAz0P8gErkfEr3lipLJgM6pjATwavZ22ebhjYl/SUbpgM0xcWPQBNMP1n29afAC/Us5PX1vg+JNQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -13231,9 +13234,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-darwin-x64": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.68.tgz",
|
||||
"integrity": "sha512-tEpvGR6vCLTo1Tx9wmDnoOKROpw57wiCWwCpDOuVlj/7rqEJOUYr9ixW4aRJgmeGBrZHgevI0EURys2ER6whmg==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.80.tgz",
|
||||
"integrity": "sha512-FqqSU7qFce0Cp3pwnTjVkKjjOtxMqRe6lmINxpIZYaZNnVI0H5FtsaraZJ36SiTHNjZlUB69/HhxNDT1Aaa9vA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -13248,9 +13251,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-arm-gnueabihf": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.68.tgz",
|
||||
"integrity": "sha512-U9xbJsumPOiAYeAFZMlHf62b9dGs2HJ6Q5xt7xTB0uEyPeurwhgYBWGgabdsEidyj38YuzI/c3LGBbSQB3vagw==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.80.tgz",
|
||||
"integrity": "sha512-eyWz0ddBDQc7/JbAtY4OtZ5SpK8tR4JsCYEZjCE3dI8pqoWUC8oMwYSBGCYfsx2w47cQgQCgMVRVTFiiO38hHQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -13265,9 +13268,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-arm64-gnu": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.68.tgz",
|
||||
"integrity": "sha512-KFkn8wEm3mPnWD4l8+OUUkxylSJuN5q9PnJRZJgv15RtCA1bgxIwTkBhI/+xuyVMcHqON9sXq7cDkEJtHm35dg==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.80.tgz",
|
||||
"integrity": "sha512-qwA63t8A86bnxhuA/GwOkK3jvb+XTQaTiVML0vAWoHyoZYTjNs7BzoOONDgTnNtr8/yHrq64XXzUoLqDzU+Uuw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -13282,9 +13285,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-arm64-musl": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.68.tgz",
|
||||
"integrity": "sha512-IQzts91rCdOALXBWQxLZRCEDrfFTGDtNRJMNu+2SKZ1uT8cmPQkPwVk5rycvFpvgAcmiFiOSCp1aRrlfU8KPpQ==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.80.tgz",
|
||||
"integrity": "sha512-1XbCOz/ymhj24lFaIXtWnwv/6eFHXDrjP0jYkc6iHQ9q8oXKzUX1Lc6bu+wuGiLhGh2GS/2JlfORC5ZcXimRcg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -13299,9 +13302,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-riscv64-gnu": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.68.tgz",
|
||||
"integrity": "sha512-e9AS5UttoIKqXSmBzKZdd3NErSVyOEYzJfNOCGtafGk1//gibTwQXGlSXmAKuErqMp09pyk9aqQRSYzm1AQfBw==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.80.tgz",
|
||||
"integrity": "sha512-XTzR125w5ZMs0lJcxRlS1K3P5RaZ9RmUsPtd1uGt+EfDyYMu4c6SEROYsxyatbbu/2+lPe7MPHOO/0a0x7L/gw==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -13316,9 +13319,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-x64-gnu": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.68.tgz",
|
||||
"integrity": "sha512-Pa/I36VE3j57I3Obhrr+J48KGFfkZk2cJN/2NmW/vCgmoF7kCP6aTVq5n+cGdGWLd/cN9CJ9JvNwEoMRDghu0g==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.80.tgz",
|
||||
"integrity": "sha512-BeXAmhKg1kX3UCrJsYbdQd3hIMDH/K6HnP/pG2LuITaXhXBiNdh//TVVVVCBbJzVQaV5gK/4ZOCMrQW9mvuTqA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -13333,9 +13336,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-linux-x64-musl": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.68.tgz",
|
||||
"integrity": "sha512-9c6rkc5195wNxuUHJdf4/mmnq433OQey9TNvQ9LspJazvHbfSkTij8wtKjASVQsJyPDva4fkWOeV/OQ7cLw0GQ==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.80.tgz",
|
||||
"integrity": "sha512-x0XvZWdHbkgdgucJsRxprX/4o4sEed7qo9rCQA9ugiS9qE2QvP0RIiEugtZhfLH3cyI+jIRFJHV4Fuz+1BHHMg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -13350,9 +13353,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/canvas-win32-x64-msvc": {
|
||||
"version": "0.1.68",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.68.tgz",
|
||||
"integrity": "sha512-Fc5Dez23u0FoSATurT6/w1oMytiRnKWEinHivdMvXpge6nG4YvhrASrtqMk8dGJMVQpHr8QJYF45rOrx2YU2Aw==",
|
||||
"version": "0.1.80",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.80.tgz",
|
||||
"integrity": "sha512-Z8jPsM6df5V8B1HrCHB05+bDiCxjE9QA//3YrkKIdVDEwn5RKaqOxCJDRJkl48cJbylcrJbW4HxZbTte8juuPg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -20010,16 +20013,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/pdf-parse": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/pdf-parse/-/pdf-parse-1.1.5.tgz",
|
||||
"integrity": "sha512-kBfrSXsloMnUJOKi25s3+hRmkycHfLK6A09eRGqF/N8BkQoPUmaCr+q8Cli5FnfohEz/rsv82zAiPz/LXtOGhA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/pg": {
|
||||
"version": "8.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz",
|
||||
@@ -39620,13 +39613,6 @@
|
||||
"node": ">=10.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-ensure": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz",
|
||||
"integrity": "sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
@@ -41147,27 +41133,32 @@
|
||||
"integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
|
||||
},
|
||||
"node_modules/pdf-parse": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz",
|
||||
"integrity": "sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-2.3.0.tgz",
|
||||
"integrity": "sha512-VRKvhqdZ694CjdR1vusZ7VIA7ZuMN/GQ7eKz+e3z9ujCQdCQMOEG9x6cHfq8ddS7XspXVrruWuKmXm8g0hFlSQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"debug": "^3.1.0",
|
||||
"node-ensure": "^0.0.0"
|
||||
"pdfjs-dist": "^5.4.296"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.8.1"
|
||||
"node": ">=20.16.0 <21 || >=22.3.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@napi-rs/canvas": "^0.1.80"
|
||||
}
|
||||
},
|
||||
"node_modules/pdf-parse/node_modules/debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||
"node_modules/pdf-parse/node_modules/pdfjs-dist": {
|
||||
"version": "5.4.296",
|
||||
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.4.296.tgz",
|
||||
"integrity": "sha512-DlOzet0HO7OEnmUmB6wWGJrrdvbyJKftI1bhMitK7O2N8W2gc757yyYBbINy9IDafXAV9wmKr9t7xsTaNKRG5Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.1"
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=20.16.0 || >=22.3.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@napi-rs/canvas": "^0.1.80"
|
||||
}
|
||||
},
|
||||
"node_modules/pdfjs-dist": {
|
||||
@@ -53269,7 +53260,6 @@
|
||||
"@overleaf/validation-tools": "*",
|
||||
"@testing-library/cypress": "^10.0.3",
|
||||
"@types/adm-zip": "^0.5.7",
|
||||
"@types/pdf-parse": "^1.1.5",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"adm-zip": "^0.5.12",
|
||||
"body-parser": "^1.20.3",
|
||||
@@ -53279,7 +53269,7 @@
|
||||
"isomorphic-git": "^1.33.1",
|
||||
"js-yaml": "^4.1.1",
|
||||
"mocha-junit-reporter": "^2.2.1",
|
||||
"pdf-parse": "^1.1.1",
|
||||
"pdf-parse": "^2.3.0",
|
||||
"uuid": "^9.0.1",
|
||||
"zod-validation-error": "^4.0.1"
|
||||
}
|
||||
@@ -56646,7 +56636,6 @@
|
||||
"@isomorphic-git/lightning-fs": "^4.6.0",
|
||||
"@testing-library/cypress": "^10.0.3",
|
||||
"@types/adm-zip": "^0.5.7",
|
||||
"@types/pdf-parse": "^1.1.5",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"adm-zip": "^0.5.12",
|
||||
"cypress": "13.13.2",
|
||||
@@ -56654,7 +56643,7 @@
|
||||
"isomorphic-git": "^1.33.1",
|
||||
"mailtrap": "^4.3.0",
|
||||
"mocha-junit-reporter": "^2.2.1",
|
||||
"pdf-parse": "^1.1.1",
|
||||
"pdf-parse": "^2.3.0",
|
||||
"typescript": "^5.0.4",
|
||||
"uuid": "^9.0.1"
|
||||
}
|
||||
|
||||
@@ -21,5 +21,9 @@
|
||||
"overrides": [
|
||||
// Extra rules for Cypress tests
|
||||
{ "files": ["**/*.spec.ts"], "extends": ["plugin:cypress/recommended"] }
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"hotfix/",
|
||||
"develop/"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
let redisConfig, siteUrl
|
||||
let e
|
||||
const Path = require('path')
|
||||
const Path = require('node:path')
|
||||
|
||||
// These credentials are used for authenticating api requests
|
||||
// between services that may need to go over public channels
|
||||
@@ -491,9 +491,9 @@ if (
|
||||
// With lots of incoming and outgoing HTTP connections to different services,
|
||||
// sometimes long running, it is a good idea to increase the default number
|
||||
// of sockets that Node will hold open.
|
||||
const http = require('http')
|
||||
const http = require('node:http')
|
||||
http.globalAgent.maxSockets = 300
|
||||
const https = require('https')
|
||||
const https = require('node:https')
|
||||
https.globalAgent.maxSockets = 300
|
||||
|
||||
module.exports = settings
|
||||
|
||||
20
server-ce/test/Jenkinsfile
vendored
20
server-ce/test/Jenkinsfile
vendored
@@ -75,6 +75,24 @@ pipeline {
|
||||
sh 'bin/run -w /overleaf/server-ce/test monorepo npm run format'
|
||||
}
|
||||
}
|
||||
stage('Lint') {
|
||||
steps {
|
||||
script {
|
||||
waitUntil {
|
||||
return job_npm_install_done
|
||||
}
|
||||
}
|
||||
sh 'bin/run -w /overleaf/server-ce/test monorepo npm run lint -- --format json --output-file reports/eslint.json'
|
||||
}
|
||||
post {
|
||||
always {
|
||||
sh """
|
||||
sed -i 's_"filePath":"/overleaf_"filePath":"/workspace_g' server-ce/test/reports/eslint.json
|
||||
"""
|
||||
recordIssues checksAnnotationScope: 'ALL', enabledForFailure: true, failOnError: true, id: 'server-pro-e2e-tests-eslint', name: 'Server-Pro-E2E-Tests eslint', qualityGates: [[integerThreshold: 1, threshold: 1.0, type: 'TOTAL']], sourceCodeRetention: 'LAST_BUILD', tools: [esLint(pattern: 'server-ce/test/reports/eslint.json')]
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Copybara') {
|
||||
steps {
|
||||
sh 'copybara/bin/sync'
|
||||
@@ -337,7 +355,7 @@ pipeline {
|
||||
post {
|
||||
// Collect junit test results for both success and failure case.
|
||||
always {
|
||||
junit checksName: 'Server Pro E2E test results', testResults: 'server-ce/test/reports/junit-*.xml'
|
||||
junit checksName: 'Server-Pro-E2E-Tests results', testResults: 'server-ce/test/reports/junit-*.xml'
|
||||
}
|
||||
// Ensure tear down of test containers, remove CE docker images, then run general Jenkins VM cleanup.
|
||||
cleanup {
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('Accounts', function () {
|
||||
cy.url().should('include', '/login')
|
||||
})
|
||||
|
||||
it('should render the email on the user activate screen', () => {
|
||||
it('should render the email on the user activate screen', function () {
|
||||
const email = 'not-activated-user@example.com'
|
||||
cy.then(async () => {
|
||||
const { url } = await createMongoUser({ email })
|
||||
|
||||
@@ -12,7 +12,7 @@ import { openEmail } from './helpers/email'
|
||||
|
||||
describe('admin panel', function () {
|
||||
function registrationTests() {
|
||||
it('via GUI and opening URL manually', () => {
|
||||
it('via GUI and opening URL manually', function () {
|
||||
const user = `${uuid()}@example.com`
|
||||
cy.findByLabelText('Emails to register new users').type(user + '{enter}')
|
||||
|
||||
@@ -24,7 +24,7 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('via GUI and email', () => {
|
||||
it('via GUI and email', function () {
|
||||
const user = `${uuid()}@example.com`
|
||||
cy.findByLabelText('Emails to register new users').type(user + '{enter}')
|
||||
|
||||
@@ -49,7 +49,7 @@ describe('admin panel', function () {
|
||||
activateUser(url)
|
||||
})
|
||||
})
|
||||
it('via script and opening URL manually', () => {
|
||||
it('via script and opening URL manually', function () {
|
||||
const user = `${uuid()}@example.com`
|
||||
let url: string
|
||||
cy.then(async () => {
|
||||
@@ -59,7 +59,7 @@ describe('admin panel', function () {
|
||||
activateUser(url)
|
||||
})
|
||||
})
|
||||
it('via script and email', () => {
|
||||
it('via script and email', function () {
|
||||
const user = `${uuid()}@example.com`
|
||||
let url: string
|
||||
cy.then(async () => {
|
||||
@@ -81,7 +81,7 @@ describe('admin panel', function () {
|
||||
})
|
||||
}
|
||||
|
||||
describe('in CE', () => {
|
||||
describe('in CE', function () {
|
||||
if (isExcludedBySharding('CE_DEFAULT')) return
|
||||
startWith({ pro: false, version: 'latest' })
|
||||
const admin = 'admin@example.com'
|
||||
@@ -89,8 +89,8 @@ describe('admin panel', function () {
|
||||
ensureUserExists({ email: admin, isAdmin: true })
|
||||
ensureUserExists({ email: user })
|
||||
|
||||
describe('create users', () => {
|
||||
beforeEach(() => {
|
||||
describe('create users', function () {
|
||||
beforeEach(function () {
|
||||
login(admin)
|
||||
cy.visit('/project')
|
||||
cy.findByRole('menuitem', { name: 'Admin' }).click()
|
||||
@@ -100,7 +100,7 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('in server pro', () => {
|
||||
describe('in server pro', function () {
|
||||
const admin = 'admin@example.com'
|
||||
const user1 = 'user@example.com'
|
||||
const user2 = 'user2@example.com'
|
||||
@@ -135,13 +135,13 @@ describe('admin panel', function () {
|
||||
)
|
||||
})
|
||||
|
||||
describe('admin menu items', () => {
|
||||
beforeEach(() => {
|
||||
describe('admin menu items', function () {
|
||||
beforeEach(function () {
|
||||
login(admin)
|
||||
cy.visit('/project')
|
||||
})
|
||||
|
||||
it('displays expected admin menu items', () => {
|
||||
it('displays expected admin menu items', function () {
|
||||
const menuitems = ['Manage Site', 'Manage Users', 'Project URL Lookup']
|
||||
menuitems.forEach(name => {
|
||||
cy.findByRole('menuitem', { name: 'Admin' }).click()
|
||||
@@ -153,15 +153,15 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('manage site', () => {
|
||||
beforeEach(() => {
|
||||
describe('manage site', function () {
|
||||
beforeEach(function () {
|
||||
login(admin)
|
||||
cy.visit('/project')
|
||||
cy.findByRole('menuitem', { name: 'Admin' }).click()
|
||||
cy.findByRole('menuitem', { name: 'Manage Site' }).click()
|
||||
})
|
||||
|
||||
it('publish and clear admin messages', () => {
|
||||
it('publish and clear admin messages', function () {
|
||||
const message = 'Admin Message ' + uuid()
|
||||
|
||||
cy.log('create system message')
|
||||
@@ -189,15 +189,15 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('manage users', () => {
|
||||
beforeEach(() => {
|
||||
describe('manage users', function () {
|
||||
beforeEach(function () {
|
||||
login(admin)
|
||||
cy.visit('/project')
|
||||
cy.findByRole('menuitem', { name: 'Admin' }).click()
|
||||
cy.findByRole('menuitem', { name: 'Manage Users' }).click()
|
||||
})
|
||||
|
||||
it('displays expected tabs', () => {
|
||||
it('displays expected tabs', function () {
|
||||
const tabs = ['Users', 'License Usage']
|
||||
cy.findAllByRole('tab').should('have.length', tabs.length)
|
||||
tabs.forEach(tabName => {
|
||||
@@ -205,21 +205,21 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('license usage tab', () => {
|
||||
it('license usage tab', function () {
|
||||
cy.get('a').contains('License Usage').click()
|
||||
cy.findByText(
|
||||
'An active user is one who has opened a project in this Server Pro instance in the last 12 months.'
|
||||
)
|
||||
})
|
||||
|
||||
describe('create users', () => {
|
||||
beforeEach(() => {
|
||||
describe('create users', function () {
|
||||
beforeEach(function () {
|
||||
cy.get('a').contains('New User').click()
|
||||
})
|
||||
registrationTests()
|
||||
})
|
||||
|
||||
it('user list RegExp search', () => {
|
||||
it('user list RegExp search', function () {
|
||||
cy.findByLabelText('RegExp').click()
|
||||
cy.findByPlaceholderText('Search users by email or id…').type(
|
||||
'user[0-9]{enter}'
|
||||
@@ -229,8 +229,8 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('user page', () => {
|
||||
beforeEach(() => {
|
||||
describe('user page', function () {
|
||||
beforeEach(function () {
|
||||
login(admin)
|
||||
cy.visit('/project')
|
||||
cy.findByRole('menuitem', { name: 'Admin' }).click()
|
||||
@@ -242,7 +242,7 @@ describe('admin panel', function () {
|
||||
cy.url().should('match', /\/admin\/user\/[a-fA-F0-9]{24}/)
|
||||
})
|
||||
|
||||
it('displays expected tabs', () => {
|
||||
it('displays expected tabs', function () {
|
||||
const tabs = [
|
||||
'User Info',
|
||||
'Projects',
|
||||
@@ -256,18 +256,18 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('user info tab', () => {
|
||||
beforeEach(() => {
|
||||
describe('user info tab', function () {
|
||||
beforeEach(function () {
|
||||
cy.findByRole('tab', { name: 'User Info' }).click()
|
||||
})
|
||||
|
||||
it('displays required sections', () => {
|
||||
it('displays required sections', function () {
|
||||
// not exhaustive list, checks the tab content is rendered
|
||||
cy.findByText('Profile')
|
||||
cy.findByText('Editor Settings')
|
||||
})
|
||||
|
||||
it('should not display SaaS-only sections', () => {
|
||||
it('should not display SaaS-only sections', function () {
|
||||
cy.findByLabelText('Referred User Count').should('not.exist')
|
||||
cy.findByRole('heading', { name: /Split Test Assignments/ }).should(
|
||||
'not.exist'
|
||||
@@ -285,7 +285,7 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('transfer project ownership', () => {
|
||||
it('transfer project ownership', function () {
|
||||
cy.log("access project admin through owners' project list")
|
||||
cy.findByRole('tablist').within(() => {
|
||||
cy.findByRole('tab', { name: 'Projects' }).click()
|
||||
@@ -326,13 +326,13 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('project page', () => {
|
||||
beforeEach(() => {
|
||||
describe('project page', function () {
|
||||
beforeEach(function () {
|
||||
login(admin)
|
||||
cy.visit(`/admin/project/${testProjectId}`)
|
||||
})
|
||||
|
||||
it('displays expected tabs', () => {
|
||||
it('displays expected tabs', function () {
|
||||
const tabs = ['Project Info', 'Deleted Docs', 'Audit Log']
|
||||
cy.findAllByRole('tab').should('have.length', tabs.length)
|
||||
tabs.forEach(tabName => {
|
||||
@@ -341,7 +341,7 @@ describe('admin panel', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('restore deleted projects', () => {
|
||||
it('restore deleted projects', function () {
|
||||
login(user1)
|
||||
cy.visit('/project')
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ describe('Project creation and compilation', function () {
|
||||
.findByRole('button', { name: 'New file' })
|
||||
.click()
|
||||
cy.findByRole('dialog').within(() => {
|
||||
cy.findByLabelText('File Name').clear().type(fileName)
|
||||
cy.findByLabelText('File Name').as('filename').clear()
|
||||
cy.get('@filename').type(fileName)
|
||||
cy.findByRole('button', { name: 'Create' }).click()
|
||||
})
|
||||
cy.findByRole('button', { name: fileName }).click()
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||
|
||||
describe('Customization', () => {
|
||||
describe('Customization', function () {
|
||||
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||
|
||||
describe('default settings', () => {
|
||||
describe('default settings', function () {
|
||||
startWith({})
|
||||
|
||||
it('should display the default right footer', () => {
|
||||
it('should display the default right footer', function () {
|
||||
cy.visit('/')
|
||||
cy.get('footer').findByRole('link', { name: 'Fork on GitHub!' })
|
||||
})
|
||||
})
|
||||
|
||||
describe('custom settings', () => {
|
||||
describe('custom settings', function () {
|
||||
startWith({
|
||||
vars: {
|
||||
OVERLEAF_APP_NAME: 'CUSTOM APP NAME',
|
||||
@@ -23,16 +23,16 @@ describe('Customization', () => {
|
||||
},
|
||||
})
|
||||
|
||||
it('should display custom name', () => {
|
||||
it('should display custom name', function () {
|
||||
cy.visit('/')
|
||||
cy.get('nav').findByText('CUSTOM APP NAME')
|
||||
})
|
||||
|
||||
it('should display custom left footer', () => {
|
||||
it('should display custom left footer', function () {
|
||||
cy.visit('/')
|
||||
cy.get('footer').findByText('CUSTOM LEFT FOOTER')
|
||||
})
|
||||
it('should display custom right footer', () => {
|
||||
it('should display custom right footer', function () {
|
||||
cy.visit('/')
|
||||
cy.get('footer').findByText('CUSTOM RIGHT FOOTER')
|
||||
})
|
||||
|
||||
@@ -53,7 +53,7 @@ export default defineConfig({
|
||||
viewportWidth: 1024,
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost',
|
||||
setupNodeEvents(on, config) {
|
||||
setupNodeEvents(on) {
|
||||
on('task', {
|
||||
readPdf,
|
||||
readFileInZip,
|
||||
|
||||
@@ -13,7 +13,7 @@ import { prepareWaitForNextCompileSlot } from './helpers/compile'
|
||||
const USER = 'user@example.com'
|
||||
const COLLABORATOR = 'collaborator@example.com'
|
||||
|
||||
describe('editor', () => {
|
||||
describe('editor', function () {
|
||||
if (isExcludedBySharding('PRO_DEFAULT_1')) return
|
||||
startWith({ pro: true })
|
||||
ensureUserExists({ email: USER })
|
||||
@@ -23,7 +23,7 @@ describe('editor', () => {
|
||||
let projectId: string
|
||||
let recompile: () => void
|
||||
let waitForCompile: (fn: () => void) => void
|
||||
beforeWithReRunOnTestRetry(function () {
|
||||
beforeWithReRunOnTestRetry(() => {
|
||||
projectName = `project-${uuid()}`
|
||||
login(USER)
|
||||
createProject(projectName, { type: 'Example project', open: false }).then(
|
||||
@@ -32,7 +32,7 @@ describe('editor', () => {
|
||||
;({ recompile, waitForCompile } = prepareWaitForNextCompileSlot())
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(function () {
|
||||
login(USER)
|
||||
waitForCompile(() => {
|
||||
openProjectById(projectId)
|
||||
@@ -58,7 +58,7 @@ describe('editor', () => {
|
||||
changeSpellCheckLanguageTo('Off')
|
||||
})
|
||||
|
||||
it('word dictionary and spelling', () => {
|
||||
it('word dictionary and spelling', function () {
|
||||
changeSpellCheckLanguageTo('English (American)')
|
||||
createNewFile()
|
||||
const word = createRandomLetterString()
|
||||
@@ -109,8 +109,8 @@ describe('editor', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('editor', () => {
|
||||
it('renders jpg', () => {
|
||||
describe('editor', function () {
|
||||
it('renders jpg', function () {
|
||||
cy.findByRole('navigation', {
|
||||
name: 'Project files and outline',
|
||||
})
|
||||
@@ -122,7 +122,7 @@ describe('editor', () => {
|
||||
.should('be.greaterThan', 0)
|
||||
})
|
||||
|
||||
it('symbol palette', () => {
|
||||
it('symbol palette', function () {
|
||||
createNewFile()
|
||||
|
||||
cy.get('button[aria-label="Insert symbol"]').click({
|
||||
@@ -139,20 +139,20 @@ describe('editor', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('add new file to project', () => {
|
||||
beforeEach(() => {
|
||||
describe('add new file to project', function () {
|
||||
beforeEach(function () {
|
||||
cy.findByRole('button', { name: 'New file' }).click()
|
||||
})
|
||||
|
||||
testNewFileUpload()
|
||||
|
||||
it('should not display import from URL', () => {
|
||||
it('should not display import from URL', function () {
|
||||
cy.findByRole('button', { name: 'From external URL' }).should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('left menu', () => {
|
||||
beforeEach(() => {
|
||||
describe('left menu', function () {
|
||||
beforeEach(function () {
|
||||
cy.findByRole('navigation', {
|
||||
name: 'Project actions',
|
||||
})
|
||||
@@ -160,7 +160,7 @@ describe('editor', () => {
|
||||
.click()
|
||||
})
|
||||
|
||||
it('can download project sources', () => {
|
||||
it('can download project sources', function () {
|
||||
cy.findByRole('link', { name: 'Source' }).click()
|
||||
const zipName = projectName.replaceAll('-', '_')
|
||||
cy.task('readFileInZip', {
|
||||
@@ -169,7 +169,7 @@ describe('editor', () => {
|
||||
}).should('contain', 'Your introduction goes here')
|
||||
})
|
||||
|
||||
it('can download project PDF', () => {
|
||||
it('can download project PDF', function () {
|
||||
cy.log('ensure project is compiled')
|
||||
cy.findByRole('region', { name: 'PDF preview and logs' }).should(
|
||||
'contain.text',
|
||||
@@ -185,7 +185,7 @@ describe('editor', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('word count', () => {
|
||||
it('word count', function () {
|
||||
cy.log('ensure project is compiled')
|
||||
cy.findByRole('region', { name: 'PDF preview and logs' }).should(
|
||||
'contain.text',
|
||||
@@ -206,8 +206,8 @@ describe('editor', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('layout selector', () => {
|
||||
it('show editor only and switch between editor and pdf', () => {
|
||||
describe('layout selector', function () {
|
||||
it('show editor only and switch between editor and pdf', function () {
|
||||
cy.findByRole('region', { name: 'PDF preview and logs' }).should(
|
||||
'be.visible'
|
||||
)
|
||||
@@ -238,7 +238,7 @@ describe('editor', () => {
|
||||
cy.get('.cm-editor').should('be.visible')
|
||||
})
|
||||
|
||||
it('show PDF only and go back to Editor & PDF', () => {
|
||||
it('show PDF only and go back to Editor & PDF', function () {
|
||||
cy.findByRole('region', { name: 'PDF preview and logs' }).should(
|
||||
'be.visible'
|
||||
)
|
||||
@@ -265,7 +265,7 @@ describe('editor', () => {
|
||||
cy.get('.cm-editor').should('be.visible')
|
||||
})
|
||||
|
||||
it('PDF in a separate tab (tests editor only)', () => {
|
||||
it('PDF in a separate tab (tests editor only)', function () {
|
||||
cy.findByTestId('pdf-viewer').should('be.visible')
|
||||
cy.get('.cm-editor').should('be.visible')
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||
import { createProject } from './helpers/project'
|
||||
|
||||
describe('SAML', () => {
|
||||
describe('SAML', function () {
|
||||
if (isExcludedBySharding('PRO_CUSTOM_1')) return
|
||||
const samlURL = Cypress.env('SAML_URL') || 'http://saml'
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('SAML', () => {
|
||||
},
|
||||
})
|
||||
|
||||
it('login', () => {
|
||||
it('login', function () {
|
||||
cy.visit('/')
|
||||
cy.findByText('Log in with SAML Test Server').click()
|
||||
|
||||
@@ -39,7 +39,7 @@ describe('SAML', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('LDAP', () => {
|
||||
describe('LDAP', function () {
|
||||
if (isExcludedBySharding('PRO_CUSTOM_1')) return
|
||||
startWith({
|
||||
pro: true,
|
||||
@@ -57,7 +57,7 @@ describe('LDAP', () => {
|
||||
},
|
||||
})
|
||||
|
||||
it('login', () => {
|
||||
it('login', function () {
|
||||
cy.visit('/')
|
||||
cy.findByText('Log in LDAP')
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ describe('filestore migration', function () {
|
||||
|
||||
// -------------------
|
||||
// filestore-migration
|
||||
beforeEach(() => {
|
||||
beforeEach(function () {
|
||||
login(email)
|
||||
waitForCompile(() => {
|
||||
openProjectById(projectId)
|
||||
@@ -311,7 +311,7 @@ describe('filestore migration', function () {
|
||||
}
|
||||
})
|
||||
|
||||
it('renders image of example project', () => {
|
||||
it('renders image of example project', function () {
|
||||
cy.findByTestId('file-tree').findByText(defaultImage).click()
|
||||
cy.get(`[alt="${defaultImage}"]`)
|
||||
.should('be.visible')
|
||||
|
||||
@@ -65,7 +65,7 @@ describe('git-bridge', function () {
|
||||
login(USER)
|
||||
})
|
||||
|
||||
it('should render the git-bridge UI in the settings', () => {
|
||||
it('should render the git-bridge UI in the settings', function () {
|
||||
maybeClearAllTokens()
|
||||
cy.visit('/user/settings')
|
||||
cy.findByRole('heading', { name: 'Git integration' })
|
||||
@@ -147,7 +147,7 @@ describe('git-bridge', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('git access', () => {
|
||||
describe('git access', function () {
|
||||
ensureUserExists({ email: 'collaborator-rw@example.com' })
|
||||
ensureUserExists({ email: 'collaborator-ro@example.com' })
|
||||
ensureUserExists({ email: 'collaborator-link-rw@example.com' })
|
||||
@@ -156,13 +156,13 @@ describe('git-bridge', function () {
|
||||
let projectName: string
|
||||
let recompile: () => void
|
||||
let waitForCompile: (triggerCompile: () => void) => void
|
||||
beforeEach(() => {
|
||||
beforeEach(function () {
|
||||
projectName = uuid()
|
||||
createProject(projectName, { open: false }).as('projectId')
|
||||
;({ recompile, waitForCompile } = prepareWaitForNextCompileSlot())
|
||||
})
|
||||
|
||||
it('should expose r/w interface to owner', () => {
|
||||
it('should expose r/w interface to owner', function () {
|
||||
maybeClearAllTokens()
|
||||
waitForCompile(() => {
|
||||
openProjectByName(projectName)
|
||||
@@ -170,7 +170,7 @@ describe('git-bridge', function () {
|
||||
checkGitAccess('readAndWrite')
|
||||
})
|
||||
|
||||
it('should expose r/w interface to invited r/w collaborator', () => {
|
||||
it('should expose r/w interface to invited r/w collaborator', function () {
|
||||
shareProjectByEmailAndAcceptInviteViaDash(
|
||||
projectName,
|
||||
'collaborator-rw@example.com',
|
||||
@@ -183,7 +183,7 @@ describe('git-bridge', function () {
|
||||
checkGitAccess('readAndWrite')
|
||||
})
|
||||
|
||||
it('should expose r/o interface to invited r/o collaborator', () => {
|
||||
it('should expose r/o interface to invited r/o collaborator', function () {
|
||||
shareProjectByEmailAndAcceptInviteViaDash(
|
||||
projectName,
|
||||
'collaborator-ro@example.com',
|
||||
@@ -196,7 +196,7 @@ describe('git-bridge', function () {
|
||||
checkGitAccess('readOnly')
|
||||
})
|
||||
|
||||
it('should expose r/w interface to link-sharing r/w collaborator', () => {
|
||||
it('should expose r/w interface to link-sharing r/w collaborator', function () {
|
||||
openProjectByName(projectName)
|
||||
enableLinkSharing().then(({ linkSharingReadAndWrite }) => {
|
||||
const email = 'collaborator-link-rw@example.com'
|
||||
@@ -213,7 +213,7 @@ describe('git-bridge', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('should expose r/o interface to link-sharing r/o collaborator', () => {
|
||||
it('should expose r/o interface to link-sharing r/o collaborator', function () {
|
||||
waitForCompile(() => {
|
||||
openProjectByName(projectName)
|
||||
})
|
||||
@@ -267,7 +267,7 @@ describe('git-bridge', function () {
|
||||
const dir = `/${projectId}`
|
||||
|
||||
async function readFile(path: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
return await new Promise((resolve, reject) => {
|
||||
fs.readFile(path, { encoding: 'utf8' }, (err, blob) => {
|
||||
if (err) return reject(err)
|
||||
resolve(blob as string)
|
||||
@@ -276,7 +276,7 @@ describe('git-bridge', function () {
|
||||
}
|
||||
|
||||
async function writeFile(path: string, data: string) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
return await new Promise<void>((resolve, reject) => {
|
||||
fs.writeFile(path, data, undefined, err => {
|
||||
if (err) return reject(err)
|
||||
resolve()
|
||||
@@ -398,8 +398,9 @@ Hello world
|
||||
cy.findByText(/\\documentclass/)
|
||||
.parent()
|
||||
.parent()
|
||||
.as('documentclass')
|
||||
.click()
|
||||
.type('% via editor{enter}')
|
||||
cy.get('@documentclass').type('% via editor{enter}')
|
||||
|
||||
// Trigger flush via compile
|
||||
recompile()
|
||||
@@ -433,7 +434,7 @@ Hello world
|
||||
function checkDisabled() {
|
||||
ensureUserExists({ email: USER })
|
||||
|
||||
it('should not render the git-bridge UI in the settings', () => {
|
||||
it('should not render the git-bridge UI in the settings', function () {
|
||||
login(USER)
|
||||
cy.visit('/user/settings')
|
||||
cy.findByRole('heading', { name: 'Git integration' }).should('not.exist')
|
||||
@@ -454,7 +455,7 @@ Hello world
|
||||
})
|
||||
}
|
||||
|
||||
describe('disabled in Server Pro', () => {
|
||||
describe('disabled in Server Pro', function () {
|
||||
if (isExcludedBySharding('PRO_DEFAULT_1')) return
|
||||
startWith({
|
||||
pro: true,
|
||||
@@ -462,7 +463,7 @@ Hello world
|
||||
checkDisabled()
|
||||
})
|
||||
|
||||
describe('unavailable in CE', () => {
|
||||
describe('unavailable in CE', function () {
|
||||
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||
startWith({
|
||||
pro: false,
|
||||
|
||||
@@ -28,7 +28,7 @@ describe('GracefulShutdown', function () {
|
||||
ensureUserExists({ email: USER })
|
||||
|
||||
let projectId: string
|
||||
it('should display banner and flush changes out of redis', () => {
|
||||
it('should display banner and flush changes out of redis', function () {
|
||||
bringServerProBackUp()
|
||||
login(USER)
|
||||
const { recompile, waitForCompile } = prepareWaitForNextCompileSlot()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export function beforeWithReRunOnTestRetry(fn: () => void | Promise<any>) {
|
||||
let ranOnce = false
|
||||
beforeEach(() => {
|
||||
beforeEach(function () {
|
||||
if (ranOnce && Cypress.currentRetry === 0) return
|
||||
ranOnce = true
|
||||
return fn()
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
*/
|
||||
export function openEmail<T>(
|
||||
subject: string | RegExp,
|
||||
runner: (frame: Cypress.Chainable<JQuery<any>>, args: T) => void,
|
||||
runner: (
|
||||
frame: Cypress.Chainable<Cypress.JQueryWithSelector<any>>,
|
||||
args: T
|
||||
) => void,
|
||||
args?: T
|
||||
) {
|
||||
const runnerS = runner.toString()
|
||||
@@ -28,9 +31,11 @@ export function openEmail<T>(
|
||||
// Use force as the subject is partially hidden
|
||||
cy.contains(subject).click({ force: true })
|
||||
cy.log('wait for iframe loading')
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(1000)
|
||||
cy.get('iframe[id="messagecontframe"]').then(frame => {
|
||||
// runnerS='(frame, args) => { runner body }'. Extract the runnable function.
|
||||
// eslint-disable-next-line no-new-func
|
||||
const runner = new Function('return ' + runnerS)()
|
||||
runner(cy.wrap(frame.prop('contentWindow').document.body), args)
|
||||
})
|
||||
|
||||
@@ -130,7 +130,7 @@ export async function purgeFilestoreData() {
|
||||
}
|
||||
|
||||
async function sleep(ms: number) {
|
||||
return new Promise(resolve => {
|
||||
return await new Promise(resolve => {
|
||||
setTimeout(resolve, ms)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -114,9 +114,8 @@ function shareProjectByEmail(
|
||||
cy.findByLabelText('Add email address', { selector: 'input' })
|
||||
.parents('form')
|
||||
.within(() => {
|
||||
cy.findByTestId('add-collaborator-select')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.findByTestId('add-collaborator-select').as('select').click()
|
||||
cy.get('@select').then(() => {
|
||||
cy.findByRole('option', { name: level }).click()
|
||||
})
|
||||
})
|
||||
@@ -275,12 +274,12 @@ export function prepareFileUploadTest(binary = false) {
|
||||
}
|
||||
|
||||
export function testNewFileUpload() {
|
||||
it('can upload text file', () => {
|
||||
it('can upload text file', function () {
|
||||
const check = prepareFileUploadTest(false)
|
||||
check()
|
||||
})
|
||||
|
||||
it('can upload binary file', () => {
|
||||
it('can upload binary file', function () {
|
||||
const check = prepareFileUploadTest(true)
|
||||
check()
|
||||
})
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
// @ts-ignore broken package entrypoint
|
||||
import pdf from 'pdf-parse/lib/pdf-parse.js'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { PDFParse } from 'pdf-parse'
|
||||
import AdmZip from 'adm-zip'
|
||||
import { setTimeout } from 'timers/promises'
|
||||
import { setTimeout } from 'node:timers/promises'
|
||||
|
||||
const MAX_ATTEMPTS = 15
|
||||
const POLL_INTERVAL = 500
|
||||
@@ -23,7 +22,7 @@ export async function readFileInZip({
|
||||
const zip = new AdmZip(path.resolve(pathToZip))
|
||||
const entry = zip
|
||||
.getEntries()
|
||||
.find(entry => entry.entryName == fileToRead)
|
||||
.find(entry => entry.entryName === fileToRead)
|
||||
if (entry) {
|
||||
return entry.getData().toString('utf8')
|
||||
} else {
|
||||
@@ -41,8 +40,15 @@ export async function readPdf(file: string) {
|
||||
while (attempt < MAX_ATTEMPTS) {
|
||||
if (fs.existsSync(file)) {
|
||||
const dataBuffer = fs.readFileSync(path.resolve(file))
|
||||
const { text } = await pdf(dataBuffer)
|
||||
return text
|
||||
const parser = new PDFParse({ data: dataBuffer })
|
||||
try {
|
||||
const result = await parser.getText()
|
||||
return result.text
|
||||
} catch (error) {
|
||||
console.error('PDF parsing failed:', error)
|
||||
} finally {
|
||||
await parser.destroy()
|
||||
}
|
||||
}
|
||||
await setTimeout(POLL_INTERVAL)
|
||||
attempt++
|
||||
|
||||
@@ -61,7 +61,7 @@ describe('History', function () {
|
||||
const CLASS_ADDITION = 'ol-cm-addition-marker'
|
||||
const CLASS_DELETION = 'ol-cm-deletion-marker'
|
||||
|
||||
it('should support labels, comparison and download', () => {
|
||||
it('should support labels, comparison and download', function () {
|
||||
const { recompile, waitForCompile } = prepareWaitForNextCompileSlot()
|
||||
waitForCompile(() => {
|
||||
createProject('labels')
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||
import { ensureUserExists, login } from './helpers/login'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
|
||||
describe('LearnWiki', function () {
|
||||
const COPYING_A_PROJECT_URL = '/learn/how-to/Copying_a_project'
|
||||
@@ -15,7 +14,7 @@ describe('LearnWiki', function () {
|
||||
ensureUserExists({ email: WITHOUT_PROJECTS_USER })
|
||||
ensureUserExists({ email: REGULAR_USER })
|
||||
|
||||
describe('enabled in Pro', () => {
|
||||
describe('enabled in Pro', function () {
|
||||
if (isExcludedBySharding('PRO_CUSTOM_2')) return
|
||||
startWith({
|
||||
pro: true,
|
||||
@@ -24,7 +23,7 @@ describe('LearnWiki', function () {
|
||||
},
|
||||
})
|
||||
|
||||
it('should add a documentation entry to the nav bar', () => {
|
||||
it('should add a documentation entry to the nav bar', function () {
|
||||
login(REGULAR_USER)
|
||||
cy.visit('/project')
|
||||
cy.findByRole('menuitem', { name: 'Documentation' }).should(
|
||||
@@ -34,7 +33,7 @@ describe('LearnWiki', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('should display a tutorial link in the welcome page', () => {
|
||||
it('should display a tutorial link in the welcome page', function () {
|
||||
login(WITHOUT_PROJECTS_USER)
|
||||
cy.visit('/project')
|
||||
cy.findByRole('link', { name: LABEL_LEARN_LATEX })
|
||||
@@ -45,7 +44,7 @@ describe('LearnWiki', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('should render wiki page', () => {
|
||||
it('should render wiki page', function () {
|
||||
login(REGULAR_USER)
|
||||
|
||||
cy.visit(UPLOADING_A_PROJECT_URL)
|
||||
@@ -81,13 +80,13 @@ describe('LearnWiki', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('disabled in Pro', () => {
|
||||
describe('disabled in Pro', function () {
|
||||
if (isExcludedBySharding('PRO_DEFAULT_1')) return
|
||||
startWith({ pro: true })
|
||||
checkDisabled()
|
||||
})
|
||||
|
||||
describe('unavailable in CE', () => {
|
||||
describe('unavailable in CE', function () {
|
||||
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||
startWith({
|
||||
pro: false,
|
||||
@@ -100,13 +99,13 @@ describe('LearnWiki', function () {
|
||||
})
|
||||
|
||||
function checkDisabled() {
|
||||
it('should not add a documentation entry to the nav bar', () => {
|
||||
it('should not add a documentation entry to the nav bar', function () {
|
||||
login(REGULAR_USER)
|
||||
cy.visit('/project')
|
||||
cy.findByText('Documentation').should('not.exist')
|
||||
})
|
||||
|
||||
it('should not render wiki page', () => {
|
||||
it('should not render wiki page', function () {
|
||||
login(REGULAR_USER)
|
||||
cy.visit(COPYING_A_PROJECT_URL, {
|
||||
failOnStatusCode: false,
|
||||
@@ -114,7 +113,7 @@ describe('LearnWiki', function () {
|
||||
cy.findByText('Not found')
|
||||
})
|
||||
|
||||
it('should not display a tutorial link in the welcome page', () => {
|
||||
it('should not display a tutorial link in the welcome page', function () {
|
||||
login(WITHOUT_PROJECTS_USER)
|
||||
cy.visit('/project')
|
||||
cy.findByText(LABEL_LEARN_LATEX).should('not.exist')
|
||||
|
||||
@@ -7,14 +7,15 @@
|
||||
"cypress:open": "cypress open --e2e --browser chrome",
|
||||
"cypress:run": "cypress run --e2e --browser chrome",
|
||||
"format": "prettier --list-different $PWD/'**/*.{js,mjs,ts,tsx}'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.{js,mjs,ts,tsx}'"
|
||||
"format:fix": "prettier --write $PWD/'**/*.{js,mjs,ts,tsx}'",
|
||||
"lint": "eslint --max-warnings 0 --format unix --ext .js,.jsx,.mjs,.ts,.tsx .",
|
||||
"lint:fix": "eslint --fix --ext .js,.jsx,.mjs,.ts,.tsx ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@isomorphic-git/lightning-fs": "^4.6.0",
|
||||
"@overleaf/validation-tools": "*",
|
||||
"@testing-library/cypress": "^10.0.3",
|
||||
"@types/adm-zip": "^0.5.7",
|
||||
"@types/pdf-parse": "^1.1.5",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"adm-zip": "^0.5.12",
|
||||
"body-parser": "^1.20.3",
|
||||
@@ -24,7 +25,7 @@
|
||||
"isomorphic-git": "^1.33.1",
|
||||
"js-yaml": "^4.1.1",
|
||||
"mocha-junit-reporter": "^2.2.1",
|
||||
"pdf-parse": "^1.1.1",
|
||||
"pdf-parse": "^2.3.0",
|
||||
"uuid": "^9.0.1",
|
||||
"zod-validation-error": "^4.0.1"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { v4 as uuid } from 'uuid'
|
||||
const WITHOUT_PROJECTS_USER = 'user-without-projects@example.com'
|
||||
const REGULAR_USER = 'user@example.com'
|
||||
|
||||
describe('Project List', () => {
|
||||
describe('Project List', function () {
|
||||
if (isExcludedBySharding('PRO_DEFAULT_2')) return
|
||||
startWith({ pro: true })
|
||||
|
||||
@@ -15,10 +15,10 @@ describe('Project List', () => {
|
||||
return cy.findByText(projectName).parent().parent()
|
||||
}
|
||||
|
||||
describe('user with no projects', () => {
|
||||
describe('user with no projects', function () {
|
||||
ensureUserExists({ email: WITHOUT_PROJECTS_USER })
|
||||
|
||||
it("'Import from GitHub' is not displayed in the welcome page", () => {
|
||||
it("'Import from GitHub' is not displayed in the welcome page", function () {
|
||||
login(WITHOUT_PROJECTS_USER)
|
||||
cy.visit('/project')
|
||||
cy.findByRole('button', { name: 'Create a new project' }).click()
|
||||
@@ -28,11 +28,11 @@ describe('Project List', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('user with projects', () => {
|
||||
describe('user with projects', function () {
|
||||
const projectName = `test-project-${uuid()}`
|
||||
ensureUserExists({ email: REGULAR_USER })
|
||||
|
||||
before(() => {
|
||||
before(function () {
|
||||
login(REGULAR_USER)
|
||||
createProject(projectName, { type: 'Example project', open: false })
|
||||
})
|
||||
@@ -41,7 +41,7 @@ describe('Project List', () => {
|
||||
cy.visit('/project')
|
||||
})
|
||||
|
||||
it('Can download project sources', () => {
|
||||
it('Can download project sources', function () {
|
||||
findProjectRow(projectName).within(() =>
|
||||
cy.findByRole('button', { name: 'Download .zip file' }).click()
|
||||
)
|
||||
@@ -53,7 +53,7 @@ describe('Project List', () => {
|
||||
}).should('contain', 'Your introduction goes here')
|
||||
})
|
||||
|
||||
it('Can download project PDF', () => {
|
||||
it('Can download project PDF', function () {
|
||||
findProjectRow(projectName).within(() =>
|
||||
cy.findByRole('button', { name: 'Download PDF' }).click()
|
||||
)
|
||||
@@ -65,7 +65,7 @@ describe('Project List', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('can assign and remove tags to projects', () => {
|
||||
it('can assign and remove tags to projects', function () {
|
||||
const tagName = uuid().slice(0, 7) // long tag names are truncated in the UI, which affects selectors
|
||||
cy.log('select project')
|
||||
cy.findByRole('checkbox', { name: `Select ${projectName}` }).check()
|
||||
@@ -88,7 +88,7 @@ describe('Project List', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('can filter by tag', () => {
|
||||
it('can filter by tag', function () {
|
||||
cy.log('create a separate project to filter')
|
||||
const nonTaggedProjectName = `project-${uuid()}`
|
||||
createProject(nonTaggedProjectName, { open: false })
|
||||
|
||||
@@ -27,13 +27,13 @@ describe('Project Sharing', function () {
|
||||
let projectName: string
|
||||
let recompile: () => void
|
||||
let waitForCompile: (triggerCompile: () => void) => void
|
||||
beforeWithReRunOnTestRetry(function () {
|
||||
beforeWithReRunOnTestRetry(() => {
|
||||
projectName = getSpamSafeProjectName()
|
||||
;({ recompile, waitForCompile } = prepareWaitForNextCompileSlot())
|
||||
setupTestProject()
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(function () {
|
||||
// Always start with a fresh session
|
||||
cy.session([uuid()], () => {})
|
||||
})
|
||||
@@ -245,22 +245,22 @@ describe('Project Sharing', function () {
|
||||
shareProjectByEmailAndAcceptInviteViaEmail(projectName, email, 'Viewer')
|
||||
})
|
||||
|
||||
it('should grant the collaborator read access', () => {
|
||||
it('should grant the collaborator read access', function () {
|
||||
expectFullReadOnlyAccess()
|
||||
expectProjectDashboardEntry()
|
||||
})
|
||||
})
|
||||
|
||||
describe('read only', () => {
|
||||
describe('read only', function () {
|
||||
const email = 'collaborator-ro@example.com'
|
||||
ensureUserExists({ email })
|
||||
|
||||
beforeWithReRunOnTestRetry(function () {
|
||||
beforeWithReRunOnTestRetry(() => {
|
||||
login('user@example.com')
|
||||
shareProjectByEmailAndAcceptInviteViaDash(projectName, email, 'Viewer')
|
||||
})
|
||||
|
||||
it('should grant the collaborator read access', () => {
|
||||
it('should grant the collaborator read access', function () {
|
||||
login(email)
|
||||
openProjectByName(projectName)
|
||||
expectFullReadOnlyAccess()
|
||||
@@ -268,16 +268,16 @@ describe('Project Sharing', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('read and write', () => {
|
||||
describe('read and write', function () {
|
||||
const email = 'collaborator-rw@example.com'
|
||||
ensureUserExists({ email })
|
||||
|
||||
beforeWithReRunOnTestRetry(function () {
|
||||
beforeWithReRunOnTestRetry(() => {
|
||||
login('user@example.com')
|
||||
shareProjectByEmailAndAcceptInviteViaDash(projectName, email, 'Editor')
|
||||
})
|
||||
|
||||
it('should grant the collaborator write access', () => {
|
||||
it('should grant the collaborator write access', function () {
|
||||
login(email)
|
||||
openProjectByName(projectName)
|
||||
expectFullReadAndWriteAccess()
|
||||
@@ -286,13 +286,13 @@ describe('Project Sharing', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('token access', () => {
|
||||
describe('logged in', () => {
|
||||
describe('read only', () => {
|
||||
describe('token access', function () {
|
||||
describe('logged in', function () {
|
||||
describe('read only', function () {
|
||||
const email = 'collaborator-link-ro@example.com'
|
||||
ensureUserExists({ email })
|
||||
|
||||
it('should grant restricted read access', () => {
|
||||
it('should grant restricted read access', function () {
|
||||
login(email)
|
||||
openProjectViaLinkSharingAsUser(
|
||||
linkSharingReadOnly,
|
||||
@@ -304,11 +304,11 @@ describe('Project Sharing', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('read and write', () => {
|
||||
describe('read and write', function () {
|
||||
const email = 'collaborator-link-rw@example.com'
|
||||
ensureUserExists({ email })
|
||||
|
||||
it('should grant full write access', () => {
|
||||
it('should grant full write access', function () {
|
||||
login(email)
|
||||
openProjectViaLinkSharingAsUser(
|
||||
linkSharingReadAndWrite,
|
||||
@@ -322,8 +322,8 @@ describe('Project Sharing', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('with OVERLEAF_ALLOW_PUBLIC_ACCESS=false', () => {
|
||||
describe('wrap startup', () => {
|
||||
describe('with OVERLEAF_ALLOW_PUBLIC_ACCESS=false', function () {
|
||||
describe('wrap startup', function () {
|
||||
startWith({
|
||||
pro: true,
|
||||
vars: {
|
||||
@@ -331,12 +331,12 @@ describe('Project Sharing', function () {
|
||||
},
|
||||
withDataDir: true,
|
||||
})
|
||||
it('should block access', () => {
|
||||
it('should block access', function () {
|
||||
expectNoAccess()
|
||||
})
|
||||
})
|
||||
|
||||
describe('with OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING=true', () => {
|
||||
describe('with OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING=true', function () {
|
||||
startWith({
|
||||
pro: true,
|
||||
vars: {
|
||||
@@ -345,14 +345,14 @@ describe('Project Sharing', function () {
|
||||
},
|
||||
withDataDir: true,
|
||||
})
|
||||
it('should block access', () => {
|
||||
it('should block access', function () {
|
||||
expectNoAccess()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with OVERLEAF_ALLOW_PUBLIC_ACCESS=true', () => {
|
||||
describe('wrap startup', () => {
|
||||
describe('with OVERLEAF_ALLOW_PUBLIC_ACCESS=true', function () {
|
||||
describe('wrap startup', function () {
|
||||
startWith({
|
||||
pro: true,
|
||||
vars: {
|
||||
@@ -360,18 +360,18 @@ describe('Project Sharing', function () {
|
||||
},
|
||||
withDataDir: true,
|
||||
})
|
||||
it('should grant read access with read link', () => {
|
||||
it('should grant read access with read link', function () {
|
||||
openProjectViaLinkSharingAsAnon(linkSharingReadOnly)
|
||||
expectRestrictedReadOnlyAccess()
|
||||
})
|
||||
|
||||
it('should prompt for login with write link', () => {
|
||||
it('should prompt for login with write link', function () {
|
||||
cy.visit(linkSharingReadAndWrite)
|
||||
cy.url().should('match', /\/login/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING=true', () => {
|
||||
describe('with OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING=true', function () {
|
||||
startWith({
|
||||
pro: true,
|
||||
vars: {
|
||||
@@ -381,12 +381,12 @@ describe('Project Sharing', function () {
|
||||
withDataDir: true,
|
||||
})
|
||||
|
||||
it('should grant read access with read link', () => {
|
||||
it('should grant read access with read link', function () {
|
||||
openProjectViaLinkSharingAsAnon(linkSharingReadOnly)
|
||||
expectRestrictedReadOnlyAccess()
|
||||
})
|
||||
|
||||
it('should grant write access with write link', () => {
|
||||
it('should grant write access with write link', function () {
|
||||
openProjectViaLinkSharingAsAnon(linkSharingReadAndWrite)
|
||||
expectAnonymousReadAndWriteAccess()
|
||||
expectEditAuthoredAs('Anonymous')
|
||||
@@ -394,7 +394,7 @@ describe('Project Sharing', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('with OVERLEAF_DISABLE_LINK_SHARING=true', () => {
|
||||
describe('with OVERLEAF_DISABLE_LINK_SHARING=true', function () {
|
||||
const email = 'collaborator-email@example.com'
|
||||
ensureUserExists({ email })
|
||||
|
||||
@@ -448,14 +448,14 @@ describe('Project Sharing', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('should not display link sharing in the sharing modal', () => {
|
||||
it('should not display link sharing in the sharing modal', function () {
|
||||
login('user@example.com')
|
||||
openProjectByName(projectName)
|
||||
cy.findByText('Share').click()
|
||||
cy.findByText('Turn on link sharing').should('not.exist')
|
||||
})
|
||||
|
||||
it('should block new access to read-only link shared projects', () => {
|
||||
it('should block new access to read-only link shared projects', function () {
|
||||
login(email)
|
||||
|
||||
// Test read-only link returns 404
|
||||
@@ -467,7 +467,7 @@ describe('Project Sharing', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('should block new access to read-write link shared projects', () => {
|
||||
it('should block new access to read-write link shared projects', function () {
|
||||
login(email)
|
||||
|
||||
// Test read-write link returns 404
|
||||
@@ -479,7 +479,7 @@ describe('Project Sharing', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('should continue to allow email sharing', () => {
|
||||
it('should continue to allow email sharing', function () {
|
||||
login('user@example.com')
|
||||
shareProjectByEmailAndAcceptInviteViaEmail(
|
||||
projectName,
|
||||
@@ -490,14 +490,14 @@ describe('Project Sharing', function () {
|
||||
expectProjectDashboardEntry()
|
||||
})
|
||||
|
||||
it('should retain read-only access when project was joined via link before link sharing was turned off', () => {
|
||||
it('should retain read-only access when project was joined via link before link sharing was turned off', function () {
|
||||
login(retainedViewerEmail)
|
||||
openProjectByName(projectName)
|
||||
expectRestrictedReadOnlyAccess()
|
||||
expectProjectDashboardEntry()
|
||||
})
|
||||
|
||||
it('should retain read-write access when project was joined via link before link sharing was turned off', () => {
|
||||
it('should retain read-write access when project was joined via link before link sharing was turned off', function () {
|
||||
login(retainedEditorEmail)
|
||||
openProjectByName(projectName)
|
||||
expectFullReadAndWriteAccess()
|
||||
|
||||
@@ -156,6 +156,7 @@ describe('SandboxedCompiles', function () {
|
||||
// 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 :/
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(1000)
|
||||
cy.findByRole('button', {
|
||||
name: 'Go to PDF location in code (Tip: double click on the PDF for best results)',
|
||||
@@ -309,6 +310,7 @@ describe('SandboxedCompiles', function () {
|
||||
})
|
||||
|
||||
// https://github.com/overleaf/internal/issues/20216
|
||||
// eslint-disable-next-line mocha/no-skipped-tests
|
||||
describe.skip('unavailable in CE', function () {
|
||||
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||
startWith({ pro: false, vars: enabledVars, resetData: true })
|
||||
|
||||
@@ -10,7 +10,7 @@ const TEMPLATES_USER = 'templates@example.com'
|
||||
// Re-use value for "exists" and "does not exist" tests
|
||||
const LABEL_BROWSE_TEMPLATES = 'Browse templates'
|
||||
|
||||
describe('Templates', () => {
|
||||
describe('Templates', function () {
|
||||
ensureUserExists({ email: TEMPLATES_USER })
|
||||
ensureUserExists({ email: WITHOUT_PROJECTS_USER })
|
||||
|
||||
@@ -31,7 +31,7 @@ describe('Templates', () => {
|
||||
}
|
||||
}
|
||||
|
||||
describe('enabled in Server Pro', () => {
|
||||
describe('enabled in Server Pro', function () {
|
||||
if (isExcludedBySharding('PRO_CUSTOM_2')) return
|
||||
startWith({
|
||||
pro: true,
|
||||
@@ -40,7 +40,7 @@ describe('Templates', () => {
|
||||
ensureUserExists({ email: REGULAR_USER })
|
||||
ensureUserExists({ email: ADMIN_USER, isAdmin: true })
|
||||
|
||||
it('should show templates link on welcome page', () => {
|
||||
it('should show templates link on welcome page', function () {
|
||||
login(WITHOUT_PROJECTS_USER)
|
||||
cy.visit('/')
|
||||
cy.findByRole('link', { name: LABEL_BROWSE_TEMPLATES })
|
||||
@@ -49,7 +49,7 @@ describe('Templates', () => {
|
||||
cy.url().should('match', /\/templates$/)
|
||||
})
|
||||
|
||||
it('should have templates feature', () => {
|
||||
it('should have templates feature', function () {
|
||||
login(TEMPLATES_USER)
|
||||
const name = `Template ${Date.now()}`
|
||||
const description = `Template Description ${Date.now()}`
|
||||
@@ -64,11 +64,8 @@ describe('Templates', () => {
|
||||
.click()
|
||||
cy.findByText('Manage Template').click()
|
||||
|
||||
cy.findByText('Template Description')
|
||||
.click()
|
||||
.parent()
|
||||
.get('textarea')
|
||||
.type(description)
|
||||
cy.findByText('Template Description').as('description').click()
|
||||
cy.get('@description').parent().get('textarea').type(description)
|
||||
cy.findByText('Publish').click()
|
||||
cy.findByText('Publishing…').parent().should('be.disabled')
|
||||
cy.findByText('Publish').should('not.exist')
|
||||
@@ -229,7 +226,7 @@ describe('Templates', () => {
|
||||
})
|
||||
|
||||
function checkDisabled() {
|
||||
it('should not have templates feature', () => {
|
||||
it('should not have templates feature', function () {
|
||||
login(TEMPLATES_USER)
|
||||
|
||||
cy.visit('/')
|
||||
@@ -254,7 +251,7 @@ describe('Templates', () => {
|
||||
cy.findAllByText('All Templates').should('not.exist')
|
||||
})
|
||||
|
||||
it('should not show templates link on welcome page', () => {
|
||||
it('should not show templates link on welcome page', function () {
|
||||
login(WITHOUT_PROJECTS_USER)
|
||||
cy.visit('/')
|
||||
cy.findByText(NEW_PROJECT_BUTTON_MATCHER) // wait for lazy loading
|
||||
@@ -262,13 +259,13 @@ describe('Templates', () => {
|
||||
})
|
||||
}
|
||||
|
||||
describe('disabled Server Pro', () => {
|
||||
describe('disabled Server Pro', function () {
|
||||
if (isExcludedBySharding('PRO_DEFAULT_2')) return
|
||||
startWith({ pro: true })
|
||||
checkDisabled()
|
||||
})
|
||||
|
||||
describe('unavailable in CE', () => {
|
||||
describe('unavailable in CE', function () {
|
||||
if (isExcludedBySharding('CE_CUSTOM_1')) return
|
||||
startWith({
|
||||
pro: false,
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||
"skipLibCheck": true /* Skip type checking of declaration files. */,
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
|
||||
"types": ["cypress", "node", "@testing-library/cypress"]
|
||||
"types": ["cypress", "node", "@testing-library/cypress"],
|
||||
"allowImportingTsExtensions": true
|
||||
},
|
||||
"include": ["**/*.ts", "**/*.tsx"]
|
||||
"include": ["**/*.ts", "**/*.js"]
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ describe('Upgrading', function () {
|
||||
) {
|
||||
const startOptions = steps.shift()!
|
||||
|
||||
before(async () => {
|
||||
before(async function () {
|
||||
cy.log('Create old instance')
|
||||
})
|
||||
startWith({
|
||||
@@ -38,7 +38,7 @@ describe('Upgrading', function () {
|
||||
cy.log('Create initial user after deleting it')
|
||||
})
|
||||
ensureUserExists({ email: USER })
|
||||
before(() => {
|
||||
before(function () {
|
||||
cy.log('Populate old instance')
|
||||
login(USER)
|
||||
;({ recompile, waitForCompile } = prepareWaitForNextCompileSlot())
|
||||
@@ -76,12 +76,12 @@ describe('Upgrading', function () {
|
||||
}
|
||||
cy.findByText('History').click()
|
||||
for (let i = 0; i < 3; i++) {
|
||||
cy.findByText(new RegExp(`\\\\section\{Old Section ${i}}`))
|
||||
cy.findByText(new RegExp(`\\\\section{Old Section ${i}}`))
|
||||
}
|
||||
})
|
||||
|
||||
for (const step of steps) {
|
||||
before(() => {
|
||||
before(function () {
|
||||
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)
|
||||
@@ -113,16 +113,16 @@ describe('Upgrading', function () {
|
||||
|
||||
step.hook?.()
|
||||
}
|
||||
beforeEach(() => {
|
||||
beforeEach(function () {
|
||||
login(USER)
|
||||
})
|
||||
|
||||
it('should list the old project', () => {
|
||||
it('should list the old project', function () {
|
||||
cy.visit('/project')
|
||||
cy.findByText(PROJECT_NAME)
|
||||
})
|
||||
|
||||
it('should open the old project', () => {
|
||||
it('should open the old project', function () {
|
||||
waitForCompile(() => {
|
||||
openProjectByName(PROJECT_NAME)
|
||||
})
|
||||
@@ -174,21 +174,21 @@ describe('Upgrading', function () {
|
||||
})
|
||||
},
|
||||
}
|
||||
describe('from 4.2 to latest', () => {
|
||||
describe('from 4.2 to latest', function () {
|
||||
testUpgrade([
|
||||
optionsFourDotTwo,
|
||||
optionsBinaryFilesMigration,
|
||||
{ version: 'latest' },
|
||||
])
|
||||
})
|
||||
describe('from 5.0 to latest', () => {
|
||||
describe('from 5.0 to latest', function () {
|
||||
testUpgrade([
|
||||
{ version: '5.0' },
|
||||
optionsBinaryFilesMigration,
|
||||
{ version: 'latest' },
|
||||
])
|
||||
})
|
||||
describe('doc version recovery', () => {
|
||||
describe('doc version recovery', function () {
|
||||
testUpgrade([
|
||||
optionsFourDotTwo,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user