merge: move remember password below login

This commit is contained in:
2026-08-21 00:47:20 +08:00
4 changed files with 69 additions and 5 deletions

View File

@@ -0,0 +1,47 @@
# Task: Move remember password below login button
## Identity
- Task ID: 20260821-remember-below-login-4a7c91d2
- Mode: Feature
- Branch: codex/20260821-remember-below-login-4a7c91d2-remember-below-login
- Worktree: D:\w\makelore-remember-below-login-4a7c91d2
- Base commit: eedd20d0618f64b525c53a3362a74eddeebd4421
- Owner: codex
- Status: Ready for Integration
## Scope
- Move the password-login “记住密码” control directly below the login button and above the shared agreement control.
- Preserve the existing remembered-password state, availability, submission, and secure-storage behavior.
- Add focused unit and Electron smoke coverage for the new control order.
## Intent And Constraints
- Treat the supplied login screenshot as the visual reference: password field → login button → remember-password control → agreement.
- Keep this as a Renderer layout-only change; do not alter Main-owned credential persistence, Works Square authentication, form validation, or spacing tokens.
- Work only in the isolated feature worktree because local `main` remains owned by the existing remember-password integration task.
## Outcome
- Reordered the existing login button and remember-password label in the password form.
- Added a DOM-order assertion to the login-page unit test.
- Extended the shared Electron login smoke with a rendered-bounds assertion proving that the remember-password checkbox appears below the login button.
- No authentication, persistence, API, or styling behavior changed.
## Verification
- `pnpm exec vitest run tests/unit/login-page.test.tsx` — 1 file / 13 tests passed.
- `pnpm exec eslint src/pages/Login/index.tsx tests/unit/login-page.test.tsx tests/e2e/app-smoke.spec.ts` — passed.
- `pnpm run typecheck` — passed.
- `pnpm run build:vite` — Renderer, Electron Main, preload, and utility worker builds passed; existing dynamic-import and large-chunk advisory warnings remain.
- `pnpm exec playwright test tests/e2e/app-smoke.spec.ts --grep 'can skip setup and open the native login surface'` — 1 Electron smoke passed.
- `git diff --check` — passed with repository line-ending conversion notices only.
## Follow-ups
- Integrate the isolated feature branch into local `main` when its current integration ownership and documentation-drift blocker are resolved or explicitly taken over.
## Promotion Candidates
- None. This is a local presentation-order correction and does not change the canonical remember-password boundary or product behavior.

View File

@@ -392,6 +392,10 @@ export function Login() {
</div>
<Input id="login-password" type="password" autoComplete="current-password" value={password} onChange={(event) => setPassword(event.target.value)} />
</div>
<Button type="submit" className="w-full" disabled={!passwordReady}>
{busy && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
</Button>
<label
className="flex w-fit items-center gap-2 text-sm text-muted-foreground"
title={rememberPasswordAvailable ? undefined : '当前环境无法使用系统安全存储'}
@@ -404,10 +408,6 @@ export function Login() {
/>
<span></span>
</label>
<Button type="submit" className="w-full" disabled={!passwordReady}>
{busy && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
</Button>
</form>
) : (
<form className="space-y-4" onSubmit={handleMobileSubmit}>

View File

@@ -35,6 +35,17 @@ test.describe('Makelore Electron smoke flows', () => {
.toHaveAttribute('aria-selected', 'true');
await expect(page.getByLabel('用户名', { exact: true })).toBeVisible();
await expect(page.getByLabel('密码', { exact: true })).toBeVisible();
const loginButton = page.getByRole('button', { name: '登录', exact: true });
const rememberPasswordCheckbox = page.getByRole('checkbox', { name: '记住密码', exact: true });
await expect(rememberPasswordCheckbox).toBeVisible();
const [loginButtonBox, rememberPasswordBox] = await Promise.all([
loginButton.boundingBox(),
rememberPasswordCheckbox.boundingBox(),
]);
if (!loginButtonBox || !rememberPasswordBox) {
throw new Error('Login controls did not produce visible bounds');
}
expect(rememberPasswordBox.y).toBeGreaterThan(loginButtonBox.y + loginButtonBox.height);
await expect(page.getByRole('button', { name: '在浏览器中继续', exact: true })).toHaveCount(0);
});

View File

@@ -108,7 +108,13 @@ describe('Login page', () => {
expect(screen.getByRole('tab', { name: '验证码登录' })).toHaveAttribute('aria-selected', 'false');
expect(screen.getByLabelText('用户名')).toHaveAttribute('autocomplete', 'username');
expect(screen.getByLabelText('密码')).toHaveAttribute('autocomplete', 'current-password');
expect(await screen.findByRole('checkbox', { name: '记住密码' })).toBeEnabled();
const rememberPasswordCheckbox = await screen.findByRole('checkbox', { name: '记住密码' });
const loginButton = screen.getByRole('button', { name: '登录' });
expect(rememberPasswordCheckbox).toBeEnabled();
expect(
loginButton.compareDocumentPosition(rememberPasswordCheckbox)
& Node.DOCUMENT_POSITION_FOLLOWING,
).toBe(Node.DOCUMENT_POSITION_FOLLOWING);
expect(screen.queryByText(/浏览器|微信|注册/)).not.toBeInTheDocument();
});