diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..3de57a360 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +node_modules/ +dist/ +logs/ +.DS_Store +.git/ +config/local.json +pleroma-backend/ +test/e2e/reports/ +test/e2e-playwright/test-results/ +test/e2e-playwright/playwright-report/ +__screenshots__/ + diff --git a/.gitignore b/.gitignore index 01ffda9a8..085805753 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ dist/ npm-debug.log test/unit/coverage test/e2e/reports +test/e2e-playwright/test-results +test/e2e-playwright/playwright-report selenium-debug.log .idea/ config/local.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 99c85dd36..3067af58b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,6 +60,34 @@ test: - test/**/__screenshots__ when: on_failure +e2e-pleroma: + stage: test + image: docker:26 + services: + - name: docker:26-dind + tags: + - amd64 + - himem + variables: + DOCKER_HOST: tcp://docker:2375 + DOCKER_TLS_CERTDIR: "" + DOCKER_DRIVER: overlay2 + script: + - docker version + - docker compose version + - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY" + - export PLEROMA_IMAGE="${PLEROMA_IMAGE:-$CI_REGISTRY/pleroma/pleroma:stable}" + - docker compose -f docker-compose.e2e.yml up --build --remove-orphans --abort-on-container-exit --exit-code-from e2e + after_script: + - docker compose -f docker-compose.e2e.yml cp e2e:/app/test/e2e-playwright/test-results test/e2e-playwright/test-results || true + - docker compose -f docker-compose.e2e.yml cp e2e:/app/test/e2e-playwright/playwright-report test/e2e-playwright/playwright-report || true + - docker compose -f docker-compose.e2e.yml down -v --remove-orphans || true + artifacts: + when: on_failure + paths: + - test/e2e-playwright/test-results + - test/e2e-playwright/playwright-report + build: stage: build tags: diff --git a/docker-compose.e2e.yml b/docker-compose.e2e.yml new file mode 100644 index 000000000..75a4979a1 --- /dev/null +++ b/docker-compose.e2e.yml @@ -0,0 +1,57 @@ +services: + db: + image: postgres:15-alpine + environment: + POSTGRES_USER: pleroma + POSTGRES_PASSWORD: pleroma + POSTGRES_DB: pleroma + healthcheck: + test: ["CMD-SHELL", "pg_isready -U pleroma -d pleroma"] + interval: 2s + timeout: 2s + retries: 30 + + pleroma: + image: ${PLEROMA_IMAGE:-git.pleroma.social:5050/pleroma/pleroma:stable} + environment: + DB_USER: pleroma + DB_PASS: pleroma + DB_NAME: pleroma + DB_HOST: db + DB_PORT: 5432 + DOMAIN: localhost + INSTANCE_NAME: Pleroma E2E + ADMIN_EMAIL: ${E2E_ADMIN_EMAIL:-admin@example.com} + NOTIFY_EMAIL: ${E2E_ADMIN_EMAIL:-admin@example.com} + E2E_ADMIN_USERNAME: ${E2E_ADMIN_USERNAME:-admin} + E2E_ADMIN_PASSWORD: ${E2E_ADMIN_PASSWORD:-adminadmin} + E2E_ADMIN_EMAIL: ${E2E_ADMIN_EMAIL:-admin@example.com} + depends_on: + db: + condition: service_healthy + volumes: + - ./docker/pleroma/entrypoint.e2e.sh:/opt/pleroma/entrypoint.e2e.sh:ro + entrypoint: ["/bin/ash", "/opt/pleroma/entrypoint.e2e.sh"] + healthcheck: + # NOTE: "localhost" may resolve to ::1 in some images (IPv6) while Pleroma only + # listens on IPv4 in this container. Use 127.0.0.1 to avoid false negatives. + test: ["CMD-SHELL", "test -f /var/lib/pleroma/.e2e_seeded && wget -qO- http://127.0.0.1:4000/api/v1/instance >/dev/null || exit 1"] + interval: 5s + timeout: 3s + retries: 60 + + e2e: + build: + context: . + dockerfile: docker/e2e/Dockerfile.e2e + depends_on: + pleroma: + condition: service_healthy + environment: + CI: "1" + VITE_PROXY_TARGET: http://pleroma:4000 + VITE_PROXY_ORIGIN: http://localhost:4000 + E2E_BASE_URL: http://localhost:8080 + E2E_ADMIN_USERNAME: ${E2E_ADMIN_USERNAME:-admin} + E2E_ADMIN_PASSWORD: ${E2E_ADMIN_PASSWORD:-adminadmin} + command: ["yarn", "e2e:pw"] diff --git a/docker/e2e/Dockerfile.e2e b/docker/e2e/Dockerfile.e2e new file mode 100644 index 000000000..ec780e894 --- /dev/null +++ b/docker/e2e/Dockerfile.e2e @@ -0,0 +1,17 @@ +FROM mcr.microsoft.com/playwright:v1.55.0-jammy + +WORKDIR /app + +ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 + +RUN npm install -g yarn@1.22.22 + +COPY package.json yarn.lock ./ +RUN yarn --frozen-lockfile + +COPY . . + +ENV CI=1 + +CMD ["yarn", "e2e:pw"] + diff --git a/docker/pleroma/entrypoint.e2e.sh b/docker/pleroma/entrypoint.e2e.sh new file mode 100644 index 000000000..6945cf5b6 --- /dev/null +++ b/docker/pleroma/entrypoint.e2e.sh @@ -0,0 +1,57 @@ +#!/bin/ash + +set -eu + +SEED_SENTINEL_PATH="/var/lib/pleroma/.e2e_seeded" + +echo "-- Waiting for database..." +while ! pg_isready -U "${DB_USER:-pleroma}" -d "postgres://${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-pleroma}" -t 1; do + sleep 1s +done + +echo "-- Running migrations..." +/opt/pleroma/bin/pleroma_ctl migrate + +echo "-- Starting!" +/opt/pleroma/bin/pleroma start & +PLEROMA_PID="$!" + +cleanup() { + if [ -n "${PLEROMA_PID:-}" ] && kill -0 "$PLEROMA_PID" 2>/dev/null; then + kill -TERM "$PLEROMA_PID" + wait "$PLEROMA_PID" || true + fi +} + +trap cleanup INT TERM + +echo "-- Waiting for API..." +api_ok="false" +for _i in $(seq 1 120); do + if wget -qO- http://127.0.0.1:4000/api/v1/instance >/dev/null 2>&1; then + api_ok="true" + break + fi + sleep 1s +done + +if [ "$api_ok" != "true" ]; then + echo "Timed out waiting for Pleroma API to become available" + exit 1 +fi + +if [ ! -f "$SEED_SENTINEL_PATH" ]; then + if [ -n "${E2E_ADMIN_USERNAME:-}" ] && [ -n "${E2E_ADMIN_PASSWORD:-}" ] && [ -n "${E2E_ADMIN_EMAIL:-}" ]; then + echo "-- Seeding admin user (${E2E_ADMIN_USERNAME})..." + if ! /opt/pleroma/bin/pleroma_ctl user new "$E2E_ADMIN_USERNAME" "$E2E_ADMIN_EMAIL" --admin --password "$E2E_ADMIN_PASSWORD" -y; then + echo "-- User already exists (or creation failed), ensuring admin + confirmed..." + /opt/pleroma/bin/pleroma_ctl user set "$E2E_ADMIN_USERNAME" --admin --confirmed + fi + else + echo "-- Skipping admin seeding (missing E2E_ADMIN_* env)" + fi + + touch "$SEED_SENTINEL_PATH" +fi + +wait "$PLEROMA_PID" diff --git a/package.json b/package.json index 21d75f0fb..19cd5be6a 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,12 @@ "unit": "node build/update-emoji.js && vitest --run", "unit-ci": "node build/update-emoji.js && vitest --run --browser.headless", "unit:watch": "node build/update-emoji.js && vitest", - "e2e": "node test/e2e/runner.js", + "e2e:pw": "playwright test --config test/e2e-playwright/playwright.config.mjs", + "e2e": "sh ./tools/e2e/run.sh", "test": "yarn run unit && yarn run e2e", "stylelint": "yarn exec stylelint '**/*.scss' '**/*.vue'", - "lint": "eslint src test/unit/specs test/e2e/specs", - "lint-fix": "eslint --fix src test/unit/specs test/e2e/specs" + "lint": "eslint src test/unit/specs test/e2e/specs test/e2e-playwright/specs test/e2e-playwright/playwright.config.mjs", + "lint-fix": "eslint --fix src test/unit/specs test/e2e/specs test/e2e-playwright/specs test/e2e-playwright/playwright.config.mjs" }, "dependencies": { "@babel/runtime": "7.28.4", diff --git a/src/components/settings_modal/helpers/rate_setting.vue b/src/components/settings_modal/helpers/rate_setting.vue index f6216223c..49e09e046 100644 --- a/src/components/settings_modal/helpers/rate_setting.vue +++ b/src/components/settings_modal/helpers/rate_setting.vue @@ -30,60 +30,61 @@
| - | - {{ $t('admin_dash.rate_limit.period') }} - | -- {{ $t('admin_dash.rate_limit.amount') }} - | -|
|---|---|---|---|
| - {{ $t('admin_dash.rate_limit.unauthenticated') }} - | -- {{ $t('admin_dash.rate_limit.rate_limit') }} - | -- update({ event: e, index: 0, side: 0, eventType: 'edit' })" - > - | -- update({ event: e, index: 1, side: 0, eventType: 'edit' })" - > - | -
| - {{ $t('admin_dash.rate_limit.authenticated') }} - | -- update({ event: e, index: 0, side: 1, eventType: 'edit' })" - > - | -- update({ event: e, index: 1, side: 1, eventType: 'edit' })" - > - | -|
| + | + {{ $t('admin_dash.rate_limit.period') }} + | ++ {{ $t('admin_dash.rate_limit.amount') }} + | +|
| + {{ isSeparate ? $t('admin_dash.rate_limit.unauthenticated') : $t('admin_dash.rate_limit.rate_limit') }} + | ++ update({ event: e, index: 0, side: 0, eventType: 'edit' })" + > + | ++ update({ event: e, index: 1, side: 0, eventType: 'edit' })" + > + | +|
| + {{ $t('admin_dash.rate_limit.authenticated') }} + | ++ update({ event: e, index: 0, side: 1, eventType: 'edit' })" + > + | ++ update({ event: e, index: 1, side: 1, eventType: 'edit' })" + > + | +