Skip to content

fix(a11y): use native form submission paths - #835

Open
seonghobae wants to merge 4 commits into
mainfrom
codex/native-form-submit-v2
Open

fix(a11y): use native form submission paths#835
seonghobae wants to merge 4 commits into
mainfrom
codex/native-form-submit-v2

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Outcome

Keyboard and assistive-technology users can submit project and connection creation from focused inputs with Enter through the same guarded path used by button activation. Diagram and canvas search controls are semantic search forms that prevent navigation while preserving live filtering.

Changes

  • wrap editor/project-list creation and connection creation in native forms
  • use one submit handler per creation action; remove duplicate click dispatch
  • preserve whitespace, DSN, secret-clearing, and in-flight request guards
  • expose diagram and canvas searches as role="search" forms
  • stabilize the async graph-refresh coverage test before enabling fake timers
  • document behavior, recovery, standards references, and changelog entry

Test-first evidence

The focused regression initially failed because Enter did not call createProject. After implementation:

  • App.coverage.test.tsx: 21 passed
  • full frontend suite: 27 files, 201 tests passed
  • typecheck: passed
  • production build: passed
  • coverage run: 27 files, 201 tests passed; App branches 100%
  • git diff --check: passed

The repository-wide coverage report remains at its existing aggregate baseline (99.8% statements / 99.55% branches); this change introduces no uncovered App branch.

Closes #756

Summary by CodeRabbit

  • 개선 사항

    • 프로젝트 및 연결 생성 시 Enter 키와 클릭이 중복 실행되지 않도록 개선했습니다.
    • 프로젝트 생성·연결 생성 UI를 표준 폼 제출 방식으로 정리했습니다.
    • 다이어그램과 캔버스 검색에서 Enter 입력 시 페이지 이동을 방지하면서 실시간 필터링은 유지합니다.
    • 검색 및 생성 기능의 키보드 접근성과 접근성 이름을 개선했습니다.
  • 문서

    • 폼 제출, 검색 동작, 유효성 검사 및 접근성 관련 가이드를 추가했습니다.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c6b9e750-760f-4c53-a809-6294efbd4178

📥 Commits

Reviewing files that changed from the base of the PR and between 7dd402e and b16ab83.

📒 Files selected for processing (2)
  • frontend/src/App.coverage.test.tsx
  • frontend/src/App.tsx
📝 Walkthrough

Walkthrough

프로젝트와 연결 생성 UI를 네이티브 form 제출 방식으로 변경했습니다. Enter와 클릭은 단일 guarded 경로를 사용합니다. 다이어그램과 캔버스 검색은 role="search" form에서 기본 탐색만 차단합니다. 관련 테스트와 문서를 추가했습니다.

Changes

네이티브 폼 제출

Layer / File(s) Summary
생성 및 검색 form 흐름
frontend/src/App.tsx, CHANGELOG.md, docs/doctoring/native-form-submission.md
프로젝트와 연결 생성 영역을 semantic form으로 변경했습니다. submit 핸들러가 기존 생성 로직과 중복 제출 방지를 유지합니다. 검색 form은 기본 페이지 이동을 차단하고 실시간 필터링을 유지합니다.
키보드 및 검색 동작 검증
frontend/src/App.coverage.test.tsx, frontend/src/erd/__tests__/App.editTable.test.tsx
Enter 제출, 공백 입력 검증, 비동기 요청 중 재진입 차단, 검색 form의 접근성 조회와 비탐색 동작을 검증합니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 네이티브 폼 제출 경로로 접근성을 개선하는 주요 변경 사항을 정확하고 간결하게 설명합니다.
Linked Issues check ✅ Passed 코드, 테스트, 문서 변경이 이슈 #756의 폼 제출, 검색, 중복 제출 방지 및 기존 동작 보존 요구를 충족합니다.
Out of Scope Changes check ✅ Passed 변경 사항은 이슈 #756의 접근성, 제출 경로, 검색 동작, 테스트, 문서 범위에 포함되며 관련 없는 변경은 확인되지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/native-form-submit-v2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Please perform a fresh independent review of unchanged exact head 3d7d94857f6ba64a73965373b04a6769c55c34a0. All current CI/security workflows are green and no unresolved inline thread is recorded; merge remains deferred until exact-head review evidence is available.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

@seonghobae I will perform a fresh independent review of PR #835 at exact head 3d7d94857f6ba64a73965373b04a6769c55c34a0. I will assess the change independently, including the native form submission paths and accessibility behavior described in the PR objectives.

⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 48 minutes.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Please review exact head 3d7d94857f6ba64a73965373b04a6769c55c34a0. Required ci, Security Scan, and SAST Semgrep workflows are successful and there are no unresolved review threads; no formal review currently exists.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

@seonghobae I will review PR #835 at exact head 3d7d94857f6ba64a73965373b04a6769c55c34a0.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

Exact-current-head independent review request for 3d7d94857f6ba64a73965373b04a6769c55c34a0.

@opencode-agent @cwl-noema-review Please provide a qualifying non-author review of this unchanged accessibility fix. CI 31316076996, Security Scan 31316076997, and SAST Semgrep 31316076987 are terminal-success on this SHA, and there are zero unresolved review threads. Repeated CodeRabbit attempts were rate-limited and are not review evidence. Do not mutate the branch or merge.

Copy link
Copy Markdown
Collaborator Author

Exact-head accessibility remediation is published at 7dd402e64827e637b5201e6b4125d90a9ce68de2.

The search forms introduced by this PR exposed anonymous search landmarks. RED was observed in the rendered application: Testing Library reported role="search" with an empty accessible name. The exact successor now gives diagram and canvas search landmarks distinct names while preserving the existing named searchboxes, live filtering, and non-navigating Enter behavior.

Verification on the published tree:

  • focused landmark/search regression: passed;
  • complete frontend: 27 files / 201 tests passed;
  • coverage: 99.80% statements, 99.55% branches, 99.69% functions, 99.92% lines; App branches 100%;
  • TypeScript typecheck and production build: passed;
  • git diff --check: clean.

Local runtime was Node 24.14 while the repository requires Node 26, so exact-head CI is authoritative. The required CodeGraph executable was unavailable in this runner; call-site search and the complete suite were used.

@coderabbitai review
@opencode-agent @cwl-noema-review Please provide a qualifying formal non-author review for this unchanged exact head. Status-only or rate-limit responses are not approval.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Checked-out revision =='
git rev-parse HEAD
git status --short
printf '%s\n' '== PR metadata and checks =='
gh pr view 835 --repo ContextualWisdomLab/pg-erd-cloud \
  --json number,headRefOid,baseRefOid,changedFiles,mergeStateStatus,reviews,reviewDecision,statusCheckRollup \
  --jq '{number, headRefOid, baseRefOid, changedFiles, mergeStateStatus, reviewDecision, reviews: [.reviews[] | {author: .author.login, state}], checks: [.statusCheckRollup[] | {name, status, conclusion}]}'
printf '%s\n' '== Changed files from merge-base =='
base="$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD HEAD~1)"
git diff --name-status "$base" HEAD
printf '%s\n' '== Commit range =='
git log --oneline --decorate "$base..HEAD"

Length of output: 3501


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base="$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD HEAD~1)"

printf '%s\n' '== Exact PR diff =='
git diff --find-renames --find-copies --unified=80 "$base" HEAD -- \
  CHANGELOG.md \
  docs/doctoring/native-form-submission.md \
  frontend/src/App.tsx \
  frontend/src/App.coverage.test.tsx \
  frontend/src/erd/__tests__/App.editTable.test.tsx

printf '%s\n' '== App source structure =='
ast-grep outline frontend/src/App.tsx --items all --view expanded

printf '%s\n' '== Updated test structure =='
ast-grep outline frontend/src/App.coverage.test.tsx --items all --view expanded
ast-grep outline frontend/src/erd/__tests__/App.editTable.test.tsx --items all --view expanded

Length of output: 64391


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Form handlers and surrounding state =='
sed -n '112,190p' frontend/src/App.tsx
sed -n '850,985p' frontend/src/App.tsx

printf '%s\n' '== Rendered form containment and search controls =='
sed -n '1010,1275p' frontend/src/App.tsx
sed -n '1275,1445p' frontend/src/App.tsx

printf '%s\n' '== Styles that target changed wrapper classes or element types =='
rg -n -C 4 --glob '*.{css,scss,sass,less}' \
  '(\.inlineCreate|\.workspaceSearch|\.canvasToolbar__search|form|label)' \
  frontend

printf '%s\n' '== Precise direct references to changed handlers and wrappers =='
rg -n -C 3 \
  '\b(onCreateProject|onCreateProjectSubmit|onCreateConnection|onCreateConnectionSubmit|onSearchSubmit)\b|className="(inlineCreate|workspaceSearch|canvasToolbar__search)"|role="search"' \
  frontend/src

