[web] add junit integration for Jenkins (#28788)

* [web] add junit integration for Jenkins

* [web] integrate junit test report for writefull into Jenkins

* [web] put all the junit test results into namespaces

GitOrigin-RevId: ba1ff07b5ea7bcfa97bb4d6bf7fa9e5291ab7b0f
This commit is contained in:
Jakob Ackermann
2025-10-02 09:28:09 +02:00
committed by Copybot
parent e8bc186ca0
commit c3c04acfea
13 changed files with 194 additions and 262 deletions
+20
View File
@@ -37047,6 +37047,23 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mocha-multi-reporters": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/mocha-multi-reporters/-/mocha-multi-reporters-1.5.1.tgz",
"integrity": "sha512-Yb4QJOaGLIcmB0VY7Wif5AjvLMUFAdV57D2TWEva1Y0kU/3LjKpeRVmlMIfuO1SVbauve459kgtIizADqxMWPg==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.1.1",
"lodash": "^4.17.15"
},
"engines": {
"node": ">=6.0.0"
},
"peerDependencies": {
"mocha": ">=3.1.2"
}
},
"node_modules/mocha/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@@ -52717,6 +52734,7 @@
"css-loader": "^6.8.1",
"css-minimizer-webpack-plugin": "^5.0.1",
"cypress": "13.13.2",
"cypress-multi-reporters": "^2.0.5",
"cypress-plugin-tab": "^1.0.5",
"d3": "^3.5.16",
"daterangepicker": "2.1.27",
@@ -52758,6 +52776,8 @@
"mini-css-extract-plugin": "^2.7.6",
"mocha": "^11.1.0",
"mocha-each": "^2.0.1",
"mocha-junit-reporter": "^2.2.1",
"mocha-multi-reporters": "^1.5.1",
"mock-fs": "^5.1.2",
"nock": "^13.5.6",
"nvd3": "^1.8.6",
+8
View File
@@ -0,0 +1,8 @@
let reporterOptions = {}
if (process.env.CI && process.env.MOCHA_ROOT_SUITE_NAME) {
reporterOptions = {
reporter: '/overleaf/node_modules/mocha-multi-reporters',
'reporter-options': ['configFile=./test/mocha-multi-reporters.js'],
}
}
module.exports = reporterOptions
+58 -253
View File
@@ -1,17 +1,3 @@
// Initialize variables to signal that a given stage finished.
// We use them to build a graph of interconnected steps/dependencies.
// - Incoming edges use "waitUntil" and reference the given variables of dependencies.
// - Outgoing edges set the given variable to true.
def action_test_frontend_ct_build = false
def action_build_deps = false
def action_copy_external_pages = false
def action_build_dev = false
def action_test_acceptance_app_server_pro = false
def action_build_webpack = false
def action_test_acceptance_app_saas = false
def action_build_pug = false
def action_build_production = false
pipeline {
agent {
node {
@@ -24,8 +10,6 @@ pipeline {
options {
// Print timestamp next to each log line.
timestamps()
// Abort build after hitting first failure.
parallelsAlwaysFailFast()
retry(3)
timeout(time: 15, unit: 'MINUTES')
}
@@ -45,34 +29,8 @@ pipeline {
CDN_PROD = "gs://mgcp-1117973-ol-prod-web-assets-1"
}
stages {
// Retries will use the same pipeline instance. Reset the vars.
stage('Reset vars') {
steps {
script {
action_test_frontend_ct_build = false
action_build_deps = false
action_copy_external_pages = false
action_build_dev = false
action_test_acceptance_app_server_pro = false
action_build_webpack = false
action_test_acceptance_app_saas = false
action_build_pug = false
action_build_production = false
}
}
}
stage ('Build, Test and Push') {
stage('Stage 1') {
parallel {
stage('Copy external pages') {
steps {
dir('services/web') {
sh 'bin/copy_external_pages'
script {
action_copy_external_pages = true
}
}
}
}
stage('Prefetch Tests Images') {
steps {
dir('services/web') {
@@ -80,50 +38,29 @@ pipeline {
}
}
}
stage('Build Deps') {
stage('Build') {
steps {
dir('services/web') {
sh 'bin/copy_external_pages'
sh 'make build_deps'
}
script {
action_build_deps = true
sh 'make build_dev'
sh 'make build_test_frontend_ct'
}
}
}
}
}
stage('Stage 2') {
parallel {
stage('Push Deps') {
steps {
script {
waitUntil {
return action_build_deps
}
}
dir('services/web') {
sh 'docker push ${AR_URL}/${IMAGE_NAME}:${BRANCH_NAME}-deps'
}
}
}
stage('Build Dev') {
stage('Format') {
steps {
script {
waitUntil {
return action_build_deps && action_copy_external_pages
}
}
dir('services/web') {
sh 'make build_dev'
}
script {
action_build_dev = true
}
}
}
stage ('Format') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh 'make format_in_docker'
}
@@ -131,15 +68,16 @@ pipeline {
}
stage('Lint') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh 'make lint_in_docker'
}
}
post {
always {
recordIssues checksAnnotationScope: 'ALL', enabledForFailure: true, failOnError: true, id: 'web-eslint', name: 'Web eslint', qualityGates: [[integerThreshold: 1, threshold: 1.0, type: 'TOTAL']], sourceCodeRetention: 'LAST_BUILD', tools: [esLint(pattern: 'services/web/data/reports/eslint.json')]
recordIssues checksAnnotationScope: 'ALL', enabledForFailure: true, failOnError: true, id: 'web-stylelint', name: 'Web stylelint', qualityGates: [[integerThreshold: 1, threshold: 1.0, type: 'TOTAL']], sourceCodeRetention: 'LAST_BUILD', tools: [styleLint(pattern: 'services/web/data/reports/stylelint.json')]
}
}
}
stage('Shellcheck') {
steps {
@@ -150,26 +88,13 @@ pipeline {
}
stage('Acceptance SaaS') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh 'make test_acceptance_app_saas'
}
script {
action_test_acceptance_app_saas = true
}
}
}
stage('Acceptance Server CE') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_acceptance_app_server_ce"
}
@@ -177,26 +102,13 @@ pipeline {
}
stage('Acceptance Server Pro') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_acceptance_app_server_pro"
}
script {
action_test_acceptance_app_server_pro = true
}
}
}
stage('test_acceptance_modules_merged_saas_1') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_acceptance_modules_merged_saas_1"
}
@@ -204,11 +116,6 @@ pipeline {
}
stage('test_acceptance_modules_merged_saas_2') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_acceptance_modules_merged_saas_2"
}
@@ -216,11 +123,6 @@ pipeline {
}
stage('test_acceptance_modules_merged_saas_3') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_acceptance_modules_merged_saas_3"
}
@@ -228,11 +130,6 @@ pipeline {
}
stage('test_acceptance_modules_merged_saas_4') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_acceptance_modules_merged_saas_4"
}
@@ -240,11 +137,6 @@ pipeline {
}
stage('test_acceptance_modules_merged_server_ce') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_acceptance_modules_merged_server_ce"
}
@@ -252,11 +144,6 @@ pipeline {
}
stage('test_acceptance_modules_merged_server_pro') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_acceptance_modules_merged_server_pro"
}
@@ -264,11 +151,6 @@ pipeline {
}
stage('test_frontend') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_frontend"
}
@@ -276,41 +158,16 @@ pipeline {
}
stage('test_writefull') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_writefull"
}
}
}
stage('test_frontend_ct_build') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make build_test_frontend_ct"
}
script {
action_test_frontend_ct_build = true
}
}
}
stage('test_frontend_ct_core_other') {
environment {
CYPRESS_INTERNAL_BROWSER_CONNECT_TIMEOUT = '120000'
}
steps {
script {
waitUntil {
return action_test_frontend_ct_build
}
}
dir('services/web') {
sh "make test_frontend_ct_core_other"
}
@@ -321,11 +178,6 @@ pipeline {
CYPRESS_INTERNAL_BROWSER_CONNECT_TIMEOUT = '120000'
}
steps {
script {
waitUntil {
return action_test_frontend_ct_build
}
}
dir('services/web') {
sh "make test_frontend_ct_core_features"
}
@@ -336,11 +188,6 @@ pipeline {
CYPRESS_INTERNAL_BROWSER_CONNECT_TIMEOUT = '120000'
}
steps {
script {
waitUntil {
return action_test_frontend_ct_build
}
}
dir('services/web') {
sh "make test_frontend_ct_modules"
}
@@ -348,11 +195,6 @@ pipeline {
}
stage('test_frontend_ct_editor_visual') {
steps {
script {
waitUntil {
return action_test_frontend_ct_build
}
}
dir('services/web') {
sh "make test_frontend_ct_editor_visual"
}
@@ -360,11 +202,6 @@ pipeline {
}
stage('test_frontend_ct_editor_other') {
steps {
script {
waitUntil {
return action_test_frontend_ct_build
}
}
dir('services/web') {
sh "make test_frontend_ct_editor_other"
}
@@ -372,11 +209,6 @@ pipeline {
}
stage('Test Unit ESM') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_unit_esm"
}
@@ -384,90 +216,60 @@ pipeline {
}
stage('Test Unit Mocha') {
steps {
script {
waitUntil {
return action_build_dev
}
}
dir('services/web') {
sh "make test_unit_mocha"
}
}
}
stage('Build Webpack') {
steps {
script {
waitUntil {
return action_build_dev && action_test_acceptance_app_server_pro
stage('Build webpack + production + cdn upload + sentry upload') {
stages {
stage('Wait a bit to give tests all the CPU capacity') {
steps {
sh 'sleep 120'
}
}
dir('services/web') {
sh 'make build_webpack'
}
script {
action_build_webpack = true
}
}
}
stage('Build Pug') {
steps {
script {
waitUntil {
return action_build_dev && action_test_acceptance_app_server_pro
stage('Build Webpack') {
steps {
dir('services/web') {
sh 'make build_webpack'
}
}
}
dir('services/web') {
sh 'make build_pug'
}
script {
action_build_pug = true
}
}
}
stage('CDN Upload Image') {
steps {
script {
waitUntil {
return action_build_webpack
stage('Build Pug') {
steps {
dir('services/web') {
sh 'make build_pug'
}
}
}
dir('services/web') {
sh 'make tar'
sh 'bin/cdn_upload'
}
}
}
stage('Build Production') {
steps {
script {
waitUntil {
return action_build_webpack && action_build_pug
stage('CDN Upload Image') {
steps {
dir('services/web') {
sh 'make tar'
sh 'bin/cdn_upload'
}
}
}
dir('services/web') {
sh 'make build'
}
script {
action_build_production = true
}
}
}
stage('Sentry Upload') {
steps {
script {
waitUntil {
return action_build_webpack && action_build_production
stage('Build Production') {
steps {
dir('services/web') {
sh 'make build'
}
}
}
dir('services/web') {
sh 'gcloud secrets versions access latest --secret=web-sentryclirc > .sentryclirc'
sh 'make sentry_upload'
}
}
post {
cleanup {
dir('services/web') {
sh 'rm -f .sentryclirc'
stage('Sentry Upload') {
steps {
dir('services/web') {
sh 'gcloud secrets versions access latest --secret=web-sentryclirc > .sentryclirc'
sh 'make sentry_upload'
}
}
post {
cleanup {
dir('services/web') {
sh 'rm -f .sentryclirc'
}
}
}
}
}
@@ -483,6 +285,9 @@ pipeline {
}
}
post {
always {
junit checksName: 'Web test results', testResults: 'services/web/data/reports/junit-*.xml'
}
// Ensure tear down of test containers, then run general Jenkins VM cleanup.
cleanup {
dir('services/web') {
+25 -3
View File
@@ -6,6 +6,7 @@ export COMMIT_SHA ?= $(shell git rev-parse HEAD)
PROJECT_NAME = web
BUILD_DIR_NAME = $(shell pwd | xargs basename | tr -cd '[a-zA-Z0-9_.\-]')
PWD = $(shell pwd)
export MONOREPO ?= $(shell cd ../../ && pwd)
export OVERLEAF_CONFIG ?= /overleaf/services/web/test/acceptance/config/settings.test.saas.js
export BASE_CONFIG ?= ${OVERLEAF_CONFIG}
@@ -60,6 +61,7 @@ SHARD_PROJECT_NAMES = \
CLEAN_SHARDS=$(addprefix clean/,$(SHARD_PROJECT_NAMES))
clean: $(CLEAN_SHARDS)
-docker run --rm --volume /dev/shm:/dev/shm --user root $(IMAGE_CI) rm -rf /dev/shm/overleaf
-docker rmi --force $(IMAGE_CI) $(IMAGE_CI)-dev $(IMAGE_CI)-pug $(IMAGE_CI)-webpack $(IMAGE_REPO_FINAL)
-docker compose down --remove-orphans --rmi local --timeout 0 --volumes
-git clean -dfX data/
@@ -98,10 +100,12 @@ test_unit_app: export COMPOSE_PROJECT_NAME=unit_test_$(BUILD_DIR_NAME)
test_unit_app: mongo_migrations_for_tests
$(DOCKER_COMPOSE) run --name unit_test_$(BUILD_DIR_NAME) --rm test_unit
test_unit_mocha: export MOCHA_ROOT_SUITE_NAME = Mocha unit tests
test_unit_mocha: export COMPOSE_PROJECT_NAME=unit_test_mocha_$(BUILD_DIR_NAME)
test_unit_mocha: mongo_migrations_for_tests
$(DOCKER_COMPOSE) run --rm test_unit npm run test:unit:mocha
test_unit_esm: export MOCHA_ROOT_SUITE_NAME = ESM unit tests
test_unit_esm: export COMPOSE_PROJECT_NAME=unit_test_esm_$(BUILD_DIR_NAME)
test_unit_esm: mongo_migrations_for_tests
$(DOCKER_COMPOSE) run --rm test_unit npm run test:unit:esm
@@ -148,6 +152,7 @@ mongo_migrations_for_tests:
# Frontend tests
#
test_frontend: export MOCHA_ROOT_SUITE_NAME = JSDOM frontend tests
test_frontend:
COMPOSE_PROJECT_NAME=frontend_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) run --rm test_frontend
COMPOSE_PROJECT_NAME=frontend_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) down -v -t 0
@@ -169,13 +174,14 @@ TEST_FRONTEND_CT_VARIANTS = \
# Writefull tests
#
test_writefull: export MOCHA_ROOT_SUITE_NAME = Writefull tests
test_writefull:
COMPOSE_PROJECT_NAME=writefull_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) run --rm test_writefull
COMPOSE_PROJECT_NAME=writefull_test_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) down -v -t 0
# Note: The below cypress targets are for CI only
build_test_frontend_ct:
docker run --rm --volume /dev/shm:/dev/shm --user root $(IMAGE_CI) bash -ec 'tar -cC / overleaf | tar -xC /dev/shm'
docker run --rm --volume /dev/shm:/dev/shm --user root $(IMAGE_CI) bash -ec 'for path in /overleaf/services/web/cypress/results /overleaf/services/web/node_modules/.cache; do mkdir -p $$path; chown -R node:node $$path; done && tar -cC / overleaf | tar -xC /dev/shm'
test_frontend_ct_core_other: export CYPRESS_RESULTS=./cypress/results/core
test_frontend_ct_core_other: export CYPRESS_SPEC_PATTERN=./test/frontend/**/*.spec.{js,jsx,ts,tsx}
@@ -214,10 +220,13 @@ TEST_ACCEPTANCE_APP := \
test_acceptance_app_server_pro \
test_acceptance_app: $(TEST_ACCEPTANCE_APP)
test_acceptance_app_saas: export MOCHA_ROOT_SUITE_NAME = SaaS app acceptance tests
test_acceptance_app_saas: export COMPOSE_PROJECT_NAME=acceptance_test_saas_$(BUILD_DIR_NAME)
test_acceptance_app_saas: export OVERLEAF_CONFIG=$(CFG_SAAS)
test_acceptance_app_server_ce: export MOCHA_ROOT_SUITE_NAME = Server CE app acceptance tests
test_acceptance_app_server_ce: export COMPOSE_PROJECT_NAME=acceptance_test_server_ce_$(BUILD_DIR_NAME)
test_acceptance_app_server_ce: export OVERLEAF_CONFIG=$(CFG_SERVER_CE)
test_acceptance_app_server_pro: export MOCHA_ROOT_SUITE_NAME = Server Pro app acceptance tests
test_acceptance_app_server_pro: export COMPOSE_PROJECT_NAME=acceptance_test_server_pro_$(BUILD_DIR_NAME)
test_acceptance_app_server_pro: export OVERLEAF_CONFIG=$(CFG_SERVER_PRO)
@@ -349,14 +358,17 @@ $(TEST_ACCEPTANCE_MODULES_MERGED_INNER_SPLIT):
)
# See docs for test_acceptance_server_ce how this works.
test_acceptance_modules_merged_saas: export MOCHA_ROOT_SUITE_NAME = SaaS modules acceptance tests
test_acceptance_modules_merged_saas: export COMPOSE_PROJECT_NAME = \
acceptance_test_modules_merged_saas_$(BUILD_DIR_NAME)
test_acceptance_modules_merged_saas: export BASE_CONFIG = $(CFG_SAAS)
test_acceptance_modules_merged_server_ce: export MOCHA_ROOT_SUITE_NAME = Server CE modules acceptance tests
test_acceptance_modules_merged_server_ce: export COMPOSE_PROJECT_NAME = \
acceptance_test_modules_merged_server_ce_$(BUILD_DIR_NAME)
test_acceptance_modules_merged_server_ce: export BASE_CONFIG = $(CFG_SERVER_CE)
test_acceptance_modules_merged_server_pro: export MOCHA_ROOT_SUITE_NAME = Server Pro modules acceptance tests
test_acceptance_modules_merged_server_pro: export COMPOSE_PROJECT_NAME = \
acceptance_test_modules_merged_server_pro_$(BUILD_DIR_NAME)
test_acceptance_modules_merged_server_pro: export BASE_CONFIG = $(CFG_SERVER_PRO)
@@ -388,6 +400,7 @@ test_acceptance_modules_merged_saas_3: export COMPOSE_PROJECT_NAME = \
test_acceptance_modules_merged_saas_4: export COMPOSE_PROJECT_NAME = \
acceptance_test_modules_merged_saas_4_$(BUILD_DIR_NAME)
$(TEST_ACCEPTANCE_MODULES_MERGED_SPLIT_SAAS): export BASE_CONFIG = $(CFG_SAAS)
$(TEST_ACCEPTANCE_MODULES_MERGED_SPLIT_SAAS): export MOCHA_ROOT_SUITE_NAME = SaaS modules acceptance tests
$(TEST_ACCEPTANCE_MODULES_MERGED_SPLIT_SAAS): test_acceptance_modules_merged_saas_%:
$(DOCKER_COMPOSE) run --rm test_acceptance make test_acceptance_modules_merged_inner_$*
@@ -408,7 +421,7 @@ ci:
#
ORG_PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
RUN_LINT_FORMAT ?= \
docker run --rm ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER)
docker run --rm --env BRANCH_NAME --env CI --env COMMIT_SHA --env MONOREPO --volume ${PWD}/data/reports:/overleaf/services/web/data/reports ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER)
NODE_MODULES_PATH := ${PATH}:${PWD}/node_modules/.bin:/overleaf/services/web/node_modules/.bin
WITH_NODE_MODULES_PATH = \
@@ -425,11 +438,21 @@ $(WITH_NODE_MODULES_PATH): export PATH=$(NODE_MODULES_PATH)
lint: lint_eslint
lint_eslint:
ifeq ($(CI),true)
-npm run lint -- --format json --output-file data/reports/eslint.json
sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' data/reports/eslint.json
else
npm run lint
endif
lint: lint_stylelint
lint_stylelint:
ifeq ($(CI),true)
-npm run lint:styles -- --formatter json --output-file data/reports/stylelint.json
sed -i 's_"source":"/overleaf_"source":"$(MONOREPO)_g' data/reports/stylelint.json
else
npm run lint:styles
endif
lint: lint_pug
lint_pug:
@@ -589,7 +612,6 @@ SENTRY_IMAGE=getsentry/sentry-cli:2.16.1
sentry_prefetch:
docker pull $(SENTRY_IMAGE)
sentry_upload: MONOREPO=$(shell cd ../../ && pwd)
sentry_upload:
docker run --rm \
--volume $(MONOREPO):$(MONOREPO) --workdir $(PWD) \
-1
View File
@@ -7,4 +7,3 @@ web
--esmock-loader=False
--node-version=22.18.0
--public-repo=False
--script-version=4.7.0
+13 -2
View File
@@ -1,11 +1,21 @@
import { defineConfig } from 'cypress'
import { webpackConfig } from './cypress/support/webpack.cypress'
let reporterOptions = {}
if (process.env.CI) {
reporterOptions = {
reporter: '/overleaf/node_modules/cypress-multi-reporters',
reporterOptions: {
configFile: 'cypress/cypress-multi-reporters.json',
},
}
}
export default defineConfig({
fixturesFolder: 'cypress/fixtures',
video: process.env.CYPRESS_VIDEO === 'true',
screenshotsFolder: 'cypress/results',
videosFolder: 'cypress/results',
screenshotsFolder: process.env.CYPRESS_RESULTS || 'cypress/results',
videosFolder: process.env.CYPRESS_RESULTS || 'cypress/results',
viewportHeight: 800,
viewportWidth: 800,
component: {
@@ -25,4 +35,5 @@ export default defineConfig({
retries: {
runMode: 3,
},
...reporterOptions,
})
@@ -0,0 +1,10 @@
{
"reporterEnabled": "spec, mocha-junit-reporter",
"mochaJunitReporterReporterOptions": {
"mochaFile": "data/reports/junit-cypress-[hash].xml",
"includePending": true,
"jenkinsMode": true,
"jenkinsClassnamePrefix": "Web Cypress tests",
"rootSuiteTitle": "Web Cypress tests"
}
}
+20 -3
View File
@@ -13,11 +13,14 @@ services:
user: node
volumes:
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
- ./data/reports:/overleaf/services/web/data/reports
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
command: npm run test:unit:app
working_dir: /overleaf/services/web
env_file: docker-compose.common.env
environment:
CI:
MOCHA_ROOT_SUITE_NAME:
BASE_CONFIG:
OVERLEAF_CONFIG:
NODE_ENV: test
@@ -38,6 +41,8 @@ services:
working_dir: /overleaf/services/web
env_file: docker-compose.common.env
environment:
CI:
MOCHA_ROOT_SUITE_NAME:
BASE_CONFIG:
OVERLEAF_CONFIG:
REDIS_HOST: redis_test
@@ -45,6 +50,7 @@ services:
- 'www.overleaf.test:127.0.0.1'
volumes:
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
- ./data/reports:/overleaf/services/web/data/reports
entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
command: npm run test:acceptance:app
user: root
@@ -61,6 +67,8 @@ services:
context: ../..
dockerfile: services/web/Dockerfile
image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER
volumes:
- ./data/reports:/overleaf/services/web/data/reports
logging:
driver: local
user: node
@@ -68,18 +76,23 @@ services:
command: npm run test:frontend
environment:
NODE_OPTIONS: "--unhandled-rejections=strict"
CI:
MOCHA_ROOT_SUITE_NAME:
test_frontend_ct:
image: cypress/included:13.13.2
logging:
driver: local
working_dir: /overleaf/services/web
user: "${DOCKER_USER:-1000:1000}"
environment:
CYPRESS_SPEC_PATTERN: ${CYPRESS_SPEC_PATTERN:-}
CYPRESS_EXCLUDE_SPEC_PATTERN: ${CYPRESS_EXCLUDE_SPEC_PATTERN:-}
CI:
CYPRESS_RESULTS:
CYPRESS_SPEC_PATTERN:
CYPRESS_EXCLUDE_SPEC_PATTERN:
volumes:
- ${CYPRESS_RESULTS:-./cypress/results}:/overleaf/services/web/cypress/results/
- /dev/shm/overleaf:/overleaf
- ./data/reports:/overleaf/services/web/data/reports
entrypoint: npm
command:
- "run"
@@ -95,7 +108,11 @@ services:
user: node
working_dir: /overleaf/services/web
command: npm run test:writefull
volumes:
- ./data/reports:/overleaf/services/web/data/reports
environment:
CI:
MOCHA_ROOT_SUITE_NAME:
NODE_OPTIONS: "--unhandled-rejections=strict"
tar:
+11
View File
@@ -15,6 +15,8 @@ services:
environment:
BASE_CONFIG:
OVERLEAF_CONFIG:
CI:
MOCHA_ROOT_SUITE_NAME:
MOCHA_GREP: ${MOCHA_GREP}
LOG_LEVEL: ${LOG_LEVEL:-}
NODE_ENV: test
@@ -40,6 +42,8 @@ services:
environment:
BASE_CONFIG:
OVERLEAF_CONFIG:
CI:
MOCHA_ROOT_SUITE_NAME:
MOCHA_GREP: ${MOCHA_GREP}
LOG_LEVEL: ${LOG_LEVEL:-}
MONGO_SERVER_SELECTION_TIMEOUT: 600000
@@ -68,6 +72,8 @@ services:
- ../../libraries:/overleaf/libraries
working_dir: /overleaf/services/web
environment:
CI:
MOCHA_ROOT_SUITE_NAME:
MOCHA_GREP: ${MOCHA_GREP}
NODE_OPTIONS: "--unhandled-rejections=strict"
VERBOSE_LOGGING:
@@ -79,8 +85,11 @@ services:
volumes:
- ../../:/overleaf
working_dir: /overleaf/services/web
user: "${DOCKER_USER:-1000:1000}"
environment:
VERBOSE_LOGGING:
CI:
MOCHA_ROOT_SUITE_NAME:
CYPRESS_SPEC_PATTERN: ${CYPRESS_SPEC_PATTERN:-}
CYPRESS_EXCLUDE_SPEC_PATTERN: ${CYPRESS_EXCLUDE_SPEC_PATTERN:-}
entrypoint: npm
@@ -99,6 +108,8 @@ services:
- ../../libraries:/overleaf/libraries
working_dir: /overleaf/services/web
environment:
CI:
MOCHA_ROOT_SUITE_NAME:
NODE_OPTIONS: "--unhandled-rejections=strict"
VERBOSE_LOGGING:
command: npm run --silent test:writefull
+3
View File
@@ -304,6 +304,7 @@
"css-loader": "^6.8.1",
"css-minimizer-webpack-plugin": "^5.0.1",
"cypress": "13.13.2",
"cypress-multi-reporters": "^2.0.5",
"cypress-plugin-tab": "^1.0.5",
"d3": "^3.5.16",
"daterangepicker": "2.1.27",
@@ -345,6 +346,8 @@
"mini-css-extract-plugin": "^2.7.6",
"mocha": "^11.1.0",
"mocha-each": "^2.0.1",
"mocha-junit-reporter": "^2.2.1",
"mocha-multi-reporters": "^1.5.1",
"mock-fs": "^5.1.2",
"nock": "^13.5.6",
"nvd3": "^1.8.6",
@@ -0,0 +1,10 @@
module.exports = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
mochaFile: 'data/reports/junit-mocha-[hash]-[suiteFilename].xml',
includePending: true,
jenkinsMode: true,
jenkinsClassnamePrefix: process.env.MOCHA_ROOT_SUITE_NAME,
rootSuiteTitle: process.env.MOCHA_ROOT_SUITE_NAME,
},
}
+16
View File
@@ -1,5 +1,20 @@
const { defineConfig } = require('vitest/config')
let reporterOptions = {}
if (process.env.CI && process.env.MOCHA_ROOT_SUITE_NAME) {
reporterOptions = {
reporters: [
'default',
[
'junit',
{
classnameTemplate: `${process.env.MOCHA_ROOT_SUITE_NAME}.{filename}`,
},
],
],
outputFile: 'data/reports/junit-vitest.xml',
}
}
module.exports = defineConfig({
test: {
include: [
@@ -9,5 +24,6 @@ module.exports = defineConfig({
setupFiles: ['./test/unit/vitest_bootstrap.mjs'],
globals: true,
isolate: false,
...reporterOptions,
},
})