Repository navigation
fix(receiver): 수신자 홈 헤더 액션에 이름을 붙이고 구성을 고정한다 (#613 일부) - #1103
Conversation
상단바 아이콘 둘 다 contentDescription 이 null 이라, 유일하게 눌리는 설정 아이콘조차 스크린리더가 읽어 주지 못했다. 이름을 붙이고 clickable 에 Role.Button 을 준다. 수신자 홈에 프로필 아이콘이 없다는 것(시안 4327:73626)과 설정 아이콘이 눌린다는 것을 회귀 가드로 고정한다 — 회원 홈 상단바를 그대로 재사용하는 구조라 기본값(true)으로 되돌아가기 쉬운 자리다. 설정 진입의 목적지 정리는 이 PR 범위 밖이다 — 수신자 전용 설정 시안이 없어 docs/qa/assumptions.md 에 근거와 함께 남겼다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1hyok
left a comment
There was a problem hiding this comment.
설정 아이콘 쪽(contentDescription + Role.Button)은 그대로 좋다. 시안도 대조했고 «수신자 홈에 프로필 아이콘이 없다» 는 판단은 정확하다. docs/qa/assumptions.md 에 톱니 목적지 미확정을 남긴 것도 규약대로다.
다만 프로필 아이콘에 붙인 이름은 되돌려야 한다. 이 PR 이 고치려던 문제를 회원 홈 쪽에 새로 만든다 — 아래 인라인에 근거를 적었다.
검증
- CI: 필수 체크 11종 전부 green.
- 시안 대조 완료 — 수신자 홈
4327:73626을 렌더해 확인했다. 헤더는 좌측 로고 + 우측 톱니 하나뿐이고 프로필 아이콘이 없다. PR 설명·테스트 KDoc 의 주장과 일치한다. - 실기동 QA 해당 없음 — 변경이 접근성 트리 semantics 라 Robolectric 테스트가 덮는 범위와 같다. 다만 아래 blocking 은 실기기 TalkBack 에서 재현되는 성질의 것이다.
HomeTopBar사용처 전수: 회원 홈(HomeTabScreen) · 애프터노트 홈 · 타임레터 발신/수신 홈 · 수신자 홈 — 5곳. 이 중showProfileIcon을 false 로 넘기는 곳은 수신자 홈뿐이다.
지적
- [blocking] 목적지 없는 장식 아이콘에 접근성 이름을 붙였다 →
HomeTopBar.kt:51인라인 코멘트.
| Image( | ||
| painter = painterResource(R.drawable.core_ui_user), | ||
| contentDescription = null, | ||
| contentDescription = stringResource(R.string.core_ui_home_top_bar_profile), |
There was a problem hiding this comment.
[blocking] 이 Image 에는 clickable 이 없다 — 바로 아래 톱니와 달리 어떤 화면에서도 눌리지 않는다. 이름을 붙이면 TalkBack 이 포커스 가능한 노드로 읽어, 사용자는 액션이 있다고 믿고 탭했다가 아무 반응도 얻지 못한다. 장식 요소에 contentDescription = null 을 두는 것이 Android 접근성 권장이고, 종전 코드가 그 상태였다.
근거가 셋 다 같은 방향을 가리킨다.
- 이슈 수신자 홈 헤더 액션이 맥락 불일치 — 프로필 아이콘 무동작·설정에 '로그아웃' 만 노출 #613 은 «접근성 트리에서도 clickable 로 잡히지 않아 사실상 장식 아이콘이다 … 프로필 아이콘은 목적지가 없으면 제거하고» 라고 적었다. 이름 부여는 그 반대 방향이다.
- 이 PR 이 함께 넣은
ReceiverHomeHeaderTest의 KDoc 도 «목적지가 없어 탭해도 아무 일도 없었다 — 접근성 트리에서도 clickable 이 아니라 사실상 장식이다» 라고 스스로 판정한다. - 영향 범위가 수신자 홈 밖이다. 수신자 홈은
showProfileIcon = false라 이 줄이 실행되지 않는다. 실제로 그려지는 곳은 회원 홈 · 애프터노트 홈 · 타임레터 발신/수신 홈 이고, 이 PR 의 범위(수신자 홈 헤더 액션이 맥락 불일치 — 프로필 아이콘 무동작·설정에 '로그아웃' 만 노출 #613 수신자 홈) 밖 화면들이다.
테스트가 «프로필 아이콘이 없다» 를 검증하려고 이름이 필요했던 것이라면, 프로덕션 semantics 대신 Modifier.testTag 로 앵커를 잡는 편이 낫다. 아니면 프로필 아이콘 자체를 여기서 걷어내는 쪽이 이슈 본문의 요구에 더 가깝다 — 다만 그건 회원 홈 시안 확정이 필요하니 별도 범위로 두는 것도 합리적이다.
core_ui_home_top_bar_profile 문자열도 함께 정리 대상이 된다.
이름을 붙이면 TalkBack 이 포커스 가능한 노드로 읽어, 사용자가 액션이 있다고 믿고 탭했다가 아무 반응도 얻지 못한다. 이 아이콘은 clickable 이 없는 장식이고, 실제로 그려지는 곳은 이 PR 범위 밖(회원 홈·애프터노트 홈·타임레터 홈)이다. 테스트가 존재 여부를 보려고 필요했던 앵커는 testTag 로 바꿔, 프로덕션 semantics 를 테스트 때문에 넓히지 않는다. 설정 아이콘의 이름·Role 은 그대로 둔다 — 그쪽은 실제로 눌리는 유일한 액션이다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
지적 반영했습니다 — 되돌리는 쪽이 맞습니다. 프로필 아이콘의 테스트 앵커는 제안대로 // 프로덕션
Image(painter = …, contentDescription = null, modifier = Modifier.size(18.dp).testTag(PROFILE_ICON_TEST_TAG))
// 테스트
composeRule.onNodeWithTag(PROFILE_ICON_TEST_TAG).assertDoesNotExist()테스트 KDoc 도 «설정은 이름을 두고 프로필은 두지 않는다» 는 이유가 남도록 고쳤습니다. 설정 아이콘의 프로필 아이콘 자체를 걷어내는 건 말씀대로 회원 홈 시안 확정이 필요해 이 PR 범위 밖으로 두었습니다. |
…to fix/613-receiver-home-header
1hyok
left a comment
There was a problem hiding this comment.
blocking 이 닫혔습니다. 승인합니다.
지적 처리
| # | 지적 | 처리 |
|---|---|---|
| 1 | [blocking] 목적지 없는 장식 아이콘에 접근성 이름을 붙였다 | 닫힘 — contentDescription = null 복귀 + 문자열 삭제 |
HomeTopBar.kt:53 이 contentDescription = null 로 돌아왔고, core_ui_home_top_bar_profile 도 지워졌습니다. 회원 홈·애프터노트 홈·타임레터 홈에 「눌러도 아무 일 없는 버튼」이 새로 생기는 일은 없습니다.
되돌리는 데서 그치지 않고 왜 이 아이콘만 이름이 없는지를 세 자리에 남긴 것이 이 수정의 값입니다 — 프로덕션 주석, strings.xml 의 설정 문자열 주석, 테스트 KDoc. 특히 KDoc 이 «설정은 이름을 두고 프로필은 두지 않는다» 를 대비로 적어 두어, 다음 사람이 «누락» 으로 오인해 채워 넣는 경로가 막혔습니다. 종전 KDoc 은 둘을 한 덩어리로 말하고 있어 그 오인이 실제로 가능했습니다.
테스트 앵커도 의도대로 갈렸습니다. onNodeWithTag(PROFILE_ICON_TEST_TAG).assertDoesNotExist() 는 프로덕션 semantics 를 건드리지 않고 «없음» 만 봅니다 — testTag 는 접근성 서비스에 노출되지 않으므로(testTagsAsResourceId 기본 off) TalkBack 이 읽는 트리는 그대로입니다.
검증
- CI: 필수 체크 전부 green (head
5473d30d). - develop 병합 실측:
git merge-tree --write-tree origin/develop <head>→ 충돌 0건. develop428022ff기준. - 삭제 자원 잔존 사용처: head 트리 전수
git grep core_ui_home_top_bar_profile→ 0건. 문자열만 지우고 참조가 남는 형태가 아닙니다. - 시안 대조: 앞 리뷰에서 확인한 수신자 홈
4327:73626대로 헤더는 로고 + 톱니 하나이고, 이번 수정은 그 판정을 바꾸지 않습니다. - 실기동 QA 해당 없음 — 변경이 semantics 라 Robolectric 이 덮는 범위와 같습니다. 이제는 이름 부여가 없어져 TalkBack 재현 대상도 사라졌습니다.
사소한 후속 여지 (이 PR 에서 안 고쳐도 됩니다)
PROFILE_ICON_TEST_TAG 는 core:ui 의 public top-level 상수가 됐습니다. 테스트가 모듈 밖(feature:receiver:presentation)에 있어 internal 이 불가하니 public 자체는 불가피한데, @VisibleForTesting 한 줄이면 «프로덕션에서 참조할 것이 아니다» 라는 의도가 표시됩니다 — #1105 에서 같은 성격의 완화를 그렇게 처리하셨으니 표기만 맞춰 두면 일관됩니다.
|
이 PR 은
|
assumptions.md 인접 추가라 양쪽을 모두 살렸다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
assumptions.md 인접 추가라 양쪽을 모두 살렸다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#613 의 1번(프로필 아이콘) 과 그 과정에서 드러난 접근성 결함을 닫는다. 2번(설정 목적지)은 시안 근거가 없어 뺐다 — 아래 「남는 것」 참고.
1번은 이미 해소돼 있었다 — 대신 재발 가드를 붙인다
ReceiverHomeScreen이showProfileIcon = false로 넘기고 있어 지금은 프로필 아이콘이 뜨지 않는다. 시안도 같다.시안 대조 — 수신자 홈
4327:73626(최종 수신자 프로토타입 → 애프터노트 - 상세확인): 헤더에 로고와 톱니 하나뿐이고 프로필 아이콘이 없다.문제는 이 구성이 기본값 하나로 되돌아간다는 점이다.
HomeTopBar(showProfileIcon: Boolean = true)라 인자를 빠뜨리면 회원 홈과 같은 헤더가 그대로 나온다. 그래서 «수신자 홈에는 프로필 아이콘이 없다» 를 테스트로 고정했다.함께 드러난 것 — 상단바 액션에 이름이 없다
두 아이콘 모두
contentDescription = null이었다. 프로필은 장식이라 그래도 됐지만, 설정은 유일하게 눌리는 액션인데도 접근성 트리에 이름이 없어 스크린리더가 무엇인지 읽어 주지 못한다.Role.Button도 함께 줬다 — 종전에는 «이미지» 로 읽혔다.남는 것 — 2번(설정 목적지)은 확정이 필요하다
지금 톱니는 회원 설정 그래프(
Route.Setting)로 그대로 보낸다. 수신자는X-Auth-Code기반이라 로그아웃할 세션이 없고, 프로필 수정·비밀번호 변경·수신자 관리도 해당이 없다.시안에도 답이 없다. 수신자 섹션 안의 「설정 메인」(
4327:75979)은 회원 설정 화면(프로필 수정 · 비밀번호 변경 · 로그아웃)을 그대로 복제한 프레임이라, 수신자 전용 설정 시안은 존재하지 않는다.선택지는 셋인데 어느 쪽도 코드만 보고 정할 수 없다.
기획·디자인 확정 뒤 후속으로 진행하고, 이 판단 보류를 근거와 함께
docs/qa/assumptions.md에 남겼다. 그래서 이 PR 은 #613 을 닫지 않는다.검증
testDebugUnitTest:app:assembleDebug·:app:compileDebugAndroidTestKotlincompileDebugScreenshotTestKotlin(core:ui · receiver)스크린샷 baseline 재생성 불필요 —
contentDescription과role은 시맨틱스만 바꾸고 픽셀을 바꾸지 않는다.실기동 QA: 못 했다. 수신자 홈은
delivery-verification이 APPROVED 여야 진입할 수 있고(#618·#614 와 같은 사정), 오늘 dev 서버가 점검 시간대라 응답하지 않는다. 대신 Robolectric 으로 실제 컴포지션을 태워 헤더 구성을 확인했다.