printf '%s\n' '== Test cases that submit changed forms or query search landmarks =='
rg -n -C 4 \
  "(submits the editor project form|project-list creation|connection once|non-navigating search|role\('search'|getByRole\('search'|user\.type\(.*\{enter\})" \
  frontend/src/App.coverage.test.tsx frontend/src/erd/__tests__/App.editTable.test.tsx

Length of output: 41284


@seonghobae Formal independent review completed for exact commit 7dd402e64827e637b5201e6b4125d90a9ce68de2.

I found no blocking source-level issue.

Verified items:

  • Project and connection forms use native submit events.
  • Submit handlers prevent browser navigation and call the existing guarded creation paths.
  • Button activation and Enter activation converge on the same handlers.
  • The project name trim guard, connection DSN validation, DSN clearing, and in-flight guards remain in place.
  • Diagram and canvas search forms prevent navigation on Enter.
  • The search landmarks have distinct accessible names: 다이어그램 검색 and ERD 캔버스 검색.
  • The existing input accessible names and CSS behavior remain compatible.
  • The updated tests cover the changed keyboard and landmark behavior.

I could not execute the frontend suite, typecheck, or build in this sandbox. I reviewed the test changes and source statically.

At review time, GitHub reported frontend, backend, Semgrep, and CodeQL-related checks as IN_PROGRESS. The PR status was BLOCKED. I therefore cannot provide approval until GitHub reports the required checks as successful.

You are interacting with an AI system.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
frontend/src/App.coverage.test.tsx (2)

355-360: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

비동기 재진입 guard를 handler 수준에서 직접 검증하세요.

첫 연결 요청이 시작되면 isCreatingConnection 때문에 submit button이 disabled 됩니다. 따라서 두 번째 user.type(...{enter})는 브라우저의 암시적 제출 단계에서 차단될 수 있습니다. 호출 횟수가 1이라는 결과만으로 onCreateConnectionSubmit의 guard가 실행됐다고 볼 수 없습니다. Promise가 pending인 동안 dsnInput.closest('form')fireEvent.submit(...)을 실행해 handler guard를 직접 검증하세요.

