Refine vault defaults and account settings
This commit is contained in:
@@ -300,12 +300,10 @@ try {
|
||||
.getByRole('button', { name: '저장', exact: true })
|
||||
.boundingBox();
|
||||
assert.equal(mobileInput.height, mobileSave.height);
|
||||
await page.getByRole('switch', { name: '다른 기기에서 발견 허용' }).waitFor();
|
||||
assert.equal(
|
||||
await page
|
||||
.locator('.discovery-setting')
|
||||
.evaluate((el) => getComputedStyle(el).borderBottomWidth),
|
||||
'0px',
|
||||
await settings.getByRole('switch', { name: '다른 기기에서 발견 허용' }).count(),
|
||||
0,
|
||||
'발견 허용 설정을 표시하지 않음',
|
||||
);
|
||||
const settingsBounds = await settings.boundingBox();
|
||||
assert(Math.abs(settingsBounds.y + settingsBounds.height - 900) < 2, '모바일 설정 하단 시트');
|
||||
@@ -381,12 +379,30 @@ try {
|
||||
assert.equal(await page.locator('.name-count').innerText(), '9/40');
|
||||
await page.getByRole('button', { name: '저장', exact: true }).click();
|
||||
await page.locator('.footer-device-name').filter({ hasText: '나의 테스트 기기' }).waitFor();
|
||||
await page.locator('.footer-device-summary').click();
|
||||
await page.getByLabel('다른 기기에서 발견 허용').uncheck();
|
||||
const oldSession = await page.evaluate(async () => {
|
||||
const session = await (
|
||||
await fetch('/api/guest/session', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: '{}',
|
||||
})
|
||||
).json();
|
||||
const response = await fetch('/api/device/me', {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': session.csrfToken },
|
||||
body: JSON.stringify({ discoverable: false }),
|
||||
});
|
||||
return { deviceId: session.device.id, ok: response.ok };
|
||||
});
|
||||
assert.equal(oldSession.ok, true);
|
||||
await page.locator('.footer-device-summary').filter({ hasText: '발견 꺼짐' }).waitFor();
|
||||
await page.getByLabel('다른 기기에서 발견 허용').check();
|
||||
await page.reload();
|
||||
await page.locator('.footer-device-summary').filter({ hasText: '발견 허용' }).waitFor();
|
||||
await page.getByRole('button', { name: '대화상자 닫기', exact: true }).click();
|
||||
assert.equal(await page.locator('.footer-device-name').innerText(), '나의 테스트 기기');
|
||||
assert.equal(
|
||||
await page.evaluate(async () => (await (await fetch('/api/device/snapshot')).json()).device.id),
|
||||
oldSession.deviceId,
|
||||
);
|
||||
await page.getByRole('button', { name: '다른 기기 연결', exact: true }).click();
|
||||
assert.equal(await page.locator('.connection-choice').count(), 2);
|
||||
assert.equal(await page.getByRole('checkbox', { name: '참여할 때 내 승인 받기' }).count(), 0);
|
||||
@@ -436,7 +452,7 @@ try {
|
||||
await page.waitForFunction(() => document.querySelectorAll('.peer-card').length === 12);
|
||||
assert.deepEqual(errors, []);
|
||||
console.log(
|
||||
'PASS: 실제 12대 자동 발견, 4/3/2열과 줄바꿈, 푸터의 내 기기 상태·이름/발견 설정, 선택 전 전송 UI 없음, 고정 크기 PC 모달·모바일 하단 시트, 하나의 전송 버튼과 파일/링크 대체, Escape, QR 참여 시 모달 자동 닫힘, 방 안의 기기 격리·나가기 후 주변 복귀.',
|
||||
'PASS: 실제 12대 자동 발견, 4/3/2열과 줄바꿈, 푸터의 기기명 설정·발견 옵션 숨김·이전 비공개 세션의 재접속 후 발견 복구, 선택 전 전송 UI 없음, 고정 크기 PC 모달·모바일 하단 시트, 하나의 전송 버튼과 파일/링크 대체, Escape, QR 참여 시 모달 자동 닫힘, 방 안의 기기 격리·나가기 후 주변 복귀.',
|
||||
);
|
||||
} finally {
|
||||
for (const socket of sockets) socket.disconnect();
|
||||
|
||||
@@ -80,10 +80,95 @@ try {
|
||||
await auth.getByLabel('비밀번호', { exact: true }).fill('1234');
|
||||
await auth.getByRole('button', { name: '로그인', exact: true }).click();
|
||||
await page.locator('.account-workspace').waitFor();
|
||||
assert.equal(
|
||||
await page.getByRole('tab', { name: '받은 항목', exact: true }).getAttribute('aria-selected'),
|
||||
'true',
|
||||
'보관함 기본 화면은 받은 항목',
|
||||
);
|
||||
assert.equal(await page.locator('.account-heading p').count(), 0);
|
||||
await page.locator('.scope-note').filter({ hasText: '항목별 최대 7일 보관' }).waitFor();
|
||||
return await page.locator('.footer-device-name').innerText();
|
||||
}
|
||||
const senderName = await register(sender, 'alice@example.com', 'Alice');
|
||||
await register(receiver, 'bob@example.com', 'Bob');
|
||||
for (const [page, email, device] of [
|
||||
[sender, 'alice@example.com', 'desktop'],
|
||||
[receiver, 'bob@example.com', 'mobile'],
|
||||
]) {
|
||||
await page.getByRole('button', { name: '계정 설정', exact: true }).click();
|
||||
const preferences = page.getByRole('dialog', { name: '계정 설정', exact: true });
|
||||
await preferences.waitFor();
|
||||
await page.keyboard.press('Shift+Tab');
|
||||
assert.equal(
|
||||
await preferences
|
||||
.getByRole('button', { name: '비밀번호 변경', exact: true })
|
||||
.evaluate((el) => document.activeElement === el),
|
||||
true,
|
||||
'포커스가 모달 밖으로 나가지 않음',
|
||||
);
|
||||
await page.keyboard.press('Tab');
|
||||
assert.equal(await preferences.locator('select,input').count(), 0, '항목 목록을 먼저 표시');
|
||||
assert.equal(await preferences.locator('.preference-item').count(), 2);
|
||||
assert.equal(
|
||||
await preferences.locator('.preference-item').first().locator('p').innerText(),
|
||||
email,
|
||||
);
|
||||
const viewport = page.viewportSize();
|
||||
const bounds = await preferences.boundingBox();
|
||||
assert(bounds.x >= 0 && bounds.x + bounds.width <= viewport.width);
|
||||
if (device === 'mobile')
|
||||
assert(
|
||||
Math.abs(bounds.y + bounds.height - viewport.height) < 2,
|
||||
'계정 설정은 모바일 하단 시트',
|
||||
);
|
||||
await page.screenshot({ path: `tests/e2e/account-settings-${device}.png` });
|
||||
await preferences.getByRole('button', { name: '비밀번호 변경', exact: true }).click();
|
||||
await preferences.getByLabel('현재 비밀번호', { exact: true }).waitFor();
|
||||
assert.equal(
|
||||
await preferences
|
||||
.getByLabel('현재 비밀번호', { exact: true })
|
||||
.evaluate((el) => document.activeElement === el),
|
||||
false,
|
||||
'입력창 자동 포커스 없음',
|
||||
);
|
||||
const headerBounds = await preferences.locator('header').boundingBox();
|
||||
const formBounds = await preferences.locator('form').boundingBox();
|
||||
assert(formBounds.y >= headerBounds.y + headerBounds.height + 16, '제목과 변경 폼 간격');
|
||||
for (const field of ['현재 비밀번호', '새 비밀번호', '새 비밀번호 확인']) {
|
||||
const input = preferences.getByLabel(field, { exact: true });
|
||||
if (device === 'mobile')
|
||||
assert.equal(await input.evaluate((el) => getComputedStyle(el).fontSize), '16px');
|
||||
await input.fill('draft1234');
|
||||
const inputBounds = await input.boundingBox();
|
||||
assert(
|
||||
inputBounds.x >= bounds.x && inputBounds.x + inputBounds.width <= bounds.x + bounds.width,
|
||||
);
|
||||
}
|
||||
await page.screenshot({ path: `tests/e2e/account-password-${device}.png` });
|
||||
await preferences.getByRole('button', { name: '계정 설정 목록으로', exact: true }).click();
|
||||
await preferences.getByRole('button', { name: '이메일 변경', exact: true }).click();
|
||||
assert.equal(
|
||||
await preferences.getByLabel('현재 비밀번호', { exact: true }).inputValue(),
|
||||
'',
|
||||
'항목 전환 시 비밀번호 초안 제거',
|
||||
);
|
||||
await preferences.getByLabel('새 이메일', { exact: true }).fill('new@example.com');
|
||||
await page.screenshot({ path: `tests/e2e/account-email-${device}.png` });
|
||||
await page.keyboard.press('Escape');
|
||||
await preferences.waitFor({ state: 'hidden' });
|
||||
await page.getByRole('button', { name: '계정 설정', exact: true }).click();
|
||||
await preferences.getByRole('button', { name: '이메일 변경', exact: true }).click();
|
||||
assert.equal(
|
||||
await preferences.getByLabel('새 이메일', { exact: true }).inputValue(),
|
||||
'',
|
||||
'모달 닫기 시 개인정보 초안 제거',
|
||||
);
|
||||
await preferences.getByRole('button', { name: '계정 설정 닫기', exact: true }).click();
|
||||
assert.equal(
|
||||
await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth),
|
||||
true,
|
||||
);
|
||||
}
|
||||
async function navigate(page, view) {
|
||||
if (view === '기기') return page.getByRole('button', { name: 'hop. 홈', exact: true }).click();
|
||||
await page.locator('.login-button').click();
|
||||
@@ -220,7 +305,7 @@ try {
|
||||
assert(!(await receiver.locator('body').innerText()).includes('https://example.com/saved'));
|
||||
assert.deepEqual(errors, []);
|
||||
console.log(
|
||||
'PASS: 1234 가입·인증·로그인, 로그인 기기 수신의 날짜별 기록, 직접 링크/파일 저장과 메모 수정, 보관함 자료의 수락 후 자동 열기/다운로드, 파일 재업로드 없음, 7일 만료, 삭제/복원, 로그아웃 권한 격리, 모바일 화면. 실제 Resend 발송은 포함하지 않음.',
|
||||
'PASS: 받은 항목 기본 화면·보관 안내, PC/모바일 계정 설정 목록·항목별 폼·간격·16px 입력·초안 제거·키보드 탐색, 가입·인증·로그인, 날짜별 기록, 직접 링크/파일 저장과 메모 수정, 보관함 자료의 수락 후 자동 열기/다운로드, 파일 재업로드 없음, 7일 만료, 삭제/복원, 로그아웃 권한 격리. 실제 Resend 발송은 포함하지 않음.',
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
Reference in New Issue
Block a user