From 806ec1aeab836d8f43d9ddc572bd8fb0223b17a1 Mon Sep 17 00:00:00 2001 From: Dream Hunter Date: Fri, 4 Sep 2026 12:10:27 +0800 Subject: [PATCH] fix: prevent Admin password dialog flash (#1134) * fix: wait for admin access settings before rendering * test: use frontend route for admin loading check * test: always release delayed admin settings request * test: track Admin password dialog during loading --- CHANGELOG.md | 1 + CHANGELOG_EN.md | 1 + e2e/tests/browser/admin-auth-loading.spec.ts | 56 ++++++++++++++++++++ frontend/src/views/Admin.vue | 2 +- 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 e2e/tests/browser/admin-auth-loading.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 255c3b0..8479b07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ ### Bug Fixes +- fix: |Admin| 修复权限设置加载完成前短暂显示管理员密码输入框的问题 - fix: |Admin| 修复切换一级标签页时二级标签页偶发无选中项、内容不显示及指示条偏移的问题 - fix: |发信页面| 统一邮箱与名称字段顺序,并修复空正文输入框的光标与占位文字错位 - fix: |用户发信| 用户地址发信接口支持角色无限额度 diff --git a/CHANGELOG_EN.md b/CHANGELOG_EN.md index 486b659..2442753 100644 --- a/CHANGELOG_EN.md +++ b/CHANGELOG_EN.md @@ -18,6 +18,7 @@ ### Bug Fixes +- fix: |Admin| Avoid briefly showing the Admin password dialog before access settings finish loading - fix: |Admin| Fix secondary tabs occasionally losing their active item, hiding content, and leaving the indicator offset after switching primary tabs - fix: |Send Mail| Use a consistent address/name field order and align the empty content editor caret with its placeholder - fix: |User Send Mail| Apply role-based unlimited sending to user-address APIs diff --git a/e2e/tests/browser/admin-auth-loading.spec.ts b/e2e/tests/browser/admin-auth-loading.spec.ts new file mode 100644 index 0000000..d3c4227 --- /dev/null +++ b/e2e/tests/browser/admin-auth-loading.spec.ts @@ -0,0 +1,56 @@ +import { expect, test } from '@playwright/test'; + +import { FRONTEND_URL } from '../../fixtures/test-helpers'; + +test('waits for access settings before showing the Admin password dialog', async ({ page }) => { + await page.addInitScript(() => { + const testWindow = window as Window & { __adminPasswordRendered?: boolean }; + testWindow.__adminPasswordRendered = false; + + const detectAdminPassword = () => { + const textNodes = document.createTreeWalker(document, NodeFilter.SHOW_TEXT); + while (textNodes.nextNode()) { + if (textNodes.currentNode.textContent?.trim() === '管理员密码') { + testWindow.__adminPasswordRendered = true; + return; + } + } + }; + + new MutationObserver(detectAdminPassword).observe(document, { + childList: true, + subtree: true, + characterData: true, + }); + }); + + let releaseSettings!: () => void; + const settingsPending = new Promise((resolve) => { + releaseSettings = resolve; + }); + let markSettingsRequested!: () => void; + const settingsRequested = new Promise((resolve) => { + markSettingsRequested = resolve; + }); + + await page.route('**/open_api/settings', async (route) => { + markSettingsRequested(); + await settingsPending; + await route.continue(); + }); + + await page.goto(`${FRONTEND_URL}/zh/admin`); + await settingsRequested; + + try { + await expect(page.getByText('管理员密码', { exact: true })).toHaveCount(0); + } finally { + releaseSettings(); + } + + await expect(page.getByText('快速设置', { exact: true })).toBeVisible(); + await expect(page.getByText('管理员密码', { exact: true })).toHaveCount(0); + expect(await page.evaluate(() => ( + window as Window & { __adminPasswordRendered?: boolean } + ).__adminPasswordRendered)).toBe(false); +}); diff --git a/frontend/src/views/Admin.vue b/frontend/src/views/Admin.vue index 8fa55b9..495009e 100644 --- a/frontend/src/views/Admin.vue +++ b/frontend/src/views/Admin.vue @@ -106,7 +106,7 @@ onMounted(async () => {