As per coding guidelines, “Add or update focused tests when changing behavior” 규칙에 따라 비동기 재진입 guard를 직접 검증해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/App.coverage.test.tsx` around lines 355 - 360, Update the
connection-creation test to verify the handler-level asynchronous re-entry guard
directly: while the first createConnection promise remains pending, submit
dsnInput.closest('form') with fireEvent.submit rather than relying on
user.type(...{enter}). Keep the assertion that api.createConnection is called
only once, ensuring onCreateConnectionSubmit itself rejects the second
submission.

Source: Coding guidelines


370-373: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

검색 form의 preventDefault()를 직접 검증하세요.

현재 테스트는 필터 결과와 role="search"만 확인합니다. onSearchSubmitpreventDefault()가 제거되어도 jsdom은 실제 페이지 이동을 수행하지 않으므로 테스트가 통과할 수 있습니다. fireEvent.submit(searchForm)의 취소 결과 또는 defaultPrevented를 확인하고, 다이어그램과 캔버스 form 모두에 적용하세요.

As per coding guidelines, “Add or update focused tests when changing behavior” 규칙에 따라 검색 제출 취소 동작을 직접 검증해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/App.coverage.test.tsx` around lines 370 - 373, 검색 제출 테스트에서 결과
필터링이나 ARIA 역할이 아닌 제출 취소 동작을 직접 검증하도록 업데이트하세요. 검색 form과 캔버스 form 각각의
`onSearchSubmit` 경로에 대해 `fireEvent.submit`의 취소 결과 또는 이벤트의 `defaultPrevented`를
확인하고, 기존 다이어그램 검색 검증도 유지하세요.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@frontend/src/App.coverage.test.tsx`:
- Around line 355-360: Update the connection-creation test to verify the
handler-level asynchronous re-entry guard directly: while the first
createConnection promise remains pending, submit dsnInput.closest('form') with
fireEvent.submit rather than relying on user.type(...{enter}). Keep the
assertion that api.createConnection is called only once, ensuring
onCreateConnectionSubmit itself rejects the second submission.
- Around line 370-373: 검색 제출 테스트에서 결과 필터링이나 ARIA 역할이 아닌 제출 취소 동작을 직접 검증하도록
업데이트하세요. 검색 form과 캔버스 form 각각의 `onSearchSubmit` 경로에 대해 `fireEvent.submit`의 취소 결과
또는 이벤트의 `defaultPrevented`를 확인하고, 기존 다이어그램 검색 검증도 유지하세요.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e3a3d636-9476-4d52-8463-09094767cb3b

📥 Commits

Reviewing files that changed from the base of the PR and between 72afe6d and 7dd402e.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • docs/doctoring/native-form-submission.md
  • frontend/src/App.coverage.test.tsx
  • frontend/src/App.tsx
  • frontend/src/erd/__tests__/App.editTable.test.tsx

Copy link
Copy Markdown
Collaborator Author

Addressed the exact-head CodeRabbit test-coverage findings at e24952fbb025ef0b256b05225c8263486c7a991f.

  • Re-entry: the pending connection test now repopulates the uncontrolled DSN input and dispatches submit directly on the form, so it reaches the handler boundary rather than relying on the disabled submit button.
  • Navigation safety: both named search forms now assert that fireEvent.submit(...) is cancelled (false), directly proving preventDefault().
  • Removed the stale v8 ignore on the now-covered connection re-entry guard.

Mutation RED evidence:

  • Removing isCreatingConnection from the guard caused createConnection to be called twice.
  • Removing onSearchSubmit's preventDefault() changed the dispatch result from false to true.

GREEN evidence after restoring production behavior:

  • focused regressions: 2 passed
  • full frontend: 27 files / 201 tests passed
  • typecheck: passed
  • production build: passed
  • coverage: 99.80% statements, 99.56% branches, 99.69% functions, 99.92% lines; App.tsx branches 100%
  • git diff --check: passed

codegraph init / codegraph sync could not run because the executable is unavailable in this environment; rg and focused source inspection were used for the bounded impact check.

@coderabbitai review the unchanged exact head e24952fbb025ef0b256b05225c8263486c7a991f.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

target='e24952fbb025ef0b256b05225c8263486c7a991f'

printf '%s\n' '== Revision =='
git rev-parse HEAD
git status --short
git cat-file -e "${target}^{commit}"
git merge-base --is-ancestor "$target" HEAD && printf '%s\n' 'target_is_ancestor_of_HEAD=yes'

printf '%s\n' '== Commit and incremental diff =='
git show --no-ext-diff --format=fuller --stat "$target"
git diff --no-ext-diff --unified=80 "${target}^" "$target" -- \
  frontend/src/App.tsx \
  frontend/src/App.coverage.test.tsx \
  frontend/src/erd/__tests__/App.editTable.test.tsx

printf '%s\n' '== Relevant source and test structure =='
ast-grep outline frontend/src/App.tsx --items all --view expanded
ast-grep outline frontend/src/App.coverage.test.tsx --items all --view expanded

printf '%s\n' '== Relevant handlers and coverage tests =='
rg -n -C 8 \
  '\b(isCreatingConnection|onCreateConnectionSubmit|onSearchSubmit|createConnection)\b|fireEvent\.submit|pending connection|non-navigating search|search.*form' \
  frontend/src/App.tsx frontend/src/App.coverage.test.tsx frontend/src/erd/__tests__/App.editTable.test.tsx

printf '%s\n' '== PR checks and head =='
gh pr view 835 --repo ContextualWisdomLab/pg-erd-cloud \
  --json headRefOid,mergeStateStatus,reviewDecision,statusCheckRollup \
  --jq '{headRefOid, mergeStateStatus, reviewDecision, checks: [.statusCheckRollup[] | {name, status, conclusion}]}'

Length of output: 45260


@seonghobae Formal independent review completed for exact commit e24952fbb025ef0b256b05225c8263486c7a991f.

I found no blocking source-level issue.

The revised connection test reaches onCreateConnection() through the form submit boundary while isCreatingConnection is true. It verifies that the second submission does not call createConnection.

The revised search tests verify that both named search forms cancel submit. This directly covers onSearchSubmit() and its event.preventDefault() call.

The removed v8 ignore comment is no longer needed.

GitHub still reports required checks as IN_PROGRESS, including frontend, backend, Semgrep, and CodeQL analysis. The PR merge state is BLOCKED. I cannot approve until the required checks complete successfully.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

CI RCA and remediation are published at exact head b16ab830da661ab32455233060414a4a75b152ef.

Failure boundary:

  • run 31514213291, frontend job 93855191644, Test step
  • App.coverage.test.tsx could not find the diagram-list 열기 button at the auto-layout failure test
  • the form-guard regressions added in the prior commit both passed in CI

Cause:

  • immediate cause: the test switched to fake timers and synchronously queried 열기 immediately after changing to the diagram view
  • root cause: listSnapshots() completes asynchronously, so the list was not guaranteed to exist before the query
  • systemic gap: three tests retained this same order while neighboring tests already awaited findAllByRole before enabling fake timers

Remedy:

  • all three affected tests now await the diagram list under real timers, capture the buttons, then enable fake timers for the polling boundary
  • production behavior and dependencies are unchanged

Verification:

  • focused affected regressions: 3 passed
  • full frontend: 27 files / 201 tests passed
  • typecheck: passed
  • production build: passed
  • coverage: 99.80% statements, 99.56% branches, 99.69% functions, 99.92% lines; App.tsx branches 100%
  • git diff --check: passed

Local Node remains 24.14 while the repository requires Node 26; this new exact-head CI is authoritative.

@coderabbitai review exact head b16ab830da661ab32455233060414a4a75b152ef.
@opencode-agent @cwl-noema-review Please provide a formal non-author verdict after exact-head required checks are terminal-success.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

target='b16ab830da661ab32455233060414a4a75b152ef'
repo='ContextualWisdomLab/pg-erd-cloud'

printf '%s\n' '== Exact revision =='
git rev-parse HEAD
git cat-file -e "${target}^{commit}"
git merge-base --is-ancestor "$target" HEAD && echo 'target_is_ancestor_of_HEAD=yes'
git status --short

printf '%s\n' '== Incremental commit and diff =='
git show --no-ext-diff --format=fuller --stat "$target"
git diff --no-ext-diff --unified=70 "${target}^" "$target" -- \
  frontend/src/App.coverage.test.tsx \
  frontend/src/App.tsx \
  frontend/src/erd/__tests__/App.editTable.test.tsx

printf '%s\n' '== Test-file outline =='
ast-grep outline frontend/src/App.coverage.test.tsx --items all --view expanded

printf '%s\n' '== Fake timer and diagram-list test contexts =='
rg -n -C 12 \
  "(useFakeTimers|useRealTimers|findAllByRole\('button'.*열기|findAllByRole\(\"button\".*열기|auto-layout|자동|listSnapshots)" \
  frontend/src/App.coverage.test.tsx

printf '%s\n' '== Exact-head PR status checks =='
gh pr view 835 --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,statusCheckRollup \
  --jq '{headRefOid, mergeStateStatus, reviewDecision, checks: [.statusCheckRollup[] | {name, status, conclusion, detailsUrl}]}'

printf '%s\n' '== Referenced workflow run =='
gh run view 31514213291 --repo "$repo" \
  --json headSha,status,conclusion,jobs \
  --jq '{headSha,status,conclusion,jobs: [.jobs[] | {name,status,conclusion,databaseId}]}'

Length of output: 41367


@seonghobae Formal independent static review completed for exact commit b16ab830da661ab32455233060414a4a75b152ef.

I found no blocking source-level issue.

The commit changes only frontend/src/App.coverage.test.tsx.

Each affected test now waits for the diagram-list 열기 buttons with findAllByRole() before it enables fake timers. This waits for the asynchronous listSnapshots() render path under real timers. The tests then start fake timers only for the polling boundary. This directly addresses the reported CI failure.

The prior failed workflow run 31514213291 ran on e24952fbb025ef0b256b05225c8263486c7a991f, not on the reviewed head.

I cannot approve yet. On the reviewed head, frontend, backend, Semgrep, CodeQL analysis, and strix are still IN_PROGRESS. GitHub reports the PR merge state as BLOCKED. I can provide a formal approval after the exact-head required checks are terminal-success.


✏️ Learnings added
Learnt from: seonghobae
URL: https://github.com/ContextualWisdomLab/pg-erd-cloud/pull/835

Timestamp: 2026-08-11T16:54:18.044Z
Learning: In `frontend/src/App.coverage.test.tsx`, tests that switch from the asynchronously rendered diagram list to fake-timer polling must await `screen.findAllByRole('button', { name: '열기' })` before `vi.useFakeTimers()`. This ensures `listSnapshots()` completes under real timers and prevents CI-only races caused by synchronous diagram-list queries.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Accessibility] Rebuild native Enter-key submission as a bounded App change

1 participant